Main Page   Modules   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages  

/root/src/subsynth/syn/Util/Filter.h

Go to the documentation of this file.
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];// + mCoef[2] * mBuf[0];
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       // invert all even coefs...
00073       mCoef[1] = 1.0f / mCoef[1];
00074       //mCoef[1] = -mCoef[1];
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          //std::cout<<"coef::"<<mCoef[k]<<std::endl;
00136       }
00137    }
00138 
00139 private:
00140    float mCoef[3]; // order 3 filter...
00141    float mBuf[3];  // keep a history of 3 samples...
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       // dest[0] = b * (src[0] + src[-1]) - a * dest[-1]
00221       lastout = b * (data + lastin) - a * lastout;
00222       lastin = data;
00223       data = lastout;
00224    }
00225 
00226 private:
00227    float mCutoff;
00228    float a, b;   // coefs
00229    float lastin, lastout; // sample history (data, lastin unfiltered, lastout filtered)
00230 };
00231 
00236 class RbjFilter
00237 {
00238 public:
00239    RbjFilter()
00240    {
00241    }
00242 
00252    void filter( float& sample )
00253    {
00254       // sample is current, 
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       // keep a history...
00259       // oldest < 0, 1, sample|temp < newest
00260       x[0] = x[1];
00261       x[1] = sample;
00262       y[0] = y[1];
00263       y[1] = temp;
00264       
00265       // return the result...
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       //            = 10^(dBgain/40)    // (for for peaking and shelving EQ filters only)
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       //            = sn*sinh[ ln(2)/2 * bandwidth * omega/sn ]     // (if bandwidth is specified instead of Q)
00285       //beta  = Math::sqrt[ (A^2 + 1)/S - (A-1)^2 ]   // (for shelving EQ filters only)
00286    }
00287       
00288          
00293    void setCutoff( float frequency, float sampRate )
00294    {
00295       setup( frequency, sampRate );
00296 
00297       //float s = (1.0f / Math::tan( omega / 2.0f )) * ((1.0f - 1.0f/z) / (1.0f + 1.0f/z));
00298       //Hs =   1.0f / (s * s + s / Q + 1.0f);
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 } // end namespace syn
00317 
00318 #endif

Generated at Mon Apr 15 09:26:08 2002 for subsynth by doxygen1.2.8.1 written by Dimitri van Heesch, © 1997-2001