CMSIS DSP library
Dependents: performance_timer Surfboard_ gps2rtty Capstone ... more
arm_fir_lattice_q31.c
00001 /* ---------------------------------------------------------------------- 00002 * Copyright (C) 2010-2014 ARM Limited. All rights reserved. 00003 * 00004 * $Date: 19. March 2015 00005 * $Revision: V.1.4.5 00006 * 00007 * Project: CMSIS DSP Library 00008 * Title: arm_fir_lattice_q31.c 00009 * 00010 * Description: Q31 FIR lattice filter processing function. 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_Lattice 00049 * @{ 00050 */ 00051 00052 00053 /** 00054 * @brief Processing function for the Q31 FIR lattice filter. 00055 * @param[in] *S points to an instance of the Q31 FIR lattice structure. 00056 * @param[in] *pSrc points to the block of input data. 00057 * @param[out] *pDst points to the block of output data 00058 * @param[in] blockSize number of samples to process. 00059 * @return none. 00060 * 00061 * @details 00062 * <b>Scaling and Overflow Behavior:</b> 00063 * In order to avoid overflows the input signal must be scaled down by 2*log2(numStages) bits. 00064 */ 00065 00066 #ifndef ARM_MATH_CM0_FAMILY 00067 00068 /* Run the below code for Cortex-M4 and Cortex-M3 */ 00069 00070 void arm_fir_lattice_q31( 00071 const arm_fir_lattice_instance_q31 * S, 00072 q31_t * pSrc, 00073 q31_t * pDst, 00074 uint32_t blockSize) 00075 { 00076 q31_t *pState; /* State pointer */ 00077 q31_t *pCoeffs = S->pCoeffs; /* Coefficient pointer */ 00078 q31_t *px; /* temporary state pointer */ 00079 q31_t *pk; /* temporary coefficient pointer */ 00080 q31_t fcurr1, fnext1, gcurr1 = 0, gnext1; /* temporary variables for first sample in loop unrolling */ 00081 q31_t fcurr2, fnext2, gnext2; /* temporary variables for second sample in loop unrolling */ 00082 uint32_t numStages = S->numStages; /* Length of the filter */ 00083 uint32_t blkCnt, stageCnt; /* temporary variables for counts */ 00084 q31_t k; 00085 00086 pState = &S->pState[0]; 00087 00088 blkCnt = blockSize >> 1u; 00089 00090 /* First part of the processing with loop unrolling. Compute 2 outputs at a time. 00091 a second loop below computes the remaining 1 sample. */ 00092 while(blkCnt > 0u) 00093 { 00094 /* f0(n) = x(n) */ 00095 fcurr1 = *pSrc++; 00096 00097 /* f0(n) = x(n) */ 00098 fcurr2 = *pSrc++; 00099 00100 /* Initialize coeff pointer */ 00101 pk = (pCoeffs); 00102 00103 /* Initialize state pointer */ 00104 px = pState; 00105 00106 /* read g0(n - 1) from state buffer */ 00107 gcurr1 = *px; 00108 00109 /* Read the reflection coefficient */ 00110 k = *pk++; 00111 00112 /* for sample 1 processing */ 00113 /* f1(n) = f0(n) + K1 * g0(n-1) */ 00114 fnext1 = (q31_t) (((q63_t) gcurr1 * k) >> 32); 00115 00116 /* g1(n) = f0(n) * K1 + g0(n-1) */ 00117 gnext1 = (q31_t) (((q63_t) fcurr1 * (k)) >> 32); 00118 fnext1 = fcurr1 + (fnext1 << 1u); 00119 gnext1 = gcurr1 + (gnext1 << 1u); 00120 00121 /* for sample 1 processing */ 00122 /* f1(n) = f0(n) + K1 * g0(n-1) */ 00123 fnext2 = (q31_t) (((q63_t) fcurr1 * k) >> 32); 00124 00125 /* g1(n) = f0(n) * K1 + g0(n-1) */ 00126 gnext2 = (q31_t) (((q63_t) fcurr2 * (k)) >> 32); 00127 fnext2 = fcurr2 + (fnext2 << 1u); 00128 gnext2 = fcurr1 + (gnext2 << 1u); 00129 00130 /* save g1(n) in state buffer */ 00131 *px++ = fcurr2; 00132 00133 /* f1(n) is saved in fcurr1 00134 for next stage processing */ 00135 fcurr1 = fnext1; 00136 fcurr2 = fnext2; 00137 00138 stageCnt = (numStages - 1u); 00139 00140 /* stage loop */ 00141 while(stageCnt > 0u) 00142 { 00143 00144 /* Read the reflection coefficient */ 00145 k = *pk++; 00146 00147 /* read g2(n) from state buffer */ 00148 gcurr1 = *px; 00149 00150 /* save g1(n) in state buffer */ 00151 *px++ = gnext2; 00152 00153 /* Sample processing for K2, K3.... */ 00154 /* f2(n) = f1(n) + K2 * g1(n-1) */ 00155 fnext1 = (q31_t) (((q63_t) gcurr1 * k) >> 32); 00156 fnext2 = (q31_t) (((q63_t) gnext1 * k) >> 32); 00157 00158 fnext1 = fcurr1 + (fnext1 << 1u); 00159 fnext2 = fcurr2 + (fnext2 << 1u); 00160 00161 /* g2(n) = f1(n) * K2 + g1(n-1) */ 00162 gnext2 = (q31_t) (((q63_t) fcurr2 * (k)) >> 32); 00163 gnext2 = gnext1 + (gnext2 << 1u); 00164 00165 /* g2(n) = f1(n) * K2 + g1(n-1) */ 00166 gnext1 = (q31_t) (((q63_t) fcurr1 * (k)) >> 32); 00167 gnext1 = gcurr1 + (gnext1 << 1u); 00168 00169 /* f1(n) is saved in fcurr1 00170 for next stage processing */ 00171 fcurr1 = fnext1; 00172 fcurr2 = fnext2; 00173 00174 stageCnt--; 00175 00176 } 00177 00178 /* y(n) = fN(n) */ 00179 *pDst++ = fcurr1; 00180 *pDst++ = fcurr2; 00181 00182 blkCnt--; 00183 00184 } 00185 00186 /* If the blockSize is not a multiple of 4, compute any remaining output samples here. 00187 ** No loop unrolling is used. */ 00188 blkCnt = blockSize % 0x2u; 00189 00190 while(blkCnt > 0u) 00191 { 00192 /* f0(n) = x(n) */ 00193 fcurr1 = *pSrc++; 00194 00195 /* Initialize coeff pointer */ 00196 pk = (pCoeffs); 00197 00198 /* Initialize state pointer */ 00199 px = pState; 00200 00201 /* read g0(n - 1) from state buffer */ 00202 gcurr1 = *px; 00203 00204 /* Read the reflection coefficient */ 00205 k = *pk++; 00206 00207 /* for sample 1 processing */ 00208 /* f1(n) = f0(n) + K1 * g0(n-1) */ 00209 fnext1 = (q31_t) (((q63_t) gcurr1 * k) >> 32); 00210 fnext1 = fcurr1 + (fnext1 << 1u); 00211 00212 /* g1(n) = f0(n) * K1 + g0(n-1) */ 00213 gnext1 = (q31_t) (((q63_t) fcurr1 * (k)) >> 32); 00214 gnext1 = gcurr1 + (gnext1 << 1u); 00215 00216 /* save g1(n) in state buffer */ 00217 *px++ = fcurr1; 00218 00219 /* f1(n) is saved in fcurr1 00220 for next stage processing */ 00221 fcurr1 = fnext1; 00222 00223 stageCnt = (numStages - 1u); 00224 00225 /* stage loop */ 00226 while(stageCnt > 0u) 00227 { 00228 /* Read the reflection coefficient */ 00229 k = *pk++; 00230 00231 /* read g2(n) from state buffer */ 00232 gcurr1 = *px; 00233 00234 /* save g1(n) in state buffer */ 00235 *px++ = gnext1; 00236 00237 /* Sample processing for K2, K3.... */ 00238 /* f2(n) = f1(n) + K2 * g1(n-1) */ 00239 fnext1 = (q31_t) (((q63_t) gcurr1 * k) >> 32); 00240 fnext1 = fcurr1 + (fnext1 << 1u); 00241 00242 /* g2(n) = f1(n) * K2 + g1(n-1) */ 00243 gnext1 = (q31_t) (((q63_t) fcurr1 * (k)) >> 32); 00244 gnext1 = gcurr1 + (gnext1 << 1u); 00245 00246 /* f1(n) is saved in fcurr1 00247 for next stage processing */ 00248 fcurr1 = fnext1; 00249 00250 stageCnt--; 00251 00252 } 00253 00254 00255 /* y(n) = fN(n) */ 00256 *pDst++ = fcurr1; 00257 00258 blkCnt--; 00259 00260 } 00261 00262 00263 } 00264 00265 00266 #else 00267 00268 /* Run the below code for Cortex-M0 */ 00269 00270 void arm_fir_lattice_q31( 00271 const arm_fir_lattice_instance_q31 * S, 00272 q31_t * pSrc, 00273 q31_t * pDst, 00274 uint32_t blockSize) 00275 { 00276 q31_t *pState; /* State pointer */ 00277 q31_t *pCoeffs = S->pCoeffs; /* Coefficient pointer */ 00278 q31_t *px; /* temporary state pointer */ 00279 q31_t *pk; /* temporary coefficient pointer */ 00280 q31_t fcurr, fnext, gcurr, gnext; /* temporary variables */ 00281 uint32_t numStages = S->numStages; /* Length of the filter */ 00282 uint32_t blkCnt, stageCnt; /* temporary variables for counts */ 00283 00284 pState = &S->pState[0]; 00285 00286 blkCnt = blockSize; 00287 00288 while(blkCnt > 0u) 00289 { 00290 /* f0(n) = x(n) */ 00291 fcurr = *pSrc++; 00292 00293 /* Initialize coeff pointer */ 00294 pk = (pCoeffs); 00295 00296 /* Initialize state pointer */ 00297 px = pState; 00298 00299 /* read g0(n-1) from state buffer */ 00300 gcurr = *px; 00301 00302 /* for sample 1 processing */ 00303 /* f1(n) = f0(n) + K1 * g0(n-1) */ 00304 fnext = (q31_t) (((q63_t) gcurr * (*pk)) >> 31) + fcurr; 00305 /* g1(n) = f0(n) * K1 + g0(n-1) */ 00306 gnext = (q31_t) (((q63_t) fcurr * (*pk++)) >> 31) + gcurr; 00307 /* save g1(n) in state buffer */ 00308 *px++ = fcurr; 00309 00310 /* f1(n) is saved in fcurr1 00311 for next stage processing */ 00312 fcurr = fnext; 00313 00314 stageCnt = (numStages - 1u); 00315 00316 /* stage loop */ 00317 while(stageCnt > 0u) 00318 { 00319 /* read g2(n) from state buffer */ 00320 gcurr = *px; 00321 00322 /* save g1(n) in state buffer */ 00323 *px++ = gnext; 00324 00325 /* Sample processing for K2, K3.... */ 00326 /* f2(n) = f1(n) + K2 * g1(n-1) */ 00327 fnext = (q31_t) (((q63_t) gcurr * (*pk)) >> 31) + fcurr; 00328 /* g2(n) = f1(n) * K2 + g1(n-1) */ 00329 gnext = (q31_t) (((q63_t) fcurr * (*pk++)) >> 31) + gcurr; 00330 00331 /* f1(n) is saved in fcurr1 00332 for next stage processing */ 00333 fcurr = fnext; 00334 00335 stageCnt--; 00336 00337 } 00338 00339 /* y(n) = fN(n) */ 00340 *pDst++ = fcurr; 00341 00342 blkCnt--; 00343 00344 } 00345 00346 } 00347 00348 #endif /* #ifndef ARM_MATH_CM0_FAMILY */ 00349 00350 00351 /** 00352 * @} end of FIR_Lattice group 00353 */
Generated on Tue Jul 12 2022 11:59:17 by 1.7.2