Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of dsp by
arm_fir_decimate_q15.c
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_fir_decimate_q15.c 00009 * 00010 * Description: Q15 FIR Decimator. 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 00032 /** 00033 * @ingroup groupFilters 00034 */ 00035 00036 /** 00037 * @addtogroup FIR_decimate 00038 * @{ 00039 */ 00040 00041 /** 00042 * @brief Processing function for the Q15 FIR decimator. 00043 * @param[in] *S points to an instance of the Q15 FIR decimator structure. 00044 * @param[in] *pSrc points to the block of input data. 00045 * @param[out] *pDst points to the location where the output result is written. 00046 * @param[in] blockSize number of input samples to process per call. 00047 * @return none. 00048 * 00049 * <b>Scaling and Overflow Behavior:</b> 00050 * \par 00051 * The function is implemented using a 64-bit internal accumulator. 00052 * Both coefficients and state variables are represented in 1.15 format and multiplications yield a 2.30 result. 00053 * The 2.30 intermediate results are accumulated in a 64-bit accumulator in 34.30 format. 00054 * There is no risk of internal overflow with this approach and the full precision of intermediate multiplications is preserved. 00055 * After all additions have been performed, the accumulator is truncated to 34.15 format by discarding low 15 bits. 00056 * Lastly, the accumulator is saturated to yield a result in 1.15 format. 00057 * 00058 * \par 00059 * Refer to the function <code>arm_fir_decimate_fast_q15()</code> for a faster but less precise implementation of this function. 00060 */ 00061 00062 void arm_fir_decimate_q15( 00063 const arm_fir_decimate_instance_q15 * S, 00064 q15_t * pSrc, 00065 q15_t * pDst, 00066 uint32_t blockSize) 00067 { 00068 q15_t *pState = S->pState; /* State pointer */ 00069 q15_t *pCoeffs = S->pCoeffs; /* Coefficient pointer */ 00070 q15_t *pStateCurnt; /* Points to the current sample of the state */ 00071 q15_t *px; /* Temporary pointer for state buffer */ 00072 q15_t *pb; /* Temporary pointer coefficient buffer */ 00073 q31_t x0, c0; /* Temporary variables to hold state and coefficient values */ 00074 q63_t sum0; /* Accumulators */ 00075 uint32_t numTaps = S->numTaps; /* Number of taps */ 00076 uint32_t i, blkCnt, tapCnt, outBlockSize = blockSize / S->M; /* Loop counters */ 00077 00078 00079 /* S->pState buffer contains previous frame (numTaps - 1) samples */ 00080 /* pStateCurnt points to the location where the new input data should be written */ 00081 pStateCurnt = S->pState + (numTaps - 1u); 00082 00083 /* Total number of output samples to be computed */ 00084 blkCnt = outBlockSize; 00085 00086 while(blkCnt > 0u) 00087 { 00088 /* Copy decimation factor number of new input samples into the state buffer */ 00089 i = S->M; 00090 00091 do 00092 { 00093 *pStateCurnt++ = *pSrc++; 00094 00095 } while(--i); 00096 00097 /*Set sum to zero */ 00098 sum0 = 0; 00099 00100 /* Initialize state pointer */ 00101 px = pState; 00102 00103 /* Initialize coeff pointer */ 00104 pb = pCoeffs; 00105 00106 /* Loop unrolling. Process 4 taps at a time. */ 00107 tapCnt = numTaps >> 2; 00108 00109 /* Loop over the number of taps. Unroll by a factor of 4. 00110 ** Repeat until we've computed numTaps-4 coefficients. */ 00111 while(tapCnt > 0u) 00112 { 00113 /* Read the Read b[numTaps-1] and b[numTaps-2] coefficients */ 00114 c0 = *__SIMD32(pb)++; 00115 00116 /* Read x[n-numTaps-1] and x[n-numTaps-2]sample */ 00117 x0 = *__SIMD32(px)++; 00118 00119 /* Perform the multiply-accumulate */ 00120 sum0 = __SMLALD(x0, c0, sum0); 00121 00122 /* Read the b[numTaps-3] and b[numTaps-4] coefficient */ 00123 c0 = *__SIMD32(pb)++; 00124 00125 /* Read x[n-numTaps-2] and x[n-numTaps-3] sample */ 00126 x0 = *__SIMD32(px)++; 00127 00128 /* Perform the multiply-accumulate */ 00129 sum0 = __SMLALD(x0, c0, sum0); 00130 00131 /* Decrement the loop counter */ 00132 tapCnt--; 00133 } 00134 00135 /* If the filter length is not a multiple of 4, compute the remaining filter taps */ 00136 tapCnt = numTaps % 0x4u; 00137 00138 while(tapCnt > 0u) 00139 { 00140 /* Read coefficients */ 00141 c0 = *pb++; 00142 00143 /* Fetch 1 state variable */ 00144 x0 = *px++; 00145 00146 /* Perform the multiply-accumulate */ 00147 sum0 = __SMLALD(x0, c0, sum0); 00148 00149 /* Decrement the loop counter */ 00150 tapCnt--; 00151 } 00152 00153 /* Advance the state pointer by the decimation factor 00154 * to process the next group of decimation factor number samples */ 00155 pState = pState + S->M; 00156 00157 /* Store filter output, smlad returns the values in 2.14 format */ 00158 /* so downsacle by 15 to get output in 1.15 */ 00159 *pDst++ = (q15_t) (__SSAT((sum0 >> 15), 16)); 00160 00161 /* Decrement the loop counter */ 00162 blkCnt--; 00163 } 00164 00165 /* Processing is complete. 00166 ** Now copy the last numTaps - 1 samples to the satrt of the state buffer. 00167 ** This prepares the state buffer for the next function call. */ 00168 00169 /* Points to the start of the state buffer */ 00170 pStateCurnt = S->pState; 00171 00172 i = (numTaps - 1u) >> 2u; 00173 00174 /* copy data */ 00175 while(i > 0u) 00176 { 00177 *__SIMD32(pStateCurnt)++ = *__SIMD32(pState)++; 00178 *__SIMD32(pStateCurnt)++ = *__SIMD32(pState)++; 00179 00180 /* Decrement the loop counter */ 00181 i--; 00182 } 00183 00184 i = (numTaps - 1u) % 0x04u; 00185 00186 /* copy data */ 00187 while(i > 0u) 00188 { 00189 *pStateCurnt++ = *pState++; 00190 00191 /* Decrement the loop counter */ 00192 i--; 00193 } 00194 } 00195 00196 /** 00197 * @} end of FIR_decimate group 00198 */
Generated on Tue Jul 12 2022 19:55:43 by
1.7.2
