diff --git a/modules/juce_audio_basics/buffers/juce_FloatVectorOperations.cpp b/modules/juce_audio_basics/buffers/juce_FloatVectorOperations.cpp index c39b52bd56..47eb058f99 100644 --- a/modules/juce_audio_basics/buffers/juce_FloatVectorOperations.cpp +++ b/modules/juce_audio_basics/buffers/juce_FloatVectorOperations.cpp @@ -104,13 +104,13 @@ namespace FloatVectorHelpers #define JUCE_BEGIN_VEC_OP \ using Mode = FloatVectorHelpers::ModeType::Mode; \ { \ - const int numLongOps = num / Mode::numParallel; + const auto numLongOps = num / Mode::numParallel; #define JUCE_FINISH_VEC_OP(normalOp) \ num &= (Mode::numParallel - 1); \ if (num == 0) return; \ } \ - for (int i = 0; i < num; ++i) normalOp; + for (auto i = (decltype (num)) 0; i < num; ++i) normalOp; #define JUCE_PERFORM_VEC_OP_DEST(normalOp, vecOp, locals, setupOp) \ JUCE_BEGIN_VEC_OP \ @@ -268,13 +268,13 @@ namespace FloatVectorHelpers using Mode = FloatVectorHelpers::ModeType::Mode; \ if (Mode::numParallel > 1) \ { \ - const int numLongOps = num / Mode::numParallel; + const auto numLongOps = num / Mode::numParallel; #define JUCE_FINISH_VEC_OP(normalOp) \ num &= (Mode::numParallel - 1); \ if (num == 0) return; \ } \ - for (int i = 0; i < num; ++i) normalOp; + for (auto i = (decltype (num)) 0; i < num; ++i) normalOp; #define JUCE_PERFORM_VEC_OP_DEST(normalOp, vecOp, locals, setupOp) \ JUCE_BEGIN_VEC_OP \ @@ -304,22 +304,22 @@ namespace FloatVectorHelpers //============================================================================== #else #define JUCE_PERFORM_VEC_OP_DEST(normalOp, vecOp, locals, setupOp) \ - for (int i = 0; i < num; ++i) normalOp; + for (auto i = (decltype (num)) 0; i < num; ++i) normalOp; #define JUCE_PERFORM_VEC_OP_SRC_DEST(normalOp, vecOp, locals, increment, setupOp) \ - for (int i = 0; i < num; ++i) normalOp; + for (auto i = (decltype (num)) 0; i < num; ++i) normalOp; #define JUCE_PERFORM_VEC_OP_SRC1_SRC2_DEST(normalOp, vecOp, locals, increment, setupOp) \ - for (int i = 0; i < num; ++i) normalOp; + for (auto i = (decltype (num)) 0; i < num; ++i) normalOp; #define JUCE_PERFORM_VEC_OP_SRC1_SRC2_DEST_DEST(normalOp, vecOp, locals, increment, setupOp) \ - for (int i = 0; i < num; ++i) normalOp; + for (auto i = (decltype (num)) 0; i < num; ++i) normalOp; #endif //============================================================================== #define JUCE_VEC_LOOP(vecOp, srcLoad, dstLoad, dstStore, locals, increment) \ - for (int i = 0; i < numLongOps; ++i) \ + for (auto i = (decltype (numLongOps)) 0; i < numLongOps; ++i) \ { \ locals (srcLoad, dstLoad); \ dstStore (dest, vecOp); \ @@ -327,7 +327,7 @@ namespace FloatVectorHelpers } #define JUCE_VEC_LOOP_TWO_SOURCES(vecOp, src1Load, src2Load, dstStore, locals, increment) \ - for (int i = 0; i < numLongOps; ++i) \ + for (auto i = (decltype (numLongOps)) 0; i < numLongOps; ++i) \ { \ locals (src1Load, src2Load); \ dstStore (dest, vecOp); \ @@ -335,7 +335,7 @@ namespace FloatVectorHelpers } #define JUCE_VEC_LOOP_TWO_SOURCES_WITH_DEST_LOAD(vecOp, src1Load, src2Load, dstLoad, dstStore, locals, increment) \ - for (int i = 0; i < numLongOps; ++i) \ + for (auto i = (decltype (numLongOps)) 0; i < numLongOps; ++i) \ { \ locals (src1Load, src2Load, dstLoad); \ dstStore (dest, vecOp); \ @@ -362,9 +362,10 @@ namespace FloatVectorHelpers using Type = typename Mode::Type; using ParallelType = typename Mode::ParallelType; - static Type findMinOrMax (const Type* src, int num, const bool isMinimum) noexcept + template + static Type findMinOrMax (const Type* src, Size num, const bool isMinimum) noexcept { - int numLongOps = num / Mode::numParallel; + auto numLongOps = num / Mode::numParallel; if (numLongOps > 1) { @@ -421,20 +422,24 @@ namespace FloatVectorHelpers num &= (Mode::numParallel - 1); src += Mode::numParallel; - for (int i = 0; i < num; ++i) + for (auto i = (decltype (num)) 0; i < num; ++i) result = isMinimum ? jmin (result, src[i]) : jmax (result, src[i]); return result; } - return isMinimum ? juce::findMinimum (src, num) - : juce::findMaximum (src, num); + if (num <= 0) + return 0; + + return isMinimum ? *std::min_element (src, src + num) + : *std::max_element (src, src + num); } - static Range findMinAndMax (const Type* src, int num) noexcept + template + static Range findMinAndMax (const Type* src, Size num) noexcept { - int numLongOps = num / Mode::numParallel; + auto numLongOps = num / Mode::numParallel; if (numLongOps > 1) { @@ -475,7 +480,7 @@ namespace FloatVectorHelpers num &= (Mode::numParallel - 1); src += Mode::numParallel; - for (int i = 0; i < num; ++i) + for (auto i = (decltype (num)) 0; i < num; ++i) result = result.getUnionWith (src[i]); return result; @@ -485,547 +490,941 @@ namespace FloatVectorHelpers } }; #endif -} //============================================================================== namespace { - #if JUCE_USE_VDSP_FRAMEWORK - // This casts away constness to account for slightly different vDSP function signatures - // in OSX 10.8 SDK and below. Can be safely removed once those SDKs are obsolete. - template - ValueType* osx108sdkCompatibilityCast (const ValueType* arg) noexcept { return const_cast (arg); } - #endif -} + template + void clear (float* dest, Size num) noexcept + { + #if JUCE_USE_VDSP_FRAMEWORK + vDSP_vclr (dest, 1, (vDSP_Length) num); + #else + zeromem (dest, (size_t) num * sizeof (float)); + #endif + } + + template + void clear (double* dest, Size num) noexcept + { + #if JUCE_USE_VDSP_FRAMEWORK + vDSP_vclrD (dest, 1, (vDSP_Length) num); + #else + zeromem (dest, (size_t) num * sizeof (double)); + #endif + } + + template + void fill (float* dest, float valueToFill, Size num) noexcept + { + #if JUCE_USE_VDSP_FRAMEWORK + vDSP_vfill (&valueToFill, dest, 1, (vDSP_Length) num); + #else + JUCE_PERFORM_VEC_OP_DEST (dest[i] = valueToFill, + val, + JUCE_LOAD_NONE, + const Mode::ParallelType val = Mode::load1 (valueToFill);) + #endif + } + + template + void fill (double* dest, double valueToFill, Size num) noexcept + { + #if JUCE_USE_VDSP_FRAMEWORK + vDSP_vfillD (&valueToFill, dest, 1, (vDSP_Length) num); + #else + JUCE_PERFORM_VEC_OP_DEST (dest[i] = valueToFill, + val, + JUCE_LOAD_NONE, + const Mode::ParallelType val = Mode::load1 (valueToFill);) + #endif + } + + template + void copyWithMultiply (float* dest, const float* src, float multiplier, Size num) noexcept + { + #if JUCE_USE_VDSP_FRAMEWORK + vDSP_vsmul (src, 1, &multiplier, dest, 1, (vDSP_Length) num); + #else + 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);) + #endif + } + + template + void copyWithMultiply (double* dest, const double* src, double multiplier, Size num) noexcept + { + #if JUCE_USE_VDSP_FRAMEWORK + vDSP_vsmulD (src, 1, &multiplier, dest, 1, (vDSP_Length) num); + #else + 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);) + #endif + } + + template + void add (float* dest, float amount, Size num) noexcept + { + #if JUCE_USE_VDSP_FRAMEWORK + vDSP_vsadd (dest, 1, &amount, dest, 1, (vDSP_Length) num); + #else + JUCE_PERFORM_VEC_OP_DEST (dest[i] += amount, + Mode::add (d, amountToAdd), + JUCE_LOAD_DEST, + const Mode::ParallelType amountToAdd = Mode::load1 (amount);) + #endif + } + + template + void add (double* dest, double amount, Size num) noexcept + { + JUCE_PERFORM_VEC_OP_DEST (dest[i] += amount, + Mode::add (d, amountToAdd), + JUCE_LOAD_DEST, + const Mode::ParallelType amountToAdd = Mode::load1 (amount);) + } + + template + void add (float* dest, const float* src, float amount, Size 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 + } + + template + void add (double* dest, const double* src, double amount, Size 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 + } + + template + void add (float* dest, const float* src, Size num) noexcept + { + #if JUCE_USE_VDSP_FRAMEWORK + vDSP_vadd (src, 1, dest, 1, dest, 1, (vDSP_Length) num); + #else + JUCE_PERFORM_VEC_OP_SRC_DEST (dest[i] += src[i], + Mode::add (d, s), + JUCE_LOAD_SRC_DEST, + JUCE_INCREMENT_SRC_DEST, ) + #endif + } + + template + void add (double* dest, const double* src, Size num) noexcept + { + #if JUCE_USE_VDSP_FRAMEWORK + vDSP_vaddD (src, 1, dest, 1, dest, 1, (vDSP_Length) num); + #else + JUCE_PERFORM_VEC_OP_SRC_DEST (dest[i] += src[i], + Mode::add (d, s), + JUCE_LOAD_SRC_DEST, + JUCE_INCREMENT_SRC_DEST, ) + #endif + } + + template + void add (float* dest, const float* src1, const float* src2, Size 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 + } + + template + void add (double* dest, const double* src1, const double* src2, Size 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 + } + + template + void subtract (float* dest, const float* src, Size num) noexcept + { + #if JUCE_USE_VDSP_FRAMEWORK + vDSP_vsub (src, 1, dest, 1, dest, 1, (vDSP_Length) num); + #else + JUCE_PERFORM_VEC_OP_SRC_DEST (dest[i] -= src[i], + Mode::sub (d, s), + JUCE_LOAD_SRC_DEST, + JUCE_INCREMENT_SRC_DEST, ) + #endif + } + + template + void subtract (double* dest, const double* src, Size num) noexcept + { + #if JUCE_USE_VDSP_FRAMEWORK + vDSP_vsubD (src, 1, dest, 1, dest, 1, (vDSP_Length) num); + #else + JUCE_PERFORM_VEC_OP_SRC_DEST (dest[i] -= src[i], + Mode::sub (d, s), + JUCE_LOAD_SRC_DEST, + JUCE_INCREMENT_SRC_DEST, ) + #endif + } + + template + void subtract (float* dest, const float* src1, const float* src2, Size 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 + } + + template + void subtract (double* dest, const double* src1, const double* src2, Size 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 + } + + template + void addWithMultiply (float* dest, const float* src, float multiplier, Size num) noexcept + { + #if JUCE_USE_VDSP_FRAMEWORK + vDSP_vsma (src, 1, &multiplier, dest, 1, dest, 1, (vDSP_Length) num); + #else + JUCE_PERFORM_VEC_OP_SRC_DEST (dest[i] += src[i] * multiplier, + Mode::add (d, Mode::mul (mult, s)), + JUCE_LOAD_SRC_DEST, + JUCE_INCREMENT_SRC_DEST, + const Mode::ParallelType mult = Mode::load1 (multiplier);) + #endif + } + + template + void addWithMultiply (double* dest, const double* src, double multiplier, Size num) noexcept + { + #if JUCE_USE_VDSP_FRAMEWORK + vDSP_vsmaD (src, 1, &multiplier, dest, 1, dest, 1, (vDSP_Length) num); + #else + JUCE_PERFORM_VEC_OP_SRC_DEST (dest[i] += src[i] * multiplier, + Mode::add (d, Mode::mul (mult, s)), + JUCE_LOAD_SRC_DEST, + JUCE_INCREMENT_SRC_DEST, + const Mode::ParallelType mult = Mode::load1 (multiplier);) + #endif + } + + template + void addWithMultiply (float* dest, const float* src1, const float* src2, Size num) noexcept + { + #if JUCE_USE_VDSP_FRAMEWORK + vDSP_vma ((float*) src1, 1, (float*) src2, 1, dest, 1, dest, 1, (vDSP_Length) num); + #else + JUCE_PERFORM_VEC_OP_SRC1_SRC2_DEST_DEST (dest[i] += src1[i] * src2[i], + Mode::add (d, Mode::mul (s1, s2)), + JUCE_LOAD_SRC1_SRC2_DEST, + JUCE_INCREMENT_SRC1_SRC2_DEST, ) + #endif + } + + template + void addWithMultiply (double* dest, const double* src1, const double* src2, Size num) noexcept + { + #if JUCE_USE_VDSP_FRAMEWORK + vDSP_vmaD ((double*) src1, 1, (double*) src2, 1, dest, 1, dest, 1, (vDSP_Length) num); + #else + JUCE_PERFORM_VEC_OP_SRC1_SRC2_DEST_DEST (dest[i] += src1[i] * src2[i], + Mode::add (d, Mode::mul (s1, s2)), + JUCE_LOAD_SRC1_SRC2_DEST, + JUCE_INCREMENT_SRC1_SRC2_DEST, ) + #endif + } + + template + void subtractWithMultiply (float* dest, const float* src, float multiplier, Size num) noexcept + { + JUCE_PERFORM_VEC_OP_SRC_DEST (dest[i] -= src[i] * multiplier, + Mode::sub (d, Mode::mul (mult, s)), + JUCE_LOAD_SRC_DEST, + JUCE_INCREMENT_SRC_DEST, + const Mode::ParallelType mult = Mode::load1 (multiplier);) + } + + template + void subtractWithMultiply (double* dest, const double* src, double multiplier, Size num) noexcept + { + JUCE_PERFORM_VEC_OP_SRC_DEST (dest[i] -= src[i] * multiplier, + Mode::sub (d, Mode::mul (mult, s)), + JUCE_LOAD_SRC_DEST, + JUCE_INCREMENT_SRC_DEST, + const Mode::ParallelType mult = Mode::load1 (multiplier);) + } + + template + void subtractWithMultiply (float* dest, const float* src1, const float* src2, Size num) noexcept + { + JUCE_PERFORM_VEC_OP_SRC1_SRC2_DEST_DEST (dest[i] -= src1[i] * src2[i], + Mode::sub (d, Mode::mul (s1, s2)), + JUCE_LOAD_SRC1_SRC2_DEST, + JUCE_INCREMENT_SRC1_SRC2_DEST, ) + } + + template + void subtractWithMultiply (double* dest, const double* src1, const double* src2, Size num) noexcept + { + JUCE_PERFORM_VEC_OP_SRC1_SRC2_DEST_DEST (dest[i] -= src1[i] * src2[i], + Mode::sub (d, Mode::mul (s1, s2)), + JUCE_LOAD_SRC1_SRC2_DEST, + JUCE_INCREMENT_SRC1_SRC2_DEST, ) + } + + template + void multiply (float* dest, const float* src, Size num) noexcept + { + #if JUCE_USE_VDSP_FRAMEWORK + vDSP_vmul (src, 1, dest, 1, dest, 1, (vDSP_Length) num); + #else + JUCE_PERFORM_VEC_OP_SRC_DEST (dest[i] *= src[i], + Mode::mul (d, s), + JUCE_LOAD_SRC_DEST, + JUCE_INCREMENT_SRC_DEST, ) + #endif + } + + template + void multiply (double* dest, const double* src, Size num) noexcept + { + #if JUCE_USE_VDSP_FRAMEWORK + vDSP_vmulD (src, 1, dest, 1, dest, 1, (vDSP_Length) num); + #else + JUCE_PERFORM_VEC_OP_SRC_DEST (dest[i] *= src[i], + Mode::mul (d, s), + JUCE_LOAD_SRC_DEST, + JUCE_INCREMENT_SRC_DEST, ) + #endif + } + + template + void multiply (float* dest, const float* src1, const float* src2, Size 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 + } + + template + void multiply (double* dest, const double* src1, const double* src2, Size 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 + } + + template + void multiply (float* dest, float multiplier, Size num) noexcept + { + #if JUCE_USE_VDSP_FRAMEWORK + vDSP_vsmul (dest, 1, &multiplier, dest, 1, (vDSP_Length) num); + #else + JUCE_PERFORM_VEC_OP_DEST (dest[i] *= multiplier, + Mode::mul (d, mult), + JUCE_LOAD_DEST, + const Mode::ParallelType mult = Mode::load1 (multiplier);) + #endif + } + + template + void multiply (double* dest, double multiplier, Size num) noexcept + { + #if JUCE_USE_VDSP_FRAMEWORK + vDSP_vsmulD (dest, 1, &multiplier, dest, 1, (vDSP_Length) num); + #else + JUCE_PERFORM_VEC_OP_DEST (dest[i] *= multiplier, + Mode::mul (d, mult), + JUCE_LOAD_DEST, + const Mode::ParallelType mult = Mode::load1 (multiplier);) + #endif + } + + template + void multiply (float* dest, const float* src, float multiplier, Size 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);) + } + + template + void multiply (double* dest, const double* src, double multiplier, Size 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);) + } + + template + void negate (float* dest, const float* src, Size num) noexcept + { + #if JUCE_USE_VDSP_FRAMEWORK + vDSP_vneg ((float*) src, 1, dest, 1, (vDSP_Length) num); + #else + copyWithMultiply (dest, src, -1.0f, num); + #endif + } + + template + void negate (double* dest, const double* src, Size num) noexcept + { + #if JUCE_USE_VDSP_FRAMEWORK + vDSP_vnegD ((double*) src, 1, dest, 1, (vDSP_Length) num); + #else + copyWithMultiply (dest, src, -1.0f, num); + #endif + } + + template + void abs (float* dest, const float* src, Size num) noexcept + { + #if JUCE_USE_VDSP_FRAMEWORK + vDSP_vabs ((float*) src, 1, dest, 1, (vDSP_Length) num); + #else + FloatVectorHelpers::signMask32 signMask; + signMask.i = 0x7fffffffUL; + JUCE_PERFORM_VEC_OP_SRC_DEST (dest[i] = std::abs (src[i]), + Mode::bit_and (s, mask), + JUCE_LOAD_SRC, + JUCE_INCREMENT_SRC_DEST, + const Mode::ParallelType mask = Mode::load1 (signMask.f);) + + ignoreUnused (signMask); + #endif + } + + template + void abs (double* dest, const double* src, Size num) noexcept + { + #if JUCE_USE_VDSP_FRAMEWORK + vDSP_vabsD ((double*) src, 1, dest, 1, (vDSP_Length) num); + #else + FloatVectorHelpers::signMask64 signMask; + signMask.i = 0x7fffffffffffffffULL; + + JUCE_PERFORM_VEC_OP_SRC_DEST (dest[i] = std::abs (src[i]), + Mode::bit_and (s, mask), + JUCE_LOAD_SRC, + JUCE_INCREMENT_SRC_DEST, + const Mode::ParallelType mask = Mode::load1 (signMask.d);) + + ignoreUnused (signMask); + #endif + } + + template + void min (float* dest, const float* src, float comp, Size num) noexcept + { + JUCE_PERFORM_VEC_OP_SRC_DEST (dest[i] = jmin (src[i], comp), + Mode::min (s, cmp), + JUCE_LOAD_SRC, + JUCE_INCREMENT_SRC_DEST, + const Mode::ParallelType cmp = Mode::load1 (comp);) + } + + template + void min (double* dest, const double* src, double comp, Size num) noexcept + { + JUCE_PERFORM_VEC_OP_SRC_DEST (dest[i] = jmin (src[i], comp), + Mode::min (s, cmp), + JUCE_LOAD_SRC, + JUCE_INCREMENT_SRC_DEST, + const Mode::ParallelType cmp = Mode::load1 (comp);) + } + + template + void min (float* dest, const float* src1, const float* src2, Size num) noexcept + { + #if JUCE_USE_VDSP_FRAMEWORK + vDSP_vmin ((float*) src1, 1, (float*) src2, 1, dest, 1, (vDSP_Length) num); + #else + JUCE_PERFORM_VEC_OP_SRC1_SRC2_DEST (dest[i] = jmin (src1[i], src2[i]), + Mode::min (s1, s2), + JUCE_LOAD_SRC1_SRC2, + JUCE_INCREMENT_SRC1_SRC2_DEST, ) + #endif + } + + template + void min (double* dest, const double* src1, const double* src2, Size num) noexcept + { + #if JUCE_USE_VDSP_FRAMEWORK + vDSP_vminD ((double*) src1, 1, (double*) src2, 1, dest, 1, (vDSP_Length) num); + #else + JUCE_PERFORM_VEC_OP_SRC1_SRC2_DEST (dest[i] = jmin (src1[i], src2[i]), + Mode::min (s1, s2), + JUCE_LOAD_SRC1_SRC2, + JUCE_INCREMENT_SRC1_SRC2_DEST, ) + #endif + } + + template + void max (float* dest, const float* src, float comp, Size num) noexcept + { + JUCE_PERFORM_VEC_OP_SRC_DEST (dest[i] = jmax (src[i], comp), + Mode::max (s, cmp), + JUCE_LOAD_SRC, + JUCE_INCREMENT_SRC_DEST, + const Mode::ParallelType cmp = Mode::load1 (comp);) + } + + template + void max (double* dest, const double* src, double comp, Size num) noexcept + { + JUCE_PERFORM_VEC_OP_SRC_DEST (dest[i] = jmax (src[i], comp), + Mode::max (s, cmp), + JUCE_LOAD_SRC, + JUCE_INCREMENT_SRC_DEST, + const Mode::ParallelType cmp = Mode::load1 (comp);) + } + + template + void max (float* dest, const float* src1, const float* src2, Size num) noexcept + { + #if JUCE_USE_VDSP_FRAMEWORK + vDSP_vmax ((float*) src1, 1, (float*) src2, 1, dest, 1, (vDSP_Length) num); + #else + JUCE_PERFORM_VEC_OP_SRC1_SRC2_DEST (dest[i] = jmax (src1[i], src2[i]), + Mode::max (s1, s2), + JUCE_LOAD_SRC1_SRC2, + JUCE_INCREMENT_SRC1_SRC2_DEST, ) + #endif + } + + template + void max (double* dest, const double* src1, const double* src2, Size num) noexcept + { + #if JUCE_USE_VDSP_FRAMEWORK + vDSP_vmaxD ((double*) src1, 1, (double*) src2, 1, dest, 1, (vDSP_Length) num); + #else + JUCE_PERFORM_VEC_OP_SRC1_SRC2_DEST (dest[i] = jmax (src1[i], src2[i]), + Mode::max (s1, s2), + JUCE_LOAD_SRC1_SRC2, + JUCE_INCREMENT_SRC1_SRC2_DEST, ) + #endif + } + + template + void clip (float* dest, const float* src, float low, float high, Size num) noexcept + { + jassert (high >= low); + + #if JUCE_USE_VDSP_FRAMEWORK + vDSP_vclip ((float*) src, 1, &low, &high, dest, 1, (vDSP_Length) num); + #else + JUCE_PERFORM_VEC_OP_SRC_DEST (dest[i] = jmax (jmin (src[i], high), low), + Mode::max (Mode::min (s, hi), lo), + JUCE_LOAD_SRC, + JUCE_INCREMENT_SRC_DEST, + const Mode::ParallelType lo = Mode::load1 (low); + const Mode::ParallelType hi = Mode::load1 (high);) + #endif + } + + template + void clip (double* dest, const double* src, double low, double high, Size num) noexcept + { + jassert (high >= low); + + #if JUCE_USE_VDSP_FRAMEWORK + vDSP_vclipD ((double*) src, 1, &low, &high, dest, 1, (vDSP_Length) num); + #else + JUCE_PERFORM_VEC_OP_SRC_DEST (dest[i] = jmax (jmin (src[i], high), low), + Mode::max (Mode::min (s, hi), lo), + JUCE_LOAD_SRC, + JUCE_INCREMENT_SRC_DEST, + const Mode::ParallelType lo = Mode::load1 (low); + const Mode::ParallelType hi = Mode::load1 (high);) + #endif + } + + template + Range findMinAndMax (const float* src, Size num) noexcept + { + #if JUCE_USE_SSE_INTRINSICS || JUCE_USE_ARM_NEON + return FloatVectorHelpers::MinMax::findMinAndMax (src, num); + #else + return Range::findMinAndMax (src, num); + #endif + } + + template + Range findMinAndMax (const double* src, Size num) noexcept + { + #if JUCE_USE_SSE_INTRINSICS || JUCE_USE_ARM_NEON + return FloatVectorHelpers::MinMax::findMinAndMax (src, num); + #else + return Range::findMinAndMax (src, num); + #endif + } + + template + float findMinimum (const float* src, Size num) noexcept + { + #if JUCE_USE_SSE_INTRINSICS || JUCE_USE_ARM_NEON + return FloatVectorHelpers::MinMax::findMinOrMax (src, num, true); + #else + return juce::findMinimum (src, num); + #endif + } + + template + double findMinimum (const double* src, Size num) noexcept + { + #if JUCE_USE_SSE_INTRINSICS || JUCE_USE_ARM_NEON + return FloatVectorHelpers::MinMax::findMinOrMax (src, num, true); + #else + return juce::findMinimum (src, num); + #endif + } + + template + float findMaximum (const float* src, Size num) noexcept + { + #if JUCE_USE_SSE_INTRINSICS || JUCE_USE_ARM_NEON + return FloatVectorHelpers::MinMax::findMinOrMax (src, num, false); + #else + return juce::findMaximum (src, num); + #endif + } + + template + double findMaximum (const double* src, Size num) noexcept + { + #if JUCE_USE_SSE_INTRINSICS || JUCE_USE_ARM_NEON + return FloatVectorHelpers::MinMax::findMinOrMax (src, num, false); + #else + return juce::findMaximum (src, num); + #endif + } + + template + void convertFixedToFloat (float* dest, const int* src, float multiplier, Size num) noexcept + { + #if JUCE_USE_ARM_NEON + JUCE_PERFORM_VEC_OP_SRC_DEST (dest[i] = (float) src[i] * multiplier, + vmulq_n_f32 (vcvtq_f32_s32 (vld1q_s32 (src)), multiplier), + JUCE_LOAD_NONE, + JUCE_INCREMENT_SRC_DEST, ) + #else + JUCE_PERFORM_VEC_OP_SRC_DEST (dest[i] = (float) src[i] * multiplier, + Mode::mul (mult, _mm_cvtepi32_ps (_mm_loadu_si128 (reinterpret_cast (src)))), + JUCE_LOAD_NONE, + JUCE_INCREMENT_SRC_DEST, + const Mode::ParallelType mult = Mode::load1 (multiplier);) + #endif + } + +} // namespace +} // namespace FloatVectorHelpers //============================================================================== -void JUCE_CALLTYPE FloatVectorOperations::clear (float* dest, int num) noexcept +template +void JUCE_CALLTYPE detail::FloatVectorOperationsBase::clear (FloatType* dest, + CountType numValues) noexcept { - #if JUCE_USE_VDSP_FRAMEWORK - vDSP_vclr (dest, 1, (size_t) num); - #else - zeromem (dest, (size_t) num * sizeof (float)); - #endif + FloatVectorHelpers::clear (dest, numValues); } -void JUCE_CALLTYPE FloatVectorOperations::clear (double* dest, int num) noexcept +template +void JUCE_CALLTYPE detail::FloatVectorOperationsBase::fill (FloatType* dest, + FloatType valueToFill, + CountType numValues) noexcept { - #if JUCE_USE_VDSP_FRAMEWORK - vDSP_vclrD (dest, 1, (size_t) num); - #else - zeromem (dest, (size_t) num * sizeof (double)); - #endif + FloatVectorHelpers::fill (dest, valueToFill, numValues); } -void JUCE_CALLTYPE FloatVectorOperations::fill (float* dest, float valueToFill, int num) noexcept +template +void JUCE_CALLTYPE detail::FloatVectorOperationsBase::copy (FloatType* dest, + const FloatType* src, + CountType numValues) noexcept { - #if JUCE_USE_VDSP_FRAMEWORK - vDSP_vfill (&valueToFill, dest, 1, (size_t) num); - #else - JUCE_PERFORM_VEC_OP_DEST (dest[i] = valueToFill, val, JUCE_LOAD_NONE, - const Mode::ParallelType val = Mode::load1 (valueToFill);) - #endif + memcpy (dest, src, (size_t) numValues * sizeof (FloatType)); } -void JUCE_CALLTYPE FloatVectorOperations::fill (double* dest, double valueToFill, int num) noexcept +template +void JUCE_CALLTYPE detail::FloatVectorOperationsBase::copyWithMultiply (FloatType* dest, + const FloatType* src, + FloatType multiplier, + CountType numValues) noexcept { - #if JUCE_USE_VDSP_FRAMEWORK - vDSP_vfillD (&valueToFill, dest, 1, (size_t) num); - #else - JUCE_PERFORM_VEC_OP_DEST (dest[i] = valueToFill, val, JUCE_LOAD_NONE, - const Mode::ParallelType val = Mode::load1 (valueToFill);) - #endif + FloatVectorHelpers::copyWithMultiply (dest, src, multiplier, numValues); } -void JUCE_CALLTYPE FloatVectorOperations::copy (float* dest, const float* src, int num) noexcept +template +void JUCE_CALLTYPE detail::FloatVectorOperationsBase::add (FloatType* dest, + FloatType amountToAdd, + CountType numValues) noexcept { - memcpy (dest, src, (size_t) num * sizeof (float)); + FloatVectorHelpers::add (dest, amountToAdd, numValues); } -void JUCE_CALLTYPE FloatVectorOperations::copy (double* dest, const double* src, int num) noexcept +template +void JUCE_CALLTYPE detail::FloatVectorOperationsBase::add (FloatType* dest, + const FloatType* src, + FloatType amount, + CountType numValues) noexcept { - memcpy (dest, src, (size_t) num * sizeof (double)); + FloatVectorHelpers::add (dest, src, amount, numValues); } -void JUCE_CALLTYPE FloatVectorOperations::copyWithMultiply (float* dest, const float* src, float multiplier, int num) noexcept +template +void JUCE_CALLTYPE detail::FloatVectorOperationsBase::add (FloatType* dest, + const FloatType* src, + CountType numValues) noexcept { - #if JUCE_USE_VDSP_FRAMEWORK - vDSP_vsmul (src, 1, &multiplier, dest, 1, (vDSP_Length) num); - #else - 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);) - #endif + FloatVectorHelpers::add (dest, src, numValues); } -void JUCE_CALLTYPE FloatVectorOperations::copyWithMultiply (double* dest, const double* src, double multiplier, int num) noexcept +template +void JUCE_CALLTYPE detail::FloatVectorOperationsBase::add (FloatType* dest, + const FloatType* src1, + const FloatType* src2, + CountType num) noexcept { - #if JUCE_USE_VDSP_FRAMEWORK - vDSP_vsmulD (src, 1, &multiplier, dest, 1, (vDSP_Length) num); - #else - 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);) - #endif + FloatVectorHelpers::add (dest, src1, src2, num); } -void JUCE_CALLTYPE FloatVectorOperations::add (float* dest, float amount, int num) noexcept +template +void JUCE_CALLTYPE detail::FloatVectorOperationsBase::subtract (FloatType* dest, + const FloatType* src, + CountType numValues) noexcept { - #if JUCE_USE_VDSP_FRAMEWORK - vDSP_vsadd (dest, 1, &amount, dest, 1, (vDSP_Length) num); - #else - JUCE_PERFORM_VEC_OP_DEST (dest[i] += amount, Mode::add (d, amountToAdd), JUCE_LOAD_DEST, - const Mode::ParallelType amountToAdd = Mode::load1 (amount);) - #endif + FloatVectorHelpers::subtract (dest, src, numValues); } -void JUCE_CALLTYPE FloatVectorOperations::add (double* dest, double amount, int num) noexcept +template +void JUCE_CALLTYPE detail::FloatVectorOperationsBase::subtract (FloatType* dest, + const FloatType* src1, + const FloatType* src2, + CountType num) noexcept { - JUCE_PERFORM_VEC_OP_DEST (dest[i] += amount, Mode::add (d, amountToAdd), JUCE_LOAD_DEST, - const Mode::ParallelType amountToAdd = Mode::load1 (amount);) + FloatVectorHelpers::subtract (dest, src1, src2, num); } -void JUCE_CALLTYPE FloatVectorOperations::add (float* dest, const float* src, float amount, int num) noexcept +template +void JUCE_CALLTYPE detail::FloatVectorOperationsBase::addWithMultiply (FloatType* dest, + const FloatType* src, + FloatType multiplier, + CountType numValues) noexcept { - #if JUCE_USE_VDSP_FRAMEWORK - vDSP_vsadd (osx108sdkCompatibilityCast (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 + FloatVectorHelpers::addWithMultiply (dest, src, multiplier, numValues); } -void JUCE_CALLTYPE FloatVectorOperations::add (double* dest, const double* src, double amount, int num) noexcept +template +void JUCE_CALLTYPE detail::FloatVectorOperationsBase::addWithMultiply (FloatType* dest, + const FloatType* src1, + const FloatType* src2, + CountType num) noexcept { - #if JUCE_USE_VDSP_FRAMEWORK - vDSP_vsaddD (osx108sdkCompatibilityCast (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 + FloatVectorHelpers::addWithMultiply (dest, src1, src2, num); } -void JUCE_CALLTYPE FloatVectorOperations::add (float* dest, const float* src, int num) noexcept +template +void JUCE_CALLTYPE detail::FloatVectorOperationsBase::subtractWithMultiply (FloatType* dest, + const FloatType* src, + FloatType multiplier, + CountType numValues) noexcept { - #if JUCE_USE_VDSP_FRAMEWORK - vDSP_vadd (src, 1, dest, 1, dest, 1, (vDSP_Length) num); - #else - JUCE_PERFORM_VEC_OP_SRC_DEST (dest[i] += src[i], Mode::add (d, s), JUCE_LOAD_SRC_DEST, JUCE_INCREMENT_SRC_DEST, ) - #endif + FloatVectorHelpers::subtractWithMultiply (dest, src, multiplier, numValues); } -void JUCE_CALLTYPE FloatVectorOperations::add (double* dest, const double* src, int num) noexcept +template +void JUCE_CALLTYPE detail::FloatVectorOperationsBase::subtractWithMultiply (FloatType* dest, + const FloatType* src1, + const FloatType* src2, + CountType num) noexcept { - #if JUCE_USE_VDSP_FRAMEWORK - vDSP_vaddD (src, 1, dest, 1, dest, 1, (vDSP_Length) num); - #else - JUCE_PERFORM_VEC_OP_SRC_DEST (dest[i] += src[i], Mode::add (d, s), JUCE_LOAD_SRC_DEST, JUCE_INCREMENT_SRC_DEST, ) - #endif + FloatVectorHelpers::subtractWithMultiply (dest, src1, src2, num); } -void JUCE_CALLTYPE FloatVectorOperations::add (float* dest, const float* src1, const float* src2, int num) noexcept +template +void JUCE_CALLTYPE detail::FloatVectorOperationsBase::multiply (FloatType* dest, + const FloatType* src, + CountType numValues) 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 + FloatVectorHelpers::multiply (dest, src, numValues); } -void JUCE_CALLTYPE FloatVectorOperations::add (double* dest, const double* src1, const double* src2, int num) noexcept +template +void JUCE_CALLTYPE detail::FloatVectorOperationsBase::multiply (FloatType* dest, + const FloatType* src1, + const FloatType* src2, + CountType numValues) 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 + FloatVectorHelpers::multiply (dest, src1, src2, numValues); } -void JUCE_CALLTYPE FloatVectorOperations::subtract (float* dest, const float* src, int num) noexcept +template +void JUCE_CALLTYPE detail::FloatVectorOperationsBase::multiply (FloatType* dest, + FloatType multiplier, + CountType numValues) noexcept { - #if JUCE_USE_VDSP_FRAMEWORK - vDSP_vsub (src, 1, dest, 1, dest, 1, (vDSP_Length) num); - #else - JUCE_PERFORM_VEC_OP_SRC_DEST (dest[i] -= src[i], Mode::sub (d, s), JUCE_LOAD_SRC_DEST, JUCE_INCREMENT_SRC_DEST, ) - #endif + FloatVectorHelpers::multiply (dest, multiplier, numValues); } -void JUCE_CALLTYPE FloatVectorOperations::subtract (double* dest, const double* src, int num) noexcept +template +void JUCE_CALLTYPE detail::FloatVectorOperationsBase::multiply (FloatType* dest, + const FloatType* src, + FloatType multiplier, + CountType num) noexcept { - #if JUCE_USE_VDSP_FRAMEWORK - vDSP_vsubD (src, 1, dest, 1, dest, 1, (vDSP_Length) num); - #else - JUCE_PERFORM_VEC_OP_SRC_DEST (dest[i] -= src[i], Mode::sub (d, s), JUCE_LOAD_SRC_DEST, JUCE_INCREMENT_SRC_DEST, ) - #endif + FloatVectorHelpers::multiply (dest, src, multiplier, num); } -void JUCE_CALLTYPE FloatVectorOperations::subtract (float* dest, const float* src1, const float* src2, int num) noexcept +template +void JUCE_CALLTYPE detail::FloatVectorOperationsBase::negate (FloatType* dest, + const FloatType* src, + CountType numValues) 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 + FloatVectorHelpers::negate (dest, src, numValues); } -void JUCE_CALLTYPE FloatVectorOperations::subtract (double* dest, const double* src1, const double* src2, int num) noexcept +template +void JUCE_CALLTYPE detail::FloatVectorOperationsBase::abs (FloatType* dest, + const FloatType* src, + CountType numValues) 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 + FloatVectorHelpers::abs (dest, src, numValues); } -void JUCE_CALLTYPE FloatVectorOperations::addWithMultiply (float* dest, const float* src, float multiplier, int num) noexcept +template +void JUCE_CALLTYPE detail::FloatVectorOperationsBase::min (FloatType* dest, + const FloatType* src, + FloatType comp, + CountType num) noexcept { - #if JUCE_USE_VDSP_FRAMEWORK - vDSP_vsma (src, 1, &multiplier, dest, 1, dest, 1, (vDSP_Length) num); - #else - JUCE_PERFORM_VEC_OP_SRC_DEST (dest[i] += src[i] * multiplier, Mode::add (d, Mode::mul (mult, s)), - JUCE_LOAD_SRC_DEST, JUCE_INCREMENT_SRC_DEST, - const Mode::ParallelType mult = Mode::load1 (multiplier);) - #endif + FloatVectorHelpers::min (dest, src, comp, num); } -void JUCE_CALLTYPE FloatVectorOperations::addWithMultiply (double* dest, const double* src, double multiplier, int num) noexcept +template +void JUCE_CALLTYPE detail::FloatVectorOperationsBase::min (FloatType* dest, + const FloatType* src1, + const FloatType* src2, + CountType num) noexcept { - #if JUCE_USE_VDSP_FRAMEWORK - vDSP_vsmaD (src, 1, &multiplier, dest, 1, dest, 1, (vDSP_Length) num); - #else - JUCE_PERFORM_VEC_OP_SRC_DEST (dest[i] += src[i] * multiplier, Mode::add (d, Mode::mul (mult, s)), - JUCE_LOAD_SRC_DEST, JUCE_INCREMENT_SRC_DEST, - const Mode::ParallelType mult = Mode::load1 (multiplier);) - #endif + FloatVectorHelpers::min (dest, src1, src2, num); } -void JUCE_CALLTYPE FloatVectorOperations::addWithMultiply (float* dest, const float* src1, const float* src2, int num) noexcept +template +void JUCE_CALLTYPE detail::FloatVectorOperationsBase::max (FloatType* dest, + const FloatType* src, + FloatType comp, + CountType num) noexcept { - #if JUCE_USE_VDSP_FRAMEWORK - vDSP_vma ((float*) src1, 1, (float*) src2, 1, dest, 1, dest, 1, (vDSP_Length) num); - #else - JUCE_PERFORM_VEC_OP_SRC1_SRC2_DEST_DEST (dest[i] += src1[i] * src2[i], Mode::add (d, Mode::mul (s1, s2)), - JUCE_LOAD_SRC1_SRC2_DEST, - JUCE_INCREMENT_SRC1_SRC2_DEST, ) - #endif + FloatVectorHelpers::max (dest, src, comp, num); } -void JUCE_CALLTYPE FloatVectorOperations::addWithMultiply (double* dest, const double* src1, const double* src2, int num) noexcept +template +void JUCE_CALLTYPE detail::FloatVectorOperationsBase::max (FloatType* dest, + const FloatType* src1, + const FloatType* src2, + CountType num) noexcept { - #if JUCE_USE_VDSP_FRAMEWORK - vDSP_vmaD ((double*) src1, 1, (double*) src2, 1, dest, 1, dest, 1, (vDSP_Length) num); - #else - JUCE_PERFORM_VEC_OP_SRC1_SRC2_DEST_DEST (dest[i] += src1[i] * src2[i], Mode::add (d, Mode::mul (s1, s2)), - JUCE_LOAD_SRC1_SRC2_DEST, - JUCE_INCREMENT_SRC1_SRC2_DEST, ) - #endif + FloatVectorHelpers::max (dest, src1, src2, num); } -void JUCE_CALLTYPE FloatVectorOperations::subtractWithMultiply (float* dest, const float* src, float multiplier, int num) noexcept +template +void JUCE_CALLTYPE detail::FloatVectorOperationsBase::clip (FloatType* dest, + const FloatType* src, + FloatType low, + FloatType high, + CountType num) noexcept { - JUCE_PERFORM_VEC_OP_SRC_DEST (dest[i] -= src[i] * multiplier, Mode::sub (d, Mode::mul (mult, s)), - JUCE_LOAD_SRC_DEST, JUCE_INCREMENT_SRC_DEST, - const Mode::ParallelType mult = Mode::load1 (multiplier);) + FloatVectorHelpers::clip (dest, src, low, high, num); } -void JUCE_CALLTYPE FloatVectorOperations::subtractWithMultiply (double* dest, const double* src, double multiplier, int num) noexcept +template +Range JUCE_CALLTYPE detail::FloatVectorOperationsBase::findMinAndMax (const FloatType* src, + CountType numValues) noexcept { - JUCE_PERFORM_VEC_OP_SRC_DEST (dest[i] -= src[i] * multiplier, Mode::sub (d, Mode::mul (mult, s)), - JUCE_LOAD_SRC_DEST, JUCE_INCREMENT_SRC_DEST, - const Mode::ParallelType mult = Mode::load1 (multiplier);) + return FloatVectorHelpers::findMinAndMax (src, numValues); } -void JUCE_CALLTYPE FloatVectorOperations::subtractWithMultiply (float* dest, const float* src1, const float* src2, int num) noexcept +template +FloatType JUCE_CALLTYPE detail::FloatVectorOperationsBase::findMinimum (const FloatType* src, + CountType numValues) noexcept { - JUCE_PERFORM_VEC_OP_SRC1_SRC2_DEST_DEST (dest[i] -= src1[i] * src2[i], Mode::sub (d, Mode::mul (s1, s2)), - JUCE_LOAD_SRC1_SRC2_DEST, - JUCE_INCREMENT_SRC1_SRC2_DEST, ) + return FloatVectorHelpers::findMinimum (src, numValues); } -void JUCE_CALLTYPE FloatVectorOperations::subtractWithMultiply (double* dest, const double* src1, const double* src2, int num) noexcept +template +FloatType JUCE_CALLTYPE detail::FloatVectorOperationsBase::findMaximum (const FloatType* src, + CountType numValues) noexcept { - JUCE_PERFORM_VEC_OP_SRC1_SRC2_DEST_DEST (dest[i] -= src1[i] * src2[i], Mode::sub (d, Mode::mul (s1, s2)), - JUCE_LOAD_SRC1_SRC2_DEST, - JUCE_INCREMENT_SRC1_SRC2_DEST, ) + return FloatVectorHelpers::findMaximum (src, numValues); } -void JUCE_CALLTYPE FloatVectorOperations::multiply (float* dest, const float* src, int num) noexcept +template struct detail::FloatVectorOperationsBase; +template struct detail::FloatVectorOperationsBase; +template struct detail::FloatVectorOperationsBase; +template struct detail::FloatVectorOperationsBase; + +void JUCE_CALLTYPE FloatVectorOperations::convertFixedToFloat (float* dest, const int* src, float multiplier, size_t num) noexcept { - #if JUCE_USE_VDSP_FRAMEWORK - vDSP_vmul (src, 1, dest, 1, dest, 1, (vDSP_Length) num); - #else - JUCE_PERFORM_VEC_OP_SRC_DEST (dest[i] *= src[i], Mode::mul (d, s), JUCE_LOAD_SRC_DEST, JUCE_INCREMENT_SRC_DEST, ) - #endif -} - -void JUCE_CALLTYPE FloatVectorOperations::multiply (double* dest, const double* src, int num) noexcept -{ - #if JUCE_USE_VDSP_FRAMEWORK - vDSP_vmulD (src, 1, dest, 1, dest, 1, (vDSP_Length) num); - #else - JUCE_PERFORM_VEC_OP_SRC_DEST (dest[i] *= src[i], Mode::mul (d, s), JUCE_LOAD_SRC_DEST, JUCE_INCREMENT_SRC_DEST, ) - #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 - vDSP_vsmul (dest, 1, &multiplier, dest, 1, (vDSP_Length) num); - #else - JUCE_PERFORM_VEC_OP_DEST (dest[i] *= multiplier, Mode::mul (d, mult), JUCE_LOAD_DEST, - const Mode::ParallelType mult = Mode::load1 (multiplier);) - #endif -} - -void JUCE_CALLTYPE FloatVectorOperations::multiply (double* dest, double multiplier, int num) noexcept -{ - #if JUCE_USE_VDSP_FRAMEWORK - vDSP_vsmulD (dest, 1, &multiplier, dest, 1, (vDSP_Length) num); - #else - JUCE_PERFORM_VEC_OP_DEST (dest[i] *= multiplier, Mode::mul (d, mult), JUCE_LOAD_DEST, - const Mode::ParallelType mult = Mode::load1 (multiplier);) - #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 - vDSP_vneg ((float*) src, 1, dest, 1, (vDSP_Length) num); - #else - copyWithMultiply (dest, src, -1.0f, num); - #endif -} - -void FloatVectorOperations::negate (double* dest, const double* src, int num) noexcept -{ - #if JUCE_USE_VDSP_FRAMEWORK - vDSP_vnegD ((double*) src, 1, dest, 1, (vDSP_Length) num); - #else - copyWithMultiply (dest, src, -1.0f, num); - #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 - FloatVectorHelpers::signMask32 signMask; - signMask.i = 0x7fffffffUL; - JUCE_PERFORM_VEC_OP_SRC_DEST (dest[i] = std::abs (src[i]), Mode::bit_and (s, mask), - JUCE_LOAD_SRC, JUCE_INCREMENT_SRC_DEST, - const Mode::ParallelType mask = Mode::load1 (signMask.f);) - - ignoreUnused (signMask); - #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 - FloatVectorHelpers::signMask64 signMask; - signMask.i = 0x7fffffffffffffffULL; - - JUCE_PERFORM_VEC_OP_SRC_DEST (dest[i] = std::abs (src[i]), Mode::bit_and (s, mask), - JUCE_LOAD_SRC, JUCE_INCREMENT_SRC_DEST, - const Mode::ParallelType mask = Mode::load1 (signMask.d);) - - ignoreUnused (signMask); - #endif + FloatVectorHelpers::convertFixedToFloat (dest, src, multiplier, num); } void JUCE_CALLTYPE FloatVectorOperations::convertFixedToFloat (float* dest, const int* src, float multiplier, int num) noexcept { - #if JUCE_USE_ARM_NEON - JUCE_PERFORM_VEC_OP_SRC_DEST (dest[i] = (float) src[i] * multiplier, - vmulq_n_f32 (vcvtq_f32_s32 (vld1q_s32 (src)), multiplier), - JUCE_LOAD_NONE, JUCE_INCREMENT_SRC_DEST, ) - #else - JUCE_PERFORM_VEC_OP_SRC_DEST (dest[i] = (float) src[i] * multiplier, - Mode::mul (mult, _mm_cvtepi32_ps (_mm_loadu_si128 (reinterpret_cast (src)))), - JUCE_LOAD_NONE, JUCE_INCREMENT_SRC_DEST, - const Mode::ParallelType mult = Mode::load1 (multiplier);) - #endif -} - -void JUCE_CALLTYPE FloatVectorOperations::min (float* dest, const float* src, float comp, int num) noexcept -{ - JUCE_PERFORM_VEC_OP_SRC_DEST (dest[i] = jmin (src[i], comp), Mode::min (s, cmp), - JUCE_LOAD_SRC, JUCE_INCREMENT_SRC_DEST, - const Mode::ParallelType cmp = Mode::load1 (comp);) -} - -void JUCE_CALLTYPE FloatVectorOperations::min (double* dest, const double* src, double comp, int num) noexcept -{ - JUCE_PERFORM_VEC_OP_SRC_DEST (dest[i] = jmin (src[i], comp), Mode::min (s, cmp), - JUCE_LOAD_SRC, JUCE_INCREMENT_SRC_DEST, - const Mode::ParallelType cmp = Mode::load1 (comp);) -} - -void JUCE_CALLTYPE FloatVectorOperations::min (float* dest, const float* src1, const float* src2, int num) noexcept -{ - #if JUCE_USE_VDSP_FRAMEWORK - vDSP_vmin ((float*) src1, 1, (float*) src2, 1, dest, 1, (vDSP_Length) num); - #else - JUCE_PERFORM_VEC_OP_SRC1_SRC2_DEST (dest[i] = jmin (src1[i], src2[i]), Mode::min (s1, s2), JUCE_LOAD_SRC1_SRC2, JUCE_INCREMENT_SRC1_SRC2_DEST, ) - #endif -} - -void JUCE_CALLTYPE FloatVectorOperations::min (double* dest, const double* src1, const double* src2, int num) noexcept -{ - #if JUCE_USE_VDSP_FRAMEWORK - vDSP_vminD ((double*) src1, 1, (double*) src2, 1, dest, 1, (vDSP_Length) num); - #else - JUCE_PERFORM_VEC_OP_SRC1_SRC2_DEST (dest[i] = jmin (src1[i], src2[i]), Mode::min (s1, s2), JUCE_LOAD_SRC1_SRC2, JUCE_INCREMENT_SRC1_SRC2_DEST, ) - #endif -} - -void JUCE_CALLTYPE FloatVectorOperations::max (float* dest, const float* src, float comp, int num) noexcept -{ - JUCE_PERFORM_VEC_OP_SRC_DEST (dest[i] = jmax (src[i], comp), Mode::max (s, cmp), - JUCE_LOAD_SRC, JUCE_INCREMENT_SRC_DEST, - const Mode::ParallelType cmp = Mode::load1 (comp);) -} - -void JUCE_CALLTYPE FloatVectorOperations::max (double* dest, const double* src, double comp, int num) noexcept -{ - JUCE_PERFORM_VEC_OP_SRC_DEST (dest[i] = jmax (src[i], comp), Mode::max (s, cmp), - JUCE_LOAD_SRC, JUCE_INCREMENT_SRC_DEST, - const Mode::ParallelType cmp = Mode::load1 (comp);) -} - -void JUCE_CALLTYPE FloatVectorOperations::max (float* dest, const float* src1, const float* src2, int num) noexcept -{ - #if JUCE_USE_VDSP_FRAMEWORK - vDSP_vmax ((float*) src1, 1, (float*) src2, 1, dest, 1, (vDSP_Length) num); - #else - JUCE_PERFORM_VEC_OP_SRC1_SRC2_DEST (dest[i] = jmax (src1[i], src2[i]), Mode::max (s1, s2), JUCE_LOAD_SRC1_SRC2, JUCE_INCREMENT_SRC1_SRC2_DEST, ) - #endif -} - -void JUCE_CALLTYPE FloatVectorOperations::max (double* dest, const double* src1, const double* src2, int num) noexcept -{ - #if JUCE_USE_VDSP_FRAMEWORK - vDSP_vmaxD ((double*) src1, 1, (double*) src2, 1, dest, 1, (vDSP_Length) num); - #else - JUCE_PERFORM_VEC_OP_SRC1_SRC2_DEST (dest[i] = jmax (src1[i], src2[i]), Mode::max (s1, s2), JUCE_LOAD_SRC1_SRC2, JUCE_INCREMENT_SRC1_SRC2_DEST, ) - #endif -} - -void JUCE_CALLTYPE FloatVectorOperations::clip (float* dest, const float* src, float low, float high, int num) noexcept -{ - jassert(high >= low); - - #if JUCE_USE_VDSP_FRAMEWORK - vDSP_vclip ((float*) src, 1, &low, &high, dest, 1, (vDSP_Length) num); - #else - JUCE_PERFORM_VEC_OP_SRC_DEST (dest[i] = jmax (jmin (src[i], high), low), Mode::max (Mode::min (s, hi), lo), - JUCE_LOAD_SRC, JUCE_INCREMENT_SRC_DEST, - const Mode::ParallelType lo = Mode::load1 (low); const Mode::ParallelType hi = Mode::load1 (high);) - #endif -} - -void JUCE_CALLTYPE FloatVectorOperations::clip (double* dest, const double* src, double low, double high, int num) noexcept -{ - jassert(high >= low); - - #if JUCE_USE_VDSP_FRAMEWORK - vDSP_vclipD ((double*) src, 1, &low, &high, dest, 1, (vDSP_Length) num); - #else - JUCE_PERFORM_VEC_OP_SRC_DEST (dest[i] = jmax (jmin (src[i], high), low), Mode::max (Mode::min (s, hi), lo), - JUCE_LOAD_SRC, JUCE_INCREMENT_SRC_DEST, - const Mode::ParallelType lo = Mode::load1 (low); const Mode::ParallelType hi = Mode::load1 (high);) - #endif -} - -Range JUCE_CALLTYPE FloatVectorOperations::findMinAndMax (const float* src, int num) noexcept -{ - #if JUCE_USE_SSE_INTRINSICS || JUCE_USE_ARM_NEON - return FloatVectorHelpers::MinMax::findMinAndMax (src, num); - #else - return Range::findMinAndMax (src, num); - #endif -} - -Range JUCE_CALLTYPE FloatVectorOperations::findMinAndMax (const double* src, int num) noexcept -{ - #if JUCE_USE_SSE_INTRINSICS || JUCE_USE_ARM_NEON - return FloatVectorHelpers::MinMax::findMinAndMax (src, num); - #else - return Range::findMinAndMax (src, num); - #endif -} - -float JUCE_CALLTYPE FloatVectorOperations::findMinimum (const float* src, int num) noexcept -{ - #if JUCE_USE_SSE_INTRINSICS || JUCE_USE_ARM_NEON - return FloatVectorHelpers::MinMax::findMinOrMax (src, num, true); - #else - return juce::findMinimum (src, num); - #endif -} - -double JUCE_CALLTYPE FloatVectorOperations::findMinimum (const double* src, int num) noexcept -{ - #if JUCE_USE_SSE_INTRINSICS || JUCE_USE_ARM_NEON - return FloatVectorHelpers::MinMax::findMinOrMax (src, num, true); - #else - return juce::findMinimum (src, num); - #endif -} - -float JUCE_CALLTYPE FloatVectorOperations::findMaximum (const float* src, int num) noexcept -{ - #if JUCE_USE_SSE_INTRINSICS || JUCE_USE_ARM_NEON - return FloatVectorHelpers::MinMax::findMinOrMax (src, num, false); - #else - return juce::findMaximum (src, num); - #endif -} - -double JUCE_CALLTYPE FloatVectorOperations::findMaximum (const double* src, int num) noexcept -{ - #if JUCE_USE_SSE_INTRINSICS || JUCE_USE_ARM_NEON - return FloatVectorHelpers::MinMax::findMinOrMax (src, num, false); - #else - return juce::findMaximum (src, num); - #endif + FloatVectorHelpers::convertFixedToFloat (dest, src, multiplier, num); } intptr_t JUCE_CALLTYPE FloatVectorOperations::getFpStatusRegister() noexcept @@ -1033,14 +1432,16 @@ intptr_t JUCE_CALLTYPE FloatVectorOperations::getFpStatusRegister() noexcept intptr_t fpsr = 0; #if JUCE_INTEL && JUCE_USE_SSE_INTRINSICS fpsr = static_cast (_mm_getcsr()); - #elif defined (__arm64__) || defined (__aarch64__) || JUCE_USE_ARM_NEON - #if defined (__arm64__) || defined (__aarch64__) - asm volatile("mrs %0, fpcr" : "=r" (fpsr)); + #elif defined(__arm64__) || defined(__aarch64__) || JUCE_USE_ARM_NEON + #if defined(__arm64__) || defined(__aarch64__) + asm volatile("mrs %0, fpcr" + : "=r"(fpsr)); #elif JUCE_USE_ARM_NEON - asm volatile("vmrs %0, fpscr" : "=r" (fpsr)); + asm volatile("vmrs %0, fpscr" + : "=r"(fpsr)); #endif #else - #if ! (defined (JUCE_INTEL) || defined (JUCE_ARM)) + #if ! (defined(JUCE_INTEL) || defined(JUCE_ARM)) jassertfalse; // No support for getting the floating point status register for your platform #endif #endif @@ -1055,14 +1456,18 @@ void JUCE_CALLTYPE FloatVectorOperations::setFpStatusRegister (intptr_t fpsr) no // which aggressively optimises away the variable otherwise volatile auto fpsr_w = static_cast (fpsr); _mm_setcsr (fpsr_w); - #elif defined (__arm64__) || defined (__aarch64__) || JUCE_USE_ARM_NEON - #if defined (__arm64__) || defined (__aarch64__) - asm volatile("msr fpcr, %0" : : "ri" (fpsr)); + #elif defined(__arm64__) || defined(__aarch64__) || JUCE_USE_ARM_NEON + #if defined(__arm64__) || defined(__aarch64__) + asm volatile("msr fpcr, %0" + : + : "ri"(fpsr)); #elif JUCE_USE_ARM_NEON - asm volatile("vmsr fpscr, %0" : : "ri" (fpsr)); + asm volatile("vmsr fpscr, %0" + : + : "ri"(fpsr)); #endif #else - #if ! (defined (JUCE_INTEL) || defined (JUCE_ARM)) + #if ! (defined(JUCE_INTEL) || defined(JUCE_ARM)) jassertfalse; // No support for getting the floating point status register for your platform #endif ignoreUnused (fpsr); @@ -1071,7 +1476,7 @@ void JUCE_CALLTYPE FloatVectorOperations::setFpStatusRegister (intptr_t fpsr) no void JUCE_CALLTYPE FloatVectorOperations::enableFlushToZeroMode (bool shouldEnable) noexcept { - #if JUCE_USE_SSE_INTRINSICS || (JUCE_USE_ARM_NEON || defined (__arm64__) || defined (__aarch64__)) + #if JUCE_USE_SSE_INTRINSICS || (JUCE_USE_ARM_NEON || defined(__arm64__) || defined(__aarch64__)) #if JUCE_USE_SSE_INTRINSICS intptr_t mask = _MM_FLUSH_ZERO_MASK; #else /*JUCE_USE_ARM_NEON*/ @@ -1079,7 +1484,7 @@ void JUCE_CALLTYPE FloatVectorOperations::enableFlushToZeroMode (bool shouldEnab #endif setFpStatusRegister ((getFpStatusRegister() & (~mask)) | (shouldEnable ? mask : 0)); #else - #if ! (defined (JUCE_INTEL) || defined (JUCE_ARM)) + #if ! (defined(JUCE_INTEL) || defined(JUCE_ARM)) jassertfalse; // No support for flush to zero mode on your platform #endif ignoreUnused (shouldEnable); @@ -1088,7 +1493,7 @@ void JUCE_CALLTYPE FloatVectorOperations::enableFlushToZeroMode (bool shouldEnab void JUCE_CALLTYPE FloatVectorOperations::disableDenormalisedNumberSupport (bool shouldDisable) noexcept { - #if JUCE_USE_SSE_INTRINSICS || (JUCE_USE_ARM_NEON || defined (__arm64__) || defined (__aarch64__)) + #if JUCE_USE_SSE_INTRINSICS || (JUCE_USE_ARM_NEON || defined(__arm64__) || defined(__aarch64__)) #if JUCE_USE_SSE_INTRINSICS intptr_t mask = 0x8040; #else /*JUCE_USE_ARM_NEON*/ @@ -1099,7 +1504,7 @@ void JUCE_CALLTYPE FloatVectorOperations::disableDenormalisedNumberSupport (bool #else ignoreUnused (shouldDisable); - #if ! (defined (JUCE_INTEL) || defined (JUCE_ARM)) + #if ! (defined(JUCE_INTEL) || defined(JUCE_ARM)) jassertfalse; // No support for disable denormals mode on your platform #endif #endif @@ -1107,7 +1512,7 @@ void JUCE_CALLTYPE FloatVectorOperations::disableDenormalisedNumberSupport (bool bool JUCE_CALLTYPE FloatVectorOperations::areDenormalsDisabled() noexcept { - #if JUCE_USE_SSE_INTRINSICS || (JUCE_USE_ARM_NEON || defined (__arm64__) || defined (__aarch64__)) + #if JUCE_USE_SSE_INTRINSICS || (JUCE_USE_ARM_NEON || defined(__arm64__) || defined(__aarch64__)) #if JUCE_USE_SSE_INTRINSICS intptr_t mask = 0x8040; #else /*JUCE_USE_ARM_NEON*/ @@ -1122,7 +1527,7 @@ bool JUCE_CALLTYPE FloatVectorOperations::areDenormalsDisabled() noexcept ScopedNoDenormals::ScopedNoDenormals() noexcept { - #if JUCE_USE_SSE_INTRINSICS || (JUCE_USE_ARM_NEON || defined (__arm64__) || defined (__aarch64__)) + #if JUCE_USE_SSE_INTRINSICS || (JUCE_USE_ARM_NEON || defined(__arm64__) || defined(__aarch64__)) #if JUCE_USE_SSE_INTRINSICS intptr_t mask = 0x8040; #else /*JUCE_USE_ARM_NEON*/ @@ -1136,9 +1541,9 @@ ScopedNoDenormals::ScopedNoDenormals() noexcept ScopedNoDenormals::~ScopedNoDenormals() noexcept { - #if JUCE_USE_SSE_INTRINSICS || (JUCE_USE_ARM_NEON || defined (__arm64__) || defined (__aarch64__)) + #if JUCE_USE_SSE_INTRINSICS || (JUCE_USE_ARM_NEON || defined(__arm64__) || defined(__aarch64__)) FloatVectorOperations::setFpStatusRegister (fpsr); - #endif + #endif } diff --git a/modules/juce_audio_basics/buffers/juce_FloatVectorOperations.h b/modules/juce_audio_basics/buffers/juce_FloatVectorOperations.h index 928815a630..ea1be4ed91 100644 --- a/modules/juce_audio_basics/buffers/juce_FloatVectorOperations.h +++ b/modules/juce_audio_basics/buffers/juce_FloatVectorOperations.h @@ -32,6 +32,106 @@ namespace juce #endif class ScopedNoDenormals; + +namespace detail +{ + +template +struct FloatVectorOperationsBase +{ + static void JUCE_CALLTYPE clear (FloatType* dest, CountType numValues) noexcept; + static void JUCE_CALLTYPE fill (FloatType* dest, FloatType valueToFill, CountType numValues) noexcept; + static void JUCE_CALLTYPE copy (FloatType* dest, const FloatType* src, CountType numValues) noexcept; + static void JUCE_CALLTYPE copyWithMultiply (FloatType* dest, const FloatType* src, FloatType multiplier, CountType numValues) noexcept; + static void JUCE_CALLTYPE add (FloatType* dest, FloatType amountToAdd, CountType numValues) noexcept; + static void JUCE_CALLTYPE add (FloatType* dest, const FloatType* src, FloatType amount, CountType numValues) noexcept; + static void JUCE_CALLTYPE add (FloatType* dest, const FloatType* src, CountType numValues) noexcept; + static void JUCE_CALLTYPE add (FloatType* dest, const FloatType* src1, const FloatType* src2, CountType num) noexcept; + static void JUCE_CALLTYPE subtract (FloatType* dest, const FloatType* src, CountType numValues) noexcept; + static void JUCE_CALLTYPE subtract (FloatType* dest, const FloatType* src1, const FloatType* src2, CountType num) noexcept; + static void JUCE_CALLTYPE addWithMultiply (FloatType* dest, const FloatType* src, FloatType multiplier, CountType numValues) noexcept; + static void JUCE_CALLTYPE addWithMultiply (FloatType* dest, const FloatType* src1, const FloatType* src2, CountType num) noexcept; + static void JUCE_CALLTYPE subtractWithMultiply (FloatType* dest, const FloatType* src, FloatType multiplier, CountType numValues) noexcept; + static void JUCE_CALLTYPE subtractWithMultiply (FloatType* dest, const FloatType* src1, const FloatType* src2, CountType num) noexcept; + static void JUCE_CALLTYPE multiply (FloatType* dest, const FloatType* src, CountType numValues) noexcept; + static void JUCE_CALLTYPE multiply (FloatType* dest, const FloatType* src1, const FloatType* src2, CountType numValues) noexcept; + static void JUCE_CALLTYPE multiply (FloatType* dest, FloatType multiplier, CountType numValues) noexcept; + static void JUCE_CALLTYPE multiply (FloatType* dest, const FloatType* src, FloatType multiplier, CountType num) noexcept; + static void JUCE_CALLTYPE negate (FloatType* dest, const FloatType* src, CountType numValues) noexcept; + static void JUCE_CALLTYPE abs (FloatType* dest, const FloatType* src, CountType numValues) noexcept; + static void JUCE_CALLTYPE min (FloatType* dest, const FloatType* src, FloatType comp, CountType num) noexcept; + static void JUCE_CALLTYPE min (FloatType* dest, const FloatType* src1, const FloatType* src2, CountType num) noexcept; + static void JUCE_CALLTYPE max (FloatType* dest, const FloatType* src, FloatType comp, CountType num) noexcept; + static void JUCE_CALLTYPE max (FloatType* dest, const FloatType* src1, const FloatType* src2, CountType num) noexcept; + static void JUCE_CALLTYPE clip (FloatType* dest, const FloatType* src, FloatType low, FloatType high, CountType num) noexcept; + static Range JUCE_CALLTYPE findMinAndMax (const FloatType* src, CountType numValues) noexcept; + static FloatType JUCE_CALLTYPE findMinimum (const FloatType* src, CountType numValues) noexcept; + static FloatType JUCE_CALLTYPE findMaximum (const FloatType* src, CountType numValues) noexcept; +}; + +template +struct NameForwarder; + +template +struct NameForwarder : Head {}; + +template +struct NameForwarder : Head, NameForwarder +{ + using Head::clear; + using NameForwarder::clear; + + using Head::fill; + using NameForwarder::fill; + + using Head::copy; + using NameForwarder::copy; + + using Head::copyWithMultiply; + using NameForwarder::copyWithMultiply; + + using Head::add; + using NameForwarder::add; + + using Head::subtract; + using NameForwarder::subtract; + + using Head::addWithMultiply; + using NameForwarder::addWithMultiply; + + using Head::subtractWithMultiply; + using NameForwarder::subtractWithMultiply; + + using Head::multiply; + using NameForwarder::multiply; + + using Head::negate; + using NameForwarder::negate; + + using Head::abs; + using NameForwarder::abs; + + using Head::min; + using NameForwarder::min; + + using Head::max; + using NameForwarder::max; + + using Head::clip; + using NameForwarder::clip; + + using Head::findMinAndMax; + using NameForwarder::findMinAndMax; + + using Head::findMinimum; + using NameForwarder::findMinimum; + + using Head::findMaximum; + using NameForwarder::findMaximum; +}; + +} // namespace detail + //============================================================================== /** A collection of simple vector operations on arrays of floats, accelerated with @@ -39,180 +139,15 @@ class ScopedNoDenormals; @tags{Audio} */ -class JUCE_API FloatVectorOperations +class JUCE_API FloatVectorOperations : public detail::NameForwarder, + detail::FloatVectorOperationsBase, + detail::FloatVectorOperationsBase, + detail::FloatVectorOperationsBase> { public: - //============================================================================== - /** Clears a vector of floats. */ - static void JUCE_CALLTYPE clear (float* dest, int numValues) noexcept; + static void JUCE_CALLTYPE convertFixedToFloat (float* dest, const int* src, float multiplier, int num) noexcept; - /** Clears a vector of doubles. */ - static void JUCE_CALLTYPE clear (double* dest, int numValues) noexcept; - - /** Copies a repeated value into a vector of floats. */ - static void JUCE_CALLTYPE fill (float* dest, float valueToFill, int numValues) noexcept; - - /** Copies a repeated value into a vector of doubles. */ - static void JUCE_CALLTYPE fill (double* dest, double valueToFill, int numValues) noexcept; - - /** Copies a vector of floats. */ - static void JUCE_CALLTYPE copy (float* dest, const float* src, int numValues) noexcept; - - /** Copies a vector of doubles. */ - static void JUCE_CALLTYPE copy (double* dest, const double* src, int numValues) noexcept; - - /** Copies a vector of floats, multiplying each value by a given multiplier */ - static void JUCE_CALLTYPE copyWithMultiply (float* dest, const float* src, float multiplier, int numValues) noexcept; - - /** Copies a vector of doubles, multiplying each value by a given multiplier */ - static void JUCE_CALLTYPE copyWithMultiply (double* dest, const double* src, double multiplier, int numValues) noexcept; - - /** Adds a fixed value to the destination values. */ - static void JUCE_CALLTYPE add (float* dest, float amountToAdd, int numValues) noexcept; - - /** 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, const 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, const 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; - - /** Multiplies each source value by the given multiplier, then adds it to the destination value. */ - static void JUCE_CALLTYPE addWithMultiply (double* dest, const double* src, double multiplier, int numValues) noexcept; - - /** Multiplies each source1 value by the corresponding source2 value, then adds it to the destination value. */ - static void JUCE_CALLTYPE addWithMultiply (float* dest, const float* src1, const float* src2, int num) noexcept; - - /** Multiplies each source1 value by the corresponding source2 value, then adds it to the destination value. */ - static void JUCE_CALLTYPE addWithMultiply (double* dest, const double* src1, const double* src2, int num) noexcept; - - /** Multiplies each source value by the given multiplier, then subtracts it to the destination value. */ - static void JUCE_CALLTYPE subtractWithMultiply (float* dest, const float* src, float multiplier, int numValues) noexcept; - - /** Multiplies each source value by the given multiplier, then subtracts it to the destination value. */ - static void JUCE_CALLTYPE subtractWithMultiply (double* dest, const double* src, double multiplier, int numValues) noexcept; - - /** Multiplies each source1 value by the corresponding source2 value, then subtracts it to the destination value. */ - static void JUCE_CALLTYPE subtractWithMultiply (float* dest, const float* src1, const float* src2, int num) noexcept; - - /** Multiplies each source1 value by the corresponding source2 value, then subtracts it to the destination value. */ - static void JUCE_CALLTYPE subtractWithMultiply (double* dest, const double* src1, const double* src2, int num) noexcept; - - /** Multiplies the destination values by the source values. */ - static void JUCE_CALLTYPE multiply (float* dest, const float* src, int numValues) noexcept; - - /** 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; - - /** 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; - - /** Each element of dest will be the minimum of the corresponding element of the source array and the given comp value. */ - static void JUCE_CALLTYPE min (float* dest, const float* src, float comp, int num) noexcept; - - /** Each element of dest will be the minimum of the corresponding element of the source array and the given comp value. */ - static void JUCE_CALLTYPE min (double* dest, const double* src, double comp, int num) noexcept; - - /** Each element of dest will be the minimum of the corresponding source1 and source2 values. */ - static void JUCE_CALLTYPE min (float* dest, const float* src1, const float* src2, int num) noexcept; - - /** Each element of dest will be the minimum of the corresponding source1 and source2 values. */ - static void JUCE_CALLTYPE min (double* dest, const double* src1, const double* src2, int num) noexcept; - - /** Each element of dest will be the maximum of the corresponding element of the source array and the given comp value. */ - static void JUCE_CALLTYPE max (float* dest, const float* src, float comp, int num) noexcept; - - /** Each element of dest will be the maximum of the corresponding element of the source array and the given comp value. */ - static void JUCE_CALLTYPE max (double* dest, const double* src, double comp, int num) noexcept; - - /** Each element of dest will be the maximum of the corresponding source1 and source2 values. */ - static void JUCE_CALLTYPE max (float* dest, const float* src1, const float* src2, int num) noexcept; - - /** Each element of dest will be the maximum of the corresponding source1 and source2 values. */ - static void JUCE_CALLTYPE max (double* dest, const double* src1, const double* src2, int num) noexcept; - - /** Each element of dest is calculated by hard clipping the corresponding src element so that it is in the range specified by the arguments low and high. */ - static void JUCE_CALLTYPE clip (float* dest, const float* src, float low, float high, int num) noexcept; - - /** Each element of dest is calculated by hard clipping the corresponding src element so that it is in the range specified by the arguments low and high. */ - static void JUCE_CALLTYPE clip (double* dest, const double* src, double low, double high, int num) noexcept; - - /** Finds the minimum and maximum values in the given array. */ - static Range JUCE_CALLTYPE findMinAndMax (const float* src, int numValues) noexcept; - - /** Finds the minimum and maximum values in the given array. */ - static Range JUCE_CALLTYPE findMinAndMax (const double* src, int numValues) noexcept; - - /** Finds the minimum value in the given array. */ - static float JUCE_CALLTYPE findMinimum (const float* src, int numValues) noexcept; - - /** Finds the minimum value in the given array. */ - static double JUCE_CALLTYPE findMinimum (const double* src, int numValues) noexcept; - - /** Finds the maximum value in the given array. */ - static float JUCE_CALLTYPE findMaximum (const float* src, int numValues) noexcept; - - /** Finds the maximum value in the given array. */ - static double JUCE_CALLTYPE findMaximum (const double* src, int numValues) noexcept; + static void JUCE_CALLTYPE convertFixedToFloat (float* dest, const int* src, float multiplier, size_t num) noexcept; /** This method enables or disables the SSE/NEON flush-to-zero mode. */ static void JUCE_CALLTYPE enableFlushToZeroMode (bool shouldEnable) noexcept; diff --git a/modules/juce_core/maths/juce_Range.h b/modules/juce_core/maths/juce_Range.h index 89ffc0c026..bf540d81f4 100644 --- a/modules/juce_core/maths/juce_Range.h +++ b/modules/juce_core/maths/juce_Range.h @@ -270,7 +270,8 @@ public: } /** Scans an array of values for its min and max, and returns these as a Range. */ - static Range findMinAndMax (const ValueType* values, int numValues) noexcept + template ::value, int> = 0> + static Range findMinAndMax (const ValueType* values, Integral numValues) noexcept { if (numValues <= 0) return Range();