/[svn]/linuxsampler/trunk/src/engines/common/BiquadFilter.h
ViewVC logotype

Diff of /linuxsampler/trunk/src/engines/common/BiquadFilter.h

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 56 by schoenebeck, Tue Apr 27 09:21:58 2004 UTC revision 80 by schoenebeck, Sun May 23 19:16:33 2004 UTC
# Line 35  namespace LinuxSampler { Line 35  namespace LinuxSampler {
35      typedef float bq_t;      typedef float bq_t;
36    
37      /**      /**
38      * Bi-quadratic filter       * Internal parameters of the biquad filter, which are actually the
39      * (adapted from lisp code by Eli Brandt, http://www.cs.cmu.edu/~eli/)       * final parameters of the filter's transfer function. This strucure is
40      */       * only needed when these parameters should stored outside the
41         * BiquadFilter class, e.g. to save calculation time by sharing them
42         * between multiple filters.
43         */
44        struct biquad_param_t {
45            bq_t a1;
46            bq_t a2;
47            bq_t b0;
48            bq_t b1;
49            bq_t b2;
50        };
51    
52        /**
53         * Bi-quadratic filter
54         * (adapted from lisp code by Eli Brandt, http://www.cs.cmu.edu/~eli/)
55         */
56      class BiquadFilter {      class BiquadFilter {
57          protected:          protected:
58                // following five variables are only used if no external biquad_param_t reference is used
59              bq_t a1;              bq_t a1;
60              bq_t a2;              bq_t a2;
61              bq_t b0;              bq_t b0;
62              bq_t b1;              bq_t b1;
63              bq_t b2;              bq_t b2;
64                // following four variables are used to buffer the feedback
65              bq_t x1;              bq_t x1;
66              bq_t x2;              bq_t x2;
67              bq_t y1;              bq_t y1;
68              bq_t y2;              bq_t y2;
69    
70              /**              /**
71              * Prevent \a f from going into denormal mode which would slow down               * Prevent \a f from going into denormal mode which would slow down
72              * subsequent floating point calculations, we achieve that by setting               * subsequent floating point calculations, we achieve that by setting
73              * \a f to zero when it falls under the denormal threshold value.               * \a f to zero when it falls under the denormal threshold value.
74              */               */
75              inline void KillDenormal(float& f) {              inline void KillDenormal(bq_t& f) {
76                  // TODO: this is a generic solution for 32bit floats, should be replaced by CPU specific asm code                  // TODO: this is a generic solution for 32bit floats, should be replaced by CPU specific asm code
77                  f += 1e-18f;                  f += 1e-18f;
78                  f -= 1e-18f;                  f -= 1e-18f;
# Line 82  namespace LinuxSampler { Line 99  namespace LinuxSampler {
99                  return y;                  return y;
100              }              }
101    
102                inline bq_t Apply(biquad_param_t* param, const bq_t x) {
103                    bq_t y;
104    
105                    y = param->b0 * x + param->b1 * this->x1 + param->b2 * this->x2 +
106                        param->a1 * this->y1 + param->a2 * this->y2;
107                    KillDenormal(y);
108                    this->x2 = this->x1;
109                    this->x1 = x;
110                    this->y2 = this->y1;
111                    this->y1 = y;
112    
113                    return y;
114                }
115    
116              inline bq_t ApplyFB(bq_t x, const bq_t fb) {              inline bq_t ApplyFB(bq_t x, const bq_t fb) {
117                  bq_t y;                  bq_t y;
118    
# Line 96  namespace LinuxSampler { Line 127  namespace LinuxSampler {
127    
128                  return y;                  return y;
129              }              }
130    
131                inline bq_t ApplyFB(biquad_param_t* param, bq_t x, const bq_t fb) {
132                    bq_t y;
133    
134                    x += this->y1 * fb * 0.98;
135                    y = param->b0 * x + param->b1 * this->x1 + param->b2 * this->x2 +
136                        param->a1 * this->y1 + param->a2 * this->y2;
137                    KillDenormal(y);
138                    this->x2 = this->x1;
139                    this->x1 = x;
140                    this->y2 = this->y1;
141                    this->y1 = y;
142    
143                    return y;
144                }
145      };      };
146    
147      class LowpassFilter : public BiquadFilter {      class LowpassFilter : public BiquadFilter {
# Line 115  namespace LinuxSampler { Line 161  namespace LinuxSampler {
161                  this->a1 = a0r * (2.0 * cs);                  this->a1 = a0r * (2.0 * cs);
162                  this->a2 = a0r * (alpha - 1.0);                  this->a2 = a0r * (alpha - 1.0);
163              }              }
164    
165                inline void SetParameters(biquad_param_t* param, bq_t fc, bq_t bw, bq_t fs) {
166                    bq_t omega = 2.0 * M_PI * fc / fs;
167                    bq_t sn    = sin(omega);
168                    bq_t cs    = cos(omega);
169                    bq_t alpha = sn * sinh(M_LN2 / 2.0 * bw * omega / sn);
170    
171                    const float a0r = 1.0 / (1.0 + alpha);
172                    param->b0 = a0r * (1.0 - cs) * 0.5;
173                    param->b1 = a0r * (1.0 - cs);
174                    param->b2 = a0r * (1.0 - cs) * 0.5;
175                    param->a1 = a0r * (2.0 * cs);
176                    param->a2 = a0r * (alpha - 1.0);
177                }
178      };      };
179    
180      class BandpassFilter : public BiquadFilter {      class BandpassFilter : public BiquadFilter {
# Line 134  namespace LinuxSampler { Line 194  namespace LinuxSampler {
194                  this->a1 = a0r * (2.0 * cs);                  this->a1 = a0r * (2.0 * cs);
195                  this->a2 = a0r * (alpha - 1.0);                  this->a2 = a0r * (alpha - 1.0);
196              }              }
197    
198                inline void SetParameters(biquad_param_t* param, bq_t fc, bq_t bw, bq_t fs) {
199                    bq_t omega = 2.0 * M_PI * fc / fs;
200                    bq_t sn    = sin(omega);
201                    bq_t cs    = cos(omega);
202                    bq_t alpha = sn * sinh(M_LN2 / 2.0 * bw * omega / sn);
203    
204                    const float a0r = 1.0 / (1.0 + alpha);
205                    param->b0 = a0r * alpha;
206                    param->b1 = 0.0;
207                    param->b2 = a0r * -alpha;
208                    param->a1 = a0r * (2.0 * cs);
209                    param->a2 = a0r * (alpha - 1.0);
210                }
211      };      };
212    
213      class HighpassFilter : public BiquadFilter {      class HighpassFilter : public BiquadFilter {
# Line 153  namespace LinuxSampler { Line 227  namespace LinuxSampler {
227                  this->a1 = a0r * (2.0 * cs);                  this->a1 = a0r * (2.0 * cs);
228                  this->a2 = a0r * (alpha - 1.0);                  this->a2 = a0r * (alpha - 1.0);
229              }              }
230    
231                inline void SetParameters(biquad_param_t* param, bq_t fc, bq_t bw, bq_t fs) {
232                    bq_t omega = 2.0 * M_PI * fc / fs;
233                    bq_t sn    = sin(omega);
234                    bq_t cs    = cos(omega);
235                    bq_t alpha = sn * sinh(M_LN2 / 2.0 * bw * omega / sn);
236    
237                    const float a0r = 1.0 / (1.0 + alpha);
238                    param->b0 = a0r * (1.0 + cs) * 0.5;
239                    param->b1 = a0r * -(1.0 + cs);
240                    param->b2 = a0r * (1.0 + cs) * 0.5;
241                    param->a1 = a0r * (2.0 * cs);
242                    param->a2 = a0r * (alpha - 1.0);
243                }
244      };      };
245    
246  } // namespace LinuxSampler  } // namespace LinuxSampler

Legend:
Removed from v.56  
changed lines
  Added in v.80

  ViewVC Help
Powered by ViewVC