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_fir_decimate_f32.c 00009 * 00010 * Description: FIR decimation for floating-point sequences. 00011 * 00012 * Target Processor: Cortex-M4/Cortex-M3/Cortex-M0 00013 * 00014 * Version 1.0.10 2011/7/15 00015 * Big Endian support added and Merged M0 and M3/M4 Source code. 00016 * 00017 * Version 1.0.3 2010/11/29 00018 * Re-organized the CMSIS folders and updated documentation. 00019 * 00020 * Version 1.0.2 2010/11/11 00021 * Documentation updated. 00022 * 00023 * Version 1.0.1 2010/10/05 00024 * Production release and review comments incorporated. 00025 * 00026 * Version 1.0.0 2010/09/20 00027 * Production release and review comments incorporated 00028 * 00029 * Version 0.0.7 2010/06/10 00030 * Misra-C changes done 00031 * 00032 * -------------------------------------------------------------------- */ 00033 00034 #include "arm_math.h" 00035 00132 void arm_fir_decimate_f32( 00133 const arm_fir_decimate_instance_f32 * S, 00134 float32_t * pSrc, 00135 float32_t * pDst, 00136 uint32_t blockSize) 00137 { 00138 float32_t *pState = S->pState; /* State pointer */ 00139 float32_t *pCoeffs = S->pCoeffs; /* Coefficient pointer */ 00140 float32_t *pStateCurnt; /* Points to the current sample of the state */ 00141 float32_t *px, *pb; /* Temporary pointers for state and coefficient buffers */ 00142 float32_t sum0; /* Accumulator */ 00143 float32_t x0, c0; /* Temporary variables to hold state and coefficient values */ 00144 uint32_t numTaps = S->numTaps; /* Number of filter coefficients in the filter */ 00145 uint32_t i, tapCnt, blkCnt, outBlockSize = blockSize / S->M; /* Loop counters */ 00146 00147 #ifndef ARM_MATH_CM0 00148 00149 /* Run the below code for Cortex-M4 and Cortex-M3 */ 00150 00151 /* S->pState buffer contains previous frame (numTaps - 1) samples */ 00152 /* pStateCurnt points to the location where the new input data should be written */ 00153 pStateCurnt = S->pState + (numTaps - 1u); 00154 00155 /* Total number of output samples to be computed */ 00156 blkCnt = outBlockSize; 00157 00158 while(blkCnt > 0u) 00159 { 00160 /* Copy decimation factor number of new input samples into the state buffer */ 00161 i = S->M; 00162 00163 do 00164 { 00165 *pStateCurnt++ = *pSrc++; 00166 00167 } while(--i); 00168 00169 /* Set accumulator to zero */ 00170 sum0 = 0.0f; 00171 00172 /* Initialize state pointer */ 00173 px = pState; 00174 00175 /* Initialize coeff pointer */ 00176 pb = pCoeffs; 00177 00178 /* Loop unrolling. Process 4 taps at a time. */ 00179 tapCnt = numTaps >> 2; 00180 00181 /* Loop over the number of taps. Unroll by a factor of 4. 00182 ** Repeat until we've computed numTaps-4 coefficients. */ 00183 while(tapCnt > 0u) 00184 { 00185 /* Read the b[numTaps-1] coefficient */ 00186 c0 = *(pb++); 00187 00188 /* Read x[n-numTaps-1] sample */ 00189 x0 = *(px++); 00190 00191 /* Perform the multiply-accumulate */ 00192 sum0 += x0 * c0; 00193 00194 /* Read the b[numTaps-2] coefficient */ 00195 c0 = *(pb++); 00196 00197 /* Read x[n-numTaps-2] sample */ 00198 x0 = *(px++); 00199 00200 /* Perform the multiply-accumulate */ 00201 sum0 += x0 * c0; 00202 00203 /* Read the b[numTaps-3] coefficient */ 00204 c0 = *(pb++); 00205 00206 /* Read x[n-numTaps-3] sample */ 00207 x0 = *(px++); 00208 00209 /* Perform the multiply-accumulate */ 00210 sum0 += x0 * c0; 00211 00212 /* Read the b[numTaps-4] coefficient */ 00213 c0 = *(pb++); 00214 00215 /* Read x[n-numTaps-4] sample */ 00216 x0 = *(px++); 00217 00218 /* Perform the multiply-accumulate */ 00219 sum0 += x0 * c0; 00220 00221 /* Decrement the loop counter */ 00222 tapCnt--; 00223 } 00224 00225 /* If the filter length is not a multiple of 4, compute the remaining filter taps */ 00226 tapCnt = numTaps % 0x4u; 00227 00228 while(tapCnt > 0u) 00229 { 00230 /* Read coefficients */ 00231 c0 = *(pb++); 00232 00233 /* Fetch 1 state variable */ 00234 x0 = *(px++); 00235 00236 /* Perform the multiply-accumulate */ 00237 sum0 += x0 * c0; 00238 00239 /* Decrement the loop counter */ 00240 tapCnt--; 00241 } 00242 00243 /* Advance the state pointer by the decimation factor 00244 * to process the next group of decimation factor number samples */ 00245 pState = pState + S->M; 00246 00247 /* The result is in the accumulator, store in the destination buffer. */ 00248 *pDst++ = sum0; 00249 00250 /* Decrement the loop counter */ 00251 blkCnt--; 00252 } 00253 00254 /* Processing is complete. 00255 ** Now copy the last numTaps - 1 samples to the satrt of the state buffer. 00256 ** This prepares the state buffer for the next function call. */ 00257 00258 /* Points to the start of the state buffer */ 00259 pStateCurnt = S->pState; 00260 00261 i = (numTaps - 1u) >> 2; 00262 00263 /* copy data */ 00264 while(i > 0u) 00265 { 00266 *pStateCurnt++ = *pState++; 00267 *pStateCurnt++ = *pState++; 00268 *pStateCurnt++ = *pState++; 00269 *pStateCurnt++ = *pState++; 00270 00271 /* Decrement the loop counter */ 00272 i--; 00273 } 00274 00275 i = (numTaps - 1u) % 0x04u; 00276 00277 /* copy data */ 00278 while(i > 0u) 00279 { 00280 *pStateCurnt++ = *pState++; 00281 00282 /* Decrement the loop counter */ 00283 i--; 00284 } 00285 00286 #else 00287 00288 /* Run the below code for Cortex-M0 */ 00289 00290 /* S->pState buffer contains previous frame (numTaps - 1) samples */ 00291 /* pStateCurnt points to the location where the new input data should be written */ 00292 pStateCurnt = S->pState + (numTaps - 1u); 00293 00294 /* Total number of output samples to be computed */ 00295 blkCnt = outBlockSize; 00296 00297 while(blkCnt > 0u) 00298 { 00299 /* Copy decimation factor number of new input samples into the state buffer */ 00300 i = S->M; 00301 00302 do 00303 { 00304 *pStateCurnt++ = *pSrc++; 00305 00306 } while(--i); 00307 00308 /* Set accumulator to zero */ 00309 sum0 = 0.0f; 00310 00311 /* Initialize state pointer */ 00312 px = pState; 00313 00314 /* Initialize coeff pointer */ 00315 pb = pCoeffs; 00316 00317 tapCnt = numTaps; 00318 00319 while(tapCnt > 0u) 00320 { 00321 /* Read coefficients */ 00322 c0 = *pb++; 00323 00324 /* Fetch 1 state variable */ 00325 x0 = *px++; 00326 00327 /* Perform the multiply-accumulate */ 00328 sum0 += x0 * c0; 00329 00330 /* Decrement the loop counter */ 00331 tapCnt--; 00332 } 00333 00334 /* Advance the state pointer by the decimation factor 00335 * to process the next group of decimation factor number samples */ 00336 pState = pState + S->M; 00337 00338 /* The result is in the accumulator, store in the destination buffer. */ 00339 *pDst++ = sum0; 00340 00341 /* Decrement the loop counter */ 00342 blkCnt--; 00343 } 00344 00345 /* Processing is complete. 00346 ** Now copy the last numTaps - 1 samples to the start of the state buffer. 00347 ** This prepares the state buffer for the next function call. */ 00348 00349 /* Points to the start of the state buffer */ 00350 pStateCurnt = S->pState; 00351 00352 /* Copy numTaps number of values */ 00353 i = (numTaps - 1u); 00354 00355 /* copy data */ 00356 while(i > 0u) 00357 { 00358 *pStateCurnt++ = *pState++; 00359 00360 /* Decrement the loop counter */ 00361 i--; 00362 } 00363 00364 #endif /* #ifndef ARM_MATH_CM0 */ 00365 00366 } 00367