commit 9af3571d2cec79cde6a1473c9e5576518365ede7
parent b07eba0758bc76cfaee77f94cf4213f83a70d46d
Author: jatinchowdhury18 <jatinchowdhury18@gmail.com>
Date: Sun, 15 May 2022 23:41:16 +0100
Rough (but working) accessibility support (#263)
* Rough (but working) accessibility support
* Update chowdsp submodule
* Apply clang-format
* Try to fix unit test with compiler error
* Fix ARM compilation error
* Try again to fix ARM compilation error
* Update submodule
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Diffstat:
6 files changed, 78 insertions(+), 26 deletions(-)
diff --git a/Plugin/Source/Headless/UnitTests/HysteresisOpsTest.cpp b/Plugin/Source/Headless/UnitTests/HysteresisOpsTest.cpp
@@ -40,7 +40,7 @@ public:
#if HYSTERESIS_USE_SIMD
auto testFunc = [=] (Vec2 H_d, Vec2 M_diff, Vec2 nc, double kap1_exp, double f1_exp) {
const auto delta = ((Vec2) 1.0 & Vec2::greaterThanOrEqual (H_d, (Vec2) 0.0)) - ((Vec2) 1.0 & Vec2::lessThan (H_d, (Vec2) 0.0));
- const auto delta_M = Vec2::equal (chowdsp::signumSIMD (delta), chowdsp::signumSIMD (M_diff));
+ const auto delta_M = Vec2::equal (HysteresisOps::signumSIMD (delta), HysteresisOps::signumSIMD (M_diff));
auto kap1 = (Vec2) nc & delta_M;
auto f1 = (Vec2) nc * delta;
diff --git a/Plugin/Source/Processors/Chew/Dropout.h b/Plugin/Source/Processors/Chew/Dropout.h
@@ -49,7 +49,7 @@ public:
inline float dropout (float x, size_t ch)
{
- auto sign = (float) chowdsp::signum (x);
+ auto sign = (float) chowdsp::sign (x);
return pow (abs (x), powerSmooth[ch].getNextValue()) * sign;
}
diff --git a/Plugin/Source/Processors/Compression/CompressionProcessor.cpp b/Plugin/Source/Processors/Compression/CompressionProcessor.cpp
@@ -49,26 +49,18 @@ void CompressionProcessor::prepare (double sr, int samplesPerBlock, int numChann
compGainVec.resize (osFactor * (size_t) samplesPerBlock, 0.0f);
}
-inline float compressionDB (float xDB, float dbPlus)
-{
- auto window = 2.0f * dbPlus;
-
- if (dbPlus <= 0.0f || xDB < -window)
- return dbPlus;
-
- return std::log (xDB + window + 1.0f) - dbPlus - xDB;
-}
-
-inline dsp::SIMDRegister<float> compressionDB (dsp::SIMDRegister<float> xDB, float dbPlus)
+template <typename T>
+inline T compressionDB (const T& xDB, float dbPlus)
{
using namespace chowdsp::SIMDUtils;
+ CHOWDSP_USING_XSIMD_STD (log)
if (dbPlus <= 0.0f)
- return (vec4) dbPlus;
+ return (T) dbPlus;
auto window = 2.0f * dbPlus;
- auto belowWin = vec4::lessThan (xDB, -window);
- return ((logSIMD (xDB + window + 1.0f) - dbPlus - xDB) & ~belowWin) + ((vec4) dbPlus & belowWin);
+ auto belowWin = xDB < -window;
+ return select (belowWin, (T) dbPlus, log (xDB + window + 1.0f) - dbPlus - xDB);
}
void CompressionProcessor::processBlock (AudioBuffer<float>& buffer)
@@ -92,14 +84,14 @@ void CompressionProcessor::processBlock (AudioBuffer<float>& buffer)
size_t n = 0;
for (; n < (size_t) numSamples; n += inc)
{
- auto xDB = dsp::SIMDRegister<float>::fromRawArray (&xDBVec[n]);
+ auto xDB = xsimd::load_aligned (&xDBVec[n]);
xDB = chowdsp::SIMDUtils::gainToDecibels (xDB);
auto compDB = compressionDB (xDB, dbPlusSmooth[ch].skip ((int) inc));
auto compGain = chowdsp::SIMDUtils::decibelsToGain (compDB);
- xDB.copyToRawArray (&xDBVec[n]);
- compGain.copyToRawArray (&compGainVec[n]);
+ xsimd::store_aligned (&xDBVec[n], xDB);
+ xsimd::store_aligned (&compGainVec[n], compGain);
}
// remaining samples that can't be vectorized
diff --git a/Plugin/Source/Processors/Hysteresis/HysteresisOps.h b/Plugin/Source/Processors/Hysteresis/HysteresisOps.h
@@ -9,6 +9,63 @@ namespace HysteresisOps
{
using namespace chowdsp::SIMDUtils;
+/** SIMD implementation of std::tanh */
+template <typename T>
+inline juce::dsp::SIMDRegister<T> tanhSIMD (juce::dsp::SIMDRegister<T> x)
+{
+ using x_type = xsimd::batch<T>;
+ return (juce::dsp::SIMDRegister<T>) xsimd::tanh ((x_type) x.value);
+}
+
+/** Signum function to determine the sign of the input. */
+template <typename T>
+inline juce::dsp::SIMDRegister<T> signumSIMD (juce::dsp::SIMDRegister<T> val)
+{
+ auto positive = juce::dsp::SIMDRegister<T> ((T) 1) & juce::dsp::SIMDRegister<T>::lessThan (juce::dsp::SIMDRegister<T> ((T) 0), val);
+ auto negative = juce::dsp::SIMDRegister<T> ((T) 1) & juce::dsp::SIMDRegister<T>::lessThan (val, juce::dsp::SIMDRegister<T> ((T) 0));
+ return positive - negative;
+}
+
+/** SIMD implementation of std::isnan */
+template <typename T>
+inline typename juce::dsp::SIMDRegister<T>::vMaskType isnanSIMD (juce::dsp::SIMDRegister<T> x)
+{
+ using x_type = xsimd::batch<T>;
+
+ // For some reason, xsimd::isnan returns a batch of doubles when using SSE
+ // but returns a batch of unsigned ints when using ARM NEON.
+#if JUCE_ARM
+ return (typename juce::dsp::SIMDRegister<T>::vMaskType) xsimd::isnan ((x_type) x.value);
+#else
+ using Vec = juce::dsp::SIMDRegister<T>;
+ return Vec::notEqual ((Vec) xsimd::isnan ((x_type) x.value), (Vec) 0);
+#endif
+}
+
+/**
+JUCE doesn't implement the divide operator for
+SIMDRegister, so here's a simple implementation.
+Based on: https://forum.juce.com/t/divide-by-simdregister/28968/18
+*/
+
+#if defined(__i386__) || defined(__amd64__) || defined(_M_X64) || defined(_X86_) || defined(_M_IX86)
+/** Divides another SIMDRegister to the receiver. */
+inline juce::dsp::SIMDRegister<double> operator/ (const juce::dsp::SIMDRegister<double>& l, const juce::dsp::SIMDRegister<double>& r)
+{
+ return _mm_div_pd (l.value, r.value);
+}
+
+#elif defined(_M_ARM64) || defined(__arm64__) || defined(__aarch64__)
+/** Divides another SIMDRegister to the receiver. */
+inline juce::dsp::SIMDRegister<double> operator/ (const juce::dsp::SIMDRegister<double>& l, const juce::dsp::SIMDRegister<double>& r)
+{
+ return vdivq_f64 (l.value, r.value);
+}
+
+#else
+JUCE_COMPILER_WARNING ("SIMD divide not implemented for this platform... using non-vectorized implementation")
+#endif
+
struct HysteresisState
{
// parameter values
@@ -112,7 +169,7 @@ static inline Float hysteresisFunc (Float M, Float H, Float H_d, HysteresisState
#if HYSTERESIS_USE_SIMD
const auto delta = ((Float) 1.0 & Float::greaterThanOrEqual (H_d, (Float) 0.0)) - ((Float) 1.0 & Float::lessThan (H_d, (Float) 0.0));
- const auto delta_M = Float::equal (chowdsp::signumSIMD (delta), chowdsp::signumSIMD (hp.M_diff));
+ const auto delta_M = Float::equal (signumSIMD (delta), signumSIMD (hp.M_diff));
hp.kap1 = (Float) hp.nc & delta_M;
#else
const auto delta = (Float) ((H_d >= 0.0) - (H_d < 0.0));
diff --git a/Plugin/Source/Processors/Hysteresis/HysteresisProcessing.h b/Plugin/Source/Processors/Hysteresis/HysteresisProcessing.h
@@ -61,7 +61,7 @@ public:
// check for instability
#if HYSTERESIS_USE_SIMD
- auto notIllCondition = ~(chowdsp::SIMDUtils::isnanSIMD (M) | Float::greaterThan (M, (Float) upperLim));
+ auto notIllCondition = ~(HysteresisOps::isnanSIMD (M) | Float::greaterThan (M, (Float) upperLim));
M = M & notIllCondition;
H_d = H_d & notIllCondition;
#else
@@ -118,8 +118,9 @@ private:
Float deltaNR;
for (int n = 0; n < nIterations; ++n)
{
- dMdt = HysteresisOps::hysteresisFunc (M, H, H_d, hpState);
- dMdtPrime = HysteresisOps::hysteresisFuncPrime (H_d, dMdt, hpState);
+ using namespace HysteresisOps;
+ dMdt = hysteresisFunc (M, H, H_d, hpState);
+ dMdtPrime = hysteresisFuncPrime (H_d, dMdt, hpState);
deltaNR = (M - M_n1 - (Float) Talpha * (dMdt + last_dMdt)) / (Float (1.0) - (Float) Talpha * dMdtPrime);
M -= deltaNR;
}
diff --git a/Plugin/modules/CMakeLists.txt b/Plugin/modules/CMakeLists.txt
@@ -26,9 +26,11 @@ target_link_libraries(juce_plugin_modules
juce::juce_audio_utils
juce::juce_audio_plugin_client
chowdsp_juce_dsp
- chowdsp_dsp
- chowdsp_gui
- chowdsp_plugin_utils
+ chowdsp::chowdsp_dsp_utils
+ chowdsp::chowdsp_plugin_base
+ chowdsp::chowdsp_plugin_utils
+ chowdsp::chowdsp_presets
+ chowdsp::chowdsp_foleys
foleys_gui_magic
RTNeural
PUBLIC