From 7e560f11331b6c96d03245985082a712fe95b9b7 Mon Sep 17 00:00:00 2001 From: jules Date: Mon, 6 Oct 2014 14:26:22 +0100 Subject: [PATCH] Added some new methods to FloatVectorOperations for operating on separate source and destination vectors. --- .../buffers/juce_FloatVectorOperations.cpp | 121 +++++++++++++++++- .../buffers/juce_FloatVectorOperations.h | 30 +++++ 2 files changed, 146 insertions(+), 5 deletions(-) diff --git a/modules/juce_audio_basics/buffers/juce_FloatVectorOperations.cpp b/modules/juce_audio_basics/buffers/juce_FloatVectorOperations.cpp index 308ac84572..9aec720bff 100644 --- a/modules/juce_audio_basics/buffers/juce_FloatVectorOperations.cpp +++ b/modules/juce_audio_basics/buffers/juce_FloatVectorOperations.cpp @@ -24,8 +24,9 @@ namespace FloatVectorHelpers { - #define JUCE_INCREMENT_SRC_DEST dest += (16 / sizeof (*dest)); src += (16 / sizeof (*dest)); - #define JUCE_INCREMENT_DEST dest += (16 / sizeof (*dest)); + #define JUCE_INCREMENT_SRC_DEST dest += (16 / sizeof (*dest)); src += (16 / sizeof (*dest)); + #define JUCE_INCREMENT_SRC1_SRC2_DEST dest += (16 / sizeof (*dest)); src1 += (16 / sizeof (*dest)); src2 += (16 / sizeof (*dest)); + #define JUCE_INCREMENT_DEST dest += (16 / sizeof (*dest)); #if JUCE_USE_SSE_INTRINSICS static bool sse2Present = false; @@ -122,6 +123,17 @@ namespace FloatVectorHelpers } \ JUCE_FINISH_VEC_OP (normalOp) +#define JUCE_PERFORM_VEC_OP_SRC1_SRC2_DEST(normalOp, vecOp, locals, increment, setupOp) \ + JUCE_BEGIN_VEC_OP \ + setupOp \ + { \ + Mode::ParallelType (&loadSrc1) (const Mode::Type* v) = FloatVectorHelpers::isAligned (src1) ? Mode::loadA : Mode::loadU; \ + Mode::ParallelType (&loadSrc2) (const Mode::Type* v) = FloatVectorHelpers::isAligned (src2) ? Mode::loadA : Mode::loadU; \ + void (&storeDst) (Mode::Type* dest, Mode::ParallelType a) = FloatVectorHelpers::isAligned (dest) ? Mode::storeA : Mode::storeU; \ + JUCE_VEC_LOOP_TWO_SOURCES (vecOp, loadSrc1, loadSrc2, storeDst, locals, increment); \ + } \ + JUCE_FINISH_VEC_OP (normalOp) + //============================================================================== #elif JUCE_USE_ARM_NEON @@ -212,10 +224,19 @@ namespace FloatVectorHelpers increment; \ } + #define JUCE_VEC_LOOP_TWO_SOURCES(vecOp, src1Load, src2Load, dstStore, locals, increment) \ + for (int i = 0; i < numLongOps; ++i) \ + { \ + locals (src1Load, src2Load); \ + dstStore (dest, vecOp); \ + increment; \ + } + #define JUCE_LOAD_NONE(srcLoad, dstLoad) - #define JUCE_LOAD_DEST(srcLoad, dstLoad) const Mode::ParallelType d = dstLoad (dest); - #define JUCE_LOAD_SRC(srcLoad, dstLoad) const Mode::ParallelType s = srcLoad (src); - #define JUCE_LOAD_SRC_DEST(srcLoad, dstLoad) const Mode::ParallelType d = dstLoad (dest), s = srcLoad (src); + #define JUCE_LOAD_DEST(srcLoad, dstLoad) const Mode::ParallelType d = dstLoad (dest); + #define JUCE_LOAD_SRC(srcLoad, dstLoad) const Mode::ParallelType s = srcLoad (src); + #define JUCE_LOAD_SRC1_SRC2(src1Load, src2Load) const Mode::ParallelType s1 = src1Load (src1), s2 = src2Load (src2); + #define JUCE_LOAD_SRC_DEST(srcLoad, dstLoad) const Mode::ParallelType d = dstLoad (dest), s = srcLoad (src); #if JUCE_USE_SSE_INTRINSICS || JUCE_USE_ARM_NEON template struct ModeType { typedef BasicOps32 Mode; }; @@ -443,6 +464,28 @@ void JUCE_CALLTYPE FloatVectorOperations::add (double* dest, double amount, int const Mode::ParallelType amountToAdd = Mode::load1 (amount);) } +void JUCE_CALLTYPE FloatVectorOperations::add (float* dest, float* src, float amount, int num) noexcept +{ + #if JUCE_USE_VDSP_FRAMEWORK + vDSP_vsadd (src, 1, &amount, dest, 1, (vDSP_Length) num); + #else + JUCE_PERFORM_VEC_OP_SRC_DEST (dest[i] = src[i] + amount, Mode::add (am, s), + JUCE_LOAD_SRC, JUCE_INCREMENT_SRC_DEST, + const Mode::ParallelType am = Mode::load1 (amount);) + #endif +} + +void JUCE_CALLTYPE FloatVectorOperations::add (double* dest, double* src, double amount, int num) noexcept +{ + #if JUCE_USE_VDSP_FRAMEWORK + vDSP_vsaddD (src, 1, &amount, dest, 1, (vDSP_Length) num); + #else + JUCE_PERFORM_VEC_OP_SRC_DEST (dest[i] = src[i] + amount, Mode::add (am, s), + JUCE_LOAD_SRC, JUCE_INCREMENT_SRC_DEST, + const Mode::ParallelType am = Mode::load1 (amount);) + #endif +} + void JUCE_CALLTYPE FloatVectorOperations::add (float* dest, const float* src, int num) noexcept { #if JUCE_USE_VDSP_FRAMEWORK @@ -461,6 +504,24 @@ void JUCE_CALLTYPE FloatVectorOperations::add (double* dest, const double* src, #endif } +void JUCE_CALLTYPE FloatVectorOperations::add (float* dest, const float* src1, const float* src2, int num) noexcept +{ + #if JUCE_USE_VDSP_FRAMEWORK + vDSP_vadd (src1, 1, src2, 1, dest, 1, (vDSP_Length) num); + #else + JUCE_PERFORM_VEC_OP_SRC1_SRC2_DEST (dest[i] = src1[i] + src2[i], Mode::add (s1, s2), JUCE_LOAD_SRC1_SRC2, JUCE_INCREMENT_SRC1_SRC2_DEST, ) + #endif +} + +void JUCE_CALLTYPE FloatVectorOperations::add (double* dest, const double* src1, const double* src2, int num) noexcept +{ + #if JUCE_USE_VDSP_FRAMEWORK + vDSP_vaddD (src1, 1, src2, 1, dest, 1, (vDSP_Length) num); + #else + JUCE_PERFORM_VEC_OP_SRC1_SRC2_DEST (dest[i] = src1[i] + src2[i], Mode::add (s1, s2), JUCE_LOAD_SRC1_SRC2, JUCE_INCREMENT_SRC1_SRC2_DEST, ) + #endif +} + void JUCE_CALLTYPE FloatVectorOperations::subtract (float* dest, const float* src, int num) noexcept { #if JUCE_USE_VDSP_FRAMEWORK @@ -479,6 +540,24 @@ void JUCE_CALLTYPE FloatVectorOperations::subtract (double* dest, const double* #endif } +void JUCE_CALLTYPE FloatVectorOperations::subtract (float* dest, const float* src1, const float* src2, int num) noexcept +{ + #if JUCE_USE_VDSP_FRAMEWORK + vDSP_vsub (src2, 1, src1, 1, dest, 1, (vDSP_Length) num); + #else + JUCE_PERFORM_VEC_OP_SRC1_SRC2_DEST (dest[i] = src1[i] - src2[i], Mode::sub (s1, s2), JUCE_LOAD_SRC1_SRC2, JUCE_INCREMENT_SRC1_SRC2_DEST, ) + #endif +} + +void JUCE_CALLTYPE FloatVectorOperations::subtract (double* dest, const double* src1, const double* src2, int num) noexcept +{ + #if JUCE_USE_VDSP_FRAMEWORK + vDSP_vsubD (src2, 1, src1, 1, dest, 1, (vDSP_Length) num); + #else + JUCE_PERFORM_VEC_OP_SRC1_SRC2_DEST (dest[i] = src1[i] - src2[i], Mode::sub (s1, s2), JUCE_LOAD_SRC1_SRC2, JUCE_INCREMENT_SRC1_SRC2_DEST, ) + #endif +} + void JUCE_CALLTYPE FloatVectorOperations::addWithMultiply (float* dest, const float* src, float multiplier, int num) noexcept { JUCE_PERFORM_VEC_OP_SRC_DEST (dest[i] += src[i] * multiplier, Mode::add (d, Mode::mul (mult, s)), @@ -511,6 +590,24 @@ void JUCE_CALLTYPE FloatVectorOperations::multiply (double* dest, const double* #endif } +void JUCE_CALLTYPE FloatVectorOperations::multiply (float* dest, const float* src1, const float* src2, int num) noexcept +{ + #if JUCE_USE_VDSP_FRAMEWORK + vDSP_vmul (src1, 1, src2, 1, dest, 1, (vDSP_Length) num); + #else + JUCE_PERFORM_VEC_OP_SRC1_SRC2_DEST (dest[i] = src1[i] * src2[i], Mode::mul (s1, s2), JUCE_LOAD_SRC1_SRC2, JUCE_INCREMENT_SRC1_SRC2_DEST, ) + #endif +} + +void JUCE_CALLTYPE FloatVectorOperations::multiply (double* dest, const double* src1, const double* src2, int num) noexcept +{ + #if JUCE_USE_VDSP_FRAMEWORK + vDSP_vmulD (src1, 1, src2, 1, dest, 1, (vDSP_Length) num); + #else + JUCE_PERFORM_VEC_OP_SRC1_SRC2_DEST (dest[i] = src1[i] * src2[i], Mode::mul (s1, s2), JUCE_LOAD_SRC1_SRC2, JUCE_INCREMENT_SRC1_SRC2_DEST, ) + #endif +} + void JUCE_CALLTYPE FloatVectorOperations::multiply (float* dest, float multiplier, int num) noexcept { #if JUCE_USE_VDSP_FRAMEWORK @@ -531,6 +628,20 @@ void JUCE_CALLTYPE FloatVectorOperations::multiply (double* dest, double multipl #endif } +void JUCE_CALLTYPE FloatVectorOperations::multiply (float* dest, const float* src, float multiplier, int num) noexcept +{ + JUCE_PERFORM_VEC_OP_SRC_DEST (dest[i] = src[i] * multiplier, Mode::mul (mult, s), + JUCE_LOAD_SRC, JUCE_INCREMENT_SRC_DEST, + const Mode::ParallelType mult = Mode::load1 (multiplier);) +} + +void JUCE_CALLTYPE FloatVectorOperations::multiply (double* dest, const double* src, double multiplier, int num) noexcept +{ + JUCE_PERFORM_VEC_OP_SRC_DEST (dest[i] = src[i] * multiplier, Mode::mul (mult, s), + JUCE_LOAD_SRC, JUCE_INCREMENT_SRC_DEST, + const Mode::ParallelType mult = Mode::load1 (multiplier);) +} + void FloatVectorOperations::negate (float* dest, const float* src, int num) noexcept { #if JUCE_USE_VDSP_FRAMEWORK diff --git a/modules/juce_audio_basics/buffers/juce_FloatVectorOperations.h b/modules/juce_audio_basics/buffers/juce_FloatVectorOperations.h index 54821d28c3..0b3fcb67c5 100644 --- a/modules/juce_audio_basics/buffers/juce_FloatVectorOperations.h +++ b/modules/juce_audio_basics/buffers/juce_FloatVectorOperations.h @@ -65,18 +65,36 @@ public: /** Adds a fixed value to the destination values. */ static void JUCE_CALLTYPE add (double* dest, double amountToAdd, int numValues) noexcept; + /** Adds a fixed value to each source value and stores it in the destination array. */ + static void JUCE_CALLTYPE add (float* dest, float* src, float amount, int numValues) noexcept; + + /** Adds a fixed value to each source value and stores it in the destination array. */ + static void JUCE_CALLTYPE add (double* dest, double* src, double amount, int numValues) noexcept; + /** Adds the source values to the destination values. */ static void JUCE_CALLTYPE add (float* dest, const float* src, int numValues) noexcept; /** Adds the source values to the destination values. */ static void JUCE_CALLTYPE add (double* dest, const double* src, int numValues) noexcept; + /** Adds each source1 value to the corresponding source2 value and stores the result in the destination array. */ + static void JUCE_CALLTYPE add (float* dest, const float* src1, const float* src2, int num) noexcept; + + /** Adds each source1 value to the corresponding source2 value and stores the result in the destination array. */ + static void JUCE_CALLTYPE add (double* dest, const double* src1, const double* src2, int num) noexcept; + /** Subtracts the source values from the destination values. */ static void JUCE_CALLTYPE subtract (float* dest, const float* src, int numValues) noexcept; /** Subtracts the source values from the destination values. */ static void JUCE_CALLTYPE subtract (double* dest, const double* src, int numValues) noexcept; + /** Subtracts each source2 value from the corresponding source1 value and stores the result in the destination array. */ + static void JUCE_CALLTYPE subtract (float* dest, const float* src1, const float* src2, int num) noexcept; + + /** Subtracts each source2 value from the corresponding source1 value and stores the result in the destination array. */ + static void JUCE_CALLTYPE subtract (double* dest, const double* src1, const double* src2, int num) noexcept; + /** Multiplies each source value by the given multiplier, then adds it to the destination value. */ static void JUCE_CALLTYPE addWithMultiply (float* dest, const float* src, float multiplier, int numValues) noexcept; @@ -89,12 +107,24 @@ public: /** Multiplies the destination values by the source values. */ static void JUCE_CALLTYPE multiply (double* dest, const double* src, int numValues) noexcept; + /** Multiplies each source1 value by the correspinding source2 value, then stores it in the destination array. */ + static void JUCE_CALLTYPE multiply (float* dest, const float* src1, const float* src2, int numValues) noexcept; + + /** Multiplies each source1 value by the correspinding source2 value, then stores it in the destination array. */ + static void JUCE_CALLTYPE multiply (double* dest, const double* src1, const double* src2, int numValues) noexcept; + /** Multiplies each of the destination values by a fixed multiplier. */ static void JUCE_CALLTYPE multiply (float* dest, float multiplier, int numValues) noexcept; /** Multiplies each of the destination values by a fixed multiplier. */ static void JUCE_CALLTYPE multiply (double* dest, double multiplier, int numValues) noexcept; + /** Multiplies each of the source values by a fixed multiplier and stores the result in the destination array. */ + static void JUCE_CALLTYPE multiply (float* dest, const float* src, float multiplier, int num) noexcept; + + /** Multiplies each of the source values by a fixed multiplier and stores the result in the destination array. */ + static void JUCE_CALLTYPE multiply (double* dest, const double* src, double multiplier, int num) noexcept; + /** Copies a source vector to a destination, negating each value. */ static void JUCE_CALLTYPE negate (float* dest, const float* src, int numValues) noexcept;