diff --git a/modules/juce_dsp/containers/juce_SIMDRegister.h b/modules/juce_dsp/containers/juce_SIMDRegister.h index 059f5c5bef..1eb4964a73 100644 --- a/modules/juce_dsp/containers/juce_SIMDRegister.h +++ b/modules/juce_dsp/containers/juce_SIMDRegister.h @@ -386,6 +386,14 @@ struct CmplxSIMDOps > } }; +//============================================================================== +#ifndef DOXYGEN + namespace util + { + template + inline void snapToZero (SIMDRegister&) noexcept {} + } +#endif //============================================================================== // Extend some common used global functions to SIMDRegister types diff --git a/modules/juce_dsp/juce_dsp.h b/modules/juce_dsp/juce_dsp.h index 5a2cc076a5..d0c803b128 100644 --- a/modules/juce_dsp/juce_dsp.h +++ b/modules/juce_dsp/juce_dsp.h @@ -177,6 +177,21 @@ namespace juce template using Complex = ::std::complex; + //============================================================================== + namespace util + { + /** Use this function to prevent denormals on intel CPUs. + + This function will work with both primitives and simple containers. + */ + inline void snapToZero (float& x) noexcept { JUCE_SNAP_TO_ZERO (x); } + #ifndef DOXYGEN + inline void snapToZero (double& x) noexcept { JUCE_SNAP_TO_ZERO (x); } + inline void snapToZero (long double& x) noexcept { JUCE_SNAP_TO_ZERO (x); } + #endif + } + + //============================================================================== #if JUCE_USE_SIMD #include "native/juce_fallback_SIMDNativeOps.h" diff --git a/modules/juce_dsp/processors/juce_IIRFilter_Impl.h b/modules/juce_dsp/processors/juce_IIRFilter_Impl.h index cb31cbdf13..c096f5d114 100644 --- a/modules/juce_dsp/processors/juce_IIRFilter_Impl.h +++ b/modules/juce_dsp/processors/juce_IIRFilter_Impl.h @@ -26,25 +26,6 @@ #ifndef DOXYGEN -template -struct SnapToZeroHelper -{ - static void snap (Type& x) noexcept - { - for (size_t i = 0; i < Type::size(); ++i) - JUCE_SNAP_TO_ZERO (x[i]); - } -}; - -template <> struct SnapToZeroHelper { static void snap (float& x) noexcept { JUCE_SNAP_TO_ZERO (x); } }; -template <> struct SnapToZeroHelper { static void snap (double& x) noexcept { JUCE_SNAP_TO_ZERO (x); } }; -template <> struct SnapToZeroHelper { static void snap (long double& x) noexcept { JUCE_SNAP_TO_ZERO (x); } }; - -#if JUCE_USE_SIMD -template -struct SnapToZeroHelper> { static void snap (SIMDRegister&) noexcept {} }; -#endif - //============================================================================== template Filter::Filter() @@ -120,7 +101,7 @@ void Filter::process (const ProcessContext& context) noexcept lv1 = (in * b1) - (out * a1); } - SnapToZeroHelper::snap (lv1); state[0] = lv1; + util::snapToZero (lv1); state[0] = lv1; } break; @@ -145,8 +126,8 @@ void Filter::process (const ProcessContext& context) noexcept lv2 = (in * b2) - (out * a2); } - SnapToZeroHelper::snap (lv1); state[0] = lv1; - SnapToZeroHelper::snap (lv2); state[1] = lv2; + util::snapToZero (lv1); state[0] = lv1; + util::snapToZero (lv2); state[1] = lv2; } break; @@ -175,9 +156,9 @@ void Filter::process (const ProcessContext& context) noexcept lv3 = (in * b3) - (out * a3); } - SnapToZeroHelper::snap (lv1); state[0] = lv1; - SnapToZeroHelper::snap (lv2); state[1] = lv2; - SnapToZeroHelper::snap (lv3); state[2] = lv3; + util::snapToZero (lv1); state[0] = lv1; + util::snapToZero (lv2); state[1] = lv2; + util::snapToZero (lv3); state[2] = lv3; } break; @@ -220,7 +201,7 @@ template void Filter::snapToZero() noexcept { for (size_t i = 0; i < order; ++i) - SnapToZeroHelper::snap (state[i]); + util::snapToZero (state[i]); } template diff --git a/modules/juce_dsp/processors/juce_StateVariableFilter.h b/modules/juce_dsp/processors/juce_StateVariableFilter.h index 98d3d4750b..437f6995cf 100644 --- a/modules/juce_dsp/processors/juce_StateVariableFilter.h +++ b/modules/juce_dsp/processors/juce_StateVariableFilter.h @@ -141,6 +141,9 @@ namespace StateVariableFilter for (size_t i = 0 ; i < n; ++i) output[i] = processLoop (input[i], state); + util::snapToZero (s1); + util::snapToZero (s2); + *parameters = state; }