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.

258 lines
10KB

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