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.

145 lines
4.0KB

  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE library.
  4. Copyright (c) 2017 - ROLI Ltd.
  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 5 End-User License
  8. Agreement and JUCE 5 Privacy Policy (both updated and effective as of the
  9. 27th April 2017).
  10. End User License Agreement: www.juce.com/juce-5-licence
  11. Privacy Policy: www.juce.com/juce-5-privacy-policy
  12. Or: You may also use this code under the terms of the GPL v3 (see
  13. www.gnu.org/licenses).
  14. JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
  15. EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
  16. DISCLAIMED.
  17. ==============================================================================
  18. */
  19. namespace juce
  20. {
  21. namespace dsp
  22. {
  23. double SpecialFunctions::besselI0 (double x) noexcept
  24. {
  25. auto ax = std::abs (x);
  26. if (ax < 3.75)
  27. {
  28. auto y = x / 3.75;
  29. y *= y;
  30. return 1.0 + y * (3.5156229 + y * (3.0899424 + y * (1.2067492
  31. + y * (0.2659732 + y * (0.360768e-1 + y * 0.45813e-2)))));
  32. }
  33. auto y = 3.75 / ax;
  34. return (std::exp (ax) / std::sqrt (ax))
  35. * (0.39894228 + y * (0.1328592e-1 + y * (0.225319e-2 + y * (-0.157565e-2 + y * (0.916281e-2
  36. + y * (-0.2057706e-1 + y * (0.2635537e-1 + y * (-0.1647633e-1 + y * 0.392377e-2))))))));
  37. }
  38. void SpecialFunctions::ellipticIntegralK (double k, double& K, double& Kp) noexcept
  39. {
  40. constexpr int M = 4;
  41. K = MathConstants<double>::halfPi;
  42. auto lastK = k;
  43. for (int i = 0; i < M; ++i)
  44. {
  45. lastK = std::pow (lastK / (1 + std::sqrt (1 - std::pow (lastK, 2.0))), 2.0);
  46. K *= 1 + lastK;
  47. }
  48. Kp = MathConstants<double>::halfPi;
  49. auto last = std::sqrt (1 - k * k);
  50. for (int i = 0; i < M; ++i)
  51. {
  52. last = std::pow (last / (1.0 + std::sqrt (1.0 - std::pow (last, 2.0))), 2.0);
  53. Kp *= 1 + last;
  54. }
  55. }
  56. Complex<double> SpecialFunctions::cde (Complex<double> u, double k) noexcept
  57. {
  58. constexpr int M = 4;
  59. double ke[M + 1];
  60. double* kei = ke;
  61. *kei = k;
  62. for (int i = 0; i < M; ++i)
  63. {
  64. auto next = std::pow (*kei / (1.0 + std::sqrt (1.0 - std::pow (*kei, 2.0))), 2.0);
  65. *++kei = next;
  66. }
  67. // NB: the spurious cast to double here is a workaround for a very odd link-time failure
  68. std::complex<double> last = std::cos (u * (double) MathConstants<double>::halfPi);
  69. for (int i = M - 1; i >= 0; --i)
  70. last = (1.0 + ke[i + 1]) / (1.0 / last + ke[i + 1] * last);
  71. return last;
  72. }
  73. Complex<double> SpecialFunctions::sne (Complex<double> u, double k) noexcept
  74. {
  75. constexpr int M = 4;
  76. double ke[M + 1];
  77. double* kei = ke;
  78. *kei = k;
  79. for (int i = 0; i < M; ++i)
  80. {
  81. auto next = std::pow (*kei / (1 + std::sqrt (1 - std::pow (*kei, 2.0))), 2.0);
  82. *++kei = next;
  83. }
  84. // NB: the spurious cast to double here is a workaround for a very odd link-time failure
  85. std::complex<double> last = std::sin (u * (double) MathConstants<double>::halfPi);
  86. for (int i = M - 1; i >= 0; --i)
  87. last = (1.0 + ke[i + 1]) / (1.0 / last + ke[i + 1] * last);
  88. return last;
  89. }
  90. Complex<double> SpecialFunctions::asne (Complex<double> w, double k) noexcept
  91. {
  92. constexpr int M = 4;
  93. double ke[M + 1];
  94. double* kei = ke;
  95. *kei = k;
  96. for (int i = 0; i < M; ++i)
  97. {
  98. auto next = std::pow (*kei / (1.0 + std::sqrt (1.0 - std::pow (*kei, 2.0))), 2.0);
  99. *++kei = next;
  100. }
  101. std::complex<double> last = w;
  102. for (int i = 1; i <= M; ++i)
  103. last = 2.0 * last / ((1.0 + ke[i]) * (1.0 + std::sqrt (1.0 - std::pow (ke[i - 1] * last, 2.0))));
  104. return 2.0 / MathConstants<double>::pi * std::asin (last);
  105. }
  106. } // namespace dsp
  107. } // namespace juce