diff --git a/modules/juce_audio_basics/buffers/juce_FloatVectorOperations.cpp b/modules/juce_audio_basics/buffers/juce_FloatVectorOperations.cpp index 2bc8a864af..fdae795367 100644 --- a/modules/juce_audio_basics/buffers/juce_FloatVectorOperations.cpp +++ b/modules/juce_audio_basics/buffers/juce_FloatVectorOperations.cpp @@ -63,6 +63,11 @@ namespace FloatVectorHelpers static forcedinline ParallelType max (ParallelType a, ParallelType b) noexcept { return _mm_max_ps (a, b); } static forcedinline ParallelType min (ParallelType a, ParallelType b) noexcept { return _mm_min_ps (a, b); } + static forcedinline ParallelType bit_and (ParallelType a, ParallelType b) noexcept { return _mm_and_ps (a, b); } + static forcedinline ParallelType bit_not (ParallelType a, ParallelType b) noexcept { return _mm_andnot_ps (a, b); } + static forcedinline ParallelType bit_or (ParallelType a, ParallelType b) noexcept { return _mm_or_ps (a, b); } + static forcedinline ParallelType bit_xor (ParallelType a, ParallelType b) noexcept { return _mm_xor_ps (a, b); } + static forcedinline Type max (ParallelType a) noexcept { Type v[numParallel]; storeU (v, a); return jmax (v[0], v[1], v[2], v[3]); } static forcedinline Type min (ParallelType a) noexcept { Type v[numParallel]; storeU (v, a); return jmin (v[0], v[1], v[2], v[3]); } }; @@ -85,10 +90,17 @@ namespace FloatVectorHelpers static forcedinline ParallelType max (ParallelType a, ParallelType b) noexcept { return _mm_max_pd (a, b); } static forcedinline ParallelType min (ParallelType a, ParallelType b) noexcept { return _mm_min_pd (a, b); } + static forcedinline ParallelType bit_and (ParallelType a, ParallelType b) noexcept { return _mm_and_pd (a, b); } + static forcedinline ParallelType bit_not (ParallelType a, ParallelType b) noexcept { return _mm_andnot_pd (a, b); } + static forcedinline ParallelType bit_or (ParallelType a, ParallelType b) noexcept { return _mm_or_pd (a, b); } + static forcedinline ParallelType bit_xor (ParallelType a, ParallelType b) noexcept { return _mm_xor_pd (a, b); } + static forcedinline Type max (ParallelType a) noexcept { Type v[numParallel]; storeU (v, a); return jmax (v[0], v[1]); } static forcedinline Type min (ParallelType a) noexcept { Type v[numParallel]; storeU (v, a); return jmin (v[0], v[1]); } }; + + #define JUCE_BEGIN_VEC_OP \ typedef FloatVectorHelpers::ModeType::Mode Mode; \ if (FloatVectorHelpers::isSSE2Available()) \ @@ -731,6 +743,35 @@ void FloatVectorOperations::negate (double* dest, const double* src, int num) no #endif } +void FloatVectorOperations::abs (float* dest, const float* src, int num) noexcept +{ + #if JUCE_USE_VDSP_FRAMEWORK + vDSP_vabs ((float*) src, 1, dest, 1, (vDSP_Length) num); + #else + union {float f; uint32 i;} signMask; + signMask.i = 0x80000000UL; + JUCE_PERFORM_VEC_OP_SRC_DEST (dest[i] = fabsf(src[i]), + Mode::bit_xor (s, Mode::bit_and (s, mask)), + JUCE_LOAD_SRC, JUCE_INCREMENT_SRC_DEST, + const Mode::ParallelType mask = Mode::load1 (signMask.f);) + #endif +} + +void FloatVectorOperations::abs (double* dest, const double* src, int num) noexcept +{ + #if JUCE_USE_VDSP_FRAMEWORK + vDSP_vabsD ((double*) src, 1, dest, 1, (vDSP_Length) num); + #else + union {double d; uint64 i;} signMask; + signMask.i = 0x8000000000000000ULL; + + JUCE_PERFORM_VEC_OP_SRC_DEST (dest[i] = fabs (src[i]), + Mode::bit_xor (s, Mode::bit_and (s, mask)), + JUCE_LOAD_SRC, JUCE_INCREMENT_SRC_DEST, + const Mode::ParallelType mask = Mode::load1 (signMask.d);) + #endif +} + void JUCE_CALLTYPE FloatVectorOperations::convertFixedToFloat (float* dest, const int* src, float multiplier, int num) noexcept { #if JUCE_USE_ARM_NEON @@ -974,6 +1015,12 @@ public: FloatVectorOperations::subtract (data1, data2, num); u.expect (areAllValuesEqual (data1, num, (ValueType) 512)); + FloatVectorOperations::abs (data1, data2, num); + u.expect (areAllValuesEqual (data1, num, (ValueType) 256)); + + FloatVectorOperations::abs (data2, data1, num); + u.expect (areAllValuesEqual (data2, num, (ValueType) 256)); + fillRandomly (random, int1, num); doConversionTest (u, data1, data2, int1, num); diff --git a/modules/juce_audio_basics/buffers/juce_FloatVectorOperations.h b/modules/juce_audio_basics/buffers/juce_FloatVectorOperations.h index b7dc972daf..114d516622 100644 --- a/modules/juce_audio_basics/buffers/juce_FloatVectorOperations.h +++ b/modules/juce_audio_basics/buffers/juce_FloatVectorOperations.h @@ -137,6 +137,12 @@ public: /** Copies a source vector to a destination, negating each value. */ static void JUCE_CALLTYPE negate (double* dest, const double* src, int numValues) noexcept; + /** Copies a source vector to a destination, taking the absolute of each value. */ + static void JUCE_CALLTYPE abs (float* dest, const float* src, int numValues) noexcept; + + /** Copies a source vector to a destination, taking the absolute of each value. */ + static void JUCE_CALLTYPE abs (double* dest, const double* src, int numValues) noexcept; + /** Converts a stream of integers to floats, multiplying each one by the given multiplier. */ static void JUCE_CALLTYPE convertFixedToFloat (float* dest, const int* src, float multiplier, int numValues) noexcept;