1.4.2.13 DSP_FilterIIRBQ16_cascade8 Function
Performs a single-sample IIR Biquad Filter as a cascade of 8 series filters.
Description
int16_t DSP_FilterIIRBQ16_cascade8(int16_t Xin, PARM_EQUAL_FILTER *pFilter_Array);
Calculates a single pass IIR biquad cascade filter on Xin, and delivers the result as a 16-bit output. The cascade of filters is 8 unique biquad filters arranged in series such that the output of one is provided as the input to the next. A unique filter coefficient set is provided to each, and 32 bit delay lines are maintained for each. All math is performed using 32 bit instructions, which results truncated to 16-bits for the output. Global gain values are available on the output. Fracgain is a Q15 fractional gain value and expgain is a binary shift gain value. The combination of the two can be utilized to normalize the output as desired. All values are fractional Q15 and Q31, see data structure for specifics.
Y = Y7 <- Y6 <- Y5 <- Y4 <- Y3 <- Y2 <- Y1 <- Y0 where each Yn filter element represents a unique IIR biquad: Yn = Y(n-1)*b0 + (b1 * Y(n-2)) + (b2 * Y(n-3)) - (a1 * Yn(-1)) - (a2 * Yn(-2)) and: for Y0; Y(n-1) = Xin(0)
Preconditions
Delay register values should be initialized to zero.
Parameters
Xin input data element X (int16_t)
pFilter pointer to filter coef and delay structure
Returns
Sample output Y (int16_t)
Remarks
The delay register values should be initialized to zero prior to the first call to the function, they are updated each pass. A gain of 2 has been hard coded into the function. This implies that all coefs should be input at half value. This is purposeful, since many filter designs need a div2 to have each coef between the required -1
Example
PARM_EQUAL_FILTER filtArray[8]; uint16_t dataY, dataX; _// example to use 2 filter blocks as notch filters_ _// fill entire Filter Array with coefs_ for (i=0;i<8;i++) { filtArray[i].Z[0]=0; filtArray[i].Z[1]=0; _// note all coefs are half value of original design, gain handled in algorithm_ _// all pass_ filtArray[i].b[0]=0x4000; filtArray[i].b[1]=0; _// feed forward b1 coef_ filtArray[i].b[2]=0; _// feed forward b2 coef_ filtArray[i].a[0]=0; _// feedback a1 coef_ filtArray[i].a[1]=0; _// feedback a2 coef_ } _// Unique filters for example_ _// 10KHz notch filter -- divide coefs by 2_ b0 = 0.5883783602332997 b1 = -0.17124071441396285 b2 = 0.5883783602332997 a1 = -0.17124071441396285 a2 = 0.1767567204665992 _// note all coefs are half value of original design, gain handled in algorithm_ filtArray[3].b[0]=0x25a7; _// feed forward b0 coef_ filtArray[3].b[1]=0xf508; _// feed forward b1 coef_ filtArray[3].b[2]=0x25a7; _// feed forward b2 coef_ _// note all coefs are half value of original design, gain handled in algorithm_ _// note subtract is handled in algorithm, so coefs go in at actual value_ filtArray[3].a[0]=0xf508; _// feedback a1 coef_ filtArray[3].a[1]=0x0b4f; _// feedback a2 coef_ _// 1 KHz notch filter -- divide coefs by 2_ b0 = 0.9087554064944908 b1 = -1.7990948352036205 b2 = 0.9087554064944908 a1 = -1.7990948352036205 a2 = 0.8175108129889816 _// note all coefs are half value of original design, gain handled in algorithm_ filtArray[7].b[0]=0x3a29; _// feed forward b0 coef_ filtArray[7].b[1]=0x8cdc; _// feed forward b1 coef_ filtArray[7].b[2]=0x3a29; _// feed forward b2 coef_ _// note all coefs are half value of original design, gain handled in algorithm_ _// note subtract is handled in algorithm, so coefs go in at actual value_ filtArray[7].a[0]=0x8cdc; _// feedback a1 coef_ filtArray[7].a[1]=0x3452; _// feedback a2 coef_ for (i=0;i<256;i++) { _// *** get input data here_ dataX = compound_300_1K_hz16[i]; dataY = DSP_FilterIIRBQ16_cascade8(dataX, filtArray); _// *** do something with the DataY here_ }
C
int16_t DSP_FilterIIRBQ16_cascade8 (int16_t Xin , PARM_EQUAL_FILTER * pFilter_Array );