It would be cool if, in addition to the linear and logarithmic smoothing, you could also switch a additional one pole filter in series, which smoothes the edges a little when a change occurs (maybe cutoff = 20Hz).
It’s not a problem to connect it in series with the existing classes, but because SmoothedValue is so nicely integrated into AudioBlock, it would be cool to add it as an option right in the class.
It also ensures that after reset()/setCurrentAndTargetValue() is called, there should be no ongoing change; setCurrentAndTargetValue() should set the current state and z1 of the one pole filter to the target value.
indeed! i’m also doing this in all of my plugins so far and i think it makes a real difference on some kinds of parameters. but i’m currently considering making that en/disable-ble, because most parameters seemed just fine with a more naiive smoothing lately. maybe this should be templated
IIRC, something to bear in mind with filter smoothing is that it’s not guaranteed to hit the target, just get very close. Which means in a naive implementation it’s never ‘done’.
This can be dealt with by snapping to the target if you detect that you’re close enough (say, within 1/1000). It can also help if you adjust the target internally so that you slightly overshoot the target and then clamp.
yes, very important. only if a parameter smoother can reach the destination you can implement performance optimisations for moments in which there is no smoothing
Thanks for the suggestions. Yes snapping to the target value makes sense.
Alternatively, the snap-on could take place after a second countdown (after the target was reached, before the one pole filter) , and not by the distance to the target.
This might be more reliable than using the distance (which can reach very small values, especially with logarithmic smoothing)
When not afraid of the math, it’s possible to calculate the number of steps required to reach the target value from a start value within a definable margin. If you quantize that up to buffer size, enabling/disabling smoothers and snapping to target when disabling can be done per block. Good for values that aren’t modulated continuously. This scheme can avoid lots of branches in the per-sample loop.