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_q31.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_q31.c 00009 * 00010 * Description: Q31 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 Q31 FIR decimator. 00043 * @param[in] *S points to an instance of the Q31 FIR decimator structure. 00044 * @param[in] *pSrc points to the block of input data. 00045 * @param[out] *pDst points to the block of output data 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 an internal 64-bit accumulator. 00052 * The accumulator has a 2.62 format and maintains full precision of the intermediate multiplication results but provides only a single guard bit. 00053 * Thus, if the accumulator result overflows it wraps around rather than clip. 00054 * In order to avoid overflows completely the input signal must be scaled down by log2(numTaps) bits (where log2 is read as log to the base 2). 00055 * After all multiply-accumulates are performed, the 2.62 accumulator is truncated to 1.32 format and then saturated to 1.31 format. 00056 * 00057 * \par 00058 * Refer to the function <code>arm_fir_decimate_fast_q31()</code> for a faster but less precise implementation of this function. 00059 */ 00060 00061 void arm_fir_decimate_q31( 00062 const arm_fir_decimate_instance_q31 * S, 00063 q31_t * pSrc, 00064 q31_t * pDst, 00065 uint32_t blockSize) 00066 { 00067 q31_t *pState = S->pState; /* State pointer */ 00068 q31_t *pCoeffs = S->pCoeffs; /* Coefficient pointer */ 00069 q31_t *pStateCurnt; /* Points to the current sample of the state */ 00070 q31_t x0, c0; /* Temporary variables to hold state and coefficient values */ 00071 q31_t *px; /* Temporary pointers for state buffer */ 00072 q31_t *pb; /* Temporary pointers for coefficient buffer */ 00073 q63_t sum0; /* Accumulator */ 00074 uint32_t numTaps = S->numTaps; /* Number of taps */ 00075 uint32_t i, tapCnt, blkCnt, outBlockSize = blockSize / S->M; /* Loop counters */ 00076 00077 00078 /* S->pState buffer contains previous frame (numTaps - 1) samples */ 00079 /* pStateCurnt points to the location where the new input data should be written */ 00080 pStateCurnt = S->pState + (numTaps - 1u); 00081 00082 /* Total number of output samples to be computed */ 00083 blkCnt = outBlockSize; 00084 00085 while(blkCnt > 0u) 00086 { 00087 /* Copy decimation factor number of new input samples into the state buffer */ 00088 i = S->M; 00089 00090 do 00091 { 00092 *pStateCurnt++ = *pSrc++; 00093 00094 } while(--i); 00095 00096 /* Set accumulator to zero */ 00097 sum0 = 0; 00098 00099 /* Initialize state pointer */ 00100 px = pState; 00101 00102 /* Initialize coeff pointer */ 00103 pb = pCoeffs; 00104 00105 /* Loop unrolling. Process 4 taps at a time. */ 00106 tapCnt = numTaps >> 2; 00107 00108 /* Loop over the number of taps. Unroll by a factor of 4. 00109 ** Repeat until we've computed numTaps-4 coefficients. */ 00110 while(tapCnt > 0u) 00111 { 00112 /* Read the b[numTaps-1] coefficient */ 00113 c0 = *(pb++); 00114 00115 /* Read x[n-numTaps-1] sample */ 00116 x0 = *(px++); 00117 00118 /* Perform the multiply-accumulate */ 00119 sum0 += (q63_t) x0 *c0; 00120 00121 /* Read the b[numTaps-2] coefficient */ 00122 c0 = *(pb++); 00123 00124 /* Read x[n-numTaps-2] sample */ 00125 x0 = *(px++); 00126 00127 /* Perform the multiply-accumulate */ 00128 sum0 += (q63_t) x0 *c0; 00129 00130 /* Read the b[numTaps-3] coefficient */ 00131 c0 = *(pb++); 00132 00133 /* Read x[n-numTaps-3] sample */ 00134 x0 = *(px++); 00135 00136 /* Perform the multiply-accumulate */ 00137 sum0 += (q63_t) x0 *c0; 00138 00139 /* Read the b[numTaps-4] coefficient */ 00140 c0 = *(pb++); 00141 00142 /* Read x[n-numTaps-4] sample */ 00143 x0 = *(px++); 00144 00145 /* Perform the multiply-accumulate */ 00146 sum0 += (q63_t) x0 *c0; 00147 00148 /* Decrement the loop counter */ 00149 tapCnt--; 00150 } 00151 00152 /* If the filter length is not a multiple of 4, compute the remaining filter taps */ 00153 tapCnt = numTaps % 0x4u; 00154 00155 while(tapCnt > 0u) 00156 { 00157 /* Read coefficients */ 00158 c0 = *(pb++); 00159 00160 /* Fetch 1 state variable */ 00161 x0 = *(px++); 00162 00163 /* Perform the multiply-accumulate */ 00164 sum0 += (q63_t) x0 *c0; 00165 00166 /* Decrement the loop counter */ 00167 tapCnt--; 00168 } 00169 00170 /* Advance the state pointer by the decimation factor 00171 * to process the next group of decimation factor number samples */ 00172 pState = pState + S->M; 00173 00174 /* The result is in the accumulator, store in the destination buffer. */ 00175 *pDst++ = (q31_t) (sum0 >> 31); 00176 00177 /* Decrement the loop counter */ 00178 blkCnt--; 00179 } 00180 00181 /* Processing is complete. 00182 ** Now copy the last numTaps - 1 samples to the satrt of the state buffer. 00183 ** This prepares the state buffer for the next function call. */ 00184 00185 /* Points to the start of the state buffer */ 00186 pStateCurnt = S->pState; 00187 00188 i = (numTaps - 1u) >> 2u; 00189 00190 /* copy data */ 00191 while(i > 0u) 00192 { 00193 *pStateCurnt++ = *pState++; 00194 *pStateCurnt++ = *pState++; 00195 *pStateCurnt++ = *pState++; 00196 *pStateCurnt++ = *pState++; 00197 00198 /* Decrement the loop counter */ 00199 i--; 00200 } 00201 00202 i = (numTaps - 1u) % 0x04u; 00203 00204 /* copy data */ 00205 while(i > 0u) 00206 { 00207 *pStateCurnt++ = *pState++; 00208 00209 /* Decrement the loop counter */ 00210 i--; 00211 } 00212 } 00213 00214 /** 00215 * @} end of FIR_decimate group 00216 */
Generated on Tue Jul 12 2022 19:55:43 by
1.7.2
