Subversion Repositories DashDisplay

Rev

Rev 49 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. /* ----------------------------------------------------------------------    
  2. * Copyright (C) 2010-2014 ARM Limited. All rights reserved.    
  3. *    
  4. * $Date:        19. March 2015
  5. * $Revision:    V.1.4.5  
  6. *    
  7. * Project:          CMSIS DSP Library    
  8. * Title:            arm_rfft_f32.c    
  9. *    
  10. * Description:  RFFT & RIFFT Floating point process function    
  11. *    
  12. * Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
  13. *  
  14. * Redistribution and use in source and binary forms, with or without
  15. * modification, are permitted provided that the following conditions
  16. * are met:
  17. *   - Redistributions of source code must retain the above copyright
  18. *     notice, this list of conditions and the following disclaimer.
  19. *   - Redistributions in binary form must reproduce the above copyright
  20. *     notice, this list of conditions and the following disclaimer in
  21. *     the documentation and/or other materials provided with the
  22. *     distribution.
  23. *   - Neither the name of ARM LIMITED nor the names of its contributors
  24. *     may be used to endorse or promote products derived from this
  25. *     software without specific prior written permission.
  26. *
  27. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  28. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  29. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  30. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  31. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  32. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  33. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  34. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  35. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  36. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  37. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  38. * POSSIBILITY OF SUCH DAMAGE.  
  39. * -------------------------------------------------------------------- */
  40.  
  41. #include "arm_math.h"
  42.  
  43. extern void arm_radix4_butterfly_f32(
  44.     float32_t * pSrc,
  45.     uint16_t fftLen,
  46.     float32_t * pCoef,
  47.     uint16_t twidCoefModifier);
  48.  
  49. extern void arm_radix4_butterfly_inverse_f32(
  50.     float32_t * pSrc,
  51.     uint16_t fftLen,
  52.     float32_t * pCoef,
  53.     uint16_t twidCoefModifier,
  54.     float32_t onebyfftLen);
  55.  
  56. extern void arm_bitreversal_f32(
  57.     float32_t * pSrc,
  58.     uint16_t fftSize,
  59.     uint16_t bitRevFactor,
  60.     uint16_t * pBitRevTab);
  61.  
  62. /**    
  63.  * @ingroup groupTransforms    
  64.  */
  65.  
  66. /*--------------------------------------------------------------------    
  67.  *              Internal functions prototypes    
  68.  *--------------------------------------------------------------------*/
  69.  
  70. void arm_split_rfft_f32(
  71.   float32_t * pSrc,
  72.   uint32_t fftLen,
  73.   float32_t * pATable,
  74.   float32_t * pBTable,
  75.   float32_t * pDst,
  76.   uint32_t modifier);
  77. void arm_split_rifft_f32(
  78.   float32_t * pSrc,
  79.   uint32_t fftLen,
  80.   float32_t * pATable,
  81.   float32_t * pBTable,
  82.   float32_t * pDst,
  83.   uint32_t modifier);
  84.  
  85. /**    
  86.  * @addtogroup RealFFT    
  87.  * @{    
  88.  */
  89.  
  90. /**    
  91.  * @brief Processing function for the floating-point RFFT/RIFFT.  
  92.  * @deprecated Do not use this function.  It has been superceded by \ref arm_rfft_fast_f32 and will be removed
  93.  * in the future.
  94.  * @param[in]  *S    points to an instance of the floating-point RFFT/RIFFT structure.  
  95.  * @param[in]  *pSrc points to the input buffer.  
  96.  * @param[out] *pDst points to the output buffer.  
  97.  * @return none.  
  98.  */
  99.  
  100. void arm_rfft_f32(
  101.   const arm_rfft_instance_f32 * S,
  102.   float32_t * pSrc,
  103.   float32_t * pDst)
  104. {
  105.   const arm_cfft_radix4_instance_f32 *S_CFFT = S->pCfft;
  106.  
  107.  
  108.   /* Calculation of Real IFFT of input */
  109.   if(S->ifftFlagR == 1u)
  110.   {
  111.     /*  Real IFFT core process */
  112.     arm_split_rifft_f32(pSrc, S->fftLenBy2, S->pTwiddleAReal,
  113.                         S->pTwiddleBReal, pDst, S->twidCoefRModifier);
  114.  
  115.  
  116.     /* Complex radix-4 IFFT process */
  117.     arm_radix4_butterfly_inverse_f32(pDst, S_CFFT->fftLen,
  118.                                      S_CFFT->pTwiddle,
  119.                                      S_CFFT->twidCoefModifier,
  120.                                      S_CFFT->onebyfftLen);
  121.  
  122.     /* Bit reversal process */
  123.     if(S->bitReverseFlagR == 1u)
  124.     {
  125.       arm_bitreversal_f32(pDst, S_CFFT->fftLen,
  126.                           S_CFFT->bitRevFactor, S_CFFT->pBitRevTable);
  127.     }
  128.   }
  129.   else
  130.   {
  131.  
  132.     /* Calculation of RFFT of input */
  133.  
  134.     /* Complex radix-4 FFT process */
  135.     arm_radix4_butterfly_f32(pSrc, S_CFFT->fftLen,
  136.                              S_CFFT->pTwiddle, S_CFFT->twidCoefModifier);
  137.  
  138.     /* Bit reversal process */
  139.     if(S->bitReverseFlagR == 1u)
  140.     {
  141.       arm_bitreversal_f32(pSrc, S_CFFT->fftLen,
  142.                           S_CFFT->bitRevFactor, S_CFFT->pBitRevTable);
  143.     }
  144.  
  145.  
  146.     /*  Real FFT core process */
  147.     arm_split_rfft_f32(pSrc, S->fftLenBy2, S->pTwiddleAReal,
  148.                        S->pTwiddleBReal, pDst, S->twidCoefRModifier);
  149.   }
  150.  
  151. }
  152.  
  153. /**    
  154.    * @} end of RealFFT group    
  155.    */
  156.  
  157. /**    
  158.  * @brief  Core Real FFT process    
  159.  * @param[in]   *pSrc                           points to the input buffer.    
  160.  * @param[in]   fftLen                          length of FFT.    
  161.  * @param[in]   *pATable                        points to the twiddle Coef A buffer.    
  162.  * @param[in]   *pBTable                        points to the twiddle Coef B buffer.    
  163.  * @param[out]  *pDst                           points to the output buffer.    
  164.  * @param[in]   modifier                twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table.  
  165.  * @return none.    
  166.  */
  167.  
  168. void arm_split_rfft_f32(
  169.   float32_t * pSrc,
  170.   uint32_t fftLen,
  171.   float32_t * pATable,
  172.   float32_t * pBTable,
  173.   float32_t * pDst,
  174.   uint32_t modifier)
  175. {
  176.   uint32_t i;                                    /* Loop Counter */
  177.   float32_t outR, outI;                          /* Temporary variables for output */
  178.   float32_t *pCoefA, *pCoefB;                    /* Temporary pointers for twiddle factors */
  179.   float32_t CoefA1, CoefA2, CoefB1;              /* Temporary variables for twiddle coefficients */
  180.   float32_t *pDst1 = &pDst[2], *pDst2 = &pDst[(4u * fftLen) - 1u];      /* temp pointers for output buffer */
  181.   float32_t *pSrc1 = &pSrc[2], *pSrc2 = &pSrc[(2u * fftLen) - 1u];      /* temp pointers for input buffer */
  182.  
  183.   /* Init coefficient pointers */
  184.   pCoefA = &pATable[modifier * 2u];
  185.   pCoefB = &pBTable[modifier * 2u];
  186.  
  187.   i = fftLen - 1u;
  188.  
  189.   while(i > 0u)
  190.   {
  191.     /*    
  192.        outR = (pSrc[2 * i] * pATable[2 * i] - pSrc[2 * i + 1] * pATable[2 * i + 1]    
  193.        + pSrc[2 * n - 2 * i] * pBTable[2 * i] +    
  194.        pSrc[2 * n - 2 * i + 1] * pBTable[2 * i + 1]);    
  195.      */
  196.  
  197.     /* outI = (pIn[2 * i + 1] * pATable[2 * i] + pIn[2 * i] * pATable[2 * i + 1] +    
  198.        pIn[2 * n - 2 * i] * pBTable[2 * i + 1] -    
  199.        pIn[2 * n - 2 * i + 1] * pBTable[2 * i]); */
  200.  
  201.     /* read pATable[2 * i] */
  202.     CoefA1 = *pCoefA++;
  203.     /* pATable[2 * i + 1] */
  204.     CoefA2 = *pCoefA;
  205.  
  206.     /* pSrc[2 * i] * pATable[2 * i] */
  207.     outR = *pSrc1 * CoefA1;
  208.     /* pSrc[2 * i] * CoefA2 */
  209.     outI = *pSrc1++ * CoefA2;
  210.  
  211.     /* (pSrc[2 * i + 1] + pSrc[2 * fftLen - 2 * i + 1]) * CoefA2 */
  212.     outR -= (*pSrc1 + *pSrc2) * CoefA2;
  213.     /* pSrc[2 * i + 1] * CoefA1 */
  214.     outI += *pSrc1++ * CoefA1;
  215.  
  216.     CoefB1 = *pCoefB;
  217.  
  218.     /* pSrc[2 * fftLen - 2 * i + 1] * CoefB1 */
  219.     outI -= *pSrc2-- * CoefB1;
  220.     /* pSrc[2 * fftLen - 2 * i] * CoefA2 */
  221.     outI -= *pSrc2 * CoefA2;
  222.  
  223.     /* pSrc[2 * fftLen - 2 * i] * CoefB1 */
  224.     outR += *pSrc2-- * CoefB1;
  225.  
  226.     /* write output */
  227.     *pDst1++ = outR;
  228.     *pDst1++ = outI;
  229.  
  230.     /* write complex conjugate output */
  231.     *pDst2-- = -outI;
  232.     *pDst2-- = outR;
  233.  
  234.     /* update coefficient pointer */
  235.     pCoefB = pCoefB + (modifier * 2u);
  236.     pCoefA = pCoefA + ((modifier * 2u) - 1u);
  237.  
  238.     i--;
  239.  
  240.   }
  241.  
  242.   pDst[2u * fftLen] = pSrc[0] - pSrc[1];
  243.   pDst[(2u * fftLen) + 1u] = 0.0f;
  244.  
  245.   pDst[0] = pSrc[0] + pSrc[1];
  246.   pDst[1] = 0.0f;
  247.  
  248. }
  249.  
  250.  
  251. /**    
  252.  * @brief  Core Real IFFT process    
  253.  * @param[in]   *pSrc                           points to the input buffer.    
  254.  * @param[in]   fftLen                          length of FFT.  
  255.  * @param[in]   *pATable                        points to the twiddle Coef A buffer.  
  256.  * @param[in]   *pBTable                        points to the twiddle Coef B buffer.  
  257.  * @param[out]  *pDst                           points to the output buffer.  
  258.  * @param[in]   modifier                twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table.    
  259.  * @return none.    
  260.  */
  261.  
  262. void arm_split_rifft_f32(
  263.   float32_t * pSrc,
  264.   uint32_t fftLen,
  265.   float32_t * pATable,
  266.   float32_t * pBTable,
  267.   float32_t * pDst,
  268.   uint32_t modifier)
  269. {
  270.   float32_t outR, outI;                          /* Temporary variables for output */
  271.   float32_t *pCoefA, *pCoefB;                    /* Temporary pointers for twiddle factors */
  272.   float32_t CoefA1, CoefA2, CoefB1;              /* Temporary variables for twiddle coefficients */
  273.   float32_t *pSrc1 = &pSrc[0], *pSrc2 = &pSrc[(2u * fftLen) + 1u];
  274.  
  275.   pCoefA = &pATable[0];
  276.   pCoefB = &pBTable[0];
  277.  
  278.   while(fftLen > 0u)
  279.   {
  280.     /*    
  281.        outR = (pIn[2 * i] * pATable[2 * i] + pIn[2 * i + 1] * pATable[2 * i + 1] +    
  282.        pIn[2 * n - 2 * i] * pBTable[2 * i] -    
  283.        pIn[2 * n - 2 * i + 1] * pBTable[2 * i + 1]);    
  284.  
  285.        outI = (pIn[2 * i + 1] * pATable[2 * i] - pIn[2 * i] * pATable[2 * i + 1] -    
  286.        pIn[2 * n - 2 * i] * pBTable[2 * i + 1] -    
  287.        pIn[2 * n - 2 * i + 1] * pBTable[2 * i]);    
  288.  
  289.      */
  290.  
  291.     CoefA1 = *pCoefA++;
  292.     CoefA2 = *pCoefA;
  293.  
  294.     /* outR = (pSrc[2 * i] * CoefA1 */
  295.     outR = *pSrc1 * CoefA1;
  296.  
  297.     /* - pSrc[2 * i] * CoefA2 */
  298.     outI = -(*pSrc1++) * CoefA2;
  299.  
  300.     /* (pSrc[2 * i + 1] + pSrc[2 * fftLen - 2 * i + 1]) * CoefA2 */
  301.     outR += (*pSrc1 + *pSrc2) * CoefA2;
  302.  
  303.     /* pSrc[2 * i + 1] * CoefA1 */
  304.     outI += (*pSrc1++) * CoefA1;
  305.  
  306.     CoefB1 = *pCoefB;
  307.  
  308.     /* - pSrc[2 * fftLen - 2 * i + 1] * CoefB1 */
  309.     outI -= *pSrc2-- * CoefB1;
  310.  
  311.     /* pSrc[2 * fftLen - 2 * i] * CoefB1 */
  312.     outR += *pSrc2 * CoefB1;
  313.  
  314.     /* pSrc[2 * fftLen - 2 * i] * CoefA2 */
  315.     outI += *pSrc2-- * CoefA2;
  316.  
  317.     /* write output */
  318.     *pDst++ = outR;
  319.     *pDst++ = outI;
  320.  
  321.     /* update coefficient pointer */
  322.     pCoefB = pCoefB + (modifier * 2u);
  323.     pCoefA = pCoefA + ((modifier * 2u) - 1u);
  324.  
  325.     /* Decrement loop count */
  326.     fftLen--;
  327.   }
  328.  
  329. }
  330.