#include #include #include "biquad_filter.h" /** * Unit_BiquadFilter implements a second order IIR filter. * * Here is the equation that we use for this filter: * y(n) = a0*x(n) + a1*x(n-1) + a2*x(n-2) - b1*y(n-1) - b2*y(n-2) * * @author (C) 2002 Phil Burk, SoftSynth.com, All Rights Reserved */ #define FILTER_PI (3.141592653589793238462643) /*********************************************************** ** Calculate coefficients common to many parametric biquad filters. */ static void BiquadFilter_CalculateCommon( BiquadFilter *filter, double ratio, double Q ) { double omega; memset( filter, 0, sizeof(BiquadFilter) ); /* Don't let frequency get too close to Nyquist or filter will blow up. */ if( ratio >= 0.499 ) ratio = 0.499; omega = 2.0 * (double)FILTER_PI * ratio; filter->cos_omega = (double) cos( omega ); filter->sin_omega = (double) sin( omega ); filter->alpha = filter->sin_omega / (2.0 * Q); } /********************************************************************************* ** Calculate coefficients for Highpass filter. */ void BiquadFilter_SetupHighPass( BiquadFilter *filter, double ratio, double Q ) { double scalar, opc; if( ratio < BIQUAD_MIN_RATIO ) ratio = BIQUAD_MIN_RATIO; if( Q < BIQUAD_MIN_Q ) Q = BIQUAD_MIN_Q; BiquadFilter_CalculateCommon( filter, ratio, Q ); scalar = 1.0 / (1.0 + filter->alpha); opc = (1.0 + filter->cos_omega); filter->a0 = opc * 0.5 * scalar; filter->a1 = - opc * scalar; filter->a2 = filter->a0; filter->b1 = -2.0 * filter->cos_omega * scalar; filter->b2 = (1.0 - filter->alpha) * scalar; } /********************************************************************************* ** Calculate coefficients for Notch filter. */ void BiquadFilter_SetupNotch( BiquadFilter *filter, double ratio, double Q ) { double scalar, opc; if( ratio < BIQUAD_MIN_RATIO ) ratio = BIQUAD_MIN_RATIO; if( Q < BIQUAD_MIN_Q ) Q = BIQUAD_MIN_Q; BiquadFilter_CalculateCommon( filter, ratio, Q ); scalar = 1.0 / (1.0 + filter->alpha); opc = (1.0 + filter->cos_omega); filter->a0 = scalar; filter->a1 = -2.0 * filter->cos_omega * scalar; filter->a2 = filter->a0; filter->b1 = filter->a1; filter->b2 = (1.0 - filter->alpha) * scalar; } /***************************************************************** ** Perform core IIR filter calculation without permutation. */ void BiquadFilter_Filter( BiquadFilter *filter, float *inputs, float *outputs, int numSamples ) { int i; double xn, yn; // Pull values from structure to speed up the calculation. double a0 = filter->a0; double a1 = filter->a1; double a2 = filter->a2; double b1 = filter->b1; double b2 = filter->b2; double xn1 = filter->xn1; double xn2 = filter->xn2; double yn1 = filter->yn1; double yn2 = filter->yn2; for( i=0; ixn1 = xn1; filter->xn2 = xn2; filter->yn1 = yn1; filter->yn2 = yn2; }