LCOV - code coverage report
Current view: top level - lib_com - ivas_mdft_imdft.c (source / functions) Hit Total Coverage
Test: Coverage on main -- short test vectors @ 6c9ddc4024a9c0e1ecb8f643f114a84a0e26ec6b Lines: 105 113 92.9 %
Date: 2025-05-23 08:37:30 Functions: 6 6 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             : #include <stdint.h>
      34             : #include "options.h"
      35             : #include "prot.h"
      36             : #include "ivas_prot.h"
      37             : #ifdef DEBUGGING
      38             : #include "debug.h"
      39             : #endif
      40             : #include "ivas_rom_com.h"
      41             : #include <assert.h>
      42             : #include "wmc_auto.h"
      43             : 
      44             : 
      45             : /*-----------------------------------------------------------------------------------------*
      46             :  * Local constants
      47             :  *-----------------------------------------------------------------------------------------*/
      48             : 
      49             : #define IVAS_ONE_BY_960 0.001041666666666666f
      50             : #define IVAS_ONE_BY_640 0.0015625f
      51             : #define IVAS_ONE_BY_320 0.003125f
      52             : #define IVAS_ONE_BY_240 0.004166666666666667f
      53             : #define IVAS_ONE_BY_160 0.00625f
      54             : #define IVAS_ONE_BY_80  0.0125f
      55             : 
      56             : 
      57             : /*-----------------------------------------------------------------------------------------*
      58             :  * Function ivas_get_mdft_twid_factors()
      59             :  *
      60             :  * get twiddle tables for MDFT
      61             :  *-----------------------------------------------------------------------------------------*/
      62             : 
      63    16792281 : static void ivas_get_mdft_twid_factors(
      64             :     const int16_t length,
      65             :     const float **ppTwid )
      66             : {
      67    16792281 :     switch ( length )
      68             :     {
      69      127223 :         case L_FRAME48k:
      70      127223 :             *ppTwid = &ivas_mdft_coeff_cos_twid_960[0];
      71      127223 :             break;
      72      139407 :         case L_FRAME32k:
      73      139407 :             *ppTwid = &ivas_mdft_coeff_cos_twid_640[0];
      74             : 
      75      139407 :             break;
      76       27486 :         case L_FRAME16k:
      77       27486 :             *ppTwid = &ivas_mdft_coeff_cos_twid_320[0];
      78       27486 :             break;
      79    14371328 :         case IVAS_240_PT_LEN:
      80    14371328 :             *ppTwid = &ivas_mdft_coeff_cos_twid_240[0];
      81    14371328 :             break;
      82     1312705 :         case IVAS_160_PT_LEN:
      83     1312705 :             *ppTwid = &ivas_mdft_coeff_cos_twid_160[0];
      84     1312705 :             break;
      85      477950 :         case IVAS_120_PT_LEN:
      86      477950 :             *ppTwid = &ivas_mdft_coeff_cos_twid_120[0];
      87      477950 :             break;
      88      336182 :         case IVAS_80_PT_LEN:
      89      336182 :             *ppTwid = &ivas_mdft_coeff_cos_twid_80[0];
      90      336182 :             break;
      91           0 :         case IVAS_40_PT_LEN:
      92           0 :             *ppTwid = &ivas_mdft_coeff_cos_twid_40[0];
      93           0 :             break;
      94             : 
      95           0 :         default:
      96           0 :             assert( !"Not supported FFT length!" );
      97             :             break;
      98             :     }
      99             : 
     100    16792281 :     return;
     101             : }
     102             : 
     103             : 
     104             : /*-----------------------------------------------------------------------------------------*
     105             :  * Function ivas_get_imdft_twid_factors()
     106             :  *
     107             :  * get twiddle tables for IMDFT
     108             :  *-----------------------------------------------------------------------------------------*/
     109             : 
     110     3071081 : static void ivas_get_imdft_twid_factors(
     111             :     const int16_t length,
     112             :     const float **ppTwid )
     113             : {
     114     3071081 :     switch ( length )
     115             :     {
     116      303578 :         case L_FRAME48k:
     117      303578 :             *ppTwid = ivas_mdft_coeff_cos_twid_960;
     118      303578 :             break;
     119      207457 :         case L_FRAME32k:
     120      207457 :             *ppTwid = ivas_mdft_coeff_cos_twid_640;
     121      207457 :             break;
     122       39986 :         case L_FRAME16k:
     123       39986 :             *ppTwid = ivas_mdft_coeff_cos_twid_320;
     124       39986 :             break;
     125     2458230 :         case 240:
     126     2458230 :             *ppTwid = ivas_mdft_coeff_cos_twid_240;
     127     2458230 :             break;
     128       21750 :         case 160:
     129       21750 :             *ppTwid = ivas_mdft_coeff_cos_twid_160;
     130       21750 :             break;
     131       40080 :         case 80:
     132       40080 :             *ppTwid = ivas_mdft_coeff_cos_twid_80;
     133       40080 :             break;
     134           0 :         default:
     135           0 :             assert( !"Not supported FFT length!" );
     136             :     }
     137             : 
     138     3071081 :     return;
     139             : }
     140             : 
     141             : 
     142     3071081 : static void get_one_by_length(
     143             :     float *one_by_length,
     144             :     const int16_t length )
     145             : {
     146     3071081 :     if ( length == L_FRAME48k )
     147             :     {
     148      303578 :         *one_by_length = IVAS_ONE_BY_960;
     149             :     }
     150     2767503 :     else if ( length == L_FRAME32k )
     151             :     {
     152      207457 :         *one_by_length = IVAS_ONE_BY_640;
     153             :     }
     154     2560046 :     else if ( length == L_FRAME16k )
     155             :     {
     156       39986 :         *one_by_length = IVAS_ONE_BY_320;
     157             :     }
     158     2520060 :     else if ( length == IVAS_240_PT_LEN )
     159             :     {
     160     2458230 :         *one_by_length = IVAS_ONE_BY_240;
     161             :     }
     162       61830 :     else if ( length == IVAS_160_PT_LEN )
     163             :     {
     164       21750 :         *one_by_length = IVAS_ONE_BY_160;
     165             :     }
     166       40080 :     else if ( length == IVAS_80_PT_LEN )
     167             :     {
     168       40080 :         *one_by_length = IVAS_ONE_BY_80;
     169             :     }
     170             :     else
     171             :     {
     172           0 :         assert( !"Not supported FFT length!" );
     173             :     }
     174             : 
     175     3071081 :     return;
     176             : }
     177             : 
     178             : 
     179             : /*-----------------------------------------------------------------------------------------*
     180             :  * Function ivas_ifft_cplx1()
     181             :  *
     182             :  * Complex IFFT implementation using fft()
     183             :  *-----------------------------------------------------------------------------------------*/
     184             : 
     185     3071081 : static void ivas_ifft_cplx1(
     186             :     float *re,
     187             :     float *im,
     188             :     const int16_t length )
     189             : {
     190             :     int16_t i;
     191             :     float one_by_length, tmp;
     192             : 
     193     3071081 :     get_one_by_length( &one_by_length, length );
     194             : 
     195             :     /* re-arrange inputs to use fft as ifft */
     196     3071081 :     re[0] = re[0] * one_by_length;
     197     3071081 :     im[0] = im[0] * one_by_length;
     198             : 
     199   519903321 :     for ( i = 1; i <= length >> 1; i++ )
     200             :     {
     201   516832240 :         tmp = re[length - i] * one_by_length;   /*stl_arr_index*/
     202   516832240 :         re[length - i] = re[i] * one_by_length; /*stl_arr_index*/
     203   516832240 :         re[i] = tmp;
     204             : 
     205   516832240 :         tmp = im[length - i] * one_by_length;   /*stl_arr_index*/
     206   516832240 :         im[length - i] = im[i] * one_by_length; /*stl_arr_index*/
     207   516832240 :         im[i] = tmp;
     208             :     }
     209             : 
     210     3071081 :     fft( re, im, length, 1 );
     211             : 
     212     3071081 :     return;
     213             : }
     214             : 
     215             : 
     216             : /*-----------------------------------------------------------------------------------------*
     217             : * Function ivas_mdft()
     218             : 
     219             : * MDFT implementation
     220             : *-----------------------------------------------------------------------------------------*/
     221             : 
     222    16792281 : void ivas_mdft(
     223             :     const float *pIn,           /* i  : input time-domain signal    */
     224             :     float *pOut_re,             /* o  : Real part of MDFT signal    */
     225             :     float *pOut_im,             /* o  : Imag. part of MDFT signal   */
     226             :     const int16_t input_length, /* i  : signal length               */
     227             :     const int16_t mdft_length   /* i  : MDFT length                 */
     228             : )
     229             : {
     230             :     float re[L_FRAME48k];
     231             :     float im[L_FRAME48k];
     232             :     int16_t j, len_by_2;
     233             :     const float *pTwid;
     234             : 
     235    16792281 :     len_by_2 = mdft_length >> 1;
     236             : 
     237    16792281 :     ivas_get_mdft_twid_factors( mdft_length, &pTwid );
     238             : 
     239    16792281 :     if ( mdft_length == input_length )
     240             :     {
     241  2928078793 :         for ( j = 0; j < mdft_length; j++ )
     242             :         {
     243  2915817120 :             re[j] = pIn[j] * pTwid[j];
     244  2915817120 :             im[j] = -pIn[j] * pTwid[mdft_length - j];
     245             :         }
     246             :     }
     247             :     else
     248             :     {
     249  1052263648 :         for ( j = 0; j < mdft_length; j++ )
     250             :         {
     251  1047733040 :             re[j] = pIn[j] * pTwid[j] - pIn[j + mdft_length] * pTwid[mdft_length - j];
     252  1047733040 :             im[j] = -pIn[j] * pTwid[mdft_length - j] - pIn[j + mdft_length] * pTwid[j];
     253             :         }
     254             :     }
     255             : 
     256    16792281 :     fft( re, im, mdft_length, 1 );
     257             : 
     258  1998567361 :     for ( j = 0; j < len_by_2; j++ )
     259             :     {
     260  1981775080 :         pOut_re[2 * j] = re[j];
     261  1981775080 :         pOut_re[2 * j + 1] = re[mdft_length - j - 1];
     262             : 
     263  1981775080 :         pOut_im[2 * j] = im[j];
     264  1981775080 :         pOut_im[2 * j + 1] = -im[mdft_length - j - 1];
     265             :     }
     266             : 
     267    16792281 :     return;
     268             : }
     269             : 
     270             : 
     271             : /*-----------------------------------------------------------------------------------------*
     272             :  * Function ivas_imdft()
     273             :  *
     274             :  * iMDFT implementation
     275             :  * out buffer needs to have 2*length worth memory
     276             :  *-----------------------------------------------------------------------------------------*/
     277             : 
     278     3071081 : void ivas_imdft(
     279             :     const float *pRe,    /* i  : Real part of MDFT signal    */
     280             :     const float *pIm,    /* i  : Imag. part of MDFT signal   */
     281             :     float *pOut,         /* o  : output time-domain signal   */
     282             :     const int16_t length /* i  : signal length               */
     283             : )
     284             : {
     285     3071081 :     float *re_tmp = pOut;
     286     3071081 :     float *im_tmp = pOut + length;
     287             :     float tmp;
     288             :     int16_t j;
     289     3071081 :     int16_t len_by_2 = length >> 1;
     290             :     const float *pTwid;
     291             : 
     292     3071081 :     ivas_get_imdft_twid_factors( length, &pTwid );
     293             : 
     294   519903321 :     for ( j = 0; j < len_by_2; j++ )
     295             :     {
     296   516832240 :         re_tmp[j] = pRe[2 * j];
     297   516832240 :         re_tmp[j + len_by_2] = pRe[length - 2 * j - 1];
     298             : 
     299   516832240 :         im_tmp[j] = pIm[2 * j];
     300   516832240 :         im_tmp[j + len_by_2] = -pIm[length - 2 * j - 1];
     301             :     }
     302             : 
     303     3071081 :     ivas_ifft_cplx1( re_tmp, im_tmp, length );
     304             : 
     305  1036735561 :     for ( j = 0; j < length; j++ )
     306             :     {
     307  1033664480 :         tmp = re_tmp[j] * pTwid[j] - im_tmp[j] * pTwid[length - j];
     308  1033664480 :         im_tmp[j] = -( re_tmp[j] * pTwid[length - j] + im_tmp[j] * pTwid[j] );
     309  1033664480 :         re_tmp[j] = tmp;
     310             :     }
     311             : 
     312     3071081 :     return;
     313             : }

Generated by: LCOV version 1.14