grame-cncm / faustlibraries

The Faust libraries
https://faustlibraries.grame.fr
183 stars 59 forks source link

add adsr_bias and ahdsr_bias #161

Closed DBraun closed 8 months ago

DBraun commented 9 months ago

This adds two new functions adsr_bias and ahdsr_bias.

Each function has three arguments to control the "bias" of the attack, decay, and release segments. This is implemented by using the derivative of a specific bias function: For every new sample of audio, we calculate a desired slope and add it to the state. Because this is a discrete method, the curves don't hit their target at the exact target time, but it's quite good. For example there are high errors if the bias is high in the decay or release (see graphs below).

This method is advantageous over https://github.com/grame-cncm/faustlibraries/pull/159 because the bias can bend the curve either up or down whereas that PR just allows pulling it up.

There is also a toggle for legato. If legato is on, then on re-trigger, the envelope is resumed wherever it left off. If legato is off, then the envelope always starts at zero.

Here are some images demonstrating usage of the functions. In the adsr_bias graphs, the settings are: attack: 1 decay: .5 sustain: varies release: 0.5 note length: varies

In the ahdsr_bias graphs, the settings are: attack: 0.5 decay: .5 sustain: varies release: 0.5 note length: varies Unknown-0 Unknown-1 Unknown-2 Unknown-3 Unknown-4 Unknown-5

sletz commented 9 months ago

I am a bit confused here: does this PR is a more general version of https://github.com/grame-cncm/faustlibraries/pull/159 and so replace it ?

DBraun commented 9 months ago

I think it's a more general version, and I would choose it over the other. The other has a different bias curve, but it also only biases in one direction. I have also implemented legato. So for those reasons I will probably find myself using adsr_bias and not adsrfqqq. If both sets of functions get added we can think harder about what the best names would be to distinguish them. Also, in the adsr_bias functions you can see how the bias parameter has a very smooth effect on the envelope. The colored lines in the graphs are nicely spaced from each other. But in the adsrfqqq functions the lines are more clumped together for low and high q values.

sletz commented 9 months ago

Then better keep a single version, OK for you @marchingband ?

marchingband commented 9 months ago

Oh wow this is awesome! It's ok with me 100%.
Legato is a great option.
Are you considering adding final?

DBraun commented 9 months ago

I’ll try that tonight. I will probably want a shortcut for a version without final however.

DBraun commented 9 months ago

The functions are now

FaustIDE Demo

DBraun commented 9 months ago

I kept finding issues with the initial values due to the final feature. I think it's ok now. I also changed it to these names:

Here's a demo.

sletz commented 9 months ago

"Error: URI Too Long" on the demo link

DBraun commented 9 months ago

Ah ok we'll have to copy paste from https://gist.github.com/DBraun/6b73b9b69300775f4eb68d2c5551d944

sletz commented 9 months ago

Is the PR considered ready to be merged ?

DBraun commented 9 months ago

The only thing I'm unsure about is the usage of it.remap.

pct = it.remap(from1, from2, 0, 1, y), 0.5 : select2(from1==from2) : bias_curve_inverse(b);

Is this sufficient to prevent a divide by zero? Or is more necessary such as

pct = it.remap(from1, from2+ba.if(from1==from2,1,0), 0, 1, y), 0.5 : select2(from1==from2) : bias_curve_inverse(b);
sletz commented 8 months ago

Thanks, merged.