The JUCE cross-platform C++ framework, with DISTRHO/KXStudio specific changes
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

215 lines
9.0KB

  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE library.
  4. Copyright (c) 2020 - Raw Material Software Limited
  5. JUCE is an open source library subject to commercial or open-source
  6. licensing.
  7. The code included in this file is provided under the terms of the ISC license
  8. http://www.isc.org/downloads/software-support-policy/isc-license. Permission
  9. To use, copy, modify, and/or distribute this software for any purpose with or
  10. without fee is hereby granted provided that the above copyright notice and
  11. this permission notice appear in all copies.
  12. JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
  13. EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
  14. DISCLAIMED.
  15. ==============================================================================
  16. */
  17. namespace juce
  18. {
  19. #ifndef JUCE_SNAP_TO_ZERO
  20. #if JUCE_INTEL
  21. #define JUCE_SNAP_TO_ZERO(n) if (! (n < -1.0e-8f || n > 1.0e-8f)) n = 0;
  22. #else
  23. #define JUCE_SNAP_TO_ZERO(n) ignoreUnused (n)
  24. #endif
  25. #endif
  26. class ScopedNoDenormals;
  27. //==============================================================================
  28. /**
  29. A collection of simple vector operations on arrays of floating point numbers,
  30. accelerated with SIMD instructions where possible, usually accessed from
  31. the FloatVectorOperations class.
  32. @code
  33. float data[64];
  34. // The following two function calls are equivalent:
  35. FloatVectorOperationsBase<float, int>::clear (data, 64);
  36. FloatVectorOperations::clear (data, 64);
  37. @endcode
  38. @see FloatVectorOperations
  39. @tags{Audio}
  40. */
  41. template <typename FloatType, typename CountType>
  42. struct FloatVectorOperationsBase
  43. {
  44. static void JUCE_CALLTYPE clear (FloatType* dest, CountType numValues) noexcept;
  45. static void JUCE_CALLTYPE fill (FloatType* dest, FloatType valueToFill, CountType numValues) noexcept;
  46. static void JUCE_CALLTYPE copy (FloatType* dest, const FloatType* src, CountType numValues) noexcept;
  47. static void JUCE_CALLTYPE copyWithMultiply (FloatType* dest, const FloatType* src, FloatType multiplier, CountType numValues) noexcept;
  48. static void JUCE_CALLTYPE add (FloatType* dest, FloatType amountToAdd, CountType numValues) noexcept;
  49. static void JUCE_CALLTYPE add (FloatType* dest, const FloatType* src, FloatType amount, CountType numValues) noexcept;
  50. static void JUCE_CALLTYPE add (FloatType* dest, const FloatType* src, CountType numValues) noexcept;
  51. static void JUCE_CALLTYPE add (FloatType* dest, const FloatType* src1, const FloatType* src2, CountType num) noexcept;
  52. static void JUCE_CALLTYPE subtract (FloatType* dest, const FloatType* src, CountType numValues) noexcept;
  53. static void JUCE_CALLTYPE subtract (FloatType* dest, const FloatType* src1, const FloatType* src2, CountType num) noexcept;
  54. static void JUCE_CALLTYPE addWithMultiply (FloatType* dest, const FloatType* src, FloatType multiplier, CountType numValues) noexcept;
  55. static void JUCE_CALLTYPE addWithMultiply (FloatType* dest, const FloatType* src1, const FloatType* src2, CountType num) noexcept;
  56. static void JUCE_CALLTYPE subtractWithMultiply (FloatType* dest, const FloatType* src, FloatType multiplier, CountType numValues) noexcept;
  57. static void JUCE_CALLTYPE subtractWithMultiply (FloatType* dest, const FloatType* src1, const FloatType* src2, CountType num) noexcept;
  58. static void JUCE_CALLTYPE multiply (FloatType* dest, const FloatType* src, CountType numValues) noexcept;
  59. static void JUCE_CALLTYPE multiply (FloatType* dest, const FloatType* src1, const FloatType* src2, CountType numValues) noexcept;
  60. static void JUCE_CALLTYPE multiply (FloatType* dest, FloatType multiplier, CountType numValues) noexcept;
  61. static void JUCE_CALLTYPE multiply (FloatType* dest, const FloatType* src, FloatType multiplier, CountType num) noexcept;
  62. static void JUCE_CALLTYPE negate (FloatType* dest, const FloatType* src, CountType numValues) noexcept;
  63. static void JUCE_CALLTYPE abs (FloatType* dest, const FloatType* src, CountType numValues) noexcept;
  64. static void JUCE_CALLTYPE min (FloatType* dest, const FloatType* src, FloatType comp, CountType num) noexcept;
  65. static void JUCE_CALLTYPE min (FloatType* dest, const FloatType* src1, const FloatType* src2, CountType num) noexcept;
  66. static void JUCE_CALLTYPE max (FloatType* dest, const FloatType* src, FloatType comp, CountType num) noexcept;
  67. static void JUCE_CALLTYPE max (FloatType* dest, const FloatType* src1, const FloatType* src2, CountType num) noexcept;
  68. static void JUCE_CALLTYPE clip (FloatType* dest, const FloatType* src, FloatType low, FloatType high, CountType num) noexcept;
  69. static Range<FloatType> JUCE_CALLTYPE findMinAndMax (const FloatType* src, CountType numValues) noexcept;
  70. static FloatType JUCE_CALLTYPE findMinimum (const FloatType* src, CountType numValues) noexcept;
  71. static FloatType JUCE_CALLTYPE findMaximum (const FloatType* src, CountType numValues) noexcept;
  72. };
  73. #if ! DOXYGEN
  74. namespace detail
  75. {
  76. template <typename...>
  77. struct NameForwarder;
  78. template <typename Head>
  79. struct NameForwarder<Head> : Head {};
  80. template <typename Head, typename... Tail>
  81. struct NameForwarder<Head, Tail...> : Head, NameForwarder<Tail...>
  82. {
  83. using Head::clear;
  84. using NameForwarder<Tail...>::clear;
  85. using Head::fill;
  86. using NameForwarder<Tail...>::fill;
  87. using Head::copy;
  88. using NameForwarder<Tail...>::copy;
  89. using Head::copyWithMultiply;
  90. using NameForwarder<Tail...>::copyWithMultiply;
  91. using Head::add;
  92. using NameForwarder<Tail...>::add;
  93. using Head::subtract;
  94. using NameForwarder<Tail...>::subtract;
  95. using Head::addWithMultiply;
  96. using NameForwarder<Tail...>::addWithMultiply;
  97. using Head::subtractWithMultiply;
  98. using NameForwarder<Tail...>::subtractWithMultiply;
  99. using Head::multiply;
  100. using NameForwarder<Tail...>::multiply;
  101. using Head::negate;
  102. using NameForwarder<Tail...>::negate;
  103. using Head::abs;
  104. using NameForwarder<Tail...>::abs;
  105. using Head::min;
  106. using NameForwarder<Tail...>::min;
  107. using Head::max;
  108. using NameForwarder<Tail...>::max;
  109. using Head::clip;
  110. using NameForwarder<Tail...>::clip;
  111. using Head::findMinAndMax;
  112. using NameForwarder<Tail...>::findMinAndMax;
  113. using Head::findMinimum;
  114. using NameForwarder<Tail...>::findMinimum;
  115. using Head::findMaximum;
  116. using NameForwarder<Tail...>::findMaximum;
  117. };
  118. } // namespace detail
  119. #endif
  120. //==============================================================================
  121. /**
  122. A collection of simple vector operations on arrays of floating point numbers,
  123. accelerated with SIMD instructions where possible and providing all methods
  124. from FloatVectorOperationsBase.
  125. @see FloatVectorOperationsBase
  126. @tags{Audio}
  127. */
  128. class JUCE_API FloatVectorOperations : public detail::NameForwarder<FloatVectorOperationsBase<float, int>,
  129. FloatVectorOperationsBase<float, size_t>,
  130. FloatVectorOperationsBase<double, int>,
  131. FloatVectorOperationsBase<double, size_t>>
  132. {
  133. public:
  134. static void JUCE_CALLTYPE convertFixedToFloat (float* dest, const int* src, float multiplier, int num) noexcept;
  135. static void JUCE_CALLTYPE convertFixedToFloat (float* dest, const int* src, float multiplier, size_t num) noexcept;
  136. /** This method enables or disables the SSE/NEON flush-to-zero mode. */
  137. static void JUCE_CALLTYPE enableFlushToZeroMode (bool shouldEnable) noexcept;
  138. /** On Intel CPUs, this method enables the SSE flush-to-zero and denormalised-are-zero modes.
  139. This effectively sets the DAZ and FZ bits of the MXCSR register. On arm CPUs this will
  140. enable flush to zero mode.
  141. It's a convenient thing to call before audio processing code where you really want to
  142. avoid denormalisation performance hits.
  143. */
  144. static void JUCE_CALLTYPE disableDenormalisedNumberSupport (bool shouldDisable = true) noexcept;
  145. /** This method returns true if denormals are currently disabled. */
  146. static bool JUCE_CALLTYPE areDenormalsDisabled() noexcept;
  147. private:
  148. friend ScopedNoDenormals;
  149. static intptr_t JUCE_CALLTYPE getFpStatusRegister() noexcept;
  150. static void JUCE_CALLTYPE setFpStatusRegister (intptr_t) noexcept;
  151. };
  152. //==============================================================================
  153. /**
  154. Helper class providing an RAII-based mechanism for temporarily disabling
  155. denormals on your CPU.
  156. @tags{Audio}
  157. */
  158. class ScopedNoDenormals
  159. {
  160. public:
  161. ScopedNoDenormals() noexcept;
  162. ~ScopedNoDenormals() noexcept;
  163. private:
  164. #if JUCE_USE_SSE_INTRINSICS || (JUCE_USE_ARM_NEON || defined (__arm64__) || defined (__aarch64__))
  165. intptr_t fpsr;
  166. #endif
  167. };
  168. } // namespace juce