Open aminixduser opened 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 :(
@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.
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.
@aminixduser Yep there is an option too. We can even have 3-of-a kind.
FYI 6-op only saves ~700 bytes 4op only saves ~1.2K
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.