LCOV - code coverage report
Current view: top level - lib_com - ivas_mdct_imdct.c (source / functions) Hit Total Coverage
Test: Coverage on main -- short test vectors @ 6c9ddc4024a9c0e1ecb8f643f114a84a0e26ec6b Lines: 105 114 92.1 %
Date: 2025-05-23 08:37:30 Functions: 8 8 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             : #include "ivas_rom_com.h"
      38             : #ifdef DEBUGGING
      39             : #include "debug.h"
      40             : #endif
      41             : #include "ivas_stat_com.h"
      42             : #include "wmc_auto.h"
      43             : 
      44             : 
      45             : /*------------------------------------------------------------------------------------------*
      46             :  * Local constants
      47             :  *------------------------------------------------------------------------------------------*/
      48             : 
      49             : #define IVAS_MDCT_SCALING_GAIN_48k 1.9699011974118126e-06f
      50             : #define IVAS_MDCT_SCALING_GAIN_32k 2.9548517961177197e-06f
      51             : #define IVAS_MDCT_SCALING_GAIN_16k 5.909703592235439e-06f
      52             : 
      53             : #define IVAS_IMDCT_SCALING_GAIN 2115.165304808f
      54             : 
      55             : 
      56             : /*-----------------------------------------------------------------------------------------*
      57             :  * Function ivas_tda()
      58             :  *
      59             :  * Time domain aliasing
      60             :  *-----------------------------------------------------------------------------------------*/
      61             : 
      62        1320 : void ivas_tda(
      63             :     const float *pIn,    /* i  : time domain buffer of size 2*length */
      64             :     float *pOut,         /* o  : time domain buffer of size length   */
      65             :     const int16_t length /* i  : length of time alised signal buffer */
      66             : )
      67             : {
      68             :     int16_t i;
      69        1320 :     int16_t len_by_2 = length >> 1;
      70             : 
      71      316200 :     for ( i = 0; i < len_by_2; i++ )
      72             :     {
      73      314880 :         pOut[i] = -pIn[len_by_2 - i - 1] + pIn[len_by_2 + i];
      74      314880 :         pOut[len_by_2 + i] = pIn[length * 2 - i - 1] + pIn[length + i];
      75             :     }
      76             : 
      77        1320 :     return;
      78             : }
      79             : 
      80             : 
      81             : /*-----------------------------------------------------------------------------------------*
      82             :  * Function ivas_dct_windowing()
      83             :  *
      84             :  * Windowing block, input is passed through Fielder window
      85             :  *-----------------------------------------------------------------------------------------*/
      86             : 
      87       55160 : void ivas_dct_windowing(
      88             :     const int16_t fade_len,
      89             :     const int16_t full_len,
      90             :     const int16_t dct_len,
      91             :     const int16_t zero_pad_len,
      92             :     const float *pWindow_coeffs,
      93             :     const int16_t frame_len,
      94             :     float *pOut_buf,
      95             :     float *pBuffer_prev,
      96             :     float *pTemp_lfe )
      97             : {
      98             :     int16_t i;
      99       55160 :     int16_t rem_len = 0;
     100             : 
     101       55160 :     mvr2r( pBuffer_prev, pOut_buf + zero_pad_len, fade_len );
     102             : 
     103       55160 :     mvr2r( pTemp_lfe, ( pOut_buf + fade_len + zero_pad_len ), dct_len );
     104             : 
     105     2687736 :     for ( i = 0; i < zero_pad_len; i++ )
     106             :     {
     107     2632576 :         pOut_buf[i] = 0.0f;
     108             :     }
     109             : 
     110       55160 :     mvr2r( ( pOut_buf + full_len - fade_len ), pBuffer_prev, fade_len );
     111             : 
     112    21115768 :     for ( i = 0; i < fade_len; i++ )
     113             :     {
     114    21060608 :         pOut_buf[zero_pad_len + i] = pOut_buf[zero_pad_len + i] * pWindow_coeffs[i];
     115             :     }
     116             : 
     117       55160 :     rem_len = full_len - ( zero_pad_len * 3 + fade_len );
     118             : 
     119    21115768 :     for ( i = 0; i < rem_len; i++ )
     120             :     {
     121    21060608 :         pOut_buf[zero_pad_len * 3 + fade_len + i] = pOut_buf[zero_pad_len * 3 + fade_len + i] * pWindow_coeffs[fade_len - i - 1];
     122             :     }
     123             : 
     124     2687736 :     for ( i = 0; i < frame_len - full_len; i++ )
     125             :     {
     126     2632576 :         pOut_buf[full_len + i] = 0.0f;
     127             :     }
     128             : 
     129       55160 :     return;
     130             : }
     131             : 
     132             : 
     133             : /*-----------------------------------------------------------------------------------------*
     134             :  * Function ivas_mdct()
     135             :  *
     136             :  * MDCT implementation
     137             :  *-----------------------------------------------------------------------------------------*/
     138             : 
     139       53840 : void ivas_mdct(
     140             :     const float *pIn,
     141             :     float *pOut,
     142             :     const int16_t length )
     143             : {
     144             :     const float *pTwid_re, *pTwid_im;
     145             :     int16_t i, len_by_2;
     146             :     float re[IVAS_480_PT_LEN], im[IVAS_480_PT_LEN];
     147             :     float ivas_mdct_scaling_gain;
     148             : 
     149       53840 :     len_by_2 = length >> 1;
     150       53840 :     ivas_mdct_scaling_gain = ivas_get_mdct_scaling_gain( len_by_2 );
     151             : 
     152       53840 :     ivas_get_twid_factors( length, &pTwid_re, &pTwid_im );
     153             : 
     154    12901840 :     for ( i = 0; i < len_by_2; i++ )
     155             :     {
     156    12848000 :         pOut[i] = -pIn[len_by_2 - i - 1] + pIn[len_by_2 + i];
     157    12848000 :         pOut[len_by_2 + i] = pIn[length * 2 - i - 1] + pIn[length + i];
     158             :     }
     159             : 
     160    12901840 :     for ( i = 0; i < len_by_2; i++ )
     161             :     {
     162    12848000 :         re[i] = -( pOut[2 * i] * pTwid_re[i] + pOut[length - 1 - 2 * i] * pTwid_im[i] );
     163    12848000 :         im[i] = pOut[length - 1 - 2 * i] * pTwid_re[i] - pOut[2 * i] * pTwid_im[i];
     164             :     }
     165             : 
     166       53840 :     DoFFT( &re[0], &im[0], len_by_2 );
     167             : 
     168    12901840 :     for ( i = 0; i < len_by_2; i++ )
     169             :     {
     170    12848000 :         re[i] = re[i] * ivas_mdct_scaling_gain;
     171    12848000 :         im[i] = im[i] * ivas_mdct_scaling_gain;
     172             :     }
     173             : 
     174    12901840 :     for ( i = 0; i < len_by_2; i++ )
     175             :     {
     176             :         float tmp;
     177    12848000 :         tmp = re[i] * pTwid_re[i] - im[i] * pTwid_im[i];
     178    12848000 :         im[i] = im[i] * pTwid_re[i] + re[i] * pTwid_im[i];
     179    12848000 :         re[i] = tmp;
     180             :     }
     181             : 
     182    12901840 :     for ( i = 0; i < len_by_2; i++ )
     183             :     {
     184    12848000 :         pOut[length - 2 * i - 1] = re[i];
     185    12848000 :         pOut[2 * i] = im[i];
     186             :     }
     187             : 
     188       53840 :     return;
     189             : }
     190             : 
     191             : 
     192             : /*-----------------------------------------------------------------------------------------*
     193             :  * Function ivas_ifft_cplx()
     194             :  *
     195             :  * Complex IFFT implementation using DoFFT
     196             :  *-----------------------------------------------------------------------------------------*/
     197             : 
     198      160236 : static void ivas_ifft_cplx(
     199             :     float *re,
     200             :     float *im,
     201             :     const int16_t length )
     202             : {
     203             :     int16_t i;
     204      160236 :     float ivas_imdct_one_by_powergain = IVAS_IMDCT_SCALING_GAIN;
     205             :     /*re-arrange inputs to use fft as ifft */
     206      160236 :     re[0] = re[0] * ivas_imdct_one_by_powergain;
     207      160236 :     im[0] = im[0] * ivas_imdct_one_by_powergain;
     208             : 
     209    18411996 :     for ( i = 1; i <= length >> 1; i++ )
     210             :     {
     211    18251760 :         float tmp = re[length - i] * ivas_imdct_one_by_powergain;
     212    18251760 :         re[length - i] = re[i] * ivas_imdct_one_by_powergain;
     213    18251760 :         re[i] = tmp;
     214             : 
     215    18251760 :         tmp = im[length - i] * ivas_imdct_one_by_powergain;
     216    18251760 :         im[length - i] = im[i] * ivas_imdct_one_by_powergain;
     217    18251760 :         im[i] = tmp;
     218             :     }
     219             : 
     220      160236 :     DoFFT( re, im, (int16_t) length );
     221             : 
     222      160236 :     return;
     223             : }
     224             : 
     225             : 
     226             : /*-----------------------------------------------------------------------------------------*
     227             :  * Function ivas_itda()
     228             :  *
     229             :  * Inverse time domain alias implementation
     230             :  *-----------------------------------------------------------------------------------------*/
     231             : 
     232        1320 : void ivas_itda(
     233             :     const float *re,     /* i  : time alised signal after IDCT       */
     234             :     float *pOut,         /* o  : time domain buffer of size 2*length */
     235             :     const int16_t length /* i  : length of time alised signal buffer */
     236             : )
     237             : {
     238             :     int16_t i;
     239        1320 :     int16_t len_by_2 = length >> 1;
     240             : 
     241      316200 :     for ( i = 0; i < len_by_2; i++ )
     242             :     {
     243      314880 :         pOut[i] = -re[len_by_2 - i - 1];
     244      314880 :         pOut[len_by_2 + i] = re[i];
     245      314880 :         pOut[length + i] = re[len_by_2 + i];
     246      314880 :         pOut[3 * len_by_2 + i] = re[length - i - 1];
     247             :     }
     248             : 
     249        1320 :     return;
     250             : }
     251             : 
     252             : 
     253             : /*-----------------------------------------------------------------------------------------*
     254             :  * Function ivas_imdct()
     255             :  *
     256             :  * IMDCT implementation
     257             :  *-----------------------------------------------------------------------------------------*/
     258             : 
     259      160236 : void ivas_imdct(
     260             :     const float *pIn,
     261             :     float *pOut,
     262             :     const int16_t length )
     263             : {
     264             :     const float *pTwid_re, *pTwid_im;
     265      160236 :     int16_t len_by_2 = length >> 1;
     266             :     int16_t i;
     267             :     float re[IVAS_480_PT_LEN];
     268             :     float im[IVAS_480_PT_LEN];
     269             : 
     270      160236 :     ivas_get_twid_factors( length, &pTwid_re, &pTwid_im );
     271             : 
     272    36663756 :     for ( i = 0; i < len_by_2; i++ )
     273             :     {
     274    36503520 :         re[i] = pIn[length - 2 * i - 1] * pTwid_re[i] + pIn[2 * i] * pTwid_im[i];  /*stl_arr_index*/
     275    36503520 :         im[i] = -pIn[length - 2 * i - 1] * pTwid_im[i] + pIn[2 * i] * pTwid_re[i]; /*stl_arr_index*/
     276             :     }
     277             : 
     278      160236 :     ivas_ifft_cplx( &re[0], &im[0], len_by_2 );
     279             : 
     280    36663756 :     for ( i = 0; i < len_by_2; i++ )
     281             :     {
     282             :         float tmp;
     283    36503520 :         tmp = re[i] * pTwid_re[i] + im[i] * pTwid_im[i];
     284    36503520 :         im[i] = -re[i] * pTwid_im[i] + im[i] * pTwid_re[i];
     285    36503520 :         re[i] = tmp;
     286             :     }
     287             : 
     288    36663756 :     for ( i = ( len_by_2 - 1 ); i >= 0; i-- )
     289             :     {
     290    36503520 :         re[2 * i + 1] = im[( len_by_2 - 1 ) - i];
     291    36503520 :         re[2 * i] = -re[i];
     292             :     }
     293             : 
     294    36663756 :     for ( i = 0; i < len_by_2; i++ )
     295             :     {
     296    36503520 :         pOut[i] = -re[len_by_2 - i - 1];
     297    36503520 :         pOut[len_by_2 + i] = re[i];
     298    36503520 :         pOut[length + i] = re[len_by_2 + i];
     299    36503520 :         pOut[3 * len_by_2 + i] = re[length - i - 1];
     300             :     }
     301             : 
     302      160236 :     return;
     303             : }
     304             : 
     305             : 
     306             : /*-----------------------------------------------------------------------------------------*
     307             :  * Function ivas_get_twid_factors()
     308             :  *
     309             :  * Sets/Maps the fft twiddle tables based on fft length
     310             :  *-----------------------------------------------------------------------------------------*/
     311             : 
     312      214076 : void ivas_get_twid_factors(
     313             :     const int16_t length,
     314             :     const float **pTwid_re,
     315             :     const float **pTwid_im )
     316             : {
     317      214076 :     if ( length == 480 )
     318             :     {
     319      200022 :         *pTwid_re = &ivas_cos_twiddle_480[0];
     320      200022 :         *pTwid_im = &ivas_sin_twiddle_480[0];
     321             :     }
     322       14054 :     else if ( length == 320 )
     323             :     {
     324        2774 :         *pTwid_re = &ivas_cos_twiddle_320[0];
     325        2774 :         *pTwid_im = &ivas_sin_twiddle_320[0];
     326             :     }
     327       11280 :     else if ( length == 160 )
     328             :     {
     329       11280 :         *pTwid_re = &ivas_cos_twiddle_160[0];
     330       11280 :         *pTwid_im = &ivas_sin_twiddle_160[0];
     331             :     }
     332           0 :     else if ( length == 80 )
     333             :     {
     334           0 :         *pTwid_re = &ivas_cos_twiddle_80[0];
     335           0 :         *pTwid_im = &ivas_sin_twiddle_80[0];
     336             :     }
     337             :     else
     338             :     {
     339           0 :         assert( !"Not supported FFT length!" );
     340             :     }
     341             : 
     342      214076 :     return;
     343             : }
     344             : 
     345             : 
     346             : /*-----------------------------------------------------------------------------------------*
     347             :  * Function ivas_get_mdct_scaling_gain()
     348             :  *
     349             :  * Get scaling gain for MDCT functions
     350             :  *-----------------------------------------------------------------------------------------*/
     351             : 
     352       53840 : float ivas_get_mdct_scaling_gain(
     353             :     const int16_t dct_len_by_2 )
     354             : {
     355       53840 :     float gain = 0.0f;
     356             : 
     357       53840 :     switch ( dct_len_by_2 )
     358             :     {
     359       52920 :         case L_FRAME48k >> 2:
     360             :         {
     361       52920 :             gain = IVAS_MDCT_SCALING_GAIN_48k;
     362       52920 :             break;
     363             :         }
     364         920 :         case L_FRAME32k >> 2:
     365             :         {
     366         920 :             gain = IVAS_MDCT_SCALING_GAIN_32k;
     367         920 :             break;
     368             :         }
     369           0 :         case L_FRAME16k >> 2:
     370             :         {
     371           0 :             gain = IVAS_MDCT_SCALING_GAIN_16k;
     372           0 :             break;
     373             :         }
     374           0 :         default:
     375             :         {
     376           0 :             assert( !"Unsupported frame length!" );
     377             :             break;
     378             :         }
     379             :     }
     380             : 
     381       53840 :     return gain;
     382             : }

Generated by: LCOV version 1.14