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.

99 lines
1.8KB

  1. #pragma once
  2. #include <common.hpp>
  3. #include <math.hpp>
  4. #include <simd/functions.hpp>
  5. namespace rack {
  6. /** Digital signal processing routines
  7. */
  8. namespace dsp {
  9. // Constants
  10. static const float FREQ_C4 = 261.6256f;
  11. static const float FREQ_A4 = 440.0000f;
  12. static const float FREQ_SEMITONE = 1.0594630943592953f;
  13. // Mathematical functions
  14. /** The normalized sinc function
  15. See https://en.wikipedia.org/wiki/Sinc_function
  16. */
  17. inline float sinc(float x) {
  18. if (x == 0.f)
  19. return 1.f;
  20. x *= M_PI;
  21. return std::sin(x) / x;
  22. }
  23. template <typename T>
  24. T sinc(T x) {
  25. T zeromask = (x == 0.f);
  26. x *= M_PI;
  27. x = simd::sin(x) / x;
  28. return simd::ifelse(zeromask, 1.f, x);
  29. }
  30. // Conversion functions
  31. template <typename T>
  32. T amplitudeToDb(T amp) {
  33. return simd::log10(amp) * 20;
  34. }
  35. template <typename T>
  36. T dbToAmplitude(T db) {
  37. return std::pow(10, db / 20);
  38. }
  39. // Functions for parameter scaling
  40. template <typename T>
  41. T quadraticBipolar(T x) {
  42. return simd::sgn(x) * (x * x);
  43. }
  44. template <typename T>
  45. T cubic(T x) {
  46. return x * x * x;
  47. }
  48. template <typename T>
  49. T quarticBipolar(T x) {
  50. return simd::sgn(x) * (x * x * x * x);
  51. }
  52. template <typename T>
  53. T quintic(T x) {
  54. // optimal with -fassociative-math
  55. return x * x * x * x * x;
  56. }
  57. template <typename T>
  58. T sqrtBipolar(T x) {
  59. return simd::sgn(x) * simd::sqrt(x);
  60. }
  61. /** This is pretty much a scaled sinh.
  62. Slow. Not recommended for parameter scaling.
  63. */
  64. template <typename T>
  65. T exponentialBipolar(T b, T x) {
  66. return (simd::pow(b, x) - simd::pow(b, -x)) / (b - 1.f / b);
  67. }
  68. /** Useful for storing arrays of samples in ring buffers and casting them to `float*` to be used by interleaved processors, like SampleRateConverter */
  69. template <size_t CHANNELS, typename T = float>
  70. struct Frame {
  71. T samples[CHANNELS];
  72. };
  73. } // namespace dsp
  74. } // namespace rack