dukesrg / logue-osc

Custom oscillators for Korg logue-sdk compatible synths. Contains Oscillator API extensions and reusable header to create wavetable-based oscilator and example web page for user wave data injection.
https://dukesrg.github.io/logue-osc/
105 stars 6 forks source link

another possible performance improvement(s) for OSC_CYCLE #21

Open aminixduser opened 4 years ago

aminixduser commented 4 years ago

Hi @dukesrg

Well my last idea was a blunder, but I think this one might be good. I'm now keeping the .list files from the compiles and I see how it optimized bit tests, what a nice instruction. Back to my idea.... update ideas, there are two here, one with a couple variants

At the start of OSC_CYCLE, for fixed frequency operators you could pre-compute the opw0[i] in the initvoice routine, and just load it, where you currently have: if (s_fixedfreq[i]) opw0[i] = pitch_to_phase(s_oppitch[i]);

you could have opw0[i] = s_opw0[i] ; // where s_opw0 has the fixed frequency values,
This wouldn't save much maybe a cycle or two per fixed oscillator, and if you used Q31 for pitch then really nothing is saved.

One other possibility is that you don't care about the pitch bender (or lfo so much), so you set a flag in the state on NOTEON, You check the flag, compute basew0, store the basew0 in part of the state and clear the flag. The next time OSC_CYCLE is called you check the flag, and then don't compute basew0 again as it is a rather large routine until the next NOTEON, or after n number of calls to OSC_CYCLE after note on and pitch bend might work or get noisy.

Another variant would be to store the params->pitch value using the set state flag in NOTEON, clear in OSC_CYCLE and store the value. The next time OSC_CYCLE is called compare the saved value to the current one, skip the compute if they are equal, and if not equal calculate basew0 again. Save the new value, and so on, that way you only do the big routine when you need to.

dukesrg commented 4 years ago

s_oppitch will save 1 operation, 3 cycles at least, if not countinf additional loads (still uncertain if thy are obligatory for floating-point operations, mul in that case). And will probable consume 2-4 more bytes

Yes it is possible to precache the calculated phase increment and check if pitch changes, Will save something about 50+ cycles. But again code will be increased and also we'll loose the option to control the several parameters in realtime with assignable controller.

But that is all not per sample, but batch of up to 64 samples. One sample fo 6-op consumes more than 50+ cycles we could save on the phase increment precaching :(

dukesrg commented 4 years ago

@aminixduser I'll consider pitch optimization in case we're out of free memory and ought to reduce bank count and/or pitch control via assignable controllers won't fit by performance.

aminixduser commented 4 years ago

Another option to save on code space would be to split the FM64 to FM6 and FM4, or whatever names you want to give them.

dukesrg commented 4 years ago

@aminixduser Yep there is an option too. We can even have 3-of-a kind.

dukesrg commented 4 years ago

FYI 6-op only saves ~700 bytes 4op only saves ~1.2K