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

- File List
- Globals

# arm_lms_norm_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_lms_norm_f32.c
    00009 *
    00010 * Description:  Processing function for the floating-point Normalised LMS.
    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
    00157 void arm_lms_norm_f32(
    00158   arm_lms_norm_instance_f32 * S,
    00159   float32_t * pSrc,
    00160   float32_t * pRef,
    00161   float32_t * pOut,
    00162   float32_t * pErr,
    00163   uint32_t blockSize)
    00164 {
    00165   float32_t *pState = S->pState;                 /* State pointer */
    00166   float32_t *pCoeffs = S->pCoeffs;               /* Coefficient pointer */
    00167   float32_t *pStateCurnt;                        /* Points to the current sample of the state */
    00168   float32_t *px, *pb;                            /* Temporary pointers for state and coefficient buffers */
    00169   float32_t mu = S->mu;                          /* Adaptive factor */
    00170   uint32_t numTaps = S->numTaps;                 /* Number of filter coefficients in the filter */
    00171   uint32_t tapCnt, blkCnt;                       /* Loop counters */
    00172   float32_t energy;                              /* Energy of the input */
    00173   float32_t sum, e, d;                           /* accumulator, error, reference data sample */
    00174   float32_t w, x0, in;                           /* weight factor, temporary variable to hold input sample and state */
    00175
    00176   /* Initializations of error,  difference, Coefficient update */
    00177   e = 0.0f;
    00178   d = 0.0f;
    00179   w = 0.0f;
    00180
    00181   energy = S->energy;
    00182   x0 = S->x0;
    00183
    00184   /* S->pState points to buffer which contains previous frame (numTaps - 1) samples */
    00185   /* pStateCurnt points to the location where the new input data should be written */
    00186   pStateCurnt = &(S->pState[(numTaps - 1u)]);
    00187
    00188   blkCnt = blockSize;
    00189
    00190   while(blkCnt > 0u)
    00191   {
    00192     /* Copy the new input sample into the state buffer */
    00193     *pStateCurnt++ = *pSrc;
    00194
    00195     /* Initialize pState pointer */
    00196     px = pState;
    00197
    00198     /* Initialize coeff pointer */
    00199     pb = (pCoeffs);
    00200
    00201     /* Read the sample from input buffer */
    00202     in = *pSrc++;
    00203
    00204     /* Update the energy calculation */
    00205     energy -= x0 * x0;
    00206     energy += in * in;
    00207
    00208     /* Set the accumulator to zero */
    00209     sum = 0.0f;
    00210
    00211     /* Loop unrolling.  Process 4 taps at a time. */
    00212     tapCnt = numTaps >> 2;
    00213
    00214     while(tapCnt > 0u)
    00215     {
    00216       /* Perform the multiply-accumulate */
    00217       sum += (*px++) * (*pb++);
    00218       sum += (*px++) * (*pb++);
    00219       sum += (*px++) * (*pb++);
    00220       sum += (*px++) * (*pb++);
    00221
    00222       /* Decrement the loop counter */
    00223       tapCnt--;
    00224     }
    00225
    00226     /* If the filter length is not a multiple of 4, compute the remaining filter taps */
    00227     tapCnt = numTaps % 0x4u;
    00228
    00229     while(tapCnt > 0u)
    00230     {
    00231       /* Perform the multiply-accumulate */
    00232       sum += (*px++) * (*pb++);
    00233
    00234       /* Decrement the loop counter */
    00235       tapCnt--;
    00236     }
    00237
    00238     /* The result in the accumulator, store in the destination buffer. */
    00239     *pOut++ = sum;
    00240
    00241     /* Compute and store error */
    00242     d = (float32_t) (*pRef++);
    00243     e = d - sum;
    00244     *pErr++ = e;
    00245
    00246     /* Calculation of Weighting factor for updating filter coefficients */
    00247     /* epsilon value 0.000000119209289f */
    00248     w = (e * mu) / (energy + 0.000000119209289f);
    00249
    00250     /* Initialize pState pointer */
    00251     px = pState;
    00252
    00253     /* Initialize coeff pointer */
    00254     pb = (pCoeffs);
    00255
    00256     /* Loop unrolling.  Process 4 taps at a time. */
    00257     tapCnt = numTaps >> 2;
    00258
    00259     /* Update filter coefficients */
    00260     while(tapCnt > 0u)
    00261     {
    00262       /* Perform the multiply-accumulate */
    00263       *pb += w * (*px++);
    00264       pb++;
    00265
    00266       *pb += w * (*px++);
    00267       pb++;
    00268
    00269       *pb += w * (*px++);
    00270       pb++;
    00271
    00272       *pb += w * (*px++);
    00273       pb++;
    00274
    00275
    00276       /* Decrement the loop counter */
    00277       tapCnt--;
    00278     }
    00279
    00280     /* If the filter length is not a multiple of 4, compute the remaining filter taps */
    00281     tapCnt = numTaps % 0x4u;
    00282
    00283     while(tapCnt > 0u)
    00284     {
    00285       /* Perform the multiply-accumulate */
    00286       *pb += w * (*px++);
    00287       pb++;
    00288
    00289       /* Decrement the loop counter */
    00290       tapCnt--;
    00291     }
    00292
    00293     x0 = *pState;
    00294
    00295     /* Advance state pointer by 1 for the next sample */
    00296     pState = pState + 1;
    00297
    00298     /* Decrement the loop counter */
    00299     blkCnt--;
    00300   }
    00301
    00302   S->energy = energy;
    00303   S->x0 = x0;
    00304
    00305   /* Processing is complete. Now copy the last numTaps - 1 samples to the
    00306      satrt of the state buffer. This prepares the state buffer for the
    00307      next function call. */
    00308
    00309   /* Points to the start of the pState buffer */
    00310   pStateCurnt = S->pState;
    00311
    00312   /* Loop unrolling for (numTaps - 1u)/4 samples copy */
    00313   tapCnt = (numTaps - 1u) >> 2u;
    00314
    00315   /* copy data */
    00316   while(tapCnt > 0u)
    00317   {
    00318     *pStateCurnt++ = *pState++;
    00319     *pStateCurnt++ = *pState++;
    00320     *pStateCurnt++ = *pState++;
    00321     *pStateCurnt++ = *pState++;
    00322
    00323     /* Decrement the loop counter */
    00324     tapCnt--;
    00325   }
    00326
    00327   /* Calculate remaining number of copies */
    00328   tapCnt = (numTaps - 1u) % 0x4u;
    00329
    00330   /* Copy the remaining q31_t data */
    00331   while(tapCnt > 0u)
    00332   {
    00333     *pStateCurnt++ = *pState++;
    00334
    00335     /* Decrement the loop counter */
    00336     tapCnt--;
    00337   }
    00338
    00339
    00340 }
    00341

All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines