Breaking change in JUCE Develop: approximatelyEqual

We’ve got some code that no longer builds…it used to be possible to use JUCE SmoothedValue with a SIMDRegister value.

juce_MathsFunctions.h:96:15: error: no matching function for call to 'abs'
           || std::abs (a - b) < std::numeric_limits<Type>::min();
              ^~~~~~~~
juce_SmoothedValue.h:274:13: note: in instantiation of function template specialization 'juce::approximatelyEqual<juce::dsp::SIMDRegister<float>>' requested here
        if (approximatelyEqual (newValue, this->target))
            ^
note: in instantiation of member function 'juce::SmoothedValue<juce::dsp::SIMDRegister<float>>::setTargetValue' requested here
    envelopeFollowerLimit.setTargetValue (getEnvelopeFollowerLimit());
                          ^```

You don’t never need approximatelyEqual there though?

Your code is:

      if (approximatelyEqual (newValue, this->target))
            return;

But you’ve surely just set it to exactly the target value here:

        if (this->isSmoothing())
            setNextValue();
        else
            this->currentValue = this->target;

So I think your previous simpler code was probably fine?

I think it will only become exactly the target value when there is no smoothing. That being said we may be able to remove the use of approximatelyEqual.

Unfortunately after having a little little look at this, even without those changes, I’m struggling to get a SIMDRegister value to work with a SmoothedValue. Could you maybe share a simple example of something that compiles for you and let me know the version of JUCE that you’re using?

it becomes the target value exactly when the counter reaches zero I think.

We’ve got

     using QuadFloat = dsp::SIMDRegister<float>;


    SmoothedValue<QuadFloat> inputGainSmoothed{};

Ah found this that we had to add:

 #ifdef JUCE_MAC
 25 /**
 26  * So a linear smoothed quadfloat builds on the Mac.  Unclear why this isn't also needed in VS2019.
 27  */
 28 template <>
 29 template <>
 30 inline void SmoothedValue<dsp::SIMDRegister<float>, ValueSmoothingTypes::Linear>::setStepSize() noexcept
 31 {
 32     this->step = (this->target - this->currentValue) * FloatType (1.0f / this->countdown);
 33 }
 34 #endif

We are on JUCE commit e49fb38d4.

OK great that’s exactly where I was hitting an issue too.

As it calculates a step value and adds that on each time in setNextValue() there’s a chance that adding the step N times to the current value will not be exactly the same as the target value. So I think the check tries to avoid creating any steps when the new target value is practically the same as the old one.

I’ll see if I can push some changes that effectively bypass this check for SIMD types, and I’ll also see if I can drop that change into setStepSize while I’m at it.

FYI - two of our plugins no longer build with the latest release of JUCE because of this issue which is pretty frustrating.

Did you think it was fixed on master? We still don’t think you need to use approximatelyEqual at all in SmoothedValue and so this change just breaks stuff and burns a few extra CPU cycles for no benefit.

cheers!

FYI approximatelyEqual also breaks Line<ValueType>::findIntersection - it won’t compile where ValueType isn’t float, because approximatelyEqual is called with a second argument of 0.0f rather than ValueType(0)

This is with Juce 7.0.6, d24c2729268e322f3ba1b5070eb96ab232d7f6ba

1 Like

There are a number of things in the pipeline to help here.

  1. I’ve removed the call to approximatelyEqual in SmoothedValue
  2. I’ve added division to the SIMD types, this should avoid the need for @jimc to add the extra code above.
  3. I have some incoming changes to approximatelyEqual which include it performing a compile time check if the type is floating point, if it’s not it just passes the call to the normal equality operator.

I’ll chase these up and see where we’re at in terms of getting them merged.

@domsmart thanks for reporting I’m sure I can get a fix pushed for that too.

5 Likes

Thank you!