LCOV - code coverage report
Current view: top level - lib_com - fft_rel.c (source / functions) Hit Total Coverage
Test: Coverage on main -- short test vectors @ 6c9ddc4024a9c0e1ecb8f643f114a84a0e26ec6b Lines: 106 106 100.0 %
Date: 2025-05-23 08:37:30 Functions: 1 1 100.0 %

          Line data    Source code
       1             : /******************************************************************************************************
       2             : 
       3             :    (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB,
       4             :    Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
       5             :    Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
       6             :    Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
       7             :    contributors to this repository. All Rights Reserved.
       8             : 
       9             :    This software is protected by copyright law and by international treaties.
      10             :    The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB,
      11             :    Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
      12             :    Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
      13             :    Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
      14             :    contributors to this repository retain full ownership rights in their respective contributions in
      15             :    the software. This notice grants no license of any kind, including but not limited to patent
      16             :    license, nor is any license granted by implication, estoppel or otherwise.
      17             : 
      18             :    Contributors are required to enter into the IVAS codec Public Collaboration agreement before making
      19             :    contributions.
      20             : 
      21             :    This software is provided "AS IS", without any express or implied warranties. The software is in the
      22             :    development stage. It is intended exclusively for experts who have experience with such software and
      23             :    solely for the purpose of inspection. All implied warranties of non-infringement, merchantability
      24             :    and fitness for a particular purpose are hereby disclaimed and excluded.
      25             : 
      26             :    Any dispute, controversy or claim arising under or in relation to providing this software shall be
      27             :    submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in
      28             :    accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and
      29             :    the United Nations Convention on Contracts on the International Sales of Goods.
      30             : 
      31             : *******************************************************************************************************/
      32             : 
      33             : /*====================================================================================
      34             :     EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0
      35             :   ====================================================================================*/
      36             : 
      37             : #include <stdint.h>
      38             : #include "options.h"
      39             : #ifdef DEBUGGING
      40             : #include "debug.h"
      41             : #endif
      42             : #include "prot.h"
      43             : #include "rom_com.h"
      44             : #include "wmc_auto.h"
      45             : 
      46             : /*---------------------------------------------------------------------*
      47             :  * Local constants
      48             :  *---------------------------------------------------------------------*/
      49             : 
      50             : #define N_MAX_FFT  1024
      51             : #define N_MAX_DIV2 ( N_MAX_FFT >> 1 )
      52             : #define N_MAX_DIV4 ( N_MAX_DIV2 >> 1 )
      53             : 
      54             : /*---------------------------------------------------------------------*
      55             :  *  fft_rel()
      56             :  *
      57             :  *  Computes the split-radix FFT in place for the real-valued
      58             :  *  signal x of length n.  The algorithm has been ported from
      59             :  *  the Fortran code of [1].
      60             :  *
      61             :  *  The function  needs sine and cosine tables t_sin and t_cos,
      62             :  *  and the constant N_MAX_FFT.  The table  entries  are defined as
      63             :  *  sin(2*pi*i) and cos(2*pi*i) for i = 0, 1, ..., N_MAX_FFT-1. The
      64             :  *  implementation  assumes  that any entry  will not be needed
      65             :  *  outside the tables. Therefore, N_MAX_FFT and n must be properly
      66             :  *  set.  The function has been tested  with the values n = 16,
      67             :  *  32, 64, 128, 256, and N_MAX_FFT = 1280.
      68             :  *
      69             :  *  References
      70             :  *  [1] H.V. Sorensen,  D.L. Jones, M.T. Heideman, C.S. Burrus,
      71             :  *      "Real-valued fast  Fourier transform  algorithm,"  IEEE
      72             :  *      Trans. on Signal Processing,  Vol.35, No.6, pp 849-863,
      73             :  *      1987.
      74             :  *
      75             :  *  OUTPUT
      76             :  *      x[0:n-1]  Transform coeffients in the order re[0], re[1],
      77             :  *                ..., re[n/2], im[n/2-1], ..., im[1].
      78             :  *---------------------------------------------------------------------*/
      79             : 
      80     3194115 : void fft_rel(
      81             :     float x[],       /* i/o: input/output vector    */
      82             :     const int16_t n, /* i  : vector length          */
      83             :     const int16_t m  /* i  : log2 of vector length  */
      84             : )
      85             : {
      86             :     int16_t i, j, k, n1, n2, n4;
      87             :     int16_t step;
      88             :     float xt, t1, t2;
      89             :     float *x0, *x1, *x2;
      90             :     float *xi2, *xi3, *xi4, *xi1;
      91             :     const float *s, *c;
      92             :     const int16_t *idx;
      93             : 
      94             :     /* !!!! NMAX = 256 is hardcoded here  (similar optimizations should be done for NMAX > 256) !!! */
      95             : 
      96             :     float *x2even, *x2odd;
      97             :     float temp[512];
      98             : 
      99     3194115 :     if ( n == 128 || n == 256 || n == 512 )
     100             :     {
     101     3027355 :         idx = fft256_read_indexes;
     102             : 
     103             :         /* Combined Digit reverse counter & Length two butterflies */
     104     3027355 :         if ( n == 128 )
     105             :         {
     106        1224 :             x2 = temp;
     107       79560 :             for ( i = 0; i < 64; i++ )
     108             :             {
     109       78336 :                 j = *idx++;
     110       78336 :                 k = *idx++;
     111             : 
     112       78336 :                 *x2++ = x[j >> 1] + x[k >> 1];
     113       78336 :                 *x2++ = x[j >> 1] - x[k >> 1];
     114             :             }
     115             :         }
     116     3026131 :         else if ( n == 256 )
     117             :         {
     118     2880301 :             x2 = temp;
     119   371558829 :             for ( i = 0; i < 128; i++ )
     120             :             {
     121   368678528 :                 j = *idx++;
     122   368678528 :                 k = *idx++;
     123             : 
     124   368678528 :                 *x2++ = x[j] + x[k];
     125   368678528 :                 *x2++ = x[j] - x[k];
     126             :             }
     127             :         }
     128      145830 :         else if ( n == 512 )
     129             :         {
     130      145830 :             x2even = temp;
     131      145830 :             x2odd = temp + 256;
     132             : 
     133    18812070 :             for ( i = 0; i < 128; i++ )
     134             :             {
     135    18666240 :                 j = 2 * *idx++;
     136    18666240 :                 k = 2 * *idx++;
     137             : 
     138    18666240 :                 *x2even++ = x[j] + x[k];
     139    18666240 :                 *x2even++ = x[j] - x[k];
     140    18666240 :                 *x2odd++ = x[++j] + x[++k];
     141    18666240 :                 *x2odd++ = x[j] - x[k];
     142             :             }
     143             :         }
     144             : 
     145             :         /*-----------------------------------------------------------------*
     146             :          * 1st Stage Loop has been Unrolled because n4 is '1' and that
     147             :          * allows the elimination of the 'for_ (j = 1; j < n4; j++)' loop
     148             :          * and the associated pointers initialization.
     149             :          * Also, it allows to Put the Data from 'temp' back into 'x' due
     150             :          * to the previous Combined Digit Reverse and Length two butterflies
     151             :          *-----------------------------------------------------------------*/
     152             : 
     153             :         /*for_ (k = 2; k < 3; k++)*/
     154             :         {
     155     3027355 :             x0 = temp;
     156     3027355 :             x1 = x0 + 2;
     157     3027355 :             x2 = x;
     158             : 
     159   206072027 :             for ( i = 0; i < n; i += 4 )
     160             :             {
     161   203044672 :                 *x2++ = *x0++ + *x1; /* x[i] = xt + x[i+n2];    */
     162   203044672 :                 *x2++ = *x0;
     163   203044672 :                 *x2++ = *--x0 - *x1++; /* x[i+n2] = xt - x[i+n2];      */
     164   203044672 :                 *x2++ = -*x1;          /* x[i+n2+n4] = -x[i+n2+n4];     */
     165             : 
     166   203044672 :                 x0 += 4;
     167   203044672 :                 x1 += 3; /* x1 has already advanced */
     168             :             }
     169             :         }
     170             :     }
     171             :     else
     172             :     {
     173             :         /*-----------------------------------------------------------------*
     174             :          * Digit reverse counter
     175             :          *-----------------------------------------------------------------*/
     176             : 
     177      166760 :         j = 0;
     178      166760 :         x0 = &x[0];
     179     7324880 :         for ( i = 0; i < n - 1; i++ )
     180             :         {
     181     7158120 :             if ( i < j )
     182             :             {
     183     3168404 :                 xt = x[j];
     184     3168404 :                 x[j] = *x0;
     185     3168404 :                 *x0 = xt;
     186             :             }
     187     7158120 :             x0++;
     188     7158120 :             k = n / 2;
     189    13548224 :             while ( k <= j )
     190             :             {
     191     6390104 :                 j -= k;
     192     6390104 :                 k = k >> 1;
     193             :             }
     194     7158120 :             j += k;
     195             :         }
     196             : 
     197             :         /*-----------------------------------------------------------------*
     198             :          * Length two butterflies
     199             :          *-----------------------------------------------------------------*/
     200             : 
     201      166760 :         x0 = &x[0];
     202      166760 :         x1 = &x[1];
     203     3829200 :         for ( i = 0; i < n / 2; i++ )
     204             :         {
     205     3662440 :             *x1 = *x0 - *x1;
     206     3662440 :             *x0 = *x0 * 2 - *x1;
     207             : 
     208     3662440 :             x0++;
     209     3662440 :             x0++;
     210     3662440 :             x1++;
     211     3662440 :             x1++;
     212             :         }
     213             : 
     214             :         /*-----------------------------------------------------------------*
     215             :          * 1st Stage Loop has been Unrolled because n4 is '1' and that
     216             :          * allows the elimination of the 'for_ (j = 1; j < n4; j++)' loop
     217             :          * and the associated pointers initialization.
     218             :          *-----------------------------------------------------------------*/
     219             : 
     220             :         /* for_ (k = 2; k < 3; k++) */
     221             :         {
     222      166760 :             x0 = x;
     223      166760 :             x1 = x0 + 2;
     224             : 
     225     1997980 :             for ( i = 0; i < n; i += 4 )
     226             :             {
     227     1831220 :                 *x1 = *x0 - *x1;       /* x[i+n2] = xt - x[i+n2];      */
     228     1831220 :                 *x0 = *x0 * 2 - *x1++; /* x[i] = xt + x[i+n2];    */
     229     1831220 :                 *x1 = -*x1;            /* x[i+n2+n4] = -x[i+n2+n4];     */
     230             : 
     231     1831220 :                 x0 += 4;
     232     1831220 :                 x1 += 3; /* x1 has already advanced */
     233             :             }
     234             :         }
     235             :     }
     236             : 
     237             :     /*-----------------------------------------------------------------*
     238             :      * Other butterflies
     239             :      *
     240             :      * The implementation described in [1] has been changed by using
     241             :      * table lookup for evaluating sine and cosine functions.  The
     242             :      * variable ind and its increment step are needed to access table
     243             :      * entries.  Note that this implementation assumes n4 to be so
     244             :      * small that ind will never exceed the table.  Thus the input
     245             :      * argument n and the constant N_MAX_FFT must be set properly.
     246             :      *-----------------------------------------------------------------*/
     247             : 
     248     3194115 :     n4 = 1;
     249     3194115 :     n2 = 2;
     250     3194115 :     n1 = 4;
     251             : 
     252     3194115 :     step = N_MAX_DIV4;
     253             : 
     254    21937347 :     for ( k = 3; k <= m; k++ )
     255             :     {
     256    18743232 :         step >>= 1;
     257    18743232 :         n4 <<= 1;
     258    18743232 :         n2 <<= 1;
     259    18743232 :         n1 <<= 1;
     260             : 
     261    18743232 :         x0 = x;
     262    18743232 :         x1 = x0 + n2;
     263    18743232 :         x2 = x1 + n4;
     264             : 
     265   220425009 :         for ( i = 0; i < n; i += n1 )
     266             :         {
     267   201681777 :             *x1 = *x0 - *x1;     /* x[i+n2] = xt - x[i+n2];      */
     268   201681777 :             *x0 = *x0 * 2 - *x1; /* x[i] = xt + x[i+n2];    */
     269   201681777 :             *x2 = -*x2;          /* x[i+n2+n4] = -x[i+n2+n4];     */
     270             : 
     271   201681777 :             s = sincos_t_ext;
     272   201681777 :             c = s + N_MAX_FFT / 4; /* 1024/4 = 256, 256/4=64 */
     273   201681777 :             xi1 = x0;
     274   201681777 :             xi3 = xi1 + n2;
     275   201681777 :             xi2 = xi3;
     276   201681777 :             x0 += n1;
     277   201681777 :             xi4 = x0;
     278             : 
     279  1244146560 :             for ( j = 1; j < n4; j++ )
     280             :             {
     281  1042464783 :                 xi3++;
     282  1042464783 :                 xi1++;
     283  1042464783 :                 xi4--;
     284  1042464783 :                 xi2--;
     285  1042464783 :                 c += step;
     286  1042464783 :                 s += step; /* autoincrement by ar0 */
     287             : 
     288  1042464783 :                 t1 = *xi3 * *c + *xi4 * *s; /* t1 = *xi3**(pt_c+ind) + *xi4**(pt_s+ind);   */
     289  1042464783 :                 t2 = *xi3 * *s - *xi4 * *c; /* t2 = *xi3**(pt_s+ind) - *xi4**(pt_c+ind);     */
     290             : 
     291  1042464783 :                 *xi4 = *xi2 - t2;
     292  1042464783 :                 *xi2 = *xi1 - t1;
     293  1042464783 :                 *xi1 = *xi1 * 2 - *xi2;
     294  1042464783 :                 *xi3 = -2 * t2 - *xi4;
     295             :             }
     296             : 
     297   201681777 :             x1 += n1;
     298   201681777 :             x2 += n1;
     299             :         }
     300             :     }
     301             : 
     302     3194115 :     return;
     303             : }

Generated by: LCOV version 1.14