NormalisableRange lambdas versus Slider behavior


#1

We are porting old (VSTGUI) software to JUCE, and I have an issue with a slider that is supposed to use an exponential function to map between real-world values and the 0…1 range.

At first, we added a NormalisableRange for the parameter attached to the slider, and called setSkewForCenter() on it. That almost worked, but the curve that creates does not quite match the old exponential functions that the versions in the field use. We really would like those to match exactly, since users have saved session and preset data based on tweaking those knobs until they are just right.

So, instead of using setSkewForCenter(), I added lambdas that allowed me to call my own mapping functions. Those functions are getting called at some point, but when painting, the slider (rotary) doesn’t use those lambdas. Instead, it uses the valueToProportionOfLength() function to give us a value that tells us how far to turn the knob (by picking a specific image out of an array of knob images). So now the knob draws as if it were linearly mapped, instead of exponential.

What is the proper way to use my own exponential mapping for a slider’s range to the 0…1 range?

Could the issue somehow be that we’re using a derived class from Slider (to reverse its range via those valueToProportionOfLength() and proportionOfLengthToValue() functions)? Those call the base Slider class functions, subtracting from 1.0 as needed, but the Slider doesn’t see the lambda functions that the parameter it’s attached to defines in its NormalisableRange. I’m not sure how to get the two to talk to each other for this purpose.


#2

use NormalisableRange and its ctor that uses lambda

valueToProportionOfLength uses internally the NormalisableRange.


#3

Oh, you mean add the NormalisableRange to the Slider (as well as the parameter itself)? I can do that. Seems odd that the Slider doesn’t use the SliderAttachment to do use the parameter’s NormalisableRange, though.


#4

The slider does have its NormalisableRange set based on the parameter range you pass in:

Seems like your issue may be at line 456… If the interval or skew aren’t 0 it will ignore your range’s lambdas when assigning the slider range


#5

It appears NormalisableRange<float>::skew == 1 by default as well.

It should work out if you create the range with the constructor you were using and then set range.skew = 0 before creating your parameter


#6

Yes! That works. I set skew and interval to 0 after creating the range, and that works (without having to add a range to the Slider separately). Thanks!


#7

So you use the ctor with lambdas and it uses skew ?

The doc says:
If you have used lambda functions for convertFrom0to1Func and convertFrom0to1Func in the constructor of this class then the skew value is ignored.


#8

AudioProcessorValueTreeState::SliderAttachment impl is wrong then

This is a bug.


#9

reported on github


#10

@t0m If a range’s interval/skew are ignored when conversion lambdas are used shouldn’t they be set to zero when using this constructor? This way we can pass ranges directly to createAndAddParameter() without a range.skew = 0.0f first


#11

Sorry for the slow response to this - I’ve been on holiday for the past couple of weeks.

A skew of 1.0 is the default (which is the same as not having a skew), so that conditional is checking the wrong thing. I’ll fix that today.


#12

#13

Awesome, thanks Tom! :slight_smile: