Main Page   Class Hierarchy   Compound List   File List   Compound Members   File Members   Examples  

mj_filter_iir2.h

00001 /* COPYRIGHT
00002  *
00003  * This file is part of Mustajuuri LGPL modules.
00004  *
00005  * Author: Tommi Ilmonen, 1999-2001.
00006  * Tommi.Ilmonen@hut.fi
00007  *
00008  * http://www.tml.hut.fi/~tilmonen/mustajuuri/
00009  *
00010  *
00011  * This file is licensed under the Lesser GNU Public License
00012  * (LGPL). Extra clauses can be found from the file MUSTAJUURI_LGPL and
00013  * further explanations from the file MUSTAJUURI_LICENSE. The license
00014  * text can be found in file "LGPL.txt".
00015  *
00016  * If you want a parallel license (for commercial reasons for example),
00017  * you should negotiate the matter with the author(s).
00018  *    
00019  */
00020 
00021 #ifndef MJ_FILTER_IIR2_H
00022 #define MJ_FILTER_IIR2_H
00023 
00024 #include <mj_math.h>
00025 #include <complex.h>
00026 
00037 template <class TElem> class MJ_FilterIIR2
00038 {
00039 public:
00042   MJ_FilterIIR2() {}
00043 
00045   ~MJ_FilterIIR2() {}
00046 
00049 
00052   inline void putSample(TElem s)
00053   {
00054     m_m2 = m_m1;
00055     m_m1 = m_m0;
00056     m_m0 = s - m_a1 * m_m1 - m_a2 * m_m2;
00057   }
00058 
00059   inline void put(TElem s) { putSample(s); }
00060 
00063   inline TElem getSample() const
00064   {
00065     return m_b0 * m_m0 + m_b1 * m_m1 +  m_b2 * m_m2;
00066   }
00067 
00068   inline TElem get() const { return getSample() ; }
00069 
00071   inline TElem putGetSample(TElem s)
00072   {
00073     m_m2 = m_m1;
00074     m_m1 = m_m0;
00075     m_m0 = s - m_a1 * m_m1 - m_a2 * m_m2;
00076     return m_b0 * m_m0 + m_b1 * m_m1 +  m_b2 * m_m2;
00077   }
00078 
00082   inline TElem putGetSampleOther(MJ_FilterIIR2 *f, TElem s)
00083   {
00084     f->m_m2 = f->m_m1;
00085     f->m_m1 = f->m_m0;
00086     f->m_m0 = s - m_a1 * f->m_m1 - m_a2 * f->m_m2;
00087     return m_b0 * f->m_m0 + m_b1 * f->m_m1 +  m_b2 * f->m_m2;
00088   }
00089 
00090   void putSamples(const TElem *input, unsigned count);
00091 
00092   void putSamples(TElem * output, 
00093                   const TElem * input, 
00094                   unsigned count);
00095 
00096   void putGetSamplesInplace(TElem *inputOutput, unsigned count);
00097 
00099   inline void resetMemory()
00100   { m_m0 = 0.0; m_m1 = 0.0; m_m2 = 0.0; }
00101 
00103 
00106 
00108   inline void flatResponse()
00109   {
00110     m_b0 = 1.0;
00111     m_b1 = 0.0;
00112     m_b2 = 0.0;
00113     m_a1 = 0.0;
00114     m_a2 = 0.0;    
00115   }
00116 
00118   inline void designHighShelve1(TElem centerRad, 
00119                                 TElem gainDb, 
00120                                 TElem slope = 1.0)
00121   { 
00122     iir2HighShelveEq
00123       (centerRad, gainDb, slope, bptr(), aptr());
00124   }
00125 
00127   inline void designHighShelve2(TElem frequencyHz, 
00128                                 TElem sampleRate,
00129                                 TElem gainDb, 
00130                                 TElem slope = 1.0)
00131   { 
00132     designHighShelve1(MJ_2pi * frequencyHz / sampleRate, gainDb, slope);
00133   }
00134 
00136   inline void designLowShelve1(TElem centerRad, 
00137                                TElem gainDb, 
00138                                TElem slope = 1.0)
00139   { 
00140     iir2LowShelveEq
00141       (centerRad, gainDb, slope, bptr(), aptr());
00142   }
00143 
00145   inline void designLowShelve2(TElem frequencyHz, 
00146                                TElem sampleRate,
00147                                TElem gainDb, 
00148                                TElem slope = 1.0)
00149   { 
00150     designLowShelve1(MJ_2pi *frequencyHz / sampleRate, gainDb, slope);
00151   }
00152 
00157   void designParametric1(TElem boostAbs, 
00158                          TElem centerRad,
00159                          TElem bandWidthRad);
00160 
00161   void designParametric2(TElem boostDb, 
00162                          TElem centerHz,
00163                          TElem bandWidthOctaves,
00164                          TElem samplingRate);
00165 
00168   void designParametricB1(TElem K,
00169                           TElem F,
00170                           TElem omega, 
00171                           TElem bw)
00172   { iir2ParametricEqB(K, F, omega, bw, bptr(), aptr()); }
00173 
00174   void designParametricB2(
00176                           TElem hz, 
00178                           TElem sr,
00180                           TElem gainDb,
00182                           TElem bw)
00183   { 
00184     if(MJ_abs(gainDb) < 0.005 || hz == 0.0 || bw == 0.0) flatResponse();
00185     else designParametricB1(MJ_pow(10.0, gainDb * 0.05), 
00186                             MJ_pow(10.0, gainDb * 0.025), 
00187                             hz / sr * MJ_2pi, bw); 
00188   }
00189   
00201   void designParametricC1(
00203                           TElem K,
00205                           TElem F,
00207                           TElem omega, 
00209                           TElem bw)
00210   { iir2ParametricEqC(K, F, omega, bw, bptr(), aptr()); }
00211 
00216   void designParametricC2(
00218                           TElem hz, 
00220                           TElem sr,
00222                           TElem gainDb,
00224                           TElem bw)
00225   { 
00226     if(MJ_abs(gainDb) < 0.005) flatResponse();
00227     else designParametricC1(MJ_pow(10.0, gainDb * 0.05), 
00228                             MJ_pow(10.0, gainDb * 0.025), 
00229                             hz / sr * MJ_2pi, bw); 
00230   }
00231 
00233   void designLowPass1(TElem omega,
00234                       TElem Q)
00235   {
00236     iir2LowPassEq(omega, Q, &m_b0, &m_a1);
00237   }
00238 
00240   void designLowPass2(
00242                       TElem hz, 
00244                       TElem sr,
00245                       TElem Q)
00246   {
00247     designLowPass1(hz / sr * MJ_2pi, Q);
00248   }
00249 
00251   void designHighPass1(TElem omega,
00252                       TElem Q)
00253   {
00254     iir2HighPassEq(omega, Q, &m_b0, &m_a1);
00255   }
00256 
00258   void designHighPass2(
00260                       TElem hz, 
00262                       TElem sr,
00263                       TElem Q)
00264   {
00265     designHighPass1(hz / sr * MJ_2pi, Q);
00266   }
00267 
00269   void designBandPass1(
00271                        TElem omega, 
00273                        TElem Q)
00274     { iir2BandPassEq(omega, Q, bptr(), aptr()); }
00275 
00277   void designBandPass2(
00279                        TElem hz, 
00281                        TElem sr,
00283                        TElem Q)
00284     { designBandPass1(hz / sr * MJ_2pi, Q); }
00285 
00287   void designBandPassB1(
00289                        TElem omega, 
00291                        TElem bw)
00292     { iir2BandPassEqB(omega, bw, bptr(), aptr()); }
00293 
00295   void designBandPassB2(
00297                         TElem hz, 
00299                         TElem sr,
00301                         TElem bw)
00302     { designBandPassB1(hz / sr * MJ_2pi, bw); }
00303 
00305   inline void copyCoefficients(const MJ_FilterIIR2 &iir)
00306   {
00307     m_b0 = iir.m_b0;
00308     m_b1 = iir.m_b1;
00309     m_b2 = iir.m_b2;
00310 
00311     m_a1 = iir.m_a1;
00312     m_a2 = iir.m_a2;
00313   }
00314 
00316   void mulGain(TElem scale)
00317   { m_b0 *= scale; m_b1 *= scale; m_b2 *= scale; }
00318 
00320 
00323 
00325   inline TElem b0() const { return m_b0; }
00327   inline TElem b1() const { return m_b1; }
00329   inline TElem b2() const { return m_b2; }
00330 
00332   inline TElem *bptr() { return & m_b0; }
00333 
00335   inline TElem a1() const { return m_a1; }
00337   inline TElem a2() const { return m_a2; }
00338 
00340   inline TElem *aptr() { return & m_a1; }
00342 
00343   void writeTo(char *);
00344 
00349 
00350   static void iir2ParametricEq
00351     (TElem gr, TElem ga, TElem gb, TElem w0, TElem dw,
00352      TElem *b, TElem *a);
00353   
00354   static void iir2ParametricEqB
00355     (TElem K, TElem F, TElem omega, TElem bw, 
00356      TElem *b, TElem *a);
00357   
00358   static void iir2ParametricEqC
00359     (TElem K, TElem F, TElem omega, TElem bw, 
00360      TElem *b, TElem *a);
00361   
00362   static void iir2HighShelveEq
00363     (TElem rate, TElem gainDb, TElem slope,
00364      TElem *b, TElem *a);
00365 
00366   static void iir2LowShelveEq
00367     (TElem rate, TElem gainDb, TElem slope,
00368      TElem *b, TElem *a);
00369 
00370   static void iir2LowPassEq (TElem omega, TElem Q,
00371                              TElem *b, TElem *a);
00372   
00373   static void iir2HighPassEq (TElem omega, TElem Q,
00374                               TElem *b, TElem *a);
00375 
00376   static void iir2BandPassEq(TElem omega, TElem Q,
00377                              TElem *b, TElem *a);
00378 
00379   static void iir2BandPassEqB(TElem omega, TElem bw,
00380                               TElem *b, TElem *a);
00381 
00383 
00386   complex<float> response(complex<float> omega){
00387     return
00388       (m_b0 + m_b1 * omega + m_b2 * omega * omega)
00389       / (1 + m_a1 * omega + m_a2 * omega * omega);
00390   }
00391 
00392 protected:
00393   TElem m_b0, m_b1, m_b2;
00394   TElem m_a1, m_a2;
00395   TElem m_m0, m_m1, m_m2;
00396 };
00397 
00398 #endif

Generated at Sun Jan 18 20:51:22 2004 for Jezabel by doxygen1.2.8.1 written by Dimitri van Heesch, © 1997-2001