DecibelsToGain LinearSmoothValue not working as expected

Still getting artifacts when changing the volume slider

prepareToplay() {
SMOOTHER.reset(sampleRate,1);
}
MIX = decibelsToGain(AudioParameterFloatVariable->get())
 SMOOTHER.setTargetValue(MIX);
            for(int i = 0; i < subBuffer.getNumSamples(); i++){
                const float m = SMOOTHER.getNextValue();
                ch1[i] = ch1[i] * m;
                ch2[i] = ch2[i] * m;
            }

It works with linear value 0-1 very well not sure why decibelsToGain throws it off

I dont think its a juce issue just how its calculated

What kinds of artifacts are you getting?

When/where do the artifacts appear? At the very start of playback, at the start of every buffer, when the parameter is changed, etc.

Note that you’re setting a ramp length of 1 second, which is very long.

It’s also a good idea to do setCurrentAndTargetValue() inside prepareToPlay() so that the smoother doesn’t need to ramp up to the initial parameter value.

Forgot to update but I was processing gain in two separate functions pre and post

Either way I changed the way I do decibels to have just a linear float value and it started working properly even with the mistake

In principle gain values are 0…1 and that’s what decibelsToGain returns. So you shouldn’t have any problem setting the smoother target to that and then using the result.

Smoothing in decibel values would definitely be a mistake prone to artefacts due to the logarithmic scaling of dB. Smoothing gain is correct.

You could use the multiplicative smoother for dB smoothing but I wouldn’t bother. Stick to 0…1

Maybe your AudioParameterFloat isn’t set up properly?

Also, setting the smoother ramp time to 1 seconds is a bit much unless you’re doing it on purpose for debugging. Typically a value of 0.05 or something around that is ok.

It would be a linear curve in decibels but an exponential curve in gain, which sounds more natural than a linear curve in gain. So doing a linear interpolation between decibel values isn’t wrong by itself.

Of course, smoothing should happen fast enough that you wouldn’t actually hear it.

The only place I could see this being a problem is if smoothing goes too fast. Then it might make large-ish jumps in gain the closer it becomes to 1.0. But a multiplicative smoother would do this too. I doubt this would be audible.

The main reason to avoid smoothing decibel values is that it isn’t very efficient since now you need to do decibelsToGain on every sample.

Sure. Having said that, the point of smoothing is to prevent large jumps which do cause artefacts. I’ve had them in level/gain controls and other values on an exponential such as filter cutoff.

If you’re smoothing in dB and converting to gain to use it, then the steps being taken in linear gain space are not the same due to the exponential curve… as you said. How natural it is doesn’t factor so in so much because you’re just wanting to get from one gain value to another without large jumps (which can cause artefacts depending how fast you turn the UI control).

Admittedly, OP shouldn’t be hearing any artefacts at all at a smooth rate of 1 second!

And, yes, it’s a bit moot anyway because smoothing in dB then converting to gain every sample is a waste of CPU.

1 Like

max is 12 decibels for instance
see how the skew is set thats how i set my defaults
then i just smooth the linear value 0-4 well 12 decibels is a little less than 4

    auto DB_ATTRIBUTES = juce::AudioParameterFloatAttributes().
    withStringFromValueFunction (
                                 [] (auto x, auto) {
                                     return juce::Decibels::toString (juce::Decibels::gainToDecibels(x));
                                 }
                                 ).
    withValueFromStringFunction(
                                [] (juce::String x) {
                                    
                                    auto decibelText = x.upToFirstOccurrenceOf ("dB", false, false).trim();    // [1]
                             
                                    return decibelText.equalsIgnoreCase ("-inf") ? juce::Decibels::decibelsToGain(-100.0f)
                                                                                 : juce::Decibels::decibelsToGain(decibelText.getDoubleValue());  // [2]
                                }
                                );
    
    
    auto DB_SKEW = juce::NormalisableRange<float>(0, juce::Decibels::decibelsToGain(12.0f), 0.001f);
    
    DB_SKEW.setSkewForCentre(juce::Decibels::decibelsToGain(-24.0f));