http://www.martin-finke.de/blog/article ... envelopes/
http://www.earlevel.com/main/2013/06/03 ... adsr-code/
My design requirement was for the decay to be infinite (based on y= 1/(x+1)^c) where "decay time" is time to an amplitude of 1/e relative to the peak value. That's how envelope time works in Reaktor and I've grown accustomed to it.
The envelope works perfectly well, but I'm doing additive synthesis where I have hundreds of these things running together, and I am finding them quite costly in terms of CPU. I can reduce the CPU with a sample rate reduction for the envelope, so it's only outputting a calculation every x number of samples, but this can introduce clicks on the attack phase. I'd rather figure out how to make it more internally efficient if possible.
Here's the graphing function if you are curious what I mean by y=1/(x+1)^c:
https://www.desmos.com/calculator/sby91g32yu
My code is that when I enter the Decay case:
Code: Select all
case ENVELOPE_STAGE_DECAY:
currentSampleIndex = 0;
sustainLevel = sustainPercent * maxLevel;
decayExponent = 1 / log(decayTimeSeconds+1);
break;
Then my nextSample() function for decay is this:
Code: Select all
else if (currentStage == ENVELOPE_STAGE_DECAY) {
currentLevel = maxLevel / pow((currentSampleIndex/sampleRate)+1.0, decayExponent);
currentSampleIndex++;
if (currentLevel <= (sustainLevel + 0.000001)) {
currentLevel = sustainLevel;
enterStage(ENVELOPE_STAGE_SUSTAIN);
Is there another cheaper way of calculating these types of infinite y=1/x^c decay curves? eg. Using recursive math?
I have no formal training in math or coding or DSP so I'm just trying to figure it out as I go and maybe I'm doing things in a really dumb way. I would very much appreciate any pointers or clarification if possible.
Thanks