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_rfft_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_rfft_f32.c 00009 * 00010 * Description: RFFT & RIFFT Floating point process function 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 groupTransforms 00034 */ 00035 00036 /** 00037 * @defgroup RFFT_RIFFT Real FFT Functions 00038 * 00039 * \par 00040 * Complex FFT/IFFT typically assumes complex input and output. However many applications use real valued data in time domain. 00041 * Real FFT/IFFT efficiently process real valued sequences with the advantage of requirement of low memory and with less complexity. 00042 * 00043 * \par 00044 * This set of functions implements Real Fast Fourier Transforms(RFFT) and Real Inverse Fast Fourier Transform(RIFFT) 00045 * for Q15, Q31, and floating-point data types. 00046 * 00047 * 00048 * \par Algorithm: 00049 * 00050 * <b>Real Fast Fourier Transform:</b> 00051 * \par 00052 * Real FFT of N-point is calculated using CFFT of N/2-point and Split RFFT process as shown below figure. 00053 * \par 00054 * \image html RFFT.gif "Real Fast Fourier Transform" 00055 * \par 00056 * The RFFT functions operate on blocks of input and output data and each call to the function processes 00057 * <code>fftLenR</code> samples through the transform. <code>pSrc</code> points to input array containing <code>fftLenR</code> values. 00058 * <code>pDst</code> points to output array containing <code>2*fftLenR</code> values. \n 00059 * Input for real FFT is in the order of 00060 * <pre>{real[0], real[1], real[2], real[3], ..}</pre> 00061 * Output for real FFT is complex and are in the order of 00062 * <pre>{real(0), imag(0), real(1), imag(1), ...}</pre> 00063 * 00064 * <b>Real Inverse Fast Fourier Transform:</b> 00065 * \par 00066 * Real IFFT of N-point is calculated using Split RIFFT process and CFFT of N/2-point as shown below figure. 00067 * \par 00068 * \image html RIFFT.gif "Real Inverse Fast Fourier Transform" 00069 * \par 00070 * The RIFFT functions operate on blocks of input and output data and each call to the function processes 00071 * <code>2*fftLenR</code> samples through the transform. <code>pSrc</code> points to input array containing <code>2*fftLenR</code> values. 00072 * <code>pDst</code> points to output array containing <code>fftLenR</code> values. \n 00073 * Input for real IFFT is complex and are in the order of 00074 * <pre>{real(0), imag(0), real(1), imag(1), ...}</pre> 00075 * Output for real IFFT is real and in the order of 00076 * <pre>{real[0], real[1], real[2], real[3], ..}</pre> 00077 * 00078 * \par Lengths supported by the transform: 00079 * \par 00080 * Real FFT/IFFT supports the lengths [128, 512, 2048], as it internally uses CFFT/CIFFT. 00081 * 00082 * \par Instance Structure 00083 * A separate instance structure must be defined for each Instance but the twiddle factors can be reused. 00084 * There are separate instance structure declarations for each of the 3 supported data types. 00085 * 00086 * \par Initialization Functions 00087 * There is also an associated initialization function for each data type. 00088 * The initialization function performs the following operations: 00089 * - Sets the values of the internal structure fields. 00090 * - Initializes twiddle factor tables. 00091 * - Initializes CFFT data structure fields. 00092 * \par 00093 * Use of the initialization function is optional. 00094 * However, if the initialization function is used, then the instance structure cannot be placed into a const data section. 00095 * To place an instance structure into a const data section, the instance structure must be manually initialized. 00096 * Manually initialize the instance structure as follows: 00097 * <pre> 00098 *arm_rfft_instance_f32 S = {fftLenReal, fftLenBy2, ifftFlagR, bitReverseFlagR, twidCoefRModifier, pTwiddleAReal, pTwiddleBReal, pCfft}; 00099 *arm_rfft_instance_q31 S = {fftLenReal, fftLenBy2, ifftFlagR, bitReverseFlagR, twidCoefRModifier, pTwiddleAReal, pTwiddleBReal, pCfft}; 00100 *arm_rfft_instance_q15 S = {fftLenReal, fftLenBy2, ifftFlagR, bitReverseFlagR, twidCoefRModifier, pTwiddleAReal, pTwiddleBReal, pCfft}; 00101 * </pre> 00102 * where <code>fftLenReal</code> length of RFFT/RIFFT; <code>fftLenBy2</code> length of CFFT/CIFFT. 00103 * <code>ifftFlagR</code> Flag for selection of RFFT or RIFFT(Set ifftFlagR to calculate RIFFT otherwise calculates RFFT); 00104 * <code>bitReverseFlagR</code> Flag for selection of output order(Set bitReverseFlagR to output in normal order otherwise output in bit reversed order); 00105 * <code>twidCoefRModifier</code> modifier for twiddle factor table which supports 128, 512, 2048 RFFT lengths with same table; 00106 * <code>pTwiddleAReal</code>points to A array of twiddle coefficients; <code>pTwiddleBReal</code>points to B array of twiddle coefficients; 00107 * <code>pCfft</code> points to the CFFT Instance structure. The CFFT structure also needs to be initialized, refer to arm_cfft_radix4_f32() for details regarding 00108 * static initialization of cfft structure. 00109 * 00110 * \par Fixed-Point Behavior 00111 * Care must be taken when using the fixed-point versions of the RFFT/RIFFT function. 00112 * Refer to the function specific documentation below for usage guidelines. 00113 */ 00114 00115 /*-------------------------------------------------------------------- 00116 * Internal functions prototypes 00117 *--------------------------------------------------------------------*/ 00118 00119 void arm_split_rfft_f32( 00120 float32_t * pSrc, 00121 uint32_t fftLen, 00122 float32_t * pATable, 00123 float32_t * pBTable, 00124 float32_t * pDst, 00125 uint32_t modifier); 00126 void arm_split_rifft_f32( 00127 float32_t * pSrc, 00128 uint32_t fftLen, 00129 float32_t * pATable, 00130 float32_t * pBTable, 00131 float32_t * pDst, 00132 uint32_t modifier); 00133 00134 /** 00135 * @addtogroup RFFT_RIFFT 00136 * @{ 00137 */ 00138 00139 /** 00140 * @brief Processing function for the floating-point RFFT/RIFFT. 00141 * @param[in] *S points to an instance of the floating-point RFFT/RIFFT structure. 00142 * @param[in] *pSrc points to the input buffer. 00143 * @param[out] *pDst points to the output buffer. 00144 * @return none. 00145 */ 00146 00147 void arm_rfft_f32( 00148 const arm_rfft_instance_f32 * S, 00149 float32_t * pSrc, 00150 float32_t * pDst) 00151 { 00152 const arm_cfft_radix4_instance_f32 *S_CFFT = S->pCfft; 00153 00154 00155 /* Calculation of Real IFFT of input */ 00156 if(S->ifftFlagR == 1u) 00157 { 00158 /* Real IFFT core process */ 00159 arm_split_rifft_f32(pSrc, S->fftLenBy2, S->pTwiddleAReal, 00160 S->pTwiddleBReal, pDst, S->twidCoefRModifier); 00161 00162 00163 /* Complex radix-4 IFFT process */ 00164 arm_radix4_butterfly_inverse_f32(pDst, S_CFFT->fftLen, 00165 S_CFFT->pTwiddle, 00166 S_CFFT->twidCoefModifier, 00167 S_CFFT->onebyfftLen); 00168 00169 /* Bit reversal process */ 00170 if(S->bitReverseFlagR == 1u) 00171 { 00172 arm_bitreversal_f32(pDst, S_CFFT->fftLen, 00173 S_CFFT->bitRevFactor, S_CFFT->pBitRevTable); 00174 } 00175 } 00176 else 00177 { 00178 00179 /* Calculation of RFFT of input */ 00180 00181 /* Complex radix-4 FFT process */ 00182 arm_radix4_butterfly_f32(pSrc, S_CFFT->fftLen, 00183 S_CFFT->pTwiddle, S_CFFT->twidCoefModifier); 00184 00185 /* Bit reversal process */ 00186 if(S->bitReverseFlagR == 1u) 00187 { 00188 arm_bitreversal_f32(pSrc, S_CFFT->fftLen, 00189 S_CFFT->bitRevFactor, S_CFFT->pBitRevTable); 00190 } 00191 00192 00193 /* Real FFT core process */ 00194 arm_split_rfft_f32(pSrc, S->fftLenBy2, S->pTwiddleAReal, 00195 S->pTwiddleBReal, pDst, S->twidCoefRModifier); 00196 } 00197 00198 } 00199 00200 /** 00201 * @} end of RFFT_RIFFT group 00202 */ 00203 00204 /** 00205 * @brief Core Real FFT process 00206 * @param[in] *pSrc points to the input buffer. 00207 * @param[in] fftLen length of FFT. 00208 * @param[in] *pATable points to the twiddle Coef A buffer. 00209 * @param[in] *pBTable points to the twiddle Coef B buffer. 00210 * @param[out] *pDst points to the output buffer. 00211 * @param[in] modifier twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. 00212 * @return none. 00213 */ 00214 00215 void arm_split_rfft_f32( 00216 float32_t * pSrc, 00217 uint32_t fftLen, 00218 float32_t * pATable, 00219 float32_t * pBTable, 00220 float32_t * pDst, 00221 uint32_t modifier) 00222 { 00223 uint32_t i; /* Loop Counter */ 00224 float32_t outR, outI; /* Temporary variables for output */ 00225 float32_t *pCoefA, *pCoefB; /* Temporary pointers for twiddle factors */ 00226 float32_t CoefA1, CoefA2, CoefB1; /* Temporary variables for twiddle coefficients */ 00227 float32_t *pDst1 = &pDst[2], *pDst2 = &pDst[(4u * fftLen) - 1u]; /* temp pointers for output buffer */ 00228 float32_t *pSrc1 = &pSrc[2], *pSrc2 = &pSrc[(2u * fftLen) - 1u]; /* temp pointers for input buffer */ 00229 00230 00231 pSrc[2u * fftLen] = pSrc[0]; 00232 pSrc[(2u * fftLen) + 1u] = pSrc[1]; 00233 00234 /* Init coefficient pointers */ 00235 pCoefA = &pATable[modifier * 2u]; 00236 pCoefB = &pBTable[modifier * 2u]; 00237 00238 i = fftLen - 1u; 00239 00240 while(i > 0u) 00241 { 00242 /* 00243 outR = (pSrc[2 * i] * pATable[2 * i] - pSrc[2 * i + 1] * pATable[2 * i + 1] 00244 + pSrc[2 * n - 2 * i] * pBTable[2 * i] + 00245 pSrc[2 * n - 2 * i + 1] * pBTable[2 * i + 1]); 00246 */ 00247 00248 /* outI = (pIn[2 * i + 1] * pATable[2 * i] + pIn[2 * i] * pATable[2 * i + 1] + 00249 pIn[2 * n - 2 * i] * pBTable[2 * i + 1] - 00250 pIn[2 * n - 2 * i + 1] * pBTable[2 * i]); */ 00251 00252 /* read pATable[2 * i] */ 00253 CoefA1 = *pCoefA++; 00254 /* pATable[2 * i + 1] */ 00255 CoefA2 = *pCoefA; 00256 00257 /* pSrc[2 * i] * pATable[2 * i] */ 00258 outR = *pSrc1 * CoefA1; 00259 /* pSrc[2 * i] * CoefA2 */ 00260 outI = *pSrc1++ * CoefA2; 00261 00262 /* (pSrc[2 * i + 1] + pSrc[2 * fftLen - 2 * i + 1]) * CoefA2 */ 00263 outR -= (*pSrc1 + *pSrc2) * CoefA2; 00264 /* pSrc[2 * i + 1] * CoefA1 */ 00265 outI += *pSrc1++ * CoefA1; 00266 00267 CoefB1 = *pCoefB; 00268 00269 /* pSrc[2 * fftLen - 2 * i + 1] * CoefB1 */ 00270 outI -= *pSrc2-- * CoefB1; 00271 /* pSrc[2 * fftLen - 2 * i] * CoefA2 */ 00272 outI -= *pSrc2 * CoefA2; 00273 00274 /* pSrc[2 * fftLen - 2 * i] * CoefB1 */ 00275 outR += *pSrc2-- * CoefB1; 00276 00277 /* write output */ 00278 *pDst1++ = outR; 00279 *pDst1++ = outI; 00280 00281 /* write complex conjugate output */ 00282 *pDst2-- = -outI; 00283 *pDst2-- = outR; 00284 00285 /* update coefficient pointer */ 00286 pCoefB = pCoefB + (modifier * 2u); 00287 pCoefA = pCoefA + ((modifier * 2u) - 1u); 00288 00289 i--; 00290 00291 } 00292 00293 pDst[2u * fftLen] = pSrc[0] - pSrc[1]; 00294 pDst[(2u * fftLen) + 1u] = 0.0f; 00295 00296 pDst[0] = pSrc[0] + pSrc[1]; 00297 pDst[1] = 0.0f; 00298 00299 } 00300 00301 00302 /** 00303 * @brief Core Real IFFT process 00304 * @param[in] *pSrc points to the input buffer. 00305 * @param[in] fftLen length of FFT. 00306 * @param[in] *pATable points to the twiddle Coef A buffer. 00307 * @param[in] *pBTable points to the twiddle Coef B buffer. 00308 * @param[out] *pDst points to the output buffer. 00309 * @param[in] modifier twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. 00310 * @return none. 00311 */ 00312 00313 void arm_split_rifft_f32( 00314 float32_t * pSrc, 00315 uint32_t fftLen, 00316 float32_t * pATable, 00317 float32_t * pBTable, 00318 float32_t * pDst, 00319 uint32_t modifier) 00320 { 00321 float32_t outR, outI; /* Temporary variables for output */ 00322 float32_t *pCoefA, *pCoefB; /* Temporary pointers for twiddle factors */ 00323 float32_t CoefA1, CoefA2, CoefB1; /* Temporary variables for twiddle coefficients */ 00324 float32_t *pSrc1 = &pSrc[0], *pSrc2 = &pSrc[(2u * fftLen) + 1u]; 00325 00326 pCoefA = &pATable[0]; 00327 pCoefB = &pBTable[0]; 00328 00329 while(fftLen > 0u) 00330 { 00331 /* 00332 outR = (pIn[2 * i] * pATable[2 * i] + pIn[2 * i + 1] * pATable[2 * i + 1] + 00333 pIn[2 * n - 2 * i] * pBTable[2 * i] - 00334 pIn[2 * n - 2 * i + 1] * pBTable[2 * i + 1]); 00335 00336 outI = (pIn[2 * i + 1] * pATable[2 * i] - pIn[2 * i] * pATable[2 * i + 1] - 00337 pIn[2 * n - 2 * i] * pBTable[2 * i + 1] - 00338 pIn[2 * n - 2 * i + 1] * pBTable[2 * i]); 00339 00340 */ 00341 00342 CoefA1 = *pCoefA++; 00343 CoefA2 = *pCoefA; 00344 00345 /* outR = (pSrc[2 * i] * CoefA1 */ 00346 outR = *pSrc1 * CoefA1; 00347 00348 /* - pSrc[2 * i] * CoefA2 */ 00349 outI = -(*pSrc1++) * CoefA2; 00350 00351 /* (pSrc[2 * i + 1] + pSrc[2 * fftLen - 2 * i + 1]) * CoefA2 */ 00352 outR += (*pSrc1 + *pSrc2) * CoefA2; 00353 00354 /* pSrc[2 * i + 1] * CoefA1 */ 00355 outI += (*pSrc1++) * CoefA1; 00356 00357 CoefB1 = *pCoefB; 00358 00359 /* - pSrc[2 * fftLen - 2 * i + 1] * CoefB1 */ 00360 outI -= *pSrc2-- * CoefB1; 00361 00362 /* pSrc[2 * fftLen - 2 * i] * CoefB1 */ 00363 outR += *pSrc2 * CoefB1; 00364 00365 /* pSrc[2 * fftLen - 2 * i] * CoefA2 */ 00366 outI += *pSrc2-- * CoefA2; 00367 00368 /* write output */ 00369 *pDst++ = outR; 00370 *pDst++ = outI; 00371 00372 /* update coefficient pointer */ 00373 pCoefB = pCoefB + (modifier * 2u); 00374 pCoefA = pCoefA + ((modifier * 2u) - 1u); 00375 00376 /* Decrement loop count */ 00377 fftLen--; 00378 } 00379 00380 }
Generated on Tue Jul 12 2022 19:55:43 by
1.7.2
