Pluginval can set an AudioParameterBools to odd values

I’m debugging a strange issue that sometimes leads to Pluginval’s state restoration test to fail. This is with an AU plugin, I’m not sure yet if it also happens with the VST3.

The test checks if the sum of parameter values is the same before and after a state restore. Under some circumstances, when the test starts, the two AudioParameterBools that the plugin uses have random values that are not 0.f or 1.f. After saving and restoring the state they are correctly set to either 0.f or 1.f, and thus the test fails because of the difference.

Whether the test fails depends mainly on which other tests have run before. There seem to be several tests that somehow manage to produce these odd parameter values.

Anyone ran into this problem before? I think it normally shouldn’t be possible at all to set AudioParameterBools to such odd values, especially from the outside.

This is on JUCE 6.1.6.

1 Like

Tracked the issue down further, and on develop it’s the same. AudioParameterBool can just be set to any float value. I’d propose the following change to fix it. That should somewhat guarantee non-surprising values for bool parameters.

diff --git a/modules/juce_audio_processors/utilities/juce_AudioParameterBool.cpp b/modules/juce_audio_processors/utilities/juce_AudioParameterBool.cpp
index 4ba512ddd..9d42b6ef7 100644
--- a/modules/juce_audio_processors/utilities/juce_AudioParameterBool.cpp
+++ b/modules/juce_audio_processors/utilities/juce_AudioParameterBool.cpp
@@ -77,7 +77,7 @@ AudioParameterBool::~AudioParameterBool()
 }
 
 float AudioParameterBool::getValue() const                               { return value; }
-void AudioParameterBool::setValue (float newValue)                       { value = newValue; valueChanged (get()); }
+void AudioParameterBool::setValue (float newValue)                       { value = newValue >= 0.5f; valueChanged (get()); }
 float AudioParameterBool::getDefaultValue() const                        { return defaultValue; }
 int AudioParameterBool::getNumSteps() const                              { return 2; }
 bool AudioParameterBool::isDiscrete() const                              { return true; }

Same issue here (JUCE 7.0.5), and a related topic as well: Basic AudioProcessorValueTreeState plugin won't pass PluginVal

As mentioned by @jacobweber, removing the guard clause from AudioProcessorValueTreeState::ParameterAdapter::setDenormalisedValue() also seems to do the trick (and perhaps is the better option?):

    void setDenormalisedValue (float value)
    {
        // if (value == unnormalisedValue)
        //    return;

        setNormalisedValue (normalise (value));
    }

I’ve yet to see a response from the JUCE team though :thinking:
Could there be any possible implications?

Thanks for reviving this. This has been lurking in my backlog for a while and is the only thing keeping me from enabling pluginval in my CI pipeline. Not sure though which fix would be the better option.

@dave96 mentions in the other thread that it might be required by auval that a parameter set to some odd value should return that odd value. But that feels like a weird requirement for any stepped parameter like bools or choices. For AudioParameterChoice I think there’s a similar logic like the one in my proposal to “snap” the normalized values to valid ones, IIRC.

it is unrealistic to assume that you can force the outside to put a parameter to integer values only, because parameters are just atomic floats on the inside, no matter what kinda wrapper juce invents over that. one of the major reasons why i’m a huge fan of not even using parameterBool and parameterChoice at all and instead using parameterFloat, but then come up with normalisableRanges that make it act steppy on the plugin gui

The AudioParameterBool and AudioParameterChoice are useful, and I would encourage anyone to use that consistent interface to access the parameters, so that normalising is never done through an independent code path that might create inconsistent behaviour.

The API has a consistent interface to set values and they are usually set to legitimate values. To allow random numbers was never the intention of the API creators, however it is sensible that the JUCE code should take care that the values are still valid in any case. Should be simple enough to be fixed, some possible fixes are already in this thread.

3 Likes