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.

193 lines
3.6KB

  1. #include "DSPMath.hpp"
  2. namespace dsp {
  3. /**
  4. * @brief Clip signal at bottom by value
  5. * @param in Sample input
  6. * @param clip Clipping value
  7. * @return Clipped sample
  8. */
  9. float clipl(float in, float clip) {
  10. if (in < clip) return clip;
  11. else return in;
  12. }
  13. /**
  14. * @brief Clip signal at top by value
  15. * @param in Sample input
  16. * @param clip Clipping value
  17. * @return Clipped sample
  18. */
  19. float cliph(float in, float clip) {
  20. if (in > clip) return clip;
  21. else return in;
  22. }
  23. /**
  24. * @brief Wrap input number between -PI..PI
  25. * @param n Input number
  26. * @return Wrapped value
  27. */
  28. float wrapTWOPI(float n) {
  29. float b = 1.f / TWOPI * n;
  30. return (b - lroundf(b)) * TWOPI;
  31. }
  32. /**
  33. * @brief Get PLL increment depending on frequency
  34. * @param frq Frequency
  35. * @return PLL increment
  36. */
  37. float getPhaseIncrement(float frq) {
  38. return TWOPI * frq / engineGetSampleRate();
  39. }
  40. /**
  41. * @brief Actual BLIT core computation
  42. * @param N Harmonics
  43. * @param phase Current phase value
  44. * @return
  45. */
  46. float BLITcore(float N, float phase) {
  47. float a = wrapTWOPI((clipl(N - 1, 0.f) + 0.5f) * phase);
  48. float x = fastSin(a) * 1.f / fastSin(0.5f * phase);
  49. return (x - 1.f) * 2.f;
  50. }
  51. /**
  52. * @brief BLIT generator based on current phase
  53. * @param N Harmonics
  54. * @param phase Current phase of PLL
  55. * @return
  56. */
  57. float BLIT(float N, float phase) {
  58. if (phase == 0.f) return 1.f;
  59. else return BLITcore(N, phase);
  60. }
  61. /**
  62. * @brief Add value to integrator
  63. * @param x Input
  64. * @param Fn
  65. * @return
  66. */
  67. float Integrator::add(float x, float Fn) {
  68. value = (x - value) * (d * Fn) + value;
  69. return value;
  70. }
  71. /**
  72. * @brief Filter function for DC block
  73. * @param x Input sample
  74. * @return Filtered sample
  75. */
  76. double DCBlocker::filter(double x) {
  77. double y = x - xm1 + r * ym1;
  78. xm1 = x;
  79. ym1 = y;
  80. return y;
  81. }
  82. DCBlocker::DCBlocker(double r) : r(r) {}
  83. /**
  84. * @brief Filter function for simple 6dB lowpass filter
  85. * @param x Input sample
  86. * @return
  87. */
  88. float LP6DBFilter::filter(float x) {
  89. float y = y0 + (alpha * (x - y0));
  90. y0 = y;
  91. return y;
  92. }
  93. /**
  94. * @brief Update filter parameter
  95. * @param fc Cutoff frequency
  96. */
  97. void LP6DBFilter::updateFrequency(float fc, int factor) {
  98. LP6DBFilter::fc = fc;
  99. RC = 1.f / (LP6DBFilter::fc * TWOPI);
  100. dt = 1.f / engineGetSampleRate() * factor;
  101. alpha = dt / (RC + dt);
  102. }
  103. /**
  104. * @brief Shaper type 1 (Saturate)
  105. * @param a Amount from 0 - x
  106. * @param x Input sample
  107. * @return
  108. */
  109. float shape1(float a, float x) {
  110. float k = 2 * a / (1 - a);
  111. float b = (1 + k) * (x * 0.5f) / (1 + k * fabsf(x * 0.5f));
  112. return b * 4;
  113. }
  114. /**
  115. * @brief Waveshaper as used in ReShaper. Input should be in the range -1..+1
  116. * @param a Shaping factor
  117. * @param x Input sample
  118. * @return
  119. */
  120. float shape2(float a, float x) {
  121. return atanf(x * a);//x * (fabs(x) + a) / (x * x + (a - 1) * fabs(x) + 1);
  122. }
  123. /**
  124. * @brief Soft saturating with a clip of a. Works only with positive values so use 'b' as helper here.
  125. * @param x Input sample
  126. * @param a Saturating threshold
  127. * @return
  128. */
  129. double saturate(double x, double a) {
  130. double b = 1;
  131. /* turn negative values positive and remind in b as coefficient */
  132. if (x < 0) {
  133. b = -1;
  134. x *= -1;
  135. }
  136. // nothing to do
  137. if (x <= a) return x * b;
  138. double d = (a + (x - a) / (1 + pow((x - a) / (1 - a), 2)));
  139. if (d > 1) {
  140. return (a + 1) / 2 * b;
  141. } else {
  142. return d * b;
  143. }
  144. }
  145. /**
  146. * @brief
  147. * @param input
  148. * @return
  149. */
  150. double overdrive(double input) {
  151. const double x = input * 0.686306;
  152. const double a = 1 + exp(sqrt(fabs(x)) * -0.75);
  153. return (exp(x) - exp(-x * a)) / (exp(x) + exp(-x));
  154. }
  155. } // namespace rack_plugin_LindenbergResearch