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
arm_fir_decimate_f32.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_f32.c 00009 * 00010 * Description: FIR decimation for floating-point sequences. 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 00031 #include "arm_math.h" 00032 00033 /** 00034 * @ingroup groupFilters 00035 */ 00036 00037 /** 00038 * @defgroup FIR_decimate Finite Impulse Response (FIR) Decimator 00039 * 00040 * These functions combine an FIR filter together with a decimator. 00041 * They are used in multirate systems for reducing the sample rate of a signal without introducing aliasing distortion. 00042 * Conceptually, the functions are equivalent to the block diagram below: 00043 * \image html FIRDecimator.gif "Components included in the FIR Decimator functions" 00044 * When decimating by a factor of <code>M</code>, the signal should be prefiltered by a lowpass filter with a normalized 00045 * cutoff frequency of <code>1/M</code> in order to prevent aliasing distortion. 00046 * The user of the function is responsible for providing the filter coefficients. 00047 * 00048 * The FIR decimator functions provided in the CMSIS DSP Library combine the FIR filter and the decimator in an efficient manner. 00049 * Instead of calculating all of the FIR filter outputs and discarding <code>M-1</code> out of every <code>M</code>, only the 00050 * samples output by the decimator are computed. 00051 * The functions operate on blocks of input and output data. 00052 * <code>pSrc</code> points to an array of <code>blockSize</code> input values and 00053 * <code>pDst</code> points to an array of <code>blockSize/M</code> output values. 00054 * In order to have an integer number of output samples <code>blockSize</code> 00055 * must always be a multiple of the decimation factor <code>M</code>. 00056 * 00057 * The library provides separate functions for Q15, Q31 and floating-point data types. 00058 * 00059 * \par Algorithm: 00060 * The FIR portion of the algorithm uses the standard form filter: 00061 * <pre> 00062 * y[n] = b[0] * x[n] + b[1] * x[n-1] + b[2] * x[n-2] + ...+ b[numTaps-1] * x[n-numTaps+1] 00063 * </pre> 00064 * where, <code>b[n]</code> are the filter coefficients. 00065 * \par 00066 * The <code>pCoeffs</code> points to a coefficient array of size <code>numTaps</code>. 00067 * Coefficients are stored in time reversed order. 00068 * \par 00069 * <pre> 00070 * {b[numTaps-1], b[numTaps-2], b[N-2], ..., b[1], b[0]} 00071 * </pre> 00072 * \par 00073 * <code>pState</code> points to a state array of size <code>numTaps + blockSize - 1</code>. 00074 * Samples in the state buffer are stored in the order: 00075 * \par 00076 * <pre> 00077 * {x[n-numTaps+1], x[n-numTaps], x[n-numTaps-1], x[n-numTaps-2]....x[0], x[1], ..., x[blockSize-1]} 00078 * </pre> 00079 * The state variables are updated after each block of data is processed, the coefficients are untouched. 00080 * 00081 * \par Instance Structure 00082 * The coefficients and state variables for a filter are stored together in an instance data structure. 00083 * A separate instance structure must be defined for each filter. 00084 * Coefficient arrays may be shared among several instances while state variable array should be allocated separately. 00085 * There are separate instance structure declarations for each of the 3 supported data types. 00086 * 00087 * \par Initialization Functions 00088 * There is also an associated initialization function for each data type. 00089 * The initialization function performs the following operations: 00090 * - Sets the values of the internal structure fields. 00091 * - Zeros out the values in the state buffer. 00092 * - Checks to make sure that the size of the input is a multiple of the decimation factor. 00093 * 00094 * \par 00095 * Use of the initialization function is optional. 00096 * However, if the initialization function is used, then the instance structure cannot be placed into a const data section. 00097 * To place an instance structure into a const data section, the instance structure must be manually initialized. 00098 * The code below statically initializes each of the 3 different data type filter instance structures 00099 * <pre> 00100 *arm_fir_decimate_instance_f32 S = {M, numTaps, pCoeffs, pState}; 00101 *arm_fir_decimate_instance_q31 S = {M, numTaps, pCoeffs, pState}; 00102 *arm_fir_decimate_instance_q15 S = {M, numTaps, pCoeffs, pState}; 00103 * </pre> 00104 * where <code>M</code> is the decimation factor; <code>numTaps</code> is the number of filter coefficients in the filter; 00105 * <code>pCoeffs</code> is the address of the coefficient buffer; 00106 * <code>pState</code> is the address of the state buffer. 00107 * Be sure to set the values in the state buffer to zeros when doing static initialization. 00108 * 00109 * \par Fixed-Point Behavior 00110 * Care must be taken when using the fixed-point versions of the FIR decimate filter functions. 00111 * In particular, the overflow and saturation behavior of the accumulator used in each function must be considered. 00112 * Refer to the function specific documentation below for usage guidelines. 00113 */ 00114 00115 /** 00116 * @addtogroup FIR_decimate 00117 * @{ 00118 */ 00119 00120 /** 00121 * @brief Processing function for the floating-point FIR decimator. 00122 * @param[in] *S points to an instance of the floating-point FIR decimator structure. 00123 * @param[in] *pSrc points to the block of input data. 00124 * @param[out] *pDst points to the block of output data. 00125 * @param[in] blockSize number of input samples to process per call. 00126 * @return none. 00127 */ 00128 00129 void arm_fir_decimate_f32( 00130 const arm_fir_decimate_instance_f32 * S, 00131 float32_t * pSrc, 00132 float32_t * pDst, 00133 uint32_t blockSize) 00134 { 00135 float32_t *pState = S->pState; /* State pointer */ 00136 float32_t *pCoeffs = S->pCoeffs; /* Coefficient pointer */ 00137 float32_t *pStateCurnt; /* Points to the current sample of the state */ 00138 float32_t *px, *pb; /* Temporary pointers for state and coefficient buffers */ 00139 float32_t sum0; /* Accumulator */ 00140 float32_t x0, c0; /* Temporary variables to hold state and coefficient values */ 00141 uint32_t numTaps = S->numTaps; /* Number of filter coefficients in the filter */ 00142 uint32_t i, tapCnt, blkCnt, outBlockSize = blockSize / S->M; /* Loop counters */ 00143 00144 /* S->pState buffer contains previous frame (numTaps - 1) samples */ 00145 /* pStateCurnt points to the location where the new input data should be written */ 00146 pStateCurnt = S->pState + (numTaps - 1u); 00147 00148 /* Total number of output samples to be computed */ 00149 blkCnt = outBlockSize; 00150 00151 while(blkCnt > 0u) 00152 { 00153 /* Copy decimation factor number of new input samples into the state buffer */ 00154 i = S->M; 00155 00156 do 00157 { 00158 *pStateCurnt++ = *pSrc++; 00159 00160 } while(--i); 00161 00162 /* Set accumulator to zero */ 00163 sum0 = 0.0f; 00164 00165 /* Initialize state pointer */ 00166 px = pState; 00167 00168 /* Initialize coeff pointer */ 00169 pb = pCoeffs; 00170 00171 /* Loop unrolling. Process 4 taps at a time. */ 00172 tapCnt = numTaps >> 2; 00173 00174 /* Loop over the number of taps. Unroll by a factor of 4. 00175 ** Repeat until we've computed numTaps-4 coefficients. */ 00176 while(tapCnt > 0u) 00177 { 00178 /* Read the b[numTaps-1] coefficient */ 00179 c0 = *(pb++); 00180 00181 /* Read x[n-numTaps-1] sample */ 00182 x0 = *(px++); 00183 00184 /* Perform the multiply-accumulate */ 00185 sum0 += x0 * c0; 00186 00187 /* Read the b[numTaps-2] coefficient */ 00188 c0 = *(pb++); 00189 00190 /* Read x[n-numTaps-2] sample */ 00191 x0 = *(px++); 00192 00193 /* Perform the multiply-accumulate */ 00194 sum0 += x0 * c0; 00195 00196 /* Read the b[numTaps-3] coefficient */ 00197 c0 = *(pb++); 00198 00199 /* Read x[n-numTaps-3] sample */ 00200 x0 = *(px++); 00201 00202 /* Perform the multiply-accumulate */ 00203 sum0 += x0 * c0; 00204 00205 /* Read the b[numTaps-4] coefficient */ 00206 c0 = *(pb++); 00207 00208 /* Read x[n-numTaps-4] sample */ 00209 x0 = *(px++); 00210 00211 /* Perform the multiply-accumulate */ 00212 sum0 += x0 * c0; 00213 00214 /* Decrement the loop counter */ 00215 tapCnt--; 00216 } 00217 00218 /* If the filter length is not a multiple of 4, compute the remaining filter taps */ 00219 tapCnt = numTaps % 0x4u; 00220 00221 while(tapCnt > 0u) 00222 { 00223 /* Read coefficients */ 00224 c0 = *(pb++); 00225 00226 /* Fetch 1 state variable */ 00227 x0 = *(px++); 00228 00229 /* Perform the multiply-accumulate */ 00230 sum0 += x0 * c0; 00231 00232 /* Decrement the loop counter */ 00233 tapCnt--; 00234 } 00235 00236 /* Advance the state pointer by the decimation factor 00237 * to process the next group of decimation factor number samples */ 00238 pState = pState + S->M; 00239 00240 /* The result is in the accumulator, store in the destination buffer. */ 00241 *pDst++ = sum0; 00242 00243 /* Decrement the loop counter */ 00244 blkCnt--; 00245 } 00246 00247 /* Processing is complete. 00248 ** Now copy the last numTaps - 1 samples to the satrt of the state buffer. 00249 ** This prepares the state buffer for the next function call. */ 00250 00251 /* Points to the start of the state buffer */ 00252 pStateCurnt = S->pState; 00253 00254 i = (numTaps - 1u) >> 2; 00255 00256 /* copy data */ 00257 while(i > 0u) 00258 { 00259 *pStateCurnt++ = *pState++; 00260 *pStateCurnt++ = *pState++; 00261 *pStateCurnt++ = *pState++; 00262 *pStateCurnt++ = *pState++; 00263 00264 /* Decrement the loop counter */ 00265 i--; 00266 } 00267 00268 i = (numTaps - 1u) % 0x04u; 00269 00270 /* copy data */ 00271 while(i > 0u) 00272 { 00273 *pStateCurnt++ = *pState++; 00274 00275 /* Decrement the loop counter */ 00276 i--; 00277 } 00278 } 00279 00280 /** 00281 * @} end of FIR_decimate group 00282 */
Generated on Tue Jul 12 2022 14:13:52 by 1.7.2