OpenShot Audio Library | OpenShotAudio 0.3.2
Loading...
Searching...
No Matches
juce_MathsFunctions.h
1/*
2 ==============================================================================
3
4 This file is part of the JUCE library.
5 Copyright (c) 2017 - ROLI Ltd.
6
7 JUCE is an open source library subject to commercial or open-source
8 licensing.
9
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.
15
16 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
17 EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
18 DISCLAIMED.
19
20 ==============================================================================
21*/
22
23namespace juce
24{
25
26//==============================================================================
27/*
28 This file sets up some handy mathematical typdefs and functions.
29*/
30
31//==============================================================================
32// Definitions for the int8, int16, int32, int64 and pointer_sized_int types.
33
35using int8 = signed char;
37using uint8 = unsigned char;
39using int16 = signed short;
41using uint16 = unsigned short;
43using int32 = signed int;
45using uint32 = unsigned int;
46
47#if JUCE_MSVC
49 using int64 = __int64;
51 using uint64 = unsigned __int64;
52#else
54 using int64 = long long;
56 using uint64 = unsigned long long;
57#endif
58
59#ifndef DOXYGEN
65 #define literal64bit(longLiteral) (longLiteral##LL)
66#endif
67
68#if JUCE_64BIT
70 using pointer_sized_int = int64;
72 using pointer_sized_uint = uint64;
73#elif JUCE_MSVC
75 using pointer_sized_int = _W64 int;
77 using pointer_sized_uint = _W64 unsigned int;
78#else
79# include <cstdint>
81 using pointer_sized_int = intptr_t;
83 using pointer_sized_uint = uintptr_t;
84#endif
85
86#if JUCE_WINDOWS && ! JUCE_MINGW
87 using ssize_t = pointer_sized_int;
88#endif
89
90//==============================================================================
91// Some indispensable min/max functions
92
94template <typename Type>
95JUCE_CONSTEXPR Type jmax (Type a, Type b) { return a < b ? b : a; }
96
98template <typename Type>
99JUCE_CONSTEXPR Type jmax (Type a, Type b, Type c) { return a < b ? (b < c ? c : b) : (a < c ? c : a); }
100
102template <typename Type>
103JUCE_CONSTEXPR Type jmax (Type a, Type b, Type c, Type d) { return jmax (a, jmax (b, c, d)); }
104
106template <typename Type>
107JUCE_CONSTEXPR Type jmin (Type a, Type b) { return b < a ? b : a; }
108
110template <typename Type>
111JUCE_CONSTEXPR Type jmin (Type a, Type b, Type c) { return b < a ? (c < b ? c : b) : (c < a ? c : a); }
112
114template <typename Type>
115JUCE_CONSTEXPR Type jmin (Type a, Type b, Type c, Type d) { return jmin (a, jmin (b, c, d)); }
116
120template <typename Type>
121JUCE_CONSTEXPR Type jmap (Type value0To1, Type targetRangeMin, Type targetRangeMax)
122{
123 return targetRangeMin + value0To1 * (targetRangeMax - targetRangeMin);
124}
125
127template <typename Type>
128Type jmap (Type sourceValue, Type sourceRangeMin, Type sourceRangeMax, Type targetRangeMin, Type targetRangeMax)
129{
130 jassert (sourceRangeMax != sourceRangeMin); // mapping from a range of zero will produce NaN!
131 return targetRangeMin + ((targetRangeMax - targetRangeMin) * (sourceValue - sourceRangeMin)) / (sourceRangeMax - sourceRangeMin);
132}
133
135template <typename Type>
136Type findMinimum (const Type* data, int numValues)
137{
138 if (numValues <= 0)
139 return Type (0);
140
141 auto result = *data++;
142
143 while (--numValues > 0) // (> 0 rather than >= 0 because we've already taken the first sample)
144 {
145 auto v = *data++;
146
147 if (v < result)
148 result = v;
149 }
150
151 return result;
152}
153
155template <typename Type>
156Type findMaximum (const Type* values, int numValues)
157{
158 if (numValues <= 0)
159 return Type (0);
160
161 auto result = *values++;
162
163 while (--numValues > 0) // (> 0 rather than >= 0 because we've already taken the first sample)
164 {
165 auto v = *values++;
166
167 if (result < v)
168 result = v;
169 }
170
171 return result;
172}
173
175template <typename Type>
176void findMinAndMax (const Type* values, int numValues, Type& lowest, Type& highest)
177{
178 if (numValues <= 0)
179 {
180 lowest = Type (0);
181 highest = Type (0);
182 }
183 else
184 {
185 auto mn = *values++;
186 auto mx = mn;
187
188 while (--numValues > 0) // (> 0 rather than >= 0 because we've already taken the first sample)
189 {
190 auto v = *values++;
191
192 if (mx < v) mx = v;
193 if (v < mn) mn = v;
194 }
195
196 lowest = mn;
197 highest = mx;
198 }
199}
200
201//==============================================================================
218template <typename Type>
219Type jlimit (Type lowerLimit,
220 Type upperLimit,
221 Type valueToConstrain) noexcept
222{
223 jassert (lowerLimit <= upperLimit); // if these are in the wrong order, results are unpredictable..
224
225 return valueToConstrain < lowerLimit ? lowerLimit
226 : (upperLimit < valueToConstrain ? upperLimit
227 : valueToConstrain);
228}
229
235template <typename Type1, typename Type2>
236bool isPositiveAndBelow (Type1 valueToTest, Type2 upperLimit) noexcept
237{
238 jassert (Type1() <= static_cast<Type1> (upperLimit)); // makes no sense to call this if the upper limit is itself below zero..
239 return Type1() <= valueToTest && valueToTest < static_cast<Type1> (upperLimit);
240}
241
242template <typename Type>
243bool isPositiveAndBelow (int valueToTest, Type upperLimit) noexcept
244{
245 jassert (upperLimit >= 0); // makes no sense to call this if the upper limit is itself below zero..
246 return static_cast<unsigned int> (valueToTest) < static_cast<unsigned int> (upperLimit);
247}
248
254template <typename Type1, typename Type2>
255bool isPositiveAndNotGreaterThan (Type1 valueToTest, Type2 upperLimit) noexcept
256{
257 jassert (Type1() <= static_cast<Type1> (upperLimit)); // makes no sense to call this if the upper limit is itself below zero..
258 return Type1() <= valueToTest && valueToTest <= static_cast<Type1> (upperLimit);
259}
260
261template <typename Type>
262bool isPositiveAndNotGreaterThan (int valueToTest, Type upperLimit) noexcept
263{
264 jassert (upperLimit >= 0); // makes no sense to call this if the upper limit is itself below zero..
265 return static_cast<unsigned int> (valueToTest) <= static_cast<unsigned int> (upperLimit);
266}
267
271template <typename Type>
272bool isWithin (Type a, Type b, Type tolerance) noexcept
273{
274 return std::abs (a - b) <= tolerance;
275}
276
280template <typename Type>
281bool approximatelyEqual (Type a, Type b) noexcept
282{
283 return std::abs (a - b) <= (std::numeric_limits<Type>::epsilon() * std::max (a, b))
284 || std::abs (a - b) < std::numeric_limits<Type>::min();
285}
286
287//==============================================================================
289template <typename... Types>
290void ignoreUnused (Types&&...) noexcept {}
291
300template <typename Type, size_t N>
301JUCE_CONSTEXPR int numElementsInArray (Type (&)[N]) noexcept { return N; }
302
303//==============================================================================
304// Some useful maths functions that aren't always present with all compilers and build settings.
305
308template <typename Type>
309Type juce_hypot (Type a, Type b) noexcept
310{
311 #if JUCE_MSVC
312 return static_cast<Type> (_hypot (a, b));
313 #else
314 return static_cast<Type> (hypot (a, b));
315 #endif
316}
317
318#ifndef DOXYGEN
319template <>
320inline float juce_hypot (float a, float b) noexcept
321{
322 #if JUCE_MSVC
323 return _hypotf (a, b);
324 #else
325 return hypotf (a, b);
326 #endif
327}
328#endif
329
330//==============================================================================
331#if JUCE_HAS_CONSTEXPR
332
337template <typename FloatType>
338struct MathConstants
339{
341 static constexpr FloatType pi = static_cast<FloatType> (3.141592653589793238L);
342
344 static constexpr FloatType twoPi = static_cast<FloatType> (2 * 3.141592653589793238L);
345
347 static constexpr FloatType halfPi = static_cast<FloatType> (3.141592653589793238L / 2);
348
350 static constexpr FloatType euler = static_cast<FloatType> (2.71828182845904523536L);
351
353 static constexpr FloatType sqrt2 = static_cast<FloatType> (1.4142135623730950488L);
354};
355
356#else
357
362template <typename FloatType>
364{
366 static const FloatType pi;
367
369 static const FloatType twoPi;
370
372 static const FloatType halfPi;
373
375 static const FloatType euler;
376
378 static const FloatType sqrt2;
379};
380
381template <typename FloatType>
382const FloatType MathConstants<FloatType>::pi = static_cast<FloatType> (3.141592653589793238L);
383
384template <typename FloatType>
385const FloatType MathConstants<FloatType>::twoPi = static_cast<FloatType> (2 * 3.141592653589793238L);
386
387template <typename FloatType>
388const FloatType MathConstants<FloatType>::halfPi = static_cast<FloatType> (3.141592653589793238L / 2);
389
390template <typename FloatType>
391const FloatType MathConstants<FloatType>::euler = static_cast<FloatType> (2.71828182845904523536L);
392
393template <typename FloatType>
394const FloatType MathConstants<FloatType>::sqrt2 = static_cast<FloatType> (1.4142135623730950488L);
395
396#endif
397
398#ifndef DOXYGEN
404const JUCE_CONSTEXPR double double_Pi = MathConstants<double>::pi;
405
411const JUCE_CONSTEXPR float float_Pi = MathConstants<float>::pi;
412#endif
413
415template <typename FloatType>
416JUCE_CONSTEXPR FloatType degreesToRadians (FloatType degrees) noexcept { return degrees * (MathConstants<FloatType>::pi / FloatType (180)); }
417
419template <typename FloatType>
420JUCE_CONSTEXPR FloatType radiansToDegrees (FloatType radians) noexcept { return radians * (FloatType (180) / MathConstants<FloatType>::pi); }
421
422
423//==============================================================================
427template <typename NumericType>
428bool juce_isfinite (NumericType) noexcept
429{
430 return true; // Integer types are always finite
431}
432
433template <>
434inline bool juce_isfinite (float value) noexcept
435{
436 #if JUCE_WINDOWS && ! JUCE_MINGW
437 return _finite (value) != 0;
438 #else
439 return std::isfinite (value);
440 #endif
441}
442
443template <>
444inline bool juce_isfinite (double value) noexcept
445{
446 #if JUCE_WINDOWS && ! JUCE_MINGW
447 return _finite (value) != 0;
448 #else
449 return std::isfinite (value);
450 #endif
451}
452
453//==============================================================================
454#if JUCE_MSVC
455 #pragma optimize ("t", off)
456 #ifndef __INTEL_COMPILER
457 #pragma float_control (precise, on, push)
458 #endif
459#endif
460
471template <typename FloatType>
472int roundToInt (const FloatType value) noexcept
473{
474 #ifdef __INTEL_COMPILER
475 #pragma float_control (precise, on, push)
476 #endif
477
478 union { int asInt[2]; double asDouble; } n;
479 n.asDouble = ((double) value) + 6755399441055744.0;
480
481 #if JUCE_BIG_ENDIAN
482 return n.asInt [1];
483 #else
484 return n.asInt [0];
485 #endif
486}
487
488inline int roundToInt (int value) noexcept
489{
490 return value;
491}
492
493#if JUCE_MSVC
494 #ifndef __INTEL_COMPILER
495 #pragma float_control (pop)
496 #endif
497 #pragma optimize ("", on) // resets optimisations to the project defaults
498#endif
499
505inline int roundToIntAccurate (double value) noexcept
506{
507 #ifdef __INTEL_COMPILER
508 #pragma float_control (pop)
509 #endif
510
511 return roundToInt (value + 1.5e-8);
512}
513
514//==============================================================================
521template <typename FloatType>
522unsigned int truncatePositiveToUnsignedInt (FloatType value) noexcept
523{
524 jassert (value >= static_cast<FloatType> (0));
525 jassert (static_cast<FloatType> (value) <= std::numeric_limits<unsigned int>::max());
526
527 return static_cast<unsigned int> (value);
528}
529
530//==============================================================================
532template <typename IntegerType>
533JUCE_CONSTEXPR bool isPowerOfTwo (IntegerType value)
534{
535 return (value & (value - 1)) == 0;
536}
537
539inline int nextPowerOfTwo (int n) noexcept
540{
541 --n;
542 n |= (n >> 1);
543 n |= (n >> 2);
544 n |= (n >> 4);
545 n |= (n >> 8);
546 n |= (n >> 16);
547 return n + 1;
548}
549
554int findHighestSetBit (uint32 n) noexcept;
555
557inline int countNumberOfBits (uint32 n) noexcept
558{
559 n -= ((n >> 1) & 0x55555555);
560 n = (((n >> 2) & 0x33333333) + (n & 0x33333333));
561 n = (((n >> 4) + n) & 0x0f0f0f0f);
562 n += (n >> 8);
563 n += (n >> 16);
564 return (int) (n & 0x3f);
565}
566
568inline int countNumberOfBits (uint64 n) noexcept
569{
570 return countNumberOfBits ((uint32) n) + countNumberOfBits ((uint32) (n >> 32));
571}
572
576template <typename IntegerType>
577IntegerType negativeAwareModulo (IntegerType dividend, const IntegerType divisor) noexcept
578{
579 jassert (divisor > 0);
580 dividend %= divisor;
581 return (dividend < 0) ? (dividend + divisor) : dividend;
582}
583
585template <typename NumericType>
586inline JUCE_CONSTEXPR NumericType square (NumericType n) noexcept
587{
588 return n * n;
589}
590
591//==============================================================================
599void writeLittleEndianBitsInBuffer (void* targetBuffer, uint32 startBit, uint32 numBits, uint32 value) noexcept;
600
608uint32 readLittleEndianBitsInBuffer (const void* sourceBuffer, uint32 startBit, uint32 numBits) noexcept;
609
610
611//==============================================================================
612#if JUCE_INTEL || defined (DOXYGEN)
617 #define JUCE_UNDENORMALISE(x) { (x) += 0.1f; (x) -= 0.1f; }
618#else
619 #define JUCE_UNDENORMALISE(x)
620#endif
621
622//==============================================================================
625namespace TypeHelpers
626{
638 template <typename Type> struct ParameterType { using type = const Type&; };
639
640 #if ! DOXYGEN
641 template <typename Type> struct ParameterType <Type&> { using type = Type&; };
642 template <typename Type> struct ParameterType <Type*> { using type = Type*; };
643 template <> struct ParameterType <char> { using type = char; };
644 template <> struct ParameterType <unsigned char> { using type = unsigned char; };
645 template <> struct ParameterType <short> { using type = short; };
646 template <> struct ParameterType <unsigned short> { using type = unsigned short; };
647 template <> struct ParameterType <int> { using type = int; };
648 template <> struct ParameterType <unsigned int> { using type = unsigned int; };
649 template <> struct ParameterType <long> { using type = long; };
650 template <> struct ParameterType <unsigned long> { using type = unsigned long; };
651 template <> struct ParameterType <int64> { using type = int64; };
652 template <> struct ParameterType <uint64> { using type = uint64; };
653 template <> struct ParameterType <bool> { using type = bool; };
654 template <> struct ParameterType <float> { using type = float; };
655 template <> struct ParameterType <double> { using type = double; };
656 #endif
657
663 template <typename Type> struct SmallestFloatType { using type = float; };
664
665 #if ! DOXYGEN
666 template <> struct SmallestFloatType <double> { using type = double; };
667 #endif
668
674 template <int bytes> struct UnsignedTypeWithSize {};
675
676 #if ! DOXYGEN
677 template <> struct UnsignedTypeWithSize<1> { using type = uint8; };
678 template <> struct UnsignedTypeWithSize<2> { using type = uint16; };
679 template <> struct UnsignedTypeWithSize<4> { using type = uint32; };
680 template <> struct UnsignedTypeWithSize<8> { using type = uint64; };
681 #endif
682}
683
684//==============================================================================
685#if ! DOXYGEN
686 // These old functions are deprecated: Just use roundToInt instead.
687 JUCE_DEPRECATED_ATTRIBUTE inline int roundDoubleToInt (double value) noexcept { return roundToInt (value); }
688 JUCE_DEPRECATED_ATTRIBUTE inline int roundFloatToInt (float value) noexcept { return roundToInt (value); }
689
690 // This old function isn't needed - just use std::abs() instead
691 JUCE_DEPRECATED_ATTRIBUTE inline int64 abs64 (int64 n) noexcept { return std::abs (n); }
692#endif
693
694} // namespace juce
static const FloatType euler
static const FloatType twoPi
static const FloatType sqrt2
static const FloatType halfPi
static const FloatType pi