AudioProcessorValueTreeState::Listener::parameterChanged - get previous value?

AudioProcessorValueTreeState::Listener::parameterChanged() gives us the newValue, but what is the best/correct way to get the previous value?

Well, the parameterChanged callback requires you to assign newValue to your internal data structures yourself, so the previous value should be intact until you overwrite it, right? You can do what you need to do before writing.

struct PRM
{
    bool changed(float v)
    {
        if(val == v)
            return false;
        val = v;
        return true;
    }

    float val;
};

you could just have this stateful little thing to represent your parameter values in processBlock. i would personally also add parameter smoothing functionality to it, while you’re at it

1 Like

Thanks, guys!

You might start getting warnings with that code, because you should not test float for equality for numerical reasons. Use juce::approximatelyEqual() instead:

    bool changed(float newValue)
    {
        if (juce::approximatelyEqual (newValue, value)) // you can set a tolerance here
            return false;

        value = newValue;
        return true;
    }

    float value = 0.0f;
2 Likes

Thank you, Daniel!

right. and that approxEqual branch should trigger snap to val. i’m used to this due to my lowpass-based parameter smoother

While the approximatelyEqual approach is useful for checking whether the change is large enough, if (val == v) is still a valid check to see whether the value actually changed or not. If this check returns false, v clearly is no longer the same as val, even if the difference is tiny.

What numerical reasons though? As others have said, this is a legitimate case for testing exact equality bacause you want to know if the value has changed at all.

It totally depends on your use case. Something what could happen is some accidental implicit cast to double and back…
But I think we are bikeshedding at that point.

If your comparing say a normalised value but somewhere along the line a conversion has taken place between real parameter values and normalised parameter values, this could be a possible source to introduce a difference such that the exact equality may not work as expected. That being said if you are sure in your case that you really need exact comparisons, or maybe you’re OK with the false positives in favour of saving a few cycles, then you can also use juce::exactlyEqual(), this will silence any warnings, and also communicate to your future self that you really meant to do exact equality comparisons.

1 Like

In this particular case the value would only change at, say, the host. If nothing was altering the parameter there then the value would be the same. In principle, exactly the same. But yes, in my code I’m using juce::exactlyEqual() to avoid the warning.