Why does AudioParameterFloat::setValue use convertFrom0to1?

I set the AudioParameterFloat range -1 to 2.3
I set my GUI Slider range -1 to 2.3
I set the value of AudioParameter by getting the value of the slider when slider changes and the values do not match up.

How do I set the parameter value correctly?

You can use operator= (float):

myParameter = 2.2f;

Or move to AudioProcessorValueTreeState and SliderAttachment, that does all that for you!

  • The skew and interval is defined in the parameter only, making behaviour of the values in the host/automation display and your slider consistent
  • The SliderAttachment takes care of all updates between processor and slider and initial value
  • The attachment handles the beginGesture() and endGesture(), crucial when automation controls your plugin, otherwise the latch mode will battle each other
  • it even propagates the textToValue and valueToText conversion from the parameter to your slider textBox

What else do I need to know to build an audio plugin using the latest JUCE facilities?

Wish this info was in an up-to-date guide or tutorial!

I want to do this the JUCE-intended way after all.

This tutorial explains the AudioProcessorValueTreeState: https://docs.juce.com/master/tutorial_audio_processor_value_tree_state.html

With the addition, that the AudioParameterFloat has now a better constructor, allowing you to supply a NormalisedRange with all the features like skew and step:

AudioParameterFloat::AudioParameterFloat (
    const String &           parameterID,
    const String &           parameterName,
    NormalisableRange<float> normalisableRange,
    float                    defaultValue,
    const String &           parameterLabel = String(),
    Category                 parameterCategory = AudioProcessorParameter::genericParameter,
    std::function< String(float value, int maximumStringLength)> stringFromValue = nullptr,
    std::function< float(const String &text)>                    valueFromString = nullptr)
NormalisableRange<ValueType>::NormalisableRange (
    ValueType  rangeStart,
    ValueType  rangeEnd,
    ValueType  intervalValue,
    ValueType  skewFactor,
    bool       useSymmetricSkew = false 
)

Looking at the tutorial, confused how to use ParameterLayout and provide multiple types instead of just a single type of Int or Float

AudioProcessorValueTreeState::ParameterLayout createParameterLayout()
{
    std::vector<std::unique_ptr<AudioParameterInt>> params;
    for (int i = 1; i < 9; ++i)
        params.push_back (std::make_unique<AudioParameterInt> (String (i), String (i), 0, i, 0));
    return { params.begin(), params.end() };
}
YourAudioProcessor()
    : apvts (*this, &undoManager, "PARAMETERS", createParameterLayout())
{
}

oh

	AudioProcessorValueTreeState::ParameterLayout createParameterLayout()
	{
		return 
		{ 
			std::make_unique<AudioParameterFloat>("AmplitudeParameter", "Amplitude", -1.0, 2.3, 0.0) 
		};
	}

Can you add parameters after construction of AudioProcessorValueTreeState?

No, parameters can’t be added or removed.

You can build a std::vector<std::unique_ptr>. RangedAudioParameter ist the base class of AudioParameterInt, etc.

If you default-construct a ParameterLayout you can just call add on it in a loop, which allows you to avoid the temporary vector of unique_ptr. The constructor taking iterators is supplied as a convenience for working with STL containers, but if you’re not using STL containers already just calling add will be clearer and more concise.

2 Likes