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

- File List
- Globals

# arm_fir_sparse_q7.c

Go to the documentation of this file.

    00001 /* ----------------------------------------------------------------------
    00002 * Copyright (C) 2010 ARM Limited. All rights reserved.
    00003 *
    00004 * $Date:        15. July 2011
    00005 * $Revision:    V1.0.10
    00006 *
    00007 * Project:      CMSIS DSP Library
    00008 * Title:        arm_fir_sparse_q7.c
    00009 *
    00010 * Description:  Q7 sparse FIR filter processing function.
    00011 *
    00012 * Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
    00013 *
    00014 * Version 1.0.10 2011/7/15
    00015 *    Big Endian support added and Merged M0 and M3/M4 Source code.
    00016 *
    00017 * Version 1.0.3 2010/11/29
    00018 *    Re-organized the CMSIS folders and updated documentation.
    00019 *
    00020 * Version 1.0.2 2010/11/11
    00021 *    Documentation updated.
    00022 *
    00023 * Version 1.0.1 2010/10/05
    00024 *    Production release and review comments incorporated.
    00025 *
    00026 * Version 1.0.0 2010/09/20
    00027 *    Production release and review comments incorporated
    00028 *
    00029 * Version 0.0.7  2010/06/10
    00030 *    Misra-C changes done
    00031 * ------------------------------------------------------------------- */
    00032 #include "arm_math.h"
    00033
    00034
    00065 void arm_fir_sparse_q7(
    00066   arm_fir_sparse_instance_q7 * S,
    00067   q7_t * pSrc,
    00068   q7_t * pDst,
    00069   q7_t * pScratchIn,
    00070   q31_t * pScratchOut,
    00071   uint32_t blockSize)
    00072 {
    00073
    00074   q7_t *pState = S->pState;                      /* State pointer */
    00075   q7_t *pCoeffs = S->pCoeffs;                    /* Coefficient pointer */
    00076   q7_t *px;                                      /* Scratch buffer pointer */
    00077   q7_t *py = pState;                             /* Temporary pointers for state buffer */
    00078   q7_t *pb = pScratchIn;                         /* Temporary pointers for scratch buffer */
    00079   q7_t *pOut = pDst;                             /* Destination pointer */
    00080   int32_t *pTapDelay = S->pTapDelay;             /* Pointer to the array containing offset of the non-zero tap values. */
    00081   uint32_t delaySize = S->maxDelay + blockSize;  /* state length */
    00082   uint16_t numTaps = S->numTaps;                 /* Filter order */
    00083   int32_t readIndex;                             /* Read index of the state buffer */
    00084   uint32_t tapCnt, blkCnt;                       /* loop counters */
    00085   q7_t coeff = *pCoeffs++;                       /* Read the coefficient value */
    00086   q31_t *pScr2 = pScratchOut;                    /* Working pointer for scratch buffer of output values */
    00087   q31_t in;
    00088
    00089
    00090 #ifndef ARM_MATH_CM0
    00091
    00092   /* Run the below code for Cortex-M4 and Cortex-M3 */
    00093
    00094   q7_t in1, in2, in3, in4;
    00095
    00096   /* BlockSize of Input samples are copied into the state buffer */
    00097   /* StateIndex points to the starting position to write in the state buffer */
    00098   arm_circularWrite_q7(py, (int32_t) delaySize, &S->stateIndex, 1, pSrc, 1,
    00099                        blockSize);
    00100
    00101   /* Loop over the number of taps. */
    00102   tapCnt = numTaps;
    00103
    00104   /* Read Index, from where the state buffer should be read, is calculated. */
    00105   readIndex = ((int32_t) S->stateIndex - (int32_t) blockSize) - *pTapDelay++;
    00106
    00107   /* Wraparound of readIndex */
    00108   if(readIndex < 0)
    00109   {
    00110     readIndex += (int32_t) delaySize;
    00111   }
    00112
    00113   /* Working pointer for state buffer is updated */
    00114   py = pState;
    00115
    00116   /* blockSize samples are read from the state buffer */
    00117   arm_circularRead_q7(py, (int32_t) delaySize, &readIndex, 1, pb, pb,
    00118                       (int32_t) blockSize, 1, blockSize);
    00119
    00120   /* Working pointer for the scratch buffer of state values */
    00121   px = pb;
    00122
    00123   /* Working pointer for scratch buffer of output values */
    00124   pScratchOut = pScr2;
    00125
    00126   /* Loop over the blockSize. Unroll by a factor of 4.
    00127    * Compute 4 multiplications at a time. */
    00128   blkCnt = blockSize >> 2;
    00129
    00130   while(blkCnt > 0u)
    00131   {
    00132     /* Perform multiplication and store in the scratch buffer */
    00133     *pScratchOut++ = ((q31_t) * px++ * coeff);
    00134     *pScratchOut++ = ((q31_t) * px++ * coeff);
    00135     *pScratchOut++ = ((q31_t) * px++ * coeff);
    00136     *pScratchOut++ = ((q31_t) * px++ * coeff);
    00137
    00138     /* Decrement the loop counter */
    00139     blkCnt--;
    00140   }
    00141
    00142   /* If the blockSize is not a multiple of 4,
    00143    * compute the remaining samples */
    00144   blkCnt = blockSize % 0x4u;
    00145
    00146   while(blkCnt > 0u)
    00147   {
    00148     /* Perform multiplication and store in the scratch buffer */
    00149     *pScratchOut++ = ((q31_t) * px++ * coeff);
    00150
    00151     /* Decrement the loop counter */
    00152     blkCnt--;
    00153   }
    00154
    00155   /* Load the coefficient value and
    00156    * increment the coefficient buffer for the next set of state values */
    00157   coeff = *pCoeffs++;
    00158
    00159   /* Read Index, from where the state buffer should be read, is calculated. */
    00160   readIndex = ((int32_t) S->stateIndex - (int32_t) blockSize) - *pTapDelay++;
    00161
    00162   /* Wraparound of readIndex */
    00163   if(readIndex < 0)
    00164   {
    00165     readIndex += (int32_t) delaySize;
    00166   }
    00167
    00168   /* Loop over the number of taps. */
    00169   tapCnt = (uint32_t) numTaps - 1u;
    00170
    00171   while(tapCnt > 0u)
    00172   {
    00173     /* Working pointer for state buffer is updated */
    00174     py = pState;
    00175
    00176     /* blockSize samples are read from the state buffer */
    00177     arm_circularRead_q7(py, (int32_t) delaySize, &readIndex, 1, pb, pb,
    00178                         (int32_t) blockSize, 1, blockSize);
    00179
    00180     /* Working pointer for the scratch buffer of state values */
    00181     px = pb;
    00182
    00183     /* Working pointer for scratch buffer of output values */
    00184     pScratchOut = pScr2;
    00185
    00186     /* Loop over the blockSize. Unroll by a factor of 4.
    00187      * Compute 4 MACS at a time. */
    00188     blkCnt = blockSize >> 2;
    00189
    00190     while(blkCnt > 0u)
    00191     {
    00192       /* Perform Multiply-Accumulate */
    00193       in = *pScratchOut + ((q31_t) * px++ * coeff);
    00194       *pScratchOut++ = in;
    00195       in = *pScratchOut + ((q31_t) * px++ * coeff);
    00196       *pScratchOut++ = in;
    00197       in = *pScratchOut + ((q31_t) * px++ * coeff);
    00198       *pScratchOut++ = in;
    00199       in = *pScratchOut + ((q31_t) * px++ * coeff);
    00200       *pScratchOut++ = in;
    00201
    00202       /* Decrement the loop counter */
    00203       blkCnt--;
    00204     }
    00205
    00206     /* If the blockSize is not a multiple of 4,
    00207      * compute the remaining samples */
    00208     blkCnt = blockSize % 0x4u;
    00209
    00210     while(blkCnt > 0u)
    00211     {
    00212       /* Perform Multiply-Accumulate */
    00213       in = *pScratchOut + ((q31_t) * px++ * coeff);
    00214       *pScratchOut++ = in;
    00215
    00216       /* Decrement the loop counter */
    00217       blkCnt--;
    00218     }
    00219
    00220     /* Load the coefficient value and
    00221      * increment the coefficient buffer for the next set of state values */
    00222     coeff = *pCoeffs++;
    00223
    00224     /* Read Index, from where the state buffer should be read, is calculated. */
    00225     readIndex = ((int32_t) S->stateIndex -
    00226                  (int32_t) blockSize) - *pTapDelay++;
    00227
    00228     /* Wraparound of readIndex */
    00229     if(readIndex < 0)
    00230     {
    00231       readIndex += (int32_t) delaySize;
    00232     }
    00233
    00234     /* Decrement the tap loop counter */
    00235     tapCnt--;
    00236   }
    00237
    00238   /* All the output values are in pScratchOut buffer.
    00239      Convert them into 1.15 format, saturate and store in the destination buffer. */
    00240   /* Loop over the blockSize. */
    00241   blkCnt = blockSize >> 2;
    00242
    00243   while(blkCnt > 0u)
    00244   {
    00245     in1 = (q7_t) __SSAT(*pScr2++ >> 7, 8);
    00246     in2 = (q7_t) __SSAT(*pScr2++ >> 7, 8);
    00247     in3 = (q7_t) __SSAT(*pScr2++ >> 7, 8);
    00248     in4 = (q7_t) __SSAT(*pScr2++ >> 7, 8);
    00249
    00250     *__SIMD32(pOut)++ = __PACKq7(in1, in2, in3, in4);
    00251
    00252     /* Decrement the blockSize loop counter */
    00253     blkCnt--;
    00254   }
    00255
    00256   /* If the blockSize is not a multiple of 4,
    00257      remaining samples are processed in the below loop */
    00258   blkCnt = blockSize % 0x4u;
    00259
    00260   while(blkCnt > 0u)
    00261   {
    00262     *pOut++ = (q7_t) __SSAT(*pScr2++ >> 7, 8);
    00263
    00264     /* Decrement the blockSize loop counter */
    00265     blkCnt--;
    00266   }
    00267
    00268 #else
    00269
    00270   /* Run the below code for Cortex-M0 */
    00271
    00272   /* BlockSize of Input samples are copied into the state buffer */
    00273   /* StateIndex points to the starting position to write in the state buffer */
    00274   arm_circularWrite_q7(py, (int32_t) delaySize, &S->stateIndex, 1, pSrc, 1,
    00275                        blockSize);
    00276
    00277   /* Loop over the number of taps. */
    00278   tapCnt = numTaps;
    00279
    00280   /* Read Index, from where the state buffer should be read, is calculated. */
    00281   readIndex = ((int32_t) S->stateIndex - (int32_t) blockSize) - *pTapDelay++;
    00282
    00283   /* Wraparound of readIndex */
    00284   if(readIndex < 0)
    00285   {
    00286     readIndex += (int32_t) delaySize;
    00287   }
    00288
    00289   /* Working pointer for state buffer is updated */
    00290   py = pState;
    00291
    00292   /* blockSize samples are read from the state buffer */
    00293   arm_circularRead_q7(py, (int32_t) delaySize, &readIndex, 1, pb, pb,
    00294                       (int32_t) blockSize, 1, blockSize);
    00295
    00296   /* Working pointer for the scratch buffer of state values */
    00297   px = pb;
    00298
    00299   /* Working pointer for scratch buffer of output values */
    00300   pScratchOut = pScr2;
    00301
    00302   /* Loop over the blockSize */
    00303   blkCnt = blockSize;
    00304
    00305   while(blkCnt > 0u)
    00306   {
    00307     /* Perform multiplication and store in the scratch buffer */
    00308     *pScratchOut++ = ((q31_t) * px++ * coeff);
    00309
    00310     /* Decrement the loop counter */
    00311     blkCnt--;
    00312   }
    00313
    00314   /* Load the coefficient value and
    00315    * increment the coefficient buffer for the next set of state values */
    00316   coeff = *pCoeffs++;
    00317
    00318   /* Read Index, from where the state buffer should be read, is calculated. */
    00319   readIndex = ((int32_t) S->stateIndex - (int32_t) blockSize) - *pTapDelay++;
    00320
    00321   /* Wraparound of readIndex */
    00322   if(readIndex < 0)
    00323   {
    00324     readIndex += (int32_t) delaySize;
    00325   }
    00326
    00327   /* Loop over the number of taps. */
    00328   tapCnt = (uint32_t) numTaps - 1u;
    00329
    00330   while(tapCnt > 0u)
    00331   {
    00332     /* Working pointer for state buffer is updated */
    00333     py = pState;
    00334
    00335     /* blockSize samples are read from the state buffer */
    00336     arm_circularRead_q7(py, (int32_t) delaySize, &readIndex, 1, pb, pb,
    00337                         (int32_t) blockSize, 1, blockSize);
    00338
    00339     /* Working pointer for the scratch buffer of state values */
    00340     px = pb;
    00341
    00342     /* Working pointer for scratch buffer of output values */
    00343     pScratchOut = pScr2;
    00344
    00345     /* Loop over the blockSize */
    00346     blkCnt = blockSize;
    00347
    00348     while(blkCnt > 0u)
    00349     {
    00350       /* Perform Multiply-Accumulate */
    00351       in = *pScratchOut + ((q31_t) * px++ * coeff);
    00352       *pScratchOut++ = in;
    00353
    00354       /* Decrement the loop counter */
    00355       blkCnt--;
    00356     }
    00357
    00358     /* Load the coefficient value and
    00359      * increment the coefficient buffer for the next set of state values */
    00360     coeff = *pCoeffs++;
    00361
    00362     /* Read Index, from where the state buffer should be read, is calculated. */
    00363     readIndex =
    00364       ((int32_t) S->stateIndex - (int32_t) blockSize) - *pTapDelay++;
    00365
    00366     /* Wraparound of readIndex */
    00367     if(readIndex < 0)
    00368     {
    00369       readIndex += (int32_t) delaySize;
    00370     }
    00371
    00372     /* Decrement the tap loop counter */
    00373     tapCnt--;
    00374   }
    00375
    00376   /* All the output values are in pScratchOut buffer.
    00377      Convert them into 1.15 format, saturate and store in the destination buffer. */
    00378   /* Loop over the blockSize. */
    00379   blkCnt = blockSize;
    00380
    00381   while(blkCnt > 0u)
    00382   {
    00383     *pOut++ = (q7_t) __SSAT(*pScr2++ >> 7, 8);
    00384
    00385     /* Decrement the blockSize loop counter */
    00386     blkCnt--;
    00387   }
    00388
    00389 #endif /*   #ifndef ARM_MATH_CM0 */
    00390
    00391 }
    00392

All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines