SVF.h 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. /*
  2. dsp/SVF.h
  3. Copyright 2002-4 Tim Goetze <tim@quitte.de>
  4. http://quitte.de/dsp/
  5. ladder filter in Chamberlin topology. supports largely independent
  6. f and Q adjustments and sweeps.
  7. */
  8. /*
  9. This program is free software; you can redistribute it and/or
  10. modify it under the terms of the GNU General Public License
  11. as published by the Free Software Foundation; either version 2
  12. of the License, or (at your option) any later version.
  13. This program is distributed in the hope that it will be useful,
  14. but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. GNU General Public License for more details.
  17. You should have received a copy of the GNU General Public License
  18. along with this program; if not, write to the Free Software
  19. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
  20. 02111-1307, USA or point your web browser to http://www.gnu.org.
  21. */
  22. /*
  23. inspired by this music-dsp entry:
  24. State Variable Filter (Double Sampled, Stable)
  25. Type : 2 Pole Low, High, Band, Notch and Peaking
  26. References :Posted by Andrew Simper
  27. Notes :
  28. Thanks to Laurent de Soras for the stability limit
  29. and Steffan Diedrichsen for the correct notch output.
  30. Code :
  31. input = input buffer;
  32. output = output buffer;
  33. fs = sampling frequency;
  34. fc = cutoff frequency normally something like:
  35. 440.0*pow(2.0, (midi_note - 69.0)/12.0);
  36. res = resonance 0 to 1;
  37. drive = internal distortion 0 to 0.1
  38. freq = MIN(0.25, 2.0*sin(PI*fc/(fs*2))); // the fs*2 is because it's double sampled
  39. damp = MIN(2.0*(1.0 - pow(res, 0.25)), MIN(2.0, 2.0/freq - freq*0.5));
  40. notch = notch output
  41. low = low pass output
  42. high = high pass output
  43. band = band pass output
  44. peak = peaking output = low - high
  45. --
  46. double sampled svf loop:
  47. for (i=0; i<numSamples; i++)
  48. {
  49. in = input[i];
  50. notch = in - damp*band;
  51. low = low + freq*band;
  52. high = notch - low;
  53. band = freq*high + band - drive*band*band*band;
  54. out = 0.5*(notch or low or high or band or peak);
  55. notch = in - damp*band;
  56. low = low + freq*band;
  57. high = notch - low;
  58. band = freq*high + band - drive*band*band*band;
  59. out += 0.5*(same out as above);
  60. output[i] = out;
  61. }
  62. */
  63. #ifndef _DSP_SVF_H_
  64. #define _DSP_SVF_H_
  65. namespace DSP {
  66. template <int OVERSAMPLE>
  67. class SVF
  68. {
  69. protected:
  70. /* loop parameters */
  71. sample_t f, q, qnorm;
  72. /* outputs (peak and notch left out) */
  73. sample_t lo, band, hi;
  74. sample_t * out;
  75. public:
  76. /* the type of filtering to do. */
  77. enum {
  78. Low = 0,
  79. Band = 1,
  80. High = 2
  81. };
  82. SVF()
  83. {
  84. set_out (Low);
  85. set_f_Q (.1, .1);
  86. }
  87. void reset()
  88. {
  89. hi = band = lo = 0;
  90. }
  91. void set_f_Q (double fc, double Q)
  92. {
  93. /* this is a very tight limit */
  94. f = min (.25, 2 * sin (M_PI * fc / OVERSAMPLE));
  95. q = 2 * cos (pow (Q, .1) * M_PI * .5);
  96. q = min (q, min (2., 2 / f - f * .5));
  97. qnorm = sqrt (fabs (q) / 2. + .001);
  98. }
  99. void set_out (int o)
  100. {
  101. if (o == Low)
  102. out = &lo;
  103. else if (o == Band)
  104. out = &band;
  105. else
  106. out = &hi;
  107. }
  108. void one_cycle (sample_t * s, int frames)
  109. {
  110. for (int i = 0; i < frames; ++i)
  111. s[i] = process (s[i]);
  112. }
  113. sample_t process (sample_t x)
  114. {
  115. x = qnorm * x;
  116. for (int pass = 0; pass < OVERSAMPLE; ++pass)
  117. {
  118. hi = x - lo - q * band;
  119. band += f * hi;
  120. lo += f * band;
  121. /* zero-padding, not 0th order holding. */
  122. x = 0;
  123. }
  124. /* peak and notch outputs don't belong in the loop, put them
  125. * here (best in a template) if needed. */
  126. return *out;
  127. }
  128. };
  129. template <int STACKED, int OVERSAMPLE>
  130. class StackedSVF
  131. {
  132. public:
  133. SVF<OVERSAMPLE> svf [STACKED];
  134. void reset()
  135. {
  136. for (int i = 0; i < STACKED; ++i)
  137. svf[i].reset();
  138. }
  139. void set_out (int out)
  140. {
  141. for (int i = 0; i < STACKED; ++i)
  142. svf[i].set_out (out);
  143. }
  144. void set_f_Q (double f, double Q)
  145. {
  146. for (int i = 0; i < STACKED; ++i)
  147. svf[i].set_f_Q (f, Q);
  148. }
  149. sample_t process (sample_t x)
  150. {
  151. for (int i = 0; i < STACKED; ++i)
  152. x = svf[i].process (x);
  153. return x;
  154. }
  155. };
  156. } /* namespace DSP */
  157. #endif /* _DSP_SVF_H_ */