CMSIS DSP Library from CMSIS 2.0. See http://www.onarm.com/cmsis/ for full details
Dependents: K22F_DSP_Matrix_least_square BNO055-ELEC3810 1BNO055 ECE4180Project--Slave2 ... more
arm_rfft_q31.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_q31.c 00009 * 00010 * Description: RFFT & RIFFT Q31 process function 00011 * 00012 * 00013 * Target Processor: Cortex-M4/Cortex-M3 00014 * 00015 * Version 1.0.3 2010/11/29 00016 * Re-organized the CMSIS folders and updated documentation. 00017 * 00018 * Version 1.0.2 2010/11/11 00019 * Documentation updated. 00020 * 00021 * Version 1.0.1 2010/10/05 00022 * Production release and review comments incorporated. 00023 * 00024 * Version 1.0.0 2010/09/20 00025 * Production release and review comments incorporated. 00026 * 00027 * Version 0.0.7 2010/06/10 00028 * Misra-C changes done 00029 * -------------------------------------------------------------------- */ 00030 00031 #include "arm_math.h" 00032 00033 /*-------------------------------------------------------------------- 00034 * Internal functions prototypes 00035 --------------------------------------------------------------------*/ 00036 00037 void arm_split_rfft_q31( 00038 q31_t * pSrc, 00039 uint32_t fftLen, 00040 q31_t * pATable, 00041 q31_t * pBTable, 00042 q31_t * pDst, 00043 uint32_t modifier); 00044 00045 void arm_split_rifft_q31( 00046 q31_t * pSrc, 00047 uint32_t fftLen, 00048 q31_t * pATable, 00049 q31_t * pBTable, 00050 q31_t * pDst, 00051 uint32_t modifier); 00052 00053 /** 00054 * @addtogroup RFFT_RIFFT 00055 * @{ 00056 */ 00057 00058 /** 00059 * @brief Processing function for the Q31 RFFT/RIFFT. 00060 * @param[in] *S points to an instance of the Q31 RFFT/RIFFT structure. 00061 * @param[in] *pSrc points to the input buffer. 00062 * @param[out] *pDst points to the output buffer. 00063 * @return none. 00064 * 00065 * \par Input an output formats: 00066 * \par 00067 * Internally input is downscaled by 2 for every stage to avoid saturations inside CFFT/CIFFT process. 00068 * Hence the output format is different for different RFFT sizes. 00069 * The input and output formats for different RFFT sizes and number of bits to upscale are mentioned in the tables below for RFFT and RIFFT: 00070 * \par 00071 * \image html RFFTQ31.gif "Input and Output Formats for Q31 RFFT" 00072 * 00073 * \par 00074 * \image html RIFFTQ31.gif "Input and Output Formats for Q31 RIFFT" 00075 */ 00076 00077 void arm_rfft_q31( 00078 const arm_rfft_instance_q31 * S, 00079 q31_t * pSrc, 00080 q31_t * pDst) 00081 { 00082 const arm_cfft_radix4_instance_q31 *S_CFFT = S->pCfft; 00083 00084 /* Calculation of RIFFT of input */ 00085 if(S->ifftFlagR == 1u) 00086 { 00087 /* Real IFFT core process */ 00088 arm_split_rifft_q31(pSrc, S->fftLenBy2, S->pTwiddleAReal, 00089 S->pTwiddleBReal, pDst, S->twidCoefRModifier); 00090 00091 /* Complex readix-4 IFFT process */ 00092 arm_radix4_butterfly_inverse_q31(pDst, S_CFFT->fftLen, 00093 S_CFFT->pTwiddle, 00094 S_CFFT->twidCoefModifier); 00095 /* Bit reversal process */ 00096 if(S->bitReverseFlagR == 1u) 00097 { 00098 arm_bitreversal_q31(pDst, S_CFFT->fftLen, 00099 S_CFFT->bitRevFactor, S_CFFT->pBitRevTable); 00100 } 00101 } 00102 else 00103 { 00104 /* Calculation of RFFT of input */ 00105 00106 /* Complex readix-4 FFT process */ 00107 arm_radix4_butterfly_q31(pSrc, S_CFFT->fftLen, 00108 S_CFFT->pTwiddle, S_CFFT->twidCoefModifier); 00109 00110 /* Bit reversal process */ 00111 if(S->bitReverseFlagR == 1u) 00112 { 00113 arm_bitreversal_q31(pSrc, S_CFFT->fftLen, 00114 S_CFFT->bitRevFactor, S_CFFT->pBitRevTable); 00115 } 00116 00117 /* Real FFT core process */ 00118 arm_split_rfft_q31(pSrc, S->fftLenBy2, S->pTwiddleAReal, 00119 S->pTwiddleBReal, pDst, S->twidCoefRModifier); 00120 } 00121 00122 } 00123 00124 00125 /** 00126 * @} end of RFFT_RIFFT group 00127 */ 00128 00129 /** 00130 * @brief Core Real FFT process 00131 * @param[in] *pSrc points to the input buffer. 00132 * @param[in] fftLen length of FFT. 00133 * @param[in] *pATable points to the twiddle Coef A buffer. 00134 * @param[in] *pBTable points to the twiddle Coef B buffer. 00135 * @param[out] *pDst points to the output buffer. 00136 * @param[in] modifier twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. 00137 * @return none. 00138 */ 00139 00140 void arm_split_rfft_q31( 00141 q31_t * pSrc, 00142 uint32_t fftLen, 00143 q31_t * pATable, 00144 q31_t * pBTable, 00145 q31_t * pDst, 00146 uint32_t modifier) 00147 { 00148 uint32_t i; /* Loop Counter */ 00149 q31_t outR, outI; /* Temporary variables for output */ 00150 q31_t *pCoefA, *pCoefB; /* Temporary pointers for twiddle factors */ 00151 q31_t CoefA1, CoefA2, CoefB1; /* Temporary variables for twiddle coefficients */ 00152 q31_t *pOut1 = &pDst[2], *pOut2 = &pDst[(4u * fftLen) - 1u]; 00153 q31_t *pIn1 = &pSrc[2], *pIn2 = &pSrc[(2u * fftLen) - 1u]; 00154 00155 pSrc[2u * fftLen] = pSrc[0]; 00156 pSrc[(2u * fftLen) + 1u] = pSrc[1]; 00157 00158 /* Init coefficient pointers */ 00159 pCoefA = &pATable[modifier * 2u]; 00160 pCoefB = &pBTable[modifier * 2u]; 00161 00162 i = fftLen - 1u; 00163 00164 while(i > 0u) 00165 { 00166 /* 00167 outR = (pSrc[2 * i] * pATable[2 * i] - pSrc[2 * i + 1] * pATable[2 * i + 1] 00168 + pSrc[2 * n - 2 * i] * pBTable[2 * i] + 00169 pSrc[2 * n - 2 * i + 1] * pBTable[2 * i + 1]); 00170 */ 00171 00172 /* outI = (pIn[2 * i + 1] * pATable[2 * i] + pIn[2 * i] * pATable[2 * i + 1] + 00173 pIn[2 * n - 2 * i] * pBTable[2 * i + 1] - 00174 pIn[2 * n - 2 * i + 1] * pBTable[2 * i]); */ 00175 00176 CoefA1 = *pCoefA++; 00177 CoefA2 = *pCoefA; 00178 00179 /* outR = (pSrc[2 * i] * pATable[2 * i] */ 00180 outR = ((int32_t) (((q63_t) * pIn1 * CoefA1) >> 32)); 00181 00182 /* outI = pIn[2 * i] * pATable[2 * i + 1] */ 00183 outI = ((int32_t) (((q63_t) * pIn1++ * CoefA2) >> 32)); 00184 00185 /* - pSrc[2 * i + 1] * pATable[2 * i + 1] */ 00186 outR = 00187 (q31_t) ((((q63_t) outR << 32) + ((q63_t) * pIn1 * (-CoefA2))) >> 32); 00188 00189 /* (pIn[2 * i + 1] * pATable[2 * i] */ 00190 outI = 00191 (q31_t) ((((q63_t) outI << 32) + ((q63_t) * pIn1++ * (CoefA1))) >> 32); 00192 00193 /* pSrc[2 * n - 2 * i] * pBTable[2 * i] */ 00194 outR = 00195 (q31_t) ((((q63_t) outR << 32) + ((q63_t) * pIn2 * (-CoefA2))) >> 32); 00196 CoefB1 = *pCoefB; 00197 00198 /* pIn[2 * n - 2 * i] * pBTable[2 * i + 1] */ 00199 outI = 00200 (q31_t) ((((q63_t) outI << 32) + ((q63_t) * pIn2-- * (-CoefB1))) >> 32); 00201 00202 /* pSrc[2 * n - 2 * i + 1] * pBTable[2 * i + 1] */ 00203 outR = 00204 (q31_t) ((((q63_t) outR << 32) + ((q63_t) * pIn2 * (CoefB1))) >> 32); 00205 00206 /* pIn[2 * n - 2 * i + 1] * pBTable[2 * i] */ 00207 outI = 00208 (q31_t) ((((q63_t) outI << 32) + ((q63_t) * pIn2-- * (-CoefA2))) >> 32); 00209 00210 /* write output */ 00211 *pOut1++ = (outR << 1u); 00212 *pOut1++ = (outI << 1u); 00213 00214 /* write complex conjugate output */ 00215 *pOut2-- = -(outI << 1u); 00216 *pOut2-- = (outR << 1u); 00217 00218 /* update coefficient pointer */ 00219 pCoefB = pCoefB + (modifier * 2u); 00220 pCoefA = pCoefA + ((modifier * 2u) - 1u); 00221 00222 i--; 00223 00224 } 00225 00226 pDst[2u * fftLen] = pSrc[0] - pSrc[1]; 00227 pDst[(2u * fftLen) + 1u] = 0; 00228 00229 pDst[0] = pSrc[0] + pSrc[1]; 00230 pDst[1] = 0; 00231 00232 } 00233 00234 00235 /** 00236 * @brief Core Real IFFT process 00237 * @param[in] *pSrc points to the input buffer. 00238 * @param[in] fftLen length of FFT. 00239 * @param[in] *pATable points to the twiddle Coef A buffer. 00240 * @param[in] *pBTable points to the twiddle Coef B buffer. 00241 * @param[out] *pDst points to the output buffer. 00242 * @param[in] modifier twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. 00243 * @return none. 00244 */ 00245 00246 void arm_split_rifft_q31( 00247 q31_t * pSrc, 00248 uint32_t fftLen, 00249 q31_t * pATable, 00250 q31_t * pBTable, 00251 q31_t * pDst, 00252 uint32_t modifier) 00253 { 00254 q31_t outR, outI; /* Temporary variables for output */ 00255 q31_t *pCoefA, *pCoefB; /* Temporary pointers for twiddle factors */ 00256 q31_t CoefA1, CoefA2, CoefB1; /* Temporary variables for twiddle coefficients */ 00257 q31_t *pIn1 = &pSrc[0], *pIn2 = &pSrc[(2u * fftLen) + 1u]; 00258 00259 pCoefA = &pATable[0]; 00260 pCoefB = &pBTable[0]; 00261 00262 while(fftLen > 0u) 00263 { 00264 /* 00265 outR = (pIn[2 * i] * pATable[2 * i] + pIn[2 * i + 1] * pATable[2 * i + 1] + 00266 pIn[2 * n - 2 * i] * pBTable[2 * i] - 00267 pIn[2 * n - 2 * i + 1] * pBTable[2 * i + 1]); 00268 00269 outI = (pIn[2 * i + 1] * pATable[2 * i] - pIn[2 * i] * pATable[2 * i + 1] - 00270 pIn[2 * n - 2 * i] * pBTable[2 * i + 1] - 00271 pIn[2 * n - 2 * i + 1] * pBTable[2 * i]); 00272 00273 */ 00274 CoefA1 = *pCoefA++; 00275 CoefA2 = *pCoefA; 00276 00277 /* outR = (pIn[2 * i] * pATable[2 * i] */ 00278 outR = ((int32_t) (((q63_t) * pIn1 * CoefA1) >> 32)); 00279 00280 /* - pIn[2 * i] * pATable[2 * i + 1] */ 00281 outI = -((int32_t) (((q63_t) * pIn1++ * CoefA2) >> 32)); 00282 00283 /* pIn[2 * i + 1] * pATable[2 * i + 1] */ 00284 outR = 00285 (q31_t) ((((q63_t) outR << 32) + ((q63_t) * pIn1 * (CoefA2))) >> 32); 00286 00287 /* pIn[2 * i + 1] * pATable[2 * i] */ 00288 outI = 00289 (q31_t) ((((q63_t) outI << 32) + ((q63_t) * pIn1++ * (CoefA1))) >> 32); 00290 00291 /* pIn[2 * n - 2 * i] * pBTable[2 * i] */ 00292 outR = 00293 (q31_t) ((((q63_t) outR << 32) + ((q63_t) * pIn2 * (CoefA2))) >> 32); 00294 00295 CoefB1 = *pCoefB; 00296 00297 /* pIn[2 * n - 2 * i] * pBTable[2 * i + 1] */ 00298 outI = 00299 (q31_t) ((((q63_t) outI << 32) - ((q63_t) * pIn2-- * (CoefB1))) >> 32); 00300 00301 /* pIn[2 * n - 2 * i + 1] * pBTable[2 * i + 1] */ 00302 outR = 00303 (q31_t) ((((q63_t) outR << 32) + ((q63_t) * pIn2 * (CoefB1))) >> 32); 00304 00305 /* pIn[2 * n - 2 * i + 1] * pBTable[2 * i] */ 00306 outI = 00307 (q31_t) ((((q63_t) outI << 32) + ((q63_t) * pIn2-- * (CoefA2))) >> 32); 00308 00309 /* write output */ 00310 *pDst++ = (outR << 1u); 00311 *pDst++ = (outI << 1u); 00312 00313 /* update coefficient pointer */ 00314 pCoefB = pCoefB + (modifier * 2u); 00315 pCoefA = pCoefA + ((modifier * 2u) - 1u); 00316 00317 /* Decrement loop count */ 00318 fftLen--; 00319 00320 } 00321 00322 00323 }
Generated on Tue Jul 12 2022 14:13:54 by 1.7.2