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

- File List
- Globals

# arm_fir_lattice_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_lattice_f32.c
    00009 *
    00010 * Description:  Processing function for the floating-point FIR Lattice filter.
    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
    00118 void arm_fir_lattice_f32(
    00119   const arm_fir_lattice_instance_f32 * S,
    00120   float32_t * pSrc,
    00121   float32_t * pDst,
    00122   uint32_t blockSize)
    00123 {
    00124   float32_t *pState;                             /* State pointer */
    00125   float32_t *pCoeffs = S->pCoeffs;               /* Coefficient pointer */
    00126   float32_t *px;                                 /* temporary state pointer */
    00127   float32_t *pk;                                 /* temporary coefficient pointer */
    00128   float32_t fcurr1, fnext1, gcurr1, gnext1;      /* temporary variables for first sample in loop unrolling */
    00129   float32_t fcurr2, fnext2, gnext2;              /* temporary variables for second sample in loop unrolling */
    00130   float32_t fcurr3, fnext3, gnext3;              /* temporary variables for third sample in loop unrolling */
    00131   float32_t fcurr4, fnext4, gnext4;              /* temporary variables for fourth sample in loop unrolling */
    00132   uint32_t numStages = S->numStages;             /* Number of stages in the filter */
    00133   uint32_t blkCnt, stageCnt;                     /* temporary variables for counts */
    00134
    00135   gcurr1 = 0.0f;
    00136   pState = &S->pState[0];
    00137
    00138   blkCnt = blockSize >> 2;
    00139
    00140   /* First part of the processing with loop unrolling.  Compute 4 outputs at a time.
    00141      a second loop below computes the remaining 1 to 3 samples. */
    00142   while(blkCnt > 0u)
    00143   {
    00144
    00145     /* Read two samples from input buffer */
    00146     /* f0(n) = x(n) */
    00147     fcurr1 = *pSrc++;
    00148     fcurr2 = *pSrc++;
    00149
    00150     /* Initialize coeff pointer */
    00151     pk = (pCoeffs);
    00152
    00153     /* Initialize state pointer */
    00154     px = pState;
    00155
    00156     /* Read g0(n-1) from state */
    00157     gcurr1 = *px;
    00158
    00159     /* Process first sample for first tap */
    00160     /* f1(n) = f0(n) +  K1 * g0(n-1) */
    00161     fnext1 = fcurr1 + ((*pk) * gcurr1);
    00162     /* g1(n) = f0(n) * K1  +  g0(n-1) */
    00163     gnext1 = (fcurr1 * (*pk)) + gcurr1;
    00164
    00165     /* Process second sample for first tap */
    00166     /* for sample 2 processing */
    00167     fnext2 = fcurr2 + ((*pk) * fcurr1);
    00168     gnext2 = (fcurr2 * (*pk)) + fcurr1;
    00169
    00170     /* Read next two samples from input buffer */
    00171     /* f0(n+2) = x(n+2) */
    00172     fcurr3 = *pSrc++;
    00173     fcurr4 = *pSrc++;
    00174
    00175     /* Copy only last input samples into the state buffer
    00176        which will be used for next four samples processing */
    00177     *px++ = fcurr4;
    00178
    00179     /* Process third sample for first tap */
    00180     fnext3 = fcurr3 + ((*pk) * fcurr2);
    00181     gnext3 = (fcurr3 * (*pk)) + fcurr2;
    00182
    00183     /* Process fourth sample for first tap */
    00184     fnext4 = fcurr4 + ((*pk) * fcurr3);
    00185     gnext4 = (fcurr4 * (*pk++)) + fcurr3;
    00186
    00187     /* Update of f values for next coefficient set processing */
    00188     fcurr1 = fnext1;
    00189     fcurr2 = fnext2;
    00190     fcurr3 = fnext3;
    00191     fcurr4 = fnext4;
    00192
    00193     /* Loop unrolling.  Process 4 taps at a time . */
    00194     stageCnt = (numStages - 1u) >> 2u;
    00195
    00196     /* Loop over the number of taps.  Unroll by a factor of 4.
    00197      ** Repeat until we've computed numStages-3 coefficients. */
    00198
    00199     /* Process 2nd, 3rd, 4th and 5th taps ... here */
    00200     while(stageCnt > 0u)
    00201     {
    00202       /* Read g1(n-1), g3(n-1) .... from state */
    00203       gcurr1 = *px;
    00204
    00205       /* save g1(n) in state buffer */
    00206       *px++ = gnext4;
    00207
    00208       /* Process first sample for 2nd, 6th .. tap */
    00209       /* Sample processing for K2, K6.... */
    00210       /* f2(n) = f1(n) +  K2 * g1(n-1) */
    00211       fnext1 = fcurr1 + ((*pk) * gcurr1);
    00212       /* Process second sample for 2nd, 6th .. tap */
    00213       /* for sample 2 processing */
    00214       fnext2 = fcurr2 + ((*pk) * gnext1);
    00215       /* Process third sample for 2nd, 6th .. tap */
    00216       fnext3 = fcurr3 + ((*pk) * gnext2);
    00217       /* Process fourth sample for 2nd, 6th .. tap */
    00218       fnext4 = fcurr4 + ((*pk) * gnext3);
    00219
    00220       /* g2(n) = f1(n) * K2  +  g1(n-1) */
    00221       /* Calculation of state values for next stage */
    00222       gnext4 = (fcurr4 * (*pk)) + gnext3;
    00223       gnext3 = (fcurr3 * (*pk)) + gnext2;
    00224       gnext2 = (fcurr2 * (*pk)) + gnext1;
    00225       gnext1 = (fcurr1 * (*pk++)) + gcurr1;
    00226
    00227
    00228       /* Read g2(n-1), g4(n-1) .... from state */
    00229       gcurr1 = *px;
    00230
    00231       /* save g2(n) in state buffer */
    00232       *px++ = gnext4;
    00233
    00234       /* Sample processing for K3, K7.... */
    00235       /* Process first sample for 3rd, 7th .. tap */
    00236       /* f3(n) = f2(n) +  K3 * g2(n-1) */
    00237       fcurr1 = fnext1 + ((*pk) * gcurr1);
    00238       /* Process second sample for 3rd, 7th .. tap */
    00239       fcurr2 = fnext2 + ((*pk) * gnext1);
    00240       /* Process third sample for 3rd, 7th .. tap */
    00241       fcurr3 = fnext3 + ((*pk) * gnext2);
    00242       /* Process fourth sample for 3rd, 7th .. tap */
    00243       fcurr4 = fnext4 + ((*pk) * gnext3);
    00244
    00245       /* Calculation of state values for next stage */
    00246       /* g3(n) = f2(n) * K3  +  g2(n-1) */
    00247       gnext4 = (fnext4 * (*pk)) + gnext3;
    00248       gnext3 = (fnext3 * (*pk)) + gnext2;
    00249       gnext2 = (fnext2 * (*pk)) + gnext1;
    00250       gnext1 = (fnext1 * (*pk++)) + gcurr1;
    00251
    00252
    00253       /* Read g1(n-1), g3(n-1) .... from state */
    00254       gcurr1 = *px;
    00255
    00256       /* save g3(n) in state buffer */
    00257       *px++ = gnext4;
    00258
    00259       /* Sample processing for K4, K8.... */
    00260       /* Process first sample for 4th, 8th .. tap */
    00261       /* f4(n) = f3(n) +  K4 * g3(n-1) */
    00262       fnext1 = fcurr1 + ((*pk) * gcurr1);
    00263       /* Process second sample for 4th, 8th .. tap */
    00264       /* for sample 2 processing */
    00265       fnext2 = fcurr2 + ((*pk) * gnext1);
    00266       /* Process third sample for 4th, 8th .. tap */
    00267       fnext3 = fcurr3 + ((*pk) * gnext2);
    00268       /* Process fourth sample for 4th, 8th .. tap */
    00269       fnext4 = fcurr4 + ((*pk) * gnext3);
    00270
    00271       /* g4(n) = f3(n) * K4  +  g3(n-1) */
    00272       /* Calculation of state values for next stage */
    00273       gnext4 = (fcurr4 * (*pk)) + gnext3;
    00274       gnext3 = (fcurr3 * (*pk)) + gnext2;
    00275       gnext2 = (fcurr2 * (*pk)) + gnext1;
    00276       gnext1 = (fcurr1 * (*pk++)) + gcurr1;
    00277
    00278       /* Read g2(n-1), g4(n-1) .... from state */
    00279       gcurr1 = *px;
    00280
    00281       /* save g4(n) in state buffer */
    00282       *px++ = gnext4;
    00283
    00284       /* Sample processing for K5, K9.... */
    00285       /* Process first sample for 5th, 9th .. tap */
    00286       /* f5(n) = f4(n) +  K5 * g4(n-1) */
    00287       fcurr1 = fnext1 + ((*pk) * gcurr1);
    00288       /* Process second sample for 5th, 9th .. tap */
    00289       fcurr2 = fnext2 + ((*pk) * gnext1);
    00290       /* Process third sample for 5th, 9th .. tap */
    00291       fcurr3 = fnext3 + ((*pk) * gnext2);
    00292       /* Process fourth sample for 5th, 9th .. tap */
    00293       fcurr4 = fnext4 + ((*pk) * gnext3);
    00294
    00295       /* Calculation of state values for next stage */
    00296       /* g5(n) = f4(n) * K5  +  g4(n-1) */
    00297       gnext4 = (fnext4 * (*pk)) + gnext3;
    00298       gnext3 = (fnext3 * (*pk)) + gnext2;
    00299       gnext2 = (fnext2 * (*pk)) + gnext1;
    00300       gnext1 = (fnext1 * (*pk++)) + gcurr1;
    00301
    00302       stageCnt--;
    00303     }
    00304
    00305     /* If the (filter length -1) is not a multiple of 4, compute the remaining filter taps */
    00306     stageCnt = (numStages - 1u) % 0x4u;
    00307
    00308     while(stageCnt > 0u)
    00309     {
    00310       gcurr1 = *px;
    00311
    00312       /* save g value in state buffer */
    00313       *px++ = gnext4;
    00314
    00315       /* Process four samples for last three taps here */
    00316       fnext1 = fcurr1 + ((*pk) * gcurr1);
    00317       fnext2 = fcurr2 + ((*pk) * gnext1);
    00318       fnext3 = fcurr3 + ((*pk) * gnext2);
    00319       fnext4 = fcurr4 + ((*pk) * gnext3);
    00320
    00321       /* g1(n) = f0(n) * K1  +  g0(n-1) */
    00322       gnext4 = (fcurr4 * (*pk)) + gnext3;
    00323       gnext3 = (fcurr3 * (*pk)) + gnext2;
    00324       gnext2 = (fcurr2 * (*pk)) + gnext1;
    00325       gnext1 = (fcurr1 * (*pk++)) + gcurr1;
    00326
    00327       /* Update of f values for next coefficient set processing */
    00328       fcurr1 = fnext1;
    00329       fcurr2 = fnext2;
    00330       fcurr3 = fnext3;
    00331       fcurr4 = fnext4;
    00332
    00333       stageCnt--;
    00334
    00335     }
    00336
    00337     /* The results in the 4 accumulators, store in the destination buffer. */
    00338     /* y(n) = fN(n) */
    00339     *pDst++ = fcurr1;
    00340     *pDst++ = fcurr2;
    00341     *pDst++ = fcurr3;
    00342     *pDst++ = fcurr4;
    00343
    00344     blkCnt--;
    00345   }
    00346
    00347   /* If the blockSize is not a multiple of 4, compute any remaining output samples here.
    00348    ** No loop unrolling is used. */
    00349   blkCnt = blockSize % 0x4u;
    00350
    00351   while(blkCnt > 0u)
    00352   {
    00353     /* f0(n) = x(n) */
    00354     fcurr1 = *pSrc++;
    00355
    00356     /* Initialize coeff pointer */
    00357     pk = (pCoeffs);
    00358
    00359     /* Initialize state pointer */
    00360     px = pState;
    00361
    00362     /* read g2(n) from state buffer */
    00363     gcurr1 = *px;
    00364
    00365     /* for sample 1 processing */
    00366     /* f1(n) = f0(n) +  K1 * g0(n-1) */
    00367     fnext1 = fcurr1 + ((*pk) * gcurr1);
    00368     /* g1(n) = f0(n) * K1  +  g0(n-1) */
    00369     gnext1 = (fcurr1 * (*pk++)) + gcurr1;
    00370
    00371     /* save g1(n) in state buffer */
    00372     *px++ = fcurr1;
    00373
    00374     /* f1(n) is saved in fcurr1
    00375        for next stage processing */
    00376     fcurr1 = fnext1;
    00377
    00378     stageCnt = (numStages - 1u);
    00379
    00380     /* stage loop */
    00381     while(stageCnt > 0u)
    00382     {
    00383       /* read g2(n) from state buffer */
    00384       gcurr1 = *px;
    00385
    00386       /* save g1(n) in state buffer */
    00387       *px++ = gnext1;
    00388
    00389       /* Sample processing for K2, K3.... */
    00390       /* f2(n) = f1(n) +  K2 * g1(n-1) */
    00391       fnext1 = fcurr1 + ((*pk) * gcurr1);
    00392       /* g2(n) = f1(n) * K2  +  g1(n-1) */
    00393       gnext1 = (fcurr1 * (*pk++)) + gcurr1;
    00394
    00395       /* f1(n) is saved in fcurr1
    00396          for next stage processing */
    00397       fcurr1 = fnext1;
    00398
    00399       stageCnt--;
    00400
    00401     }
    00402
    00403     /* y(n) = fN(n) */
    00404     *pDst++ = fcurr1;
    00405
    00406     blkCnt--;
    00407
    00408   }
    00409 }
    00410

All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines