Parameter Display from 0 to 1


#1

Hi,

I am very new to JUCE and C++ in general. I am in the process of making a plugin and have overrided the AudioParameterFloat class so that the values are not normalized between 0 and 1. However, if I open Bitwig or Logic and see the parameter display (outside of the plugin GUI) the (parameter display) slider defaults between 0 and 1. If I change the value of the sliders in the GUI (not logic or bitwig sliders) such that the value is greater than 1 the text value on the parameter slider follows accordingly but the slider stops moving after 1. The text value however keeps increasing above 1 but the slider is at full after the text reaches 1. So essentially I would like it so that Logic and Bitwig default between the proper values such that the DAW parameter slider outside of my plugin correctly correspond to those inside my Plugin GUI.

I hope this is not too confusing since I am talking about two different sliders (those inside the plugin and those in the DAW controls).

I have attached some images of my problem.



Thank You!


#2

Hi,

When Plugin-Parameters are transferred from/to the Host, the values always need to be normalized in the range [0…1] . So there needs to be conversion from the 0…1 representation the Host uses and the value that is displayed to the user. If you don’t want to go mad with parameter-range-conversion, I highly recommend using the AudioProcessorValueTreeState Class.

Just create an instance as a member in your processor and call

preDelay = state.createAndAddParameter("pre-delay", "pre-delay", "pre-delay", NormalisableRange<float>(0.0f, 500.0f), 0.0f,
    [](float v)         -> String { return String(v, 2) + " ms"; },
    [](const String& s) -> float  { return s.getFloatValue(); }
);

for all your parameters.

Then you can easily load/save your state:

void MyAudioProcessor::getStateInformation (MemoryBlock& destData)
{
    MemoryOutputStream mos(destData, false);
    state.state.writeToStream(mos);
}

void MyAudioProcessor::setStateInformation (const void* data, int sizeInBytes)
{
    MemoryInputStream mis(data, sizeInBytes, false);
    state.state = ValueTree::readFromStream(mis);
}

Also in your PluginEditor you can attach sliders to the parameters like so:

sliderAttachments.add(new AudioProcessorValueTreeState::SliderAttachment(filter->state, "pre-delay", *pre_delay));

Note: sliderAttachments is a OwnedArrayAudioProcessorValueTreeState::SliderAttachment member of the editor and pre_delay is a Slider.

The neat thing is, that when you create a parameter via createAndAddParameter() you can provide a skewFactor, this way your logarithmic dB values can be properly automated with the same logarithmicality as your sliders :slight_smile:

Best,
Ben


#3

Thanks pixelpacker,

I figured out a workaround by setting my GUI slider range from 0 to 1 and then changing the range in the parameters. This ends up changing the GUI slider range aswell.

I hope this is an acceptable method

I know this isn’t the way you said but I already have the Slider and parameters in place. It was the slider range * the parameter range that caused the issue, not the normalization. There is probably a better way to do this. I am still learning


#4

I have an own parameter class “DSPParameter” derived from AudioProcessorParameter and when I initialise a parameter I make sure I have all these values:

// UI param values (not 0 - 1 range)
float minValue;
float maxValue;
int   resolution;
float initValue;

// DSP param values (0 - 1 range)
float currentValue;
float defaultValue; // equals the init value but in DSP range (0 - 1)

And on top of that two functions:

float currentUIValue();
float calculateDSPValue(float uiValue);

They are implemented like this:

float DSPParameter::currentUIValue()
{
  return currentValue * (maxValue - minValue) + minValue;
}


float DSPParameter::calculateDSPValue(float uiValue)
{
  return (maxValue > minValue) ? (uiValue - minValue) / (maxValue - minValue) : 0.0f;
}

Now you just have to make sure that you use the UI values like min, max and resolution for range when initialising controls.
When updating UI from DSP, use control->setValue(param->currentUIValue()) and param->calculateDSPValue(control->getValue()) when updating DSP from UI.

Hope this helps.