LCOV - code coverage report
Current view: top level - lib_com - arith_coder_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main -- dec/rend @ 633e3f2e309758d10805ef21e0436356fe719b7a Lines: 159 253 62.8 %
Date: 2025-08-23 01:22:27 Functions: 3 6 50.0 %

          Line data    Source code
       1             : /*====================================================================================
       2             :     EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0
       3             :   ====================================================================================*/
       4             : 
       5             : #include <stdint.h>
       6             : #include <assert.h>
       7             : #include "options.h"
       8             : #include "prot_fx.h"
       9             : #include "basop_util.h"
      10             : #include "basop_proto_func.h"
      11             : #include "cnst.h"
      12             : 
      13             : /* Fixed point implementation of exp(negate()) */
      14           0 : Word32 expfp(                    /* o: Q31 */
      15             :               const Word16 x,    /* i: mantissa  Q-e */
      16             :               const Word16 x_e ) /* i: exponent  Q0  */
      17             : {
      18             :     Word16 xi, xf, tmp;
      19             :     Word16 b0, b1, b2, b3;
      20             :     Word32 y, L_tmp;
      21             : 
      22             : 
      23           0 :     assert( x > 0 );
      24             : 
      25           0 :     L_tmp = L_shl( L_deposit_h( x ), x_e ); /* Q31 */
      26             : 
      27             :     /* split into integer and fractional parts */
      28           0 :     xi = round_fx( L_tmp );  /* Q15 */
      29           0 :     xf = extract_l( L_tmp ); /* Q31 */
      30             : 
      31             :     BASOP_SATURATE_WARNING_OFF_EVS;
      32           0 :     xf = negate( xf );
      33             :     BASOP_SATURATE_WARNING_ON_EVS;
      34             : 
      35             :     /* Fractional part */
      36             :     /* y = 65536
      37             :             +         xf
      38             :             +       ((xf*xf) / (2*65536))
      39             :             +   ((((((xf*xf) / (2*65536))*xf) / 65536)*65536/3) / 65536)
      40             :             + ((((((((xf*xf) / (2*65536))*xf) / 65536)*65536/3) / 65536)*xf) / (4*65536)); */
      41           0 :     y = L_mac0( 65536, xf, 1 ); /* Q16 */
      42           0 :     tmp = shr( mult( xf, xf ), 2 );
      43           0 :     y = L_mac0( y, tmp, 1 ); /* Q16 */
      44           0 :     tmp = shr( mult( shr( mult( tmp, xf ), 1 ), 65536 / 3 ), 1 );
      45           0 :     y = L_mac0( y, tmp, 1 ); /* Q16 */
      46           0 :     tmp = shr( mult( tmp, xf ), 3 );
      47           0 :     y = L_mac0( y, tmp, 1 ); /* Q16 */
      48             : 
      49             :     /* Integer part */
      50           0 :     b0 = s_and( xi, 1 );
      51           0 :     b1 = s_and( xi, 2 );
      52           0 :     b2 = s_and( xi, 4 );
      53           0 :     b3 = s_and( xi, 8 );
      54             : 
      55           0 :     IF( b0 != 0 )
      56             :     {
      57           0 :         y = Mpy_32_16_1( y, 24109 ); /* exp(-1) in -1Q16 */
      58             :     }
      59           0 :     IF( b1 != 0 )
      60             :     {
      61           0 :         y = Mpy_32_16_1( y, 17739 ); /* exp(-2) in -2Q17 */
      62             :     }
      63           0 :     IF( b2 != 0 )
      64             :     {
      65           0 :         y = Mpy_32_16_1( y, 19205 ); /* exp(-4) in -5Q20 */
      66             :     }
      67           0 :     IF( b3 != 0 )
      68             :     {
      69           0 :         y = Mpy_32_16_1( y, 22513 ); /* exp(-8) in -11Q26 */
      70             :     }
      71             : 
      72             :     /* scaling: -1*b0 - 2*b1 -5*b2 -11*b3 */
      73           0 :     y = L_shr( y, add( add( xi, shr( xi, 2 ) ), shr( b3, 3 ) ) );
      74             : 
      75             :     /* zero for xi >= 16 */
      76           0 :     if ( shr( xi, 4 ) > 0 )
      77             :     {
      78           0 :         y = L_deposit_l( 0 );
      79             :     }
      80             : 
      81             : 
      82           0 :     return L_shl( y, 15 );
      83             : }
      84             : 
      85             : /* Fixed point implementation of pow(), where base is fixed point (16/16) and exponent a small *odd* integer
      86             :  *
      87             :  * Returns: *pout1 = ( (base/65536)^(2*exp - 1) ) * 65536
      88             :  *          *pout2 = ( (base/65536)^(2*exp + 1) ) * 65536
      89             :  *
      90             :  * NOTE: This function must be in sync with ari_decode_14bits_pow_fx() */
      91           0 : void powfp_odd2(
      92             :     const Word16 base, /* Q15 */
      93             :     const Word16 exp,  /* Q0  */
      94             :     Word16 *pout1,     /* Q15 */
      95             :     Word16 *pout2      /* Q15 */
      96             : )
      97             : {
      98             :     /* this version is in sync with ari_enc_14bits_pow()
      99             :      * that is, we have to start multiplication from the largest power-of-two, in order to
     100             :      * get the rounding errors to appear at the same places */
     101             :     Word16 pows[12]; /* powers of two exponents*/
     102             :     Word16 exp2;
     103             :     Word16 out, out2;
     104             :     Word16 k, h, maxk;
     105             : 
     106           0 :     assert( exp >= 0 );
     107             : 
     108           0 :     out = base; /* Q15 */
     109           0 :     move16();
     110           0 :     out2 = 0x7FFF; /* 1 in Q15 */
     111           0 :     move16();
     112           0 :     IF( exp != 0 )
     113             :     {
     114           0 :         exp2 = sub( exp, 1 );
     115           0 :         maxk = sub( 15, norm_s( exp ) );
     116           0 :         assert( maxk < 12 );
     117             : 
     118           0 :         pows[0] = base; /* Q15 */
     119           0 :         move16();
     120           0 :         FOR( k = 0; k < maxk; k++ )
     121             :         {
     122           0 :             pows[k + 1] = mult_r( pows[k], pows[k] ); /* Q15 */
     123           0 :             move16();
     124             :         }
     125           0 :         k = sub( k, 1 );
     126           0 :         h = shl( 1, k ); /* highest bit of exp2 */
     127           0 :         out2 = base;
     128           0 :         move16();
     129           0 :         out = mult_r( out, pows[k + 1] ); /* we already know that "exp" has the highest bit set to one since we calculated .. */
     130             :         /* .. the effective length of "exp" earlier on, thus we omit the branch for out2 */
     131           0 :         IF( s_and( exp2, h ) != 0 )
     132             :         {
     133           0 :             out2 = mult_r( out2, pows[k + 1] ); /* Q15 */
     134             :         }
     135             : 
     136           0 :         h = shr( h, 1 );
     137           0 :         FOR( k = sub( k, 1 ); k >= 0; k-- )
     138             :         {
     139           0 :             IF( s_and( exp, h ) != 0 )
     140             :             {
     141           0 :                 out = mult_r( out, pows[k + 1] ); /* Q15 */
     142             :             }
     143             : 
     144           0 :             IF( s_and( exp2, h ) != 0 )
     145             :             {
     146           0 :                 out2 = mult_r( out2, pows[k + 1] ); /* Q15 */
     147             :             }
     148             : 
     149           0 :             h = shr( h, 1 );
     150             :         }
     151             :     }
     152             : 
     153           0 :     *pout1 = out2; /* Q15 */
     154           0 :     move16();
     155           0 :     *pout2 = out; /* Q15 */
     156           0 :     move16();
     157           0 : }
     158             : 
     159             : /*------------------------------------------------------------------------
     160             :  * Function: tcx_arith_scale_envelope
     161             :  *
     162             :  * For optimal performance of the arithmetic coder, the envelope shape must
     163             :  * be scaled such that the expected bit-consumption of a signal that
     164             :  * follows the scaled shape coincides with the target bitrate.
     165             :  * This function calculates a first-guess scaling and then uses the bi-section
     166             :  * search to find the optimal scaling.
     167             :  *
     168             :  * We assume that lines follow the Laplacian distribution, whereby the expected
     169             :  * bit-consumption would be log2(2*e*s[k]), where s[k] is the envelope value
     170             :  * for the line in question. However, this theoretical formula assumes that
     171             :  * all lines are encoded with magnitude+sign. Since the sign is unnecessary
     172             :  * for 0-values, that estimate of bit-consumption is biased when s[k] is small.
     173             :  * Analytical solution of the expectation for small s[k] is difficult, whereby
     174             :  * we use the approximation log2(2*e*s[k] + 0.15 + 0.035 / s[k]) which is accurate
     175             :  * on the range 0.08 to 1.0.
     176             :  *
     177             :  * NOTE: This function must be bit-exact on all platforms such that encoder
     178             :  * and decoder remain synchronized.
     179             :  *-------------------------------------------------------------------------*/
     180       14024 : void tcx_arith_scale_envelope(
     181             :     const Word16 L_spec_core,    /* i: number of lines to scale    Q0 */
     182             :     Word16 L_frame,              /* i: number of lines             Q0 */
     183             :     const Word32 env[],          /* i: unscaled envelope           Q16 */
     184             :     Word16 target_bits,          /* i: number of available bits    Q0 */
     185             :     const Word16 low_complexity, /* i: low-complexity flag         Q0 */
     186             :     Word16 s_env[],              /* o: scaled envelope             Q15-e */
     187             :     Word16 *s_env_e              /* o: scaled envelope exponent    Q0 */
     188             : )
     189             : {
     190             :     Word32 ienv[N_MAX_ARI];
     191             :     Word16 scale, iscale, iscale_e, a_e, b, b_e;
     192             :     Word16 lob, hib, adjust;
     193             :     Word16 k, iter, max_iter, lob_bits, hib_bits;
     194             :     Word16 statesi, bits;
     195             :     Word32 mean, a, s, L_tmp;
     196             :     Word16 mean_e, tmp, tmp2;
     197             : #ifndef ISSUE_1836_replace_overflow_libcom
     198             : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
     199             :     Flag Overflow = 0;
     200             :     move32();
     201             : #endif
     202             : #endif
     203             : 
     204             : 
     205       14024 :     lob_bits = 0;
     206       14024 :     move16();
     207       14024 :     hib_bits = 0;
     208       14024 :     move16();
     209             : 
     210             :     /* Boosting to account for expected spectrum truncation (kMax) */
     211             :     /* target_bits = (int)(target_bits * (1.2f - 0.00045f * target_bits + 0.00000025f * target_bits * target_bits)); */
     212       14024 :     L_tmp = L_shr( Mpy_32_16_1( L_mult0( target_bits, target_bits ), 17180 ), 6 ); /* Q15; 17180 -> 0.00000025f (Q36) */
     213       14024 :     L_tmp = L_sub( L_tmp, L_shr( L_mult0( target_bits, 30199 ), 11 ) );            /* Q15; 30199 -> 0.00045f (Q26) */
     214       14024 :     L_tmp = L_add( L_tmp, 39322 );                                                 /* Q15; 39322 -> 1.2f (Q15) */
     215       14024 :     L_tmp = Mpy_32_16_1( L_tmp, target_bits );                                     /* Q0 */
     216       14024 :     assert( L_tmp < 32768 );
     217       14024 :     target_bits = extract_l( L_tmp );
     218             : 
     219             :     /* Calculate inverse envelope and find initial scale guess based on mean */
     220       14024 :     mean = L_deposit_l( 0 );
     221     2943512 :     FOR( k = 0; k < L_frame; k++ )
     222             :     {
     223             :         /* ienv[k] = 1.0f / env[k];
     224             :         mean += ienv[k]; */
     225             : 
     226     2929488 :         tmp = norm_l( env[k] );
     227     2929488 :         tmp2 = sub( 15, tmp );
     228             : #ifdef ISSUE_1836_replace_overflow_libcom
     229     2929488 :         tmp = Inv16( round_fx_sat( L_shl( env[k], tmp ) ), &tmp2 ); /* exp(tmp2) */
     230             : #else
     231             :         tmp = Inv16( round_fx_o( L_shl_o( env[k], tmp, &Overflow ), &Overflow ), &tmp2 ); /* exp(tmp2) */
     232             : #endif
     233     2929488 :         ienv[k] = L_shl( L_deposit_h( tmp ), sub( tmp2, 15 ) ); /* Q16 */
     234     2929488 :         move32();
     235     2929488 :         mean = L_add( mean, ienv[k] ); /* Q16 */
     236             :     }
     237       14024 :     tmp = norm_s( L_frame );
     238       14024 :     tmp = shl( div_s( 8192, shl( L_frame, tmp ) ), sub( tmp, 7 ) );
     239       14024 :     mean = L_shr( Mpy_32_16_1( mean, tmp ), 6 ); /* Q16 */
     240             : 
     241             :     /* Rate dependent compensation to get closer to the target on average */
     242             :     /* mean = (float)pow(mean, (float)L_frame / (float)target_bits * 0.357f); */
     243       14024 :     tmp = BASOP_Util_Divide1616_Scale( L_frame, target_bits, &tmp2 ); /* exp(tmp2) */
     244       14024 :     tmp = mult_r( tmp, 11698 /*0.357f Q15*/ );
     245       14024 :     mean = BASOP_Util_fPow( mean, 15, L_deposit_h( tmp ), tmp2, &mean_e ); /* exp(mean_e) */
     246             : 
     247             :     /* Find first-guess scaling coefficient "scale" such that if "mean" is the
     248             :      * mean of the envelope, then the mean bit-consumption is approximately
     249             :      *
     250             :      * log2(2*e*mean*scale + 0.15 + 0.035/(mean*scale)) * L_frame = target_bits
     251             :      */
     252             :     /* a = 2*2.71828183f*mean*mean; */
     253       14024 :     tmp = round_fx( mean );                                      /* Q15 - mean_e */
     254       14024 :     a = L_mult( mult_r( tmp, 22268 /*2.71828183f Q13*/ ), tmp ); /* 2 * mean_e + 3 */
     255       14024 :     a_e = add( shl( mean_e, 1 ), 3 );
     256             : 
     257             :     /* b = (0.15f - (float)pow(2.0f, target_bits/(float)L_frame)) * mean; */
     258       14024 :     tmp = BASOP_Util_Divide1616_Scale( target_bits, L_frame, &tmp2 ); /* exp(tmp2) */
     259       14024 :     tmp = round_fx( BASOP_util_Pow2( L_deposit_h( tmp ), tmp2, &tmp2 ) );
     260       14024 :     b_e = BASOP_Util_Add_MantExp( 4915 /*0.15f Q15*/, 0, negate( tmp ), tmp2, &b );
     261       14024 :     b = mult_r( b, round_fx( mean ) ); /* exp(b_e + mean_e) */
     262       14024 :     b_e = add( b_e, mean_e );
     263             : 
     264             :     /* scale = (-b + (float)sqrt(b*b - 4.0f*a*0.035f)) / (2.0f * a); */
     265             : #ifdef ISSUE_1836_replace_overflow_libcom
     266       14024 :     tmp = round_fx_sat( BASOP_Util_Add_Mant32Exp( L_mult( b, b ), shl( b_e, 1 ), Mpy_32_16_1( a, -4588 /*-4.0f*0.035f Q15*/ ), a_e, &tmp2 ) );
     267             : #else
     268             :     tmp = round_fx_o( BASOP_Util_Add_Mant32Exp( L_mult( b, b ), shl( b_e, 1 ), Mpy_32_16_1( a, -4588 /*-4.0f*0.035f Q15*/ ), a_e, &tmp2 ), &Overflow );
     269             : #endif
     270             : 
     271       14024 :     IF( tmp <= 0 )
     272             :     {
     273           0 :         tmp = 0;
     274           0 :         move16();
     275           0 :         set16_fx( s_env, 0, L_frame );
     276             :     }
     277             :     ELSE
     278             :     {
     279       14024 :         tmp = Sqrt16( tmp, &tmp2 );
     280             :     }
     281             : 
     282       14024 :     tmp2 = BASOP_Util_Add_MantExp( negate( b ), b_e, tmp, tmp2, &scale ); /* exp(scale) */
     283       14024 :     scale = BASOP_Util_Divide1616_Scale( scale, round_fx( a ), &tmp );
     284             : #ifdef ISSUE_1836_replace_overflow_libcom
     285       14024 :     scale = shl_sat( scale, sub( sub( add( tmp, tmp2 ), a_e ), 1 ) ); /* Q15 */
     286             : #else
     287             :     scale = shl_o( scale, sub( sub( add( tmp, tmp2 ), a_e ), 1 ), &Overflow ); /* Q15 */
     288             : #endif
     289             : 
     290             :     /* iscale = 1.0f / scale; */
     291       14024 :     iscale_e = 0;
     292       14024 :     move16();
     293       14024 :     iscale = Inv16( s_max( 1, scale ), &iscale_e ); /* exp(isacle_e) */
     294             : 
     295       14024 :     lob = 0;
     296       14024 :     move16();
     297       14024 :     hib = 0;
     298       14024 :     move16();
     299             : 
     300       14024 :     max_iter = 2;
     301       14024 :     move16();
     302       14024 :     if ( low_complexity )
     303             :     {
     304       12648 :         max_iter = 1;
     305       12648 :         move16();
     306             :     }
     307             : 
     308       29424 :     FOR( iter = 0; iter < max_iter; iter++ )
     309             :     {
     310       15400 :         statesi = 0x7FFF; /* 1 in Q15 */
     311       15400 :         move16();
     312       15400 :         bits = 0;
     313       15400 :         move16();
     314             : 
     315     3233006 :         FOR( k = 0; k < L_frame; k++ )
     316             :         {
     317     3217606 :             s = Mpy_32_16_1( ienv[k], scale ); /* Q16 */
     318             : 
     319     3217606 :             IF( LE_32( s, 5243l /*0.08f Q16*/ ) )
     320             :             {
     321             :                 /* If s = 0.08, the expected bit-consumption is log2(1.0224). Below 0.08, the bit-consumption
     322             :                    estimate function becomes inaccurate, so use log2(1.0224) for all values below 0.08. */
     323             :                 /* round(state * 1.0224 * 32768) */
     324       12662 :                 statesi = mult_r( statesi, 16751 /*1.0224 Q14*/ ); /* Q14 */
     325       12662 :                 tmp = norm_s( statesi );
     326       12662 :                 statesi = shl( statesi, tmp );     /* Q15 */
     327       12662 :                 bits = add( bits, sub( 1, tmp ) ); /* Q0 */
     328             :             }
     329     3204944 :             ELSE IF( LE_32( s, 16711680l /*255.0 Q16*/ ) )
     330             :             {
     331             :                 /* a = 5.436564f * s + 0.15f + 0.035f * env[k] * iscale; */
     332     3204944 :                 L_tmp = L_shl( Mpy_32_16_1( s, 22268 /*5.436564f Q12*/ ), 3 );                                           /* Q16 */
     333     3204944 :                 L_tmp = L_add( L_tmp, 9830l /*0.15f Q16*/ );                                                             /* Q16 */
     334     3204944 :                 L_tmp = L_add( L_tmp, L_shl( Mpy_32_16_1( env[k], mult_r( 1147 /*0.035f Q15*/, iscale ) ), iscale_e ) ); /* Q16 */
     335             : 
     336     3204944 :                 tmp = norm_l( L_tmp );
     337             : #ifdef ISSUE_1836_replace_overflow_libcom
     338     3204944 :                 statesi = mult_r( statesi, round_fx_sat( L_shl( L_tmp, tmp ) ) );
     339             : #else
     340             :                 statesi = mult_r( statesi, round_fx_o( L_shl_o( L_tmp, tmp, &Overflow ), &Overflow ) );
     341             : #endif
     342     3204944 :                 bits = add( bits, sub( 15, tmp ) );
     343             : 
     344     3204944 :                 tmp = norm_s( statesi );
     345     3204944 :                 statesi = shl( statesi, tmp );
     346     3204944 :                 bits = sub( bits, tmp ); /* Q0 */
     347             :             }
     348             :             ELSE
     349             :             {
     350             :                 /* for large envelope values, s > 255, bit consumption is approx log2(2*e*s)
     351             :                  * further, we use round(log2(x)) = floor(log2(x)+0.5) = floor(log2(x*sqrt(2))) */
     352             :                 /* a = 5.436564f * s; */
     353           0 :                 L_tmp = Mpy_32_16_1( s, 31492 /*5.436564f * 1.4142f Q12*/ ); /* Q13 */
     354           0 :                 bits = add( bits, sub( 17, norm_l( L_tmp ) ) );              /* Q0 */
     355             :             }
     356             :         }
     357             : 
     358       15400 :         IF( LE_16( bits, target_bits ) ) /* Bits leftover => scale is too small */
     359             :         {
     360        1727 :             lob = scale; /* Q0 */
     361        1727 :             move16();
     362        1727 :             lob_bits = bits; /* Q0 */
     363        1727 :             move16();
     364             : 
     365        1727 :             IF( hib > 0 ) /* Bisection search */
     366             :             {
     367        1237 :                 adjust = div_s( sub( hib_bits, target_bits ), sub( hib_bits, lob_bits ) ); /* Q15 */
     368        1237 :                 scale = add( mult_r( sub( lob, hib ), adjust ), hib );
     369             :             }
     370             :             ELSE /* Initial scale adaptation */
     371             :             {
     372             :                 /* adjust = 1.05f * target_bits / (float)bits;
     373             :                    scale *= adjust; */
     374         490 :                 adjust = mult_r( 17203 /*1.05f Q14*/, target_bits );
     375         490 :                 adjust = BASOP_Util_Divide1616_Scale( adjust, bits, &tmp ); /* exp(tmp) */
     376         490 :                 scale = shl( mult_r( scale, adjust ), add( 1, tmp ) );
     377             :             }
     378             :         }
     379             :         ELSE /* Ran out of bits => scale is too large */
     380             :         {
     381       13673 :             hib = scale;
     382       13673 :             move16();
     383       13673 :             hib_bits = bits;
     384       13673 :             move16();
     385             : 
     386       13673 :             IF( lob > 0 ) /* Bisection search */
     387             :             {
     388          54 :                 adjust = div_s( sub( hib_bits, target_bits ), sub( hib_bits, lob_bits ) ); /* Q15 */
     389          54 :                 scale = add( mult_r( sub( lob, hib ), adjust ), hib );
     390             :             }
     391             :             ELSE
     392             :             { /* Initial scale adaptation */
     393       13619 :                 test();
     394       13619 :                 IF( target_bits <= 0 || bits <= 0 ) /* safety check in case of bit errors */
     395             :                 {
     396           0 :                     adjust = 0;
     397           0 :                     move16();
     398           0 :                     set16_fx( s_env, 0, L_frame );
     399             :                 }
     400             :                 ELSE
     401             :                 {
     402       13619 :                     adjust = div_s( mult_r( 31130 /*0.95f Q15*/, target_bits ), bits ); /* Q15 */
     403             :                 }
     404       13619 :                 scale = mult_r( scale, adjust );
     405             :             }
     406             :         }
     407       15400 :         iscale_e = 0;
     408       15400 :         move16();
     409             : 
     410       15400 :         IF( scale == 0 ) /* safety check in case of bit errors */
     411             :         {
     412           0 :             iscale = 0;
     413           0 :             move16();
     414           0 :             set16_fx( s_env, 0, L_frame );
     415             :         }
     416             :         ELSE
     417             :         {
     418       15400 :             iscale = Inv16( scale, &iscale_e );
     419             :         }
     420             :     }
     421       14024 :     L_frame = L_spec_core; /* Q0 */
     422       14024 :     move16();
     423             : 
     424       14024 :     tmp = getScaleFactor32( env, L_frame );
     425       14024 :     *s_env_e = sub( add( 15, iscale_e ), tmp );
     426       14024 :     move16();
     427             :     BASOP_SATURATE_WARNING_OFF_EVS;
     428             : #ifdef ISSUE_1836_replace_overflow_libcom
     429       14024 :     a = L_shl_sat( 1265000, sub( 15, *s_env_e ) );
     430             : #else
     431             :     a = L_shl_o( 1265000, sub( 15, *s_env_e ), &Overflow );
     432             : #endif
     433             :     BASOP_SATURATE_WARNING_ON_EVS;
     434             : 
     435     8751064 :     FOR( k = 0; k < L_frame; k++ )
     436             :     {
     437     8737040 :         L_tmp = Mpy_32_16_1( L_shl( env[k], tmp ), iscale ); /* Q31 - e */
     438     8737040 :         L_tmp = L_min( L_tmp, a );                           /* Q31 - e */
     439     8737040 :         s_env[k] = round_fx( L_tmp );                        /* Q15 - e */
     440     8737040 :         move16();
     441             :     }
     442       14024 : }
     443             : 
     444             : /*------------------------------------------------------------------------
     445             :  * Function: tcx_arith_render_envelope
     446             :  *
     447             :  * Calculate the envelope of the spectrum based on the LPC shape. The
     448             :  * envelope is used in a perceptual domain, whereby the LPC shape has to
     449             :  * be multiplied by the perceptual model.
     450             :  * Operations that are performed on the spectrum, which change the magnitude
     451             :  * expectation of lines, such as low-frequency emphasis, are included in the
     452             :  * envelope shape.
     453             :  * NOTE: This function must be bit-exact on all platforms such that encoder
     454             :  * and decoder remain synchronized.
     455             :  *-------------------------------------------------------------------------*/
     456           0 : void tcx_arith_render_envelope(
     457             :     const Word16 A_ind[],     /* i: LPC coefficients of signal envelope                         Q12*/
     458             :     const Word16 L_frame,     /* i: number of spectral lines                                            Q0*/
     459             :     const Word16 L_spec,      /* Q0 */
     460             :     const Word16 preemph_fac, /* i: pre-emphasis factor                                                         Q15*/
     461             :     const Word16 gamma_w,     /* i: A_ind -> weighted envelope factor                                Q15*/
     462             :     const Word16 gamma_uw,    /* i: A_ind -> non-weighted envelope factor                    Q14*/
     463             :     Word32 env[]              /* o: shaped signal envelope                                                      Q16*/
     464             : )
     465             : {
     466             :     Word16 k;
     467             :     Word16 tmpA[M + 2];
     468             :     Word16 signal_env[FDNS_NPTS], signal_env_e[FDNS_NPTS];
     469             :     Word16 gainlpc[FDNS_NPTS], gainlpc_e[FDNS_NPTS];
     470             : 
     471             : 
     472             :     /* Compute perceptual LPC envelope, transform it into freq.-domain gains */
     473           0 :     weight_a_fx( A_ind, tmpA, gamma_w, M );
     474           0 :     lpc2mdct( tmpA, M, NULL, NULL, gainlpc, gainlpc_e, FDNS_NPTS, 0 );
     475             : 
     476             :     /* Add pre-emphasis tilt to LPC envelope, transform LPC into MDCT gains */
     477           0 :     E_LPC_a_weight_inv( A_ind, signal_env, gamma_uw, M );
     478           0 :     E_LPC_a_add_tilt( signal_env, tmpA, preemph_fac, M );
     479           0 :     lpc2mdct( tmpA, M + 1, signal_env, signal_env_e, NULL, NULL, FDNS_NPTS, 0 );
     480             : 
     481             :     /* Compute weighted signal envelope in perceptual domain */
     482           0 :     FOR( k = 0; k < FDNS_NPTS; k++ )
     483             :     {
     484           0 :         signal_env[k] = mult_r( signal_env[k], gainlpc[k] ); /* exp(signal_env_e + gainlpc_e)  */
     485           0 :         move16();
     486           0 :         signal_env_e[k] = add( signal_env_e[k], gainlpc_e[k] );
     487           0 :         move16();
     488             :     }
     489             : 
     490             :     /* Adaptive low frequency emphasis */
     491           0 :     set32_fx( env, 0x10000 /* 1 in Q16 */, L_frame );
     492             : 
     493           0 :     AdaptLowFreqDeemph( env, 15,
     494             :                         1,
     495             :                         gainlpc, gainlpc_e,
     496             :                         L_frame, NULL );
     497             : 
     498             :     /* Scale from FDNS_NPTS to L_frame and multiply LFE gains */
     499           0 :     mdct_noiseShaping_interp( env, L_frame, signal_env, signal_env_e );
     500             : 
     501           0 :     FOR( k = L_frame; k < L_spec; ++k )
     502             :     {
     503           0 :         env[k] = env[k - 1]; /* Q16 */
     504           0 :         move32();
     505             :     }
     506           0 : }
     507             : 
     508             : #define WMC_TOOL_SKIP
     509             : 
     510             : /*-------------------------------------------------------*
     511             :  * expfp_evs()
     512             :  *
     513             :  * Fixed point implementation of exp()
     514             :  *-------------------------------------------------------*/
     515             : 
     516             : /*! r: Q15 */
     517     8614277 : Word16 expfp_evs_fx(
     518             :     const Word16 x,  /* i  : mantissa  Q15-e */
     519             :     const Word16 x_e /* i  : exponent  Q0 */
     520             : )
     521             : {
     522             :     Word16 xi, xf, tmp;
     523             :     Word16 b0, b1, b2, b3;
     524             :     Word32 y, L_tmp;
     525             : 
     526     8614277 :     assert( x <= 0 );
     527             : 
     528     8614277 :     L_tmp = L_negate( L_shl( L_deposit_h( x ), sub( x_e, 15 ) ) ); /* Q16 */
     529             : 
     530             :     /* split into integer and fractional parts */
     531     8614277 :     xi = round_fx( L_tmp );  /* Q0 */
     532     8614277 :     xf = extract_l( L_tmp ); /* Q16 */
     533             : 
     534             :     BASOP_SATURATE_WARNING_OFF;
     535     8614277 :     xf = negate( xf );
     536             :     BASOP_SATURATE_WARNING_ON;
     537             : 
     538             :     /* Fractional part */
     539             :     /* y = 65536
     540             :                     +         xf
     541             :                     +       ((xf*xf) / (2*65536))
     542             :                     +   ((((((xf*xf) / (2*65536))*xf) / 65536)*65536/3) / 65536)
     543             :                     + ((((((((xf*xf) / (2*65536))*xf) / 65536)*65536/3) / 65536)*xf) / (4*65536)); */
     544     8614277 :     y = L_mac0( 65536, xf, 1 );     /* Q16 */
     545     8614277 :     tmp = shr( mult( xf, xf ), 2 ); /* Q15 */
     546     8614277 :     y = L_mac0( y, tmp, 1 );        /* Q16 */
     547     8614277 :     tmp = shr( mult( shr( mult( tmp, xf ), 1 ), 65536 / 3 ), 1 );
     548     8614277 :     y = L_mac0( y, tmp, 1 ); /* Q16 */
     549     8614277 :     tmp = shr( mult( tmp, xf ), 3 );
     550     8614277 :     y = L_mac0( y, tmp, 1 ); /* Q16 */
     551             : 
     552             :     /* Integer part */
     553     8614277 :     b0 = s_and( xi, 1 );
     554     8614277 :     b1 = s_and( xi, 2 );
     555     8614277 :     b2 = s_and( xi, 4 );
     556     8614277 :     b3 = s_and( xi, 8 );
     557             : 
     558     8614277 :     if ( b0 != 0 )
     559     4172279 :         y = Mpy_32_16_1( y, 24109 ); /* exp(-1) in -1Q16 */
     560     8614277 :     if ( b1 != 0 )
     561     3989340 :         y = Mpy_32_16_1( y, 17739 ); /* exp(-2) in -2Q17 */
     562     8614277 :     if ( b2 != 0 )
     563     5008142 :         y = Mpy_32_16_1( y, 19205 ); /* exp(-4) in -5Q20 */
     564     8614277 :     if ( b3 != 0 )
     565      588988 :         y = Mpy_32_16_1( y, 22513 ); /* exp(-8) in -11Q26 */
     566             : 
     567             :     /* scaling: -1*b0 - 2*b1 -5*b2 -11*b3 */
     568     8614277 :     y = L_shr( y, add( add( xi, shr( xi, 2 ) ), shr( b3, 3 ) ) ); /* Q16 */
     569             : 
     570             :     /* zero for xi >= 16 */
     571     8614277 :     if ( shr( xi, 4 ) > 0 )
     572             :     {
     573           0 :         y = L_deposit_l( 0 );
     574           0 :         move16();
     575             :     }
     576             : 
     577     8614277 :     return round_fx( L_shl( y, 15 ) );
     578             : }
     579             : 
     580             : /*-------------------------------------------------------*
     581             :  * powfp_odd2_evs()
     582             :  *
     583             :  * Fixed point implementation of pow(), where base is fixed point (16/16) and exponent a small *odd* integer
     584             :  *-------------------------------------------------------*/
     585             : /*
     586             :  *
     587             :  * Returns: *pout1 = ( (base/65536)^(2*exp - 1) ) * 65536
     588             :  *          *pout2 = ( (base/65536)^(2*exp + 1) ) * 65536
     589             :  *
     590             :  * NOTE: This function must be in sync with ari_decode_14bits_pow_ivas() */
     591             : 
     592             : 
     593             : /*------------------------------------------------------------------------
     594             :  * Function: tcx_arith_render_envelope_flt
     595             :  *
     596             :  * Calculate the envelope of the spectrum based on the LPC shape. The
     597             :  * envelope is used in a perceptual domain, whereby the LPC shape has to
     598             :  * be multiplied by the perceptual model.
     599             :  * Operations that are performed on the spectrum, which change the magnitude
     600             :  * expectation of lines, such as low-frequency emphasis, are included in the
     601             :  * envelope shape.
     602             :  * NOTE: This function must be bit-exact on all platforms such that encoder
     603             :  * and decoder remain synchronized.
     604             :  *-------------------------------------------------------------------------*/
     605             : 
     606       14024 : void tcx_arith_render_envelope_ivas_fx(
     607             :     const Word16 A_ind[],     /* i  : LPC coefficients of signal envelope        Q12*/
     608             :     const Word16 L_frame,     /* i  : number of spectral lines                   Q0*/
     609             :     const Word16 L_spec,      /* i  : length of the coded spectrum               Q0*/
     610             :     const Word16 preemph_fac, /* i  : pre-emphasis factor                        Q15*/
     611             :     const Word16 gamma_w,     /* i  : A_ind -> weighted envelope factor          Q15*/
     612             :     const Word16 gamma_uw,    /* i  : A_ind -> non-weighted envelope factor      Q14*/
     613             :     Word32 env[]              /* o  : shaped signal envelope                     Q16*/
     614             : )
     615             : {
     616             :     Word16 k;
     617             :     Word16 tmpA[M + 2];
     618             :     Word16 signal_env[FDNS_NPTS], signal_env_e[FDNS_NPTS];
     619             :     Word16 gainlpc[FDNS_NPTS], gainlpc_e[FDNS_NPTS];
     620             : 
     621             :     /* Compute perceptual LPC envelope, transform it into freq.-domain gains */
     622       14024 :     basop_weight_a( A_ind, tmpA, gamma_w );
     623       14024 :     basop_lpc2mdct_fx( tmpA, M, NULL, NULL, gainlpc, gainlpc_e );
     624             : 
     625             :     /* Add pre-emphasis tilt to LPC envelope, transform LPC into MDCT gains */
     626       14024 :     basop_weight_a_inv( A_ind, signal_env, gamma_uw );
     627       14024 :     basop_E_LPC_a_add_tilt( signal_env, tmpA, preemph_fac );
     628       14024 :     basop_lpc2mdct_fx( tmpA, M + 1, signal_env, signal_env_e, NULL, NULL );
     629             : 
     630             :     /* Compute weighted signal envelope in perceptual domain */
     631      911560 :     FOR( k = 0; k < FDNS_NPTS; k++ )
     632             :     {
     633      897536 :         signal_env[k] = mult_r( signal_env[k], gainlpc[k] ); /* exp(signal_env_e + gainlpc_e)  */
     634      897536 :         move16();
     635      897536 :         signal_env_e[k] = add( signal_env_e[k], gainlpc_e[k] );
     636      897536 :         move16();
     637             :     }
     638             : 
     639             :     /* Adaptive low frequency emphasis */
     640     3688008 :     FOR( k = 0; k < L_frame; k++ )
     641             :     {
     642     3673984 :         env[k] = 0x10000; /* 1 in Q16 */
     643     3673984 :         move32();
     644             :     }
     645             : 
     646       14024 :     basop_PsychAdaptLowFreqDeemph_fx( env, gainlpc, gainlpc_e, NULL );
     647             : 
     648             :     /* Scale from FDNS_NPTS to L_frame and multiply LFE gains */
     649       14024 :     basop_mdct_noiseShaping_interp_fx( env, L_frame, signal_env, signal_env_e );
     650             : 
     651     5077080 :     FOR( k = L_frame; k < L_spec; ++k )
     652             :     {
     653     5063056 :         env[k] = env[k - 1]; /* Q16 */
     654     5063056 :         move32();
     655             :     }
     656             : 
     657       14024 :     return;
     658             : }
     659             : 
     660             : #undef WMC_TOOL_SKIP

Generated by: LCOV version 1.14