26namespace FloatVectorHelpers
28 #define JUCE_INCREMENT_SRC_DEST dest += (16 / sizeof (*dest)); src += (16 / sizeof (*dest));
29 #define JUCE_INCREMENT_SRC1_SRC2_DEST dest += (16 / sizeof (*dest)); src1 += (16 / sizeof (*dest)); src2 += (16 / sizeof (*dest));
30 #define JUCE_INCREMENT_DEST dest += (16 / sizeof (*dest));
32 #if JUCE_USE_SSE_INTRINSICS
33 inline static bool isAligned (
const void* p)
noexcept
35 return (((pointer_sized_int) p) & 15) == 0;
41 using ParallelType = __m128;
42 using IntegerType = __m128;
43 enum { numParallel = 4 };
46 static forcedinline IntegerType toint (ParallelType v)
noexcept {
return v; }
47 static forcedinline ParallelType toflt (IntegerType v)
noexcept {
return v; }
49 static forcedinline ParallelType load1 (Type v)
noexcept {
return _mm_load1_ps (&v); }
50 static forcedinline ParallelType loadA (
const Type* v)
noexcept {
return _mm_load_ps (v); }
51 static forcedinline ParallelType loadU (
const Type* v)
noexcept {
return _mm_loadu_ps (v); }
52 static forcedinline
void storeA (Type* dest, ParallelType a)
noexcept { _mm_store_ps (dest, a); }
53 static forcedinline
void storeU (Type* dest, ParallelType a)
noexcept { _mm_storeu_ps (dest, a); }
55 static forcedinline ParallelType add (ParallelType a, ParallelType b)
noexcept {
return _mm_add_ps (a, b); }
56 static forcedinline ParallelType sub (ParallelType a, ParallelType b)
noexcept {
return _mm_sub_ps (a, b); }
57 static forcedinline ParallelType mul (ParallelType a, ParallelType b)
noexcept {
return _mm_mul_ps (a, b); }
58 static forcedinline ParallelType max (ParallelType a, ParallelType b)
noexcept {
return _mm_max_ps (a, b); }
59 static forcedinline ParallelType min (ParallelType a, ParallelType b)
noexcept {
return _mm_min_ps (a, b); }
61 static forcedinline ParallelType bit_and (ParallelType a, ParallelType b)
noexcept {
return _mm_and_ps (a, b); }
62 static forcedinline ParallelType bit_not (ParallelType a, ParallelType b)
noexcept {
return _mm_andnot_ps (a, b); }
63 static forcedinline ParallelType bit_or (ParallelType a, ParallelType b)
noexcept {
return _mm_or_ps (a, b); }
64 static forcedinline ParallelType bit_xor (ParallelType a, ParallelType b)
noexcept {
return _mm_xor_ps (a, b); }
66 static forcedinline Type max (ParallelType a)
noexcept { Type v[numParallel]; storeU (v, a);
return jmax (v[0], v[1], v[2], v[3]); }
67 static forcedinline Type min (ParallelType a)
noexcept { Type v[numParallel]; storeU (v, a);
return jmin (v[0], v[1], v[2], v[3]); }
73 using ParallelType = __m128d;
74 using IntegerType = __m128d;
75 enum { numParallel = 2 };
78 static forcedinline IntegerType toint (ParallelType v)
noexcept {
return v; }
79 static forcedinline ParallelType toflt (IntegerType v)
noexcept {
return v; }
81 static forcedinline ParallelType load1 (Type v)
noexcept {
return _mm_load1_pd (&v); }
82 static forcedinline ParallelType loadA (
const Type* v)
noexcept {
return _mm_load_pd (v); }
83 static forcedinline ParallelType loadU (
const Type* v)
noexcept {
return _mm_loadu_pd (v); }
84 static forcedinline
void storeA (Type* dest, ParallelType a)
noexcept { _mm_store_pd (dest, a); }
85 static forcedinline
void storeU (Type* dest, ParallelType a)
noexcept { _mm_storeu_pd (dest, a); }
87 static forcedinline ParallelType add (ParallelType a, ParallelType b)
noexcept {
return _mm_add_pd (a, b); }
88 static forcedinline ParallelType sub (ParallelType a, ParallelType b)
noexcept {
return _mm_sub_pd (a, b); }
89 static forcedinline ParallelType mul (ParallelType a, ParallelType b)
noexcept {
return _mm_mul_pd (a, b); }
90 static forcedinline ParallelType max (ParallelType a, ParallelType b)
noexcept {
return _mm_max_pd (a, b); }
91 static forcedinline ParallelType min (ParallelType a, ParallelType b)
noexcept {
return _mm_min_pd (a, b); }
93 static forcedinline ParallelType bit_and (ParallelType a, ParallelType b)
noexcept {
return _mm_and_pd (a, b); }
94 static forcedinline ParallelType bit_not (ParallelType a, ParallelType b)
noexcept {
return _mm_andnot_pd (a, b); }
95 static forcedinline ParallelType bit_or (ParallelType a, ParallelType b)
noexcept {
return _mm_or_pd (a, b); }
96 static forcedinline ParallelType bit_xor (ParallelType a, ParallelType b)
noexcept {
return _mm_xor_pd (a, b); }
98 static forcedinline Type max (ParallelType a)
noexcept { Type v[numParallel]; storeU (v, a);
return jmax (v[0], v[1]); }
99 static forcedinline Type min (ParallelType a)
noexcept { Type v[numParallel]; storeU (v, a);
return jmin (v[0], v[1]); }
104 #define JUCE_BEGIN_VEC_OP \
105 using Mode = FloatVectorHelpers::ModeType<sizeof(*dest)>::Mode; \
107 const int numLongOps = num / Mode::numParallel;
109 #define JUCE_FINISH_VEC_OP(normalOp) \
110 num &= (Mode::numParallel - 1); \
111 if (num == 0) return; \
113 for (int i = 0; i < num; ++i) normalOp;
115 #define JUCE_PERFORM_VEC_OP_DEST(normalOp, vecOp, locals, setupOp) \
118 if (FloatVectorHelpers::isAligned (dest)) JUCE_VEC_LOOP (vecOp, dummy, Mode::loadA, Mode::storeA, locals, JUCE_INCREMENT_DEST) \
119 else JUCE_VEC_LOOP (vecOp, dummy, Mode::loadU, Mode::storeU, locals, JUCE_INCREMENT_DEST) \
120 JUCE_FINISH_VEC_OP (normalOp)
122 #define JUCE_PERFORM_VEC_OP_SRC_DEST(normalOp, vecOp, locals, increment, setupOp) \
125 if (FloatVectorHelpers::isAligned (dest)) \
127 if (FloatVectorHelpers::isAligned (src)) JUCE_VEC_LOOP (vecOp, Mode::loadA, Mode::loadA, Mode::storeA, locals, increment) \
128 else JUCE_VEC_LOOP (vecOp, Mode::loadU, Mode::loadA, Mode::storeA, locals, increment) \
132 if (FloatVectorHelpers::isAligned (src)) JUCE_VEC_LOOP (vecOp, Mode::loadA, Mode::loadU, Mode::storeU, locals, increment) \
133 else JUCE_VEC_LOOP (vecOp, Mode::loadU, Mode::loadU, Mode::storeU, locals, increment) \
135 JUCE_FINISH_VEC_OP (normalOp)
137 #define JUCE_PERFORM_VEC_OP_SRC1_SRC2_DEST(normalOp, vecOp, locals, increment, setupOp) \
140 if (FloatVectorHelpers::isAligned (dest)) \
142 if (FloatVectorHelpers::isAligned (src1)) \
144 if (FloatVectorHelpers::isAligned (src2)) JUCE_VEC_LOOP_TWO_SOURCES (vecOp, Mode::loadA, Mode::loadA, Mode::storeA, locals, increment) \
145 else JUCE_VEC_LOOP_TWO_SOURCES (vecOp, Mode::loadA, Mode::loadU, Mode::storeA, locals, increment) \
149 if (FloatVectorHelpers::isAligned (src2)) JUCE_VEC_LOOP_TWO_SOURCES (vecOp, Mode::loadU, Mode::loadA, Mode::storeA, locals, increment) \
150 else JUCE_VEC_LOOP_TWO_SOURCES (vecOp, Mode::loadU, Mode::loadU, Mode::storeA, locals, increment) \
155 if (FloatVectorHelpers::isAligned (src1)) \
157 if (FloatVectorHelpers::isAligned (src2)) JUCE_VEC_LOOP_TWO_SOURCES (vecOp, Mode::loadA, Mode::loadA, Mode::storeU, locals, increment) \
158 else JUCE_VEC_LOOP_TWO_SOURCES (vecOp, Mode::loadA, Mode::loadU, Mode::storeU, locals, increment) \
162 if (FloatVectorHelpers::isAligned (src2)) JUCE_VEC_LOOP_TWO_SOURCES (vecOp, Mode::loadU, Mode::loadA, Mode::storeU, locals, increment) \
163 else JUCE_VEC_LOOP_TWO_SOURCES (vecOp, Mode::loadU, Mode::loadU, Mode::storeU, locals, increment) \
166 JUCE_FINISH_VEC_OP (normalOp)
168 #define JUCE_PERFORM_VEC_OP_SRC1_SRC2_DEST_DEST(normalOp, vecOp, locals, increment, setupOp) \
171 if (FloatVectorHelpers::isAligned (dest)) \
173 if (FloatVectorHelpers::isAligned (src1)) \
175 if (FloatVectorHelpers::isAligned (src2)) JUCE_VEC_LOOP_TWO_SOURCES_WITH_DEST_LOAD (vecOp, Mode::loadA, Mode::loadA, Mode::loadA, Mode::storeA, locals, increment) \
176 else JUCE_VEC_LOOP_TWO_SOURCES_WITH_DEST_LOAD (vecOp, Mode::loadA, Mode::loadU, Mode::loadA, Mode::storeA, locals, increment) \
180 if (FloatVectorHelpers::isAligned (src2)) JUCE_VEC_LOOP_TWO_SOURCES_WITH_DEST_LOAD (vecOp, Mode::loadU, Mode::loadA, Mode::loadA, Mode::storeA, locals, increment) \
181 else JUCE_VEC_LOOP_TWO_SOURCES_WITH_DEST_LOAD (vecOp, Mode::loadU, Mode::loadU, Mode::loadA, Mode::storeA, locals, increment) \
186 if (FloatVectorHelpers::isAligned (src1)) \
188 if (FloatVectorHelpers::isAligned (src2)) JUCE_VEC_LOOP_TWO_SOURCES_WITH_DEST_LOAD (vecOp, Mode::loadA, Mode::loadA, Mode::loadU, Mode::storeU, locals, increment) \
189 else JUCE_VEC_LOOP_TWO_SOURCES_WITH_DEST_LOAD (vecOp, Mode::loadA, Mode::loadU, Mode::loadU, Mode::storeU, locals, increment) \
193 if (FloatVectorHelpers::isAligned (src2)) JUCE_VEC_LOOP_TWO_SOURCES_WITH_DEST_LOAD (vecOp, Mode::loadU, Mode::loadA, Mode::loadU, Mode::storeU, locals, increment) \
194 else JUCE_VEC_LOOP_TWO_SOURCES_WITH_DEST_LOAD (vecOp, Mode::loadU, Mode::loadU, Mode::loadU, Mode::storeU, locals, increment) \
197 JUCE_FINISH_VEC_OP (normalOp)
201 #elif JUCE_USE_ARM_NEON
206 using ParallelType = float32x4_t;
207 using IntegerType = uint32x4_t;
208 union signMaskUnion { ParallelType f; IntegerType i; };
209 enum { numParallel = 4 };
211 static forcedinline IntegerType toint (ParallelType v)
noexcept { signMaskUnion u; u.f = v;
return u.i; }
212 static forcedinline ParallelType toflt (IntegerType v)
noexcept { signMaskUnion u; u.i = v;
return u.f; }
214 static forcedinline ParallelType load1 (Type v)
noexcept {
return vld1q_dup_f32 (&v); }
215 static forcedinline ParallelType loadA (
const Type* v)
noexcept {
return vld1q_f32 (v); }
216 static forcedinline ParallelType loadU (
const Type* v)
noexcept {
return vld1q_f32 (v); }
217 static forcedinline
void storeA (Type* dest, ParallelType a)
noexcept { vst1q_f32 (dest, a); }
218 static forcedinline
void storeU (Type* dest, ParallelType a)
noexcept { vst1q_f32 (dest, a); }
220 static forcedinline ParallelType add (ParallelType a, ParallelType b)
noexcept {
return vaddq_f32 (a, b); }
221 static forcedinline ParallelType sub (ParallelType a, ParallelType b)
noexcept {
return vsubq_f32 (a, b); }
222 static forcedinline ParallelType mul (ParallelType a, ParallelType b)
noexcept {
return vmulq_f32 (a, b); }
223 static forcedinline ParallelType max (ParallelType a, ParallelType b)
noexcept {
return vmaxq_f32 (a, b); }
224 static forcedinline ParallelType min (ParallelType a, ParallelType b)
noexcept {
return vminq_f32 (a, b); }
226 static forcedinline ParallelType bit_and (ParallelType a, ParallelType b)
noexcept {
return toflt (vandq_u32 (toint (a), toint (b))); }
227 static forcedinline ParallelType bit_not (ParallelType a, ParallelType b)
noexcept {
return toflt (vbicq_u32 (toint (a), toint (b))); }
228 static forcedinline ParallelType bit_or (ParallelType a, ParallelType b)
noexcept {
return toflt (vorrq_u32 (toint (a), toint (b))); }
229 static forcedinline ParallelType bit_xor (ParallelType a, ParallelType b)
noexcept {
return toflt (veorq_u32 (toint (a), toint (b))); }
231 static forcedinline Type max (ParallelType a)
noexcept { Type v[numParallel]; storeU (v, a);
return jmax (v[0], v[1], v[2], v[3]); }
232 static forcedinline Type min (ParallelType a)
noexcept { Type v[numParallel]; storeU (v, a);
return jmin (v[0], v[1], v[2], v[3]); }
238 using ParallelType = double;
239 using IntegerType = uint64;
240 union signMaskUnion { ParallelType f; IntegerType i; };
241 enum { numParallel = 1 };
243 static forcedinline IntegerType toint (ParallelType v)
noexcept { signMaskUnion u; u.f = v;
return u.i; }
244 static forcedinline ParallelType toflt (IntegerType v)
noexcept { signMaskUnion u; u.i = v;
return u.f; }
246 static forcedinline ParallelType load1 (Type v)
noexcept {
return v; }
247 static forcedinline ParallelType loadA (
const Type* v)
noexcept {
return *v; }
248 static forcedinline ParallelType loadU (
const Type* v)
noexcept {
return *v; }
249 static forcedinline
void storeA (Type* dest, ParallelType a)
noexcept { *dest = a; }
250 static forcedinline
void storeU (Type* dest, ParallelType a)
noexcept { *dest = a; }
252 static forcedinline ParallelType add (ParallelType a, ParallelType b)
noexcept {
return a + b; }
253 static forcedinline ParallelType sub (ParallelType a, ParallelType b)
noexcept {
return a - b; }
254 static forcedinline ParallelType mul (ParallelType a, ParallelType b)
noexcept {
return a * b; }
255 static forcedinline ParallelType max (ParallelType a, ParallelType b)
noexcept {
return jmax (a, b); }
256 static forcedinline ParallelType min (ParallelType a, ParallelType b)
noexcept {
return jmin (a, b); }
258 static forcedinline ParallelType bit_and (ParallelType a, ParallelType b)
noexcept {
return toflt (toint (a) & toint (b)); }
259 static forcedinline ParallelType bit_not (ParallelType a, ParallelType b)
noexcept {
return toflt ((~toint (a)) & toint (b)); }
260 static forcedinline ParallelType bit_or (ParallelType a, ParallelType b)
noexcept {
return toflt (toint (a) | toint (b)); }
261 static forcedinline ParallelType bit_xor (ParallelType a, ParallelType b)
noexcept {
return toflt (toint (a) ^ toint (b)); }
263 static forcedinline Type max (ParallelType a)
noexcept {
return a; }
264 static forcedinline Type min (ParallelType a)
noexcept {
return a; }
267 #define JUCE_BEGIN_VEC_OP \
268 using Mode = FloatVectorHelpers::ModeType<sizeof(*dest)>::Mode; \
269 if (Mode::numParallel > 1) \
271 const int numLongOps = num / Mode::numParallel;
273 #define JUCE_FINISH_VEC_OP(normalOp) \
274 num &= (Mode::numParallel - 1); \
275 if (num == 0) return; \
277 for (int i = 0; i < num; ++i) normalOp;
279 #define JUCE_PERFORM_VEC_OP_DEST(normalOp, vecOp, locals, setupOp) \
282 JUCE_VEC_LOOP (vecOp, dummy, Mode::loadU, Mode::storeU, locals, JUCE_INCREMENT_DEST) \
283 JUCE_FINISH_VEC_OP (normalOp)
285 #define JUCE_PERFORM_VEC_OP_SRC_DEST(normalOp, vecOp, locals, increment, setupOp) \
288 JUCE_VEC_LOOP (vecOp, Mode::loadU, Mode::loadU, Mode::storeU, locals, increment) \
289 JUCE_FINISH_VEC_OP (normalOp)
291 #define JUCE_PERFORM_VEC_OP_SRC1_SRC2_DEST(normalOp, vecOp, locals, increment, setupOp) \
294 JUCE_VEC_LOOP_TWO_SOURCES (vecOp, Mode::loadU, Mode::loadU, Mode::storeU, locals, increment) \
295 JUCE_FINISH_VEC_OP (normalOp)
297 #define JUCE_PERFORM_VEC_OP_SRC1_SRC2_DEST_DEST(normalOp, vecOp, locals, increment, setupOp) \
300 JUCE_VEC_LOOP_TWO_SOURCES_WITH_DEST_LOAD (vecOp, Mode::loadU, Mode::loadU, Mode::loadU, Mode::storeU, locals, increment) \
301 JUCE_FINISH_VEC_OP (normalOp)
306 #define JUCE_PERFORM_VEC_OP_DEST(normalOp, vecOp, locals, setupOp) \
307 for (int i = 0; i < num; ++i) normalOp;
309 #define JUCE_PERFORM_VEC_OP_SRC_DEST(normalOp, vecOp, locals, increment, setupOp) \
310 for (int i = 0; i < num; ++i) normalOp;
312 #define JUCE_PERFORM_VEC_OP_SRC1_SRC2_DEST(normalOp, vecOp, locals, increment, setupOp) \
313 for (int i = 0; i < num; ++i) normalOp;
315 #define JUCE_PERFORM_VEC_OP_SRC1_SRC2_DEST_DEST(normalOp, vecOp, locals, increment, setupOp) \
316 for (int i = 0; i < num; ++i) normalOp;
321 #define JUCE_VEC_LOOP(vecOp, srcLoad, dstLoad, dstStore, locals, increment) \
322 for (int i = 0; i < numLongOps; ++i) \
324 locals (srcLoad, dstLoad); \
325 dstStore (dest, vecOp); \
329 #define JUCE_VEC_LOOP_TWO_SOURCES(vecOp, src1Load, src2Load, dstStore, locals, increment) \
330 for (int i = 0; i < numLongOps; ++i) \
332 locals (src1Load, src2Load); \
333 dstStore (dest, vecOp); \
337 #define JUCE_VEC_LOOP_TWO_SOURCES_WITH_DEST_LOAD(vecOp, src1Load, src2Load, dstLoad, dstStore, locals, increment) \
338 for (int i = 0; i < numLongOps; ++i) \
340 locals (src1Load, src2Load, dstLoad); \
341 dstStore (dest, vecOp); \
345 #define JUCE_LOAD_NONE(srcLoad, dstLoad)
346 #define JUCE_LOAD_DEST(srcLoad, dstLoad) const Mode::ParallelType d = dstLoad (dest);
347 #define JUCE_LOAD_SRC(srcLoad, dstLoad) const Mode::ParallelType s = srcLoad (src);
348 #define JUCE_LOAD_SRC1_SRC2(src1Load, src2Load) const Mode::ParallelType s1 = src1Load (src1), s2 = src2Load (src2);
349 #define JUCE_LOAD_SRC1_SRC2_DEST(src1Load, src2Load, dstLoad) const Mode::ParallelType d = dstLoad (dest), s1 = src1Load (src1), s2 = src2Load (src2);
350 #define JUCE_LOAD_SRC_DEST(srcLoad, dstLoad) const Mode::ParallelType d = dstLoad (dest), s = srcLoad (src);
352 union signMask32 {
float f; uint32 i; };
353 union signMask64 {
double d; uint64 i; };
355 #if JUCE_USE_SSE_INTRINSICS || JUCE_USE_ARM_NEON
356 template<
int typeSize>
struct ModeType {
using Mode = BasicOps32; };
357 template<>
struct ModeType<8> {
using Mode = BasicOps64; };
359 template <
typename Mode>
362 using Type =
typename Mode::Type;
363 using ParallelType =
typename Mode::ParallelType;
365 static Type findMinOrMax (
const Type* src,
int num,
const bool isMinimum)
noexcept
367 int numLongOps = num / Mode::numParallel;
373 #if ! JUCE_USE_ARM_NEON
376 val = Mode::loadA (src);
380 while (--numLongOps > 0)
382 src += Mode::numParallel;
383 val = Mode::min (val, Mode::loadA (src));
388 while (--numLongOps > 0)
390 src += Mode::numParallel;
391 val = Mode::max (val, Mode::loadA (src));
398 val = Mode::loadU (src);
402 while (--numLongOps > 0)
404 src += Mode::numParallel;
405 val = Mode::min (val, Mode::loadU (src));
410 while (--numLongOps > 0)
412 src += Mode::numParallel;
413 val = Mode::max (val, Mode::loadU (src));
418 Type result = isMinimum ? Mode::min (val)
421 num &= (Mode::numParallel - 1);
422 src += Mode::numParallel;
424 for (
int i = 0; i < num; ++i)
425 result = isMinimum ? jmin (result, src[i])
426 : jmax (result, src[i]);
431 return isMinimum ? juce::findMinimum (src, num)
432 : juce::findMaximum (src, num);
435 static Range<Type> findMinAndMax (
const Type* src,
int num)
noexcept
437 int numLongOps = num / Mode::numParallel;
443 #if ! JUCE_USE_ARM_NEON
446 mn = Mode::loadA (src);
449 while (--numLongOps > 0)
451 src += Mode::numParallel;
452 const ParallelType v = Mode::loadA (src);
453 mn = Mode::min (mn, v);
454 mx = Mode::max (mx, v);
460 mn = Mode::loadU (src);
463 while (--numLongOps > 0)
465 src += Mode::numParallel;
466 const ParallelType v = Mode::loadU (src);
467 mn = Mode::min (mn, v);
468 mx = Mode::max (mx, v);
472 Range<Type> result (Mode::min (mn),
475 num &= (Mode::numParallel - 1);
476 src += Mode::numParallel;
478 for (
int i = 0; i < num; ++i)
479 result = result.getUnionWith (src[i]);
484 return Range<Type>::findMinAndMax (src, num);
493 #if JUCE_USE_VDSP_FRAMEWORK
496 template <
typename ValueType>
497 ValueType* osx108sdkCompatibilityCast (
const ValueType* arg)
noexcept {
return const_cast<ValueType*
> (arg); }
504 #if JUCE_USE_VDSP_FRAMEWORK
507 zeromem (dest, (
size_t)
num *
sizeof (
float));
513 #if JUCE_USE_VDSP_FRAMEWORK
516 zeromem (dest, (
size_t)
num *
sizeof (
double));
522 #if JUCE_USE_VDSP_FRAMEWORK
525 JUCE_PERFORM_VEC_OP_DEST (dest[i] =
valueToFill,
val, JUCE_LOAD_NONE,
532 #if JUCE_USE_VDSP_FRAMEWORK
535 JUCE_PERFORM_VEC_OP_DEST (dest[i] =
valueToFill,
val, JUCE_LOAD_NONE,
552 #if JUCE_USE_VDSP_FRAMEWORK
555 JUCE_PERFORM_VEC_OP_SRC_DEST (dest[i] =
src[i] *
multiplier, Mode::mul (
mult, s),
556 JUCE_LOAD_SRC, JUCE_INCREMENT_SRC_DEST,
563 #if JUCE_USE_VDSP_FRAMEWORK
566 JUCE_PERFORM_VEC_OP_SRC_DEST (dest[i] =
src[i] *
multiplier, Mode::mul (
mult, s),
567 JUCE_LOAD_SRC, JUCE_INCREMENT_SRC_DEST,
574 #if JUCE_USE_VDSP_FRAMEWORK
577 JUCE_PERFORM_VEC_OP_DEST (dest[i] +=
amount, Mode::add (d,
amountToAdd), JUCE_LOAD_DEST,
584 JUCE_PERFORM_VEC_OP_DEST (dest[i] +=
amount, Mode::add (d,
amountToAdd), JUCE_LOAD_DEST,
590 #if JUCE_USE_VDSP_FRAMEWORK
593 JUCE_PERFORM_VEC_OP_SRC_DEST (dest[i] =
src[i] +
amount, Mode::add (
am, s),
594 JUCE_LOAD_SRC, JUCE_INCREMENT_SRC_DEST,
595 const Mode::ParallelType
am = Mode::load1 (
amount);)
601 #if JUCE_USE_VDSP_FRAMEWORK
604 JUCE_PERFORM_VEC_OP_SRC_DEST (dest[i] =
src[i] +
amount, Mode::add (
am, s),
605 JUCE_LOAD_SRC, JUCE_INCREMENT_SRC_DEST,
606 const Mode::ParallelType
am = Mode::load1 (
amount);)
612 #if JUCE_USE_VDSP_FRAMEWORK
615 JUCE_PERFORM_VEC_OP_SRC_DEST (dest[i] +=
src[i], Mode::add (d, s), JUCE_LOAD_SRC_DEST, JUCE_INCREMENT_SRC_DEST, )
621 #if JUCE_USE_VDSP_FRAMEWORK
624 JUCE_PERFORM_VEC_OP_SRC_DEST (dest[i] +=
src[i], Mode::add (d, s), JUCE_LOAD_SRC_DEST, JUCE_INCREMENT_SRC_DEST, )
630 #if JUCE_USE_VDSP_FRAMEWORK
633 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, )
639 #if JUCE_USE_VDSP_FRAMEWORK
642 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, )
648 #if JUCE_USE_VDSP_FRAMEWORK
651 JUCE_PERFORM_VEC_OP_SRC_DEST (dest[i] -=
src[i], Mode::sub (d, s), JUCE_LOAD_SRC_DEST, JUCE_INCREMENT_SRC_DEST, )
657 #if JUCE_USE_VDSP_FRAMEWORK
660 JUCE_PERFORM_VEC_OP_SRC_DEST (dest[i] -=
src[i], Mode::sub (d, s), JUCE_LOAD_SRC_DEST, JUCE_INCREMENT_SRC_DEST, )
666 #if JUCE_USE_VDSP_FRAMEWORK
669 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, )
675 #if JUCE_USE_VDSP_FRAMEWORK
678 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, )
684 #if JUCE_USE_VDSP_FRAMEWORK
687 JUCE_PERFORM_VEC_OP_SRC_DEST (dest[i] +=
src[i] *
multiplier, Mode::add (d, Mode::mul (
mult, s)),
688 JUCE_LOAD_SRC_DEST, JUCE_INCREMENT_SRC_DEST,
695 #if JUCE_USE_VDSP_FRAMEWORK
698 JUCE_PERFORM_VEC_OP_SRC_DEST (dest[i] +=
src[i] *
multiplier, Mode::add (d, Mode::mul (
mult, s)),
699 JUCE_LOAD_SRC_DEST, JUCE_INCREMENT_SRC_DEST,
706 #if JUCE_USE_VDSP_FRAMEWORK
709 JUCE_PERFORM_VEC_OP_SRC1_SRC2_DEST_DEST (dest[i] +=
src1[i] *
src2[i], Mode::add (d, Mode::mul (s1, s2)),
710 JUCE_LOAD_SRC1_SRC2_DEST,
711 JUCE_INCREMENT_SRC1_SRC2_DEST, )
717 #if JUCE_USE_VDSP_FRAMEWORK
720 JUCE_PERFORM_VEC_OP_SRC1_SRC2_DEST_DEST (dest[i] +=
src1[i] *
src2[i], Mode::add (d, Mode::mul (s1, s2)),
721 JUCE_LOAD_SRC1_SRC2_DEST,
722 JUCE_INCREMENT_SRC1_SRC2_DEST, )
728 JUCE_PERFORM_VEC_OP_SRC_DEST (dest[i] -=
src[i] *
multiplier, Mode::sub (d, Mode::mul (
mult, s)),
729 JUCE_LOAD_SRC_DEST, JUCE_INCREMENT_SRC_DEST,
735 JUCE_PERFORM_VEC_OP_SRC_DEST (dest[i] -=
src[i] *
multiplier, Mode::sub (d, Mode::mul (
mult, s)),
736 JUCE_LOAD_SRC_DEST, JUCE_INCREMENT_SRC_DEST,
742 JUCE_PERFORM_VEC_OP_SRC1_SRC2_DEST_DEST (dest[i] -=
src1[i] *
src2[i], Mode::sub (d, Mode::mul (s1, s2)),
743 JUCE_LOAD_SRC1_SRC2_DEST,
744 JUCE_INCREMENT_SRC1_SRC2_DEST, )
749 JUCE_PERFORM_VEC_OP_SRC1_SRC2_DEST_DEST (dest[i] -=
src1[i] *
src2[i], Mode::sub (d, Mode::mul (s1, s2)),
750 JUCE_LOAD_SRC1_SRC2_DEST,
751 JUCE_INCREMENT_SRC1_SRC2_DEST, )
756 #if JUCE_USE_VDSP_FRAMEWORK
759 JUCE_PERFORM_VEC_OP_SRC_DEST (dest[i] *=
src[i], Mode::mul (d, s), JUCE_LOAD_SRC_DEST, JUCE_INCREMENT_SRC_DEST, )
765 #if JUCE_USE_VDSP_FRAMEWORK
768 JUCE_PERFORM_VEC_OP_SRC_DEST (dest[i] *=
src[i], Mode::mul (d, s), JUCE_LOAD_SRC_DEST, JUCE_INCREMENT_SRC_DEST, )
774 #if JUCE_USE_VDSP_FRAMEWORK
777 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, )
783 #if JUCE_USE_VDSP_FRAMEWORK
786 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, )
792 #if JUCE_USE_VDSP_FRAMEWORK
795 JUCE_PERFORM_VEC_OP_DEST (dest[i] *=
multiplier, Mode::mul (d,
mult), JUCE_LOAD_DEST,
802 #if JUCE_USE_VDSP_FRAMEWORK
805 JUCE_PERFORM_VEC_OP_DEST (dest[i] *=
multiplier, Mode::mul (d,
mult), JUCE_LOAD_DEST,
812 JUCE_PERFORM_VEC_OP_SRC_DEST (dest[i] =
src[i] *
multiplier, Mode::mul (
mult, s),
813 JUCE_LOAD_SRC, JUCE_INCREMENT_SRC_DEST,
819 JUCE_PERFORM_VEC_OP_SRC_DEST (dest[i] =
src[i] *
multiplier, Mode::mul (
mult, s),
820 JUCE_LOAD_SRC, JUCE_INCREMENT_SRC_DEST,
826 #if JUCE_USE_VDSP_FRAMEWORK
829 copyWithMultiply (dest,
src, -1.0f,
num);
835 #if JUCE_USE_VDSP_FRAMEWORK
838 copyWithMultiply (dest,
src, -1.0f,
num);
844 #if JUCE_USE_VDSP_FRAMEWORK
847 FloatVectorHelpers::signMask32
signMask;
849 JUCE_PERFORM_VEC_OP_SRC_DEST (dest[i] = std::abs (
src[i]), Mode::bit_and (s, mask),
850 JUCE_LOAD_SRC, JUCE_INCREMENT_SRC_DEST,
851 const Mode::ParallelType mask = Mode::load1 (
signMask.f);)
859 #if JUCE_USE_VDSP_FRAMEWORK
862 FloatVectorHelpers::signMask64
signMask;
865 JUCE_PERFORM_VEC_OP_SRC_DEST (dest[i] = std::abs (
src[i]), Mode::bit_and (s, mask),
866 JUCE_LOAD_SRC, JUCE_INCREMENT_SRC_DEST,
867 const Mode::ParallelType mask = Mode::load1 (
signMask.d);)
875 #if JUCE_USE_ARM_NEON
878 JUCE_LOAD_NONE, JUCE_INCREMENT_SRC_DEST, )
880 JUCE_PERFORM_VEC_OP_SRC_DEST (dest[i] = (
float)
src[i] *
multiplier,
882 JUCE_LOAD_NONE, JUCE_INCREMENT_SRC_DEST,
889 JUCE_PERFORM_VEC_OP_SRC_DEST (dest[i] = jmin (
src[i], comp), Mode::min (s, cmp),
890 JUCE_LOAD_SRC, JUCE_INCREMENT_SRC_DEST,
891 const Mode::ParallelType cmp = Mode::load1 (comp);)
896 JUCE_PERFORM_VEC_OP_SRC_DEST (dest[i] = jmin (
src[i], comp), Mode::min (s, cmp),
897 JUCE_LOAD_SRC, JUCE_INCREMENT_SRC_DEST,
898 const Mode::ParallelType cmp = Mode::load1 (comp);)
903 #if JUCE_USE_VDSP_FRAMEWORK
906 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, )
912 #if JUCE_USE_VDSP_FRAMEWORK
915 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, )
921 JUCE_PERFORM_VEC_OP_SRC_DEST (dest[i] = jmax (
src[i], comp), Mode::max (s, cmp),
922 JUCE_LOAD_SRC, JUCE_INCREMENT_SRC_DEST,
923 const Mode::ParallelType cmp = Mode::load1 (comp);)
928 JUCE_PERFORM_VEC_OP_SRC_DEST (dest[i] = jmax (
src[i], comp), Mode::max (s, cmp),
929 JUCE_LOAD_SRC, JUCE_INCREMENT_SRC_DEST,
930 const Mode::ParallelType cmp = Mode::load1 (comp);)
935 #if JUCE_USE_VDSP_FRAMEWORK
938 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, )
944 #if JUCE_USE_VDSP_FRAMEWORK
947 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, )
955 #if JUCE_USE_VDSP_FRAMEWORK
958 JUCE_PERFORM_VEC_OP_SRC_DEST (dest[i] = jmax (jmin (
src[i],
high),
low), Mode::max (Mode::min (s,
hi),
lo),
959 JUCE_LOAD_SRC, JUCE_INCREMENT_SRC_DEST,
960 const Mode::ParallelType
lo = Mode::load1 (
low);
const Mode::ParallelType
hi = Mode::load1 (
high);)
968 #if JUCE_USE_VDSP_FRAMEWORK
971 JUCE_PERFORM_VEC_OP_SRC_DEST (dest[i] = jmax (jmin (
src[i],
high),
low), Mode::max (Mode::min (s,
hi),
lo),
972 JUCE_LOAD_SRC, JUCE_INCREMENT_SRC_DEST,
973 const Mode::ParallelType
lo = Mode::load1 (
low);
const Mode::ParallelType
hi = Mode::load1 (
high);)
979 #if JUCE_USE_SSE_INTRINSICS || JUCE_USE_ARM_NEON
980 return FloatVectorHelpers::MinMax<FloatVectorHelpers::BasicOps32>::findMinAndMax (
src,
num);
988 #if JUCE_USE_SSE_INTRINSICS || JUCE_USE_ARM_NEON
989 return FloatVectorHelpers::MinMax<FloatVectorHelpers::BasicOps64>::findMinAndMax (
src,
num);
997 #if JUCE_USE_SSE_INTRINSICS || JUCE_USE_ARM_NEON
998 return FloatVectorHelpers::MinMax<FloatVectorHelpers::BasicOps32>::findMinOrMax (
src,
num,
true);
1000 return juce::findMinimum (
src,
num);
1006 #if JUCE_USE_SSE_INTRINSICS || JUCE_USE_ARM_NEON
1007 return FloatVectorHelpers::MinMax<FloatVectorHelpers::BasicOps64>::findMinOrMax (
src,
num,
true);
1009 return juce::findMinimum (
src,
num);
1015 #if JUCE_USE_SSE_INTRINSICS || JUCE_USE_ARM_NEON
1016 return FloatVectorHelpers::MinMax<FloatVectorHelpers::BasicOps32>::findMinOrMax (
src,
num,
false);
1018 return juce::findMaximum (
src,
num);
1024 #if JUCE_USE_SSE_INTRINSICS || JUCE_USE_ARM_NEON
1025 return FloatVectorHelpers::MinMax<FloatVectorHelpers::BasicOps64>::findMinOrMax (
src,
num,
false);
1027 return juce::findMaximum (
src,
num);
1031intptr_t JUCE_CALLTYPE FloatVectorOperations::getFpStatusRegister()
noexcept
1034 #if JUCE_INTEL && JUCE_USE_SSE_INTRINSICS
1036 #elif defined (__arm64__) || defined (__aarch64__) || JUCE_USE_ARM_NEON
1037 #if defined (__arm64__) || defined (__aarch64__)
1038 asm volatile(
"mrs %0, fpcr" :
"=r" (
fpsr));
1039 #elif JUCE_USE_ARM_NEON
1040 asm volatile(
"vmrs %0, fpscr" :
"=r" (
fpsr));
1043 #if ! (defined (JUCE_INTEL) || defined (JUCE_ARM))
1051void JUCE_CALLTYPE FloatVectorOperations::setFpStatusRegister (intptr_t fpsr)
noexcept
1053 #if JUCE_INTEL && JUCE_USE_SSE_INTRINSICS
1054 auto fpsr_w =
static_cast<uint32_t
> (fpsr);
1055 _mm_setcsr (fpsr_w);
1056 #elif defined (__arm64__) || defined (__aarch64__) || JUCE_USE_ARM_NEON
1057 #if defined (__arm64__) || defined (__aarch64__)
1058 asm volatile(
"msr fpcr, %0" : :
"ri" (fpsr));
1059 #elif JUCE_USE_ARM_NEON
1060 asm volatile(
"vmsr fpscr, %0" : :
"ri" (fpsr));
1063 #if ! (defined (JUCE_INTEL) || defined (JUCE_ARM))
1066 ignoreUnused (fpsr);
1072 #if JUCE_USE_SSE_INTRINSICS || (JUCE_USE_ARM_NEON || defined (__arm64__) || defined (__aarch64__))
1073 #if JUCE_USE_SSE_INTRINSICS
1078 setFpStatusRegister ((getFpStatusRegister() & (~mask)) | (
shouldEnable ? mask : 0));
1080 #if ! (defined (JUCE_INTEL) || defined (JUCE_ARM))
1089 #if JUCE_USE_SSE_INTRINSICS || (JUCE_USE_ARM_NEON || defined (__arm64__) || defined (__aarch64__))
1090 #if JUCE_USE_SSE_INTRINSICS
1096 setFpStatusRegister ((getFpStatusRegister() & (~mask)) | (
shouldDisable ? mask : 0));
1100 #if ! (defined (JUCE_INTEL) || defined (JUCE_ARM))
1108 #if JUCE_USE_SSE_INTRINSICS || (JUCE_USE_ARM_NEON || defined (__arm64__) || defined (__aarch64__))
1109 #if JUCE_USE_SSE_INTRINSICS
1115 return ((getFpStatusRegister() & mask) == mask);
1121ScopedNoDenormals::ScopedNoDenormals()
noexcept
1123 #if JUCE_USE_SSE_INTRINSICS || (JUCE_USE_ARM_NEON || defined (__arm64__) || defined (__aarch64__))
1124 #if JUCE_USE_SSE_INTRINSICS
1130 fpsr = FloatVectorOperations::getFpStatusRegister();
1131 FloatVectorOperations::setFpStatusRegister (
fpsr | mask);
1135ScopedNoDenormals::~ScopedNoDenormals() noexcept
1137 #if JUCE_USE_SSE_INTRINSICS || (JUCE_USE_ARM_NEON || defined (__arm64__) || defined (__aarch64__))
1138 FloatVectorOperations::setFpStatusRegister (fpsr);
1147class FloatVectorOperationsTests :
public UnitTest
1151 : UnitTest (
"FloatVectorOperations", UnitTestCategories::audio)
1154 template <
typename ValueType>
1157 static void runTest (UnitTest& u, Random random)
1159 const int range = random.nextBool() ? 500 : 10;
1160 const int num = random.nextInt (range) + 1;
1162 HeapBlock<ValueType> buffer1 (num + 16), buffer2 (num + 16);
1163 HeapBlock<int> buffer3 (num + 16);
1166 ValueType*
const data1 = buffer1;
1167 ValueType*
const data2 = buffer2;
1168 int*
const int1 = buffer3;
1172 ValueType*
const data1 = addBytesToPointer (buffer1.get(), random.nextInt (16));
1173 ValueType*
const data2 = addBytesToPointer (buffer2.get(), random.nextInt (16));
1174 int*
const int1 = addBytesToPointer (buffer3.get(), random.nextInt (16));
1177 fillRandomly (random, data1, num);
1178 fillRandomly (random, data2, num);
1180 Range<ValueType> minMax1 (FloatVectorOperations::findMinAndMax (data1, num));
1181 Range<ValueType> minMax2 (Range<ValueType>::findMinAndMax (data1, num));
1182 u.expect (minMax1 == minMax2);
1184 u.expect (valuesMatch (FloatVectorOperations::findMinimum (data1, num), juce::findMinimum (data1, num)));
1185 u.expect (valuesMatch (FloatVectorOperations::findMaximum (data1, num), juce::findMaximum (data1, num)));
1187 u.expect (valuesMatch (FloatVectorOperations::findMinimum (data2, num), juce::findMinimum (data2, num)));
1188 u.expect (valuesMatch (FloatVectorOperations::findMaximum (data2, num), juce::findMaximum (data2, num)));
1190 FloatVectorOperations::clear (data1, num);
1191 u.expect (areAllValuesEqual (data1, num, 0));
1193 FloatVectorOperations::fill (data1, (ValueType) 2, num);
1194 u.expect (areAllValuesEqual (data1, num, (ValueType) 2));
1196 FloatVectorOperations::add (data1, (ValueType) 2, num);
1197 u.expect (areAllValuesEqual (data1, num, (ValueType) 4));
1199 FloatVectorOperations::copy (data2, data1, num);
1200 u.expect (areAllValuesEqual (data2, num, (ValueType) 4));
1202 FloatVectorOperations::add (data2, data1, num);
1203 u.expect (areAllValuesEqual (data2, num, (ValueType) 8));
1205 FloatVectorOperations::copyWithMultiply (data2, data1, (ValueType) 4, num);
1206 u.expect (areAllValuesEqual (data2, num, (ValueType) 16));
1208 FloatVectorOperations::addWithMultiply (data2, data1, (ValueType) 4, num);
1209 u.expect (areAllValuesEqual (data2, num, (ValueType) 32));
1211 FloatVectorOperations::multiply (data1, (ValueType) 2, num);
1212 u.expect (areAllValuesEqual (data1, num, (ValueType) 8));
1214 FloatVectorOperations::multiply (data1, data2, num);
1215 u.expect (areAllValuesEqual (data1, num, (ValueType) 256));
1217 FloatVectorOperations::negate (data2, data1, num);
1218 u.expect (areAllValuesEqual (data2, num, (ValueType) -256));
1220 FloatVectorOperations::subtract (data1, data2, num);
1221 u.expect (areAllValuesEqual (data1, num, (ValueType) 512));
1223 FloatVectorOperations::abs (data1, data2, num);
1224 u.expect (areAllValuesEqual (data1, num, (ValueType) 256));
1226 FloatVectorOperations::abs (data2, data1, num);
1227 u.expect (areAllValuesEqual (data2, num, (ValueType) 256));
1229 fillRandomly (random, int1, num);
1230 doConversionTest (u, data1, data2, int1, num);
1232 FloatVectorOperations::fill (data1, (ValueType) 2, num);
1233 FloatVectorOperations::fill (data2, (ValueType) 3, num);
1234 FloatVectorOperations::addWithMultiply (data1, data1, data2, num);
1235 u.expect (areAllValuesEqual (data1, num, (ValueType) 8));
1238 static void doConversionTest (UnitTest& u,
float* data1,
float* data2,
int*
const int1,
int num)
1240 FloatVectorOperations::convertFixedToFloat (data1, int1, 2.0f, num);
1241 convertFixed (data2, int1, 2.0f, num);
1242 u.expect (buffersMatch (data1, data2, num));
1245 static void doConversionTest (UnitTest&,
double*,
double*,
int*,
int) {}
1247 static void fillRandomly (Random& random, ValueType* d,
int num)
1250 *d++ = (ValueType) (random.nextDouble() * 1000.0);
1253 static void fillRandomly (Random& random,
int* d,
int num)
1256 *d++ = random.nextInt();
1259 static void convertFixed (
float* d,
const int* s, ValueType multiplier,
int num)
1262 *d++ = (float) *s++ * multiplier;
1265 static bool areAllValuesEqual (
const ValueType* d,
int num, ValueType target)
1274 static bool buffersMatch (
const ValueType* d1,
const ValueType* d2,
int num)
1277 if (! valuesMatch (*d1++, *d2++))
1283 static bool valuesMatch (ValueType v1, ValueType v2)
1285 return std::abs (v1 - v2) < std::numeric_limits<ValueType>::epsilon();
1289 void runTest()
override
1291 beginTest (
"FloatVectorOperations");
1293 for (
int i = 1000; --i >= 0;)
1295 TestRunner<float>::runTest (*
this, getRandom());
1296 TestRunner<double>::runTest (*
this, getRandom());
1301static FloatVectorOperationsTests vectorOpTests;
static void JUCE_CALLTYPE convertFixedToFloat(float *dest, const int *src, float multiplier, int numValues) noexcept
static void JUCE_CALLTYPE disableDenormalisedNumberSupport(bool shouldDisable=true) noexcept
static void JUCE_CALLTYPE max(float *dest, const float *src, float comp, int num) noexcept
static void JUCE_CALLTYPE negate(float *dest, const float *src, int numValues) noexcept
static float JUCE_CALLTYPE findMaximum(const float *src, int numValues) noexcept
static void JUCE_CALLTYPE fill(float *dest, float valueToFill, int numValues) noexcept
static void JUCE_CALLTYPE multiply(float *dest, const float *src, int numValues) noexcept
static void JUCE_CALLTYPE enableFlushToZeroMode(bool shouldEnable) noexcept
static void JUCE_CALLTYPE clear(float *dest, int numValues) noexcept
static void JUCE_CALLTYPE subtract(float *dest, const float *src, int numValues) noexcept
static void JUCE_CALLTYPE clip(float *dest, const float *src, float low, float high, int num) noexcept
static void JUCE_CALLTYPE copyWithMultiply(float *dest, const float *src, float multiplier, int numValues) noexcept
static void JUCE_CALLTYPE copy(float *dest, const float *src, int numValues) noexcept
static void JUCE_CALLTYPE subtractWithMultiply(float *dest, const float *src, float multiplier, int numValues) noexcept
static void JUCE_CALLTYPE addWithMultiply(float *dest, const float *src, float multiplier, int numValues) noexcept
static void JUCE_CALLTYPE min(float *dest, const float *src, float comp, int num) noexcept
static float JUCE_CALLTYPE findMinimum(const float *src, int numValues) noexcept
static Range< float > JUCE_CALLTYPE findMinAndMax(const float *src, int numValues) noexcept
static void JUCE_CALLTYPE abs(float *dest, const float *src, int numValues) noexcept
static void JUCE_CALLTYPE add(float *dest, float amountToAdd, int numValues) noexcept
static bool JUCE_CALLTYPE areDenormalsDisabled() noexcept
static Range findMinAndMax(const ValueType *values, int numValues) noexcept