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.

179 lines
3.3KB

  1. #pragma once
  2. #include <dsp/common.hpp>
  3. namespace rack {
  4. namespace dsp {
  5. /** The simplest possible analog filter using an Euler solver.
  6. https://en.wikipedia.org/wiki/RC_circuit
  7. Use two RC filters in series for a bandpass filter.
  8. */
  9. template <typename T = float>
  10. struct TRCFilter {
  11. T c = 0.f;
  12. T xstate[1];
  13. T ystate[1];
  14. TRCFilter() {
  15. reset();
  16. }
  17. void reset() {
  18. xstate[0] = 0.f;
  19. ystate[0] = 0.f;
  20. }
  21. /** Sets the cutoff angular frequency in radians.
  22. */
  23. void setCutoff(T r) {
  24. c = 2.f / r;
  25. }
  26. /** Sets the cutoff frequency.
  27. `f` is the ratio between the cutoff frequency and sample rate, i.e. f = f_c / f_s
  28. */
  29. void setCutoffFreq(T f) {
  30. setCutoff(2.f * M_PI * f);
  31. }
  32. void process(T x) {
  33. T y = (x + xstate[0] - ystate[0] * (1 - c)) / (1 + c);
  34. xstate[0] = x;
  35. ystate[0] = y;
  36. }
  37. T lowpass() {
  38. return ystate[0];
  39. }
  40. T highpass() {
  41. return xstate[0] - ystate[0];
  42. }
  43. };
  44. typedef TRCFilter<> RCFilter;
  45. /** Applies exponential smoothing to a signal with the ODE
  46. \f$ \frac{dy}{dt} = x \lambda \f$.
  47. */
  48. template <typename T = float>
  49. struct TExponentialFilter {
  50. T out = 0.f;
  51. T lambda = 0.f;
  52. void reset() {
  53. out = 0.f;
  54. }
  55. void setLambda(T lambda) {
  56. this->lambda = lambda;
  57. }
  58. T process(T deltaTime, T in) {
  59. T y = out + (in - out) * lambda * deltaTime;
  60. // If no change was made between the old and new output, assume T granularity is too small and snap output to input
  61. out = simd::ifelse(out == y, in, y);
  62. return out;
  63. }
  64. DEPRECATED T process(T in) {
  65. return process(1.f, in);
  66. }
  67. };
  68. typedef TExponentialFilter<> ExponentialFilter;
  69. /** Like ExponentialFilter but jumps immediately to higher values.
  70. */
  71. template <typename T = float>
  72. struct TPeakFilter {
  73. T out = 0.f;
  74. T lambda = 0.f;
  75. void reset() {
  76. out = 0.f;
  77. }
  78. void setLambda(T lambda) {
  79. this->lambda = lambda;
  80. }
  81. T process(T deltaTime, T in) {
  82. T y = out + (in - out) * lambda * deltaTime;
  83. out = simd::fmax(y, in);
  84. return out;
  85. }
  86. /** Use the return value of process() instead. */
  87. DEPRECATED T peak() {
  88. return out;
  89. }
  90. /** Use setLambda() instead. */
  91. DEPRECATED void setRate(T r) {
  92. lambda = 1.f - r;
  93. }
  94. DEPRECATED T process(T x) {
  95. return process(1.f, x);
  96. }
  97. };
  98. typedef TPeakFilter<> PeakFilter;
  99. template <typename T = float>
  100. struct TSlewLimiter {
  101. T out = 0.f;
  102. T rise = 0.f;
  103. T fall = 0.f;
  104. void reset() {
  105. out = 0.f;
  106. }
  107. void setRiseFall(T rise, T fall) {
  108. this->rise = rise;
  109. this->fall = fall;
  110. }
  111. T process(T deltaTime, T in) {
  112. out = simd::clamp(in, out - fall * deltaTime, out + rise * deltaTime);
  113. return out;
  114. }
  115. DEPRECATED T process(T in) {
  116. return process(1.f, in);
  117. }
  118. };
  119. typedef TSlewLimiter<> SlewLimiter;
  120. template <typename T = float>
  121. struct TExponentialSlewLimiter {
  122. T out = 0.f;
  123. T riseLambda = 0.f;
  124. T fallLambda = 0.f;
  125. void reset() {
  126. out = 0.f;
  127. }
  128. void setRiseFall(T riseLambda, T fallLambda) {
  129. this->riseLambda = riseLambda;
  130. this->fallLambda = fallLambda;
  131. }
  132. T process(T deltaTime, T in) {
  133. T lambda = simd::ifelse(in > out, riseLambda, fallLambda);
  134. T y = out + (in - out) * lambda * deltaTime;
  135. // If the change from the old out to the new out is too small for floats, set `in` directly.
  136. out = simd::ifelse(out == y, in, y);
  137. return out;
  138. }
  139. DEPRECATED T process(T in) {
  140. return process(1.f, in);
  141. }
  142. };
  143. typedef TExponentialSlewLimiter<> ExponentialSlewLimiter;
  144. } // namespace dsp
  145. } // namespace rack