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_q15.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_q15.c 00009 * 00010 * Description: RFFT & RIFFT Q15 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 00032 #include "arm_math.h" 00033 00034 /*-------------------------------------------------------------------- 00035 * Internal functions prototypes 00036 --------------------------------------------------------------------*/ 00037 00038 void arm_split_rfft_q15( 00039 q15_t * pSrc, 00040 uint32_t fftLen, 00041 q15_t * pATable, 00042 q15_t * pBTable, 00043 q15_t * pDst, 00044 uint32_t modifier); 00045 00046 void arm_split_rifft_q15( 00047 q15_t * pSrc, 00048 uint32_t fftLen, 00049 q15_t * pATable, 00050 q15_t * pBTable, 00051 q15_t * pDst, 00052 uint32_t modifier); 00053 00054 /** 00055 * @addtogroup RFFT_RIFFT 00056 * @{ 00057 */ 00058 00059 /** 00060 * @brief Processing function for the Q15 RFFT/RIFFT. 00061 * @param[in] *S points to an instance of the Q15 RFFT/RIFFT structure. 00062 * @param[in] *pSrc points to the input buffer. 00063 * @param[out] *pDst points to the output buffer. 00064 * @return none. 00065 * 00066 * \par Input an output formats: 00067 * \par 00068 * Internally input is downscaled by 2 for every stage to avoid saturations inside CFFT/CIFFT process. 00069 * Hence the output format is different for different RFFT sizes. 00070 * 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: 00071 * \par 00072 * \image html RFFTQ15.gif "Input and Output Formats for Q15 RFFT" 00073 * \par 00074 * \image html RIFFTQ15.gif "Input and Output Formats for Q15 RIFFT" 00075 */ 00076 00077 void arm_rfft_q15( 00078 const arm_rfft_instance_q15 * S, 00079 q15_t * pSrc, 00080 q15_t * pDst) 00081 { 00082 const arm_cfft_radix4_instance_q15 *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_q15(pSrc, S->fftLenBy2, S->pTwiddleAReal, 00089 S->pTwiddleBReal, pDst, S->twidCoefRModifier); 00090 00091 /* Complex readix-4 IFFT process */ 00092 arm_radix4_butterfly_inverse_q15(pDst, S_CFFT->fftLen, 00093 S_CFFT->pTwiddle, 00094 S_CFFT->twidCoefModifier); 00095 00096 /* Bit reversal process */ 00097 if(S->bitReverseFlagR == 1u) 00098 { 00099 arm_bitreversal_q15(pDst, S_CFFT->fftLen, 00100 S_CFFT->bitRevFactor, S_CFFT->pBitRevTable); 00101 } 00102 } 00103 else 00104 { 00105 /* Calculation of RFFT of input */ 00106 00107 /* Complex readix-4 FFT process */ 00108 arm_radix4_butterfly_q15(pSrc, S_CFFT->fftLen, 00109 S_CFFT->pTwiddle, S_CFFT->twidCoefModifier); 00110 00111 /* Bit reversal process */ 00112 if(S->bitReverseFlagR == 1u) 00113 { 00114 arm_bitreversal_q15(pSrc, S_CFFT->fftLen, 00115 S_CFFT->bitRevFactor, S_CFFT->pBitRevTable); 00116 } 00117 00118 arm_split_rfft_q15(pSrc, S->fftLenBy2, S->pTwiddleAReal, 00119 S->pTwiddleBReal, pDst, S->twidCoefRModifier); 00120 } 00121 00122 } 00123 00124 /** 00125 * @} end of RFFT_RIFFT group 00126 */ 00127 00128 /** 00129 * @brief Core Real FFT process 00130 * @param *pSrc points to the input buffer. 00131 * @param fftLen length of FFT. 00132 * @param *pATable points to the A twiddle Coef buffer. 00133 * @param *pBTable points to the B twiddle Coef buffer. 00134 * @param *pDst points to the output buffer. 00135 * @param modifier twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. 00136 * @return none. 00137 * The function implements a Real FFT 00138 */ 00139 00140 void arm_split_rfft_q15( 00141 q15_t * pSrc, 00142 uint32_t fftLen, 00143 q15_t * pATable, 00144 q15_t * pBTable, 00145 q15_t * pDst, 00146 uint32_t modifier) 00147 { 00148 uint32_t i; /* Loop Counter */ 00149 q31_t outR, outI; /* Temporary variables for output */ 00150 q15_t *pCoefA, *pCoefB; /* Temporary pointers for twiddle factors */ 00151 q15_t *pSrc1, *pSrc2; 00152 00153 00154 pSrc[2u * fftLen] = pSrc[0]; 00155 pSrc[(2u * fftLen) + 1u] = pSrc[1]; 00156 00157 pCoefA = &pATable[modifier * 2u]; 00158 pCoefB = &pBTable[modifier * 2u]; 00159 00160 pSrc1 = &pSrc[2]; 00161 pSrc2 = &pSrc[(2u * fftLen) - 2u]; 00162 00163 i = 1u; 00164 00165 while(i < fftLen) 00166 { 00167 /* 00168 outR = (pSrc[2 * i] * pATable[2 * i] - pSrc[2 * i + 1] * pATable[2 * i + 1] 00169 + pSrc[2 * n - 2 * i] * pBTable[2 * i] + 00170 pSrc[2 * n - 2 * i + 1] * pBTable[2 * i + 1]); 00171 */ 00172 00173 /* outI = (pIn[2 * i + 1] * pATable[2 * i] + pIn[2 * i] * pATable[2 * i + 1] + 00174 pIn[2 * n - 2 * i] * pBTable[2 * i + 1] - 00175 pIn[2 * n - 2 * i + 1] * pBTable[2 * i]); */ 00176 00177 /* pSrc[2 * i] * pATable[2 * i] - pSrc[2 * i + 1] * pATable[2 * i + 1] */ 00178 outR = __SMUSD(*__SIMD32(pSrc1), *__SIMD32(pCoefA)); 00179 00180 /* pSrc[2 * n - 2 * i] * pBTable[2 * i] + 00181 pSrc[2 * n - 2 * i + 1] * pBTable[2 * i + 1]) */ 00182 outR = __SMLAD(*__SIMD32(pSrc2), *__SIMD32(pCoefB), outR) >> 15u; 00183 00184 /* pIn[2 * n - 2 * i] * pBTable[2 * i + 1] - 00185 pIn[2 * n - 2 * i + 1] * pBTable[2 * i] */ 00186 outI = __SMUSDX(*__SIMD32(pSrc2)--, *__SIMD32(pCoefB)); 00187 00188 /* (pIn[2 * i + 1] * pATable[2 * i] + pIn[2 * i] * pATable[2 * i + 1] */ 00189 outI = __SMLADX(*__SIMD32(pSrc1)++, *__SIMD32(pCoefA), outI); 00190 00191 /* write output */ 00192 pDst[2u * i] = (q15_t) outR; 00193 pDst[(2u * i) + 1u] = outI >> 15u; 00194 00195 /* write complex conjugate output */ 00196 pDst[(4u * fftLen) - (2u * i)] = (q15_t) outR; 00197 pDst[((4u * fftLen) - (2u * i)) + 1u] = -(outI >> 15u); 00198 00199 /* update coefficient pointer */ 00200 pCoefB = pCoefB + (2u * modifier); 00201 pCoefA = pCoefA + (2u * modifier); 00202 00203 i++; 00204 00205 } 00206 00207 pDst[2u * fftLen] = pSrc[0] - pSrc[1]; 00208 pDst[(2u * fftLen) + 1u] = 0; 00209 00210 pDst[0] = pSrc[0] + pSrc[1]; 00211 pDst[1] = 0; 00212 00213 } 00214 00215 00216 /** 00217 * @brief Core Real IFFT process 00218 * @param[in] *pSrc points to the input buffer. 00219 * @param[in] fftLen length of FFT. 00220 * @param[in] *pATable points to the twiddle Coef A buffer. 00221 * @param[in] *pBTable points to the twiddle Coef B buffer. 00222 * @param[out] *pDst points to the output buffer. 00223 * @param[in] modifier twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. 00224 * @return none. 00225 * The function implements a Real IFFT 00226 */ 00227 00228 void arm_split_rifft_q15( 00229 q15_t * pSrc, 00230 uint32_t fftLen, 00231 q15_t * pATable, 00232 q15_t * pBTable, 00233 q15_t * pDst, 00234 uint32_t modifier) 00235 { 00236 uint32_t i; /* Loop Counter */ 00237 q31_t outR, outI; /* Temporary variables for output */ 00238 q15_t *pCoefA, *pCoefB; /* Temporary pointers for twiddle factors */ 00239 q15_t *pSrc1, *pSrc2; 00240 q15_t *pDst1 = &pDst[0]; 00241 00242 pCoefA = &pATable[0]; 00243 pCoefB = &pBTable[0]; 00244 00245 pSrc1 = &pSrc[0]; 00246 pSrc2 = &pSrc[2u * fftLen]; 00247 00248 i = fftLen; 00249 00250 while(i > 0u) 00251 { 00252 00253 /* 00254 outR = (pIn[2 * i] * pATable[2 * i] + pIn[2 * i + 1] * pATable[2 * i + 1] + 00255 pIn[2 * n - 2 * i] * pBTable[2 * i] - 00256 pIn[2 * n - 2 * i + 1] * pBTable[2 * i + 1]); 00257 00258 outI = (pIn[2 * i + 1] * pATable[2 * i] - pIn[2 * i] * pATable[2 * i + 1] - 00259 pIn[2 * n - 2 * i] * pBTable[2 * i + 1] - 00260 pIn[2 * n - 2 * i + 1] * pBTable[2 * i]); 00261 00262 */ 00263 00264 /* pIn[2 * n - 2 * i] * pBTable[2 * i] - 00265 pIn[2 * n - 2 * i + 1] * pBTable[2 * i + 1]) */ 00266 outR = __SMUSD(*__SIMD32(pSrc2), *__SIMD32(pCoefB)); 00267 00268 /* pIn[2 * i] * pATable[2 * i] + pIn[2 * i + 1] * pATable[2 * i + 1] + 00269 pIn[2 * n - 2 * i] * pBTable[2 * i] */ 00270 outR = __SMLAD(*__SIMD32(pSrc1), *__SIMD32(pCoefA), outR) >> 15u; 00271 00272 /* 00273 -pIn[2 * n - 2 * i] * pBTable[2 * i + 1] + 00274 pIn[2 * n - 2 * i + 1] * pBTable[2 * i] */ 00275 outI = __SMUADX(*__SIMD32(pSrc2)--, *__SIMD32(pCoefB)); 00276 00277 /* pIn[2 * i + 1] * pATable[2 * i] - pIn[2 * i] * pATable[2 * i + 1] */ 00278 outI = __SMLSDX(*__SIMD32(pCoefA), *__SIMD32(pSrc1)++, -outI); 00279 00280 /* write output */ 00281 *__SIMD32(pDst1)++ = 00282 (q31_t) ((outI << 1u) & 0xFFFF0000) | (outR & 0x0000FFFF); 00283 00284 /* update coefficient pointer */ 00285 pCoefB = pCoefB + (2u * modifier); 00286 pCoefA = pCoefA + (2u * modifier); 00287 00288 i--; 00289 00290 } 00291 00292 }
Generated on Tue Jul 12 2022 14:13:54 by 1.7.2