- Main Page
- Modules
- Data Structures
- Files
- Examples

- File List
- Globals

# arm_fir_f32.c

Go to the documentation of this file.

    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_f32.c
    00009 *
    00010 * Description:  Floating-point FIR filter processing function.
    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.5  2010/04/26
    00027 *    incorporated review comments and updated with latest CMSIS layer
    00028 *
    00029 * Version 0.0.3  2010/03/10
    00030 *    Initial version
    00031 * -------------------------------------------------------------------- */
    00032
    00033 #include "arm_math.h"
    00034
    00124 void arm_fir_f32(
    00125   const arm_fir_instance_f32 * S,
    00126   float32_t * pSrc,
    00127   float32_t * pDst,
    00128   uint32_t blockSize)
    00129 {
    00130   float32_t *pState = S->pState;                 /* State pointer */
    00131   float32_t *pCoeffs = S->pCoeffs;               /* Coefficient pointer */
    00132   float32_t *pStateCurnt;                        /* Points to the current sample of the state */
    00133   float32_t *px, *pb;                            /* Temporary pointers for state and coefficient buffers */
    00134   float32_t acc0, acc1, acc2, acc3;              /* Accumulators */
    00135   float32_t x0, x1, x2, x3, c0;                  /* Temporary variables to hold state and coefficient values */
    00136   uint32_t numTaps = S->numTaps;                 /* Number of filter coefficients in the filter */
    00137   uint32_t i, tapCnt, blkCnt;                    /* Loop counters */
    00138
    00139   /* S->pState points to state array which contains previous frame (numTaps - 1) samples */
    00140   /* pStateCurnt points to the location where the new input data should be written */
    00141   pStateCurnt = &(S->pState[(numTaps - 1u)]);
    00142
    00143   /* Apply loop unrolling and compute 4 output values simultaneously.
    00144    * The variables acc0 ... acc3 hold output values that are being computed:
    00145    *
    00146    *    acc0 =  b[numTaps-1] * x[n-numTaps-1] + b[numTaps-2] * x[n-numTaps-2] + b[numTaps-3] * x[n-numTaps-3] +...+ b[0] * x[0]
    00147    *    acc1 =  b[numTaps-1] * x[n-numTaps] +   b[numTaps-2] * x[n-numTaps-1] + b[numTaps-3] * x[n-numTaps-2] +...+ b[0] * x[1]
    00148    *    acc2 =  b[numTaps-1] * x[n-numTaps+1] + b[numTaps-2] * x[n-numTaps] +   b[numTaps-3] * x[n-numTaps-1] +...+ b[0] * x[2]
    00149    *    acc3 =  b[numTaps-1] * x[n-numTaps+2] + b[numTaps-2] * x[n-numTaps+1] + b[numTaps-3] * x[n-numTaps]   +...+ b[0] * x[3]
    00150    */
    00151   blkCnt = blockSize >> 2;
    00152
    00153   /* First part of the processing with loop unrolling.  Compute 4 outputs at a time.
    00154    ** a second loop below computes the remaining 1 to 3 samples. */
    00155   while(blkCnt > 0u)
    00156   {
    00157     /* Copy four new input samples into the state buffer */
    00158     *pStateCurnt++ = *pSrc++;
    00159     *pStateCurnt++ = *pSrc++;
    00160     *pStateCurnt++ = *pSrc++;
    00161     *pStateCurnt++ = *pSrc++;
    00162
    00163     /* Set all accumulators to zero */
    00164     acc0 = 0.0f;
    00165     acc1 = 0.0f;
    00166     acc2 = 0.0f;
    00167     acc3 = 0.0f;
    00168
    00169     /* Initialize state pointer */
    00170     px = pState;
    00171
    00172     /* Initialize coeff pointer */
    00173     pb = (pCoeffs);
    00174
    00175     /* Read the first three samples from the state buffer:  x[n-numTaps], x[n-numTaps-1], x[n-numTaps-2] */
    00176     x0 = *px++;
    00177     x1 = *px++;
    00178     x2 = *px++;
    00179
    00180     /* Loop unrolling.  Process 4 taps at a time. */
    00181     tapCnt = numTaps >> 2u;
    00182
    00183     /* Loop over the number of taps.  Unroll by a factor of 4.
    00184      ** Repeat until we've computed numTaps-4 coefficients. */
    00185     while(tapCnt > 0u)
    00186     {
    00187       /* Read the b[numTaps-1] coefficient */
    00188       c0 = *(pb++);
    00189
    00190       /* Read x[n-numTaps-3] sample */
    00191       x3 = *(px++);
    00192
    00193       /* acc0 +=  b[numTaps-1] * x[n-numTaps] */
    00194       acc0 += x0 * c0;
    00195
    00196       /* acc1 +=  b[numTaps-1] * x[n-numTaps-1] */
    00197       acc1 += x1 * c0;
    00198
    00199       /* acc2 +=  b[numTaps-1] * x[n-numTaps-2] */
    00200       acc2 += x2 * c0;
    00201
    00202       /* acc3 +=  b[numTaps-1] * x[n-numTaps-3] */
    00203       acc3 += x3 * c0;
    00204
    00205       /* Read the b[numTaps-2] coefficient */
    00206       c0 = *(pb++);
    00207
    00208       /* Read x[n-numTaps-4] sample */
    00209       x0 = *(px++);
    00210
    00211       /* Perform the multiply-accumulate */
    00212       acc0 += x1 * c0;
    00213       acc1 += x2 * c0;
    00214       acc2 += x3 * c0;
    00215       acc3 += x0 * c0;
    00216
    00217       /* Read the b[numTaps-3] coefficient */
    00218       c0 = *(pb++);
    00219
    00220       /* Read x[n-numTaps-5] sample */
    00221       x1 = *(px++);
    00222
    00223       /* Perform the multiply-accumulates */
    00224       acc0 += x2 * c0;
    00225       acc1 += x3 * c0;
    00226       acc2 += x0 * c0;
    00227       acc3 += x1 * c0;
    00228
    00229       /* Read the b[numTaps-4] coefficient */
    00230       c0 = *(pb++);
    00231
    00232       /* Read x[n-numTaps-6] sample */
    00233       x2 = *(px++);
    00234
    00235       /* Perform the multiply-accumulates */
    00236       acc0 += x3 * c0;
    00237       acc1 += x0 * c0;
    00238       acc2 += x1 * c0;
    00239       acc3 += x2 * c0;
    00240
    00241       tapCnt--;
    00242     }
    00243
    00244     /* If the filter length is not a multiple of 4, compute the remaining filter taps */
    00245     tapCnt = numTaps % 0x4u;
    00246
    00247     while(tapCnt > 0u)
    00248     {
    00249       /* Read coefficients */
    00250       c0 = *(pb++);
    00251
    00252       /* Fetch 1 state variable */
    00253       x3 = *(px++);
    00254
    00255       /* Perform the multiply-accumulates */
    00256       acc0 += x0 * c0;
    00257       acc1 += x1 * c0;
    00258       acc2 += x2 * c0;
    00259       acc3 += x3 * c0;
    00260
    00261       /* Reuse the present sample states for next sample */
    00262       x0 = x1;
    00263       x1 = x2;
    00264       x2 = x3;
    00265
    00266       /* Decrement the loop counter */
    00267       tapCnt--;
    00268     }
    00269
    00270     /* Advance the state pointer by 4 to process the next group of 4 samples */
    00271     pState = pState + 4;
    00272
    00273     /* The results in the 4 accumulators, store in the destination buffer. */
    00274     *pDst++ = acc0;
    00275     *pDst++ = acc1;
    00276     *pDst++ = acc2;
    00277     *pDst++ = acc3;
    00278
    00279     blkCnt--;
    00280   }
    00281
    00282   /* If the blockSize is not a multiple of 4, compute any remaining output samples here.
    00283    ** No loop unrolling is used. */
    00284   blkCnt = blockSize % 0x4u;
    00285
    00286   while(blkCnt > 0u)
    00287   {
    00288     /* Copy one sample at a time into state buffer */
    00289     *pStateCurnt++ = *pSrc++;
    00290
    00291     /* Set the accumulator to zero */
    00292     acc0 = 0.0f;
    00293
    00294     /* Initialize state pointer */
    00295     px = pState;
    00296
    00297     /* Initialize Coefficient pointer */
    00298     pb = (pCoeffs);
    00299
    00300     i = numTaps;
    00301
    00302     /* Perform the multiply-accumulates */
    00303     do
    00304     {
    00305       acc0 += *px++ * *pb++;
    00306       i--;
    00307
    00308     } while(i > 0u);
    00309
    00310     /* The result is store in the destination buffer. */
    00311     *pDst++ = acc0;
    00312
    00313     /* Advance state pointer by 1 for the next sample */
    00314     pState = pState + 1;
    00315
    00316     blkCnt--;
    00317   }
    00318
    00319   /* Processing is complete.
    00320    ** Now copy the last numTaps - 1 samples to the satrt of the state buffer.
    00321    ** This prepares the state buffer for the next function call. */
    00322
    00323   /* Points to the start of the state buffer */
    00324   pStateCurnt = S->pState;
    00325
    00326   tapCnt = (numTaps - 1u) >> 2u;
    00327
    00328   /* copy data */
    00329   while(tapCnt > 0u)
    00330   {
    00331     *pStateCurnt++ = *pState++;
    00332     *pStateCurnt++ = *pState++;
    00333     *pStateCurnt++ = *pState++;
    00334     *pStateCurnt++ = *pState++;
    00335
    00336     /* Decrement the loop counter */
    00337     tapCnt--;
    00338   }
    00339
    00340   /* Calculate remaining number of copies */
    00341   tapCnt = (numTaps - 1u) % 0x4u;
    00342
    00343   /* Copy the remaining q31_t data */
    00344   while(tapCnt > 0u)
    00345   {
    00346     *pStateCurnt++ = *pState++;
    00347
    00348     /* Decrement the loop counter */
    00349     tapCnt--;
    00350   }
    00351 }
    00352

All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines