00001 /* ---------------------------------------------------------------------- 00002 * Copyright (C) 2010 ARM Limited. All rights reserved. 00003 * 00004 * $Date: 15. July 2011 00005 * $Revision: V1.0.10 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/Cortex-M0 00014 * 00015 * Version 1.0.10 2011/7/15 00016 * Big Endian support added and Merged M0 and M3/M4 Source code. 00017 * 00018 * Version 1.0.3 2010/11/29 00019 * Re-organized the CMSIS folders and updated documentation. 00020 * 00021 * Version 1.0.2 2010/11/11 00022 * Documentation updated. 00023 * 00024 * Version 1.0.1 2010/10/05 00025 * Production release and review comments incorporated. 00026 * 00027 * Version 1.0.0 2010/09/20 00028 * Production release and review comments incorporated 00029 * 00030 * Version 0.0.7 2010/06/10 00031 * Misra-C changes done 00032 * -------------------------------------------------------------------- */ 00033 00034 #include "arm_math.h" 00035 00143 void arm_biquad_cascade_df2T_f32( 00144 const arm_biquad_cascade_df2T_instance_f32 * S, 00145 float32_t * pSrc, 00146 float32_t * pDst, 00147 uint32_t blockSize) 00148 { 00149 00150 float32_t *pIn = pSrc; /* source pointer */ 00151 float32_t *pOut = pDst; /* destination pointer */ 00152 float32_t *pState = S->pState; /* State pointer */ 00153 float32_t *pCoeffs = S->pCoeffs; /* coefficient pointer */ 00154 float32_t acc0; /* Simulates the accumulator */ 00155 float32_t b0, b1, b2, a1, a2; /* Filter coefficients */ 00156 float32_t Xn; /* temporary input */ 00157 float32_t d1, d2; /* state variables */ 00158 uint32_t sample, stage = S->numStages; /* loop counters */ 00159 00160 00161 #ifndef ARM_MATH_CM0 00162 00163 /* Run the below code for Cortex-M4 and Cortex-M3 */ 00164 00165 do 00166 { 00167 /* Reading the coefficients */ 00168 b0 = *pCoeffs++; 00169 b1 = *pCoeffs++; 00170 b2 = *pCoeffs++; 00171 a1 = *pCoeffs++; 00172 a2 = *pCoeffs++; 00173 00174 /*Reading the state values */ 00175 d1 = pState[0]; 00176 d2 = pState[1]; 00177 00178 /* Apply loop unrolling and compute 4 output values simultaneously. */ 00179 sample = blockSize >> 2u; 00180 00181 /* First part of the processing with loop unrolling. Compute 4 outputs at a time. 00182 ** a second loop below computes the remaining 1 to 3 samples. */ 00183 while(sample > 0u) 00184 { 00185 /* Read the first input */ 00186 Xn = *pIn++; 00187 00188 /* y[n] = b0 * x[n] + d1 */ 00189 acc0 = (b0 * Xn) + d1; 00190 00191 /* Store the result in the accumulator in the destination buffer. */ 00192 *pOut++ = acc0; 00193 00194 /* Every time after the output is computed state should be updated. */ 00195 /* d1 = b1 * x[n] + a1 * y[n] + d2 */ 00196 d1 = ((b1 * Xn) + (a1 * acc0)) + d2; 00197 00198 /* d2 = b2 * x[n] + a2 * y[n] */ 00199 d2 = (b2 * Xn) + (a2 * acc0); 00200 00201 /* Read the second input */ 00202 Xn = *pIn++; 00203 00204 /* y[n] = b0 * x[n] + d1 */ 00205 acc0 = (b0 * Xn) + d1; 00206 00207 /* Store the result in the accumulator in the destination buffer. */ 00208 *pOut++ = acc0; 00209 00210 /* Every time after the output is computed state should be updated. */ 00211 /* d1 = b1 * x[n] + a1 * y[n] + d2 */ 00212 d1 = ((b1 * Xn) + (a1 * acc0)) + d2; 00213 00214 /* d2 = b2 * x[n] + a2 * y[n] */ 00215 d2 = (b2 * Xn) + (a2 * acc0); 00216 00217 /* Read the third input */ 00218 Xn = *pIn++; 00219 00220 /* y[n] = b0 * x[n] + d1 */ 00221 acc0 = (b0 * Xn) + d1; 00222 00223 /* Store the result in the accumulator in the destination buffer. */ 00224 *pOut++ = acc0; 00225 00226 /* Every time after the output is computed state should be updated. */ 00227 /* d1 = b1 * x[n] + a1 * y[n] + d2 */ 00228 d1 = ((b1 * Xn) + (a1 * acc0)) + d2; 00229 00230 /* d2 = b2 * x[n] + a2 * y[n] */ 00231 d2 = (b2 * Xn) + (a2 * acc0); 00232 00233 /* Read the fourth input */ 00234 Xn = *pIn++; 00235 00236 /* y[n] = b0 * x[n] + d1 */ 00237 acc0 = (b0 * Xn) + d1; 00238 00239 /* Store the result in the accumulator in the destination buffer. */ 00240 *pOut++ = acc0; 00241 00242 /* Every time after the output is computed state should be updated. */ 00243 /* d1 = b1 * x[n] + a1 * y[n] + d2 */ 00244 d1 = (b1 * Xn) + (a1 * acc0) + d2; 00245 00246 /* d2 = b2 * x[n] + a2 * y[n] */ 00247 d2 = (b2 * Xn) + (a2 * acc0); 00248 00249 /* decrement the loop counter */ 00250 sample--; 00251 00252 } 00253 00254 /* If the blockSize is not a multiple of 4, compute any remaining output samples here. 00255 ** No loop unrolling is used. */ 00256 sample = blockSize & 0x3u; 00257 00258 while(sample > 0u) 00259 { 00260 /* Read the input */ 00261 Xn = *pIn++; 00262 00263 /* y[n] = b0 * x[n] + d1 */ 00264 acc0 = (b0 * Xn) + d1; 00265 00266 /* Store the result in the accumulator in the destination buffer. */ 00267 *pOut++ = acc0; 00268 00269 /* Every time after the output is computed state should be updated. */ 00270 /* d1 = b1 * x[n] + a1 * y[n] + d2 */ 00271 d1 = ((b1 * Xn) + (a1 * acc0)) + d2; 00272 00273 /* d2 = b2 * x[n] + a2 * y[n] */ 00274 d2 = (b2 * Xn) + (a2 * acc0); 00275 00276 /* decrement the loop counter */ 00277 sample--; 00278 } 00279 00280 /* Store the updated state variables back into the state array */ 00281 *pState++ = d1; 00282 *pState++ = d2; 00283 00284 /* The current stage input is given as the output to the next stage */ 00285 pIn = pDst; 00286 00287 /*Reset the output working pointer */ 00288 pOut = pDst; 00289 00290 /* decrement the loop counter */ 00291 stage--; 00292 00293 } while(stage > 0u); 00294 00295 #else 00296 00297 /* Run the below code for Cortex-M0 */ 00298 00299 do 00300 { 00301 /* Reading the coefficients */ 00302 b0 = *pCoeffs++; 00303 b1 = *pCoeffs++; 00304 b2 = *pCoeffs++; 00305 a1 = *pCoeffs++; 00306 a2 = *pCoeffs++; 00307 00308 /*Reading the state values */ 00309 d1 = pState[0]; 00310 d2 = pState[1]; 00311 00312 00313 sample = blockSize; 00314 00315 while(sample > 0u) 00316 { 00317 /* Read the input */ 00318 Xn = *pIn++; 00319 00320 /* y[n] = b0 * x[n] + d1 */ 00321 acc0 = (b0 * Xn) + d1; 00322 00323 /* Store the result in the accumulator in the destination buffer. */ 00324 *pOut++ = acc0; 00325 00326 /* Every time after the output is computed state should be updated. */ 00327 /* d1 = b1 * x[n] + a1 * y[n] + d2 */ 00328 d1 = ((b1 * Xn) + (a1 * acc0)) + d2; 00329 00330 /* d2 = b2 * x[n] + a2 * y[n] */ 00331 d2 = (b2 * Xn) + (a2 * acc0); 00332 00333 /* decrement the loop counter */ 00334 sample--; 00335 } 00336 00337 /* Store the updated state variables back into the state array */ 00338 *pState++ = d1; 00339 *pState++ = d2; 00340 00341 /* The current stage input is given as the output to the next stage */ 00342 pIn = pDst; 00343 00344 /*Reset the output working pointer */ 00345 pOut = pDst; 00346 00347 /* decrement the loop counter */ 00348 stage--; 00349 00350 } while(stage > 0u); 00351 00352 #endif /* #ifndef ARM_MATH_CM0 */ 00353 00354 } 00355 00356