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.

138 lines
2.8KB

  1. #pragma once
  2. #include "math.hpp"
  3. namespace rack {
  4. namespace dsp {
  5. // Constants
  6. static const float FREQ_C4 = 261.6256f;
  7. static const float FREQ_A4 = 440.0000f;
  8. // Mathematical functions
  9. /** The normalized sinc function
  10. See https://en.wikipedia.org/wiki/Sinc_function
  11. */
  12. inline float sinc(float x) {
  13. if (x == 0.f)
  14. return 1.f;
  15. x *= M_PI;
  16. return std::sin(x) / x;
  17. }
  18. // Window functions
  19. /** Hann window function
  20. p: proportion from [0, 1], usually `i / (len - 1)`
  21. https://en.wikipedia.org/wiki/Window_function#Hann_and_Hamming_windows
  22. */
  23. inline float hann(float p) {
  24. return 0.5f * (1.f - std::cos(2*M_PI * p));
  25. }
  26. inline void hannWindow(float *x, int len) {
  27. for (int i = 0; i < len; i++) {
  28. x[i] *= hann((float) i / (len - 1));
  29. }
  30. }
  31. /** Blackman window function
  32. https://en.wikipedia.org/wiki/Window_function#Blackman_window
  33. A typical alpha value is 0.16.
  34. */
  35. inline float blackman(float alpha, float p) {
  36. return
  37. + (1 - alpha) / 2.f
  38. - 1 / 2.f * std::cos(2*M_PI * p)
  39. + alpha / 2.f * std::cos(4*M_PI * p);
  40. }
  41. inline void blackmanWindow(float alpha, float *x, int len) {
  42. for (int i = 0; i < len; i++) {
  43. x[i] *= blackman(alpha, (float) i / (len - 1));
  44. }
  45. }
  46. /** Blackman-Nuttall window function
  47. https://en.wikipedia.org/wiki/Window_function#Blackman%E2%80%93Nuttall_window
  48. */
  49. inline float blackmanNuttall(float p) {
  50. return
  51. + 0.3635819f
  52. - 0.4891775f * std::cos(2*M_PI * p)
  53. + 0.1365995f * std::cos(4*M_PI * p)
  54. - 0.0106411f * std::cos(6*M_PI * p);
  55. }
  56. inline void blackmanNuttallWindow(float *x, int len) {
  57. for (int i = 0; i < len; i++) {
  58. x[i] *= blackmanNuttall((float) i / (len - 1));
  59. }
  60. }
  61. /** Blackman-Harris window function
  62. https://en.wikipedia.org/wiki/Window_function#Blackman%E2%80%93Harris_window
  63. */
  64. inline float blackmanHarris(float p) {
  65. return
  66. + 0.35875f
  67. - 0.48829f * std::cos(2*M_PI * p)
  68. + 0.14128f * std::cos(4*M_PI * p)
  69. - 0.01168f * std::cos(6*M_PI * p);
  70. }
  71. inline void blackmanHarrisWindow(float *x, int len) {
  72. for (int i = 0; i < len; i++) {
  73. x[i] *= blackmanHarris((float) i / (len - 1));
  74. }
  75. }
  76. // Conversion functions
  77. inline float amplitudeToDb(float amp) {
  78. return std::log10(amp) * 20.f;
  79. }
  80. inline float dbToAmplitude(float db) {
  81. return std::pow(10.f, db / 20.f);
  82. }
  83. // Functions for parameter scaling
  84. inline float quadraticBipolar(float x) {
  85. float x2 = x*x;
  86. return (x >= 0.f) ? x2 : -x2;
  87. }
  88. inline float cubic(float x) {
  89. return x*x*x;
  90. }
  91. inline float quarticBipolar(float x) {
  92. float y = x*x*x*x;
  93. return (x >= 0.f) ? y : -y;
  94. }
  95. inline float quintic(float x) {
  96. // optimal with -fassociative-math
  97. return x*x*x*x*x;
  98. }
  99. inline float sqrtBipolar(float x) {
  100. return (x >= 0.f) ? std::sqrt(x) : -std::sqrt(-x);
  101. }
  102. /** This is pretty much a scaled sinh */
  103. inline float exponentialBipolar(float b, float x) {
  104. const float a = b - 1.f / b;
  105. return (std::pow(b, x) - std::pow(b, -x)) / a;
  106. }
  107. } // namespace dsp
  108. } // namespace rack