FR + Patch: Allow apply smoothing of AudioBlocks with different sampleTypes

When using long fades with juce::SmoothedValue, it is necessary to use double coefficients, so that the fade is precise enough in the end.

Currently the AudioBlock functions like replaceWithProductOf only allow smoothers which use the same type as the AudioBlock.

It is super easy to extend the AudioBlock-classes to allow smoothers with different types, by just adding a template parameter SmoothingSampleType, and a few casts. Here is a example replace for replaceWithProductOf

diff --git a/modules/juce_dsp/containers/juce_AudioBlock.h b/modules/juce_dsp/containers/juce_AudioBlock.h
index 35cdaa159..abe4cd986 100644
--- a/modules/juce_dsp/containers/juce_AudioBlock.h
+++ b/modules/juce_dsp/containers/juce_AudioBlock.h
@@ -465,8 +465,8 @@ public:
     /** Replaces each channel of this block with the product of the src block and a smoothed value. */
     template <typename OtherSampleType, typename SmoothingType>
     AudioBlock&       replaceWithProductOf (AudioBlock<OtherSampleType> src, SmoothedValue<SampleType, SmoothingType>& value)       noexcept   { replaceWithProductOfInternal (src, value); return *this; }
-    template <typename OtherSampleType, typename SmoothingType>
-    const AudioBlock& replaceWithProductOf (AudioBlock<OtherSampleType> src, SmoothedValue<SampleType, SmoothingType>& value) const noexcept   { replaceWithProductOfInternal (src, value); return *this; }
+    template <typename OtherSampleType, typename SmoothingType, typename SmoothingSampleType>
+    const AudioBlock& replaceWithProductOf (AudioBlock<OtherSampleType> src, SmoothedValue<SmoothingSampleType, SmoothingType>& value) const noexcept   { replaceWithProductOfInternal (src, value); return *this; }
 
     //==============================================================================
     /** Multiplies each value in src by a fixed value and adds the result to this block. */
@@ -775,14 +775,14 @@ private:
         }
     }
 
-    template <typename OtherSampleType, typename SmoothingType>
-    void replaceWithProductOfInternal (AudioBlock<OtherSampleType> src, SmoothedValue<SampleType, SmoothingType>& value) const noexcept
+    template <typename OtherSampleType, typename SmoothingType, typename SmoothingSampleType>
+    void replaceWithProductOfInternal (AudioBlock<OtherSampleType> src, SmoothedValue<SmoothingSampleType, SmoothingType>& value) const noexcept
     {
         jassert (numChannels == src.numChannels);
 
         if (! value.isSmoothing())
         {
-            replaceWithProductOfInternal (src, value.getTargetValue());
+            replaceWithProductOfInternal (src, OtherSampleType(value.getTargetValue()));
         }
         else
         {
@@ -790,7 +790,7 @@ private:
 
             for (size_t i = 0; i < n; ++i)
             {
-                const auto scaler = value.getNextValue();
+                const auto scaler = OtherSampleType( value.getNextValue() );
 
                 for (size_t ch = 0; ch < numChannels; ++ch)
                     getDataPointer (ch)[i] = scaler * src.getChannelPointer (ch)[i];
1 Like

I created a pull request for this feature (currently only for the method where I need that)