Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of dsp by
arm_biquad_cascade_df2T_f32.c
00001 /* ---------------------------------------------------------------------- 00002 * Copyright (C) 2010 ARM Limited. All rights reserved. 00003 * 00004 * $Date: 29. November 2010 00005 * $Revision: V1.0.3 00006 * 00007 * Project: CMSIS DSP Library 00008 * Title: arm_biquad_cascade_df2T_f32.c 00009 * 00010 * Description: Processing function for the floating-point transposed 00011 * direct form II Biquad cascade filter. 00012 * 00013 * Target Processor: Cortex-M4/Cortex-M3 00014 * 00015 * Version 1.0.3 2010/11/29 00016 * Re-organized the CMSIS folders and updated documentation. 00017 * 00018 * Version 1.0.2 2010/11/11 00019 * Documentation updated. 00020 * 00021 * Version 1.0.1 2010/10/05 00022 * Production release and review comments incorporated. 00023 * 00024 * Version 1.0.0 2010/09/20 00025 * Production release and review comments incorporated 00026 * 00027 * Version 0.0.7 2010/06/10 00028 * Misra-C changes done 00029 * -------------------------------------------------------------------- */ 00030 00031 #include "arm_math.h" 00032 00033 /** 00034 * @ingroup groupFilters 00035 */ 00036 00037 /** 00038 * @defgroup BiquadCascadeDF2T Biquad Cascade IIR Filters Using a Direct Form II Transposed Structure 00039 * 00040 * This set of functions implements arbitrary order recursive (IIR) filters using a transposed direct form II structure. 00041 * The filters are implemented as a cascade of second order Biquad sections. 00042 * These functions provide a slight memory savings as compared to the direct form I Biquad filter functions. 00043 * Only floating-point data is supported. 00044 * 00045 * This function operate on blocks of input and output data and each call to the function 00046 * processes <code>blockSize</code> samples through the filter. 00047 * <code>pSrc</code> points to the array of input data and 00048 * <code>pDst</code> points to the array of output data. 00049 * Both arrays contain <code>blockSize</code> values. 00050 * 00051 * \par Algorithm 00052 * Each Biquad stage implements a second order filter using the difference equation: 00053 * <pre> 00054 * y[n] = b0 * x[n] + d1 00055 * d1 = b1 * x[n] + a1 * y[n] + d2 00056 * d2 = b2 * x[n] + a2 * y[n] 00057 * </pre> 00058 * where d1 and d2 represent the two state values. 00059 * 00060 * \par 00061 * A Biquad filter using a transposed Direct Form II structure is shown below. 00062 * \image html BiquadDF2Transposed.gif "Single transposed Direct Form II Biquad" 00063 * Coefficients <code>b0, b1, and b2 </code> multiply the input signal <code>x[n]</code> and are referred to as the feedforward coefficients. 00064 * Coefficients <code>a1</code> and <code>a2</code> multiply the output signal <code>y[n]</code> and are referred to as the feedback coefficients. 00065 * Pay careful attention to the sign of the feedback coefficients. 00066 * Some design tools flip the sign of the feedback coefficients: 00067 * <pre> 00068 * y[n] = b0 * x[n] + d1; 00069 * d1 = b1 * x[n] - a1 * y[n] + d2; 00070 * d2 = b2 * x[n] - a2 * y[n]; 00071 * </pre> 00072 * In this case the feedback coefficients <code>a1</code> and <code>a2</code> must be negated when used with the CMSIS DSP Library. 00073 * 00074 * \par 00075 * Higher order filters are realized as a cascade of second order sections. 00076 * <code>numStages</code> refers to the number of second order stages used. 00077 * For example, an 8th order filter would be realized with <code>numStages=4</code> second order stages. 00078 * A 9th order filter would be realized with <code>numStages=5</code> second order stages with the 00079 * coefficients for one of the stages configured as a first order filter (<code>b2=0</code> and <code>a2=0</code>). 00080 * 00081 * \par 00082 * <code>pState</code> points to the state variable array. 00083 * Each Biquad stage has 2 state variables <code>d1</code> and <code>d2</code>. 00084 * The state variables are arranged in the <code>pState</code> array as: 00085 * <pre> 00086 * {d11, d12, d21, d22, ...} 00087 * </pre> 00088 * where <code>d1x</code> refers to the state variables for the first Biquad and 00089 * <code>d2x</code> refers to the state variables for the second Biquad. 00090 * The state array has a total length of <code>2*numStages</code> values. 00091 * The state variables are updated after each block of data is processed; the coefficients are untouched. 00092 * 00093 * \par 00094 * The CMSIS library contains Biquad filters in both Direct Form I and transposed Direct Form II. 00095 * The advantage of the Direct Form I structure is that it is numerically more robust for fixed-point data types. 00096 * That is why the Direct Form I structure supports Q15 and Q31 data types. 00097 * The transposed Direct Form II structure, on the other hand, requires a wide dynamic range for the state variables <code>d1</code> and <code>d2</code>. 00098 * Because of this, the CMSIS library only has a floating-point version of the Direct Form II Biquad. 00099 * The advantage of the Direct Form II Biquad is that it requires half the number of state variables, 2 rather than 4, per Biquad stage. 00100 * 00101 * \par Instance Structure 00102 * The coefficients and state variables for a filter are stored together in an instance data structure. 00103 * A separate instance structure must be defined for each filter. 00104 * Coefficient arrays may be shared among several instances while state variable arrays cannot be shared. 00105 * 00106 * \par Init Functions 00107 * There is also an associated initialization function. 00108 * The initialization function performs following operations: 00109 * - Sets the values of the internal structure fields. 00110 * - Zeros out the values in the state buffer. 00111 * 00112 * \par 00113 * Use of the initialization function is optional. 00114 * However, if the initialization function is used, then the instance structure cannot be placed into a const data section. 00115 * To place an instance structure into a const data section, the instance structure must be manually initialized. 00116 * Set the values in the state buffer to zeros before static initialization. 00117 * For example, to statically initialize the instance structure use 00118 * <pre> 00119 * arm_biquad_cascade_df2T_instance_f32 S1 = {numStages, pState, pCoeffs}; 00120 * </pre> 00121 * where <code>numStages</code> is the number of Biquad stages in the filter; <code>pState</code> is the address of the state buffer. 00122 * <code>pCoeffs</code> is the address of the coefficient buffer; 00123 * 00124 */ 00125 00126 /** 00127 * @addtogroup BiquadCascadeDF2T 00128 * @{ 00129 */ 00130 00131 /** 00132 * @brief Processing function for the floating-point transposed direct form II Biquad cascade filter. 00133 * @param[in] *S points to an instance of the filter data structure. 00134 * @param[in] *pSrc points to the block of input data. 00135 * @param[out] *pDst points to the block of output data 00136 * @param[in] blockSize number of samples to process. 00137 * @return none. 00138 */ 00139 00140 void arm_biquad_cascade_df2T_f32( 00141 const arm_biquad_cascade_df2T_instance_f32 * S, 00142 float32_t * pSrc, 00143 float32_t * pDst, 00144 uint32_t blockSize) 00145 { 00146 00147 float32_t *pIn = pSrc; /* source pointer */ 00148 float32_t *pOut = pDst; /* destination pointer */ 00149 float32_t *pState = S->pState; /* State pointer */ 00150 float32_t *pCoeffs = S->pCoeffs; /* coefficient pointer */ 00151 float32_t acc0; /* Simulates the accumulator */ 00152 float32_t b0, b1, b2, a1, a2; /* Filter coefficients */ 00153 float32_t Xn; /* temporary input */ 00154 float32_t d1, d2; /* state variables */ 00155 uint32_t sample, stage = S->numStages; /* loop counters */ 00156 00157 00158 do 00159 { 00160 /* Reading the coefficients */ 00161 b0 = *pCoeffs++; 00162 b1 = *pCoeffs++; 00163 b2 = *pCoeffs++; 00164 a1 = *pCoeffs++; 00165 a2 = *pCoeffs++; 00166 00167 /*Reading the state values */ 00168 d1 = pState[0]; 00169 d2 = pState[1]; 00170 00171 /* Apply loop unrolling and compute 4 output values simultaneously. */ 00172 sample = blockSize >> 2u; 00173 00174 /* First part of the processing with loop unrolling. Compute 4 outputs at a time. 00175 ** a second loop below computes the remaining 1 to 3 samples. */ 00176 while(sample > 0u) 00177 { 00178 /* Read the first input */ 00179 Xn = *pIn++; 00180 00181 /* y[n] = b0 * x[n] + d1 */ 00182 acc0 = (b0 * Xn) + d1; 00183 00184 /* Store the result in the accumulator in the destination buffer. */ 00185 *pOut++ = acc0; 00186 00187 /* Every time after the output is computed state should be updated. */ 00188 /* d1 = b1 * x[n] + a1 * y[n] + d2 */ 00189 d1 = ((b1 * Xn) + (a1 * acc0)) + d2; 00190 00191 /* d2 = b2 * x[n] + a2 * y[n] */ 00192 d2 = (b2 * Xn) + (a2 * acc0); 00193 00194 /* Read the second input */ 00195 Xn = *pIn++; 00196 00197 /* y[n] = b0 * x[n] + d1 */ 00198 acc0 = (b0 * Xn) + d1; 00199 00200 /* Store the result in the accumulator in the destination buffer. */ 00201 *pOut++ = acc0; 00202 00203 /* Every time after the output is computed state should be updated. */ 00204 /* d1 = b1 * x[n] + a1 * y[n] + d2 */ 00205 d1 = ((b1 * Xn) + (a1 * acc0)) + d2; 00206 00207 /* d2 = b2 * x[n] + a2 * y[n] */ 00208 d2 = (b2 * Xn) + (a2 * acc0); 00209 00210 /* Read the third input */ 00211 Xn = *pIn++; 00212 00213 /* y[n] = b0 * x[n] + d1 */ 00214 acc0 = (b0 * Xn) + d1; 00215 00216 /* Store the result in the accumulator in the destination buffer. */ 00217 *pOut++ = acc0; 00218 00219 /* Every time after the output is computed state should be updated. */ 00220 /* d1 = b1 * x[n] + a1 * y[n] + d2 */ 00221 d1 = ((b1 * Xn) + (a1 * acc0)) + d2; 00222 00223 /* d2 = b2 * x[n] + a2 * y[n] */ 00224 d2 = (b2 * Xn) + (a2 * acc0); 00225 00226 /* Read the fourth input */ 00227 Xn = *pIn++; 00228 00229 /* y[n] = b0 * x[n] + d1 */ 00230 acc0 = (b0 * Xn) + d1; 00231 00232 /* Store the result in the accumulator in the destination buffer. */ 00233 *pOut++ = acc0; 00234 00235 /* Every time after the output is computed state should be updated. */ 00236 /* d1 = b1 * x[n] + a1 * y[n] + d2 */ 00237 d1 = (b1 * Xn) + (a1 * acc0) + d2; 00238 00239 /* d2 = b2 * x[n] + a2 * y[n] */ 00240 d2 = (b2 * Xn) + (a2 * acc0); 00241 00242 /* decrement the loop counter */ 00243 sample--; 00244 00245 } 00246 00247 /* If the blockSize is not a multiple of 4, compute any remaining output samples here. 00248 ** No loop unrolling is used. */ 00249 sample = blockSize & 0x3u; 00250 00251 while(sample > 0u) 00252 { 00253 /* Read the input */ 00254 Xn = *pIn++; 00255 00256 /* y[n] = b0 * x[n] + d1 */ 00257 acc0 = (b0 * Xn) + d1; 00258 00259 /* Store the result in the accumulator in the destination buffer. */ 00260 *pOut++ = acc0; 00261 00262 /* Every time after the output is computed state should be updated. */ 00263 /* d1 = b1 * x[n] + a1 * y[n] + d2 */ 00264 d1 = ((b1 * Xn) + (a1 * acc0)) + d2; 00265 00266 /* d2 = b2 * x[n] + a2 * y[n] */ 00267 d2 = (b2 * Xn) + (a2 * acc0); 00268 00269 /* decrement the loop counter */ 00270 sample--; 00271 } 00272 00273 /* Store the updated state variables back into the state array */ 00274 *pState++ = d1; 00275 *pState++ = d2; 00276 00277 /* The current stage input is given as the output to the next stage */ 00278 pIn = pDst; 00279 00280 /*Reset the output working pointer */ 00281 pOut = pDst; 00282 00283 /* decrement the loop counter */ 00284 stage--; 00285 00286 } while(stage > 0u); 00287 00288 00289 } 00290 00291 00292 /** 00293 * @} end of BiquadCascadeDF2T group 00294 */
Generated on Tue Jul 12 2022 19:55:42 by
1.7.2
