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

- File List
- Globals

# arm_lms_q31.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_q31.c
    00009 *
    00010 * Description:  Processing function for the Q31 LMS 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"
    00063 void arm_lms_q31(
    00064   const arm_lms_instance_q31 * S,
    00065   q31_t * pSrc,
    00066   q31_t * pRef,
    00067   q31_t * pOut,
    00068   q31_t * pErr,
    00069   uint32_t blockSize)
    00070 {
    00071   q31_t *pState = S->pState;                     /* State pointer */
    00072   uint32_t numTaps = S->numTaps;                 /* Number of filter coefficients in the filter */
    00073   q31_t *pCoeffs = S->pCoeffs;                   /* Coefficient pointer */
    00074   q31_t *pStateCurnt;                            /* Points to the current sample of the state */
    00075   q31_t mu = S->mu;                              /* Adaptive factor */
    00076   q31_t *px;                                     /* Temporary pointer for state */
    00077   q31_t *pb;                                     /* Temporary pointer for coefficient buffer */
    00078   uint32_t tapCnt, blkCnt;                       /* Loop counters */
    00079   q63_t acc;                                     /* Accumulator */
    00080   q31_t e = 0;                                   /* error of data sample */
    00081   q31_t alpha;                                   /* Intermediate constant for taps update */
    00082   uint8_t shift = (uint8_t) (32u - (S->postShift + 1u));        /* Shift to be applied to the output */
    00083   q31_t coef;                                    /* Temporary variable for coef */
    00084
    00085   /* S->pState points to buffer which contains previous frame (numTaps - 1) samples */
    00086   /* pStateCurnt points to the location where the new input data should be written */
    00087   pStateCurnt = &(S->pState[(numTaps - 1u)]);
    00088
    00089   /* Initializing blkCnt with blockSize */
    00090   blkCnt = blockSize;
    00091
    00092   while(blkCnt > 0u)
    00093   {
    00094     /* Copy the new input sample into the state buffer */
    00095     *pStateCurnt++ = *pSrc++;
    00096
    00097     /* Initialize state pointer */
    00098     px = pState;
    00099
    00100     /* Initialize coefficient pointer */
    00101     pb = pCoeffs;
    00102
    00103     /* Set the accumulator to zero */
    00104     acc = 0;
    00105
    00106     /* Loop unrolling.  Process 4 taps at a time. */
    00107     tapCnt = numTaps >> 2;
    00108
    00109     while(tapCnt > 0u)
    00110     {
    00111       /* Perform the multiply-accumulate */
    00112       /* acc +=  b[N] * x[n-N] */
    00113       acc += ((q63_t) (*px++)) * (*pb++);
    00114
    00115       /* acc +=  b[N-1] * x[n-N-1] */
    00116       acc += ((q63_t) (*px++)) * (*pb++);
    00117
    00118       /* acc +=  b[N-2] * x[n-N-2] */
    00119       acc += ((q63_t) (*px++)) * (*pb++);
    00120
    00121       /* acc +=  b[N-3] * x[n-N-3] */
    00122       acc += ((q63_t) (*px++)) * (*pb++);
    00123
    00124       /* Decrement the loop counter */
    00125       tapCnt--;
    00126     }
    00127
    00128     /* If the filter length is not a multiple of 4, compute the remaining filter taps */
    00129     tapCnt = numTaps % 0x4u;
    00130
    00131     while(tapCnt > 0u)
    00132     {
    00133       /* Perform the multiply-accumulate */
    00134       acc += ((q63_t) (*px++)) * (*pb++);
    00135
    00136       /* Decrement the loop counter */
    00137       tapCnt--;
    00138     }
    00139
    00140     /* Converting the result to 1.31 format */
    00141     /* Store the result from accumulator into the destination buffer. */
    00142     acc = (q31_t) (acc >> shift);
    00143
    00144     *pOut++ = (q31_t) acc;
    00145
    00146     /* Compute and store error */
    00147     e = *pRef++ - (q31_t) acc;
    00148
    00149     *pErr++ = (q31_t) e;
    00150
    00151     /* Compute alpha i.e. intermediate constant for taps update */
    00152     alpha = (q31_t) (((q63_t) e * mu) >> 31);
    00153
    00154     /* Initialize state pointer */
    00155     /* Advance state pointer by 1 for the next sample */
    00156     px = pState++;
    00157
    00158     /* Initialize coefficient pointer */
    00159     pb = pCoeffs;
    00160
    00161     /* Loop unrolling.  Process 4 taps at a time. */
    00162     tapCnt = numTaps >> 2;
    00163
    00164     /* Update filter coefficients */
    00165     while(tapCnt > 0u)
    00166     {
    00167       /* coef is in 2.30 format */
    00168       coef = (q31_t) (((q63_t) alpha * (*px++)) >> (32));
    00169       /* get coef in 1.31 format by left shifting */
    00170       *pb = clip_q63_to_q31((q63_t) *pb + (coef << 1u));
    00171       /* update coefficient buffer to next coefficient */
    00172       pb++;
    00173
    00174       coef = (q31_t) (((q63_t) alpha * (*px++)) >> (32));
    00175       *pb = clip_q63_to_q31((q63_t) *pb + (coef << 1u));
    00176       pb++;
    00177
    00178       coef = (q31_t) (((q63_t) alpha * (*px++)) >> (32));
    00179       *pb = clip_q63_to_q31((q63_t) *pb + (coef << 1u));
    00180       pb++;
    00181
    00182       coef = (q31_t) (((q63_t) alpha * (*px++)) >> (32));
    00183       *pb = clip_q63_to_q31((q63_t) *pb + (coef << 1u));
    00184       pb++;
    00185
    00186       /* Decrement the loop counter */
    00187       tapCnt--;
    00188     }
    00189
    00190     /* If the filter length is not a multiple of 4, compute the remaining filter taps */
    00191     tapCnt = numTaps % 0x4u;
    00192
    00193     while(tapCnt > 0u)
    00194     {
    00195       /* Perform the multiply-accumulate */
    00196       coef = (q31_t) (((q63_t) alpha * (*px++)) >> (32));
    00197       *pb = clip_q63_to_q31((q63_t) *pb + (coef << 1u));
    00198       pb++;
    00199
    00200       /* Decrement the loop counter */
    00201       tapCnt--;
    00202     }
    00203
    00204     /* Decrement the loop counter */
    00205     blkCnt--;
    00206   }
    00207
    00208   /* Processing is complete. Now copy the last numTaps - 1 samples to the
    00209      satrt of the state buffer. This prepares the state buffer for the
    00210      next function call. */
    00211
    00212   /* Points to the start of the pState buffer */
    00213   pStateCurnt = S->pState;
    00214
    00215   /* Loop unrolling for (numTaps - 1u) samples copy */
    00216   tapCnt = (numTaps - 1u) >> 2u;
    00217
    00218   /* copy data */
    00219   while(tapCnt > 0u)
    00220   {
    00221     *pStateCurnt++ = *pState++;
    00222     *pStateCurnt++ = *pState++;
    00223     *pStateCurnt++ = *pState++;
    00224     *pStateCurnt++ = *pState++;
    00225
    00226     /* Decrement the loop counter */
    00227     tapCnt--;
    00228   }
    00229
    00230   /* Calculate remaining number of copies */
    00231   tapCnt = (numTaps - 1u) % 0x4u;
    00232
    00233   /* Copy the remaining q31_t data */
    00234   while(tapCnt > 0u)
    00235   {
    00236     *pStateCurnt++ = *pState++;
    00237
    00238     /* Decrement the loop counter */
    00239     tapCnt--;
    00240   }
    00241
    00242 }
    00243

All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines