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_rfft_f32.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_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 18:44:10 by
1.7.2
