LCOV - code coverage report
Current view: top level - lib_com - arith_coder.c (source / functions) Hit Total Coverage
Test: Coverage on main -- short test vectors @ 6c9ddc4024a9c0e1ecb8f643f114a84a0e26ec6b Lines: 194 212 91.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 <math.h>
      44             : #include "cnst.h"
      45             : #include "prot.h"
      46             : #include "basop_util.h"
      47             : #include "basop_proto_func.h"
      48             : #include "wmc_auto.h"
      49             : 
      50             : 
      51             : #define WMC_TOOL_SKIP
      52             : 
      53             : /*-------------------------------------------------------*
      54             :  * expfp()
      55             :  *
      56             :  * Fixed point implementation of exp()
      57             :  *-------------------------------------------------------*/
      58             : 
      59             : /*! r: Q15 */
      60    42580947 : Word16 expfp(
      61             :     const Word16 x,  /* i  : mantissa  Q15-e */
      62             :     const Word16 x_e /* i  : exponent  Q0 */
      63             : )
      64             : {
      65             :     Word16 xi, xf, tmp;
      66             :     Word16 b0, b1, b2, b3;
      67             :     Word32 y, L_tmp;
      68             : 
      69    42580947 :     assert( x <= 0 );
      70             : 
      71    42580947 :     L_tmp = L_negate( L_shl( L_deposit_h( x ), sub( x_e, 15 ) ) );
      72             : 
      73             :     /* split into integer and fractional parts */
      74    42580947 :     xi = round_fx( L_tmp );
      75    42580947 :     xf = extract_l( L_tmp );
      76             : 
      77             :     BASOP_SATURATE_WARNING_OFF;
      78    42580947 :     xf = negate( xf );
      79             :     BASOP_SATURATE_WARNING_ON;
      80             : 
      81             :     /* Fractional part */
      82             :     /* y = 65536
      83             :             +         xf
      84             :             +       ((xf*xf) / (2*65536))
      85             :             +   ((((((xf*xf) / (2*65536))*xf) / 65536)*65536/3) / 65536)
      86             :             + ((((((((xf*xf) / (2*65536))*xf) / 65536)*65536/3) / 65536)*xf) / (4*65536)); */
      87    42580947 :     y = L_mac0( 65536, xf, 1 );
      88    42580947 :     tmp = shr( mult( xf, xf ), 2 );
      89    42580947 :     y = L_mac0( y, tmp, 1 );
      90    42580947 :     tmp = shr( mult( shr( mult( tmp, xf ), 1 ), 65536 / 3 ), 1 );
      91    42580947 :     y = L_mac0( y, tmp, 1 );
      92    42580947 :     tmp = shr( mult( tmp, xf ), 3 );
      93    42580947 :     y = L_mac0( y, tmp, 1 );
      94             : 
      95             :     /* Integer part */
      96    42580947 :     b0 = s_and( xi, 1 );
      97    42580947 :     b1 = s_and( xi, 2 );
      98    42580947 :     b2 = s_and( xi, 4 );
      99    42580947 :     b3 = s_and( xi, 8 );
     100             : 
     101    42580947 :     if ( b0 != 0 )
     102    20643122 :         y = Mpy_32_16( y, 24109 ); /* exp(-1) in -1Q16 */
     103    42580947 :     if ( b1 != 0 )
     104    19897189 :         y = Mpy_32_16( y, 17739 ); /* exp(-2) in -2Q17 */
     105    42580947 :     if ( b2 != 0 )
     106    24788878 :         y = Mpy_32_16( y, 19205 ); /* exp(-4) in -5Q20 */
     107    42580947 :     if ( b3 != 0 )
     108     3114959 :         y = Mpy_32_16( y, 22513 ); /* exp(-8) in -11Q26 */
     109             : 
     110             :     /* scaling: -1*b0 - 2*b1 -5*b2 -11*b3 */
     111    42580947 :     y = L_shr( y, add( add( xi, shr( xi, 2 ) ), shr( b3, 3 ) ) );
     112             : 
     113             :     /* zero for xi >= 16 */
     114    42580947 :     if ( shr( xi, 4 ) > 0 )
     115             :     {
     116           0 :         y = L_deposit_l( 0 );
     117           0 :         move16();
     118             :     }
     119             : 
     120    42580947 :     return round_fx( L_shl( y, 15 ) );
     121             : }
     122             : 
     123             : 
     124             : /*-------------------------------------------------------*
     125             :  * powfp_odd2()
     126             :  *
     127             :  * Fixed point implementation of pow(), where base is fixed point (16/16) and exponent a small *odd* integer
     128             :  *-------------------------------------------------------*/
     129             : /*
     130             :  *
     131             :  * Returns: *pout1 = ( (base/65536)^(2*exp - 1) ) * 65536
     132             :  *          *pout2 = ( (base/65536)^(2*exp + 1) ) * 65536
     133             :  *
     134             :  * NOTE: This function must be in sync with ari_decode_14bits_pow() */
     135             : 
     136      876988 : void powfp_odd2(
     137             :     const Word16 base, /* Q15 */
     138             :     const Word16 exp,  /* Q0  */
     139             :     Word16 *pout1,     /* Q15 */
     140             :     Word16 *pout2      /* Q15 */
     141             : )
     142             : {
     143             :     /* this version is in sync with ari_enc_14bits_pow()
     144             :      * that is, we have to start multiplication from the largest power-of-two, in order to
     145             :      * get the rounding errors to appear at the same places */
     146             :     Word16 pows[12]; /* powers of two exponents*/
     147             :     Word16 exp2;
     148             :     Word16 out, out2;
     149             :     Word16 k, h, maxk;
     150             : 
     151      876988 :     assert( exp >= 0 );
     152             : 
     153      876988 :     out = base;
     154      876988 :     move16();
     155      876988 :     out2 = 0x7FFF;
     156      876988 :     move16();
     157      876988 :     IF( exp != 0 )
     158             :     {
     159      876988 :         exp2 = sub( exp, 1 );
     160      876988 :         maxk = sub( 15, norm_s( exp ) );
     161      876988 :         assert( maxk < 12 );
     162             : 
     163      876988 :         pows[0] = base;
     164      876988 :         move16();
     165     2532865 :         FOR( k = 0; k < maxk; k++ )
     166             :         {
     167     1655877 :             pows[k + 1] = mult_r( pows[k], pows[k] );
     168     1655877 :             move16();
     169             :         }
     170      876988 :         k = sub( k, 1 );
     171      876988 :         h = shl( 1, k ); /* highest bit of exp2 */
     172      876988 :         out2 = base;
     173      876988 :         move16();
     174      876988 :         out = mult_r( out, pows[k + 1] ); /* we already know that "exp" has the highest bit set to one since we calculated .. */
     175             :         /* .. the effective length of "exp" earlier on, thus we omit the branch for out2 */
     176      876988 :         if ( s_and( exp2, h ) != 0 )
     177             :         {
     178      233012 :             out2 = mult_r( out2, pows[k + 1] );
     179             :         }
     180             : 
     181      876988 :         h = shr( h, 1 );
     182     1655877 :         FOR( k = sub( k, 1 ); k >= 0; k-- )
     183             :         {
     184      778889 :             if ( s_and( exp, h ) != 0 )
     185             :             {
     186      285503 :                 out = mult_r( out, pows[k + 1] );
     187             :             }
     188             : 
     189      778889 :             if ( s_and( exp2, h ) != 0 )
     190             :             {
     191      445447 :                 out2 = mult_r( out2, pows[k + 1] );
     192             :             }
     193             : 
     194      778889 :             h = shr( h, 1 );
     195             :         }
     196             :     }
     197             : 
     198      876988 :     *pout1 = out2;
     199      876988 :     move16();
     200      876988 :     *pout2 = out;
     201      876988 :     move16();
     202             : 
     203      876988 :     return;
     204             : }
     205             : 
     206             : 
     207             : /*------------------------------------------------------------------------
     208             :  * Function: tcx_arith_scale_envelope
     209             :  *
     210             :  * For optimal performance of the arithmetic coder, the envelope shape must
     211             :  * be scaled such that the expected bit-consumption of a signal that
     212             :  * follows the scaled shape coincides with the target bitrate.
     213             :  * This function calculates a first-guess scaling and then uses the bi-section
     214             :  * search to find the optimal scaling.
     215             :  *
     216             :  * We assume that lines follow the Laplacian distribution, whereby the expected
     217             :  * bit-consumption would be log2(2*e*s[k]), where s[k] is the envelope value
     218             :  * for the line in question. However, this theoretical formula assumes that
     219             :  * all lines are encoded with magnitude+sign. Since the sign is unnecessary
     220             :  * for 0-values, that estimate of bit-consumption is biased when s[k] is small.
     221             :  * Analytical solution of the expectation for small s[k] is difficult, whereby
     222             :  * we use the approximation log2(2*e*s[k] + 0.15 + 0.035 / s[k]) which is accurate
     223             :  * on the range 0.08 to 1.0.
     224             :  *
     225             :  * NOTE: This function must be bit-exact on all platforms such that encoder
     226             :  * and decoder remain synchronized.
     227             :  *-------------------------------------------------------------------------*/
     228             : 
     229       68415 : void tcx_arith_scale_envelope(
     230             :     const Word16 L_spec_core,    /* i  : number of lines to scale    Q0 */
     231             :     Word16 L_frame,              /* i  : number of lines             Q0 */
     232             :     const Word32 env[],          /* i  : unscaled envelope           Q16 */
     233             :     Word16 target_bits,          /* i  : number of available bits    Q0 */
     234             :     const Word16 low_complexity, /* i  : low-complexity              Q0 */
     235             :     Word16 s_env[],              /* o  : scaled envelope             Q15-e */
     236             :     Word16 *s_env_e              /* o  : scaled envelope exponent    Q0 */
     237             : )
     238             : {
     239             :     Word32 ienv[N_MAX_ARI];
     240             :     Word16 scale, iscale, iscale_e, a_e, b, b_e;
     241             :     Word16 lob, hib, adjust;
     242             :     Word16 k, iter, max_iter, lob_bits, hib_bits;
     243             :     Word16 statesi, bits;
     244             :     Word32 mean, a, s, L_tmp;
     245             :     Word16 mean_e, tmp, tmp2;
     246             : #ifdef BASOP_NOGLOB
     247             :     Flag Overflow;
     248             : #endif /* BASOP_NOGLOB */
     249             : 
     250             : 
     251       68415 :     lob_bits = 0;
     252       68415 :     move16();
     253       68415 :     hib_bits = 0;
     254       68415 :     move16();
     255             : 
     256             :     /* Boosting to account for expected spectrum truncation (kMax) */
     257             :     /* target_bits = (int16_t)(target_bits * (1.2f - 0.00045f * target_bits + 0.00000025f * target_bits * target_bits)); */
     258       68415 :     L_tmp = L_shr( Mpy_32_16( L_mult0( target_bits, target_bits ), 17180 ), 6 ); /* Q15; 17180 -> 0.00000025f (Q36) */
     259       68415 :     L_tmp = L_sub( L_tmp, L_shr( L_mult0( target_bits, 30199 ), 11 ) );          /* Q15; 30199 -> 0.00045f (Q26) */
     260       68415 :     L_tmp = L_add( L_tmp, 39322 );                                               /* Q15; 39322 -> 1.2f (Q15) */
     261       68415 :     L_tmp = Mpy_32_16( L_tmp, target_bits );                                     /* Q0 */
     262       68415 :     assert( L_tmp < 32768 );
     263       68415 :     target_bits = extract_l( L_tmp );
     264             : 
     265             :     /* Calculate inverse envelope and find initial scale guess based on mean */
     266       68415 :     mean = L_deposit_l( 0 );
     267    14319995 :     FOR( k = 0; k < L_frame; k++ )
     268             :     {
     269             :         /* ienv[k] = 1.0f / env[k];
     270             :         mean += ienv[k]; */
     271             : 
     272    14251580 :         tmp = norm_l( env[k] );
     273    14251580 :         tmp2 = sub( 15, tmp );
     274             : #ifndef BASOP_NOGLOB
     275             :         tmp = Inv16( round_fx( L_shl( env[k], tmp ) ), &tmp2 );
     276             : #else                                                           /* BASOP_NOGLOB */
     277    14251580 :         tmp = Inv16( round_fx_o( L_shl( env[k], tmp ), &Overflow ), &tmp2 );
     278             : #endif                                                          /* BASOP_NOGLOB */
     279    14251580 :         ienv[k] = L_shl( L_deposit_h( tmp ), sub( tmp2, 15 ) ); /* Q16 */
     280    14251580 :         move32();
     281    14251580 :         mean = L_add( mean, ienv[k] );
     282             :     }
     283       68415 :     tmp = norm_s( L_frame );
     284       68415 :     tmp2 = div_s( 8192, shl( L_frame, tmp ) );
     285       68415 :     tmp = shl( tmp2, sub( tmp, 7 ) );
     286       68415 :     mean = L_shr( Mpy_32_16( mean, tmp ), 6 ); /* Q16 */
     287             : 
     288             :     /* Rate dependent compensation to get closer to the target on average */
     289             :     /* mean = powf(mean, (float)L_frame / target_bits * 0.357f); */
     290       68415 :     tmp = BASOP_Util_Divide1616_Scale( L_frame, target_bits, &tmp2 );
     291       68415 :     tmp = mult_r( tmp, FL2WORD16( 0.357f ) );
     292       68415 :     mean = BASOP_Util_fPow( mean, 15, L_deposit_h( tmp ), tmp2, &mean_e );
     293             : 
     294             :     /* Find first-guess scaling coefficient "scale" such that if "mean" is the
     295             :      * mean of the envelope, then the mean bit-consumption is approximately
     296             :      *
     297             :      * log2(2*e*mean*scale + 0.15 + 0.035/(mean*scale)) * L_frame = target_bits
     298             :      */
     299             :     /* a = 2*2.71828183f*mean*mean; */
     300       68415 :     tmp = round_fx( mean );
     301       68415 :     a = L_mult( mult_r( tmp, FL2WORD16_SCALE( 2.71828183f, 2 ) ), tmp );
     302       68415 :     a_e = add( shl( mean_e, 1 ), 3 );
     303             : 
     304             :     /* b = (0.15f - powf(2.0f, target_bits/(float)L_frame)) * mean; */
     305       68415 :     tmp = BASOP_Util_Divide1616_Scale( target_bits, L_frame, &tmp2 );
     306       68415 :     tmp = round_fx( BASOP_util_Pow2( L_deposit_h( tmp ), tmp2, &tmp2 ) );
     307       68415 :     b_e = BASOP_Util_Add_MantExp( FL2WORD16( 0.15f ), 0, negate( tmp ), tmp2, &b );
     308       68415 :     b = mult_r( b, round_fx( mean ) );
     309       68415 :     b_e = add( b_e, mean_e );
     310             : 
     311             :     /* scale = (-b + sqrtf(b*b - 4.0f*a*0.035f)) / (2.0f * a); */
     312             : #ifndef BASOP_NOGLOB
     313             :     tmp = round_fx( BASOP_Util_Add_Mant32Exp( L_mult( b, b ), shl( b_e, 1 ), Mpy_32_16( a, FL2WORD16( -4.0f * 0.035f ) ), a_e, &tmp2 ) );
     314             : #else
     315       68415 :     tmp = round_fx_o( BASOP_Util_Add_Mant32Exp( L_mult( b, b ), shl( b_e, 1 ), Mpy_32_16( a, FL2WORD16( -4.0f * 0.035f ) ), a_e, &tmp2 ), &Overflow );
     316             : #endif
     317             : 
     318       68415 :     IF( tmp <= 0 )
     319             :     {
     320           0 :         tmp = 0;
     321             : 
     322           0 :         FOR( k = 0; k < L_frame; k++ )
     323             :         {
     324           0 :             s_env[k] = 0;
     325           0 :             move16();
     326             :         }
     327             :     }
     328             :     ELSE
     329             :     {
     330       68415 :         tmp = Sqrt16( tmp, &tmp2 );
     331             :     }
     332             : 
     333       68415 :     tmp2 = BASOP_Util_Add_MantExp( negate( b ), b_e, tmp, tmp2, &scale );
     334       68415 :     scale = BASOP_Util_Divide1616_Scale( scale, round_fx( a ), &tmp );
     335             : #ifndef BASOP_NOGLOB
     336             :     scale = shl( scale, sub( sub( add( tmp, tmp2 ), a_e ), 1 ) ); /* Q15 */
     337             : #else
     338       68415 :     scale = shl_o( scale, sub( sub( add( tmp, tmp2 ), a_e ), 1 ), &Overflow ); /* Q15 */
     339             : #endif
     340             : 
     341             :     /* iscale = 1.0f / scale; */
     342       68415 :     iscale_e = 0;
     343       68415 :     move16();
     344       68415 :     iscale = Inv16( s_max( 1, scale ), &iscale_e );
     345             : 
     346       68415 :     lob = 0;
     347       68415 :     move16();
     348       68415 :     hib = 0;
     349       68415 :     move16();
     350             : 
     351       68415 :     max_iter = 2;
     352       68415 :     move16();
     353       68415 :     if ( low_complexity )
     354             :     {
     355       62973 :         max_iter = 1;
     356       62973 :         move16();
     357             :     }
     358             : 
     359      142272 :     FOR( iter = 0; iter < max_iter; iter++ )
     360             :     {
     361       73857 :         statesi = 0x7FFF;
     362       73857 :         move16();
     363       73857 :         bits = 0;
     364       73857 :         move16();
     365             : 
     366    15464837 :         FOR( k = 0; k < L_frame; k++ )
     367             :         {
     368    15390980 :             s = Mpy_32_16( ienv[k], scale ); /* Q16 */
     369             : 
     370    15390980 :             IF( L_sub( s, FL2WORD32_SCALE( 0.08f, 15 ) ) <= 0 )
     371             :             {
     372             :                 /* If s = 0.08, the expected bit-consumption is log2(1.0224). Below 0.08, the bit-consumption
     373             :                    estimate function becomes inaccurate, so use log2(1.0224) for all values below 0.08. */
     374             :                 /* round(state * 1.0224 * 32768) */
     375       61480 :                 statesi = mult_r( statesi, FL2WORD16_SCALE( 1.0224, 1 ) );
     376       61480 :                 tmp = norm_s( statesi );
     377       61480 :                 statesi = shl( statesi, tmp );
     378       61480 :                 bits = add( bits, sub( 1, tmp ) );
     379             :             }
     380    15329500 :             ELSE IF( L_sub( s, FL2WORD32_SCALE( 255.0, 15 ) ) <= 0 )
     381             :             {
     382             :                 /* a = 5.436564f * s + 0.15f + 0.035f * env[k] * iscale; */
     383    15329500 :                 L_tmp = L_shl( Mpy_32_16( s, FL2WORD16_SCALE( 5.436564f, 3 ) ), 3 );
     384    15329500 :                 L_tmp = L_add( L_tmp, FL2WORD32_SCALE( 0.15f, 15 ) );
     385    15329500 :                 L_tmp = L_add( L_tmp, L_shl( Mpy_32_16( env[k], mult_r( FL2WORD16( 0.035f ), iscale ) ), iscale_e ) );
     386             : 
     387    15329500 :                 tmp = norm_l( L_tmp );
     388             : #ifndef BASOP_NOGLOB
     389             :                 statesi = mult_r( statesi, round_fx( L_shl( L_tmp, tmp ) ) );
     390             : #else  /* BASOP_NOGLOB */
     391    15329500 :                 statesi = mult_r( statesi, round_fx_o( L_shl( L_tmp, tmp ), &Overflow ) );
     392             : #endif /* BASOP_NOGLOB */
     393    15329500 :                 bits = add( bits, sub( 15, tmp ) );
     394             : 
     395    15329500 :                 tmp = norm_s( statesi );
     396    15329500 :                 statesi = shl( statesi, tmp );
     397    15329500 :                 bits = sub( bits, tmp );
     398             :             }
     399             :             ELSE
     400             :             {
     401             :                 /* for large envelope values, s > 255, bit consumption is approx log2(2*e*s)
     402             :                  * further, we use round(log2(x)) = floor(log2(x)+0.5) = floor(log2(x*sqrt(2))) */
     403             :                 /* a = 5.436564f * s; */
     404           0 :                 L_tmp = Mpy_32_16( s, FL2WORD16_SCALE( 5.436564f * 1.4142f, 3 ) ); /* Q13 */
     405           0 :                 bits = add( bits, sub( 17, norm_l( L_tmp ) ) );
     406             :             }
     407             :         }
     408             : 
     409       73857 :         IF( sub( bits, target_bits ) <= 0 )
     410             :         {
     411             :             /* Bits leftover => scale is too small */
     412        6884 :             lob = scale;
     413        6884 :             move16();
     414        6884 :             lob_bits = bits;
     415        6884 :             move16();
     416             : 
     417        6884 :             IF( hib > 0 ) /* Bisection search */
     418             :             {
     419        4895 :                 adjust = div_s( sub( hib_bits, target_bits ), sub( hib_bits, lob_bits ) );
     420        4895 :                 scale = add( mult_r( sub( lob, hib ), adjust ), hib );
     421             :             }
     422             :             ELSE
     423             :             {
     424             :                 /* Initial scale adaptation */
     425             :                 /* adjust = 1.05f * target_bits / (float)bits;
     426             :                    scale *= adjust; */
     427        1989 :                 adjust = mult_r( FL2WORD16_SCALE( 1.05f, 1 ), target_bits );
     428        1989 :                 adjust = BASOP_Util_Divide1616_Scale( adjust, bits, &tmp );
     429        1989 :                 scale = shl( mult_r( scale, adjust ), add( 1, tmp ) );
     430             :             }
     431             :         }
     432             :         ELSE
     433             :         {
     434             :             /* Ran out of bits => scale is too large */
     435       66973 :             hib = scale;
     436       66973 :             move16();
     437       66973 :             hib_bits = bits;
     438       66973 :             move16();
     439             : 
     440       66973 :             IF( lob > 0 ) /* Bisection search */
     441             :             {
     442         207 :                 adjust = div_s( sub( hib_bits, target_bits ), sub( hib_bits, lob_bits ) );
     443         207 :                 scale = add( mult_r( sub( lob, hib ), adjust ), hib );
     444             :             }
     445             :             ELSE
     446             :             { /* Initial scale adaptation */
     447       66766 :                 test();
     448       66766 :                 IF( target_bits <= 0 || bits <= 0 ) /* safety check in case of bit errors */
     449             :                 {
     450           0 :                     adjust = 0;
     451           0 :                     move16();
     452             : 
     453           0 :                     FOR( k = 0; k < L_frame; k++ )
     454             :                     {
     455           0 :                         s_env[k] = 0;
     456           0 :                         move16();
     457             :                     }
     458             :                 }
     459             :                 ELSE
     460             :                 {
     461       66766 :                     adjust = div_s( mult_r( 31130 /*0.95f Q15*/, target_bits ), bits );
     462             :                 }
     463       66766 :                 scale = mult_r( scale, adjust );
     464             :             }
     465             :         }
     466       73857 :         iscale_e = 0;
     467       73857 :         move16();
     468             : 
     469       73857 :         IF( scale == 0 ) /* safety check in case of bit errors */
     470             :         {
     471           0 :             iscale = 0;
     472           0 :             move16();
     473             : 
     474           0 :             FOR( k = 0; k < L_frame; k++ )
     475             :             {
     476           0 :                 s_env[k] = 0;
     477           0 :                 move16();
     478             :             }
     479             :         }
     480             :         ELSE
     481             :         {
     482       73857 :             iscale = Inv16( scale, &iscale_e );
     483             :         }
     484             :     }
     485       68415 :     L_frame = L_spec_core;
     486       68415 :     move16();
     487             : 
     488       68415 :     tmp = getScaleFactor32( env, L_frame );
     489       68415 :     *s_env_e = sub( add( 15, iscale_e ), tmp );
     490       68415 :     move16();
     491             :     BASOP_SATURATE_WARNING_OFF;
     492             : #ifndef BASOP_NOGLOB
     493             :     a = L_shl( 1265000, sub( 15, *s_env_e ) );
     494             : #else  /* BASOP_NOGLOB */
     495       68415 :     a = L_shl_o( 1265000, sub( 15, *s_env_e ), &Overflow );
     496             : #endif /* BASOP_NOGLOB */
     497             :     BASOP_SATURATE_WARNING_ON;
     498             : 
     499    43142655 :     FOR( k = 0; k < L_frame; k++ )
     500             :     {
     501    43074240 :         L_tmp = Mpy_32_16( L_shl( env[k], tmp ), iscale );
     502    43074240 :         L_tmp = L_min( L_tmp, a );
     503    43074240 :         s_env[k] = round_fx( L_tmp );
     504    43074240 :         move16();
     505             :     }
     506             : 
     507       68415 :     return;
     508             : }
     509             : 
     510             : 
     511             : /*------------------------------------------------------------------------
     512             :  * Function: tcx_arith_render_envelope
     513             :  *
     514             :  * Calculate the envelope of the spectrum based on the LPC shape. The
     515             :  * envelope is used in a perceptual domain, whereby the LPC shape has to
     516             :  * be multiplied by the perceptual model.
     517             :  * Operations that are performed on the spectrum, which change the magnitude
     518             :  * expectation of lines, such as low-frequency emphasis, are included in the
     519             :  * envelope shape.
     520             :  * NOTE: This function must be bit-exact on all platforms such that encoder
     521             :  * and decoder remain synchronized.
     522             :  *-------------------------------------------------------------------------*/
     523             : 
     524       68415 : void tcx_arith_render_envelope(
     525             :     const Word16 A_ind[],     /* i  : LPC coefficients of signal envelope        */
     526             :     const Word16 L_frame,     /* i  : number of spectral lines                   */
     527             :     const Word16 L_spec,      /* i  : length of the coded spectrum               */
     528             :     const Word16 preemph_fac, /* i  : pre-emphasis factor                        */
     529             :     const Word16 gamma_w,     /* i  : A_ind -> weighted envelope factor          */
     530             :     const Word16 gamma_uw,    /* i  : A_ind -> non-weighted envelope factor      */
     531             :     Word32 env[]              /* o  : shaped signal envelope                     */
     532             : )
     533             : {
     534             :     Word16 k;
     535             :     Word16 tmpA[M + 2];
     536             :     Word16 signal_env[FDNS_NPTS], signal_env_e[FDNS_NPTS];
     537             :     Word16 gainlpc[FDNS_NPTS], gainlpc_e[FDNS_NPTS];
     538             : 
     539             :     /* Compute perceptual LPC envelope, transform it into freq.-domain gains */
     540       68415 :     basop_weight_a( A_ind, tmpA, gamma_w );
     541       68415 :     basop_lpc2mdct( tmpA, M, NULL, NULL, gainlpc, gainlpc_e );
     542             : 
     543             :     /* Add pre-emphasis tilt to LPC envelope, transform LPC into MDCT gains */
     544       68415 :     basop_weight_a_inv( A_ind, signal_env, gamma_uw );
     545       68415 :     basop_E_LPC_a_add_tilt( signal_env, tmpA, preemph_fac );
     546       68415 :     basop_lpc2mdct( tmpA, M + 1, signal_env, signal_env_e, NULL, NULL );
     547             : 
     548             :     /* Compute weighted signal envelope in perceptual domain */
     549     4446975 :     FOR( k = 0; k < FDNS_NPTS; k++ )
     550             :     {
     551     4378560 :         signal_env[k] = mult_r( signal_env[k], gainlpc[k] );
     552     4378560 :         move16();
     553     4378560 :         signal_env_e[k] = add( signal_env_e[k], gainlpc_e[k] );
     554     4378560 :         move16();
     555             :     }
     556             : 
     557             :     /* Adaptive low frequency emphasis */
     558    18006975 :     FOR( k = 0; k < L_frame; k++ )
     559             :     {
     560    17938560 :         env[k] = 0x10000;
     561    17938560 :         move32();
     562             :     }
     563             : 
     564       68415 :     basop_PsychAdaptLowFreqDeemph( env, gainlpc, gainlpc_e, NULL );
     565             : 
     566             :     /* Scale from FDNS_NPTS to L_frame and multiply LFE gains */
     567       68415 :     basop_mdct_noiseShaping_interp( env, L_frame, signal_env, signal_env_e );
     568             : 
     569    25204095 :     FOR( k = L_frame; k < L_spec; ++k )
     570             :     {
     571    25135680 :         env[k] = env[k - 1];
     572    25135680 :         move32();
     573             :     }
     574             : 
     575       68415 :     return;
     576             : }
     577             : 
     578             : #undef WMC_TOOL_SKIP

Generated by: LCOV version 1.14