Eq.h 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. /*
  2. Eq.h
  3. Copyright 2004-7 Tim Goetze <tim@quitte.de>
  4. http://quitte.de/dsp/
  5. Equalizer circuit using recursive filtering.
  6. Based on a motorola paper implementing a similar circuit on a DSP56001.
  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. #ifndef _DSP_EQ_H_
  23. #define _DSP_EQ_H_
  24. namespace DSP {
  25. /* A single bandpass as used by the Eq, expressed as a biquad. Like all
  26. * band-pass filters I know of, the filter works with a FIR coefficient of 0
  27. * for x[-1], so a generic biquad isn't the optimum implementation.
  28. *
  29. * This routine isn't used anywhere, just here for testing purposes.
  30. */
  31. template <class T>
  32. void
  33. _BP (double fc, double Q, T * ca, T * cb)
  34. {
  35. double theta = 2 * fc * M_PI;
  36. double
  37. b = (Q - theta * .5) / (2 * Q + theta),
  38. a = (.5 - b) / 2,
  39. c = (.5 + b) * cos (theta);
  40. ca[0] = 2 * a;
  41. ca[1] = 0;
  42. ca[2] = -2 * a;
  43. cb[0] = 0;
  44. cb[1] = 2 * c;
  45. cb[2] = -2 * b;
  46. }
  47. template <int Bands, class eq_sample = float>
  48. class Eq
  49. {
  50. public:
  51. /* recursion coefficients, 3 per band */
  52. eq_sample __attribute__ ((aligned)) a[Bands], b[Bands], c[Bands];
  53. /* past outputs, 2 per band */
  54. eq_sample __attribute__ ((aligned)) y[2][Bands];
  55. /* current gain and recursion factor, each 1 per band = 2 */
  56. eq_sample __attribute__ ((aligned)) gain[Bands], gf[Bands];
  57. /* input history */
  58. eq_sample x[2];
  59. /* history index */
  60. int h;
  61. eq_sample normal;
  62. Eq()
  63. {
  64. h = 0;
  65. normal = NOISE_FLOOR;
  66. }
  67. void reset()
  68. {
  69. for (int z = 0; z < 2; ++z)
  70. {
  71. memset( y[z], 0, Bands*sizeof( eq_sample ) );
  72. x[z] = 0;
  73. }
  74. }
  75. void init (double fs, double Q)
  76. {
  77. double f = 31.25;
  78. int i = 0;
  79. for (i = 0; i < Bands && f < fs / 2; ++i, f *= 2)
  80. init_band (i, 2 * f * M_PI / fs, Q);
  81. /* just in case, zero the remaining coefficients */
  82. for ( ; i < Bands; ++i)
  83. zero_band (i);
  84. reset();
  85. }
  86. void init_band (int i, double theta, double Q)
  87. {
  88. b[i] = (Q - theta * .5) / (2 * Q + theta);
  89. a[i] = (.5 - b[i]) / 2;
  90. c[i] = (.5 + b[i]) * cos (theta);
  91. /* fprintf (stderr, "%02d %f %f %f\n", i, a[i], b[i], c[i]); */
  92. gain[i] = 1;
  93. gf[i] = 1;
  94. }
  95. void zero_band (int i)
  96. {
  97. a[i] = b[i] = c[i] = 0;
  98. }
  99. /* per-band recursion:
  100. * y = 2 * (a * (x - x[-2]) + c * y[-1] - b * y[-2])
  101. */
  102. eq_sample process (eq_sample s)
  103. {
  104. int z1 = h, z2 = h ^ 1;
  105. eq_sample * y1 = y[z1];
  106. eq_sample * y2 = y[z2];
  107. eq_sample x_x2 = s - x[z2];
  108. eq_sample r = 0;
  109. for (int i = 0; i < Bands; ++i)
  110. {
  111. y2[i] = normal + 2 * (a[i] * x_x2 + c[i] * y1[i] - b[i] * y2[i]);
  112. r += gain[i] * y2[i];
  113. gain[i] *= gf[i];
  114. }
  115. x[z2] = s;
  116. h = z2;
  117. return r;
  118. }
  119. /* zap denormals in history */
  120. void flush_0()
  121. {
  122. for (int i = 0; i < Bands; ++i)
  123. if (is_denormal (y[0][i]))
  124. y[0][i] = 0;
  125. }
  126. };
  127. } /* namespace DSP */
  128. #endif /* _DSP_EQ_H_ */