Aded CMSIS5 DSP and NN folder. Needs some work

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers arm_rfft_f32.c Source File

arm_rfft_f32.c

00001 /* ----------------------------------------------------------------------
00002  * Project:      CMSIS DSP Library
00003  * Title:        arm_rfft_f32.c
00004  * Description:  RFFT & RIFFT Floating point process function
00005  *
00006  * $Date:        27. January 2017
00007  * $Revision:    V.1.5.1
00008  *
00009  * Target Processor: Cortex-M cores
00010  * -------------------------------------------------------------------- */
00011 /*
00012  * Copyright (C) 2010-2017 ARM Limited or its affiliates. All rights reserved.
00013  *
00014  * SPDX-License-Identifier: Apache-2.0
00015  *
00016  * Licensed under the Apache License, Version 2.0 (the License); you may
00017  * not use this file except in compliance with the License.
00018  * You may obtain a copy of the License at
00019  *
00020  * www.apache.org/licenses/LICENSE-2.0
00021  *
00022  * Unless required by applicable law or agreed to in writing, software
00023  * distributed under the License is distributed on an AS IS BASIS, WITHOUT
00024  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00025  * See the License for the specific language governing permissions and
00026  * limitations under the License.
00027  */
00028 
00029 #include "arm_math.h"
00030 
00031 /* ----------------------------------------------------------------------
00032  * Internal functions prototypes
00033  * -------------------------------------------------------------------- */
00034 
00035 extern void arm_radix4_butterfly_f32(
00036     float32_t * pSrc,
00037     uint16_t fftLen,
00038     float32_t * pCoef,
00039     uint16_t twidCoefModifier);
00040 
00041 extern void arm_radix4_butterfly_inverse_f32(
00042     float32_t * pSrc,
00043     uint16_t fftLen,
00044     float32_t * pCoef,
00045     uint16_t twidCoefModifier,
00046     float32_t onebyfftLen);
00047 
00048 extern void arm_bitreversal_f32(
00049     float32_t * pSrc,
00050     uint16_t fftSize,
00051     uint16_t bitRevFactor,
00052     uint16_t * pBitRevTab);
00053 
00054 void arm_split_rfft_f32(
00055   float32_t * pSrc,
00056   uint32_t fftLen,
00057   float32_t * pATable,
00058   float32_t * pBTable,
00059   float32_t * pDst,
00060   uint32_t modifier);
00061 
00062 void arm_split_rifft_f32(
00063   float32_t * pSrc,
00064   uint32_t fftLen,
00065   float32_t * pATable,
00066   float32_t * pBTable,
00067   float32_t * pDst,
00068   uint32_t modifier);
00069 
00070 /**
00071 * @ingroup groupTransforms
00072 */
00073 
00074 /**
00075  * @addtogroup RealFFT
00076  * @{
00077  */
00078 
00079 /**
00080  * @brief Processing function for the floating-point RFFT/RIFFT.
00081  * @deprecated Do not use this function.  It has been superceded by \ref arm_rfft_fast_f32 and will be removed
00082  * in the future.
00083  * @param[in]  *S    points to an instance of the floating-point RFFT/RIFFT structure.
00084  * @param[in]  *pSrc points to the input buffer.
00085  * @param[out] *pDst points to the output buffer.
00086  * @return none.
00087  */
00088 
00089 void arm_rfft_f32(
00090   const arm_rfft_instance_f32 * S,
00091   float32_t * pSrc,
00092   float32_t * pDst)
00093 {
00094   const arm_cfft_radix4_instance_f32 *S_CFFT = S->pCfft;
00095 
00096 
00097   /* Calculation of Real IFFT of input */
00098   if (S->ifftFlagR == 1U)
00099   {
00100     /*  Real IFFT core process */
00101     arm_split_rifft_f32(pSrc, S->fftLenBy2, S->pTwiddleAReal,
00102                         S->pTwiddleBReal, pDst, S->twidCoefRModifier);
00103 
00104 
00105     /* Complex radix-4 IFFT process */
00106     arm_radix4_butterfly_inverse_f32(pDst, S_CFFT->fftLen,
00107                                      S_CFFT->pTwiddle,
00108                                      S_CFFT->twidCoefModifier,
00109                                      S_CFFT->onebyfftLen);
00110 
00111     /* Bit reversal process */
00112     if (S->bitReverseFlagR == 1U)
00113     {
00114       arm_bitreversal_f32(pDst, S_CFFT->fftLen,
00115                           S_CFFT->bitRevFactor, S_CFFT->pBitRevTable);
00116     }
00117   }
00118   else
00119   {
00120 
00121     /* Calculation of RFFT of input */
00122 
00123     /* Complex radix-4 FFT process */
00124     arm_radix4_butterfly_f32(pSrc, S_CFFT->fftLen,
00125                              S_CFFT->pTwiddle, S_CFFT->twidCoefModifier);
00126 
00127     /* Bit reversal process */
00128     if (S->bitReverseFlagR == 1U)
00129     {
00130       arm_bitreversal_f32(pSrc, S_CFFT->fftLen,
00131                           S_CFFT->bitRevFactor, S_CFFT->pBitRevTable);
00132     }
00133 
00134 
00135     /*  Real FFT core process */
00136     arm_split_rfft_f32(pSrc, S->fftLenBy2, S->pTwiddleAReal,
00137                        S->pTwiddleBReal, pDst, S->twidCoefRModifier);
00138   }
00139 
00140 }
00141 
00142 /**
00143    * @} end of RealFFT group
00144    */
00145 
00146 /**
00147  * @brief  Core Real FFT process
00148  * @param[in]   *pSrc               points to the input buffer.
00149  * @param[in]   fftLen              length of FFT.
00150  * @param[in]   *pATable            points to the twiddle Coef A buffer.
00151  * @param[in]   *pBTable            points to the twiddle Coef B buffer.
00152  * @param[out]  *pDst               points to the output buffer.
00153  * @param[in]   modifier            twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table.
00154  * @return none.
00155  */
00156 
00157 void arm_split_rfft_f32(
00158   float32_t * pSrc,
00159   uint32_t fftLen,
00160   float32_t * pATable,
00161   float32_t * pBTable,
00162   float32_t * pDst,
00163   uint32_t modifier)
00164 {
00165   uint32_t i;                                    /* Loop Counter */
00166   float32_t outR, outI;                          /* Temporary variables for output */
00167   float32_t *pCoefA, *pCoefB;                    /* Temporary pointers for twiddle factors */
00168   float32_t CoefA1, CoefA2, CoefB1;              /* Temporary variables for twiddle coefficients */
00169   float32_t *pDst1 = &pDst[2], *pDst2 = &pDst[(4U * fftLen) - 1U];      /* temp pointers for output buffer */
00170   float32_t *pSrc1 = &pSrc[2], *pSrc2 = &pSrc[(2U * fftLen) - 1U];      /* temp pointers for input buffer */
00171 
00172   /* Init coefficient pointers */
00173   pCoefA = &pATable[modifier * 2U];
00174   pCoefB = &pBTable[modifier * 2U];
00175 
00176   i = fftLen - 1U;
00177 
00178   while (i > 0U)
00179   {
00180     /*
00181        outR = (pSrc[2 * i] * pATable[2 * i] - pSrc[2 * i + 1] * pATable[2 * i + 1]
00182        + pSrc[2 * n - 2 * i] * pBTable[2 * i] +
00183        pSrc[2 * n - 2 * i + 1] * pBTable[2 * i + 1]);
00184      */
00185 
00186     /* outI = (pIn[2 * i + 1] * pATable[2 * i] + pIn[2 * i] * pATable[2 * i + 1] +
00187        pIn[2 * n - 2 * i] * pBTable[2 * i + 1] -
00188        pIn[2 * n - 2 * i + 1] * pBTable[2 * i]); */
00189 
00190     /* read pATable[2 * i] */
00191     CoefA1 = *pCoefA++;
00192     /* pATable[2 * i + 1] */
00193     CoefA2 = *pCoefA;
00194 
00195     /* pSrc[2 * i] * pATable[2 * i] */
00196     outR = *pSrc1 * CoefA1;
00197     /* pSrc[2 * i] * CoefA2 */
00198     outI = *pSrc1++ * CoefA2;
00199 
00200     /* (pSrc[2 * i + 1] + pSrc[2 * fftLen - 2 * i + 1]) * CoefA2 */
00201     outR -= (*pSrc1 + *pSrc2) * CoefA2;
00202     /* pSrc[2 * i + 1] * CoefA1 */
00203     outI += *pSrc1++ * CoefA1;
00204 
00205     CoefB1 = *pCoefB;
00206 
00207     /* pSrc[2 * fftLen - 2 * i + 1] * CoefB1 */
00208     outI -= *pSrc2-- * CoefB1;
00209     /* pSrc[2 * fftLen - 2 * i] * CoefA2 */
00210     outI -= *pSrc2 * CoefA2;
00211 
00212     /* pSrc[2 * fftLen - 2 * i] * CoefB1 */
00213     outR += *pSrc2-- * CoefB1;
00214 
00215     /* write output */
00216     *pDst1++ = outR;
00217     *pDst1++ = outI;
00218 
00219     /* write complex conjugate output */
00220     *pDst2-- = -outI;
00221     *pDst2-- = outR;
00222 
00223     /* update coefficient pointer */
00224     pCoefB = pCoefB + (modifier * 2U);
00225     pCoefA = pCoefA + ((modifier * 2U) - 1U);
00226 
00227     i--;
00228 
00229   }
00230 
00231   pDst[2U * fftLen] = pSrc[0] - pSrc[1];
00232   pDst[(2U * fftLen) + 1U] = 0.0f;
00233 
00234   pDst[0] = pSrc[0] + pSrc[1];
00235   pDst[1] = 0.0f;
00236 
00237 }
00238 
00239 
00240 /**
00241  * @brief  Core Real IFFT process
00242  * @param[in]   *pSrc               points to the input buffer.
00243  * @param[in]   fftLen              length of FFT.
00244  * @param[in]   *pATable            points to the twiddle Coef A buffer.
00245  * @param[in]   *pBTable            points to the twiddle Coef B buffer.
00246  * @param[out]  *pDst               points to the output buffer.
00247  * @param[in]   modifier            twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table.
00248  * @return none.
00249  */
00250 
00251 void arm_split_rifft_f32(
00252   float32_t * pSrc,
00253   uint32_t fftLen,
00254   float32_t * pATable,
00255   float32_t * pBTable,
00256   float32_t * pDst,
00257   uint32_t modifier)
00258 {
00259   float32_t outR, outI;                          /* Temporary variables for output */
00260   float32_t *pCoefA, *pCoefB;                    /* Temporary pointers for twiddle factors */
00261   float32_t CoefA1, CoefA2, CoefB1;              /* Temporary variables for twiddle coefficients */
00262   float32_t *pSrc1 = &pSrc[0], *pSrc2 = &pSrc[(2U * fftLen) + 1U];
00263 
00264   pCoefA = &pATable[0];
00265   pCoefB = &pBTable[0];
00266 
00267   while (fftLen > 0U)
00268   {
00269     /*
00270        outR = (pIn[2 * i] * pATable[2 * i] + pIn[2 * i + 1] * pATable[2 * i + 1] +
00271        pIn[2 * n - 2 * i] * pBTable[2 * i] -
00272        pIn[2 * n - 2 * i + 1] * pBTable[2 * i + 1]);
00273 
00274        outI = (pIn[2 * i + 1] * pATable[2 * i] - pIn[2 * i] * pATable[2 * i + 1] -
00275        pIn[2 * n - 2 * i] * pBTable[2 * i + 1] -
00276        pIn[2 * n - 2 * i + 1] * pBTable[2 * i]);
00277 
00278      */
00279 
00280     CoefA1 = *pCoefA++;
00281     CoefA2 = *pCoefA;
00282 
00283     /* outR = (pSrc[2 * i] * CoefA1 */
00284     outR = *pSrc1 * CoefA1;
00285 
00286     /* - pSrc[2 * i] * CoefA2 */
00287     outI = -(*pSrc1++) * CoefA2;
00288 
00289     /* (pSrc[2 * i + 1] + pSrc[2 * fftLen - 2 * i + 1]) * CoefA2 */
00290     outR += (*pSrc1 + *pSrc2) * CoefA2;
00291 
00292     /* pSrc[2 * i + 1] * CoefA1 */
00293     outI += (*pSrc1++) * CoefA1;
00294 
00295     CoefB1 = *pCoefB;
00296 
00297     /* - pSrc[2 * fftLen - 2 * i + 1] * CoefB1 */
00298     outI -= *pSrc2-- * CoefB1;
00299 
00300     /* pSrc[2 * fftLen - 2 * i] * CoefB1 */
00301     outR += *pSrc2 * CoefB1;
00302 
00303     /* pSrc[2 * fftLen - 2 * i] * CoefA2 */
00304     outI += *pSrc2-- * CoefA2;
00305 
00306     /* write output */
00307     *pDst++ = outR;
00308     *pDst++ = outI;
00309 
00310     /* update coefficient pointer */
00311     pCoefB = pCoefB + (modifier * 2U);
00312     pCoefA = pCoefA + ((modifier * 2U) - 1U);
00313 
00314     /* Decrement loop count */
00315     fftLen--;
00316   }
00317 
00318 }
00319