2 ==============================================================================
4 This file is part of the JUCE library.
5 Copyright (c) 2022 - Raw Material Software Limited
7 JUCE is an open source library subject to commercial or open-source
10 The code included in this file is provided under the terms of the ISC license
11 http://www.isc.org/downloads/software-support-policy/isc-license. Permission
12 To use, copy, modify, and/or distribute this software for any purpose with or
13 without fee is hereby granted provided that the above copyright notice and
14 this permission notice appear in all copies.
16 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
17 EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
20 ==============================================================================
26 #ifndef JUCE_SNAP_TO_ZERO
28 #define JUCE_SNAP_TO_ZERO(n) if (! (n < -1.0e-8f || n > 1.0e-8f)) n = 0;
30 #define JUCE_SNAP_TO_ZERO(n) ignoreUnused (n)
33 class ScopedNoDenormals
;
35 //==============================================================================
37 A collection of simple vector operations on arrays of floating point numbers,
38 accelerated with SIMD instructions where possible, usually accessed from
39 the FloatVectorOperations class.
44 // The following two function calls are equivalent:
45 FloatVectorOperationsBase<float, int>::clear (data, 64);
46 FloatVectorOperations::clear (data, 64);
49 @see FloatVectorOperations
53 template <typename FloatType
, typename CountType
>
54 struct FloatVectorOperationsBase
56 /** Clears a vector of floating point numbers. */
57 static void JUCE_CALLTYPE
clear (FloatType
* dest
, CountType numValues
) noexcept
;
59 /** Copies a repeated value into a vector of floating point numbers. */
60 static void JUCE_CALLTYPE
fill (FloatType
* dest
, FloatType valueToFill
, CountType numValues
) noexcept
;
62 /** Copies a vector of floating point numbers. */
63 static void JUCE_CALLTYPE
copy (FloatType
* dest
, const FloatType
* src
, CountType numValues
) noexcept
;
65 /** Copies a vector of floating point numbers, multiplying each value by a given multiplier */
66 static void JUCE_CALLTYPE
copyWithMultiply (FloatType
* dest
, const FloatType
* src
, FloatType multiplier
, CountType numValues
) noexcept
;
68 /** Adds a fixed value to the destination values. */
69 static void JUCE_CALLTYPE
add (FloatType
* dest
, FloatType amountToAdd
, CountType numValues
) noexcept
;
71 /** Adds a fixed value to each source value and stores it in the destination array. */
72 static void JUCE_CALLTYPE
add (FloatType
* dest
, const FloatType
* src
, FloatType amount
, CountType numValues
) noexcept
;
74 /** Adds the source values to the destination values. */
75 static void JUCE_CALLTYPE
add (FloatType
* dest
, const FloatType
* src
, CountType numValues
) noexcept
;
77 /** Adds each source1 value to the corresponding source2 value and stores the result in the destination array. */
78 static void JUCE_CALLTYPE
add (FloatType
* dest
, const FloatType
* src1
, const FloatType
* src2
, CountType num
) noexcept
;
80 /** Subtracts the source values from the destination values. */
81 static void JUCE_CALLTYPE
subtract (FloatType
* dest
, const FloatType
* src
, CountType numValues
) noexcept
;
83 /** Subtracts each source2 value from the corresponding source1 value and stores the result in the destination array. */
84 static void JUCE_CALLTYPE
subtract (FloatType
* dest
, const FloatType
* src1
, const FloatType
* src2
, CountType num
) noexcept
;
86 /** Multiplies each source value by the given multiplier, then adds it to the destination value. */
87 static void JUCE_CALLTYPE
addWithMultiply (FloatType
* dest
, const FloatType
* src
, FloatType multiplier
, CountType numValues
) noexcept
;
89 /** Multiplies each source1 value by the corresponding source2 value, then adds it to the destination value. */
90 static void JUCE_CALLTYPE
addWithMultiply (FloatType
* dest
, const FloatType
* src1
, const FloatType
* src2
, CountType num
) noexcept
;
92 /** Multiplies each source value by the given multiplier, then subtracts it to the destination value. */
93 static void JUCE_CALLTYPE
subtractWithMultiply (FloatType
* dest
, const FloatType
* src
, FloatType multiplier
, CountType numValues
) noexcept
;
95 /** Multiplies each source1 value by the corresponding source2 value, then subtracts it to the destination value. */
96 static void JUCE_CALLTYPE
subtractWithMultiply (FloatType
* dest
, const FloatType
* src1
, const FloatType
* src2
, CountType num
) noexcept
;
98 /** Multiplies the destination values by the source values. */
99 static void JUCE_CALLTYPE
multiply (FloatType
* dest
, const FloatType
* src
, CountType numValues
) noexcept
;
101 /** Multiplies each source1 value by the correspinding source2 value, then stores it in the destination array. */
102 static void JUCE_CALLTYPE
multiply (FloatType
* dest
, const FloatType
* src1
, const FloatType
* src2
, CountType numValues
) noexcept
;
104 /** Multiplies each of the destination values by a fixed multiplier. */
105 static void JUCE_CALLTYPE
multiply (FloatType
* dest
, FloatType multiplier
, CountType numValues
) noexcept
;
107 /** Multiplies each of the source values by a fixed multiplier and stores the result in the destination array. */
108 static void JUCE_CALLTYPE
multiply (FloatType
* dest
, const FloatType
* src
, FloatType multiplier
, CountType num
) noexcept
;
110 /** Copies a source vector to a destination, negating each value. */
111 static void JUCE_CALLTYPE
negate (FloatType
* dest
, const FloatType
* src
, CountType numValues
) noexcept
;
113 /** Copies a source vector to a destination, taking the absolute of each value. */
114 static void JUCE_CALLTYPE
abs (FloatType
* dest
, const FloatType
* src
, CountType numValues
) noexcept
;
116 /** Each element of dest will be the minimum of the corresponding element of the source array and the given comp value. */
117 static void JUCE_CALLTYPE
min (FloatType
* dest
, const FloatType
* src
, FloatType comp
, CountType num
) noexcept
;
119 /** Each element of dest will be the minimum of the corresponding source1 and source2 values. */
120 static void JUCE_CALLTYPE
min (FloatType
* dest
, const FloatType
* src1
, const FloatType
* src2
, CountType num
) noexcept
;
122 /** Each element of dest will be the maximum of the corresponding element of the source array and the given comp value. */
123 static void JUCE_CALLTYPE
max (FloatType
* dest
, const FloatType
* src
, FloatType comp
, CountType num
) noexcept
;
125 /** Each element of dest will be the maximum of the corresponding source1 and source2 values. */
126 static void JUCE_CALLTYPE
max (FloatType
* dest
, const FloatType
* src1
, const FloatType
* src2
, CountType num
) noexcept
;
128 /** 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. */
129 static void JUCE_CALLTYPE
clip (FloatType
* dest
, const FloatType
* src
, FloatType low
, FloatType high
, CountType num
) noexcept
;
131 /** Finds the minimum and maximum values in the given array. */
132 static Range
<FloatType
> JUCE_CALLTYPE
findMinAndMax (const FloatType
* src
, CountType numValues
) noexcept
;
134 /** Finds the minimum value in the given array. */
135 static FloatType JUCE_CALLTYPE
findMinimum (const FloatType
* src
, CountType numValues
) noexcept
;
137 /** Finds the maximum value in the given array. */
138 static FloatType JUCE_CALLTYPE
findMaximum (const FloatType
* src
, CountType numValues
) noexcept
;
145 template <typename
...>
146 struct NameForwarder
;
148 template <typename Head
>
149 struct NameForwarder
<Head
> : Head
{};
151 template <typename Head
, typename
... Tail
>
152 struct NameForwarder
<Head
, Tail
...> : Head
, NameForwarder
<Tail
...>
155 using NameForwarder
<Tail
...>::clear
;
158 using NameForwarder
<Tail
...>::fill
;
161 using NameForwarder
<Tail
...>::copy
;
163 using Head::copyWithMultiply
;
164 using NameForwarder
<Tail
...>::copyWithMultiply
;
167 using NameForwarder
<Tail
...>::add
;
169 using Head::subtract
;
170 using NameForwarder
<Tail
...>::subtract
;
172 using Head::addWithMultiply
;
173 using NameForwarder
<Tail
...>::addWithMultiply
;
175 using Head::subtractWithMultiply
;
176 using NameForwarder
<Tail
...>::subtractWithMultiply
;
178 using Head::multiply
;
179 using NameForwarder
<Tail
...>::multiply
;
182 using NameForwarder
<Tail
...>::negate
;
185 using NameForwarder
<Tail
...>::abs
;
188 using NameForwarder
<Tail
...>::min
;
191 using NameForwarder
<Tail
...>::max
;
194 using NameForwarder
<Tail
...>::clip
;
196 using Head::findMinAndMax
;
197 using NameForwarder
<Tail
...>::findMinAndMax
;
199 using Head::findMinimum
;
200 using NameForwarder
<Tail
...>::findMinimum
;
202 using Head::findMaximum
;
203 using NameForwarder
<Tail
...>::findMaximum
;
206 } // namespace detail
209 //==============================================================================
211 A collection of simple vector operations on arrays of floating point numbers,
212 accelerated with SIMD instructions where possible and providing all methods
213 from FloatVectorOperationsBase.
215 @see FloatVectorOperationsBase
219 class JUCE_API FloatVectorOperations
: public detail::NameForwarder
<FloatVectorOperationsBase
<float, int>,
220 FloatVectorOperationsBase
<float, size_t>,
221 FloatVectorOperationsBase
<double, int>,
222 FloatVectorOperationsBase
<double, size_t>>
225 static void JUCE_CALLTYPE
convertFixedToFloat (float* dest
, const int* src
, float multiplier
, int num
) noexcept
;
227 static void JUCE_CALLTYPE
convertFixedToFloat (float* dest
, const int* src
, float multiplier
, size_t num
) noexcept
;
229 /** This method enables or disables the SSE/NEON flush-to-zero mode. */
230 static void JUCE_CALLTYPE
enableFlushToZeroMode (bool shouldEnable
) noexcept
;
232 /** On Intel CPUs, this method enables the SSE flush-to-zero and denormalised-are-zero modes.
233 This effectively sets the DAZ and FZ bits of the MXCSR register. On arm CPUs this will
234 enable flush to zero mode.
235 It's a convenient thing to call before audio processing code where you really want to
236 avoid denormalisation performance hits.
238 static void JUCE_CALLTYPE
disableDenormalisedNumberSupport (bool shouldDisable
= true) noexcept
;
240 /** This method returns true if denormals are currently disabled. */
241 static bool JUCE_CALLTYPE
areDenormalsDisabled() noexcept
;
244 friend ScopedNoDenormals
;
246 static intptr_t JUCE_CALLTYPE
getFpStatusRegister() noexcept
;
247 static void JUCE_CALLTYPE
setFpStatusRegister (intptr_t) noexcept
;
250 //==============================================================================
252 Helper class providing an RAII-based mechanism for temporarily disabling
253 denormals on your CPU.
257 class ScopedNoDenormals
260 ScopedNoDenormals() noexcept
;
261 ~ScopedNoDenormals() noexcept
;
264 #if JUCE_USE_SSE_INTRINSICS || (JUCE_USE_ARM_NEON || defined (__arm64__) || defined (__aarch64__))