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_lattice_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_lattice_f32.c 00009 * 00010 * Description: Processing function for the floating-point FIR Lattice filter. 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 * @defgroup FIR_Lattice Finite Impulse Response (FIR) Lattice Filters 00038 * 00039 * This set of functions implements Finite Impulse Response (FIR) lattice filters 00040 * for Q15, Q31 and floating-point data types. Lattice filters are used in a 00041 * variety of adaptive filter applications. The filter structure is feedforward and 00042 * the net impulse response is finite length. 00043 * The functions operate on blocks 00044 * of input and output data and each call to the function processes 00045 * <code>blockSize</code> samples through the filter. <code>pSrc</code> and 00046 * <code>pDst</code> point to input and output arrays containing <code>blockSize</code> values. 00047 * 00048 * \par Algorithm: 00049 * \image html FIRLattice.gif "Finite Impulse Response Lattice filter" 00050 * The following difference equation is implemented: 00051 * <pre> 00052 * f0[n] = g0[n] = x[n] 00053 * fm[n] = fm-1[n] + km * gm-1[n-1] for m = 1, 2, ...M 00054 * gm[n] = km * fm-1[n] + gm-1[n-1] for m = 1, 2, ...M 00055 * y[n] = fM[n] 00056 * </pre> 00057 * \par 00058 * <code>pCoeffs</code> points to tha array of reflection coefficients of size <code>numStages</code>. 00059 * Reflection Coefficients are stored in the following order. 00060 * \par 00061 * <pre> 00062 * {k1, k2, ..., kM} 00063 * </pre> 00064 * where M is number of stages 00065 * \par 00066 * <code>pState</code> points to a state array of size <code>numStages</code>. 00067 * The state variables (g values) hold previous inputs and are stored in the following order. 00068 * <pre> 00069 * {g0[n], g1[n], g2[n] ...gM-1[n]} 00070 * </pre> 00071 * The state variables are updated after each block of data is processed; the coefficients are untouched. 00072 * \par Instance Structure 00073 * The coefficients and state variables for a filter are stored together in an instance data structure. 00074 * A separate instance structure must be defined for each filter. 00075 * Coefficient arrays may be shared among several instances while state variable arrays cannot be shared. 00076 * There are separate instance structure declarations for each of the 3 supported data types. 00077 * 00078 * \par Initialization Functions 00079 * There is also an associated initialization function for each data type. 00080 * The initialization function performs the following operations: 00081 * - Sets the values of the internal structure fields. 00082 * - Zeros out the values in the state buffer. 00083 * 00084 * \par 00085 * Use of the initialization function is optional. 00086 * However, if the initialization function is used, then the instance structure cannot be placed into a const data section. 00087 * To place an instance structure into a const data section, the instance structure must be manually initialized. 00088 * Set the values in the state buffer to zeros and then manually initialize the instance structure as follows: 00089 * <pre> 00090 *arm_fir_lattice_instance_f32 S = {numStages, pState, pCoeffs}; 00091 *arm_fir_lattice_instance_q31 S = {numStages, pState, pCoeffs}; 00092 *arm_fir_lattice_instance_q15 S = {numStages, pState, pCoeffs}; 00093 * </pre> 00094 * \par 00095 * where <code>numStages</code> is the number of stages in the filter; <code>pState</code> is the address of the state buffer; 00096 * <code>pCoeffs</code> is the address of the coefficient buffer. 00097 * \par Fixed-Point Behavior 00098 * Care must be taken when using the fixed-point versions of the FIR Lattice filter functions. 00099 * In particular, the overflow and saturation behavior of the accumulator used in each function must be considered. 00100 * Refer to the function specific documentation below for usage guidelines. 00101 */ 00102 00103 /** 00104 * @addtogroup FIR_Lattice 00105 * @{ 00106 */ 00107 00108 00109 /** 00110 * @brief Processing function for the floating-point FIR lattice filter. 00111 * @param[in] *S points to an instance of the floating-point FIR lattice structure. 00112 * @param[in] *pSrc points to the block of input data. 00113 * @param[out] *pDst points to the block of output data 00114 * @param[in] blockSize number of samples to process. 00115 * @return none. 00116 */ 00117 00118 void arm_fir_lattice_f32( 00119 const arm_fir_lattice_instance_f32 * S, 00120 float32_t * pSrc, 00121 float32_t * pDst, 00122 uint32_t blockSize) 00123 { 00124 float32_t *pState; /* State pointer */ 00125 float32_t *pCoeffs = S->pCoeffs; /* Coefficient pointer */ 00126 float32_t *px; /* temporary state pointer */ 00127 float32_t *pk; /* temporary coefficient pointer */ 00128 float32_t fcurr1, fnext1, gcurr1, gnext1; /* temporary variables for first sample in loop unrolling */ 00129 float32_t fcurr2, fnext2, gnext2; /* temporary variables for second sample in loop unrolling */ 00130 float32_t fcurr3, fnext3, gnext3; /* temporary variables for third sample in loop unrolling */ 00131 float32_t fcurr4, fnext4, gnext4; /* temporary variables for fourth sample in loop unrolling */ 00132 uint32_t numStages = S->numStages; /* Number of stages in the filter */ 00133 uint32_t blkCnt, stageCnt; /* temporary variables for counts */ 00134 00135 gcurr1 = 0.0f; 00136 pState = &S->pState[0]; 00137 00138 blkCnt = blockSize >> 2; 00139 00140 /* First part of the processing with loop unrolling. Compute 4 outputs at a time. 00141 a second loop below computes the remaining 1 to 3 samples. */ 00142 while(blkCnt > 0u) 00143 { 00144 00145 /* Read two samples from input buffer */ 00146 /* f0(n) = x(n) */ 00147 fcurr1 = *pSrc++; 00148 fcurr2 = *pSrc++; 00149 00150 /* Initialize coeff pointer */ 00151 pk = (pCoeffs); 00152 00153 /* Initialize state pointer */ 00154 px = pState; 00155 00156 /* Read g0(n-1) from state */ 00157 gcurr1 = *px; 00158 00159 /* Process first sample for first tap */ 00160 /* f1(n) = f0(n) + K1 * g0(n-1) */ 00161 fnext1 = fcurr1 + ((*pk) * gcurr1); 00162 /* g1(n) = f0(n) * K1 + g0(n-1) */ 00163 gnext1 = (fcurr1 * (*pk)) + gcurr1; 00164 00165 /* Process second sample for first tap */ 00166 /* for sample 2 processing */ 00167 fnext2 = fcurr2 + ((*pk) * fcurr1); 00168 gnext2 = (fcurr2 * (*pk)) + fcurr1; 00169 00170 /* Read next two samples from input buffer */ 00171 /* f0(n+2) = x(n+2) */ 00172 fcurr3 = *pSrc++; 00173 fcurr4 = *pSrc++; 00174 00175 /* Copy only last input samples into the state buffer 00176 which will be used for next four samples processing */ 00177 *px++ = fcurr4; 00178 00179 /* Process third sample for first tap */ 00180 fnext3 = fcurr3 + ((*pk) * fcurr2); 00181 gnext3 = (fcurr3 * (*pk)) + fcurr2; 00182 00183 /* Process fourth sample for first tap */ 00184 fnext4 = fcurr4 + ((*pk) * fcurr3); 00185 gnext4 = (fcurr4 * (*pk++)) + fcurr3; 00186 00187 /* Update of f values for next coefficient set processing */ 00188 fcurr1 = fnext1; 00189 fcurr2 = fnext2; 00190 fcurr3 = fnext3; 00191 fcurr4 = fnext4; 00192 00193 /* Loop unrolling. Process 4 taps at a time . */ 00194 stageCnt = (numStages - 1u) >> 2u; 00195 00196 /* Loop over the number of taps. Unroll by a factor of 4. 00197 ** Repeat until we've computed numStages-3 coefficients. */ 00198 00199 /* Process 2nd, 3rd, 4th and 5th taps ... here */ 00200 while(stageCnt > 0u) 00201 { 00202 /* Read g1(n-1), g3(n-1) .... from state */ 00203 gcurr1 = *px; 00204 00205 /* save g1(n) in state buffer */ 00206 *px++ = gnext4; 00207 00208 /* Process first sample for 2nd, 6th .. tap */ 00209 /* Sample processing for K2, K6.... */ 00210 /* f2(n) = f1(n) + K2 * g1(n-1) */ 00211 fnext1 = fcurr1 + ((*pk) * gcurr1); 00212 /* Process second sample for 2nd, 6th .. tap */ 00213 /* for sample 2 processing */ 00214 fnext2 = fcurr2 + ((*pk) * gnext1); 00215 /* Process third sample for 2nd, 6th .. tap */ 00216 fnext3 = fcurr3 + ((*pk) * gnext2); 00217 /* Process fourth sample for 2nd, 6th .. tap */ 00218 fnext4 = fcurr4 + ((*pk) * gnext3); 00219 00220 /* g2(n) = f1(n) * K2 + g1(n-1) */ 00221 /* Calculation of state values for next stage */ 00222 gnext4 = (fcurr4 * (*pk)) + gnext3; 00223 gnext3 = (fcurr3 * (*pk)) + gnext2; 00224 gnext2 = (fcurr2 * (*pk)) + gnext1; 00225 gnext1 = (fcurr1 * (*pk++)) + gcurr1; 00226 00227 00228 /* Read g2(n-1), g4(n-1) .... from state */ 00229 gcurr1 = *px; 00230 00231 /* save g2(n) in state buffer */ 00232 *px++ = gnext4; 00233 00234 /* Sample processing for K3, K7.... */ 00235 /* Process first sample for 3rd, 7th .. tap */ 00236 /* f3(n) = f2(n) + K3 * g2(n-1) */ 00237 fcurr1 = fnext1 + ((*pk) * gcurr1); 00238 /* Process second sample for 3rd, 7th .. tap */ 00239 fcurr2 = fnext2 + ((*pk) * gnext1); 00240 /* Process third sample for 3rd, 7th .. tap */ 00241 fcurr3 = fnext3 + ((*pk) * gnext2); 00242 /* Process fourth sample for 3rd, 7th .. tap */ 00243 fcurr4 = fnext4 + ((*pk) * gnext3); 00244 00245 /* Calculation of state values for next stage */ 00246 /* g3(n) = f2(n) * K3 + g2(n-1) */ 00247 gnext4 = (fnext4 * (*pk)) + gnext3; 00248 gnext3 = (fnext3 * (*pk)) + gnext2; 00249 gnext2 = (fnext2 * (*pk)) + gnext1; 00250 gnext1 = (fnext1 * (*pk++)) + gcurr1; 00251 00252 00253 /* Read g1(n-1), g3(n-1) .... from state */ 00254 gcurr1 = *px; 00255 00256 /* save g3(n) in state buffer */ 00257 *px++ = gnext4; 00258 00259 /* Sample processing for K4, K8.... */ 00260 /* Process first sample for 4th, 8th .. tap */ 00261 /* f4(n) = f3(n) + K4 * g3(n-1) */ 00262 fnext1 = fcurr1 + ((*pk) * gcurr1); 00263 /* Process second sample for 4th, 8th .. tap */ 00264 /* for sample 2 processing */ 00265 fnext2 = fcurr2 + ((*pk) * gnext1); 00266 /* Process third sample for 4th, 8th .. tap */ 00267 fnext3 = fcurr3 + ((*pk) * gnext2); 00268 /* Process fourth sample for 4th, 8th .. tap */ 00269 fnext4 = fcurr4 + ((*pk) * gnext3); 00270 00271 /* g4(n) = f3(n) * K4 + g3(n-1) */ 00272 /* Calculation of state values for next stage */ 00273 gnext4 = (fcurr4 * (*pk)) + gnext3; 00274 gnext3 = (fcurr3 * (*pk)) + gnext2; 00275 gnext2 = (fcurr2 * (*pk)) + gnext1; 00276 gnext1 = (fcurr1 * (*pk++)) + gcurr1; 00277 00278 /* Read g2(n-1), g4(n-1) .... from state */ 00279 gcurr1 = *px; 00280 00281 /* save g4(n) in state buffer */ 00282 *px++ = gnext4; 00283 00284 /* Sample processing for K5, K9.... */ 00285 /* Process first sample for 5th, 9th .. tap */ 00286 /* f5(n) = f4(n) + K5 * g4(n-1) */ 00287 fcurr1 = fnext1 + ((*pk) * gcurr1); 00288 /* Process second sample for 5th, 9th .. tap */ 00289 fcurr2 = fnext2 + ((*pk) * gnext1); 00290 /* Process third sample for 5th, 9th .. tap */ 00291 fcurr3 = fnext3 + ((*pk) * gnext2); 00292 /* Process fourth sample for 5th, 9th .. tap */ 00293 fcurr4 = fnext4 + ((*pk) * gnext3); 00294 00295 /* Calculation of state values for next stage */ 00296 /* g5(n) = f4(n) * K5 + g4(n-1) */ 00297 gnext4 = (fnext4 * (*pk)) + gnext3; 00298 gnext3 = (fnext3 * (*pk)) + gnext2; 00299 gnext2 = (fnext2 * (*pk)) + gnext1; 00300 gnext1 = (fnext1 * (*pk++)) + gcurr1; 00301 00302 stageCnt--; 00303 } 00304 00305 /* If the (filter length -1) is not a multiple of 4, compute the remaining filter taps */ 00306 stageCnt = (numStages - 1u) % 0x4u; 00307 00308 while(stageCnt > 0u) 00309 { 00310 gcurr1 = *px; 00311 00312 /* save g value in state buffer */ 00313 *px++ = gnext4; 00314 00315 /* Process four samples for last three taps here */ 00316 fnext1 = fcurr1 + ((*pk) * gcurr1); 00317 fnext2 = fcurr2 + ((*pk) * gnext1); 00318 fnext3 = fcurr3 + ((*pk) * gnext2); 00319 fnext4 = fcurr4 + ((*pk) * gnext3); 00320 00321 /* g1(n) = f0(n) * K1 + g0(n-1) */ 00322 gnext4 = (fcurr4 * (*pk)) + gnext3; 00323 gnext3 = (fcurr3 * (*pk)) + gnext2; 00324 gnext2 = (fcurr2 * (*pk)) + gnext1; 00325 gnext1 = (fcurr1 * (*pk++)) + gcurr1; 00326 00327 /* Update of f values for next coefficient set processing */ 00328 fcurr1 = fnext1; 00329 fcurr2 = fnext2; 00330 fcurr3 = fnext3; 00331 fcurr4 = fnext4; 00332 00333 stageCnt--; 00334 00335 } 00336 00337 /* The results in the 4 accumulators, store in the destination buffer. */ 00338 /* y(n) = fN(n) */ 00339 *pDst++ = fcurr1; 00340 *pDst++ = fcurr2; 00341 *pDst++ = fcurr3; 00342 *pDst++ = fcurr4; 00343 00344 blkCnt--; 00345 } 00346 00347 /* If the blockSize is not a multiple of 4, compute any remaining output samples here. 00348 ** No loop unrolling is used. */ 00349 blkCnt = blockSize % 0x4u; 00350 00351 while(blkCnt > 0u) 00352 { 00353 /* f0(n) = x(n) */ 00354 fcurr1 = *pSrc++; 00355 00356 /* Initialize coeff pointer */ 00357 pk = (pCoeffs); 00358 00359 /* Initialize state pointer */ 00360 px = pState; 00361 00362 /* read g2(n) from state buffer */ 00363 gcurr1 = *px; 00364 00365 /* for sample 1 processing */ 00366 /* f1(n) = f0(n) + K1 * g0(n-1) */ 00367 fnext1 = fcurr1 + ((*pk) * gcurr1); 00368 /* g1(n) = f0(n) * K1 + g0(n-1) */ 00369 gnext1 = (fcurr1 * (*pk++)) + gcurr1; 00370 00371 /* save g1(n) in state buffer */ 00372 *px++ = fcurr1; 00373 00374 /* f1(n) is saved in fcurr1 00375 for next stage processing */ 00376 fcurr1 = fnext1; 00377 00378 stageCnt = (numStages - 1u); 00379 00380 /* stage loop */ 00381 while(stageCnt > 0u) 00382 { 00383 /* read g2(n) from state buffer */ 00384 gcurr1 = *px; 00385 00386 /* save g1(n) in state buffer */ 00387 *px++ = gnext1; 00388 00389 /* Sample processing for K2, K3.... */ 00390 /* f2(n) = f1(n) + K2 * g1(n-1) */ 00391 fnext1 = fcurr1 + ((*pk) * gcurr1); 00392 /* g2(n) = f1(n) * K2 + g1(n-1) */ 00393 gnext1 = (fcurr1 * (*pk++)) + gcurr1; 00394 00395 /* f1(n) is saved in fcurr1 00396 for next stage processing */ 00397 fcurr1 = fnext1; 00398 00399 stageCnt--; 00400 00401 } 00402 00403 /* y(n) = fN(n) */ 00404 *pDst++ = fcurr1; 00405 00406 blkCnt--; 00407 00408 } 00409 } 00410 00411 /** 00412 * @} end of FIR_Lattice group 00413 */
Generated on Tue Jul 12 2022 19:55:43 by
1.7.2
