CMSIS DSP library
Dependents: performance_timer Surfboard_ gps2rtty Capstone ... more
arm_cfft_radix2_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_cfft_radix2_q31.c 00009 * 00010 * Description: Radix-2 Decimation in Frequency CFFT & CIFFT Fixed point processing function 00011 * 00012 * 00013 * Target Processor: Cortex-M4/Cortex-M3/Cortex-M0 00014 * 00015 * Redistribution and use in source and binary forms, with or without 00016 * modification, are permitted provided that the following conditions 00017 * are met: 00018 * - Redistributions of source code must retain the above copyright 00019 * notice, this list of conditions and the following disclaimer. 00020 * - Redistributions in binary form must reproduce the above copyright 00021 * notice, this list of conditions and the following disclaimer in 00022 * the documentation and/or other materials provided with the 00023 * distribution. 00024 * - Neither the name of ARM LIMITED nor the names of its contributors 00025 * may be used to endorse or promote products derived from this 00026 * software without specific prior written permission. 00027 * 00028 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 00029 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 00030 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 00031 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 00032 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 00033 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 00034 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 00035 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 00036 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 00037 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 00038 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 00039 * POSSIBILITY OF SUCH DAMAGE. 00040 * -------------------------------------------------------------------- */ 00041 00042 #include "arm_math.h" 00043 00044 void arm_radix2_butterfly_q31( 00045 q31_t * pSrc, 00046 uint32_t fftLen, 00047 q31_t * pCoef, 00048 uint16_t twidCoefModifier); 00049 00050 void arm_radix2_butterfly_inverse_q31( 00051 q31_t * pSrc, 00052 uint32_t fftLen, 00053 q31_t * pCoef, 00054 uint16_t twidCoefModifier); 00055 00056 void arm_bitreversal_q31( 00057 q31_t * pSrc, 00058 uint32_t fftLen, 00059 uint16_t bitRevFactor, 00060 uint16_t * pBitRevTab); 00061 00062 /** 00063 * @ingroup groupTransforms 00064 */ 00065 00066 /** 00067 * @addtogroup ComplexFFT 00068 * @{ 00069 */ 00070 00071 /** 00072 * @details 00073 * @brief Processing function for the fixed-point CFFT/CIFFT. 00074 * @deprecated Do not use this function. It has been superseded by \ref arm_cfft_q31 and will be removed 00075 * @param[in] *S points to an instance of the fixed-point CFFT/CIFFT structure. 00076 * @param[in, out] *pSrc points to the complex data buffer of size <code>2*fftLen</code>. Processing occurs in-place. 00077 * @return none. 00078 */ 00079 00080 void arm_cfft_radix2_q31( 00081 const arm_cfft_radix2_instance_q31 * S, 00082 q31_t * pSrc) 00083 { 00084 00085 if(S->ifftFlag == 1u) 00086 { 00087 arm_radix2_butterfly_inverse_q31(pSrc, S->fftLen, 00088 S->pTwiddle, S->twidCoefModifier); 00089 } 00090 else 00091 { 00092 arm_radix2_butterfly_q31(pSrc, S->fftLen, 00093 S->pTwiddle, S->twidCoefModifier); 00094 } 00095 00096 arm_bitreversal_q31(pSrc, S->fftLen, S->bitRevFactor, S->pBitRevTable); 00097 } 00098 00099 /** 00100 * @} end of ComplexFFT group 00101 */ 00102 00103 void arm_radix2_butterfly_q31( 00104 q31_t * pSrc, 00105 uint32_t fftLen, 00106 q31_t * pCoef, 00107 uint16_t twidCoefModifier) 00108 { 00109 00110 unsigned i, j, k, l, m; 00111 unsigned n1, n2, ia; 00112 q31_t xt, yt, cosVal, sinVal; 00113 q31_t p0, p1; 00114 00115 //N = fftLen; 00116 n2 = fftLen; 00117 00118 n1 = n2; 00119 n2 = n2 >> 1; 00120 ia = 0; 00121 00122 // loop for groups 00123 for (i = 0; i < n2; i++) 00124 { 00125 cosVal = pCoef[ia * 2]; 00126 sinVal = pCoef[(ia * 2) + 1]; 00127 ia = ia + twidCoefModifier; 00128 00129 l = i + n2; 00130 xt = (pSrc[2 * i] >> 1u) - (pSrc[2 * l] >> 1u); 00131 pSrc[2 * i] = ((pSrc[2 * i] >> 1u) + (pSrc[2 * l] >> 1u)) >> 1u; 00132 00133 yt = (pSrc[2 * i + 1] >> 1u) - (pSrc[2 * l + 1] >> 1u); 00134 pSrc[2 * i + 1] = 00135 ((pSrc[2 * l + 1] >> 1u) + (pSrc[2 * i + 1] >> 1u)) >> 1u; 00136 00137 mult_32x32_keep32_R(p0, xt, cosVal); 00138 mult_32x32_keep32_R(p1, yt, cosVal); 00139 multAcc_32x32_keep32_R(p0, yt, sinVal); 00140 multSub_32x32_keep32_R(p1, xt, sinVal); 00141 00142 pSrc[2u * l] = p0; 00143 pSrc[2u * l + 1u] = p1; 00144 00145 } // groups loop end 00146 00147 twidCoefModifier <<= 1u; 00148 00149 // loop for stage 00150 for (k = fftLen / 2; k > 2; k = k >> 1) 00151 { 00152 n1 = n2; 00153 n2 = n2 >> 1; 00154 ia = 0; 00155 00156 // loop for groups 00157 for (j = 0; j < n2; j++) 00158 { 00159 cosVal = pCoef[ia * 2]; 00160 sinVal = pCoef[(ia * 2) + 1]; 00161 ia = ia + twidCoefModifier; 00162 00163 // loop for butterfly 00164 i = j; 00165 m = fftLen / n1; 00166 do 00167 { 00168 l = i + n2; 00169 xt = pSrc[2 * i] - pSrc[2 * l]; 00170 pSrc[2 * i] = (pSrc[2 * i] + pSrc[2 * l]) >> 1u; 00171 00172 yt = pSrc[2 * i + 1] - pSrc[2 * l + 1]; 00173 pSrc[2 * i + 1] = (pSrc[2 * l + 1] + pSrc[2 * i + 1]) >> 1u; 00174 00175 mult_32x32_keep32_R(p0, xt, cosVal); 00176 mult_32x32_keep32_R(p1, yt, cosVal); 00177 multAcc_32x32_keep32_R(p0, yt, sinVal); 00178 multSub_32x32_keep32_R(p1, xt, sinVal); 00179 00180 pSrc[2u * l] = p0; 00181 pSrc[2u * l + 1u] = p1; 00182 i += n1; 00183 m--; 00184 } while( m > 0); // butterfly loop end 00185 00186 } // groups loop end 00187 00188 twidCoefModifier <<= 1u; 00189 } // stages loop end 00190 00191 n1 = n2; 00192 n2 = n2 >> 1; 00193 ia = 0; 00194 00195 cosVal = pCoef[ia * 2]; 00196 sinVal = pCoef[(ia * 2) + 1]; 00197 ia = ia + twidCoefModifier; 00198 00199 // loop for butterfly 00200 for (i = 0; i < fftLen; i += n1) 00201 { 00202 l = i + n2; 00203 xt = pSrc[2 * i] - pSrc[2 * l]; 00204 pSrc[2 * i] = (pSrc[2 * i] + pSrc[2 * l]); 00205 00206 yt = pSrc[2 * i + 1] - pSrc[2 * l + 1]; 00207 pSrc[2 * i + 1] = (pSrc[2 * l + 1] + pSrc[2 * i + 1]); 00208 00209 pSrc[2u * l] = xt; 00210 00211 pSrc[2u * l + 1u] = yt; 00212 00213 i += n1; 00214 l = i + n2; 00215 00216 xt = pSrc[2 * i] - pSrc[2 * l]; 00217 pSrc[2 * i] = (pSrc[2 * i] + pSrc[2 * l]); 00218 00219 yt = pSrc[2 * i + 1] - pSrc[2 * l + 1]; 00220 pSrc[2 * i + 1] = (pSrc[2 * l + 1] + pSrc[2 * i + 1]); 00221 00222 pSrc[2u * l] = xt; 00223 00224 pSrc[2u * l + 1u] = yt; 00225 00226 } // butterfly loop end 00227 00228 } 00229 00230 00231 void arm_radix2_butterfly_inverse_q31( 00232 q31_t * pSrc, 00233 uint32_t fftLen, 00234 q31_t * pCoef, 00235 uint16_t twidCoefModifier) 00236 { 00237 00238 unsigned i, j, k, l; 00239 unsigned n1, n2, ia; 00240 q31_t xt, yt, cosVal, sinVal; 00241 q31_t p0, p1; 00242 00243 //N = fftLen; 00244 n2 = fftLen; 00245 00246 n1 = n2; 00247 n2 = n2 >> 1; 00248 ia = 0; 00249 00250 // loop for groups 00251 for (i = 0; i < n2; i++) 00252 { 00253 cosVal = pCoef[ia * 2]; 00254 sinVal = pCoef[(ia * 2) + 1]; 00255 ia = ia + twidCoefModifier; 00256 00257 l = i + n2; 00258 xt = (pSrc[2 * i] >> 1u) - (pSrc[2 * l] >> 1u); 00259 pSrc[2 * i] = ((pSrc[2 * i] >> 1u) + (pSrc[2 * l] >> 1u)) >> 1u; 00260 00261 yt = (pSrc[2 * i + 1] >> 1u) - (pSrc[2 * l + 1] >> 1u); 00262 pSrc[2 * i + 1] = 00263 ((pSrc[2 * l + 1] >> 1u) + (pSrc[2 * i + 1] >> 1u)) >> 1u; 00264 00265 mult_32x32_keep32_R(p0, xt, cosVal); 00266 mult_32x32_keep32_R(p1, yt, cosVal); 00267 multSub_32x32_keep32_R(p0, yt, sinVal); 00268 multAcc_32x32_keep32_R(p1, xt, sinVal); 00269 00270 pSrc[2u * l] = p0; 00271 pSrc[2u * l + 1u] = p1; 00272 } // groups loop end 00273 00274 twidCoefModifier = twidCoefModifier << 1u; 00275 00276 // loop for stage 00277 for (k = fftLen / 2; k > 2; k = k >> 1) 00278 { 00279 n1 = n2; 00280 n2 = n2 >> 1; 00281 ia = 0; 00282 00283 // loop for groups 00284 for (j = 0; j < n2; j++) 00285 { 00286 cosVal = pCoef[ia * 2]; 00287 sinVal = pCoef[(ia * 2) + 1]; 00288 ia = ia + twidCoefModifier; 00289 00290 // loop for butterfly 00291 for (i = j; i < fftLen; i += n1) 00292 { 00293 l = i + n2; 00294 xt = pSrc[2 * i] - pSrc[2 * l]; 00295 pSrc[2 * i] = (pSrc[2 * i] + pSrc[2 * l]) >> 1u; 00296 00297 yt = pSrc[2 * i + 1] - pSrc[2 * l + 1]; 00298 pSrc[2 * i + 1] = (pSrc[2 * l + 1] + pSrc[2 * i + 1]) >> 1u; 00299 00300 mult_32x32_keep32_R(p0, xt, cosVal); 00301 mult_32x32_keep32_R(p1, yt, cosVal); 00302 multSub_32x32_keep32_R(p0, yt, sinVal); 00303 multAcc_32x32_keep32_R(p1, xt, sinVal); 00304 00305 pSrc[2u * l] = p0; 00306 pSrc[2u * l + 1u] = p1; 00307 } // butterfly loop end 00308 00309 } // groups loop end 00310 00311 twidCoefModifier = twidCoefModifier << 1u; 00312 } // stages loop end 00313 00314 n1 = n2; 00315 n2 = n2 >> 1; 00316 ia = 0; 00317 00318 cosVal = pCoef[ia * 2]; 00319 sinVal = pCoef[(ia * 2) + 1]; 00320 ia = ia + twidCoefModifier; 00321 00322 // loop for butterfly 00323 for (i = 0; i < fftLen; i += n1) 00324 { 00325 l = i + n2; 00326 xt = pSrc[2 * i] - pSrc[2 * l]; 00327 pSrc[2 * i] = (pSrc[2 * i] + pSrc[2 * l]); 00328 00329 yt = pSrc[2 * i + 1] - pSrc[2 * l + 1]; 00330 pSrc[2 * i + 1] = (pSrc[2 * l + 1] + pSrc[2 * i + 1]); 00331 00332 pSrc[2u * l] = xt; 00333 00334 pSrc[2u * l + 1u] = yt; 00335 00336 i += n1; 00337 l = i + n2; 00338 00339 xt = pSrc[2 * i] - pSrc[2 * l]; 00340 pSrc[2 * i] = (pSrc[2 * i] + pSrc[2 * l]); 00341 00342 yt = pSrc[2 * i + 1] - pSrc[2 * l + 1]; 00343 pSrc[2 * i + 1] = (pSrc[2 * l + 1] + pSrc[2 * i + 1]); 00344 00345 pSrc[2u * l] = xt; 00346 00347 pSrc[2u * l + 1u] = yt; 00348 00349 } // butterfly loop end 00350 00351 }
Generated on Tue Jul 12 2022 11:59:15 by 1.7.2