Subversion Repositories DashDisplay

Rev

Blame | 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_cfft_radix2_f32.c  
  9. *  
  10. * Description:  Radix-2 Decimation in Frequency CFFT & CIFFT Floating point processing function  
  11. *  
  12. *  
  13. * Target Processor: Cortex-M4/Cortex-M3/Cortex-M0
  14. *  
  15. * Redistribution and use in source and binary forms, with or without
  16. * modification, are permitted provided that the following conditions
  17. * are met:
  18. *   - Redistributions of source code must retain the above copyright
  19. *     notice, this list of conditions and the following disclaimer.
  20. *   - Redistributions in binary form must reproduce the above copyright
  21. *     notice, this list of conditions and the following disclaimer in
  22. *     the documentation and/or other materials provided with the
  23. *     distribution.
  24. *   - Neither the name of ARM LIMITED nor the names of its contributors
  25. *     may be used to endorse or promote products derived from this
  26. *     software without specific prior written permission.
  27. *
  28. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  29. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  30. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  31. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  32. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  33. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  34. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  35. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  36. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  37. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  38. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  39. * POSSIBILITY OF SUCH DAMAGE.  
  40. * -------------------------------------------------------------------- */
  41.  
  42. #include "arm_math.h"
  43.  
  44. void arm_radix2_butterfly_f32(
  45.   float32_t * pSrc,
  46.   uint32_t fftLen,
  47.   float32_t * pCoef,
  48.   uint16_t twidCoefModifier);
  49.  
  50. void arm_radix2_butterfly_inverse_f32(
  51.   float32_t * pSrc,
  52.   uint32_t fftLen,
  53.   float32_t * pCoef,
  54.   uint16_t twidCoefModifier,
  55.   float32_t onebyfftLen);
  56.  
  57. extern void arm_bitreversal_f32(
  58.     float32_t * pSrc,
  59.     uint16_t fftSize,
  60.     uint16_t bitRevFactor,
  61.     uint16_t * pBitRevTab);
  62.  
  63. /**  
  64. * @ingroup groupTransforms  
  65. */
  66.  
  67. /**  
  68. * @addtogroup ComplexFFT  
  69. * @{  
  70. */
  71.  
  72. /**  
  73. * @details
  74. * @brief Radix-2 CFFT/CIFFT.
  75. * @deprecated Do not use this function.  It has been superseded by \ref arm_cfft_f32 and will be removed
  76. * in the future.
  77. * @param[in]      *S    points to an instance of the floating-point Radix-2 CFFT/CIFFT structure.  
  78. * @param[in, out] *pSrc points to the complex data buffer of size <code>2*fftLen</code>. Processing occurs in-place.  
  79. * @return none.
  80. */
  81.  
  82. void arm_cfft_radix2_f32(
  83. const arm_cfft_radix2_instance_f32 * S,
  84. float32_t * pSrc)
  85. {
  86.  
  87.    if(S->ifftFlag == 1u)
  88.    {
  89.       /*  Complex IFFT radix-2  */
  90.       arm_radix2_butterfly_inverse_f32(pSrc, S->fftLen, S->pTwiddle,
  91.       S->twidCoefModifier, S->onebyfftLen);
  92.    }
  93.    else
  94.    {
  95.       /*  Complex FFT radix-2  */
  96.       arm_radix2_butterfly_f32(pSrc, S->fftLen, S->pTwiddle,
  97.       S->twidCoefModifier);
  98.    }
  99.  
  100.    if(S->bitReverseFlag == 1u)
  101.    {
  102.       /*  Bit Reversal */
  103.       arm_bitreversal_f32(pSrc, S->fftLen, S->bitRevFactor, S->pBitRevTable);
  104.    }
  105.  
  106. }
  107.  
  108.  
  109. /**    
  110. * @} end of ComplexFFT group    
  111. */
  112.  
  113.  
  114.  
  115. /* ----------------------------------------------------------------------    
  116. ** Internal helper function used by the FFTs    
  117. ** ------------------------------------------------------------------- */
  118.  
  119. /*    
  120. * @brief  Core function for the floating-point CFFT butterfly process.  
  121. * @param[in, out] *pSrc            points to the in-place buffer of floating-point data type.  
  122. * @param[in]      fftLen           length of the FFT.  
  123. * @param[in]      *pCoef           points to the twiddle coefficient buffer.  
  124. * @param[in]      twidCoefModifier twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table.  
  125. * @return none.  
  126. */
  127.  
  128. void arm_radix2_butterfly_f32(
  129. float32_t * pSrc,
  130. uint32_t fftLen,
  131. float32_t * pCoef,
  132. uint16_t twidCoefModifier)
  133. {
  134.  
  135.    uint32_t i, j, k, l;
  136.    uint32_t n1, n2, ia;
  137.    float32_t xt, yt, cosVal, sinVal;
  138.    float32_t p0, p1, p2, p3;
  139.    float32_t a0, a1;
  140.  
  141. #ifndef ARM_MATH_CM0_FAMILY
  142.  
  143.    /*  Initializations for the first stage */
  144.    n2 = fftLen >> 1;
  145.    ia = 0;
  146.    i = 0;
  147.  
  148.    // loop for groups
  149.    for (k = n2; k > 0; k--)
  150.    {
  151.       cosVal = pCoef[ia * 2];
  152.       sinVal = pCoef[(ia * 2) + 1];
  153.  
  154.       /*  Twiddle coefficients index modifier */
  155.       ia += twidCoefModifier;
  156.  
  157.       /*  index calculation for the input as, */
  158.       /*  pSrc[i + 0], pSrc[i + fftLen/1] */
  159.       l = i + n2;
  160.  
  161.       /*  Butterfly implementation */
  162.       a0 = pSrc[2 * i] + pSrc[2 * l];
  163.       xt = pSrc[2 * i] - pSrc[2 * l];
  164.  
  165.       yt = pSrc[2 * i + 1] - pSrc[2 * l + 1];
  166.       a1 = pSrc[2 * l + 1] + pSrc[2 * i + 1];
  167.      
  168.       p0 = xt * cosVal;
  169.       p1 = yt * sinVal;
  170.       p2 = yt * cosVal;
  171.       p3 = xt * sinVal;  
  172.      
  173.       pSrc[2 * i]     = a0;  
  174.       pSrc[2 * i + 1] = a1;      
  175.      
  176.       pSrc[2 * l]     = p0 + p1;
  177.       pSrc[2 * l + 1] = p2 - p3;
  178.      
  179.       i++;
  180.    }                             // groups loop end
  181.  
  182.    twidCoefModifier <<= 1u;
  183.  
  184.    // loop for stage
  185.    for (k = n2; k > 2; k = k >> 1)
  186.    {
  187.       n1 = n2;
  188.       n2 = n2 >> 1;
  189.       ia = 0;
  190.  
  191.       // loop for groups
  192.       j = 0;
  193.       do
  194.       {
  195.          cosVal = pCoef[ia * 2];
  196.          sinVal = pCoef[(ia * 2) + 1];
  197.          ia += twidCoefModifier;
  198.  
  199.          // loop for butterfly
  200.          i = j;
  201.          do
  202.          {
  203.             l = i + n2;
  204.             a0 = pSrc[2 * i] + pSrc[2 * l];
  205.             xt = pSrc[2 * i] - pSrc[2 * l];
  206.  
  207.             yt = pSrc[2 * i + 1] - pSrc[2 * l + 1];
  208.             a1 = pSrc[2 * l + 1] + pSrc[2 * i + 1];
  209.            
  210.             p0 = xt * cosVal;
  211.             p1 = yt * sinVal;
  212.             p2 = yt * cosVal;
  213.             p3 = xt * sinVal;  
  214.            
  215.             pSrc[2 * i] = a0;  
  216.             pSrc[2 * i + 1] = a1;      
  217.            
  218.             pSrc[2 * l]     = p0 + p1;
  219.             pSrc[2 * l + 1] = p2 - p3;
  220.            
  221.             i += n1;
  222.          } while( i < fftLen );                        // butterfly loop end
  223.          j++;
  224.       } while( j < n2);                          // groups loop end
  225.       twidCoefModifier <<= 1u;
  226.    }                             // stages loop end
  227.  
  228.    // loop for butterfly
  229.    for (i = 0; i < fftLen; i += 2)
  230.    {
  231.       a0 = pSrc[2 * i] + pSrc[2 * i + 2];
  232.       xt = pSrc[2 * i] - pSrc[2 * i + 2];
  233.  
  234.       yt = pSrc[2 * i + 1] - pSrc[2 * i + 3];
  235.       a1 = pSrc[2 * i + 3] + pSrc[2 * i + 1];
  236.      
  237.       pSrc[2 * i] = a0;  
  238.       pSrc[2 * i + 1] = a1;
  239.       pSrc[2 * i + 2] = xt;
  240.       pSrc[2 * i + 3] = yt;
  241.    }                             // groups loop end
  242.  
  243. #else
  244.  
  245.    n2 = fftLen;
  246.  
  247.    // loop for stage
  248.    for (k = fftLen; k > 1; k = k >> 1)
  249.    {
  250.       n1 = n2;
  251.       n2 = n2 >> 1;
  252.       ia = 0;
  253.  
  254.       // loop for groups
  255.       j = 0;
  256.       do
  257.       {
  258.          cosVal = pCoef[ia * 2];
  259.          sinVal = pCoef[(ia * 2) + 1];
  260.          ia += twidCoefModifier;
  261.  
  262.          // loop for butterfly
  263.          i = j;
  264.          do
  265.          {
  266.             l = i + n2;
  267.             a0 = pSrc[2 * i] + pSrc[2 * l];
  268.             xt = pSrc[2 * i] - pSrc[2 * l];
  269.  
  270.             yt = pSrc[2 * i + 1] - pSrc[2 * l + 1];
  271.             a1 = pSrc[2 * l + 1] + pSrc[2 * i + 1];
  272.            
  273.             p0 = xt * cosVal;
  274.             p1 = yt * sinVal;
  275.             p2 = yt * cosVal;
  276.             p3 = xt * sinVal;  
  277.            
  278.             pSrc[2 * i] = a0;  
  279.             pSrc[2 * i + 1] = a1;      
  280.            
  281.             pSrc[2 * l]     = p0 + p1;
  282.             pSrc[2 * l + 1] = p2 - p3;
  283.            
  284.             i += n1;
  285.          } while(i < fftLen);
  286.          j++;
  287.       } while(j < n2);
  288.       twidCoefModifier <<= 1u;
  289.    }
  290.  
  291. #endif //    #ifndef ARM_MATH_CM0_FAMILY
  292.  
  293. }
  294.  
  295.  
  296. void arm_radix2_butterfly_inverse_f32(
  297. float32_t * pSrc,
  298. uint32_t fftLen,
  299. float32_t * pCoef,
  300. uint16_t twidCoefModifier,
  301. float32_t onebyfftLen)
  302. {
  303.  
  304.    uint32_t i, j, k, l;
  305.    uint32_t n1, n2, ia;
  306.    float32_t xt, yt, cosVal, sinVal;
  307.    float32_t p0, p1, p2, p3;
  308.    float32_t a0, a1;
  309.  
  310. #ifndef ARM_MATH_CM0_FAMILY
  311.  
  312.    n2 = fftLen >> 1;
  313.    ia = 0;
  314.  
  315.    // loop for groups
  316.    for (i = 0; i < n2; i++)
  317.    {
  318.       cosVal = pCoef[ia * 2];
  319.       sinVal = pCoef[(ia * 2) + 1];
  320.       ia += twidCoefModifier;
  321.  
  322.       l = i + n2;
  323.       a0 = pSrc[2 * i] + pSrc[2 * l];
  324.       xt = pSrc[2 * i] - pSrc[2 * l];
  325.  
  326.       yt = pSrc[2 * i + 1] - pSrc[2 * l + 1];
  327.       a1 = pSrc[2 * l + 1] + pSrc[2 * i + 1];
  328.      
  329.       p0 = xt * cosVal;
  330.       p1 = yt * sinVal;
  331.       p2 = yt * cosVal;
  332.       p3 = xt * sinVal;  
  333.      
  334.       pSrc[2 * i] = a0;  
  335.       pSrc[2 * i + 1] = a1;      
  336.      
  337.       pSrc[2 * l]     = p0 - p1;
  338.       pSrc[2 * l + 1] = p2 + p3;  
  339.    }                             // groups loop end
  340.  
  341.    twidCoefModifier <<= 1u;
  342.  
  343.    // loop for stage
  344.    for (k = fftLen / 2; k > 2; k = k >> 1)
  345.    {
  346.       n1 = n2;
  347.       n2 = n2 >> 1;
  348.       ia = 0;
  349.  
  350.       // loop for groups
  351.       j = 0;
  352.       do
  353.       {
  354.          cosVal = pCoef[ia * 2];
  355.          sinVal = pCoef[(ia * 2) + 1];
  356.          ia += twidCoefModifier;
  357.  
  358.          // loop for butterfly
  359.          i = j;
  360.          do
  361.          {
  362.             l = i + n2;
  363.             a0 = pSrc[2 * i] + pSrc[2 * l];
  364.             xt = pSrc[2 * i] - pSrc[2 * l];
  365.  
  366.             yt = pSrc[2 * i + 1] - pSrc[2 * l + 1];
  367.             a1 = pSrc[2 * l + 1] + pSrc[2 * i + 1];
  368.            
  369.             p0 = xt * cosVal;
  370.             p1 = yt * sinVal;
  371.             p2 = yt * cosVal;
  372.             p3 = xt * sinVal;  
  373.            
  374.             pSrc[2 * i] = a0;  
  375.             pSrc[2 * i + 1] = a1;      
  376.            
  377.             pSrc[2 * l]     = p0 - p1;
  378.             pSrc[2 * l + 1] = p2 + p3;
  379.  
  380.             i += n1;
  381.          } while( i < fftLen );                 // butterfly loop end
  382.          j++;
  383.       } while(j < n2);                      // groups loop end
  384.  
  385.       twidCoefModifier <<= 1u;
  386.    }                             // stages loop end
  387.  
  388.    // loop for butterfly
  389.    for (i = 0; i < fftLen; i += 2)
  390.    {  
  391.       a0 = pSrc[2 * i] + pSrc[2 * i + 2];
  392.       xt = pSrc[2 * i] - pSrc[2 * i + 2];
  393.      
  394.       a1 = pSrc[2 * i + 3] + pSrc[2 * i + 1];
  395.       yt = pSrc[2 * i + 1] - pSrc[2 * i + 3];
  396.      
  397.       p0 = a0 * onebyfftLen;
  398.       p2 = xt * onebyfftLen;
  399.       p1 = a1 * onebyfftLen;
  400.       p3 = yt * onebyfftLen;
  401.      
  402.       pSrc[2 * i] = p0;
  403.       pSrc[2 * i + 1] = p1;  
  404.       pSrc[2 * i + 2] = p2;      
  405.       pSrc[2 * i + 3] = p3;
  406.    }                             // butterfly loop end
  407.  
  408. #else
  409.  
  410.    n2 = fftLen;
  411.  
  412.    // loop for stage
  413.    for (k = fftLen; k > 2; k = k >> 1)
  414.    {
  415.       n1 = n2;
  416.       n2 = n2 >> 1;
  417.       ia = 0;
  418.  
  419.       // loop for groups
  420.       j = 0;
  421.       do
  422.       {
  423.          cosVal = pCoef[ia * 2];
  424.          sinVal = pCoef[(ia * 2) + 1];
  425.          ia = ia + twidCoefModifier;
  426.  
  427.          // loop for butterfly
  428.          i = j;
  429.          do
  430.          {
  431.             l = i + n2;
  432.             a0 = pSrc[2 * i] + pSrc[2 * l];
  433.             xt = pSrc[2 * i] - pSrc[2 * l];
  434.  
  435.             yt = pSrc[2 * i + 1] - pSrc[2 * l + 1];
  436.             a1 = pSrc[2 * l + 1] + pSrc[2 * i + 1];
  437.            
  438.             p0 = xt * cosVal;
  439.             p1 = yt * sinVal;
  440.             p2 = yt * cosVal;
  441.             p3 = xt * sinVal;  
  442.            
  443.             pSrc[2 * i] = a0;  
  444.             pSrc[2 * i + 1] = a1;      
  445.            
  446.             pSrc[2 * l]     = p0 - p1;
  447.             pSrc[2 * l + 1] = p2 + p3;  
  448.            
  449.             i += n1;
  450.          } while( i < fftLen );                    // butterfly loop end
  451.          j++;
  452.       } while( j < n2 );                      // groups loop end
  453.  
  454.       twidCoefModifier = twidCoefModifier << 1u;
  455.    }                             // stages loop end
  456.  
  457.    n1 = n2;
  458.    n2 = n2 >> 1;
  459.  
  460.    // loop for butterfly
  461.    for (i = 0; i < fftLen; i += n1)
  462.    {
  463.       l = i + n2;
  464.      
  465.       a0 = pSrc[2 * i] + pSrc[2 * l];
  466.       xt = pSrc[2 * i] - pSrc[2 * l];
  467.      
  468.       a1 = pSrc[2 * l + 1] + pSrc[2 * i + 1];
  469.       yt = pSrc[2 * i + 1] - pSrc[2 * l + 1];
  470.      
  471.       p0 = a0 * onebyfftLen;
  472.       p2 = xt * onebyfftLen;
  473.       p1 = a1 * onebyfftLen;
  474.       p3 = yt * onebyfftLen;
  475.      
  476.       pSrc[2 * i] = p0;
  477.       pSrc[2u * l] = p2;
  478.      
  479.       pSrc[2 * i + 1] = p1;    
  480.       pSrc[2u * l + 1u] = p3;
  481.    }                             // butterfly loop end
  482.  
  483. #endif //      #ifndef ARM_MATH_CM0_FAMILY
  484.  
  485. }
  486.