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_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 19:55:43 by
 1.7.2
 1.7.2 
    