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

Generated by: LCOV version 1.14