/********************************************************************** Audacity: A Digital Audio Editor Biquad.h Norm C Max Maisel ***********************************************************************/ #ifndef __BIQUAD_H__ #define __BIQUAD_H__ #include "MemoryX.h" /// \brief Represents a biquad digital filter. struct Biquad { Biquad(); void Reset(); void Process(float* pfIn, float* pfOut, int iNumSamples); enum { /// Numerator coefficient indices B0=0, B1, B2, /// Denominator coefficient indices A1=0, A2, /// Possible filter orders for the Calc...Filter(...) functions MIN_Order = 1, MAX_Order = 10 }; inline float ProcessOne(float fIn) { // Biquad must use double for all calculations. Otherwise some // filters may have catastrophic rounding errors! double fOut = double(fIn) * fNumerCoeffs[B0] + fPrevIn * fNumerCoeffs[B1] + fPrevPrevIn * fNumerCoeffs[B2] - fPrevOut * fDenomCoeffs[A1] - fPrevPrevOut * fDenomCoeffs[A2]; fPrevPrevIn = fPrevIn; fPrevIn = fIn; fPrevPrevOut = fPrevOut; fPrevOut = fOut; return fOut; } double fNumerCoeffs[3]; // B0 B1 B2 double fDenomCoeffs[2]; // A1 A2, A0 == 1.0 double fPrevIn; double fPrevPrevIn; double fPrevOut; double fPrevPrevOut; enum kSubTypes { kLowPass, kHighPass, nSubTypes }; static ArrayOf CalcButterworthFilter(int order, double fn, double fc, int type); static ArrayOf CalcChebyshevType1Filter(int order, double fn, double fc, double ripple, int type); static ArrayOf CalcChebyshevType2Filter(int order, double fn, double fc, double ripple, int type); static void ComplexDiv (double fNumerR, double fNumerI, double fDenomR, double fDenomI, double* pfQuotientR, double* pfQuotientI); static bool BilinTransform (double fSX, double fSY, double* pfZX, double* pfZY); static float Calc2D_DistSqr (double fX1, double fY1, double fX2, double fY2); static const double s_fChebyCoeffs[MAX_Order][MAX_Order + 1]; static double ChebyPoly(int Order, double NormFreq); }; #endif