diff --git a/examples/DSP module plugin demo/DSP module plugin demo.jucer b/examples/DSP module plugin demo/DSP module plugin demo.jucer
index 67e37a1318..839660664f 100644
--- a/examples/DSP module plugin demo/DSP module plugin demo.jucer
+++ b/examples/DSP module plugin demo/DSP module plugin demo.jucer
@@ -125,5 +125,5 @@
-
+
diff --git a/examples/DSP module plugin demo/JuceLibraryCode/AppConfig.h b/examples/DSP module plugin demo/JuceLibraryCode/AppConfig.h
index 69c1fbf2cb..31d8d119c3 100644
--- a/examples/DSP module plugin demo/JuceLibraryCode/AppConfig.h
+++ b/examples/DSP module plugin demo/JuceLibraryCode/AppConfig.h
@@ -130,6 +130,10 @@
//#define JUCE_FORCE_USE_LEGACY_PARAM_IDS 1
#endif
+#ifndef JUCE_FORCE_LEGACY_PARAMETER_AUTOMATION_TYPE
+ //#define JUCE_FORCE_LEGACY_PARAMETER_AUTOMATION_TYPE 1
+#endif
+
#ifndef JUCE_USE_STUDIO_ONE_COMPATIBLE_PARAMETERS
//#define JUCE_USE_STUDIO_ONE_COMPATIBLE_PARAMETERS 1
#endif
@@ -214,6 +218,10 @@
//#define JUCE_DSP_USE_STATIC_FFTW 1
#endif
+#ifndef JUCE_DSP_ENABLE_SNAP_TO_ZERO
+ #define JUCE_DSP_ENABLE_SNAP_TO_ZERO 0
+#endif
+
//==============================================================================
// juce_events flags:
diff --git a/examples/DSP module plugin demo/Source/PluginProcessor.cpp b/examples/DSP module plugin demo/Source/PluginProcessor.cpp
index 8e9ac479ac..389776a3c8 100644
--- a/examples/DSP module plugin demo/Source/PluginProcessor.cpp
+++ b/examples/DSP module plugin demo/Source/PluginProcessor.cpp
@@ -114,6 +114,8 @@ void DspModulePluginDemoAudioProcessor::releaseResources()
void DspModulePluginDemoAudioProcessor::process (dsp::ProcessContextReplacing context) noexcept
{
+ ScopedNoDenormals noDenormals;
+
// Input volume applied with a LinearSmoothedValue
inputVolume.process (context);
diff --git a/extras/Projucer/JuceLibraryCode/BinaryData.cpp b/extras/Projucer/JuceLibraryCode/BinaryData.cpp
index ab7a9dda7e..543a94bc05 100644
--- a/extras/Projucer/JuceLibraryCode/BinaryData.cpp
+++ b/extras/Projucer/JuceLibraryCode/BinaryData.cpp
@@ -1617,6 +1617,7 @@ static const unsigned char temp_binary_data_8[] =
"\r\n"
"void FILTERCLASSNAME::processBlock (AudioSampleBuffer& buffer, MidiBuffer& midiMessages)\r\n"
"{\r\n"
+" ScopedNoDenormals noDenormals;\r\n"
" const int totalNumInputChannels = getTotalNumInputChannels();\r\n"
" const int totalNumOutputChannels = getTotalNumOutputChannels();\r\n"
"\r\n"
@@ -7028,7 +7029,7 @@ const char* getNamedResource (const char* resourceNameUTF8, int& numBytes) throw
case 0xafccbd3f: numBytes = 3141; return jucer_AudioComponentTemplate_cpp;
case 0x27c5a93a: numBytes = 1310; return jucer_AudioPluginEditorTemplate_cpp;
case 0x4d0721bf: numBytes = 938; return jucer_AudioPluginEditorTemplate_h;
- case 0x51b49ac5: numBytes = 5611; return jucer_AudioPluginFilterTemplate_cpp;
+ case 0x51b49ac5: numBytes = 5647; return jucer_AudioPluginFilterTemplate_cpp;
case 0x488afa0a: numBytes = 2245; return jucer_AudioPluginFilterTemplate_h;
case 0xabad7041: numBytes = 2151; return jucer_ComponentTemplate_cpp;
case 0xfc72fe86: numBytes = 2064; return jucer_ComponentTemplate_h;
diff --git a/extras/Projucer/JuceLibraryCode/BinaryData.h b/extras/Projucer/JuceLibraryCode/BinaryData.h
index 1ad41adb5c..798ca25825 100644
--- a/extras/Projucer/JuceLibraryCode/BinaryData.h
+++ b/extras/Projucer/JuceLibraryCode/BinaryData.h
@@ -33,7 +33,7 @@ namespace BinaryData
const int jucer_AudioPluginEditorTemplate_hSize = 938;
extern const char* jucer_AudioPluginFilterTemplate_cpp;
- const int jucer_AudioPluginFilterTemplate_cppSize = 5611;
+ const int jucer_AudioPluginFilterTemplate_cppSize = 5647;
extern const char* jucer_AudioPluginFilterTemplate_h;
const int jucer_AudioPluginFilterTemplate_hSize = 2245;
diff --git a/extras/Projucer/Source/BinaryData/jucer_AudioPluginFilterTemplate.cpp b/extras/Projucer/Source/BinaryData/jucer_AudioPluginFilterTemplate.cpp
index 64b036e975..bec4e61204 100644
--- a/extras/Projucer/Source/BinaryData/jucer_AudioPluginFilterTemplate.cpp
+++ b/extras/Projucer/Source/BinaryData/jucer_AudioPluginFilterTemplate.cpp
@@ -131,6 +131,7 @@ bool FILTERCLASSNAME::isBusesLayoutSupported (const BusesLayout& layouts) const
void FILTERCLASSNAME::processBlock (AudioSampleBuffer& buffer, MidiBuffer& midiMessages)
{
+ ScopedNoDenormals noDenormals;
const int totalNumInputChannels = getTotalNumInputChannels();
const int totalNumOutputChannels = getTotalNumOutputChannels();
diff --git a/modules/juce_audio_basics/buffers/juce_FloatVectorOperations.h b/modules/juce_audio_basics/buffers/juce_FloatVectorOperations.h
index 708f5ac2aa..c44bbd800f 100644
--- a/modules/juce_audio_basics/buffers/juce_FloatVectorOperations.h
+++ b/modules/juce_audio_basics/buffers/juce_FloatVectorOperations.h
@@ -221,4 +221,34 @@ public:
static void JUCE_CALLTYPE disableDenormalisedNumberSupport() noexcept;
};
+//==============================================================================
+/**
+ Helper class providing an RAII-based mechanism for temporarily disabling
+ denormals on your CPU.
+*/
+class ScopedNoDenormals
+{
+public:
+ inline ScopedNoDenormals() noexcept
+ {
+ #if JUCE_USE_SSE_INTRINSICS
+ mxcsr = _mm_getcsr();
+ _mm_setcsr (mxcsr | 0x8040); // add the DAZ and FZ bits
+ #endif
+ }
+
+
+ inline ~ScopedNoDenormals() noexcept
+ {
+ #if JUCE_USE_SSE_INTRINSICS
+ _mm_setcsr (mxcsr);
+ #endif
+ }
+
+private:
+ #if JUCE_USE_SSE_INTRINSICS
+ unsigned int mxcsr;
+ #endif
+};
+
} // namespace juce
diff --git a/modules/juce_audio_basics/juce_audio_basics.h b/modules/juce_audio_basics/juce_audio_basics.h
index 023fa4760b..a6c7b85f1e 100644
--- a/modules/juce_audio_basics/juce_audio_basics.h
+++ b/modules/juce_audio_basics/juce_audio_basics.h
@@ -51,6 +51,7 @@
#include
+//==============================================================================
#undef Complex // apparently some C libraries actually define these symbols (!)
#undef Factor
diff --git a/modules/juce_dsp/juce_dsp.h b/modules/juce_dsp/juce_dsp.h
index 4566489153..c700684cae 100644
--- a/modules/juce_dsp/juce_dsp.h
+++ b/modules/juce_dsp/juce_dsp.h
@@ -166,6 +166,23 @@
#define JUCE_DSP_USE_STATIC_FFTW 0
#endif
+/** Config: JUCE_DSP_ENABLE_SNAP_TO_ZERO
+
+ Enables code in the dsp module to avoid floating point denormals during the
+ processing of some of the dsp module's filters.
+
+ Enabling this will add a slight performance overhead to the DSP module's
+ filters and algorithms. If your audio app already disables denormals altogether
+ (for exmaple, by using the ScopedNoDenormals class or the
+ FloatVectorOperations::disableDenormalisedNumberSupport method), then you
+ can safely disable this flag to shave off a few cpu cycles from the DSP module's
+ filters and algorithms.
+*/
+#ifndef JUCE_DSP_ENABLE_SNAP_TO_ZERO
+ #define JUCE_DSP_ENABLE_SNAP_TO_ZERO 1
+#endif
+
+
//==============================================================================
#undef Complex // apparently some C libraries actually define these symbols (!)
#undef Factor
@@ -185,11 +202,19 @@ namespace juce
This function will work with both primitives and simple containers.
*/
+ #if JUCE_DSP_ENABLE_SNAP_TO_ZERO
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
+ #else
+ inline void snapToZero (float& x) noexcept { ignoreUnused (x); }
+ #ifndef DOXYGEN
+ inline void snapToZero (double& x) noexcept { ignoreUnused (x); }
+ inline void snapToZero (long double& x) noexcept { ignoreUnused (x); }
+ #endif
+ #endif
}
}
}
diff --git a/modules/juce_dsp/processors/juce_Oversampling.cpp b/modules/juce_dsp/processors/juce_Oversampling.cpp
index c039f484b3..2ce6ea6cb9 100644
--- a/modules/juce_dsp/processors/juce_Oversampling.cpp
+++ b/modules/juce_dsp/processors/juce_Oversampling.cpp
@@ -444,7 +444,7 @@ public:
auto numStages = coefficientsUp.size();
for (auto n = 0; n < numStages; n++)
- JUCE_SNAP_TO_ZERO (lv1[n]);
+ util::snapToZero (lv1[n]);
}
}
else
@@ -455,7 +455,7 @@ public:
auto numStages = coefficientsDown.size();
for (auto n = 0; n < numStages; n++)
- JUCE_SNAP_TO_ZERO (lv1[n]);
+ util::snapToZero (lv1[n]);
}
}
}