[BUG] AudioProcessorValueTreeState parameter is NaN on load when out of range


#1

I’m loading parameter state using ValueTree::fromXml(). The range of a given parameter_used_ to be 0 - 1 but changed to 0.001 - 1. Because said parameter is stored as 0, the load turns it into a NaN. All sorts of problems arise with slider attachments and more.

Is it an idea a parameter makes a choice by either clipping within the range (preferred) or changing to default? I don’t think NaN is the way to go.

Obviously, the range shouldn’t change and have been decided on from the get-go, but reality says so otherwise and our client wouldn’t want to throw away all their old presets.


#2

Hi there! Can’t imagine we’re the only ones that have had this problem. Is there a possibility anyone could address this issue?


#3

@t0m has been looking at the parameters recently and he’ll be back from holidays next week.


#4

Perfect, thanks! :slight_smile:


#5

At what point is the value turned into a NaN? I’m not able to trigger the same behaviour. Can you step through in a debugger to pinpoint the place?


#6

Found it! Alright, so here’s the deal:

  • The problem surfaces at the jassert on line juce_Slider.cpp:1144. sliderPos is Nan, and so is lastCurrentValue before that.
  • This happens because Slider::setValue() is called with a NaN at juce_AudioProcessorValueTreeState.cpp:501, which comes all the way from juce_AudioProcessorValueTreeState.cpp:109.
  • The culprit is the range.convertTo0to1(newUnnormalisedValue) line above that. It takes a 0 and spits out NaN for this particular param.

The parameter in question has a range of 0.001 - 10, and a skew of 0.5. Because that 0 falls outside the range, proportion in convertTo0to1() gets a value of approx. -0.0001. The damage is done on juce_NormalisableRange.h:154, where a pow of a negative is taken with exponent 0.5, resulting in a NaN.


#7

As well as asserting we now also clamp the normalised values.


#8

Great! Thanks!


#9

Wait, now we assert on juce_NormalisableRange.h:257. Obviously, clampedValue != value, otherwise we shouldn’t have to clamp in the first place.

It’s clamping that -0.001 and asserting that it’s 0.

Commenting out that jassert fixes all issues we encounted with loading parameter state, btw.


#10

Yes, the assertion is deliberate. If you have to clamp then the most likely cause is that something has gone wrong with one of your algorithms, and developers will want to know when this happens (rather than silently “fixing” the problem in the background). In your case it’s not an algorithm misfiring, but it’s still good to find out that parameter values are being modified.

Remember that jasserts are not included in release builds, and you can continue past this one safely when debugging.


#11

Hmmm, I see where you’re coming from. Though as a developer I’d rather have that opt-in that opt-out. Having to continue my debugger every time I load an “old” preset will get tiresome rather quick. But again, I do see your point, silently adjusting values is perhaps even worse. And most of all, thanks for fixing this :slight_smile: