Newb - Whats the theory behind implementing an ADSR envelope to act on a Volume parameter - is my theory "efficient"?

Let’s say I want to have an ADSR envelope acting on a Volume parameter over time.

Whats the theory behind doing that in the best/most efficient way possible?

As a beginner, my thinking is to store the X,Y value of each point in the envelope and for every one sample I process, I would have those values act on the Volume (there will be many points between the start of Attack and the beginning of Decay of course - I just don’t know how many yet). As one sample is processed, I point to the next X,Y values in the array.

I know probing arrays is not going to give me the quickest code,… what way would you do it?
image

I calculate the slope of each segment.
Then I calculate the ‘increment per sample’. i.e. if the attack section ramps from 0.0 to 1.0 over 1 second, the ‘increment’ is 1 / samplerate.

then for each sample, all you need to do is add the increment to the current height, and check if you’ve reached (or overshot) the ‘target’ value (1.0).

This is very efficient (1 addition per sample).

2 Likes

@JeffMcClintock You use trig to calculate the slope… what happens if the slope is not linear but something like this, ease in, ease out:
image

ease-in ease-out can be considered a function of the linear value.
and it can be quite convenient to calculate the linear value first (as before) then use that to either lookup the magnitude of the curve in a table, or to calculate the curve directly using a polynomial or whatever.

I tend to use tables myself, they are a good general-purpose method. But it’s arguable in some cases that calculating the curve from a formula can consume less memory bandwidth than a lookup table. It depends on how complex the curve calculation is. (as is the usual advice - measure don’t assume).

3 Likes

Yes, I would recommend you have all slopes be in the 0-1 range. It makes a lot of things easier in the end. Linearly interpolate a small (256 value) table of these slopes:
[ADSR slope](https://Desmos slope demo)
You could use Juce’s own class for this: [JUCE: dsp::LookupTable< FloatType > Class Template Reference](https://Juce LUT)

1 Like

In case you’re looking for the typical formulas used for ease-in etc: https://easings.net

2 Likes

@DaveH @kerfuffle - thanks, those links are super helpful :+1:

To add to the easing function suggestion, you’re more than welcome to copy/paste anything from here into your code: squarepine_core/Easing.h at main · SquarePine/squarepine_core · GitHub

All functions I wrote in there are based around a 0 to 1 scale.

3 Likes

thanks @jrlanglois , much appreciated :+1:

Oooo that’s a nice slope thanks for sharing!