CMSIS DSP library

Dependents:   performance_timer Surfboard_ gps2rtty Capstone ... more

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers arm_rfft_f32.c Source File

arm_rfft_f32.c

00001 /* ----------------------------------------------------------------------    
00002 * Copyright (C) 2010-2014 ARM Limited. All rights reserved.    
00003 *    
00004 * $Date:        19. March 2015 
00005 * $Revision:    V.1.4.5  
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 }