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
80 using pointer_sized_int = int;
82 using pointer_sized_uint = unsigned int;
83#endif
84
85#if JUCE_WINDOWS && ! JUCE_MINGW
86 using ssize_t = pointer_sized_int;
87#endif
88
89//==============================================================================
90// Some indispensable min/max functions
91
93template <typename Type>
94JUCE_CONSTEXPR Type jmax (Type a, Type b) { return a < b ? b : a; }
95
97template <typename Type>
98JUCE_CONSTEXPR Type jmax (Type a, Type b, Type c) { return a < b ? (b < c ? c : b) : (a < c ? c : a); }
99
101template <typename Type>
102JUCE_CONSTEXPR Type jmax (Type a, Type b, Type c, Type d) { return jmax (a, jmax (b, c, d)); }
103
105template <typename Type>
106JUCE_CONSTEXPR Type jmin (Type a, Type b) { return b < a ? b : a; }
107
109template <typename Type>
110JUCE_CONSTEXPR Type jmin (Type a, Type b, Type c) { return b < a ? (c < b ? c : b) : (c < a ? c : a); }
111
113template <typename Type>
114JUCE_CONSTEXPR Type jmin (Type a, Type b, Type c, Type d) { return jmin (a, jmin (b, c, d)); }
115
119template <typename Type>
120JUCE_CONSTEXPR Type jmap (Type value0To1, Type targetRangeMin, Type targetRangeMax)
121{
122 return targetRangeMin + value0To1 * (targetRangeMax - targetRangeMin);
123}
124
126template <typename Type>
127Type jmap (Type sourceValue, Type sourceRangeMin, Type sourceRangeMax, Type targetRangeMin, Type targetRangeMax)
128{
129 jassert (sourceRangeMax != sourceRangeMin); // mapping from a range of zero will produce NaN!
130 return targetRangeMin + ((targetRangeMax - targetRangeMin) * (sourceValue - sourceRangeMin)) / (sourceRangeMax - sourceRangeMin);
131}
132
134template <typename Type>
135Type findMinimum (const Type* data, int numValues)
136{
137 if (numValues <= 0)
138 return Type (0);
139
140 auto result = *data++;
141
142 while (--numValues > 0) // (> 0 rather than >= 0 because we've already taken the first sample)
143 {
144 auto v = *data++;
145
146 if (v < result)
147 result = v;
148 }
149
150 return result;
151}
152
154template <typename Type>
155Type findMaximum (const Type* values, int numValues)
156{
157 if (numValues <= 0)
158 return Type (0);
159
160 auto result = *values++;
161
162 while (--numValues > 0) // (> 0 rather than >= 0 because we've already taken the first sample)
163 {
164 auto v = *values++;
165
166 if (result < v)
167 result = v;
168 }
169
170 return result;
171}
172
174template <typename Type>
175void findMinAndMax (const Type* values, int numValues, Type& lowest, Type& highest)
176{
177 if (numValues <= 0)
178 {
179 lowest = Type (0);
180 highest = Type (0);
181 }
182 else
183 {
184 auto mn = *values++;
185 auto mx = mn;
186
187 while (--numValues > 0) // (> 0 rather than >= 0 because we've already taken the first sample)
188 {
189 auto v = *values++;
190
191 if (mx < v) mx = v;
192 if (v < mn) mn = v;
193 }
194
195 lowest = mn;
196 highest = mx;
197 }
198}
199
200//==============================================================================
217template <typename Type>
218Type jlimit (Type lowerLimit,
219 Type upperLimit,
220 Type valueToConstrain) noexcept
221{
222 jassert (lowerLimit <= upperLimit); // if these are in the wrong order, results are unpredictable..
223
224 return valueToConstrain < lowerLimit ? lowerLimit
225 : (upperLimit < valueToConstrain ? upperLimit
226 : valueToConstrain);
227}
228
234template <typename Type1, typename Type2>
235bool isPositiveAndBelow (Type1 valueToTest, Type2 upperLimit) noexcept
236{
237 jassert (Type1() <= static_cast<Type1> (upperLimit)); // makes no sense to call this if the upper limit is itself below zero..
238 return Type1() <= valueToTest && valueToTest < static_cast<Type1> (upperLimit);
239}
240
241template <typename Type>
242bool isPositiveAndBelow (int valueToTest, Type upperLimit) noexcept
243{
244 jassert (upperLimit >= 0); // makes no sense to call this if the upper limit is itself below zero..
245 return static_cast<unsigned int> (valueToTest) < static_cast<unsigned int> (upperLimit);
246}
247
253template <typename Type1, typename Type2>
254bool isPositiveAndNotGreaterThan (Type1 valueToTest, Type2 upperLimit) noexcept
255{
256 jassert (Type1() <= static_cast<Type1> (upperLimit)); // makes no sense to call this if the upper limit is itself below zero..
257 return Type1() <= valueToTest && valueToTest <= static_cast<Type1> (upperLimit);
258}
259
260template <typename Type>
261bool isPositiveAndNotGreaterThan (int valueToTest, Type upperLimit) noexcept
262{
263 jassert (upperLimit >= 0); // makes no sense to call this if the upper limit is itself below zero..
264 return static_cast<unsigned int> (valueToTest) <= static_cast<unsigned int> (upperLimit);
265}
266
270template <typename Type>
271bool isWithin (Type a, Type b, Type tolerance) noexcept
272{
273 return std::abs (a - b) <= tolerance;
274}
275
279template <typename Type>
280bool approximatelyEqual (Type a, Type b) noexcept
281{
282 return std::abs (a - b) <= (std::numeric_limits<Type>::epsilon() * std::max (a, b))
283 || std::abs (a - b) < std::numeric_limits<Type>::min();
284}
285
286//==============================================================================
288template <typename... Types>
289void ignoreUnused (Types&&...) noexcept {}
290
299template <typename Type, size_t N>
300JUCE_CONSTEXPR int numElementsInArray (Type (&)[N]) noexcept { return N; }
301
302//==============================================================================
303// Some useful maths functions that aren't always present with all compilers and build settings.
304
307template <typename Type>
308Type juce_hypot (Type a, Type b) noexcept
309{
310 #if JUCE_MSVC
311 return static_cast<Type> (_hypot (a, b));
312 #else
313 return static_cast<Type> (hypot (a, b));
314 #endif
315}
316
317#ifndef DOXYGEN
318template <>
319inline float juce_hypot (float a, float b) noexcept
320{
321 #if JUCE_MSVC
322 return _hypotf (a, b);
323 #else
324 return hypotf (a, b);
325 #endif
326}
327#endif
328
329//==============================================================================
330#if JUCE_HAS_CONSTEXPR
331
336template <typename FloatType>
337struct MathConstants
338{
340 static constexpr FloatType pi = static_cast<FloatType> (3.141592653589793238L);
341
343 static constexpr FloatType twoPi = static_cast<FloatType> (2 * 3.141592653589793238L);
344
346 static constexpr FloatType halfPi = static_cast<FloatType> (3.141592653589793238L / 2);
347
349 static constexpr FloatType euler = static_cast<FloatType> (2.71828182845904523536L);
350
352 static constexpr FloatType sqrt2 = static_cast<FloatType> (1.4142135623730950488L);
353};
354
355#else
356
361template <typename FloatType>
363{
365 static const FloatType pi;
366
368 static const FloatType twoPi;
369
371 static const FloatType halfPi;
372
374 static const FloatType euler;
375
377 static const FloatType sqrt2;
378};
379
380template <typename FloatType>
381const FloatType MathConstants<FloatType>::pi = static_cast<FloatType> (3.141592653589793238L);
382
383template <typename FloatType>
384const FloatType MathConstants<FloatType>::twoPi = static_cast<FloatType> (2 * 3.141592653589793238L);
385
386template <typename FloatType>
387const FloatType MathConstants<FloatType>::halfPi = static_cast<FloatType> (3.141592653589793238L / 2);
388
389template <typename FloatType>
390const FloatType MathConstants<FloatType>::euler = static_cast<FloatType> (2.71828182845904523536L);
391
392template <typename FloatType>
393const FloatType MathConstants<FloatType>::sqrt2 = static_cast<FloatType> (1.4142135623730950488L);
394
395#endif
396
397#ifndef DOXYGEN
403const JUCE_CONSTEXPR double double_Pi = MathConstants<double>::pi;
404
410const JUCE_CONSTEXPR float float_Pi = MathConstants<float>::pi;
411#endif
412
414template <typename FloatType>
415JUCE_CONSTEXPR FloatType degreesToRadians (FloatType degrees) noexcept { return degrees * (MathConstants<FloatType>::pi / FloatType (180)); }
416
418template <typename FloatType>
419JUCE_CONSTEXPR FloatType radiansToDegrees (FloatType radians) noexcept { return radians * (FloatType (180) / MathConstants<FloatType>::pi); }
420
421
422//==============================================================================
426template <typename NumericType>
427bool juce_isfinite (NumericType) noexcept
428{
429 return true; // Integer types are always finite
430}
431
432template <>
433inline bool juce_isfinite (float value) noexcept
434{
435 #if JUCE_WINDOWS && ! JUCE_MINGW
436 return _finite (value) != 0;
437 #else
438 return std::isfinite (value);
439 #endif
440}
441
442template <>
443inline bool juce_isfinite (double value) noexcept
444{
445 #if JUCE_WINDOWS && ! JUCE_MINGW
446 return _finite (value) != 0;
447 #else
448 return std::isfinite (value);
449 #endif
450}
451
452//==============================================================================
453#if JUCE_MSVC
454 #pragma optimize ("t", off)
455 #ifndef __INTEL_COMPILER
456 #pragma float_control (precise, on, push)
457 #endif
458#endif
459
470template <typename FloatType>
471int roundToInt (const FloatType value) noexcept
472{
473 #ifdef __INTEL_COMPILER
474 #pragma float_control (precise, on, push)
475 #endif
476
477 union { int asInt[2]; double asDouble; } n;
478 n.asDouble = ((double) value) + 6755399441055744.0;
479
480 #if JUCE_BIG_ENDIAN
481 return n.asInt [1];
482 #else
483 return n.asInt [0];
484 #endif
485}
486
487inline int roundToInt (int value) noexcept
488{
489 return value;
490}
491
492#if JUCE_MSVC
493 #ifndef __INTEL_COMPILER
494 #pragma float_control (pop)
495 #endif
496 #pragma optimize ("", on) // resets optimisations to the project defaults
497#endif
498
504inline int roundToIntAccurate (double value) noexcept
505{
506 #ifdef __INTEL_COMPILER
507 #pragma float_control (pop)
508 #endif
509
510 return roundToInt (value + 1.5e-8);
511}
512
513//==============================================================================
520template <typename FloatType>
521unsigned int truncatePositiveToUnsignedInt (FloatType value) noexcept
522{
523 jassert (value >= static_cast<FloatType> (0));
524 jassert (static_cast<FloatType> (value) <= std::numeric_limits<unsigned int>::max());
525
526 return static_cast<unsigned int> (value);
527}
528
529//==============================================================================
531template <typename IntegerType>
532JUCE_CONSTEXPR bool isPowerOfTwo (IntegerType value)
533{
534 return (value & (value - 1)) == 0;
535}
536
538inline int nextPowerOfTwo (int n) noexcept
539{
540 --n;
541 n |= (n >> 1);
542 n |= (n >> 2);
543 n |= (n >> 4);
544 n |= (n >> 8);
545 n |= (n >> 16);
546 return n + 1;
547}
548
553int findHighestSetBit (uint32 n) noexcept;
554
556inline int countNumberOfBits (uint32 n) noexcept
557{
558 n -= ((n >> 1) & 0x55555555);
559 n = (((n >> 2) & 0x33333333) + (n & 0x33333333));
560 n = (((n >> 4) + n) & 0x0f0f0f0f);
561 n += (n >> 8);
562 n += (n >> 16);
563 return (int) (n & 0x3f);
564}
565
567inline int countNumberOfBits (uint64 n) noexcept
568{
569 return countNumberOfBits ((uint32) n) + countNumberOfBits ((uint32) (n >> 32));
570}
571
575template <typename IntegerType>
576IntegerType negativeAwareModulo (IntegerType dividend, const IntegerType divisor) noexcept
577{
578 jassert (divisor > 0);
579 dividend %= divisor;
580 return (dividend < 0) ? (dividend + divisor) : dividend;
581}
582
584template <typename NumericType>
585inline JUCE_CONSTEXPR NumericType square (NumericType n) noexcept
586{
587 return n * n;
588}
589
590//==============================================================================
598void writeLittleEndianBitsInBuffer (void* targetBuffer, uint32 startBit, uint32 numBits, uint32 value) noexcept;
599
607uint32 readLittleEndianBitsInBuffer (const void* sourceBuffer, uint32 startBit, uint32 numBits) noexcept;
608
609
610//==============================================================================
611#if JUCE_INTEL || defined (DOXYGEN)
616 #define JUCE_UNDENORMALISE(x) { (x) += 0.1f; (x) -= 0.1f; }
617#else
618 #define JUCE_UNDENORMALISE(x)
619#endif
620
621//==============================================================================
624namespace TypeHelpers
625{
637 template <typename Type> struct ParameterType { using type = const Type&; };
638
639 #if ! DOXYGEN
640 template <typename Type> struct ParameterType <Type&> { using type = Type&; };
641 template <typename Type> struct ParameterType <Type*> { using type = Type*; };
642 template <> struct ParameterType <char> { using type = char; };
643 template <> struct ParameterType <unsigned char> { using type = unsigned char; };
644 template <> struct ParameterType <short> { using type = short; };
645 template <> struct ParameterType <unsigned short> { using type = unsigned short; };
646 template <> struct ParameterType <int> { using type = int; };
647 template <> struct ParameterType <unsigned int> { using type = unsigned int; };
648 template <> struct ParameterType <long> { using type = long; };
649 template <> struct ParameterType <unsigned long> { using type = unsigned long; };
650 template <> struct ParameterType <int64> { using type = int64; };
651 template <> struct ParameterType <uint64> { using type = uint64; };
652 template <> struct ParameterType <bool> { using type = bool; };
653 template <> struct ParameterType <float> { using type = float; };
654 template <> struct ParameterType <double> { using type = double; };
655 #endif
656
662 template <typename Type> struct SmallestFloatType { using type = float; };
663
664 #if ! DOXYGEN
665 template <> struct SmallestFloatType <double> { using type = double; };
666 #endif
667
673 template <int bytes> struct UnsignedTypeWithSize {};
674
675 #if ! DOXYGEN
676 template <> struct UnsignedTypeWithSize<1> { using type = uint8; };
677 template <> struct UnsignedTypeWithSize<2> { using type = uint16; };
678 template <> struct UnsignedTypeWithSize<4> { using type = uint32; };
679 template <> struct UnsignedTypeWithSize<8> { using type = uint64; };
680 #endif
681}
682
683//==============================================================================
684#if ! DOXYGEN
685 // These old functions are deprecated: Just use roundToInt instead.
686 JUCE_DEPRECATED_ATTRIBUTE inline int roundDoubleToInt (double value) noexcept { return roundToInt (value); }
687 JUCE_DEPRECATED_ATTRIBUTE inline int roundFloatToInt (float value) noexcept { return roundToInt (value); }
688
689 // This old function isn't needed - just use std::abs() instead
690 JUCE_DEPRECATED_ATTRIBUTE inline int64 abs64 (int64 n) noexcept { return std::abs (n); }
691#endif
692
693} // namespace juce
static const FloatType euler
static const FloatType twoPi
static const FloatType sqrt2
static const FloatType halfPi
static const FloatType pi