CMSIS DSP Library from CMSIS 2.0. See http://www.onarm.com/cmsis/ for full details

Dependents:   K22F_DSP_Matrix_least_square BNO055-ELEC3810 1BNO055 ECE4180Project--Slave2 ... more

Committer:
simon
Date:
Thu Mar 10 15:07:50 2011 +0000
Revision:
0:1014af42efd9

        

Who changed what in which revision?

UserRevisionLine numberNew contents of line
simon 0:1014af42efd9 1 /* ----------------------------------------------------------------------
simon 0:1014af42efd9 2 * Copyright (C) 2010 ARM Limited. All rights reserved.
simon 0:1014af42efd9 3 *
simon 0:1014af42efd9 4 * $Date: 29. November 2010
simon 0:1014af42efd9 5 * $Revision: V1.0.3
simon 0:1014af42efd9 6 *
simon 0:1014af42efd9 7 * Project: CMSIS DSP Library
simon 0:1014af42efd9 8 * Title: arm_fir_decimate_fast_q15.c
simon 0:1014af42efd9 9 *
simon 0:1014af42efd9 10 * Description: Fast Q15 FIR Decimator.
simon 0:1014af42efd9 11 *
simon 0:1014af42efd9 12 * Target Processor: Cortex-M4/Cortex-M3
simon 0:1014af42efd9 13 *
simon 0:1014af42efd9 14 * Version 1.0.3 2010/11/29
simon 0:1014af42efd9 15 * Re-organized the CMSIS folders and updated documentation.
simon 0:1014af42efd9 16 *
simon 0:1014af42efd9 17 * Version 1.0.2 2010/11/11
simon 0:1014af42efd9 18 * Documentation updated.
simon 0:1014af42efd9 19 *
simon 0:1014af42efd9 20 * Version 1.0.1 2010/10/05
simon 0:1014af42efd9 21 * Production release and review comments incorporated.
simon 0:1014af42efd9 22 *
simon 0:1014af42efd9 23 * Version 1.0.0 2010/09/20
simon 0:1014af42efd9 24 * Production release and review comments incorporated.
simon 0:1014af42efd9 25 * -------------------------------------------------------------------- */
simon 0:1014af42efd9 26
simon 0:1014af42efd9 27 #include "arm_math.h"
simon 0:1014af42efd9 28
simon 0:1014af42efd9 29 /**
simon 0:1014af42efd9 30 * @ingroup groupFilters
simon 0:1014af42efd9 31 */
simon 0:1014af42efd9 32
simon 0:1014af42efd9 33 /**
simon 0:1014af42efd9 34 * @addtogroup FIR_decimate
simon 0:1014af42efd9 35 * @{
simon 0:1014af42efd9 36 */
simon 0:1014af42efd9 37
simon 0:1014af42efd9 38 /**
simon 0:1014af42efd9 39 * @brief Processing function for the Q15 FIR decimator (fast variant).
simon 0:1014af42efd9 40 * @param[in] *S points to an instance of the Q15 FIR decimator structure.
simon 0:1014af42efd9 41 * @param[in] *pSrc points to the block of input data.
simon 0:1014af42efd9 42 * @param[out] *pDst points to the block of output data
simon 0:1014af42efd9 43 * @param[in] blockSize number of input samples to process per call.
simon 0:1014af42efd9 44 * @return none
simon 0:1014af42efd9 45 *
simon 0:1014af42efd9 46 * <b>Scaling and Overflow Behavior:</b>
simon 0:1014af42efd9 47 * \par
simon 0:1014af42efd9 48 * This fast version uses a 32-bit accumulator with 2.30 format.
simon 0:1014af42efd9 49 * The accumulator maintains full precision of the intermediate multiplication results but provides only a single guard bit.
simon 0:1014af42efd9 50 * Thus, if the accumulator result overflows it wraps around and distorts the result.
simon 0:1014af42efd9 51 * In order to avoid overflows completely the input signal must be scaled down by log2(numTaps) bits (log2 is read as log to the base 2).
simon 0:1014af42efd9 52 * The 2.30 accumulator is then truncated to 2.15 format and saturated to yield the 1.15 result.
simon 0:1014af42efd9 53 *
simon 0:1014af42efd9 54 * \par
simon 0:1014af42efd9 55 * Refer to the function <code>arm_fir_decimate_q15()</code> for a slower implementation of this function which uses 64-bit accumulation to avoid wrap around distortion.
simon 0:1014af42efd9 56 * Both the slow and the fast versions use the same instance structure.
simon 0:1014af42efd9 57 * Use the function <code>arm_fir_decimate_init_q15()</code> to initialize the filter structure.
simon 0:1014af42efd9 58 */
simon 0:1014af42efd9 59
simon 0:1014af42efd9 60 void arm_fir_decimate_fast_q15(
simon 0:1014af42efd9 61 const arm_fir_decimate_instance_q15 * S,
simon 0:1014af42efd9 62 q15_t * pSrc,
simon 0:1014af42efd9 63 q15_t * pDst,
simon 0:1014af42efd9 64 uint32_t blockSize)
simon 0:1014af42efd9 65 {
simon 0:1014af42efd9 66 q15_t *pState = S->pState; /* State pointer */
simon 0:1014af42efd9 67 q15_t *pCoeffs = S->pCoeffs; /* Coefficient pointer */
simon 0:1014af42efd9 68 q15_t *pStateCurnt; /* Points to the current sample of the state */
simon 0:1014af42efd9 69 q15_t *px; /* Temporary pointer for state buffer */
simon 0:1014af42efd9 70 q15_t *pb; /* Temporary pointer coefficient buffer */
simon 0:1014af42efd9 71 q31_t x0, c0; /* Temporary variables to hold state and coefficient values */
simon 0:1014af42efd9 72 q31_t sum0; /* Accumulators */
simon 0:1014af42efd9 73 uint32_t numTaps = S->numTaps; /* Number of taps */
simon 0:1014af42efd9 74 uint32_t i, blkCnt, tapCnt, outBlockSize = blockSize / S->M; /* Loop counters */
simon 0:1014af42efd9 75
simon 0:1014af42efd9 76
simon 0:1014af42efd9 77 /* S->pState buffer contains previous frame (numTaps - 1) samples */
simon 0:1014af42efd9 78 /* pStateCurnt points to the location where the new input data should be written */
simon 0:1014af42efd9 79 pStateCurnt = S->pState + (numTaps - 1u);
simon 0:1014af42efd9 80
simon 0:1014af42efd9 81 /* Total number of output samples to be computed */
simon 0:1014af42efd9 82 blkCnt = outBlockSize;
simon 0:1014af42efd9 83
simon 0:1014af42efd9 84 while(blkCnt > 0u)
simon 0:1014af42efd9 85 {
simon 0:1014af42efd9 86 /* Copy decimation factor number of new input samples into the state buffer */
simon 0:1014af42efd9 87 i = S->M;
simon 0:1014af42efd9 88
simon 0:1014af42efd9 89 do
simon 0:1014af42efd9 90 {
simon 0:1014af42efd9 91 *pStateCurnt++ = *pSrc++;
simon 0:1014af42efd9 92
simon 0:1014af42efd9 93 } while(--i);
simon 0:1014af42efd9 94
simon 0:1014af42efd9 95 /*Set sum to zero */
simon 0:1014af42efd9 96 sum0 = 0;
simon 0:1014af42efd9 97
simon 0:1014af42efd9 98 /* Initialize state pointer */
simon 0:1014af42efd9 99 px = pState;
simon 0:1014af42efd9 100
simon 0:1014af42efd9 101 /* Initialize coeff pointer */
simon 0:1014af42efd9 102 pb = pCoeffs;
simon 0:1014af42efd9 103
simon 0:1014af42efd9 104 /* Loop unrolling. Process 4 taps at a time. */
simon 0:1014af42efd9 105 tapCnt = numTaps >> 2;
simon 0:1014af42efd9 106
simon 0:1014af42efd9 107 /* Loop over the number of taps. Unroll by a factor of 4.
simon 0:1014af42efd9 108 ** Repeat until we've computed numTaps-4 coefficients. */
simon 0:1014af42efd9 109 while(tapCnt > 0u)
simon 0:1014af42efd9 110 {
simon 0:1014af42efd9 111 /* Read the Read b[numTaps-1] and b[numTaps-2] coefficients */
simon 0:1014af42efd9 112 c0 = *__SIMD32(pb)++;
simon 0:1014af42efd9 113
simon 0:1014af42efd9 114 /* Read x[n-numTaps-1] and x[n-numTaps-2]sample */
simon 0:1014af42efd9 115 x0 = *__SIMD32(px)++;
simon 0:1014af42efd9 116
simon 0:1014af42efd9 117 /* Perform the multiply-accumulate */
simon 0:1014af42efd9 118 sum0 = __SMLAD(x0, c0, sum0);
simon 0:1014af42efd9 119
simon 0:1014af42efd9 120 /* Read the b[numTaps-3] and b[numTaps-4] coefficient */
simon 0:1014af42efd9 121 c0 = *__SIMD32(pb)++;
simon 0:1014af42efd9 122
simon 0:1014af42efd9 123 /* Read x[n-numTaps-2] and x[n-numTaps-3] sample */
simon 0:1014af42efd9 124 x0 = *__SIMD32(px)++;
simon 0:1014af42efd9 125
simon 0:1014af42efd9 126 /* Perform the multiply-accumulate */
simon 0:1014af42efd9 127 sum0 = __SMLAD(x0, c0, sum0);
simon 0:1014af42efd9 128
simon 0:1014af42efd9 129 /* Decrement the loop counter */
simon 0:1014af42efd9 130 tapCnt--;
simon 0:1014af42efd9 131 }
simon 0:1014af42efd9 132
simon 0:1014af42efd9 133 /* If the filter length is not a multiple of 4, compute the remaining filter taps */
simon 0:1014af42efd9 134 tapCnt = numTaps % 0x4u;
simon 0:1014af42efd9 135
simon 0:1014af42efd9 136 while(tapCnt > 0u)
simon 0:1014af42efd9 137 {
simon 0:1014af42efd9 138 /* Read coefficients */
simon 0:1014af42efd9 139 c0 = *pb++;
simon 0:1014af42efd9 140
simon 0:1014af42efd9 141 /* Fetch 1 state variable */
simon 0:1014af42efd9 142 x0 = *px++;
simon 0:1014af42efd9 143
simon 0:1014af42efd9 144 /* Perform the multiply-accumulate */
simon 0:1014af42efd9 145 sum0 = __SMLAD(x0, c0, sum0);
simon 0:1014af42efd9 146
simon 0:1014af42efd9 147 /* Decrement the loop counter */
simon 0:1014af42efd9 148 tapCnt--;
simon 0:1014af42efd9 149 }
simon 0:1014af42efd9 150
simon 0:1014af42efd9 151 /* Advance the state pointer by the decimation factor
simon 0:1014af42efd9 152 * to process the next group of decimation factor number samples */
simon 0:1014af42efd9 153 pState = pState + S->M;
simon 0:1014af42efd9 154
simon 0:1014af42efd9 155 /* Store filter output , smlad returns the values in 2.14 format */
simon 0:1014af42efd9 156 /* so downsacle by 15 to get output in 1.15 */
simon 0:1014af42efd9 157 *pDst++ = (q15_t) ((sum0 >> 15));
simon 0:1014af42efd9 158
simon 0:1014af42efd9 159 /* Decrement the loop counter */
simon 0:1014af42efd9 160 blkCnt--;
simon 0:1014af42efd9 161 }
simon 0:1014af42efd9 162
simon 0:1014af42efd9 163 /* Processing is complete.
simon 0:1014af42efd9 164 ** Now copy the last numTaps - 1 samples to the satrt of the state buffer.
simon 0:1014af42efd9 165 ** This prepares the state buffer for the next function call. */
simon 0:1014af42efd9 166
simon 0:1014af42efd9 167 /* Points to the start of the state buffer */
simon 0:1014af42efd9 168 pStateCurnt = S->pState;
simon 0:1014af42efd9 169
simon 0:1014af42efd9 170 i = (numTaps - 1u) >> 2u;
simon 0:1014af42efd9 171
simon 0:1014af42efd9 172 /* copy data */
simon 0:1014af42efd9 173 while(i > 0u)
simon 0:1014af42efd9 174 {
simon 0:1014af42efd9 175 *__SIMD32(pStateCurnt)++ = *__SIMD32(pState)++;
simon 0:1014af42efd9 176 *__SIMD32(pStateCurnt)++ = *__SIMD32(pState)++;
simon 0:1014af42efd9 177
simon 0:1014af42efd9 178 /* Decrement the loop counter */
simon 0:1014af42efd9 179 i--;
simon 0:1014af42efd9 180 }
simon 0:1014af42efd9 181
simon 0:1014af42efd9 182 i = (numTaps - 1u) % 0x04u;
simon 0:1014af42efd9 183
simon 0:1014af42efd9 184 /* copy data */
simon 0:1014af42efd9 185 while(i > 0u)
simon 0:1014af42efd9 186 {
simon 0:1014af42efd9 187 *pStateCurnt++ = *pState++;
simon 0:1014af42efd9 188
simon 0:1014af42efd9 189 /* Decrement the loop counter */
simon 0:1014af42efd9 190 i--;
simon 0:1014af42efd9 191 }
simon 0:1014af42efd9 192 }
simon 0:1014af42efd9 193
simon 0:1014af42efd9 194 /**
simon 0:1014af42efd9 195 * @} end of FIR_decimate group
simon 0:1014af42efd9 196 */