Subversion Repositories dashGPS

Rev

Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. /* ----------------------------------------------------------------------
  2.  * Project:      CMSIS DSP Library
  3.  * Title:        arm_cfft_radix2_q31.c
  4.  * Description:  Radix-2 Decimation in Frequency CFFT & CIFFT Fixed 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_q31(
  32.   q31_t * pSrc,
  33.   uint32_t fftLen,
  34.   q31_t * pCoef,
  35.   uint16_t twidCoefModifier);
  36.  
  37. void arm_radix2_butterfly_inverse_q31(
  38.   q31_t * pSrc,
  39.   uint32_t fftLen,
  40.   q31_t * pCoef,
  41.   uint16_t twidCoefModifier);
  42.  
  43. void arm_bitreversal_q31(
  44.   q31_t * pSrc,
  45.   uint32_t fftLen,
  46.   uint16_t bitRevFactor,
  47.   uint16_t * pBitRevTab);
  48.  
  49. /**
  50. * @ingroup groupTransforms
  51. */
  52.  
  53. /**
  54. * @addtogroup ComplexFFT
  55. * @{
  56. */
  57.  
  58. /**
  59. * @details
  60. * @brief Processing function for the fixed-point CFFT/CIFFT.
  61. * @deprecated Do not use this function.  It has been superseded by \ref arm_cfft_q31 and will be removed
  62. * @param[in]      *S    points to an instance of the fixed-point CFFT/CIFFT structure.
  63. * @param[in, out] *pSrc points to the complex data buffer of size <code>2*fftLen</code>. Processing occurs in-place.
  64. * @return none.
  65. */
  66.  
  67. void arm_cfft_radix2_q31(
  68. const arm_cfft_radix2_instance_q31 * S,
  69. q31_t * pSrc)
  70. {
  71.  
  72.    if (S->ifftFlag == 1U)
  73.    {
  74.       arm_radix2_butterfly_inverse_q31(pSrc, S->fftLen,
  75.       S->pTwiddle, S->twidCoefModifier);
  76.    }
  77.    else
  78.    {
  79.       arm_radix2_butterfly_q31(pSrc, S->fftLen,
  80.       S->pTwiddle, S->twidCoefModifier);
  81.    }
  82.  
  83.    arm_bitreversal_q31(pSrc, S->fftLen, S->bitRevFactor, S->pBitRevTable);
  84. }
  85.  
  86. /**
  87. * @} end of ComplexFFT group
  88. */
  89.  
  90. void arm_radix2_butterfly_q31(
  91. q31_t * pSrc,
  92. uint32_t fftLen,
  93. q31_t * pCoef,
  94. uint16_t twidCoefModifier)
  95. {
  96.  
  97.    unsigned i, j, k, l, m;
  98.    unsigned n1, n2, ia;
  99.    q31_t xt, yt, cosVal, sinVal;
  100.    q31_t p0, p1;
  101.  
  102.    //N = fftLen;
  103.    n2 = fftLen;
  104.  
  105.    n1 = n2;
  106.    n2 = n2 >> 1;
  107.    ia = 0;
  108.  
  109.    // loop for groups
  110.    for (i = 0; i < n2; i++)
  111.    {
  112.       cosVal = pCoef[ia * 2];
  113.       sinVal = pCoef[(ia * 2) + 1];
  114.       ia = ia + twidCoefModifier;
  115.  
  116.       l = i + n2;
  117.       xt = (pSrc[2 * i] >> 1U) - (pSrc[2 * l] >> 1U);
  118.       pSrc[2 * i] = ((pSrc[2 * i] >> 1U) + (pSrc[2 * l] >> 1U)) >> 1U;
  119.  
  120.       yt = (pSrc[2 * i + 1] >> 1U) - (pSrc[2 * l + 1] >> 1U);
  121.       pSrc[2 * i + 1] =
  122.         ((pSrc[2 * l + 1] >> 1U) + (pSrc[2 * i + 1] >> 1U)) >> 1U;
  123.  
  124.       mult_32x32_keep32_R(p0, xt, cosVal);
  125.       mult_32x32_keep32_R(p1, yt, cosVal);
  126.       multAcc_32x32_keep32_R(p0, yt, sinVal);
  127.       multSub_32x32_keep32_R(p1, xt, sinVal);
  128.  
  129.       pSrc[2U * l] = p0;
  130.       pSrc[2U * l + 1U] = p1;
  131.  
  132.    }                             // groups loop end
  133.  
  134.    twidCoefModifier <<= 1U;
  135.  
  136.    // loop for stage
  137.    for (k = fftLen / 2; k > 2; k = k >> 1)
  138.    {
  139.       n1 = n2;
  140.       n2 = n2 >> 1;
  141.       ia = 0;
  142.  
  143.       // loop for groups
  144.       for (j = 0; j < n2; j++)
  145.       {
  146.          cosVal = pCoef[ia * 2];
  147.          sinVal = pCoef[(ia * 2) + 1];
  148.          ia = ia + twidCoefModifier;
  149.  
  150.          // loop for butterfly
  151.          i = j;
  152.          m = fftLen / n1;
  153.          do
  154.          {
  155.             l = i + n2;
  156.             xt = pSrc[2 * i] - pSrc[2 * l];
  157.             pSrc[2 * i] = (pSrc[2 * i] + pSrc[2 * l]) >> 1U;
  158.  
  159.             yt = pSrc[2 * i + 1] - pSrc[2 * l + 1];
  160.             pSrc[2 * i + 1] = (pSrc[2 * l + 1] + pSrc[2 * i + 1]) >> 1U;
  161.  
  162.             mult_32x32_keep32_R(p0, xt, cosVal);
  163.             mult_32x32_keep32_R(p1, yt, cosVal);
  164.             multAcc_32x32_keep32_R(p0, yt, sinVal);
  165.             multSub_32x32_keep32_R(p1, xt, sinVal);
  166.  
  167.             pSrc[2U * l] = p0;
  168.             pSrc[2U * l + 1U] = p1;
  169.             i += n1;
  170.             m--;
  171.          } while ( m > 0);                   // butterfly loop end
  172.  
  173.       }                           // groups loop end
  174.  
  175.       twidCoefModifier <<= 1U;
  176.    }                             // stages loop end
  177.  
  178.    n1 = n2;
  179.    n2 = n2 >> 1;
  180.    ia = 0;
  181.  
  182.    cosVal = pCoef[ia * 2];
  183.    sinVal = pCoef[(ia * 2) + 1];
  184.    ia = ia + twidCoefModifier;
  185.  
  186.    // loop for butterfly
  187.    for (i = 0; i < fftLen; i += n1)
  188.    {
  189.       l = i + n2;
  190.       xt = pSrc[2 * i] - pSrc[2 * l];
  191.       pSrc[2 * i] = (pSrc[2 * i] + pSrc[2 * l]);
  192.  
  193.       yt = pSrc[2 * i + 1] - pSrc[2 * l + 1];
  194.       pSrc[2 * i + 1] = (pSrc[2 * l + 1] + pSrc[2 * i + 1]);
  195.  
  196.       pSrc[2U * l] = xt;
  197.  
  198.       pSrc[2U * l + 1U] = yt;
  199.  
  200.       i += n1;
  201.       l = i + n2;
  202.  
  203.       xt = pSrc[2 * i] - pSrc[2 * l];
  204.       pSrc[2 * i] = (pSrc[2 * i] + pSrc[2 * l]);
  205.  
  206.       yt = pSrc[2 * i + 1] - pSrc[2 * l + 1];
  207.       pSrc[2 * i + 1] = (pSrc[2 * l + 1] + pSrc[2 * i + 1]);
  208.  
  209.       pSrc[2U * l] = xt;
  210.  
  211.       pSrc[2U * l + 1U] = yt;
  212.  
  213.    }                             // butterfly loop end
  214.  
  215. }
  216.  
  217.  
  218. void arm_radix2_butterfly_inverse_q31(
  219. q31_t * pSrc,
  220. uint32_t fftLen,
  221. q31_t * pCoef,
  222. uint16_t twidCoefModifier)
  223. {
  224.  
  225.    unsigned i, j, k, l;
  226.    unsigned n1, n2, ia;
  227.    q31_t xt, yt, cosVal, sinVal;
  228.    q31_t p0, p1;
  229.  
  230.    //N = fftLen;
  231.    n2 = fftLen;
  232.  
  233.    n1 = n2;
  234.    n2 = n2 >> 1;
  235.    ia = 0;
  236.  
  237.    // loop for groups
  238.    for (i = 0; i < n2; i++)
  239.    {
  240.       cosVal = pCoef[ia * 2];
  241.       sinVal = pCoef[(ia * 2) + 1];
  242.       ia = ia + twidCoefModifier;
  243.  
  244.       l = i + n2;
  245.       xt = (pSrc[2 * i] >> 1U) - (pSrc[2 * l] >> 1U);
  246.       pSrc[2 * i] = ((pSrc[2 * i] >> 1U) + (pSrc[2 * l] >> 1U)) >> 1U;
  247.  
  248.       yt = (pSrc[2 * i + 1] >> 1U) - (pSrc[2 * l + 1] >> 1U);
  249.       pSrc[2 * i + 1] =
  250.         ((pSrc[2 * l + 1] >> 1U) + (pSrc[2 * i + 1] >> 1U)) >> 1U;
  251.  
  252.       mult_32x32_keep32_R(p0, xt, cosVal);
  253.       mult_32x32_keep32_R(p1, yt, cosVal);
  254.       multSub_32x32_keep32_R(p0, yt, sinVal);
  255.       multAcc_32x32_keep32_R(p1, xt, sinVal);
  256.  
  257.       pSrc[2U * l] = p0;
  258.       pSrc[2U * l + 1U] = p1;
  259.    }                             // groups loop end
  260.  
  261.    twidCoefModifier = twidCoefModifier << 1U;
  262.  
  263.    // loop for stage
  264.    for (k = fftLen / 2; k > 2; k = k >> 1)
  265.    {
  266.       n1 = n2;
  267.       n2 = n2 >> 1;
  268.       ia = 0;
  269.  
  270.       // loop for groups
  271.       for (j = 0; j < n2; j++)
  272.       {
  273.          cosVal = pCoef[ia * 2];
  274.          sinVal = pCoef[(ia * 2) + 1];
  275.          ia = ia + twidCoefModifier;
  276.  
  277.          // loop for butterfly
  278.          for (i = j; i < fftLen; i += n1)
  279.          {
  280.             l = i + n2;
  281.             xt = pSrc[2 * i] - pSrc[2 * l];
  282.             pSrc[2 * i] = (pSrc[2 * i] + pSrc[2 * l]) >> 1U;
  283.  
  284.             yt = pSrc[2 * i + 1] - pSrc[2 * l + 1];
  285.             pSrc[2 * i + 1] = (pSrc[2 * l + 1] + pSrc[2 * i + 1]) >> 1U;
  286.  
  287.             mult_32x32_keep32_R(p0, xt, cosVal);
  288.             mult_32x32_keep32_R(p1, yt, cosVal);
  289.             multSub_32x32_keep32_R(p0, yt, sinVal);
  290.             multAcc_32x32_keep32_R(p1, xt, sinVal);
  291.  
  292.             pSrc[2U * l] = p0;
  293.             pSrc[2U * l + 1U] = p1;
  294.          }                         // butterfly loop end
  295.  
  296.       }                           // groups loop end
  297.  
  298.       twidCoefModifier = twidCoefModifier << 1U;
  299.    }                             // stages loop end
  300.  
  301.    n1 = n2;
  302.    n2 = n2 >> 1;
  303.    ia = 0;
  304.  
  305.    cosVal = pCoef[ia * 2];
  306.    sinVal = pCoef[(ia * 2) + 1];
  307.    ia = ia + twidCoefModifier;
  308.  
  309.    // loop for butterfly
  310.    for (i = 0; i < fftLen; i += n1)
  311.    {
  312.       l = i + n2;
  313.       xt = pSrc[2 * i] - pSrc[2 * l];
  314.       pSrc[2 * i] = (pSrc[2 * i] + pSrc[2 * l]);
  315.  
  316.       yt = pSrc[2 * i + 1] - pSrc[2 * l + 1];
  317.       pSrc[2 * i + 1] = (pSrc[2 * l + 1] + pSrc[2 * i + 1]);
  318.  
  319.       pSrc[2U * l] = xt;
  320.  
  321.       pSrc[2U * l + 1U] = yt;
  322.  
  323.       i += n1;
  324.       l = i + n2;
  325.  
  326.       xt = pSrc[2 * i] - pSrc[2 * l];
  327.       pSrc[2 * i] = (pSrc[2 * i] + pSrc[2 * l]);
  328.  
  329.       yt = pSrc[2 * i + 1] - pSrc[2 * l + 1];
  330.       pSrc[2 * i + 1] = (pSrc[2 * l + 1] + pSrc[2 * i + 1]);
  331.  
  332.       pSrc[2U * l] = xt;
  333.  
  334.       pSrc[2U * l + 1U] = yt;
  335.  
  336.    }                             // butterfly loop end
  337.  
  338. }
  339.