getRawParameterValue() not working with negative value - are limitations from the Editor slider.setRange() making it fail?

edit: If I set the range 6.0f to 18.0f in the parameter layout, the volumeValue shows correct debug value. Is this something to do with the range starting with a negative number (especially can mVolume.setRange() take a range starting from a negative number, and if not what’s a workaround for this?)

I have declared a parameter in my APVTS here

    layout.add(std::make_unique<juce::AudioParameterFloat>("mVolume", "Volume",
        juce::NormalisableRange<float>(-12.0f, 12.0f, 0.1f, 1.0f), 0.0f));

But when I try and get the volume, it only returns values in the range 0.0f to 1.0f. Why?

    float volumeValue = *apvts.getRawParameterValue("mVolume");
    DBG("Volume: " + juce::String(volumeValue));

Same thing happens if I use (apvts.getRawParameterValue("mVolume")->load());

In the non-GUI area in Ableton, it does show the range -12 to +12. But not in the DBG variable.

    //Volume SLIDER
    mVolume_slider.setTextBoxStyle(juce::Slider::NoTextBox, true, 40, 20);
    juce::NormalisableRange<double> logRangeVolume(-12.0, 12.0,
        [](double start, double end, double alpha) { return start * std::pow(end / start, alpha); },
        [](double start, double end, double value) { return std::log(value / start) / std::log(end / start); });
    mVolume_slider.setNormalisableRange(logRangeVolume); 
    mVolume_slider.setValue(audioProcessor.get_mVolume_value());
    mVolume_slider.setSliderStyle(juce::Slider::RotaryVerticalDrag);
    mVolume_slider.setTextValueSuffix(" dB");
    addAndMakeVisible(mVolume_slider);

You maybe shouldn’t be setting the slider’s range manually yourself, but instead use a parameter attachment. Alternatively, just set the Slider’s range to be a linear range from -12 to 12, like your actual parameter has it. I am not sure what you are trying to do with that pow and log stuff…?

std::log(value / start) / std::log(end / start)

With start == -12 and end == 12, you’re taking log of negatives. This kind of conversion only works for strictly positive ranges.

@xenakios @kamedin
I went with the log route because it gave me smooth slider animation.
But I also tried the normal linear setRange(-12,12,0.1); and that didn’t work either. Is there a recommended approach for ranges that are negative to positive?

There must be something wrong elsewhere in your code, there shouldn’t be any problem using negative values with the Sliders. How are you actually updating the parameter value from the slider?

Not sure what you mean with smooth animation. Maybe you were seeing jumps of interval size (0.1 in your case). If you don’t want that, you can set the interval to 0. I guess what you want is to have the value snapped to the interval, but the slider position to be continuous. By design that’s not possible -the slider position represents the actual value, with snapping included. The log scaling doesn’t fix that, it’s just that you didn’t include a snapToLegalValueFunc in your range constructor, so there’s no snapping.

The kind of log scaling you used makes sense for things like frequency, where you convert to a pitch ratio with log (f / min) / log (max / min), knowing that min will never reach zero. Volume in dB is already a log scale, and (-12,12) is a small, symmetric range -unless the particular use case requires it, I would leave it linear.

Also, as Xenakios said before, it’s a good idea to use attachments for this. Having different NormalisableRanges for the parameter and the slider is strange, especially if they have different skews -you’d have linear behavior in the DAW and log behavior in your UI.

sounds like you’re getting the normalized value out. there’s probably a step in your code that’s missing from what AudioProcessorValueTreeState::SliderAttachment does - i’d look at the juce_ParameterAttachment code (or maybe just use it instead?).

alternately, you could get the non-normalized value by doing something like:

slider.getNormalisableRange().convertFrom0to1(*apvts.getRawParameterValue("mVolume")); 
1 Like

I took out the setRange() from the slider declaration and let the parameter attachment just set the values as @xenakios mentioned earlier, and this seems to work now. :+1:

2 Likes