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

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers arm_rfft_q31.c Source File

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 }