LCOV - code coverage report
Current view: top level - lib_com - basop_tcx_utils.c (source / functions) Hit Total Coverage
Test: Coverage on main -- conformance test test_26252.py @ 0c5691e6405a865cd50088c4936e8acb16f658a1 Lines: 211 228 92.5 %
Date: 2025-12-18 05:24:35 Functions: 4 4 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 <assert.h>
      38             : #include <stdint.h>
      39             : #include "options.h"
      40             : #ifdef DEBUGGING
      41             : #include "debug.h"
      42             : #endif
      43             : #include "cnst.h"
      44             : #include "basop_proto_func.h"
      45             : #include "stl.h"
      46             : #include "prot.h"
      47             : #include "rom_com.h"
      48             : 
      49             : #define WMC_TOOL_SKIP
      50             : 
      51             : /* compare two positive normalized 16 bit mantissa/exponent values */
      52             : /* return value: positive if first value greater, negative if second value greater, zero if equal */
      53      705364 : static Word16 compMantExp16Unorm( Word16 m1, Word16 e1, Word16 m2, Word16 e2 )
      54             : {
      55             :     Word16 tmp;
      56             : 
      57      705364 :     assert( ( m1 >= 0x4000 ) && ( m2 >= 0x4000 ) ); /* comparisons below work only for normalized mantissas */
      58             : 
      59      705364 :     tmp = sub( e1, e2 );
      60      705364 :     if ( tmp == 0 )
      61      441960 :         tmp = sub( m1, m2 );
      62             : 
      63      705364 :     return tmp;
      64             : }
      65             : 
      66       82984 : void basop_lpc2mdct( Word16 *lpcCoeffs, Word16 lpcOrder, Word16 *mdct_gains, Word16 *mdct_gains_exp, Word16 *mdct_inv_gains, Word16 *mdct_inv_gains_exp )
      67             : {
      68             :     Word32 RealData[FDNS_NPTS];
      69             :     Word32 ImagData[FDNS_NPTS];
      70             :     Word16 i, j, k, step, scale, s, tmp16;
      71             :     Word16 g, g_e, ig, ig_e;
      72             :     Word32 tmp32;
      73             :     const PWord16 *ptwiddle;
      74             : 
      75             : 
      76             :     /* short-cut, to avoid calling of BASOP_getTables() */
      77       82984 :     ptwiddle = SineTable512_fx;
      78       82984 :     step = 8;
      79             : 
      80             :     /*ODFT*/
      81       82984 :     assert( lpcOrder < FDNS_NPTS );
      82             : 
      83             :     /* pre-twiddle */
      84     1535204 :     FOR( i = 0; i <= lpcOrder; i++ )
      85             :     {
      86     1452220 :         RealData[i] = L_mult( lpcCoeffs[i], ptwiddle->v.re );
      87     1452220 :         move32();
      88     1452220 :         ImagData[i] = L_negate( L_mult( lpcCoeffs[i], ptwiddle->v.im ) );
      89     1452220 :         move32();
      90     1452220 :         ptwiddle += step;
      91             :     }
      92             : 
      93             :     /* zero padding */
      94     3941740 :     FOR( ; i < FDNS_NPTS; i++ )
      95             :     {
      96     3858756 :         RealData[i] = 0;
      97     3858756 :         move32();
      98     3858756 :         ImagData[i] = 0;
      99     3858756 :         move32();
     100             :     }
     101             : 
     102             :     /* half length FFT */
     103       82984 :     scale = add( norm_s( lpcCoeffs[0] ), 1 );
     104       82984 :     move16();
     105       82984 :     BASOP_cfft( RealData, ImagData, 1, &scale ); /* sizeOfFft == FDNS_NPTS == 8 */
     106             : 
     107             : 
     108             :     /*Get amplitude*/
     109       82984 :     j = FDNS_NPTS - 1;
     110       82984 :     k = 0;
     111       82984 :     move16();
     112             : 
     113     2738472 :     FOR( i = 0; i < FDNS_NPTS / 2; i++ )
     114             :     {
     115     2655488 :         s = sub( norm_l( L_max( L_abs( RealData[i] ), L_abs( ImagData[i] ) ) ), 1 );
     116             : 
     117     2655488 :         tmp16 = extract_h( L_shl( RealData[i], s ) );
     118     2655488 :         tmp32 = L_mult( tmp16, tmp16 );
     119             : 
     120     2655488 :         tmp16 = extract_h( L_shl( ImagData[i], s ) );
     121     2655488 :         tmp16 = mac_r( tmp32, tmp16, tmp16 );
     122             : 
     123     2655488 :         s = shl( sub( scale, s ), 1 );
     124             : 
     125     2655488 :         if ( tmp16 == 0 )
     126             :         {
     127           0 :             s = -16;
     128           0 :             move16();
     129             :         }
     130     2655488 :         if ( tmp16 == 0 )
     131             :         {
     132           0 :             tmp16 = 1;
     133           0 :             move16();
     134             :         }
     135             : 
     136     2655488 :         BASOP_Util_Sqrt_InvSqrt_MantExp( tmp16, s, &g, &g_e, &ig, &ig_e );
     137             : 
     138     2655488 :         if ( mdct_gains != NULL )
     139             :         {
     140     1327744 :             mdct_gains[k] = g;
     141     1327744 :             move16();
     142             :         }
     143             : 
     144     2655488 :         if ( mdct_gains_exp != NULL )
     145             :         {
     146     1327744 :             mdct_gains_exp[k] = g_e;
     147     1327744 :             move16();
     148             :         }
     149             : 
     150     2655488 :         if ( mdct_inv_gains != NULL )
     151             :         {
     152     1327744 :             mdct_inv_gains[k] = ig;
     153     1327744 :             move16();
     154             :         }
     155             : 
     156     2655488 :         if ( mdct_inv_gains_exp != NULL )
     157             :         {
     158     1327744 :             mdct_inv_gains_exp[k] = ig_e;
     159     1327744 :             move16();
     160             :         }
     161             : 
     162     2655488 :         k = add( k, 1 );
     163             : 
     164             : 
     165     2655488 :         s = sub( norm_l( L_max( L_abs( RealData[j] ), L_abs( ImagData[j] ) ) ), 1 );
     166             : 
     167     2655488 :         tmp16 = extract_h( L_shl( RealData[j], s ) );
     168     2655488 :         tmp32 = L_mult( tmp16, tmp16 );
     169             : 
     170     2655488 :         tmp16 = extract_h( L_shl( ImagData[j], s ) );
     171     2655488 :         tmp16 = mac_r( tmp32, tmp16, tmp16 );
     172             : 
     173     2655488 :         s = shl( sub( scale, s ), 1 );
     174             : 
     175     2655488 :         if ( tmp16 == 0 )
     176             :         {
     177           0 :             s = -16;
     178           0 :             move16();
     179             :         }
     180     2655488 :         if ( tmp16 == 0 )
     181             :         {
     182           0 :             tmp16 = 1;
     183           0 :             move16();
     184             :         }
     185             : 
     186     2655488 :         BASOP_Util_Sqrt_InvSqrt_MantExp( tmp16, s, &g, &g_e, &ig, &ig_e );
     187             : 
     188     2655488 :         if ( mdct_gains != NULL )
     189             :         {
     190     1327744 :             mdct_gains[k] = g;
     191     1327744 :             move16();
     192             :         }
     193             : 
     194     2655488 :         if ( mdct_gains_exp != NULL )
     195             :         {
     196     1327744 :             mdct_gains_exp[k] = g_e;
     197     1327744 :             move16();
     198             :         }
     199             : 
     200     2655488 :         if ( mdct_inv_gains != NULL )
     201             :         {
     202     1327744 :             mdct_inv_gains[k] = ig;
     203     1327744 :             move16();
     204             :         }
     205             : 
     206     2655488 :         if ( mdct_inv_gains_exp != NULL )
     207             :         {
     208     1327744 :             mdct_inv_gains_exp[k] = ig_e;
     209     1327744 :             move16();
     210             :         }
     211             : 
     212     2655488 :         j = sub( j, 1 );
     213     2655488 :         k = add( k, 1 );
     214             :     }
     215       82984 : }
     216             : 
     217             : 
     218       41492 : void basop_mdct_noiseShaping_interp( Word32 x[], Word16 lg, Word16 gains[], Word16 gains_exp[] )
     219             : {
     220             :     Word16 i, j, jp, jn, k, l;
     221             :     Word16 g, pg, ng, e, tmp;
     222             : 
     223             : 
     224       41492 :     assert( lg % FDNS_NPTS == 0 );
     225       41492 :     k = shr( lg, 6 ); /* FDNS_NPTS = 64 */
     226             : 
     227       41492 :     IF( gains != NULL )
     228             :     {
     229             :         /* Linear interpolation */
     230       41492 :         IF( sub( k, 4 ) == 0 )
     231             :         {
     232       37981 :             jp = 0;
     233       37981 :             move16();
     234       37981 :             j = 0;
     235       37981 :             move16();
     236       37981 :             jn = 1;
     237       37981 :             move16();
     238             : 
     239     2468765 :             FOR( i = 0; i < lg; i += 4 )
     240             :             {
     241     2430784 :                 pg = gains[jp];
     242     2430784 :                 move16();
     243     2430784 :                 g = gains[j];
     244     2430784 :                 move16();
     245     2430784 :                 ng = gains[jn];
     246     2430784 :                 move16();
     247             : 
     248             :                 /* common exponent for pg and g */
     249     2430784 :                 tmp = sub( gains_exp[j], gains_exp[jp] );
     250     2430784 :                 if ( tmp > 0 )
     251      259611 :                     pg = shr( pg, tmp );
     252     2430784 :                 if ( tmp < 0 )
     253      153381 :                     g = shl( g, tmp );
     254     2430784 :                 e = s_max( gains_exp[j], gains_exp[jp] );
     255             : 
     256     2430784 :                 tmp = mac_r( L_mult( pg, FL2WORD16( 0.375f ) ), g, FL2WORD16( 0.625f ) );
     257     2430784 :                 x[i] = L_shl( Mpy_32_16( x[i], tmp ), e );
     258     2430784 :                 move32();
     259             : 
     260     2430784 :                 tmp = mac_r( L_mult( pg, FL2WORD16( 0.125f ) ), g, FL2WORD16( 0.875f ) );
     261     2430784 :                 x[i + 1] = L_shl( Mpy_32_16( x[i + 1], tmp ), e );
     262     2430784 :                 move32();
     263             : 
     264             :                 /* common exponent for g and ng */
     265     2430784 :                 g = gains[j];
     266     2430784 :                 move16();
     267     2430784 :                 tmp = sub( gains_exp[j], gains_exp[jn] );
     268     2430784 :                 if ( tmp > 0 )
     269      153381 :                     ng = shr( ng, tmp );
     270     2430784 :                 if ( tmp < 0 )
     271      259611 :                     g = shl( g, tmp );
     272     2430784 :                 e = s_max( gains_exp[j], gains_exp[jn] );
     273             : 
     274     2430784 :                 tmp = mac_r( L_mult( g, FL2WORD16( 0.875f ) ), ng, FL2WORD16( 0.125f ) );
     275     2430784 :                 x[i + 2] = L_shl( Mpy_32_16( x[i + 2], tmp ), e );
     276     2430784 :                 move32();
     277             : 
     278     2430784 :                 tmp = mac_r( L_mult( g, FL2WORD16( 0.625f ) ), ng, FL2WORD16( 0.375f ) );
     279     2430784 :                 x[i + 3] = L_shl( Mpy_32_16( x[i + 3], tmp ), e );
     280     2430784 :                 move32();
     281             : 
     282     2430784 :                 jp = j;
     283     2430784 :                 move16();
     284     2430784 :                 j = jn;
     285     2430784 :                 move16();
     286     2430784 :                 jn = s_min( add( jn, 1 ), FDNS_NPTS - 1 );
     287             :             }
     288             :         }
     289        3511 :         ELSE IF( sub( k, 5 ) == 0 )
     290             :         {
     291        3511 :             jp = 0;
     292        3511 :             move16();
     293        3511 :             j = 0;
     294        3511 :             move16();
     295        3511 :             jn = 1;
     296        3511 :             move16();
     297             : 
     298      228215 :             FOR( i = 0; i < lg; i += 5 )
     299             :             {
     300      224704 :                 pg = gains[jp];
     301      224704 :                 move16();
     302      224704 :                 g = gains[j];
     303      224704 :                 move16();
     304      224704 :                 ng = gains[jn];
     305      224704 :                 move16();
     306             : 
     307             :                 /* common exponent for pg and g */
     308      224704 :                 tmp = sub( gains_exp[j], gains_exp[jp] );
     309      224704 :                 if ( tmp > 0 )
     310       23678 :                     pg = shr( pg, tmp );
     311      224704 :                 if ( tmp < 0 )
     312       13832 :                     g = shl( g, tmp );
     313      224704 :                 e = s_max( gains_exp[j], gains_exp[jp] );
     314             : 
     315      224704 :                 tmp = mac_r( L_mult( pg, FL2WORD16( 0.40f ) ), g, FL2WORD16( 0.60f ) );
     316      224704 :                 x[i] = L_shl( Mpy_32_16( x[i], tmp ), e );
     317      224704 :                 move32();
     318             : 
     319      224704 :                 tmp = mac_r( L_mult( pg, FL2WORD16( 0.20f ) ), g, FL2WORD16( 0.80f ) );
     320      224704 :                 x[i + 1] = L_shl( Mpy_32_16( x[i + 1], tmp ), e );
     321      224704 :                 move32();
     322             : 
     323             : 
     324      224704 :                 x[i + 2] = L_shl( Mpy_32_16( x[i + 2], gains[j] ), gains_exp[j] );
     325      224704 :                 move32();
     326             : 
     327             :                 /* common exponent for g and ng */
     328      224704 :                 g = gains[j];
     329      224704 :                 move16();
     330      224704 :                 tmp = sub( gains_exp[j], gains_exp[jn] );
     331      224704 :                 if ( tmp > 0 )
     332       13832 :                     ng = shr( ng, tmp );
     333      224704 :                 if ( tmp < 0 )
     334       23678 :                     g = shl( g, tmp );
     335      224704 :                 e = s_max( gains_exp[j], gains_exp[jn] );
     336             : 
     337      224704 :                 tmp = mac_r( L_mult( g, FL2WORD16( 0.80f ) ), ng, FL2WORD16( 0.20f ) );
     338      224704 :                 x[i + 3] = L_shl( Mpy_32_16( x[i + 3], tmp ), e );
     339      224704 :                 move32();
     340             : 
     341      224704 :                 tmp = mac_r( L_mult( g, FL2WORD16( 0.60f ) ), ng, FL2WORD16( 0.40f ) );
     342      224704 :                 x[i + 4] = L_shl( Mpy_32_16( x[i + 4], tmp ), e );
     343      224704 :                 move32();
     344             : 
     345      224704 :                 jp = j;
     346      224704 :                 move16();
     347      224704 :                 j = jn;
     348      224704 :                 move16();
     349      224704 :                 jn = s_min( add( jn, 1 ), FDNS_NPTS - 1 );
     350             :             }
     351             :         }
     352             :         ELSE /* no interpolation */
     353             :         {
     354           0 :             FOR( i = 0; i < FDNS_NPTS; i++ )
     355             :             {
     356           0 :                 FOR( l = 0; l < k; l++ )
     357             :                 {
     358           0 :                     *x = L_shl( Mpy_32_16( *x, *gains ), *gains_exp );
     359           0 :                     move32();
     360           0 :                     x++;
     361             :                 }
     362             : 
     363           0 :                 gains++;
     364           0 :                 gains_exp++;
     365             :             }
     366             :         }
     367             :     }
     368       41492 : }
     369             : 
     370             : 
     371       41492 : void basop_PsychAdaptLowFreqDeemph( Word32 x[], const Word16 lpcGains[], const Word16 lpcGains_e[], Word16 lf_deemph_factors[] )
     372             : {
     373             :     Word16 i;
     374             :     Word16 max_val, max_e, fac, min_val, min_e, tmp, tmp_e;
     375             :     Word32 L_tmp;
     376             : 
     377             : 
     378       41492 :     assert( lpcGains[0] >= 0x4000 );
     379             : 
     380       41492 :     max_val = lpcGains[0];
     381       41492 :     move16();
     382       41492 :     max_e = lpcGains_e[0];
     383       41492 :     move16();
     384       41492 :     min_val = lpcGains[0];
     385       41492 :     move16();
     386       41492 :     min_e = lpcGains_e[0];
     387       41492 :     move16();
     388             : 
     389             :     /* find minimum (min) and maximum (max) of LPC gains in low frequencies */
     390      373428 :     FOR( i = 1; i < 9; i++ )
     391             :     {
     392      331936 :         IF( compMantExp16Unorm( lpcGains[i], lpcGains_e[i], min_val, min_e ) < 0 )
     393             :         {
     394      221107 :             min_val = lpcGains[i];
     395      221107 :             move16();
     396      221107 :             min_e = lpcGains_e[i];
     397      221107 :             move16();
     398             :         }
     399             : 
     400      331936 :         IF( compMantExp16Unorm( lpcGains[i], lpcGains_e[i], max_val, max_e ) > 0 )
     401             :         {
     402       78072 :             max_val = lpcGains[i];
     403       78072 :             move16();
     404       78072 :             max_e = lpcGains_e[i];
     405       78072 :             move16();
     406             :         }
     407             :     }
     408             : 
     409       41492 :     min_e = add( min_e, 5 ); /* min *= 32.0f; */
     410             : 
     411       41492 :     test();
     412       41492 :     IF( ( compMantExp16Unorm( max_val, max_e, min_val, min_e ) < 0 ) && ( min_val > 0 ) )
     413             :     {
     414             :         /* fac = tmp = (float)pow(max / min, 0.0078125f); */
     415       41492 :         tmp_e = min_e;
     416       41492 :         move16();
     417       41492 :         tmp = Inv16( min_val, &tmp_e );
     418       41492 :         L_tmp = L_shl( L_mult( tmp, max_val ), add( tmp_e, max_e ) ); /* Q31 */
     419       41492 :         L_tmp = BASOP_Util_Log2( L_tmp );                             /* Q25 */
     420       41492 :         L_tmp = L_shr( L_tmp, 7 );                                    /* 0.0078125f = 1.f/(1<<7) */
     421       41492 :         L_tmp = BASOP_Util_InvLog2( L_tmp );                          /* Q31 */
     422       41492 :         tmp = round_fx( L_tmp );                                      /* Q15 */
     423       41492 :         fac = tmp;                                                    /* Q15 */
     424       41492 :         move16();
     425             : 
     426             :         /* gradual lowering of lowest 32 bins; DC is lowered by (max/tmp)^1/4 */
     427     1369236 :         FOR( i = 31; i >= 0; i-- )
     428             :         {
     429     1327744 :             x[i] = Mpy_32_16( x[i], fac );
     430     1327744 :             move32();
     431     1327744 :             if ( lf_deemph_factors != NULL )
     432             :             {
     433           0 :                 lf_deemph_factors[i] = mult_r( lf_deemph_factors[i], fac );
     434           0 :                 move16();
     435             :             }
     436     1327744 :             fac = mult_r( fac, tmp );
     437             :         }
     438             :     }
     439       41492 : }
     440             : 
     441             : #undef WMC_TOOL_SKIP

Generated by: LCOV version 1.14