CMSIS DSP library
Dependents: performance_timer Surfboard_ gps2rtty Capstone ... more
arm_rfft_f32.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_rfft_f32.c 00009 * 00010 * Description: RFFT & RIFFT Floating point process 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 extern void arm_radix4_butterfly_f32( 00044 float32_t * pSrc, 00045 uint16_t fftLen, 00046 float32_t * pCoef, 00047 uint16_t twidCoefModifier); 00048 00049 extern void arm_radix4_butterfly_inverse_f32( 00050 float32_t * pSrc, 00051 uint16_t fftLen, 00052 float32_t * pCoef, 00053 uint16_t twidCoefModifier, 00054 float32_t onebyfftLen); 00055 00056 extern void arm_bitreversal_f32( 00057 float32_t * pSrc, 00058 uint16_t fftSize, 00059 uint16_t bitRevFactor, 00060 uint16_t * pBitRevTab); 00061 00062 /** 00063 * @ingroup groupTransforms 00064 */ 00065 00066 /*-------------------------------------------------------------------- 00067 * Internal functions prototypes 00068 *--------------------------------------------------------------------*/ 00069 00070 void arm_split_rfft_f32( 00071 float32_t * pSrc, 00072 uint32_t fftLen, 00073 float32_t * pATable, 00074 float32_t * pBTable, 00075 float32_t * pDst, 00076 uint32_t modifier); 00077 void arm_split_rifft_f32( 00078 float32_t * pSrc, 00079 uint32_t fftLen, 00080 float32_t * pATable, 00081 float32_t * pBTable, 00082 float32_t * pDst, 00083 uint32_t modifier); 00084 00085 /** 00086 * @addtogroup RealFFT 00087 * @{ 00088 */ 00089 00090 /** 00091 * @brief Processing function for the floating-point RFFT/RIFFT. 00092 * @deprecated Do not use this function. It has been superceded by \ref arm_rfft_fast_f32 and will be removed 00093 * in the future. 00094 * @param[in] *S points to an instance of the floating-point RFFT/RIFFT structure. 00095 * @param[in] *pSrc points to the input buffer. 00096 * @param[out] *pDst points to the output buffer. 00097 * @return none. 00098 */ 00099 00100 void arm_rfft_f32( 00101 const arm_rfft_instance_f32 * S, 00102 float32_t * pSrc, 00103 float32_t * pDst) 00104 { 00105 const arm_cfft_radix4_instance_f32 *S_CFFT = S->pCfft; 00106 00107 00108 /* Calculation of Real IFFT of input */ 00109 if(S->ifftFlagR == 1u) 00110 { 00111 /* Real IFFT core process */ 00112 arm_split_rifft_f32(pSrc, S->fftLenBy2, S->pTwiddleAReal, 00113 S->pTwiddleBReal, pDst, S->twidCoefRModifier); 00114 00115 00116 /* Complex radix-4 IFFT process */ 00117 arm_radix4_butterfly_inverse_f32(pDst, S_CFFT->fftLen, 00118 S_CFFT->pTwiddle, 00119 S_CFFT->twidCoefModifier, 00120 S_CFFT->onebyfftLen); 00121 00122 /* Bit reversal process */ 00123 if(S->bitReverseFlagR == 1u) 00124 { 00125 arm_bitreversal_f32(pDst, S_CFFT->fftLen, 00126 S_CFFT->bitRevFactor, S_CFFT->pBitRevTable); 00127 } 00128 } 00129 else 00130 { 00131 00132 /* Calculation of RFFT of input */ 00133 00134 /* Complex radix-4 FFT process */ 00135 arm_radix4_butterfly_f32(pSrc, S_CFFT->fftLen, 00136 S_CFFT->pTwiddle, S_CFFT->twidCoefModifier); 00137 00138 /* Bit reversal process */ 00139 if(S->bitReverseFlagR == 1u) 00140 { 00141 arm_bitreversal_f32(pSrc, S_CFFT->fftLen, 00142 S_CFFT->bitRevFactor, S_CFFT->pBitRevTable); 00143 } 00144 00145 00146 /* Real FFT core process */ 00147 arm_split_rfft_f32(pSrc, S->fftLenBy2, S->pTwiddleAReal, 00148 S->pTwiddleBReal, pDst, S->twidCoefRModifier); 00149 } 00150 00151 } 00152 00153 /** 00154 * @} end of RealFFT group 00155 */ 00156 00157 /** 00158 * @brief Core Real FFT process 00159 * @param[in] *pSrc points to the input buffer. 00160 * @param[in] fftLen length of FFT. 00161 * @param[in] *pATable points to the twiddle Coef A buffer. 00162 * @param[in] *pBTable points to the twiddle Coef B buffer. 00163 * @param[out] *pDst points to the output buffer. 00164 * @param[in] modifier twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. 00165 * @return none. 00166 */ 00167 00168 void arm_split_rfft_f32( 00169 float32_t * pSrc, 00170 uint32_t fftLen, 00171 float32_t * pATable, 00172 float32_t * pBTable, 00173 float32_t * pDst, 00174 uint32_t modifier) 00175 { 00176 uint32_t i; /* Loop Counter */ 00177 float32_t outR, outI; /* Temporary variables for output */ 00178 float32_t *pCoefA, *pCoefB; /* Temporary pointers for twiddle factors */ 00179 float32_t CoefA1, CoefA2, CoefB1; /* Temporary variables for twiddle coefficients */ 00180 float32_t *pDst1 = &pDst[2], *pDst2 = &pDst[(4u * fftLen) - 1u]; /* temp pointers for output buffer */ 00181 float32_t *pSrc1 = &pSrc[2], *pSrc2 = &pSrc[(2u * fftLen) - 1u]; /* temp pointers for input buffer */ 00182 00183 /* Init coefficient pointers */ 00184 pCoefA = &pATable[modifier * 2u]; 00185 pCoefB = &pBTable[modifier * 2u]; 00186 00187 i = fftLen - 1u; 00188 00189 while(i > 0u) 00190 { 00191 /* 00192 outR = (pSrc[2 * i] * pATable[2 * i] - pSrc[2 * i + 1] * pATable[2 * i + 1] 00193 + pSrc[2 * n - 2 * i] * pBTable[2 * i] + 00194 pSrc[2 * n - 2 * i + 1] * pBTable[2 * i + 1]); 00195 */ 00196 00197 /* outI = (pIn[2 * i + 1] * pATable[2 * i] + pIn[2 * i] * pATable[2 * i + 1] + 00198 pIn[2 * n - 2 * i] * pBTable[2 * i + 1] - 00199 pIn[2 * n - 2 * i + 1] * pBTable[2 * i]); */ 00200 00201 /* read pATable[2 * i] */ 00202 CoefA1 = *pCoefA++; 00203 /* pATable[2 * i + 1] */ 00204 CoefA2 = *pCoefA; 00205 00206 /* pSrc[2 * i] * pATable[2 * i] */ 00207 outR = *pSrc1 * CoefA1; 00208 /* pSrc[2 * i] * CoefA2 */ 00209 outI = *pSrc1++ * CoefA2; 00210 00211 /* (pSrc[2 * i + 1] + pSrc[2 * fftLen - 2 * i + 1]) * CoefA2 */ 00212 outR -= (*pSrc1 + *pSrc2) * CoefA2; 00213 /* pSrc[2 * i + 1] * CoefA1 */ 00214 outI += *pSrc1++ * CoefA1; 00215 00216 CoefB1 = *pCoefB; 00217 00218 /* pSrc[2 * fftLen - 2 * i + 1] * CoefB1 */ 00219 outI -= *pSrc2-- * CoefB1; 00220 /* pSrc[2 * fftLen - 2 * i] * CoefA2 */ 00221 outI -= *pSrc2 * CoefA2; 00222 00223 /* pSrc[2 * fftLen - 2 * i] * CoefB1 */ 00224 outR += *pSrc2-- * CoefB1; 00225 00226 /* write output */ 00227 *pDst1++ = outR; 00228 *pDst1++ = outI; 00229 00230 /* write complex conjugate output */ 00231 *pDst2-- = -outI; 00232 *pDst2-- = outR; 00233 00234 /* update coefficient pointer */ 00235 pCoefB = pCoefB + (modifier * 2u); 00236 pCoefA = pCoefA + ((modifier * 2u) - 1u); 00237 00238 i--; 00239 00240 } 00241 00242 pDst[2u * fftLen] = pSrc[0] - pSrc[1]; 00243 pDst[(2u * fftLen) + 1u] = 0.0f; 00244 00245 pDst[0] = pSrc[0] + pSrc[1]; 00246 pDst[1] = 0.0f; 00247 00248 } 00249 00250 00251 /** 00252 * @brief Core Real IFFT process 00253 * @param[in] *pSrc points to the input buffer. 00254 * @param[in] fftLen length of FFT. 00255 * @param[in] *pATable points to the twiddle Coef A buffer. 00256 * @param[in] *pBTable points to the twiddle Coef B buffer. 00257 * @param[out] *pDst points to the output buffer. 00258 * @param[in] modifier twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. 00259 * @return none. 00260 */ 00261 00262 void arm_split_rifft_f32( 00263 float32_t * pSrc, 00264 uint32_t fftLen, 00265 float32_t * pATable, 00266 float32_t * pBTable, 00267 float32_t * pDst, 00268 uint32_t modifier) 00269 { 00270 float32_t outR, outI; /* Temporary variables for output */ 00271 float32_t *pCoefA, *pCoefB; /* Temporary pointers for twiddle factors */ 00272 float32_t CoefA1, CoefA2, CoefB1; /* Temporary variables for twiddle coefficients */ 00273 float32_t *pSrc1 = &pSrc[0], *pSrc2 = &pSrc[(2u * fftLen) + 1u]; 00274 00275 pCoefA = &pATable[0]; 00276 pCoefB = &pBTable[0]; 00277 00278 while(fftLen > 0u) 00279 { 00280 /* 00281 outR = (pIn[2 * i] * pATable[2 * i] + pIn[2 * i + 1] * pATable[2 * i + 1] + 00282 pIn[2 * n - 2 * i] * pBTable[2 * i] - 00283 pIn[2 * n - 2 * i + 1] * pBTable[2 * i + 1]); 00284 00285 outI = (pIn[2 * i + 1] * pATable[2 * i] - pIn[2 * i] * pATable[2 * i + 1] - 00286 pIn[2 * n - 2 * i] * pBTable[2 * i + 1] - 00287 pIn[2 * n - 2 * i + 1] * pBTable[2 * i]); 00288 00289 */ 00290 00291 CoefA1 = *pCoefA++; 00292 CoefA2 = *pCoefA; 00293 00294 /* outR = (pSrc[2 * i] * CoefA1 */ 00295 outR = *pSrc1 * CoefA1; 00296 00297 /* - pSrc[2 * i] * CoefA2 */ 00298 outI = -(*pSrc1++) * CoefA2; 00299 00300 /* (pSrc[2 * i + 1] + pSrc[2 * fftLen - 2 * i + 1]) * CoefA2 */ 00301 outR += (*pSrc1 + *pSrc2) * CoefA2; 00302 00303 /* pSrc[2 * i + 1] * CoefA1 */ 00304 outI += (*pSrc1++) * CoefA1; 00305 00306 CoefB1 = *pCoefB; 00307 00308 /* - pSrc[2 * fftLen - 2 * i + 1] * CoefB1 */ 00309 outI -= *pSrc2-- * CoefB1; 00310 00311 /* pSrc[2 * fftLen - 2 * i] * CoefB1 */ 00312 outR += *pSrc2 * CoefB1; 00313 00314 /* pSrc[2 * fftLen - 2 * i] * CoefA2 */ 00315 outI += *pSrc2-- * CoefA2; 00316 00317 /* write output */ 00318 *pDst++ = outR; 00319 *pDst++ = outI; 00320 00321 /* update coefficient pointer */ 00322 pCoefB = pCoefB + (modifier * 2u); 00323 pCoefA = pCoefA + ((modifier * 2u) - 1u); 00324 00325 /* Decrement loop count */ 00326 fftLen--; 00327 } 00328 00329 }
Generated on Tue Jul 12 2022 11:59:18 by 1.7.2