SynthMaker

Optimizing FFT... driving me nuts!

Archive · 2011 30 old posts

From the original SynthMaker forum (2004–2014), with its members’ names and dates.

tor ·

Hello good folks. As some might know I have a FFT in my EQ. I have tried everything I think. The only way I actually managed to get the CPU load down is to have a tick divide. But I can not go under tick25/2. The graphics just become to slow to funktion proper. On my Core 2 Duo the stock FFT consume between 50-70% and loopeytunes report that his i3 processor consumes 20%. I have gotten the load down in my EQ's FFT a little by reducing size and ticks. I really need this to be reduced much more.

I share this for anyone to look into and hopefully someone can give a hand in the optimizing. Please help me 😕

BTW: I have cleaned up and fixed alot of GUI/interaction stuff from the earlier version of DPE i shared in the RBJ thread.

MichaelBenjamin ·

have you tried to use a "redraw area" module instead? also to make sure no unnecessary triggers get to the redraw - use some of infuzions redraw limiters. you should get down to a reasonable amount of cpu use, but still, in general graphics redrawing seems to be like a weak spot in sm.

trogluddite ·

Yes, MB has a good point. I had a little play with the schematic, and even with the FFT disconnected and no audio running, the CPU load is pretty high - nearly 40% on my little notebook. This is a particular problem with SM - redrawing large areas is very CPU greedy, even when well optimised. It would be worth having a play with various parts disabled to find exactly where all that CPU is going - could be that the actual FFT maths is using less than you think. Another trick worth trying would be to buffer the EQ curve into a bitmap - that part only needs recalculating when you move a knob, but because it is overlaid over the FFT, the curve points also get calculated every time the FFT is redrawn - the trigger in GUI parts do weird stuff like that sometimes. You can turn the curve into a temporary bitmap when the controls are static, which is much faster to draw to the screen. The thread Lower GUI CPU Load has examples of these CPU savers for graphics - but don't expect miraccles, big animations are just a bit of a pain in SM.

tor ·

No I did not try the redraw area this time. But the redraw component is connected to a max clipped down video connection. I thought maybe it did the same trick. I try now and see it actually helps a little. But far from what I want. Thank you!

tor ·

would it be better maybe to separate the layers. reponse graphs and dots in one gui panel and fft in a panel then give them seaparate dredraw prims? or will the two overlaying panels redraw affect eacother?

trogluddite ·

Could possibly help. When you redraw an area, it will will redraw any view that overlaps that area , even if they are in completely different modules- and if you are using graphs or vector graphics, that means that all the hidden maths to calculate the pixels gets done too.

You can sometimes use this to your advantage... Say you had a row of level meters like on a mixer - instead of having a ReDraw inside every meter, you can have another module that overlaps all of the meters, and use it to Redraw all of them at once - because ometimes drawing one big area can use less CPU than drawing a lot of little ones. The big 'overlay' module doesn't even have to have any graphics in it - just an MGUI and a ReDraw Area.

Something else I found that might help - Redraws can also make lots of green triggers too... e.g. You have a vector graphic with lots of green maths that calculates where the vectors have to go - if you do a redraw of the vectors, the green maths gets done again too, sometimes - even if the values haven't changed. Putting trigger blockers (or Sample and Hold) to seperate the 'Green' from the 'Yellow' can help here - e.g. putting blockers on the green inputs to a Float-to-Area. Could be that is happening with your schematic - the ReDraws might be making the Float Array calculations use extra CPU.

tor ·

hmmm... i see. so this happens even though it is not connected to the redraw? your suggestion is to have a sample and hold between the green math and the respecting graph components? and where should i get the triggers from that control sample and hold? why will not sample and hold be affected by the redraw if all other green is? if green math gets retriggered by redraw will not triggers connected in the same system also be?

tor ·

when i turn a knob or drag a node in the graphics there is a huge cpu raise. so i guess they are not constantly beein recalculated by the redraw. if not then the case is that i get double up with green calculations while adjusting the parameters.

i am ok with a constant cpu load. that why i use one tick25/2 as redraw and get trigger. i just dont see how i can get ok rendering with any lower trig rate.

must investigate more in the trig block prim though... but i think it will be a heck of a job finding where to implement them in the schematic and if they actually make significant difference.

trogluddite ·

tor wrote: hmmm... i see. so this happens even though it is not connected to the redraw

Can do, yes, though it's kind of unpredictable when it happens. Even if not connected to the redraw, if it is connected to any GUI parts that overlap the view, you can still get these 'backwards' triggers where the graphics are 'asking' the green to re-calculate the value - even if they are using the same tick. You don't always need an extra source for the S&H triggers, you can connect like this...

(shown with float, but works the same with other green) Looks kinda odd, like it doesn't do anything!? But it stops 'backwards' triggers from coming through (from right to left) - so the maths only gets done once, even if other parts on the right hand side are refreshing many times. I often put one right at the end of any complicated maths, so that I know the maths only gets done when I want it to.

tor wrote: i get double up with green calculations while adjusting the parameters

Yes, that's a good place to look for some CPU saving - the handles and EQ plot shouldn't need ReDraws, because the FFT animation is already drawing that part of the screen.

tor ·

trogluddite wrote: Yes, that's a good place to look for some CPU saving - the handles and EQ plot shouldn't need ReDraws, because the FFT animation is already drawing that part of the screen.

so i understood 🙂

i only have one redraw for that area. will try the sample and hold trick to see if it helps

thank you

trogluddite ·

Yeah, it can be hard work chipping little 1% here and there - Good luck. 🙂

tor ·

sample and hold in the end of all green math actually icreased cpu load 😝

trogluddite ·

Ouch, that doesn't usually happen! 🙁

Oh yes, one last tip (if you still trust me 😉 ) - when checking GUI CPU load, make sure none of the modules are selected in the SM window. It's a mystery, but for some reason a selected module always uses a bit of extra CPU

tor ·

hmmm... ok.

i have no problem trusting you trog 🙂

as far as i can remember you have helped me out numberous times. and i am thankful for you dedication to the SM community

😀

Andrew J ·

tor wrote: hmmm... ok.

i have no problem trusting you trog 🙂

as far as i can remember you have helped me out numberous times. and i am thankful for you dedication to the SM community

😀

He uh good lad, inn't he?

tor ·

Certainly is!

And so are you 😉

aliasant ·

Something you could do is to cache the black background. That should save you a few. Maybe also cache the grid and other graphics that are not moving. Only redraw what is actually moving.

aliasant ·

Here.

I removed the Trig Divide so now everything is running at 25/sec. I cached the Graphline and controllers. That makes a huge difference. I also cached the background black color. No need to keep redrawing that. Havnt touched the meters so they could use some caching too. I set the cache to also blur / use less resolution on some parts. Original is 8 but I set them to 6. That makes it faster and slightly blurry.

The problems now are mostly the controls. When you change one of them you send triggers to all of them. Maybe use a trigger flow control to only change the band that you actually changing? That part really could use some optimizing.

The FFT is also quite distracting. It could use some averaging to calm down abit. I get nervous looking at it 😉

MichaelBenjamin ·

dont know if the smoothing is worth it. looks too blurred to me. tried to reset view, but then it was built in. what could be another problem is the semi transparency, which slows down everything alot. i tried it once with transparent png layers and that also slowed down massively.

aliasant ·

MichaelBenjamin wrote: dont know if the smoothing is worth it. looks too blurred to me. tried to reset view, but then it was built in. what could be another problem is the semi transparency, which slows down everything alot. i tried it once with transparent png layers and that also slowed down massively.

The smoothing isnt that important but can help a little and its also a nice tool if you want to smoothen graphics or shadows.

What really makes a difference is the caching of all the controllers. That dropped the cpu usage almost down to nothing.

Mo ·

It would also help to optimize the knobs, so they don't use cpu when not moving: Fixed and optimized Readout Knob

Also, using triggers from a mouse drag primitive for the EQ redraw, would make it update more smooth.

tor ·

the background is just temporary it will be replaced by a static picture. i see now that it will pay off to remove transparency and move as much of the vector graphics as possible into the static background. the CPU load after your bitmap trick aliasant is now half of what it was when no controllers are moved. i actually have thought of smoothing the fft out, but have yet to come up with a method for this. mo, i will have to look at the knob optimations aswell. still have a hard time to see how i get the green float(array) maths optimized effective.

i did not get much sleep this night, so guess i will have to come back stronger tomorrow

tank you all for the effort 🙂

aliasant ·

tor wrote: the background is just temporary it will be replaced by a static picture. i see now that it will pay off to remove transparency and move as much of the vector graphics as possible into the static background. the CPU load after your bitmap trick aliasant is now half of what it was when no controllers are moved. i actually have thought of smoothing the fft out, but have yet to come up with a method for this. mo, i will have to look at the knob optimations aswell. still have a hard time to see how i get the green float(array) maths optimized effective.

i did not get much sleep this night, so guess i will have to come back stronger tomorrow

tank you all for the effort 🙂

Half but also twice as fast redraws and much much smoother 🙂

tor ·

Cant belive I did not think of it earlier. To use trigger counters more actively in the search for optimizations in the greens. I found a bug in the Mouse Drag prims. Seems like they produce 2 ticks pr float change in the outputs. Workaround: Insert a Float Changed module right after all mouse drag prims to reduce all green calculations with prox 50%. This aply to all knobs and the graphic controls. This the amount of calculations involved it really makes a difference.

matti ·

tor wrote: Cant belive I did not think of it earlier. To use trigger counters more actively in the search for optimizations in the greens. I found a bug in the Mouse Drag prims. Seems like they produce 2 ticks pr float change in the outputs. Workaround: Insert a Float Changed module right after all mouse drag prims to reduce all green calculations with prox 50%. This aply to all knobs and the graphic controls. This the amount of calculations involved it really makes a difference.

Cool find 🙂 (haven't tested it yet tho..)

What i found in your schematic is that you are redrawing your knobs at full precision. There's no need for that. Something like 100 quadrants for a circle should be enough to not be noticeable. Use tick dividers there.. You can still do the math at full precision. Graphics are the thing that are heavy. You could do something about text elements too. Remember that the stock elements(like the knob) are in no way perfect, or as light as possible. Making your own elements, or at least modifying them to better suit your needs, is essential.

Definitely go for just one redraw area on your graph. Not many. Every redraw area that overlaps other elements will redraw those elements too. So you'll be doing loads of unnecessary work. (But of course do knob and font redraws on their own, with as little areas as possible.)

You are having a lot of stuff drawn here. Not sure if you can get it "much" lighter. But you can always try 🙂 I can post some examples of my take on the same subject a bit later.. when i get to my files.

trogluddite ·

matti wrote: There's no need for that. Something like 100 quadrants for a circle should be enough to not be noticeable.

If you take an Integer Changed from the cell selection for the bitmap, there will only be a trigger when there is actually a change in the graphics. That gives a nice 1:1 ratio between the number of 'quadrants' and the number of animation frames. You can then even apply a trigger limiter to that, to slow the animation when there are big sweeps of the knob. Here's a stock animated knob with the mod's I mean...

AngularMomentum ·

What would make that even leaner is by having the triggers shut off when min or max is reached. When moving the knob below a value of 0 or over 1 now, it still redraws.

To go completely off topic...I am building a A-station controller and it fires too much MIDI data to the A-Station making the sound stutter, I have to reduce the amount of triggers so thanks for your example there, it's a great help!

trogluddite ·

AngularMomentum wrote: When moving the knob below a value of 0 or over 1 now, it still redraws.

The knob itself won't ReDraw because the animation frame will stay the same. The float output from the knob will still send too many triggers, though - which in turn may lead to ReDraws in other parts of the GUI (and possibly extra automation events). Should be easy to fix with a 'Float Changed' module in the right place.

infuzion ·

trogluddite wrote: You can then even apply a trigger limiter to that, to slow the animation when there are big sweeps of the knob.

looks familiar...

AngularMomentum ·

Sorry that is what I meant...I hooked up a float label and it was still sending out floats and triggers when it is not necessary, too much gin yesterday I guess. 🙂

Wrote something here? To have a post removed or your name hidden, write to [email protected].

Before your first post

A few rules keep this a friendly place. You agree to them once.

Shown next to what you post, here and in the app. It doesn’t have to be your real name: 3–24 lower-case letters, digits or _ (capitals become lower case, spaces become _).

    Then your post goes up straight away.

    Delete this reply?

    Open it in SynthMaker?

    It goes on the track you’re editing there, in place of that track’s sound, and into My sounds. Your other tracks stay as they are.

    Want to keep that track’s sound? Start a new song in SynthMaker first (Song › New song), then open this.

    Report this reply?

    Only the developer reads reports. The person isn’t told who reported them.

    What’s wrong with it?

    Block this person?

    You won’t see their posts and replies here any more. They aren’t told, and you can unblock them at any time.

    People you’ve blocked

    Their posts and replies are hidden from you. Unblock someone to see them again.

    The community rules

    A few rules keep this a friendly place. Everyone agrees to them once, before their first post.