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.

139 lines
2.9KB

  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. /** Applies the Hann window to a signal `x` */
  27. inline void hannWindow(float *x, int len) {
  28. for (int i = 0; i < len; i++) {
  29. x[i] *= hann((float) i / (len - 1));
  30. }
  31. }
  32. /** Blackman window function
  33. https://en.wikipedia.org/wiki/Window_function#Blackman_window
  34. A typical alpha value is 0.16.
  35. */
  36. inline float blackman(float alpha, float p) {
  37. return
  38. + (1 - alpha) / 2.f
  39. - 1 / 2.f * std::cos(2*M_PI * p)
  40. + alpha / 2.f * std::cos(4*M_PI * p);
  41. }
  42. inline void blackmanWindow(float alpha, float *x, int len) {
  43. for (int i = 0; i < len; i++) {
  44. x[i] *= blackman(alpha, (float) i / (len - 1));
  45. }
  46. }
  47. /** Blackman-Nuttall window function
  48. https://en.wikipedia.org/wiki/Window_function#Blackman%E2%80%93Nuttall_window
  49. */
  50. inline float blackmanNuttall(float p) {
  51. return
  52. + 0.3635819f
  53. - 0.4891775f * std::cos(2*M_PI * p)
  54. + 0.1365995f * std::cos(4*M_PI * p)
  55. - 0.0106411f * std::cos(6*M_PI * p);
  56. }
  57. inline void blackmanNuttallWindow(float *x, int len) {
  58. for (int i = 0; i < len; i++) {
  59. x[i] *= blackmanNuttall((float) i / (len - 1));
  60. }
  61. }
  62. /** Blackman-Harris window function
  63. https://en.wikipedia.org/wiki/Window_function#Blackman%E2%80%93Harris_window
  64. */
  65. inline float blackmanHarris(float p) {
  66. return
  67. + 0.35875f
  68. - 0.48829f * std::cos(2*M_PI * p)
  69. + 0.14128f * std::cos(4*M_PI * p)
  70. - 0.01168f * std::cos(6*M_PI * p);
  71. }
  72. inline void blackmanHarrisWindow(float *x, int len) {
  73. for (int i = 0; i < len; i++) {
  74. x[i] *= blackmanHarris((float) i / (len - 1));
  75. }
  76. }
  77. // Conversion functions
  78. inline float amplitudeToDb(float amp) {
  79. return std::log10(amp) * 20.f;
  80. }
  81. inline float dbToAmplitude(float db) {
  82. return std::pow(10.f, db / 20.f);
  83. }
  84. // Functions for parameter scaling
  85. inline float quadraticBipolar(float x) {
  86. float x2 = x*x;
  87. return (x >= 0.f) ? x2 : -x2;
  88. }
  89. inline float cubic(float x) {
  90. return x*x*x;
  91. }
  92. inline float quarticBipolar(float x) {
  93. float y = x*x*x*x;
  94. return (x >= 0.f) ? y : -y;
  95. }
  96. inline float quintic(float x) {
  97. // optimal with -fassociative-math
  98. return x*x*x*x*x;
  99. }
  100. inline float sqrtBipolar(float x) {
  101. return (x >= 0.f) ? std::sqrt(x) : -std::sqrt(-x);
  102. }
  103. /** This is pretty much a scaled sinh */
  104. inline float exponentialBipolar(float b, float x) {
  105. const float a = b - 1.f / b;
  106. return (std::pow(b, x) - std::pow(b, -x)) / a;
  107. }
  108. } // namespace dsp
  109. } // namespace rack