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_fir_interpolate_f32.c 00009 * 00010 * Description: FIR interpolation for floating-point sequences. 00011 * 00012 * Target Processor: Cortex-M4/Cortex-M3 00013 * 00014 * Version 1.0.3 2010/11/29 00015 * Re-organized the CMSIS folders and updated documentation. 00016 * 00017 * Version 1.0.2 2010/11/11 00018 * Documentation updated. 00019 * 00020 * Version 1.0.1 2010/10/05 00021 * Production release and review comments incorporated. 00022 * 00023 * Version 1.0.0 2010/09/20 00024 * Production release and review comments incorporated 00025 * 00026 * Version 0.0.7 2010/06/10 00027 * Misra-C changes done 00028 * -------------------------------------------------------------------- */ 00029 00030 #include "arm_math.h" 00031 00132 void arm_fir_interpolate_f32( 00133 const arm_fir_interpolate_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 *ptr1, *ptr2; /* Temporary pointers for state and coefficient buffers */ 00142 float32_t sum0; /* Accumulators */ 00143 float32_t x0, c0; /* Temporary variables to hold state and coefficient values */ 00144 uint32_t i, blkCnt, j; /* Loop counters */ 00145 uint16_t phaseLen = S->phaseLength, tapCnt; /* Length of each polyphase filter component */ 00146 00147 00148 /* S->pState buffer contains previous frame (phaseLen - 1) samples */ 00149 /* pStateCurnt points to the location where the new input data should be written */ 00150 pStateCurnt = S->pState + (phaseLen - 1u); 00151 00152 /* Total number of intput samples */ 00153 blkCnt = blockSize; 00154 00155 /* Loop over the blockSize. */ 00156 while(blkCnt > 0u) 00157 { 00158 /* Copy new input sample into the state buffer */ 00159 *pStateCurnt++ = *pSrc++; 00160 00161 /* Address modifier index of coefficient buffer */ 00162 j = 1u; 00163 00164 /* Loop over the Interpolation factor. */ 00165 i = S->L; 00166 while(i > 0u) 00167 { 00168 /* Set accumulator to zero */ 00169 sum0 = 0.0f; 00170 00171 /* Initialize state pointer */ 00172 ptr1 = pState; 00173 00174 /* Initialize coefficient pointer */ 00175 ptr2 = pCoeffs + (S->L - j); 00176 00177 /* Loop over the polyPhase length. Unroll by a factor of 4. 00178 ** Repeat until we've computed numTaps-(4*S->L) coefficients. */ 00179 tapCnt = phaseLen >> 2u; 00180 while(tapCnt > 0u) 00181 { 00182 00183 /* Read the coefficient */ 00184 c0 = *(ptr2); 00185 00186 /* Upsampling is done by stuffing L-1 zeros between each sample. 00187 * So instead of multiplying zeros with coefficients, 00188 * Increment the coefficient pointer by interpolation factor times. */ 00189 ptr2 += S->L; 00190 00191 /* Read the input sample */ 00192 x0 = *(ptr1++); 00193 00194 /* Perform the multiply-accumulate */ 00195 sum0 += x0 * c0; 00196 00197 /* Read the coefficient */ 00198 c0 = *(ptr2); 00199 00200 /* Increment the coefficient pointer by interpolation factor times. */ 00201 ptr2 += S->L; 00202 00203 /* Read the input sample */ 00204 x0 = *(ptr1++); 00205 00206 /* Perform the multiply-accumulate */ 00207 sum0 += x0 * c0; 00208 00209 /* Read the coefficient */ 00210 c0 = *(ptr2); 00211 00212 /* Increment the coefficient pointer by interpolation factor times. */ 00213 ptr2 += S->L; 00214 00215 /* Read the input sample */ 00216 x0 = *(ptr1++); 00217 00218 /* Perform the multiply-accumulate */ 00219 sum0 += x0 * c0; 00220 00221 /* Read the coefficient */ 00222 c0 = *(ptr2); 00223 00224 /* Increment the coefficient pointer by interpolation factor times. */ 00225 ptr2 += S->L; 00226 00227 /* Read the input sample */ 00228 x0 = *(ptr1++); 00229 00230 /* Perform the multiply-accumulate */ 00231 sum0 += x0 * c0; 00232 00233 /* Decrement the loop counter */ 00234 tapCnt--; 00235 } 00236 00237 /* If the polyPhase length is not a multiple of 4, compute the remaining filter taps */ 00238 tapCnt = phaseLen % 0x4u; 00239 00240 while(tapCnt > 0u) 00241 { 00242 /* Perform the multiply-accumulate */ 00243 sum0 += *(ptr1++) * (*ptr2); 00244 00245 /* Increment the coefficient pointer by interpolation factor times. */ 00246 ptr2 += S->L; 00247 00248 /* Decrement the loop counter */ 00249 tapCnt--; 00250 } 00251 00252 /* The result is in the accumulator, store in the destination buffer. */ 00253 *pDst++ = sum0; 00254 00255 /* Increment the address modifier index of coefficient buffer */ 00256 j++; 00257 00258 /* Decrement the loop counter */ 00259 i--; 00260 } 00261 00262 /* Advance the state pointer by 1 00263 * to process the next group of interpolation factor number samples */ 00264 pState = pState + 1; 00265 00266 /* Decrement the loop counter */ 00267 blkCnt--; 00268 } 00269 00270 /* Processing is complete. 00271 ** Now copy the last phaseLen - 1 samples to the satrt of the state buffer. 00272 ** This prepares the state buffer for the next function call. */ 00273 00274 /* Points to the start of the state buffer */ 00275 pStateCurnt = S->pState; 00276 00277 tapCnt = (phaseLen - 1u) >> 2u; 00278 00279 /* copy data */ 00280 while(tapCnt > 0u) 00281 { 00282 *pStateCurnt++ = *pState++; 00283 *pStateCurnt++ = *pState++; 00284 *pStateCurnt++ = *pState++; 00285 *pStateCurnt++ = *pState++; 00286 00287 /* Decrement the loop counter */ 00288 tapCnt--; 00289 } 00290 00291 tapCnt = (phaseLen - 1u) % 0x04u; 00292 00293 while(tapCnt > 0u) 00294 { 00295 *pStateCurnt++ = *pState++; 00296 00297 /* Decrement the loop counter */ 00298 tapCnt--; 00299 } 00300 } 00301