00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
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