blob: 0ffb29ee7411595cddc513bd2f89fdb720068a0e [file] [log] [blame]
*     y[n] = b0 * x[n] + b1 * x[n-1] + b2 * x[n-2] + a1 * y[n-1] + a2 * y[n-2]
*
* A Direct Form I algorithm is used with 5 coefficients and 4 state variables per stage. * \image html Biquad.gif "Single Biquad filter stage" * Coefficients b0, b1 and b2 multiply the input signal x[n] and are referred to as the feedforward coefficients. * Coefficients a1 and a2 multiply the output signal y[n] and are referred to as the feedback coefficients. * Pay careful attention to the sign of the feedback coefficients. * Some design tools use the difference equation *
*     y[n] = b0 * x[n] + b1 * x[n-1] + b2 * x[n-2] - a1 * y[n-1] - a2 * y[n-2]
*
* In this case the feedback coefficients a1 and a2 must be negated when used with the CMSIS DSP Library. * * \par * Higher order filters are realized as a cascade of second order sections. * numStages refers to the number of second order stages used. * For example, an 8th order filter would be realized with numStages=4 second order stages. * \image html BiquadCascade.gif "8th order filter using a cascade of Biquad stages" * A 9th order filter would be realized with numStages=5 second order stages with the coefficients for one of the stages configured as a first order filter (b2=0 and a2=0). * * \par * The pState points to state variables array. * Each Biquad stage has 4 state variables x[n-1], x[n-2], y[n-1], and y[n-2]. * The state variables are arranged in the pState array as: *
*     {x[n-1], x[n-2], y[n-1], y[n-2]}
*
* * \par * The 4 state variables for stage 1 are first, then the 4 state variables for stage 2, and so on. * The state array has a total length of 4*numStages values. * The state variables are updated after each block of data is processed, the coefficients are untouched. * * \par Instance Structure * The coefficients and state variables for a filter are stored together in an instance data structure. * A separate instance structure must be defined for each filter. * Coefficient arrays may be shared among several instances while state variable arrays cannot be shared. * There are separate instance structure declarations for each of the 3 supported data types. * * \par Init Functions * There is also an associated initialization function for each data type. * The initialization function performs following operations: * - Sets the values of the internal structure fields. * - Zeros out the values in the state buffer. * To do this manually without calling the init function, assign the follow subfields of the instance structure: * numStages, pCoeffs, pState. Also set all of the values in pState to zero. * * \par * Use of the initialization function is optional. * However, if the initialization function is used, then the instance structure cannot be placed into a const data section. * To place an instance structure into a const data section, the instance structure must be manually initialized. * Set the values in the state buffer to zeros before static initialization. * The code below statically initializes each of the 3 different data type filter instance structures *
*     arm_biquad_casd_df1_inst_f32 S1 = {numStages, pState, pCoeffs};
*     arm_biquad_casd_df1_inst_q15 S2 = {numStages, pState, pCoeffs, postShift};
*     arm_biquad_casd_df1_inst_q31 S3 = {numStages, pState, pCoeffs, postShift};
*
* where numStages is the number of Biquad stages in the filter; pState is the address of the state buffer; * pCoeffs is the address of the coefficient buffer; postShift shift to be applied. * * \par Fixed-Point Behavior * Care must be taken when using the Q15 and Q31 versions of the Biquad Cascade filter functions. * Following issues must be considered: * - Scaling of coefficients * - Filter gain * - Overflow and saturation * * \par * Scaling of coefficients: * Filter coefficients are represented as fractional values and * coefficients are restricted to lie in the range [-1 +1). * The fixed-point functions have an additional scaling parameter postShift * which allow the filter coefficients to exceed the range [+1 -1). * At the output of the filter's accumulator is a shift register which shifts the result by postShift bits. * \image html BiquadPostshift.gif "Fixed-point Biquad with shift by postShift bits after accumulator" * This essentially scales the filter coefficients by 2^postShift. * For example, to realize the coefficients *
*    {1.5, -0.8, 1.2, 1.6, -0.9}
*
* set the pCoeffs array to: *
*    {0.75, -0.4, 0.6, 0.8, -0.45}
*