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_interpolate_f32.c 00009 * 00010 * Description: FIR interpolation 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 #include "arm_math.h" 00034 00135 void arm_fir_interpolate_f32( 00136 const arm_fir_interpolate_instance_f32 * S, 00137 float32_t * pSrc, 00138 float32_t * pDst, 00139 uint32_t blockSize) 00140 { 00141 float32_t *pState = S->pState; /* State pointer */ 00142 float32_t *pCoeffs = S->pCoeffs; /* Coefficient pointer */ 00143 float32_t *pStateCurnt; /* Points to the current sample of the state */ 00144 float32_t *ptr1, *ptr2; /* Temporary pointers for state and coefficient buffers */ 00145 00146 00147 #ifndef ARM_MATH_CM0 00148 00149 /* Run the below code for Cortex-M4 and Cortex-M3 */ 00150 00151 float32_t sum0; /* Accumulators */ 00152 float32_t x0, c0; /* Temporary variables to hold state and coefficient values */ 00153 uint32_t i, blkCnt, j; /* Loop counters */ 00154 uint16_t phaseLen = S->phaseLength, tapCnt; /* Length of each polyphase filter component */ 00155 00156 00157 /* S->pState buffer contains previous frame (phaseLen - 1) samples */ 00158 /* pStateCurnt points to the location where the new input data should be written */ 00159 pStateCurnt = S->pState + (phaseLen - 1u); 00160 00161 /* Total number of intput samples */ 00162 blkCnt = blockSize; 00163 00164 /* Loop over the blockSize. */ 00165 while(blkCnt > 0u) 00166 { 00167 /* Copy new input sample into the state buffer */ 00168 *pStateCurnt++ = *pSrc++; 00169 00170 /* Address modifier index of coefficient buffer */ 00171 j = 1u; 00172 00173 /* Loop over the Interpolation factor. */ 00174 i = S->L; 00175 while(i > 0u) 00176 { 00177 /* Set accumulator to zero */ 00178 sum0 = 0.0f; 00179 00180 /* Initialize state pointer */ 00181 ptr1 = pState; 00182 00183 /* Initialize coefficient pointer */ 00184 ptr2 = pCoeffs + (S->L - j); 00185 00186 /* Loop over the polyPhase length. Unroll by a factor of 4. 00187 ** Repeat until we've computed numTaps-(4*S->L) coefficients. */ 00188 tapCnt = phaseLen >> 2u; 00189 while(tapCnt > 0u) 00190 { 00191 00192 /* Read the coefficient */ 00193 c0 = *(ptr2); 00194 00195 /* Upsampling is done by stuffing L-1 zeros between each sample. 00196 * So instead of multiplying zeros with coefficients, 00197 * Increment the coefficient pointer by interpolation factor times. */ 00198 ptr2 += S->L; 00199 00200 /* Read the input sample */ 00201 x0 = *(ptr1++); 00202 00203 /* Perform the multiply-accumulate */ 00204 sum0 += x0 * c0; 00205 00206 /* Read the coefficient */ 00207 c0 = *(ptr2); 00208 00209 /* Increment the coefficient pointer by interpolation factor times. */ 00210 ptr2 += S->L; 00211 00212 /* Read the input sample */ 00213 x0 = *(ptr1++); 00214 00215 /* Perform the multiply-accumulate */ 00216 sum0 += x0 * c0; 00217 00218 /* Read the coefficient */ 00219 c0 = *(ptr2); 00220 00221 /* Increment the coefficient pointer by interpolation factor times. */ 00222 ptr2 += S->L; 00223 00224 /* Read the input sample */ 00225 x0 = *(ptr1++); 00226 00227 /* Perform the multiply-accumulate */ 00228 sum0 += x0 * c0; 00229 00230 /* Read the coefficient */ 00231 c0 = *(ptr2); 00232 00233 /* Increment the coefficient pointer by interpolation factor times. */ 00234 ptr2 += S->L; 00235 00236 /* Read the input sample */ 00237 x0 = *(ptr1++); 00238 00239 /* Perform the multiply-accumulate */ 00240 sum0 += x0 * c0; 00241 00242 /* Decrement the loop counter */ 00243 tapCnt--; 00244 } 00245 00246 /* If the polyPhase length is not a multiple of 4, compute the remaining filter taps */ 00247 tapCnt = phaseLen % 0x4u; 00248 00249 while(tapCnt > 0u) 00250 { 00251 /* Perform the multiply-accumulate */ 00252 sum0 += *(ptr1++) * (*ptr2); 00253 00254 /* Increment the coefficient pointer by interpolation factor times. */ 00255 ptr2 += S->L; 00256 00257 /* Decrement the loop counter */ 00258 tapCnt--; 00259 } 00260 00261 /* The result is in the accumulator, store in the destination buffer. */ 00262 *pDst++ = sum0; 00263 00264 /* Increment the address modifier index of coefficient buffer */ 00265 j++; 00266 00267 /* Decrement the loop counter */ 00268 i--; 00269 } 00270 00271 /* Advance the state pointer by 1 00272 * to process the next group of interpolation factor number samples */ 00273 pState = pState + 1; 00274 00275 /* Decrement the loop counter */ 00276 blkCnt--; 00277 } 00278 00279 /* Processing is complete. 00280 ** Now copy the last phaseLen - 1 samples to the satrt of the state buffer. 00281 ** This prepares the state buffer for the next function call. */ 00282 00283 /* Points to the start of the state buffer */ 00284 pStateCurnt = S->pState; 00285 00286 tapCnt = (phaseLen - 1u) >> 2u; 00287 00288 /* copy data */ 00289 while(tapCnt > 0u) 00290 { 00291 *pStateCurnt++ = *pState++; 00292 *pStateCurnt++ = *pState++; 00293 *pStateCurnt++ = *pState++; 00294 *pStateCurnt++ = *pState++; 00295 00296 /* Decrement the loop counter */ 00297 tapCnt--; 00298 } 00299 00300 tapCnt = (phaseLen - 1u) % 0x04u; 00301 00302 while(tapCnt > 0u) 00303 { 00304 *pStateCurnt++ = *pState++; 00305 00306 /* Decrement the loop counter */ 00307 tapCnt--; 00308 } 00309 00310 #else 00311 00312 /* Run the below code for Cortex-M0 */ 00313 00314 float32_t sum; /* Accumulator */ 00315 uint32_t i, blkCnt; /* Loop counters */ 00316 uint16_t phaseLen = S->phaseLength, tapCnt; /* Length of each polyphase filter component */ 00317 00318 00319 /* S->pState buffer contains previous frame (phaseLen - 1) samples */ 00320 /* pStateCurnt points to the location where the new input data should be written */ 00321 pStateCurnt = S->pState + (phaseLen - 1u); 00322 00323 /* Total number of intput samples */ 00324 blkCnt = blockSize; 00325 00326 /* Loop over the blockSize. */ 00327 while(blkCnt > 0u) 00328 { 00329 /* Copy new input sample into the state buffer */ 00330 *pStateCurnt++ = *pSrc++; 00331 00332 /* Loop over the Interpolation factor. */ 00333 i = S->L; 00334 00335 while(i > 0u) 00336 { 00337 /* Set accumulator to zero */ 00338 sum = 0.0f; 00339 00340 /* Initialize state pointer */ 00341 ptr1 = pState; 00342 00343 /* Initialize coefficient pointer */ 00344 ptr2 = pCoeffs + (i - 1u); 00345 00346 /* Loop over the polyPhase length */ 00347 tapCnt = phaseLen; 00348 00349 while(tapCnt > 0u) 00350 { 00351 /* Perform the multiply-accumulate */ 00352 sum += *ptr1++ * *ptr2; 00353 00354 /* Increment the coefficient pointer by interpolation factor times. */ 00355 ptr2 += S->L; 00356 00357 /* Decrement the loop counter */ 00358 tapCnt--; 00359 } 00360 00361 /* The result is in the accumulator, store in the destination buffer. */ 00362 *pDst++ = sum; 00363 00364 /* Decrement the loop counter */ 00365 i--; 00366 } 00367 00368 /* Advance the state pointer by 1 00369 * to process the next group of interpolation factor number samples */ 00370 pState = pState + 1; 00371 00372 /* Decrement the loop counter */ 00373 blkCnt--; 00374 } 00375 00376 /* Processing is complete. 00377 ** Now copy the last phaseLen - 1 samples to the start of the state buffer. 00378 ** This prepares the state buffer for the next function call. */ 00379 00380 /* Points to the start of the state buffer */ 00381 pStateCurnt = S->pState; 00382 00383 tapCnt = phaseLen - 1u; 00384 00385 while(tapCnt > 0u) 00386 { 00387 *pStateCurnt++ = *pState++; 00388 00389 /* Decrement the loop counter */ 00390 tapCnt--; 00391 } 00392 00393 #endif /* #ifndef ARM_MATH_CM0 */ 00394 00395 } 00396