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_lattice_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_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 18:44:09 by
1.7.2
