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

- File List
- Globals

# arm_fir_sparse_q15.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_q15.c
    00009 *
    00010 * Description:  Q15 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
    00060 void arm_fir_sparse_q15(
    00061   arm_fir_sparse_instance_q15 * S,
    00062   q15_t * pSrc,
    00063   q15_t * pDst,
    00064   q15_t * pScratchIn,
    00065   q31_t * pScratchOut,
    00066   uint32_t blockSize)
    00067 {
    00068
    00069   q15_t *pState = S->pState;                     /* State pointer */
    00070   q15_t *pIn = pSrc;                             /* Working pointer for input */
    00071   q15_t *pOut = pDst;                            /* Working pointer for output */
    00072   q15_t *pCoeffs = S->pCoeffs;                   /* Coefficient pointer */
    00073   q15_t *px;                                     /* Temporary pointers for scratch buffer */
    00074   q15_t *pb = pScratchIn;                        /* Temporary pointers for scratch buffer */
    00075   q15_t *py = pState;                            /* Temporary pointers for state buffer */
    00076   int32_t *pTapDelay = S->pTapDelay;             /* Pointer to the array containing offset of the non-zero tap values. */
    00077   uint32_t delaySize = S->maxDelay + blockSize;  /* state length */
    00078   uint16_t numTaps = S->numTaps;                 /* Filter order */
    00079   int32_t readIndex;                             /* Read index of the state buffer */
    00080   uint32_t tapCnt, blkCnt;                       /* loop counters */
    00081   q15_t coeff = *pCoeffs++;                      /* Read the first coefficient value */
    00082   q31_t *pScr2 = pScratchOut;                    /* Working pointer for pScratchOut */
    00083
    00084
    00085 #ifndef ARM_MATH_CM0
    00086
    00087   /* Run the below code for Cortex-M4 and Cortex-M3 */
    00088
    00089   q31_t in1, in2;                                /* Temporary variables */
    00090
    00091
    00092   /* BlockSize of Input samples are copied into the state buffer */
    00093   /* StateIndex points to the starting position to write in the state buffer */
    00094   arm_circularWrite_q15(py, delaySize, &S->stateIndex, 1, pIn, 1, blockSize);
    00095
    00096   /* Loop over the number of taps. */
    00097   tapCnt = numTaps;
    00098
    00099   /* Read Index, from where the state buffer should be read, is calculated. */
    00100   readIndex = (S->stateIndex - blockSize) - *pTapDelay++;
    00101
    00102   /* Wraparound of readIndex */
    00103   if(readIndex < 0)
    00104   {
    00105     readIndex += (int32_t) delaySize;
    00106   }
    00107
    00108   /* Working pointer for state buffer is updated */
    00109   py = pState;
    00110
    00111   /* blockSize samples are read from the state buffer */
    00112   arm_circularRead_q15(py, delaySize, &readIndex, 1,
    00113                        pb, pb, blockSize, 1, blockSize);
    00114
    00115   /* Working pointer for the scratch buffer of state values */
    00116   px = pb;
    00117
    00118   /* Working pointer for scratch buffer of output values */
    00119   pScratchOut = pScr2;
    00120
    00121   /* Loop over the blockSize. Unroll by a factor of 4.
    00122    * Compute 4 multiplications at a time. */
    00123   blkCnt = blockSize >> 2;
    00124
    00125   while(blkCnt > 0u)
    00126   {
    00127     /* Perform multiplication and store in the scratch buffer */
    00128     *pScratchOut++ = ((q31_t) * px++ * coeff);
    00129     *pScratchOut++ = ((q31_t) * px++ * coeff);
    00130     *pScratchOut++ = ((q31_t) * px++ * coeff);
    00131     *pScratchOut++ = ((q31_t) * px++ * coeff);
    00132
    00133     /* Decrement the loop counter */
    00134     blkCnt--;
    00135   }
    00136
    00137   /* If the blockSize is not a multiple of 4,
    00138    * compute the remaining samples */
    00139   blkCnt = blockSize % 0x4u;
    00140
    00141   while(blkCnt > 0u)
    00142   {
    00143     /* Perform multiplication and store in the scratch buffer */
    00144     *pScratchOut++ = ((q31_t) * px++ * coeff);
    00145
    00146     /* Decrement the loop counter */
    00147     blkCnt--;
    00148   }
    00149
    00150   /* Load the coefficient value and
    00151    * increment the coefficient buffer for the next set of state values */
    00152   coeff = *pCoeffs++;
    00153
    00154   /* Read Index, from where the state buffer should be read, is calculated. */
    00155   readIndex = (S->stateIndex - blockSize) - *pTapDelay++;
    00156
    00157   /* Wraparound of readIndex */
    00158   if(readIndex < 0)
    00159   {
    00160     readIndex += (int32_t) delaySize;
    00161   }
    00162
    00163   /* Loop over the number of taps. */
    00164   tapCnt = (uint32_t) numTaps - 1u;
    00165
    00166   while(tapCnt > 0u)
    00167   {
    00168     /* Working pointer for state buffer is updated */
    00169     py = pState;
    00170
    00171     /* blockSize samples are read from the state buffer */
    00172     arm_circularRead_q15(py, delaySize, &readIndex, 1,
    00173                          pb, pb, blockSize, 1, blockSize);
    00174
    00175     /* Working pointer for the scratch buffer of state values */
    00176     px = pb;
    00177
    00178     /* Working pointer for scratch buffer of output values */
    00179     pScratchOut = pScr2;
    00180
    00181     /* Loop over the blockSize. Unroll by a factor of 4.
    00182      * Compute 4 MACS at a time. */
    00183     blkCnt = blockSize >> 2;
    00184
    00185     while(blkCnt > 0u)
    00186     {
    00187       /* Perform Multiply-Accumulate */
    00188       *pScratchOut++ += (q31_t) * px++ * coeff;
    00189       *pScratchOut++ += (q31_t) * px++ * coeff;
    00190       *pScratchOut++ += (q31_t) * px++ * coeff;
    00191       *pScratchOut++ += (q31_t) * px++ * coeff;
    00192
    00193       /* Decrement the loop counter */
    00194       blkCnt--;
    00195     }
    00196
    00197     /* If the blockSize is not a multiple of 4,
    00198      * compute the remaining samples */
    00199     blkCnt = blockSize % 0x4u;
    00200
    00201     while(blkCnt > 0u)
    00202     {
    00203       /* Perform Multiply-Accumulate */
    00204       *pScratchOut++ += (q31_t) * px++ * coeff;
    00205
    00206       /* Decrement the loop counter */
    00207       blkCnt--;
    00208     }
    00209
    00210     /* Load the coefficient value and
    00211      * increment the coefficient buffer for the next set of state values */
    00212     coeff = *pCoeffs++;
    00213
    00214     /* Read Index, from where the state buffer should be read, is calculated. */
    00215     readIndex = (S->stateIndex - blockSize) - *pTapDelay++;
    00216
    00217     /* Wraparound of readIndex */
    00218     if(readIndex < 0)
    00219     {
    00220       readIndex += (int32_t) delaySize;
    00221     }
    00222
    00223     /* Decrement the tap loop counter */
    00224     tapCnt--;
    00225   }
    00226
    00227   /* All the output values are in pScratchOut buffer.
    00228      Convert them into 1.15 format, saturate and store in the destination buffer. */
    00229   /* Loop over the blockSize. */
    00230   blkCnt = blockSize >> 2;
    00231
    00232   while(blkCnt > 0u)
    00233   {
    00234     in1 = *pScr2++;
    00235     in2 = *pScr2++;
    00236
    00237 #ifndef  ARM_MATH_BIG_ENDIAN
    00238
    00239     *__SIMD32(pOut)++ =
    00240       __PKHBT((q15_t) __SSAT(in1 >> 15, 16), (q15_t) __SSAT(in2 >> 15, 16),
    00241               16);
    00242
    00243 #else
    00244     *__SIMD32(pOut)++ =
    00245       __PKHBT((q15_t) __SSAT(in2 >> 15, 16), (q15_t) __SSAT(in1 >> 15, 16),
    00246               16);
    00247
    00248 #endif /*      #ifndef  ARM_MATH_BIG_ENDIAN    */
    00249
    00250     in1 = *pScr2++;
    00251
    00252     in2 = *pScr2++;
    00253
    00254 #ifndef  ARM_MATH_BIG_ENDIAN
    00255
    00256     *__SIMD32(pOut)++ =
    00257       __PKHBT((q15_t) __SSAT(in1 >> 15, 16), (q15_t) __SSAT(in2 >> 15, 16),
    00258               16);
    00259
    00260 #else
    00261
    00262     *__SIMD32(pOut)++ =
    00263       __PKHBT((q15_t) __SSAT(in2 >> 15, 16), (q15_t) __SSAT(in1 >> 15, 16),
    00264               16);
    00265
    00266 #endif /*      #ifndef  ARM_MATH_BIG_ENDIAN    */
    00267
    00268
    00269     blkCnt--;
    00270
    00271   }
    00272
    00273   /* If the blockSize is not a multiple of 4,
    00274      remaining samples are processed in the below loop */
    00275   blkCnt = blockSize % 0x4u;
    00276
    00277   while(blkCnt > 0u)
    00278   {
    00279     *pOut++ = (q15_t) __SSAT(*pScr2++ >> 15, 16);
    00280     blkCnt--;
    00281   }
    00282
    00283 #else
    00284
    00285   /* Run the below code for Cortex-M0 */
    00286
    00287   /* BlockSize of Input samples are copied into the state buffer */
    00288   /* StateIndex points to the starting position to write in the state buffer */
    00289   arm_circularWrite_q15(py, delaySize, &S->stateIndex, 1, pIn, 1, blockSize);
    00290
    00291   /* Loop over the number of taps. */
    00292   tapCnt = numTaps;
    00293
    00294   /* Read Index, from where the state buffer should be read, is calculated. */
    00295   readIndex = (S->stateIndex - blockSize) - *pTapDelay++;
    00296
    00297   /* Wraparound of readIndex */
    00298   if(readIndex < 0)
    00299   {
    00300     readIndex += (int32_t) delaySize;
    00301   }
    00302
    00303   /* Working pointer for state buffer is updated */
    00304   py = pState;
    00305
    00306   /* blockSize samples are read from the state buffer */
    00307   arm_circularRead_q15(py, delaySize, &readIndex, 1,
    00308                        pb, pb, blockSize, 1, blockSize);
    00309
    00310   /* Working pointer for the scratch buffer of state values */
    00311   px = pb;
    00312
    00313   /* Working pointer for scratch buffer of output values */
    00314   pScratchOut = pScr2;
    00315
    00316   blkCnt = blockSize;
    00317
    00318   while(blkCnt > 0u)
    00319   {
    00320     /* Perform multiplication and store in the scratch buffer */
    00321     *pScratchOut++ = ((q31_t) * px++ * coeff);
    00322
    00323     /* Decrement the loop counter */
    00324     blkCnt--;
    00325   }
    00326
    00327   /* Load the coefficient value and
    00328    * increment the coefficient buffer for the next set of state values */
    00329   coeff = *pCoeffs++;
    00330
    00331   /* Read Index, from where the state buffer should be read, is calculated. */
    00332   readIndex = (S->stateIndex - blockSize) - *pTapDelay++;
    00333
    00334   /* Wraparound of readIndex */
    00335   if(readIndex < 0)
    00336   {
    00337     readIndex += (int32_t) delaySize;
    00338   }
    00339
    00340   /* Loop over the number of taps. */
    00341   tapCnt = (uint32_t) numTaps - 1u;
    00342
    00343   while(tapCnt > 0u)
    00344   {
    00345     /* Working pointer for state buffer is updated */
    00346     py = pState;
    00347
    00348     /* blockSize samples are read from the state buffer */
    00349     arm_circularRead_q15(py, delaySize, &readIndex, 1,
    00350                          pb, pb, blockSize, 1, blockSize);
    00351
    00352     /* Working pointer for the scratch buffer of state values */
    00353     px = pb;
    00354
    00355     /* Working pointer for scratch buffer of output values */
    00356     pScratchOut = pScr2;
    00357
    00358     blkCnt = blockSize;
    00359
    00360     while(blkCnt > 0u)
    00361     {
    00362       /* Perform Multiply-Accumulate */
    00363       *pScratchOut++ += (q31_t) * px++ * coeff;
    00364
    00365       /* Decrement the loop counter */
    00366       blkCnt--;
    00367     }
    00368
    00369     /* Load the coefficient value and
    00370      * increment the coefficient buffer for the next set of state values */
    00371     coeff = *pCoeffs++;
    00372
    00373     /* Read Index, from where the state buffer should be read, is calculated. */
    00374     readIndex = (S->stateIndex - blockSize) - *pTapDelay++;
    00375
    00376     /* Wraparound of readIndex */
    00377     if(readIndex < 0)
    00378     {
    00379       readIndex += (int32_t) delaySize;
    00380     }
    00381
    00382     /* Decrement the tap loop counter */
    00383     tapCnt--;
    00384   }
    00385
    00386   /* All the output values are in pScratchOut buffer.
    00387      Convert them into 1.15 format, saturate and store in the destination buffer. */
    00388   /* Loop over the blockSize. */
    00389   blkCnt = blockSize;
    00390
    00391   while(blkCnt > 0u)
    00392   {
    00393     *pOut++ = (q15_t) __SSAT(*pScr2++ >> 15, 16);
    00394     blkCnt--;
    00395   }
    00396
    00397 #endif /*   #ifndef ARM_MATH_CM0 */
    00398
    00399 }
    00400

All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines