3 * Copyright (C) 2011-2023 Filipe Coelho <falktx@falktx.com>
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation; either version 2 of
8 * the License, or any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * For a full copy of the GNU General Public License see the doc/GPL.txt file.
18 #ifndef CARLA_MATH_UTILS_HPP_INCLUDED
19 #define CARLA_MATH_UTILS_HPP_INCLUDED
21 #include "CarlaUtils.hpp"
26 // --------------------------------------------------------------------------------------------------------------------
27 // math functions (base)
30 * Return the lower of 2 values, with 'min' as the minimum possible value (ie, constrain).
34 const T
& carla_minConstrained(const T
& v1
, const T
& v2
, const T
& min
) noexcept
36 return (v1
<= min
|| v2
<= min
) ? min
: (v1
< v2
? v1
: v2
);
40 * Return the lower positive of 2 values.
41 * If one of the values is zero, returns zero.
42 * If one value is negative but the other positive, returns the positive.
43 * Returned value is guaranteed to be >= 0.
47 T
carla_minPositive(const T
& v1
, const T
& v2
) noexcept
49 if (v1
== 0 || v2
== 0)
52 return (v2
> 0) ? v2
: 0;
54 return (v1
> 0) ? v1
: 0;
55 return (v1
< v2
) ? v1
: v2
;
59 * Return the higher of 2 values, with 'max' as the maximum possible value (ie, limit).
63 const T
& carla_maxLimited(const T
& v1
, const T
& v2
, const T
& max
) noexcept
65 return (v1
>= max
|| v2
>= max
) ? max
: (v1
> v2
? v1
: v2
);
69 * Return the higher negative of 2 values.
70 * If one of the values is zero, returns zero.
71 * If one value is positive but the other negative, returns the negative.
72 * Returned value is guaranteed to be <= 0.
76 T
carla_maxNegative(const T
& v1
, const T
& v2
) noexcept
78 if (v1
== 0 || v2
== 0)
81 return (v2
< 0) ? v2
: 0;
83 return (v1
< 0) ? v1
: 0;
84 return (v1
> v2
) ? v1
: v2
;
88 * Return a value between 'min' and 'max'.
92 const T
& carla_fixedValue(const T
& min
, const T
& max
, const T
& value
) noexcept
94 CARLA_SAFE_ASSERT_RETURN(max
> min
, min
);
104 * Get next power of 2.
107 uint32_t carla_nextPowerOf2(uint32_t size
) noexcept
109 CARLA_SAFE_ASSERT_RETURN(size
> 0, 0);
111 // http://graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2
122 * Safely check if 2 numbers are equal.
126 bool carla_isEqual(const T
& v1
, const T
& v2
)
128 return std::abs(v1
-v2
) < std::numeric_limits
<T
>::epsilon();
132 * Safely check if 2 numbers are not equal.
136 bool carla_isNotEqual(const T
& v1
, const T
& v2
)
138 return std::abs(v1
-v2
) >= std::numeric_limits
<T
>::epsilon();
142 * Safely check if a number is zero.
146 bool carla_isZero(const T
& value
)
148 return std::abs(value
) < std::numeric_limits
<T
>::epsilon();
152 * Safely check if a number is not zero.
156 bool carla_isNotZero(const T
& value
)
158 return std::abs(value
) >= std::numeric_limits
<T
>::epsilon();
161 // --------------------------------------------------------------------------------------------------------------------
162 // math functions (extended)
165 * Add float array values to another float array.
168 void carla_addFloats(float dest
[], const float src
[], const std::size_t count
) noexcept
170 CARLA_SAFE_ASSERT_RETURN(dest
!= nullptr,);
171 CARLA_SAFE_ASSERT_RETURN(src
!= nullptr,);
172 CARLA_SAFE_ASSERT_RETURN(count
> 0,);
174 for (std::size_t i
=0; i
<count
; ++i
)
177 if (!std::isfinite(dest
[i
]))
178 __builtin_unreachable();
179 if (!std::isfinite(src
[i
]))
180 __builtin_unreachable();
187 * Copy float array values to another float array.
190 void carla_copyFloats(float dest
[], const float src
[], const std::size_t count
) noexcept
192 CARLA_SAFE_ASSERT_RETURN(dest
!= nullptr,);
193 CARLA_SAFE_ASSERT_RETURN(src
!= nullptr,);
194 CARLA_SAFE_ASSERT_RETURN(count
> 0,);
196 std::memcpy(dest
, src
, count
*sizeof(float));
200 * Fill a float array with a single float value.
203 void carla_fillFloatsWithSingleValue(float data
[], const float& value
, const std::size_t count
) noexcept
205 CARLA_SAFE_ASSERT_RETURN(data
!= nullptr,);
206 CARLA_SAFE_ASSERT_RETURN(count
> 0,);
208 if (carla_isZero(value
))
210 std::memset(data
, 0, count
*sizeof(float));
214 for (std::size_t i
=0; i
<count
; ++i
)
217 if (!std::isfinite(data
[i
]))
218 __builtin_unreachable();
226 * Clear a float array.
229 void carla_zeroFloats(float floats
[], const std::size_t count
) noexcept
231 CARLA_SAFE_ASSERT_RETURN(floats
!= nullptr,);
232 CARLA_SAFE_ASSERT_RETURN(count
> 0,);
234 std::memset(floats
, 0, count
*sizeof(float));
237 // --------------------------------------------------------------------------------------------------------------------
240 * Fill an array with a fixed value, floating-point version.
244 void carla_fill
<float>(float data
[], const float& value
, const std::size_t count
) noexcept
246 carla_fillFloatsWithSingleValue(data
, value
, count
);
250 * Find the highest absolute and normalized value within a float array.
253 float carla_findMaxNormalizedFloat(const float floats
[], const std::size_t count
)
255 CARLA_SAFE_ASSERT_RETURN(floats
!= nullptr, 0.f
);
256 CARLA_SAFE_ASSERT_RETURN(count
> 0, 0.f
);
258 static constexpr const float kEmptyFloats
[8192] = {};
260 if (count
<= 8192 && std::memcmp(floats
, kEmptyFloats
, sizeof(float)*count
) == 0)
263 float tmp
, maxf2
= std::abs(floats
[0]);
265 for (std::size_t i
=1; i
<count
; ++i
)
268 if (!std::isfinite(floats
[i
]))
269 __builtin_unreachable();
272 tmp
= std::abs(floats
[i
]);
285 * Multiply an array with a fixed value, float-specific version.
288 void carla_multiply(float data
[], const float& multiplier
, const std::size_t count
) noexcept
290 CARLA_SAFE_ASSERT_RETURN(data
!= nullptr,);
291 CARLA_SAFE_ASSERT_RETURN(count
> 0,);
293 if (carla_isZero(multiplier
))
295 std::memset(data
, 0, count
*sizeof(float));
299 for (std::size_t i
=0; i
<count
; ++i
)
302 if (!std::isfinite(data
[i
]))
303 __builtin_unreachable();
305 data
[i
] *= multiplier
;
310 // --------------------------------------------------------------------------------------------------------------------
311 // Missing functions in old OSX versions.
313 #if ! defined(DISTRHO_UTILS_HPP_INCLUDED) && ! defined(CARLA_PROPER_CPP11_SUPPORT)
315 inline float fmin(float __x
, float __y
)
316 { return __builtin_fminf(__x
, __y
); }
317 inline float fmax(float __x
, float __y
)
318 { return __builtin_fmaxf(__x
, __y
); }
319 inline float rint(float __x
)
320 { return __builtin_rintf(__x
); }
321 inline float round(float __x
)
322 { return __builtin_roundf(__x
); }
326 // --------------------------------------------------------------------------------------------------------------------
328 #endif // CARLA_MATH_UTILS_HPP_INCLUDED