I need discrete stopping points on a knob

ok so, I am trying to update my plugin with what my client wants. he wants discrete stopping points on a certain knob but i’ve been looking on the forums and i can’t find how to do it. can someone help me out here?

Using an AudioParameterInt or AudioParameterChoice instead of an AudioParamerFloat will automatically give you discrete stopping points.

but I need it at a specific incriment of 0.1 from a range of -100 db to +60, would it still do that or do i need to define it

that or you just fix the display to only show one number after the floating point separator :slight_smile:

ok i tried this and it just showed a ton of errors

ok i think i got it… I just needed to change a decimal point

The Slider uses the NormalisableRange of the parameter.
When you setup the NormalisableRange you can also supply a step range, as well with a lambda to create programmatic legal positions to snap to.

The signature of the remap function is:

std::function<ValueType(ValueType rangeStart, ValueType rangeEnd, ValueType valueToRemap)>

auto snapToValue = [](float start, float end, float value)
{
    // do your logic here and return the snapped value
};

Note the decimal point probably only works visually, so the user can still dial in values that don’t snap

gotcha, thanks so much for the help

ok so im still having errors pop up: here’s my code:
juce::AudioProcessorValueTreeState::ParameterLayout OnlyGainsAudioProcessor::createParameterLayout()
{
APVTS::ParameterLayout layout;

// Define snapToValue function before using it
std::function<float(float, float, float)> snapToValue = [](float start, float end, float value)
{
    // Snap to increments of 0.1
    return std::round(value / 0.1f) * 0.1f;
};

using namespace juce;

layout.add(std::make_unique<AudioParameterFloat>(juce::ParameterID{ "Gain", 1 }, "Gain", NormalisableRange<float>(-100.0f, 60.0f, snapToValue), 0));

auto strFromValDb = [](float val, int)
{
    return juce::String(val, 2) + "Gain";
};

return layout;

}
and heres the errors:

The compiler tells you that it cannot find a constructor that matches the arguments you give to NormalisableRange. Indeed you only pass 3 arguments (float, float, ValueRemapFunction) and there’s no such constructor like this mentioned in the documentation…

What you want to use is this one as Daniel pointed out: JUCE: NormalisableRange< ValueType > Class Template Reference

I suppose you want to pass your snapToValue lambda as the 5th argument. The 3rd argument is also a lambda to describe how you convert from [0,1] (i.e. normalised values) to your expanded range (i.e. your -100dB to 60dB in your case). The 4th is the other way around (from [-100, 60] to [0,1]).

If you only need to set the slider/parameter’s sensitivity to 0.1 it is as easy as:

layout.add(std::make_unique<AudioParameterFloat>(juce::ParameterID{ "Gain", 1 }, "Gain", 
    NormalisableRange<float>(-100.0f, 60.0f, 0.1f), 0.0f));

I had a usecase in mind, where the interval changes, e.g. I used in an equalizer in 1 Hz up to 1kHz, then I switched to the interval of 0.01 kHz and so on…
But in that case you have to supply ALL mapping functions to satisfy the constructor:

juce::NormalisableRange<float> range(-100.0f, 60.0f,
    [](float start, float end, float value) { return juce::jmap (value, start, end); },
    [](float start, float end, float value) { return juce::jmap (value, start, end, 0.0f, 1.0f); },
    [](float start, float end, float value) { return juce::roundToInt (value * 10.0f) * 0.1f; });
layout.add(std::make_unique<AudioParameterFloat>(juce::ParameterID{ "Gain", 1 }, "Gain", range, 0.0f));

With the later approach you have tons of options

2 Likes