How do I smooth changes to an AudioParameterFloat's value?

I’m working on a VST3 plugin in which I use MIDI CC messages to change the values of AudioParameterFloats contained in an AudioProcessorValueTreeState. I am getting zippering effects as the parameters change and I am looking for advice on how to smooth out the transitions. Can the SmoothedValue class be used in some way, or does it only apply to audio buffers?

Also: Is it true that the range and skew factor settings of AudioParameterFloats cannot be modified while the plugin is running?

The juce smoothed value has a SampleRate input parameter in its initialise (or is is reset?) method.

My take is that as long as you “sample” regularly (i.e. you cal getNextValue regularly for example from a timer callback) you can use it in whatever context you want.

Anyway I’m afraid If you’re hearing strange noises in the audio output when changing parameters my guess is that you actually need to use a smoother in the audio output computation.

My guess:
Midi CC --> [some logic] --> float param --> [some DSP] --> audio output

If this is correct it makes more sense to me to smooth the float param as it is used in the DSP algo than smoothing the input Midi CC…

I should be more explicit about what my plugin (“CC Panel”) is doing. It doesn’t produce audio itself; I’m using it in Reaper to enhance changing parameters in other synth and FX plugins via a hardware controller. A parameter in CC Panel gets linked to a parameter in another plugin via Reaper’s “Link from MIDI or FX Parameter” function. It allows for much greater precision, nuance, and flexibility than is possible with Reaper’s “MIDI Learn” function. In addition, CC Panel’s GUI matches the layout of knobs, faders, and buttons on the hardware controller and has editable labels for each control, making it easier to keep track of which parameter in which plugin a hardware control is linked to.

My problem occurs when I use CC Panel to control a parameter like LPF Cutoff Frequency in a soft synth. Since changes to the CC panel parameter made via MIDI messages are discrete, there are audible jumps as it changes the filter frequency in the other plugin. Interestingly, if I change the CC Panel parameter via an attached slider in CC Panel’s GUI, there is no audible zippering in the other plugin’s filter sweep. This indicates that it is indeed possible to smooth the parameter change in some way.

I made a clumsy attempt at smoothing by using a for loop to subdivide parameter changes. It actually worked for a short time, but the plugin would crash Reaper after a few knob turns :woozy_face: Anyway, I’ll continue to study the SmoothedValue class. I think your suggestion to use getNextValue() with a timer will help me out here. Thanks @fefanto !

Take a look at this, you could apply smth similar at the output instead of directly translating the midi value to a certain frequency

This seems like an implementation problem in the synth itself. The synth is smoothing parameter changes which originate from it’s own GUI, but not ones from MIDI. Since you don’t have access to the instruments internal operation, I suspect you can not fix this yourself.

Note that changes to the parameter from the GUI are also discrete (only higher-resolution), so there is no technical reason not to smooth MIDI-parameter-changes as like GUI parameter-changes.

I came up with a method for doing this which is still rough, but at least proves that it’s possible: I added floats for targetValue and smoothedIncrement to my plugin processor’s member variables. When a CC message is received from the hardware knob, a new targetValue for the CC Panel parameter is calculated according to the range of the parameter in the target plugin and how fast the hardware knob is turned. The distance between targetValue and the current value of the parameter is divided by 10 and stored in smoothedIncrement. In each cycle of processBlock(), there is a check to see whether the parameter’s current value and targetValue are the same. If they are not, smoothedIncrement is added to or subtracted from the parameter value to move it closer to targetValue. If the distance between the values is less than smoothedIncrement, the parameter value is simply set to targetValue (otherwise the two values would never quite converge).

I’ve tried this out with several synth and FX plugins from different developers, targeting various frequency- and level-related parameters. I no longer get any zippering artifacts, the interaction between the hardware knob and the parameter “feels right,” and so far the method seems to be stable. However, it currently blocks changing a parameter using an attached slider in CC Panel’s GUI. I also need to add the option to turn smoothing on or off since it isn’t necessary for many parameters.

1 Like