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.

262 lines
11KB

  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE library.
  4. Copyright (c) 2022 - Raw Material Software Limited
  5. JUCE is an open source library subject to commercial or open-source
  6. licensing.
  7. By using JUCE, you agree to the terms of both the JUCE 7 End-User License
  8. Agreement and JUCE Privacy Policy.
  9. End User License Agreement: www.juce.com/juce-7-licence
  10. Privacy Policy: www.juce.com/juce-privacy-policy
  11. Or: You may also use this code under the terms of the GPL v3 (see
  12. www.gnu.org/licenses).
  13. JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
  14. EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
  15. DISCLAIMED.
  16. ==============================================================================
  17. */
  18. namespace juce::dsp
  19. {
  20. /**
  21. This class contains various fast mathematical function approximations.
  22. @tags{DSP}
  23. */
  24. struct FastMathApproximations
  25. {
  26. /** Provides a fast approximation of the function cosh(x) using a Pade approximant
  27. continued fraction, calculated sample by sample.
  28. Note: This is an approximation which works on a limited range. You are
  29. advised to use input values only between -5 and +5 for limiting the error.
  30. */
  31. template <typename FloatType>
  32. static FloatType cosh (FloatType x) noexcept
  33. {
  34. auto x2 = x * x;
  35. auto numerator = -(39251520 + x2 * (18471600 + x2 * (1075032 + 14615 * x2)));
  36. auto denominator = -39251520 + x2 * (1154160 + x2 * (-16632 + 127 * x2));
  37. return numerator / denominator;
  38. }
  39. /** Provides a fast approximation of the function cosh(x) using a Pade approximant
  40. continued fraction, calculated on a whole buffer.
  41. Note: This is an approximation which works on a limited range. You are
  42. advised to use input values only between -5 and +5 for limiting the error.
  43. */
  44. template <typename FloatType>
  45. static void cosh (FloatType* values, size_t numValues) noexcept
  46. {
  47. for (size_t i = 0; i < numValues; ++i)
  48. values[i] = FastMathApproximations::cosh (values[i]);
  49. }
  50. /** Provides a fast approximation of the function sinh(x) using a Pade approximant
  51. continued fraction, calculated sample by sample.
  52. Note: This is an approximation which works on a limited range. You are
  53. advised to use input values only between -5 and +5 for limiting the error.
  54. */
  55. template <typename FloatType>
  56. static FloatType sinh (FloatType x) noexcept
  57. {
  58. auto x2 = x * x;
  59. auto numerator = -x * (11511339840 + x2 * (1640635920 + x2 * (52785432 + x2 * 479249)));
  60. auto denominator = -11511339840 + x2 * (277920720 + x2 * (-3177720 + x2 * 18361));
  61. return numerator / denominator;
  62. }
  63. /** Provides a fast approximation of the function sinh(x) using a Pade approximant
  64. continued fraction, calculated on a whole buffer.
  65. Note: This is an approximation which works on a limited range. You are
  66. advised to use input values only between -5 and +5 for limiting the error.
  67. */
  68. template <typename FloatType>
  69. static void sinh (FloatType* values, size_t numValues) noexcept
  70. {
  71. for (size_t i = 0; i < numValues; ++i)
  72. values[i] = FastMathApproximations::sinh (values[i]);
  73. }
  74. /** Provides a fast approximation of the function tanh(x) using a Pade approximant
  75. continued fraction, calculated sample by sample.
  76. Note: This is an approximation which works on a limited range. You are
  77. advised to use input values only between -5 and +5 for limiting the error.
  78. */
  79. template <typename FloatType>
  80. static FloatType tanh (FloatType x) noexcept
  81. {
  82. auto x2 = x * x;
  83. auto numerator = x * (135135 + x2 * (17325 + x2 * (378 + x2)));
  84. auto denominator = 135135 + x2 * (62370 + x2 * (3150 + 28 * x2));
  85. return numerator / denominator;
  86. }
  87. /** Provides a fast approximation of the function tanh(x) using a Pade approximant
  88. continued fraction, calculated on a whole buffer.
  89. Note: This is an approximation which works on a limited range. You are
  90. advised to use input values only between -5 and +5 for limiting the error.
  91. */
  92. template <typename FloatType>
  93. static void tanh (FloatType* values, size_t numValues) noexcept
  94. {
  95. for (size_t i = 0; i < numValues; ++i)
  96. values[i] = FastMathApproximations::tanh (values[i]);
  97. }
  98. //==============================================================================
  99. /** Provides a fast approximation of the function cos(x) using a Pade approximant
  100. continued fraction, calculated sample by sample.
  101. Note: This is an approximation which works on a limited range. You are
  102. advised to use input values only between -pi and +pi for limiting the error.
  103. */
  104. template <typename FloatType>
  105. static FloatType cos (FloatType x) noexcept
  106. {
  107. auto x2 = x * x;
  108. auto numerator = -(-39251520 + x2 * (18471600 + x2 * (-1075032 + 14615 * x2)));
  109. auto denominator = 39251520 + x2 * (1154160 + x2 * (16632 + x2 * 127));
  110. return numerator / denominator;
  111. }
  112. /** Provides a fast approximation of the function cos(x) using a Pade approximant
  113. continued fraction, calculated on a whole buffer.
  114. Note: This is an approximation which works on a limited range. You are
  115. advised to use input values only between -pi and +pi for limiting the error.
  116. */
  117. template <typename FloatType>
  118. static void cos (FloatType* values, size_t numValues) noexcept
  119. {
  120. for (size_t i = 0; i < numValues; ++i)
  121. values[i] = FastMathApproximations::cos (values[i]);
  122. }
  123. /** Provides a fast approximation of the function sin(x) using a Pade approximant
  124. continued fraction, calculated sample by sample.
  125. Note: This is an approximation which works on a limited range. You are
  126. advised to use input values only between -pi and +pi for limiting the error.
  127. */
  128. template <typename FloatType>
  129. static FloatType sin (FloatType x) noexcept
  130. {
  131. auto x2 = x * x;
  132. auto numerator = -x * (-11511339840 + x2 * (1640635920 + x2 * (-52785432 + x2 * 479249)));
  133. auto denominator = 11511339840 + x2 * (277920720 + x2 * (3177720 + x2 * 18361));
  134. return numerator / denominator;
  135. }
  136. /** Provides a fast approximation of the function sin(x) using a Pade approximant
  137. continued fraction, calculated on a whole buffer.
  138. Note: This is an approximation which works on a limited range. You are
  139. advised to use input values only between -pi and +pi for limiting the error.
  140. */
  141. template <typename FloatType>
  142. static void sin (FloatType* values, size_t numValues) noexcept
  143. {
  144. for (size_t i = 0; i < numValues; ++i)
  145. values[i] = FastMathApproximations::sin (values[i]);
  146. }
  147. /** Provides a fast approximation of the function tan(x) using a Pade approximant
  148. continued fraction, calculated sample by sample.
  149. Note: This is an approximation which works on a limited range. You are
  150. advised to use input values only between -pi/2 and +pi/2 for limiting the error.
  151. */
  152. template <typename FloatType>
  153. static FloatType tan (FloatType x) noexcept
  154. {
  155. auto x2 = x * x;
  156. auto numerator = x * (-135135 + x2 * (17325 + x2 * (-378 + x2)));
  157. auto denominator = -135135 + x2 * (62370 + x2 * (-3150 + 28 * x2));
  158. return numerator / denominator;
  159. }
  160. /** Provides a fast approximation of the function tan(x) using a Pade approximant
  161. continued fraction, calculated on a whole buffer.
  162. Note: This is an approximation which works on a limited range. You are
  163. advised to use input values only between -pi/2 and +pi/2 for limiting the error.
  164. */
  165. template <typename FloatType>
  166. static void tan (FloatType* values, size_t numValues) noexcept
  167. {
  168. for (size_t i = 0; i < numValues; ++i)
  169. values[i] = FastMathApproximations::tan (values[i]);
  170. }
  171. //==============================================================================
  172. /** Provides a fast approximation of the function exp(x) using a Pade approximant
  173. continued fraction, calculated sample by sample.
  174. Note: This is an approximation which works on a limited range. You are
  175. advised to use input values only between -6 and +4 for limiting the error.
  176. */
  177. template <typename FloatType>
  178. static FloatType exp (FloatType x) noexcept
  179. {
  180. auto numerator = 1680 + x * (840 + x * (180 + x * (20 + x)));
  181. auto denominator = 1680 + x *(-840 + x * (180 + x * (-20 + x)));
  182. return numerator / denominator;
  183. }
  184. /** Provides a fast approximation of the function exp(x) using a Pade approximant
  185. continued fraction, calculated on a whole buffer.
  186. Note: This is an approximation which works on a limited range. You are
  187. advised to use input values only between -6 and +4 for limiting the error.
  188. */
  189. template <typename FloatType>
  190. static void exp (FloatType* values, size_t numValues) noexcept
  191. {
  192. for (size_t i = 0; i < numValues; ++i)
  193. values[i] = FastMathApproximations::exp (values[i]);
  194. }
  195. /** Provides a fast approximation of the function log(x+1) using a Pade approximant
  196. continued fraction, calculated sample by sample.
  197. Note: This is an approximation which works on a limited range. You are
  198. advised to use input values only between -0.8 and +5 for limiting the error.
  199. */
  200. template <typename FloatType>
  201. static FloatType logNPlusOne (FloatType x) noexcept
  202. {
  203. auto numerator = x * (7560 + x * (15120 + x * (9870 + x * (2310 + x * 137))));
  204. auto denominator = 7560 + x * (18900 + x * (16800 + x * (6300 + x * (900 + 30 * x))));
  205. return numerator / denominator;
  206. }
  207. /** Provides a fast approximation of the function log(x+1) using a Pade approximant
  208. continued fraction, calculated on a whole buffer.
  209. Note: This is an approximation which works on a limited range. You are
  210. advised to use input values only between -0.8 and +5 for limiting the error.
  211. */
  212. template <typename FloatType>
  213. static void logNPlusOne (FloatType* values, size_t numValues) noexcept
  214. {
  215. for (size_t i = 0; i < numValues; ++i)
  216. values[i] = FastMathApproximations::logNPlusOne (values[i]);
  217. }
  218. };
  219. } // namespace juce::dsp