Subversion Repositories dashGPS

Rev

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

  1. /* ----------------------------------------------------------------------
  2.  * Project:      CMSIS DSP Library
  3.  * Title:        arm_cfft_radix2_f32.c
  4.  * Description:  Radix-2 Decimation in Frequency CFFT & CIFFT Floating point processing function
  5.  *
  6.  * $Date:        27. January 2017
  7.  * $Revision:    V.1.5.1
  8.  *
  9.  * Target Processor: Cortex-M cores
  10.  * -------------------------------------------------------------------- */
  11. /*
  12.  * Copyright (C) 2010-2017 ARM Limited or its affiliates. All rights reserved.
  13.  *
  14.  * SPDX-License-Identifier: Apache-2.0
  15.  *
  16.  * Licensed under the Apache License, Version 2.0 (the License); you may
  17.  * not use this file except in compliance with the License.
  18.  * You may obtain a copy of the License at
  19.  *
  20.  * www.apache.org/licenses/LICENSE-2.0
  21.  *
  22.  * Unless required by applicable law or agreed to in writing, software
  23.  * distributed under the License is distributed on an AS IS BASIS, WITHOUT
  24.  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  25.  * See the License for the specific language governing permissions and
  26.  * limitations under the License.
  27.  */
  28.  
  29. #include "arm_math.h"
  30.  
  31. void arm_radix2_butterfly_f32(
  32.   float32_t * pSrc,
  33.   uint32_t fftLen,
  34.   float32_t * pCoef,
  35.   uint16_t twidCoefModifier);
  36.  
  37. void arm_radix2_butterfly_inverse_f32(
  38.   float32_t * pSrc,
  39.   uint32_t fftLen,
  40.   float32_t * pCoef,
  41.   uint16_t twidCoefModifier,
  42.   float32_t onebyfftLen);
  43.  
  44. extern void arm_bitreversal_f32(
  45.     float32_t * pSrc,
  46.     uint16_t fftSize,
  47.     uint16_t bitRevFactor,
  48.     uint16_t * pBitRevTab);
  49.  
  50. /**
  51. * @ingroup groupTransforms
  52. */
  53.  
  54. /**
  55. * @addtogroup ComplexFFT
  56. * @{
  57. */
  58.  
  59. /**
  60. * @details
  61. * @brief Radix-2 CFFT/CIFFT.
  62. * @deprecated Do not use this function.  It has been superseded by \ref arm_cfft_f32 and will be removed
  63. * in the future.
  64. * @param[in]      *S    points to an instance of the floating-point Radix-2 CFFT/CIFFT structure.
  65. * @param[in, out] *pSrc points to the complex data buffer of size <code>2*fftLen</code>. Processing occurs in-place.
  66. * @return none.
  67. */
  68.  
  69. void arm_cfft_radix2_f32(
  70. const arm_cfft_radix2_instance_f32 * S,
  71. float32_t * pSrc)
  72. {
  73.  
  74.    if (S->ifftFlag == 1U)
  75.    {
  76.       /*  Complex IFFT radix-2  */
  77.       arm_radix2_butterfly_inverse_f32(pSrc, S->fftLen, S->pTwiddle,
  78.       S->twidCoefModifier, S->onebyfftLen);
  79.    }
  80.    else
  81.    {
  82.       /*  Complex FFT radix-2  */
  83.       arm_radix2_butterfly_f32(pSrc, S->fftLen, S->pTwiddle,
  84.       S->twidCoefModifier);
  85.    }
  86.  
  87.    if (S->bitReverseFlag == 1U)
  88.    {
  89.       /*  Bit Reversal */
  90.       arm_bitreversal_f32(pSrc, S->fftLen, S->bitRevFactor, S->pBitRevTable);
  91.    }
  92.  
  93. }
  94.  
  95.  
  96. /**
  97. * @} end of ComplexFFT group
  98. */
  99.  
  100.  
  101.  
  102. /* ----------------------------------------------------------------------
  103. ** Internal helper function used by the FFTs
  104. ** ------------------------------------------------------------------- */
  105.  
  106. /*
  107. * @brief  Core function for the floating-point CFFT butterfly process.
  108. * @param[in, out] *pSrc            points to the in-place buffer of floating-point data type.
  109. * @param[in]      fftLen           length of the FFT.
  110. * @param[in]      *pCoef           points to the twiddle coefficient buffer.
  111. * @param[in]      twidCoefModifier twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table.
  112. * @return none.
  113. */
  114.  
  115. void arm_radix2_butterfly_f32(
  116. float32_t * pSrc,
  117. uint32_t fftLen,
  118. float32_t * pCoef,
  119. uint16_t twidCoefModifier)
  120. {
  121.  
  122.    uint32_t i, j, k, l;
  123.    uint32_t n1, n2, ia;
  124.    float32_t xt, yt, cosVal, sinVal;
  125.    float32_t p0, p1, p2, p3;
  126.    float32_t a0, a1;
  127.  
  128. #if defined (ARM_MATH_DSP)
  129.  
  130.    /*  Initializations for the first stage */
  131.    n2 = fftLen >> 1;
  132.    ia = 0;
  133.    i = 0;
  134.  
  135.    // loop for groups
  136.    for (k = n2; k > 0; k--)
  137.    {
  138.       cosVal = pCoef[ia * 2];
  139.       sinVal = pCoef[(ia * 2) + 1];
  140.  
  141.       /*  Twiddle coefficients index modifier */
  142.       ia += twidCoefModifier;
  143.  
  144.       /*  index calculation for the input as, */
  145.       /*  pSrc[i + 0], pSrc[i + fftLen/1] */
  146.       l = i + n2;
  147.  
  148.       /*  Butterfly implementation */
  149.       a0 = pSrc[2 * i] + pSrc[2 * l];
  150.       xt = pSrc[2 * i] - pSrc[2 * l];
  151.  
  152.       yt = pSrc[2 * i + 1] - pSrc[2 * l + 1];
  153.       a1 = pSrc[2 * l + 1] + pSrc[2 * i + 1];
  154.  
  155.       p0 = xt * cosVal;
  156.       p1 = yt * sinVal;
  157.       p2 = yt * cosVal;
  158.       p3 = xt * sinVal;
  159.  
  160.       pSrc[2 * i]     = a0;
  161.       pSrc[2 * i + 1] = a1;
  162.  
  163.       pSrc[2 * l]     = p0 + p1;
  164.       pSrc[2 * l + 1] = p2 - p3;
  165.  
  166.       i++;
  167.    }                             // groups loop end
  168.  
  169.    twidCoefModifier <<= 1U;
  170.  
  171.    // loop for stage
  172.    for (k = n2; k > 2; k = k >> 1)
  173.    {
  174.       n1 = n2;
  175.       n2 = n2 >> 1;
  176.       ia = 0;
  177.  
  178.       // loop for groups
  179.       j = 0;
  180.       do
  181.       {
  182.          cosVal = pCoef[ia * 2];
  183.          sinVal = pCoef[(ia * 2) + 1];
  184.          ia += twidCoefModifier;
  185.  
  186.          // loop for butterfly
  187.          i = j;
  188.          do
  189.          {
  190.             l = i + n2;
  191.             a0 = pSrc[2 * i] + pSrc[2 * l];
  192.             xt = pSrc[2 * i] - pSrc[2 * l];
  193.  
  194.             yt = pSrc[2 * i + 1] - pSrc[2 * l + 1];
  195.             a1 = pSrc[2 * l + 1] + pSrc[2 * i + 1];
  196.  
  197.             p0 = xt * cosVal;
  198.             p1 = yt * sinVal;
  199.             p2 = yt * cosVal;
  200.             p3 = xt * sinVal;
  201.  
  202.             pSrc[2 * i] = a0;
  203.             pSrc[2 * i + 1] = a1;
  204.  
  205.             pSrc[2 * l]     = p0 + p1;
  206.             pSrc[2 * l + 1] = p2 - p3;
  207.  
  208.             i += n1;
  209.          } while ( i < fftLen );                        // butterfly loop end
  210.          j++;
  211.       } while ( j < n2);                          // groups loop end
  212.       twidCoefModifier <<= 1U;
  213.    }                             // stages loop end
  214.  
  215.    // loop for butterfly
  216.    for (i = 0; i < fftLen; i += 2)
  217.    {
  218.       a0 = pSrc[2 * i] + pSrc[2 * i + 2];
  219.       xt = pSrc[2 * i] - pSrc[2 * i + 2];
  220.  
  221.       yt = pSrc[2 * i + 1] - pSrc[2 * i + 3];
  222.       a1 = pSrc[2 * i + 3] + pSrc[2 * i + 1];
  223.  
  224.       pSrc[2 * i] = a0;
  225.       pSrc[2 * i + 1] = a1;
  226.       pSrc[2 * i + 2] = xt;
  227.       pSrc[2 * i + 3] = yt;
  228.    }                             // groups loop end
  229.  
  230. #else
  231.  
  232.    n2 = fftLen;
  233.  
  234.    // loop for stage
  235.    for (k = fftLen; k > 1; k = k >> 1)
  236.    {
  237.       n1 = n2;
  238.       n2 = n2 >> 1;
  239.       ia = 0;
  240.  
  241.       // loop for groups
  242.       j = 0;
  243.       do
  244.       {
  245.          cosVal = pCoef[ia * 2];
  246.          sinVal = pCoef[(ia * 2) + 1];
  247.          ia += twidCoefModifier;
  248.  
  249.          // loop for butterfly
  250.          i = j;
  251.          do
  252.          {
  253.             l = i + n2;
  254.             a0 = pSrc[2 * i] + pSrc[2 * l];
  255.             xt = pSrc[2 * i] - pSrc[2 * l];
  256.  
  257.             yt = pSrc[2 * i + 1] - pSrc[2 * l + 1];
  258.             a1 = pSrc[2 * l + 1] + pSrc[2 * i + 1];
  259.  
  260.             p0 = xt * cosVal;
  261.             p1 = yt * sinVal;
  262.             p2 = yt * cosVal;
  263.             p3 = xt * sinVal;
  264.  
  265.             pSrc[2 * i] = a0;
  266.             pSrc[2 * i + 1] = a1;
  267.  
  268.             pSrc[2 * l]     = p0 + p1;
  269.             pSrc[2 * l + 1] = p2 - p3;
  270.  
  271.             i += n1;
  272.          } while (i < fftLen);
  273.          j++;
  274.       } while (j < n2);
  275.       twidCoefModifier <<= 1U;
  276.    }
  277.  
  278. #endif //    #if defined (ARM_MATH_DSP)
  279.  
  280. }
  281.  
  282.  
  283. void arm_radix2_butterfly_inverse_f32(
  284. float32_t * pSrc,
  285. uint32_t fftLen,
  286. float32_t * pCoef,
  287. uint16_t twidCoefModifier,
  288. float32_t onebyfftLen)
  289. {
  290.  
  291.    uint32_t i, j, k, l;
  292.    uint32_t n1, n2, ia;
  293.    float32_t xt, yt, cosVal, sinVal;
  294.    float32_t p0, p1, p2, p3;
  295.    float32_t a0, a1;
  296.  
  297. #if defined (ARM_MATH_DSP)
  298.  
  299.    n2 = fftLen >> 1;
  300.    ia = 0;
  301.  
  302.    // loop for groups
  303.    for (i = 0; i < n2; i++)
  304.    {
  305.       cosVal = pCoef[ia * 2];
  306.       sinVal = pCoef[(ia * 2) + 1];
  307.       ia += twidCoefModifier;
  308.  
  309.       l = i + n2;
  310.       a0 = pSrc[2 * i] + pSrc[2 * l];
  311.       xt = pSrc[2 * i] - pSrc[2 * l];
  312.  
  313.       yt = pSrc[2 * i + 1] - pSrc[2 * l + 1];
  314.       a1 = pSrc[2 * l + 1] + pSrc[2 * i + 1];
  315.  
  316.       p0 = xt * cosVal;
  317.       p1 = yt * sinVal;
  318.       p2 = yt * cosVal;
  319.       p3 = xt * sinVal;
  320.  
  321.       pSrc[2 * i] = a0;
  322.       pSrc[2 * i + 1] = a1;
  323.  
  324.       pSrc[2 * l]     = p0 - p1;
  325.       pSrc[2 * l + 1] = p2 + p3;
  326.    }                             // groups loop end
  327.  
  328.    twidCoefModifier <<= 1U;
  329.  
  330.    // loop for stage
  331.    for (k = fftLen / 2; k > 2; k = k >> 1)
  332.    {
  333.       n1 = n2;
  334.       n2 = n2 >> 1;
  335.       ia = 0;
  336.  
  337.       // loop for groups
  338.       j = 0;
  339.       do
  340.       {
  341.          cosVal = pCoef[ia * 2];
  342.          sinVal = pCoef[(ia * 2) + 1];
  343.          ia += twidCoefModifier;
  344.  
  345.          // loop for butterfly
  346.          i = j;
  347.          do
  348.          {
  349.             l = i + n2;
  350.             a0 = pSrc[2 * i] + pSrc[2 * l];
  351.             xt = pSrc[2 * i] - pSrc[2 * l];
  352.  
  353.             yt = pSrc[2 * i + 1] - pSrc[2 * l + 1];
  354.             a1 = pSrc[2 * l + 1] + pSrc[2 * i + 1];
  355.  
  356.             p0 = xt * cosVal;
  357.             p1 = yt * sinVal;
  358.             p2 = yt * cosVal;
  359.             p3 = xt * sinVal;
  360.  
  361.             pSrc[2 * i] = a0;
  362.             pSrc[2 * i + 1] = a1;
  363.  
  364.             pSrc[2 * l]     = p0 - p1;
  365.             pSrc[2 * l + 1] = p2 + p3;
  366.  
  367.             i += n1;
  368.          } while ( i < fftLen );                 // butterfly loop end
  369.          j++;
  370.       } while (j < n2);                      // groups loop end
  371.  
  372.       twidCoefModifier <<= 1U;
  373.    }                             // stages loop end
  374.  
  375.    // loop for butterfly
  376.    for (i = 0; i < fftLen; i += 2)
  377.    {
  378.       a0 = pSrc[2 * i] + pSrc[2 * i + 2];
  379.       xt = pSrc[2 * i] - pSrc[2 * i + 2];
  380.  
  381.       a1 = pSrc[2 * i + 3] + pSrc[2 * i + 1];
  382.       yt = pSrc[2 * i + 1] - pSrc[2 * i + 3];
  383.  
  384.       p0 = a0 * onebyfftLen;
  385.       p2 = xt * onebyfftLen;
  386.       p1 = a1 * onebyfftLen;
  387.       p3 = yt * onebyfftLen;
  388.  
  389.       pSrc[2 * i] = p0;
  390.       pSrc[2 * i + 1] = p1;
  391.       pSrc[2 * i + 2] = p2;
  392.       pSrc[2 * i + 3] = p3;
  393.    }                             // butterfly loop end
  394.  
  395. #else
  396.  
  397.    n2 = fftLen;
  398.  
  399.    // loop for stage
  400.    for (k = fftLen; k > 2; k = k >> 1)
  401.    {
  402.       n1 = n2;
  403.       n2 = n2 >> 1;
  404.       ia = 0;
  405.  
  406.       // loop for groups
  407.       j = 0;
  408.       do
  409.       {
  410.          cosVal = pCoef[ia * 2];
  411.          sinVal = pCoef[(ia * 2) + 1];
  412.          ia = ia + twidCoefModifier;
  413.  
  414.          // loop for butterfly
  415.          i = j;
  416.          do
  417.          {
  418.             l = i + n2;
  419.             a0 = pSrc[2 * i] + pSrc[2 * l];
  420.             xt = pSrc[2 * i] - pSrc[2 * l];
  421.  
  422.             yt = pSrc[2 * i + 1] - pSrc[2 * l + 1];
  423.             a1 = pSrc[2 * l + 1] + pSrc[2 * i + 1];
  424.  
  425.             p0 = xt * cosVal;
  426.             p1 = yt * sinVal;
  427.             p2 = yt * cosVal;
  428.             p3 = xt * sinVal;
  429.  
  430.             pSrc[2 * i] = a0;
  431.             pSrc[2 * i + 1] = a1;
  432.  
  433.             pSrc[2 * l]     = p0 - p1;
  434.             pSrc[2 * l + 1] = p2 + p3;
  435.  
  436.             i += n1;
  437.          } while ( i < fftLen );                    // butterfly loop end
  438.          j++;
  439.       } while ( j < n2 );                      // groups loop end
  440.  
  441.       twidCoefModifier = twidCoefModifier << 1U;
  442.    }                             // stages loop end
  443.  
  444.    n1 = n2;
  445.    n2 = n2 >> 1;
  446.  
  447.    // loop for butterfly
  448.    for (i = 0; i < fftLen; i += n1)
  449.    {
  450.       l = i + n2;
  451.  
  452.       a0 = pSrc[2 * i] + pSrc[2 * l];
  453.       xt = pSrc[2 * i] - pSrc[2 * l];
  454.  
  455.       a1 = pSrc[2 * l + 1] + pSrc[2 * i + 1];
  456.       yt = pSrc[2 * i + 1] - pSrc[2 * l + 1];
  457.  
  458.       p0 = a0 * onebyfftLen;
  459.       p2 = xt * onebyfftLen;
  460.       p1 = a1 * onebyfftLen;
  461.       p3 = yt * onebyfftLen;
  462.  
  463.       pSrc[2 * i] = p0;
  464.       pSrc[2U * l] = p2;
  465.  
  466.       pSrc[2 * i + 1] = p1;
  467.       pSrc[2U * l + 1U] = p3;
  468.    }                             // butterfly loop end
  469.  
  470. #endif //      #if defined (ARM_MATH_DSP)
  471.  
  472. }
  473.