NeuralAmpModelerPlugin

Plugin for Neural Amp Modeler
Log | Files | Refs | Submodules | README | LICENSE

commit 5d99c5ab534b3279e2a952a9301ac9136e468160
parent c6ae79fe2690fbae294823cada8a1a1320d8eb26
Author: Mike Oliphant <oliphant@nostatic.org>
Date:   Mon, 27 Mar 2023 16:24:56 -0700

Added floating point denormal disabling (#149)


Diffstat:
MNeuralAmpModeler/NeuralAmpModeler.cpp | 9+++++++++
ANeuralAmpModeler/architecture.hpp | 102+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 111 insertions(+), 0 deletions(-)

diff --git a/NeuralAmpModeler/NeuralAmpModeler.cpp b/NeuralAmpModeler/NeuralAmpModeler.cpp @@ -12,6 +12,7 @@ #include "NeuralAmpModeler.h" #include "IPlug_include_in_plug_src.h" // clang-format on +#include "architecture.hpp"; using namespace iplug; using namespace igraphics; @@ -530,6 +531,11 @@ void NeuralAmpModeler::ProcessBlock(iplug::sample **inputs, const size_t numFrames = (size_t)nFrames; const double sampleRate = this->GetSampleRate(); + // Disable floating point denormals + std::fenv_t fe_state; + std::feholdexcept(&fe_state); + disable_denormals(); + this->_PrepareBuffers(numChannelsInternal, numFrames); // Input is collapsed to mono in preparation for the NAM. this->_ProcessInput(inputs, numFrames, numChannelsExternalIn, @@ -621,6 +627,9 @@ void NeuralAmpModeler::ProcessBlock(iplug::sample **inputs, irPointers = this->mIR->Process(toneStackOutPointers, numChannelsInternal, numFrames); + // restore previous floating point state + std::feupdateenv(&fe_state); + // Let's get outta here // This is where we exit mono for whatever the output requires. this->_ProcessOutput(irPointers, outputs, numFrames, numChannelsInternal, diff --git a/NeuralAmpModeler/architecture.hpp b/NeuralAmpModeler/architecture.hpp @@ -0,0 +1,102 @@ +// From https://github.com/Dougal-s/Aether + +#ifndef ARCHITECTURE_HPP +#define ARCHITECTURE_HPP + +// check cpu architecture + +#if /* x86_64 */ \ + /* clang & gcc */ defined(__x86_64__) || \ + /* msvc */ defined(_M_AMD64) \ + + #define ARCH_X86 + #define ARCH_X86_64 + +#elif /* i386 */ \ + /* clang & gcc */ defined(__i386__) || \ + /* msvc */ defined(_M_IX86) \ + + #define ARCH_X86 + #define ARCH_I386 + +#elif /* Arm64 */ \ + /* clang & gcc */ defined(__aarch64__) || \ + /* msvc */ defined(_M_ARM64) \ + + #define ARCH_ARM + #define ARCH_ARM64 + +#elif /* Arm */ \ + /* clang & gcc */ defined(__arm__) || \ + /* msvc */ defined(_M_ARM) \ + + #define ARCH_ARM + #define ARCH_ARM32 + +#else + #define ARCH_UNKNOWN +#endif + + +// check cpu extensions + +/* clang & gcc */ +#ifdef __SSE__ + #define ARCH_EXT_SSE +#endif + +#ifdef __SSE2__ + #define ARCH_EXT_SSE2 +#endif + +#ifdef __SSE3__ + #define ARCH_EXT_SSE3 +#endif + +/* msvc */ +#if defined(ARCH_X86_64) + #define ARCH_EXT_SSE + #define ARCH_EXT_SSE2 + + // msvc doesn't seem to have anything for sse3 so I am just assuming + // it is supported + #define ARCH_EXT_SSE3 +#elif defined(ARCH_I386) + #if _M_IX86_FP > 0 + #define ARCH_EXT_SSE + #elif _M_IX86_FP > 1 + #define ARCH_EXT_SSE3 + #define ARCH_EXT_SSE2 + #define ARCH_EXT_SSE + #endif +#endif + + +// misc functions + +#ifdef ARCH_EXT_SSE + + #include <cfenv> + #ifndef FE_DFL_DISABLE_SSE_DENORMS_ENV + #include <immintrin.h> + #endif + +#endif + +inline void disable_denormals() noexcept { + + #if defined(ARCH_EXT_SSE) + #ifdef FE_DFL_DISABLE_SSE_DENORMS_ENV + std::fesetenv(FE_DFL_DISABLE_SSE_DENORMS_ENV); + #else + _mm_setcsr(_mm_getcsr() | 0x8040); + #endif + #elif defined(ARCH_ARM) + #if __has_builtin(__builtin_arm_set_fpscr) && __has_builtin(__builtin_arm_get_fpscr) + __builtin_arm_set_fpscr(__builtin_arm_get_fpscr() | (1 << 24)); + #endif + #endif + +} + +#endif