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 @ a21f94bc6bac334fe001a5bad2f7b32b79038097 Lines: 211 228 92.5 %
Date: 2025-11-01 05:07:43 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      477139 : static Word16 compMantExp16Unorm( Word16 m1, Word16 e1, Word16 m2, Word16 e2 )
      54             : {
      55             :     Word16 tmp;
      56             : 
      57      477139 :     assert( ( m1 >= 0x4000 ) && ( m2 >= 0x4000 ) ); /* comparisons below work only for normalized mantissas */
      58             : 
      59      477139 :     tmp = sub( e1, e2 );
      60      477139 :     if ( tmp == 0 )
      61      288120 :         tmp = sub( m1, m2 );
      62             : 
      63      477139 :     return tmp;
      64             : }
      65             : 
      66       56134 : 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       56134 :     ptwiddle = SineTable512_fx;
      78       56134 :     step = 8;
      79             : 
      80             :     /*ODFT*/
      81       56134 :     assert( lpcOrder < FDNS_NPTS );
      82             : 
      83             :     /* pre-twiddle */
      84     1038479 :     FOR( i = 0; i <= lpcOrder; i++ )
      85             :     {
      86      982345 :         RealData[i] = L_mult( lpcCoeffs[i], ptwiddle->v.re );
      87      982345 :         move32();
      88      982345 :         ImagData[i] = L_negate( L_mult( lpcCoeffs[i], ptwiddle->v.im ) );
      89      982345 :         move32();
      90      982345 :         ptwiddle += step;
      91             :     }
      92             : 
      93             :     /* zero padding */
      94     2666365 :     FOR( ; i < FDNS_NPTS; i++ )
      95             :     {
      96     2610231 :         RealData[i] = 0;
      97     2610231 :         move32();
      98     2610231 :         ImagData[i] = 0;
      99     2610231 :         move32();
     100             :     }
     101             : 
     102             :     /* half length FFT */
     103       56134 :     scale = add( norm_s( lpcCoeffs[0] ), 1 );
     104       56134 :     move16();
     105       56134 :     BASOP_cfft( RealData, ImagData, 1, &scale ); /* sizeOfFft == FDNS_NPTS == 8 */
     106             : 
     107             : 
     108             :     /*Get amplitude*/
     109       56134 :     j = FDNS_NPTS - 1;
     110       56134 :     k = 0;
     111       56134 :     move16();
     112             : 
     113     1852422 :     FOR( i = 0; i < FDNS_NPTS / 2; i++ )
     114             :     {
     115     1796288 :         s = sub( norm_l( L_max( L_abs( RealData[i] ), L_abs( ImagData[i] ) ) ), 1 );
     116             : 
     117     1796288 :         tmp16 = extract_h( L_shl( RealData[i], s ) );
     118     1796288 :         tmp32 = L_mult( tmp16, tmp16 );
     119             : 
     120     1796288 :         tmp16 = extract_h( L_shl( ImagData[i], s ) );
     121     1796288 :         tmp16 = mac_r( tmp32, tmp16, tmp16 );
     122             : 
     123     1796288 :         s = shl( sub( scale, s ), 1 );
     124             : 
     125     1796288 :         if ( tmp16 == 0 )
     126             :         {
     127           0 :             s = -16;
     128           0 :             move16();
     129             :         }
     130     1796288 :         if ( tmp16 == 0 )
     131             :         {
     132           0 :             tmp16 = 1;
     133           0 :             move16();
     134             :         }
     135             : 
     136     1796288 :         BASOP_Util_Sqrt_InvSqrt_MantExp( tmp16, s, &g, &g_e, &ig, &ig_e );
     137             : 
     138     1796288 :         if ( mdct_gains != NULL )
     139             :         {
     140      898144 :             mdct_gains[k] = g;
     141      898144 :             move16();
     142             :         }
     143             : 
     144     1796288 :         if ( mdct_gains_exp != NULL )
     145             :         {
     146      898144 :             mdct_gains_exp[k] = g_e;
     147      898144 :             move16();
     148             :         }
     149             : 
     150     1796288 :         if ( mdct_inv_gains != NULL )
     151             :         {
     152      898144 :             mdct_inv_gains[k] = ig;
     153      898144 :             move16();
     154             :         }
     155             : 
     156     1796288 :         if ( mdct_inv_gains_exp != NULL )
     157             :         {
     158      898144 :             mdct_inv_gains_exp[k] = ig_e;
     159      898144 :             move16();
     160             :         }
     161             : 
     162     1796288 :         k = add( k, 1 );
     163             : 
     164             : 
     165     1796288 :         s = sub( norm_l( L_max( L_abs( RealData[j] ), L_abs( ImagData[j] ) ) ), 1 );
     166             : 
     167     1796288 :         tmp16 = extract_h( L_shl( RealData[j], s ) );
     168     1796288 :         tmp32 = L_mult( tmp16, tmp16 );
     169             : 
     170     1796288 :         tmp16 = extract_h( L_shl( ImagData[j], s ) );
     171     1796288 :         tmp16 = mac_r( tmp32, tmp16, tmp16 );
     172             : 
     173     1796288 :         s = shl( sub( scale, s ), 1 );
     174             : 
     175     1796288 :         if ( tmp16 == 0 )
     176             :         {
     177           0 :             s = -16;
     178           0 :             move16();
     179             :         }
     180     1796288 :         if ( tmp16 == 0 )
     181             :         {
     182           0 :             tmp16 = 1;
     183           0 :             move16();
     184             :         }
     185             : 
     186     1796288 :         BASOP_Util_Sqrt_InvSqrt_MantExp( tmp16, s, &g, &g_e, &ig, &ig_e );
     187             : 
     188     1796288 :         if ( mdct_gains != NULL )
     189             :         {
     190      898144 :             mdct_gains[k] = g;
     191      898144 :             move16();
     192             :         }
     193             : 
     194     1796288 :         if ( mdct_gains_exp != NULL )
     195             :         {
     196      898144 :             mdct_gains_exp[k] = g_e;
     197      898144 :             move16();
     198             :         }
     199             : 
     200     1796288 :         if ( mdct_inv_gains != NULL )
     201             :         {
     202      898144 :             mdct_inv_gains[k] = ig;
     203      898144 :             move16();
     204             :         }
     205             : 
     206     1796288 :         if ( mdct_inv_gains_exp != NULL )
     207             :         {
     208      898144 :             mdct_inv_gains_exp[k] = ig_e;
     209      898144 :             move16();
     210             :         }
     211             : 
     212     1796288 :         j = sub( j, 1 );
     213     1796288 :         k = add( k, 1 );
     214             :     }
     215       56134 : }
     216             : 
     217             : 
     218       28067 : 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       28067 :     assert( lg % FDNS_NPTS == 0 );
     225       28067 :     k = shr( lg, 6 ); /* FDNS_NPTS = 64 */
     226             : 
     227       28067 :     IF( gains != NULL )
     228             :     {
     229             :         /* Linear interpolation */
     230       28067 :         IF( sub( k, 4 ) == 0 )
     231             :         {
     232       25227 :             jp = 0;
     233       25227 :             move16();
     234       25227 :             j = 0;
     235       25227 :             move16();
     236       25227 :             jn = 1;
     237       25227 :             move16();
     238             : 
     239     1639755 :             FOR( i = 0; i < lg; i += 4 )
     240             :             {
     241     1614528 :                 pg = gains[jp];
     242     1614528 :                 move16();
     243     1614528 :                 g = gains[j];
     244     1614528 :                 move16();
     245     1614528 :                 ng = gains[jn];
     246     1614528 :                 move16();
     247             : 
     248             :                 /* common exponent for pg and g */
     249     1614528 :                 tmp = sub( gains_exp[j], gains_exp[jp] );
     250     1614528 :                 if ( tmp > 0 )
     251      177826 :                     pg = shr( pg, tmp );
     252     1614528 :                 if ( tmp < 0 )
     253      106921 :                     g = shl( g, tmp );
     254     1614528 :                 e = s_max( gains_exp[j], gains_exp[jp] );
     255             : 
     256     1614528 :                 tmp = mac_r( L_mult( pg, FL2WORD16( 0.375f ) ), g, FL2WORD16( 0.625f ) );
     257     1614528 :                 x[i] = L_shl( Mpy_32_16( x[i], tmp ), e );
     258     1614528 :                 move32();
     259             : 
     260     1614528 :                 tmp = mac_r( L_mult( pg, FL2WORD16( 0.125f ) ), g, FL2WORD16( 0.875f ) );
     261     1614528 :                 x[i + 1] = L_shl( Mpy_32_16( x[i + 1], tmp ), e );
     262     1614528 :                 move32();
     263             : 
     264             :                 /* common exponent for g and ng */
     265     1614528 :                 g = gains[j];
     266     1614528 :                 move16();
     267     1614528 :                 tmp = sub( gains_exp[j], gains_exp[jn] );
     268     1614528 :                 if ( tmp > 0 )
     269      106921 :                     ng = shr( ng, tmp );
     270     1614528 :                 if ( tmp < 0 )
     271      177826 :                     g = shl( g, tmp );
     272     1614528 :                 e = s_max( gains_exp[j], gains_exp[jn] );
     273             : 
     274     1614528 :                 tmp = mac_r( L_mult( g, FL2WORD16( 0.875f ) ), ng, FL2WORD16( 0.125f ) );
     275     1614528 :                 x[i + 2] = L_shl( Mpy_32_16( x[i + 2], tmp ), e );
     276     1614528 :                 move32();
     277             : 
     278     1614528 :                 tmp = mac_r( L_mult( g, FL2WORD16( 0.625f ) ), ng, FL2WORD16( 0.375f ) );
     279     1614528 :                 x[i + 3] = L_shl( Mpy_32_16( x[i + 3], tmp ), e );
     280     1614528 :                 move32();
     281             : 
     282     1614528 :                 jp = j;
     283     1614528 :                 move16();
     284     1614528 :                 j = jn;
     285     1614528 :                 move16();
     286     1614528 :                 jn = s_min( add( jn, 1 ), FDNS_NPTS - 1 );
     287             :             }
     288             :         }
     289        2840 :         ELSE IF( sub( k, 5 ) == 0 )
     290             :         {
     291        2840 :             jp = 0;
     292        2840 :             move16();
     293        2840 :             j = 0;
     294        2840 :             move16();
     295        2840 :             jn = 1;
     296        2840 :             move16();
     297             : 
     298      184600 :             FOR( i = 0; i < lg; i += 5 )
     299             :             {
     300      181760 :                 pg = gains[jp];
     301      181760 :                 move16();
     302      181760 :                 g = gains[j];
     303      181760 :                 move16();
     304      181760 :                 ng = gains[jn];
     305      181760 :                 move16();
     306             : 
     307             :                 /* common exponent for pg and g */
     308      181760 :                 tmp = sub( gains_exp[j], gains_exp[jp] );
     309      181760 :                 if ( tmp > 0 )
     310       19355 :                     pg = shr( pg, tmp );
     311      181760 :                 if ( tmp < 0 )
     312       11382 :                     g = shl( g, tmp );
     313      181760 :                 e = s_max( gains_exp[j], gains_exp[jp] );
     314             : 
     315      181760 :                 tmp = mac_r( L_mult( pg, FL2WORD16( 0.40f ) ), g, FL2WORD16( 0.60f ) );
     316      181760 :                 x[i] = L_shl( Mpy_32_16( x[i], tmp ), e );
     317      181760 :                 move32();
     318             : 
     319      181760 :                 tmp = mac_r( L_mult( pg, FL2WORD16( 0.20f ) ), g, FL2WORD16( 0.80f ) );
     320      181760 :                 x[i + 1] = L_shl( Mpy_32_16( x[i + 1], tmp ), e );
     321      181760 :                 move32();
     322             : 
     323             : 
     324      181760 :                 x[i + 2] = L_shl( Mpy_32_16( x[i + 2], gains[j] ), gains_exp[j] );
     325      181760 :                 move32();
     326             : 
     327             :                 /* common exponent for g and ng */
     328      181760 :                 g = gains[j];
     329      181760 :                 move16();
     330      181760 :                 tmp = sub( gains_exp[j], gains_exp[jn] );
     331      181760 :                 if ( tmp > 0 )
     332       11382 :                     ng = shr( ng, tmp );
     333      181760 :                 if ( tmp < 0 )
     334       19355 :                     g = shl( g, tmp );
     335      181760 :                 e = s_max( gains_exp[j], gains_exp[jn] );
     336             : 
     337      181760 :                 tmp = mac_r( L_mult( g, FL2WORD16( 0.80f ) ), ng, FL2WORD16( 0.20f ) );
     338      181760 :                 x[i + 3] = L_shl( Mpy_32_16( x[i + 3], tmp ), e );
     339      181760 :                 move32();
     340             : 
     341      181760 :                 tmp = mac_r( L_mult( g, FL2WORD16( 0.60f ) ), ng, FL2WORD16( 0.40f ) );
     342      181760 :                 x[i + 4] = L_shl( Mpy_32_16( x[i + 4], tmp ), e );
     343      181760 :                 move32();
     344             : 
     345      181760 :                 jp = j;
     346      181760 :                 move16();
     347      181760 :                 j = jn;
     348      181760 :                 move16();
     349      181760 :                 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       28067 : }
     369             : 
     370             : 
     371       28067 : 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       28067 :     assert( lpcGains[0] >= 0x4000 );
     379             : 
     380       28067 :     max_val = lpcGains[0];
     381       28067 :     move16();
     382       28067 :     max_e = lpcGains_e[0];
     383       28067 :     move16();
     384       28067 :     min_val = lpcGains[0];
     385       28067 :     move16();
     386       28067 :     min_e = lpcGains_e[0];
     387       28067 :     move16();
     388             : 
     389             :     /* find minimum (min) and maximum (max) of LPC gains in low frequencies */
     390      252603 :     FOR( i = 1; i < 9; i++ )
     391             :     {
     392      224536 :         IF( compMantExp16Unorm( lpcGains[i], lpcGains_e[i], min_val, min_e ) < 0 )
     393             :         {
     394      155847 :             min_val = lpcGains[i];
     395      155847 :             move16();
     396      155847 :             min_e = lpcGains_e[i];
     397      155847 :             move16();
     398             :         }
     399             : 
     400      224536 :         IF( compMantExp16Unorm( lpcGains[i], lpcGains_e[i], max_val, max_e ) > 0 )
     401             :         {
     402       48321 :             max_val = lpcGains[i];
     403       48321 :             move16();
     404       48321 :             max_e = lpcGains_e[i];
     405       48321 :             move16();
     406             :         }
     407             :     }
     408             : 
     409       28067 :     min_e = add( min_e, 5 ); /* min *= 32.0f; */
     410             : 
     411       28067 :     test();
     412       28067 :     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       28067 :         tmp_e = min_e;
     416       28067 :         move16();
     417       28067 :         tmp = Inv16( min_val, &tmp_e );
     418       28067 :         L_tmp = L_shl( L_mult( tmp, max_val ), add( tmp_e, max_e ) ); /* Q31 */
     419       28067 :         L_tmp = BASOP_Util_Log2( L_tmp );                             /* Q25 */
     420       28067 :         L_tmp = L_shr( L_tmp, 7 );                                    /* 0.0078125f = 1.f/(1<<7) */
     421       28067 :         L_tmp = BASOP_Util_InvLog2( L_tmp );                          /* Q31 */
     422       28067 :         tmp = round_fx( L_tmp );                                      /* Q15 */
     423       28067 :         fac = tmp;                                                    /* Q15 */
     424       28067 :         move16();
     425             : 
     426             :         /* gradual lowering of lowest 32 bins; DC is lowered by (max/tmp)^1/4 */
     427      926211 :         FOR( i = 31; i >= 0; i-- )
     428             :         {
     429      898144 :             x[i] = Mpy_32_16( x[i], fac );
     430      898144 :             move32();
     431      898144 :             if ( lf_deemph_factors != NULL )
     432             :             {
     433           0 :                 lf_deemph_factors[i] = mult_r( lf_deemph_factors[i], fac );
     434           0 :                 move16();
     435             :             }
     436      898144 :             fac = mult_r( fac, tmp );
     437             :         }
     438             :     }
     439       28067 : }
     440             : 
     441             : #undef WMC_TOOL_SKIP

Generated by: LCOV version 1.14