00001 #ifndef SYN_BASIC_FILTERS_H
00002 #define SYN_BASIC_FILTERS_H
00003
00023 namespace syn
00024 {
00025
00032 class FirFilter
00033 {
00034 public:
00035 FirFilter()
00036 {
00037 mBuf[0] = 0.0f;
00038 mBuf[1] = 0.0f;
00039 mBuf[2] = 0.0f;
00040 mCoef[0] = 0.0f;
00041 mCoef[1] = 0.0f;
00042 mCoef[2] = 0.0f;
00043 }
00044
00054 void filter( float& sample )
00055 {
00056 float temp;
00057 mBuf[2] = sample;
00058 temp = mCoef[0] * mBuf[2] + mCoef[1] * mBuf[1];
00059 mBuf[0] = mBuf[1];
00060 mBuf[1] = mBuf[2];
00061 sample = temp;
00062 }
00063
00066 int order() const { return 3; }
00067
00070 void invert()
00071 {
00072
00073 mCoef[1] = 1.0f / mCoef[1];
00074
00075 }
00076
00080 void setSimpleLowPass()
00081 {
00082 mCoef[0] = 0.5f;
00083 mCoef[1] = 0.5f;
00084 mCoef[2] = 0.0f;
00085 }
00086
00090 void setSimpleHighPass()
00091 {
00092 mCoef[0] = 0.5f;
00093 mCoef[1] = -0.5f;
00094 mCoef[2] = 0.0f;
00095 }
00096
00100 void setSimpleBandReject()
00101 {
00102 mCoef[0] = 0.5f;
00103 mCoef[1] = 0.0f;
00104 mCoef[2] = 0.5f;
00105 }
00106
00110 void setSimpleBandPass()
00111 {
00112 mCoef[0] = 0.5f;
00113 mCoef[1] = 0.0f;
00114 mCoef[2] = -0.5f;
00115 }
00116
00122 void setCutoff( float fc, float sampRate )
00123 {
00124 const int N = this->order();
00125
00126 for (int k = 0; k < N; ++k)
00127 {
00128 float k_minus_n_over_2 = k - (N / 2.0f);
00129 float junk = 2.0f * Math::PI * k_minus_n_over_2;
00130 float top = Math::sin( junk * (fc / sampRate) );
00131 float bottom = Math::PI * k_minus_n_over_2;
00132 float left = top / bottom;
00133 float right = 0.54f + 0.46f * Math::cos( junk / N );
00134 mCoef[k] = left * right;
00135
00136 }
00137 }
00138
00139 private:
00140 float mCoef[3];
00141 float mBuf[3];
00142 };
00143
00144 class SimpleLowPass
00145 {
00146 public:
00147 SimpleLowPass() : mCutoff( 1.0f ), last( 0 )
00148 {
00149 this->setCutoff( mCutoff, 44100.0f );
00150 }
00151
00152 void setCutoff( float cutoff, float sampRate )
00153 {
00154 mCutoff = cutoff / sampRate;
00155 if (mCutoff < 0.0f) mCutoff = 0.0f;
00156 if (mCutoff > 1.0f) mCutoff = 1.0f;
00157
00158 a = 1.0f / ( 1.0f + 0.2756644477f / mCutoff );
00159 b = 1.0f - a;
00160 }
00161
00162 inline void filter( float& data )
00163 {
00164 data = last = a*data + b*last;
00165 }
00166
00167 float mCutoff, last;
00168 float a, b;
00169 };
00170
00171 class SimpleHighPass
00172 {
00173 public:
00174 SimpleHighPass() : mCutoff( 1.0f ), lastin( 0 ), lastout( 0 )
00175 {
00176 this->setCutoff( mCutoff, 44100.0f );
00177 }
00178
00179 void setCutoff( float cutoff, float sampRate )
00180 {
00181 mCutoff = cutoff / sampRate;
00182 if (mCutoff < 0.0f) mCutoff = 0.0f;
00183 if (mCutoff > 1.0f) mCutoff = 1.0f;
00184
00185 a = 1.0f / ( 1.0f + 10.8827961853f * mCutoff );
00186 }
00187
00188 inline void filter( float& data )
00189 {
00190 lastout = a*lastout + data - lastin;
00191 lastin = data;
00192 data = lastout;
00193 }
00194
00195 float mCutoff, lastin, lastout;
00196 float a;
00197 };
00198
00199 class SimpleLP
00200 {
00201 public:
00202 SimpleLP() : mCutoff( 44100.0f ), lastin( 0 ), lastout( 0 )
00203 {
00204 this->setCutoff( mCutoff, 44100.0f );
00205 }
00206
00207 void setCutoff( float cutoff, float sampRate )
00208 {
00209 mCutoff = cutoff / sampRate;
00210 if (mCutoff < 0.0f) mCutoff = 0.0f;
00211 if (mCutoff > 1.0f) mCutoff = 1.0f;
00212
00213 float omega = Math::aTan( Math::PI * mCutoff );
00214 a = -(1.0f - omega) / (1.0f + omega);
00215 b = (1.0f - b) / 2.0f;
00216 }
00217
00218 void filter( float& data )
00219 {
00220
00221 lastout = b * (data + lastin) - a * lastout;
00222 lastin = data;
00223 data = lastout;
00224 }
00225
00226 private:
00227 float mCutoff;
00228 float a, b;
00229 float lastin, lastout;
00230 };
00231
00236 class RbjFilter
00237 {
00238 public:
00239 RbjFilter()
00240 {
00241 }
00242
00252 void filter( float& sample )
00253 {
00254
00255 float temp;
00256 temp = (b0/a0)*sample + (b1/a0)*x[1] + (b2/a0)*x[0]
00257 - (a1/a0)*y[1] - (a2/a0)*y[0];
00258
00259
00260 x[0] = x[1];
00261 x[1] = sample;
00262 y[0] = y[1];
00263 y[1] = temp;
00264
00265
00266 sample = temp;
00267 }
00268
00269
00270 float A;
00271 float omega;
00272 float sn;
00273 float cs;
00274 float alpha;
00275 float beta;
00276 void setup( float frequency, float sampRate, float dBgain = 20.0f, float Q = 1.0f )
00277 {
00278 A = Math::sqrt( pow( 10.0f, (dBgain/20.0f) ) );
00279
00280 omega = 2.0f * Math::PI * frequency / sampRate;
00281 sn = Math::sin( omega );
00282 cs = Math::cos( omega );
00283 alpha = sn / (2.0f * Q);
00284
00285
00286 }
00287
00288
00293 void setCutoff( float frequency, float sampRate )
00294 {
00295 setup( frequency, sampRate );
00296
00297
00298
00299 a0 = 1.0f + alpha;
00300 a1 = -2.0f * cs;
00301 a2 = 1.0f - alpha;
00302 b0 = (1.0f - cs) / 2.0f;
00303 b1 = 1.0f - cs;
00304 b2 = (1.0f - cs) / 2.0f;
00305 }
00306
00307 private:
00308 float mCoef[3];
00309 float x[3];
00310 float y[3];
00311 float Hs;
00312 float a0, a1, a2;
00313 float b0, b1, b2;
00314 };
00315
00316 }
00317
00318 #endif