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.

143 lines
3.7KB

  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 = double_Pi * 0.5;
  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 = double_Pi * 0.5;
  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. std::complex<double> last = std::cos (0.5 * u * double_Pi);
  68. for (int i = M - 1; i >= 0; --i)
  69. last = (1.0 + ke[i + 1]) / (1.0 / last + ke[i + 1] * last);
  70. return last;
  71. }
  72. Complex<double> SpecialFunctions::sne (Complex<double> u, double k) noexcept
  73. {
  74. constexpr int M = 4;
  75. double ke[M + 1];
  76. double* kei = ke;
  77. *kei = k;
  78. for (int i = 0; i < M; ++i)
  79. {
  80. auto next = std::pow (*kei / (1 + std::sqrt (1 - std::pow (*kei, 2.0))), 2.0);
  81. *++kei = next;
  82. }
  83. std::complex<double> last = std::sin (0.5 * u * double_Pi);
  84. for (int i = M - 1; i >= 0; --i)
  85. last = (1.0 + ke[i + 1]) / (1.0 / last + ke[i + 1] * last);
  86. return last;
  87. }
  88. Complex<double> SpecialFunctions::asne (Complex<double> w, double k) noexcept
  89. {
  90. constexpr int M = 4;
  91. double ke[M + 1];
  92. double* kei = ke;
  93. *kei = k;
  94. for (int i = 0; i < M; ++i)
  95. {
  96. auto next = std::pow (*kei / (1.0 + std::sqrt (1.0 - std::pow (*kei, 2.0))), 2.0);
  97. *++kei = next;
  98. }
  99. std::complex<double> last = w;
  100. for (int i = 1; i <= M; ++i)
  101. last = 2.0 * last / ((1.0 + ke[i]) * (1.0 + std::sqrt (1.0 - std::pow (ke[i - 1] * last, 2.0))));
  102. return 2.0 / double_Pi * std::asin (last);
  103. }
  104. } // namespace dsp
  105. } // namespace juce