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 mbed-dsp by
arm_fir_decimate_q31.c
00001 /* ---------------------------------------------------------------------- 00002 * Copyright (C) 2010-2013 ARM Limited. All rights reserved. 00003 * 00004 * $Date: 17. January 2013 00005 * $Revision: V1.4.1 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/Cortex-M0 00013 * 00014 * Redistribution and use in source and binary forms, with or without 00015 * modification, are permitted provided that the following conditions 00016 * are met: 00017 * - Redistributions of source code must retain the above copyright 00018 * notice, this list of conditions and the following disclaimer. 00019 * - Redistributions in binary form must reproduce the above copyright 00020 * notice, this list of conditions and the following disclaimer in 00021 * the documentation and/or other materials provided with the 00022 * distribution. 00023 * - Neither the name of ARM LIMITED nor the names of its contributors 00024 * may be used to endorse or promote products derived from this 00025 * software without specific prior written permission. 00026 * 00027 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 00028 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 00029 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 00030 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 00031 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 00032 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 00033 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 00034 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 00035 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 00036 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 00037 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 00038 * POSSIBILITY OF SUCH DAMAGE. 00039 * -------------------------------------------------------------------- */ 00040 00041 #include "arm_math.h" 00042 00043 /** 00044 * @ingroup groupFilters 00045 */ 00046 00047 /** 00048 * @addtogroup FIR_decimate 00049 * @{ 00050 */ 00051 00052 /** 00053 * @brief Processing function for the Q31 FIR decimator. 00054 * @param[in] *S points to an instance of the Q31 FIR decimator structure. 00055 * @param[in] *pSrc points to the block of input data. 00056 * @param[out] *pDst points to the block of output data 00057 * @param[in] blockSize number of input samples to process per call. 00058 * @return none 00059 * 00060 * <b>Scaling and Overflow Behavior:</b> 00061 * \par 00062 * The function is implemented using an internal 64-bit accumulator. 00063 * The accumulator has a 2.62 format and maintains full precision of the intermediate multiplication results but provides only a single guard bit. 00064 * Thus, if the accumulator result overflows it wraps around rather than clip. 00065 * 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). 00066 * After all multiply-accumulates are performed, the 2.62 accumulator is truncated to 1.32 format and then saturated to 1.31 format. 00067 * 00068 * \par 00069 * Refer to the function <code>arm_fir_decimate_fast_q31()</code> for a faster but less precise implementation of this function for Cortex-M3 and Cortex-M4. 00070 */ 00071 00072 void arm_fir_decimate_q31( 00073 const arm_fir_decimate_instance_q31 * S, 00074 q31_t * pSrc, 00075 q31_t * pDst, 00076 uint32_t blockSize) 00077 { 00078 q31_t *pState = S->pState; /* State pointer */ 00079 q31_t *pCoeffs = S->pCoeffs; /* Coefficient pointer */ 00080 q31_t *pStateCurnt; /* Points to the current sample of the state */ 00081 q31_t x0, c0; /* Temporary variables to hold state and coefficient values */ 00082 q31_t *px; /* Temporary pointers for state buffer */ 00083 q31_t *pb; /* Temporary pointers for coefficient buffer */ 00084 q63_t sum0; /* Accumulator */ 00085 uint32_t numTaps = S->numTaps; /* Number of taps */ 00086 uint32_t i, tapCnt, blkCnt, outBlockSize = blockSize / S->M; /* Loop counters */ 00087 00088 00089 #ifndef ARM_MATH_CM0_FAMILY 00090 00091 /* Run the below code for Cortex-M4 and Cortex-M3 */ 00092 00093 /* S->pState buffer contains previous frame (numTaps - 1) samples */ 00094 /* pStateCurnt points to the location where the new input data should be written */ 00095 pStateCurnt = S->pState + (numTaps - 1u); 00096 00097 /* Total number of output samples to be computed */ 00098 blkCnt = outBlockSize; 00099 00100 while(blkCnt > 0u) 00101 { 00102 /* Copy decimation factor number of new input samples into the state buffer */ 00103 i = S->M; 00104 00105 do 00106 { 00107 *pStateCurnt++ = *pSrc++; 00108 00109 } while(--i); 00110 00111 /* Set accumulator to zero */ 00112 sum0 = 0; 00113 00114 /* Initialize state pointer */ 00115 px = pState; 00116 00117 /* Initialize coeff pointer */ 00118 pb = pCoeffs; 00119 00120 /* Loop unrolling. Process 4 taps at a time. */ 00121 tapCnt = numTaps >> 2; 00122 00123 /* Loop over the number of taps. Unroll by a factor of 4. 00124 ** Repeat until we've computed numTaps-4 coefficients. */ 00125 while(tapCnt > 0u) 00126 { 00127 /* Read the b[numTaps-1] coefficient */ 00128 c0 = *(pb++); 00129 00130 /* Read x[n-numTaps-1] sample */ 00131 x0 = *(px++); 00132 00133 /* Perform the multiply-accumulate */ 00134 sum0 += (q63_t) x0 *c0; 00135 00136 /* Read the b[numTaps-2] coefficient */ 00137 c0 = *(pb++); 00138 00139 /* Read x[n-numTaps-2] sample */ 00140 x0 = *(px++); 00141 00142 /* Perform the multiply-accumulate */ 00143 sum0 += (q63_t) x0 *c0; 00144 00145 /* Read the b[numTaps-3] coefficient */ 00146 c0 = *(pb++); 00147 00148 /* Read x[n-numTaps-3] sample */ 00149 x0 = *(px++); 00150 00151 /* Perform the multiply-accumulate */ 00152 sum0 += (q63_t) x0 *c0; 00153 00154 /* Read the b[numTaps-4] coefficient */ 00155 c0 = *(pb++); 00156 00157 /* Read x[n-numTaps-4] sample */ 00158 x0 = *(px++); 00159 00160 /* Perform the multiply-accumulate */ 00161 sum0 += (q63_t) x0 *c0; 00162 00163 /* Decrement the loop counter */ 00164 tapCnt--; 00165 } 00166 00167 /* If the filter length is not a multiple of 4, compute the remaining filter taps */ 00168 tapCnt = numTaps % 0x4u; 00169 00170 while(tapCnt > 0u) 00171 { 00172 /* Read coefficients */ 00173 c0 = *(pb++); 00174 00175 /* Fetch 1 state variable */ 00176 x0 = *(px++); 00177 00178 /* Perform the multiply-accumulate */ 00179 sum0 += (q63_t) x0 *c0; 00180 00181 /* Decrement the loop counter */ 00182 tapCnt--; 00183 } 00184 00185 /* Advance the state pointer by the decimation factor 00186 * to process the next group of decimation factor number samples */ 00187 pState = pState + S->M; 00188 00189 /* The result is in the accumulator, store in the destination buffer. */ 00190 *pDst++ = (q31_t) (sum0 >> 31); 00191 00192 /* Decrement the loop counter */ 00193 blkCnt--; 00194 } 00195 00196 /* Processing is complete. 00197 ** Now copy the last numTaps - 1 samples to the satrt of the state buffer. 00198 ** This prepares the state buffer for the next function call. */ 00199 00200 /* Points to the start of the state buffer */ 00201 pStateCurnt = S->pState; 00202 00203 i = (numTaps - 1u) >> 2u; 00204 00205 /* copy data */ 00206 while(i > 0u) 00207 { 00208 *pStateCurnt++ = *pState++; 00209 *pStateCurnt++ = *pState++; 00210 *pStateCurnt++ = *pState++; 00211 *pStateCurnt++ = *pState++; 00212 00213 /* Decrement the loop counter */ 00214 i--; 00215 } 00216 00217 i = (numTaps - 1u) % 0x04u; 00218 00219 /* copy data */ 00220 while(i > 0u) 00221 { 00222 *pStateCurnt++ = *pState++; 00223 00224 /* Decrement the loop counter */ 00225 i--; 00226 } 00227 00228 #else 00229 00230 /* Run the below code for Cortex-M0 */ 00231 00232 /* S->pState buffer contains previous frame (numTaps - 1) samples */ 00233 /* pStateCurnt points to the location where the new input data should be written */ 00234 pStateCurnt = S->pState + (numTaps - 1u); 00235 00236 /* Total number of output samples to be computed */ 00237 blkCnt = outBlockSize; 00238 00239 while(blkCnt > 0u) 00240 { 00241 /* Copy decimation factor number of new input samples into the state buffer */ 00242 i = S->M; 00243 00244 do 00245 { 00246 *pStateCurnt++ = *pSrc++; 00247 00248 } while(--i); 00249 00250 /* Set accumulator to zero */ 00251 sum0 = 0; 00252 00253 /* Initialize state pointer */ 00254 px = pState; 00255 00256 /* Initialize coeff pointer */ 00257 pb = pCoeffs; 00258 00259 tapCnt = numTaps; 00260 00261 while(tapCnt > 0u) 00262 { 00263 /* Read coefficients */ 00264 c0 = *pb++; 00265 00266 /* Fetch 1 state variable */ 00267 x0 = *px++; 00268 00269 /* Perform the multiply-accumulate */ 00270 sum0 += (q63_t) x0 *c0; 00271 00272 /* Decrement the loop counter */ 00273 tapCnt--; 00274 } 00275 00276 /* Advance the state pointer by the decimation factor 00277 * to process the next group of decimation factor number samples */ 00278 pState = pState + S->M; 00279 00280 /* The result is in the accumulator, store in the destination buffer. */ 00281 *pDst++ = (q31_t) (sum0 >> 31); 00282 00283 /* Decrement the loop counter */ 00284 blkCnt--; 00285 } 00286 00287 /* Processing is complete. 00288 ** Now copy the last numTaps - 1 samples to the start of the state buffer. 00289 ** This prepares the state buffer for the next function call. */ 00290 00291 /* Points to the start of the state buffer */ 00292 pStateCurnt = S->pState; 00293 00294 i = numTaps - 1u; 00295 00296 /* copy data */ 00297 while(i > 0u) 00298 { 00299 *pStateCurnt++ = *pState++; 00300 00301 /* Decrement the loop counter */ 00302 i--; 00303 } 00304 00305 #endif /* #ifndef ARM_MATH_CM0_FAMILY */ 00306 00307 } 00308 00309 /** 00310 * @} end of FIR_decimate group 00311 */
Generated on Tue Jul 12 2022 18:44:09 by
