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

Generated by: LCOV version 1.14