LCOV - code coverage report
Current view: top level - lib_enc - arith_coder_enc_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main @ 43b7b28dcb1471ff5d355252c4b8f37ee7ecc268 Lines: 333 404 82.4 %
Date: 2025-11-02 02:02:47 Functions: 7 8 87.5 %

          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 "cnst.h"
       9             : #include "prot_fx.h"     /* Function prototypes                    */
      10             : #include "prot_fx_enc.h" /* Function prototypes                    */
      11             : #include "basop_util.h"
      12             : #include "rom_com.h"
      13             : 
      14             : 
      15             : /*-------------------------------------------------------------------*
      16             :  * Local constants
      17             :  *-------------------------------------------------------------------*/
      18             : 
      19             : #define kMaxNumHeapElems 10
      20             : #define LOG2_E           23637 /*1.44269504089f Q14*/
      21             : 
      22             : typedef struct HeapElem
      23             : {
      24             :     Word32 mScore; /* Sort key                    */
      25             :     Word16 mIndex; /* Original index              */
      26             : } HeapElem;
      27             : 
      28             : typedef struct Heap
      29             : {
      30             :     HeapElem mElem[2 * kMaxNumHeapElems + 1];
      31             :     Word16 mSize;
      32             : } Heap;
      33             : 
      34             : /*-------------------------------------------------------------------*
      35             :  * tcx_arith_estimate_scale()
      36             :  *
      37             :  *
      38             :  * Returns: estimated SQ scale    Q15-e
      39             :  *-------------------------------------------------------------------*/
      40       17444 : static Word16 tcx_arith_estimate_scale(
      41             :     const Word32 abs_spectrum[], /* i: absolute MDCT coefficients  Q31-e */
      42             :     const Word16 abs_spectrum_e, /* i: MDCT exponent               Q0 */
      43             :     const Word16 L_frame,        /* i: number of spectral lines    Q0 */
      44             :     const Word16 envelope[],     /* i: scaled envelope             Q15-e */
      45             :     const Word16 envelope_e,     /* i: scaled envelope exponent    Q0 */
      46             :     Word16 *scale_e              /* o: scale exponent              Q0 */
      47             : )
      48             : {
      49             :     Word16 scale, tmp, k, s, s1;
      50             :     Word32 L_tmp, accu;
      51             : 
      52             :     /* compute normalised standard deviation and determine approximate scale */
      53       17444 :     accu = L_deposit_l( 0 );
      54       17444 :     s = 30;
      55       17444 :     move16();
      56             : 
      57    11026404 :     FOR( k = 0; k < L_frame; k++ )
      58             :     {
      59             :         /* tmp = abs_spectrum[k] * envelope[k];
      60             :            scale += tmp * tmp; */
      61             : 
      62             :         /* normalize, multiply, square */
      63    11008960 :         s1 = 30;
      64    11008960 :         move16();
      65    11008960 :         if ( abs_spectrum[k] != 0 )
      66             :         {
      67     3639649 :             s1 = norm_l( abs_spectrum[k] );
      68             :         }
      69             : 
      70    11008960 :         tmp = mult_r( round_fx_sat( L_shl( abs_spectrum[k], s1 ) ), envelope[k] );
      71    11008960 :         L_tmp = L_mult0( tmp, tmp );
      72    11008960 :         tmp = sub( shl( s1, 1 ), 1 );
      73             : 
      74             :         /* adjust accu scaling */
      75    11008960 :         s1 = s;
      76    11008960 :         move16();
      77    11008960 :         if ( L_and( accu, 0x40000000 ) != 0 )
      78          20 :             s = sub( s, 1 );
      79    11008960 :         s = s_min( s, tmp );
      80             : 
      81    11008960 :         s1 = sub( s1, s );
      82    11008960 :         if ( s1 != 0 )
      83       55959 :             accu = L_shr( accu, s1 );
      84             : 
      85             :         /* scale and accumulate */
      86             :         BASOP_SATURATE_WARNING_OFF_EVS;
      87    11008960 :         accu = L_add_sat( accu, L_shr( L_tmp, sub( tmp, s ) ) );
      88             :         BASOP_SATURATE_WARNING_ON_EVS;
      89             :     }
      90       17444 :     s = sub( shl( add( abs_spectrum_e, envelope_e ), 1 ), s );
      91       17444 :     if ( accu == 0 )
      92           0 :         accu = L_deposit_l( 1 );
      93             : 
      94             :     /* scale = (float)sqrt((L_frame * 65536.0f*65536.0f*4.0f) / scale); */
      95       17444 :     scale = BASOP_Util_Divide3216_Scale( accu, shl( L_frame, 2 ), &tmp );
      96       17444 :     s = sub( add( s, tmp ), 15 );
      97       17444 :     scale = ISqrt16( scale, &s );
      98       17444 :     *scale_e = s;
      99             : 
     100       17444 :     return scale;
     101             : }
     102             : 
     103             : /*-------------------------------------------------------------------*
     104             :  * MinHeapify_i()
     105             :  *
     106             :  *
     107             :  *-------------------------------------------------------------------*/
     108      691619 : static void MinHeapify_i( Heap *H, Word16 i )
     109             : {
     110             :     Word16 left, right, largest;
     111             :     HeapElem T;
     112             : 
     113      691619 :     left = add( shl( i, 1 ), 1 );
     114      691619 :     right = add( left, 1 );
     115      691619 :     largest = i;
     116      691619 :     move16();
     117             : 
     118      691619 :     if ( LT_32( H->mElem[left].mScore, H->mElem[largest].mScore ) )
     119             :     {
     120      597700 :         largest = left;
     121      597700 :         move16();
     122             :     }
     123             : 
     124      691619 :     if ( LT_32( H->mElem[right].mScore, H->mElem[largest].mScore ) )
     125             :     {
     126      223371 :         largest = right;
     127      223371 :         move16();
     128             :     }
     129             : 
     130     2069167 :     WHILE( NE_16( largest, i ) )
     131             :     {
     132     1377548 :         T.mIndex = H->mElem[i].mIndex;
     133     1377548 :         move16();
     134     1377548 :         T.mScore = L_add( H->mElem[i].mScore, 0 );
     135             : 
     136     1377548 :         H->mElem[i].mIndex = H->mElem[largest].mIndex;
     137     1377548 :         move16();
     138     1377548 :         H->mElem[i].mScore = H->mElem[largest].mScore;
     139     1377548 :         move32();
     140             : 
     141     1377548 :         H->mElem[largest].mIndex = T.mIndex;
     142     1377548 :         move16();
     143     1377548 :         H->mElem[largest].mScore = T.mScore;
     144     1377548 :         move32();
     145             : 
     146     1377548 :         i = largest;
     147     1377548 :         move16();
     148             : 
     149     1377548 :         left = add( shl( i, 1 ), 1 );
     150     1377548 :         right = add( left, 1 );
     151             : 
     152     1377548 :         if ( LT_32( H->mElem[left].mScore, H->mElem[largest].mScore ) )
     153             :         {
     154      631745 :             largest = left;
     155      631745 :             move16();
     156             :         }
     157             : 
     158     1377548 :         if ( LT_32( H->mElem[right].mScore, H->mElem[largest].mScore ) )
     159             :         {
     160      293508 :             largest = right;
     161      293508 :             move16();
     162             :         }
     163             :     }
     164      691619 : }
     165             : /*-------------------------------------------------------------------*
     166             :  * tcx_arith_find_max_scale()
     167             :  *
     168             :  *
     169             :  *-------------------------------------------------------------------*/
     170       17444 : static Word16 tcx_arith_find_max_scale(                              /*  Q15-e */
     171             :                                         const Word32 abs_spectrum[], /* i: absolute MDCT coefficients    Q31-e */
     172             :                                         const Word16 abs_spectrum_e, /* i: MDCT exponent                 Q0 */
     173             :                                         const Word16 L_frame,        /* i: number of spectral lines      Q0 */
     174             :                                         const Word16 envelope[],     /* i: scaled envelope               Q15-e */
     175             :                                         const Word16 envelope_e,     /* i: scaled envelope exponent      Q0 */
     176             :                                         const Word16 exps[],         /* i: expfp(-(int)envelope[]/2)     Q15 */
     177             :                                         const Word16 deadzone,       /* i: deadzone (0.5f = no deadzone) Q15 */
     178             :                                         Word16 *scale_e              /* o: scale exponent                Q0 */
     179             : )
     180             : {
     181             :     Word16 i, k, q, scale, tmp, s;
     182             :     Word32 p, L_tmp;
     183       17444 :     Heap heap = { { { 0, 0 } }, 0 }; /* silence a compiler warning */
     184             :     Word16 tmpi1, tmpi2;
     185       17444 :     const Word32 limit = -325614240l /*-9.70406052784f Q25*/; /* = ln(1/16384): log of smallest allowed probability */
     186       17444 :     move32();
     187             :     /* Find the top most offending lines according to probability estimates */
     188      191884 :     FOR( i = 0; i < kMaxNumHeapElems; i++ )
     189             :     {
     190      174440 :         heap.mElem[i].mIndex = 0;
     191      174440 :         move16();
     192      174440 :         heap.mElem[i].mScore = L_deposit_l( 0 );
     193      174440 :         move32();
     194             :     }
     195             : 
     196       17444 :     tmp = add( shl( kMaxNumHeapElems, 1 ), 1 );
     197      209328 :     FOR( ; i < tmp; i++ )
     198             :     {
     199      191884 :         heap.mElem[i].mScore = L_deposit_h( 0x7FFF );
     200      191884 :         move32();
     201             :     }
     202             : 
     203    11026404 :     FOR( k = 0; k < L_frame; k++ )
     204             :     {
     205    11008960 :         p = Mpy_32_16_1( abs_spectrum[k], envelope[k] );
     206             : 
     207    11008960 :         IF( GT_32( p, heap.mElem[0].mScore ) )
     208             :         {
     209      691619 :             heap.mElem[0].mScore = p;
     210      691619 :             move32();
     211      691619 :             heap.mElem[0].mIndex = k;
     212      691619 :             move16();
     213      691619 :             MinHeapify_i( &heap, 0 );
     214             :         }
     215             :     }
     216             : 
     217             :     /* Make sure the scale is limited so that the offending lines don't cause probability underflow. */
     218             :     /* Also limit scale to avoiding saturation of the gain quantizer */
     219             :     /* scale = 1.0f/(float)sqrt(L_frame*0.5f); */
     220       17444 :     tmp = 15 - 1;
     221       17444 :     scale = ISqrt16( L_frame, &tmp );
     222       17444 :     move16();
     223       17444 :     *scale_e = tmp;
     224       17444 :     move16();
     225             : 
     226      191884 :     FOR( i = 0; i < kMaxNumHeapElems; i++ )
     227             :     {
     228      174440 :         k = heap.mElem[i].mIndex;
     229      174440 :         move16();
     230             : 
     231             :         /* Get approximate maximum allowed magnitude */
     232             :         /* q = (int)ceil(((limit - log(1.0f - (exps[k]/65536.0) * (exps[k]/65536.0))) / (-(int)envelope[k]/2/65536.0) - 1) / 2.0f); */
     233      174440 :         L_tmp = L_sub( 0x7FFFFFFF, L_mult( exps[k], exps[k] ) );
     234      174440 :         L_tmp = Mpy_32_16_1( BASOP_Util_Log2( L_tmp ), 22713 ); /* Q25; 22713 -> 1/log2(e) */
     235      174440 :         L_tmp = L_sub( limit, L_tmp );
     236      174440 :         tmp = negate( BASOP_Util_Divide3216_Scale( L_tmp, envelope[k], &s ) );
     237      174440 :         s = sub( add( s, 6 ), sub( envelope_e, 1 ) );
     238      174440 :         L_tmp = L_shl( L_deposit_h( tmp ), sub( s, 15 + 1 ) ); /* Q16 */
     239      174440 :         L_tmp = L_sub( L_tmp, 0x8000 );
     240      174440 :         q = extract_h( L_add( L_tmp, 0xFFFF ) ); /* ceil */
     241             : 
     242             :         /* Refinement: get the exact q */
     243      174440 :         powfp_odd2( exps[k], q, &tmpi1, &tmpi2 );
     244             : 
     245      174440 :         IF( GE_16( sub( tmpi1, tmpi2 ), 2 ) ) /* q may be too low */
     246             :         {
     247      174390 :             powfp_odd2( exps[k], add( q, 1 ), &tmpi1, &tmpi2 );
     248             : 
     249      197524 :             WHILE( GE_16( sub( tmpi1, tmpi2 ), 2 ) )
     250             :             {
     251       23134 :                 q = add( q, 1 );
     252       23134 :                 powfp_odd2( exps[k], add( q, 1 ), &tmpi1, &tmpi2 );
     253             :             }
     254             :         }
     255             :         ELSE /* q is too high */
     256             :         {
     257          50 :             q = sub( q, 1 );
     258          50 :             powfp_odd2( exps[k], q, &tmpi1, &tmpi2 );
     259             : 
     260          50 :             WHILE( LT_16( sub( tmpi1, tmpi2 ), 2 ) )
     261             :             {
     262           0 :                 q = sub( q, 1 );
     263           0 :                 powfp_odd2( exps[k], q, &tmpi1, &tmpi2 );
     264             :             }
     265             :         }
     266             : 
     267             :         /* Find the largest scale so that the quantized magnitude is at most q */
     268             :         /* p = (q+0.99f-deadzone)/(abs_spectrum[k] + 0.000001f); */
     269      174440 :         L_tmp = L_add( L_deposit_h( q ), L_mult( sub( 32440 /*0.99f Q15*/, deadzone ), 1 ) ); /* Q16 */
     270      174440 :         tmp = BASOP_Util_Divide3232_Scale( L_tmp, L_add( abs_spectrum[k], 1 ), &s );
     271      174440 :         s = sub( add( s, 15 ), abs_spectrum_e );
     272             : 
     273      174440 :         k = norm_s( tmp );
     274      174440 :         tmp = shl( tmp, k );
     275      174440 :         s = sub( s, k );
     276             : 
     277             :         /* assert((int)(abs_spectrum[k] * p + deadzone) <= q); */
     278             : 
     279             :         /* scale = min(scale, p); */
     280      174440 :         IF( compMantExp16Unorm( tmp, s, scale, *scale_e ) < 0 )
     281             :         {
     282       54866 :             scale = tmp;
     283       54866 :             move16();
     284       54866 :             *scale_e = s;
     285       54866 :             move16();
     286             :         }
     287             :     }
     288             : 
     289             : 
     290       17444 :     return scale;
     291             : }
     292             : /*-------------------------------------------------------------------*
     293             :  * tcx_arith_find_kMax()
     294             :  *
     295             :  *
     296             :  * Returns: index of highest freq. nonzero line (-1 if all zeros)
     297             :  *-------------------------------------------------------------------*/
     298      285901 : static Word16 tcx_arith_find_kMax(
     299             :     const Word32 abs_spectrum[], /* i: absolute MDCT coefficients    Q31-e */
     300             :     const Word16 abs_spectrum_e, /* i: MDCT exponent                 Q0 */
     301             :     const Word16 L_frame,        /* i: number of spectral lines      Q0 */
     302             :     const Word16 scale,          /* i: scalar quantizer scale        Q15-e */
     303             :     const Word16 scale_e,        /* i: scale exponent                Q0 */
     304             :     const Word16 deadzone,       /* i: deadzone (0.5f = no deadzone) Q15 */
     305             :     const Word8 deadzone_flags[] /* i: line-wise deadzone control    */
     306             : )
     307             : {
     308             :     Word16 kMax;
     309             :     Word32 tmp[2];
     310             : 
     311             : 
     312      285901 :     move32();
     313      285901 :     move32();
     314      285901 :     tmp[0] = L_shr( L_mac( 0x7FFFFFFF, deadzone, (Word16) 0x8000 ), abs_spectrum_e ); /* 1.0f - deadzone scaled to MDCT exponent */
     315      285901 :     tmp[1] = L_shr( 0x7FFFFFFF, abs_spectrum_e );                                     /* 1.0f scaled to MDCT exponent */
     316             : 
     317   144603573 :     FOR( kMax = sub( L_frame, 1 ); kMax >= 0; kMax-- )
     318             :     {
     319   144602583 :         IF( GE_32( L_shl( Mpy_32_16_1( abs_spectrum[kMax], scale ), scale_e ), tmp[deadzone_flags[kMax]] ) )
     320             :         {
     321      284911 :             BREAK;
     322             :         }
     323             :     }
     324             : 
     325             : 
     326      285901 :     return kMax;
     327             : }
     328             : 
     329             : /*-------------------------------------------------------------------*
     330             :  * tcx_arith_rateloop()
     331             :  *
     332             :  *
     333             :  * Returns: best scale  Q15-e
     334             :  *-------------------------------------------------------------------*/
     335       17444 : static Word16 tcx_arith_rateloop(
     336             :     const Word32 abs_spectrum[],  /* i: absolute MDCT coefficients     Q31-e */
     337             :     const Word16 abs_spectrum_e,  /* i: MDCT exponent                  Q0 */
     338             :     const Word16 L_frame,         /* i: number of spectral lines       Q0 */
     339             :     const Word16 envelope[],      /* i: scaled envelope                Q15-e */
     340             :     const Word16 envelope_e,      /* i: scaled envelope exponent       Q0 */
     341             :     const Word16 exps[],          /* i: expfp(-(int)envelope[]/2)      Q15 */
     342             :     const Word16 target_bits,     /* i: target bit budget              Q0 */
     343             :     const Word16 deadzone,        /* i: deadzone (0.5f = no deadzone)  Q15 */
     344             :     const Word8 deadzone_flags[], /* i: line-wise deadzone control     Q0 */
     345             :     Word16 *target_bits_fac,      /* i/o: scale estimator compensation Q14 */
     346             :     Word16 *scale_e               /* o: scale exponent                 Q0 */
     347             : )
     348             : {
     349             :     Word16 k, kMax, q;
     350             :     Word16 s, adjust;
     351             :     Word16 fixed_bits[2][N_MAX_ARI];
     352             :     Word32 max_complexity;
     353             :     Word16 iter;       /* rate loop iteration counter               */
     354             :     Word16 scale;      /* SQ scale factor to try next               */
     355             :     Word16 scale_best; /* best SQ scale factor                      */
     356             :     Word16 scale_max;  /* maximum allowable scale factor            */
     357             :     Word16 lob;        /* lower bound of SQ scale factor            */
     358             :     Word16 hib;        /* upper bound of SQ scale factor            */
     359             :     Word16 flag;       /* 1:bit surplus, -1:bit deficit, 0:unknown  */
     360             :     Word32 complexity; /* cumulative rate loop complexity           */
     361             :     Word32 bits;       /* number of bits (approximate)           Q9 */
     362             :     Word32 L_tmp;
     363             :     Word16 tmp, tmp3;
     364             :     Word32 tmp2;
     365             : 
     366       17444 :     scale = tcx_arith_estimate_scale( abs_spectrum, abs_spectrum_e, L_frame, envelope, envelope_e, &tmp );
     367       17444 :     scale = mult_r( scale, *target_bits_fac );
     368       17444 :     tmp = add( tmp, 1 );
     369             : 
     370       17444 :     scale_max = tcx_arith_find_max_scale( abs_spectrum, abs_spectrum_e, L_frame, envelope, envelope_e, exps, deadzone, scale_e );
     371             : 
     372       17444 :     scale = shl_sat( scale, sub( tmp, *scale_e ) );
     373       17444 :     scale = s_min( scale, scale_max );
     374             : 
     375       17444 :     scale_best = scale;
     376       17444 :     move16();
     377       17444 :     lob = 0;
     378       17444 :     move16();
     379       17444 :     hib = 0;
     380       17444 :     move16();
     381       17444 :     flag = 0;
     382       17444 :     move16();
     383       17444 :     complexity = L_deposit_l( 0 );
     384       17444 :     bits = L_deposit_l( 0 );
     385       17444 :     iter = 0;
     386       17444 :     move16();
     387             : 
     388       17444 :     max_complexity = L_mult0( 96, L_frame );
     389             : 
     390             :     /* Precalculate fixed bit costs */
     391    11026404 :     FOR( k = 0; k < L_frame; k++ )
     392             :     {
     393             :         /* fixed_bits[0][k] = -log2f(1 - exps[k] / 65536.0f); */
     394    11008960 :         L_tmp = L_mac( 0x7FFFFFFF, exps[k], (Word16) 0x8000 ); /* Q31 */
     395    11008960 :         L_tmp = L_negate( BASOP_Util_Log2( L_tmp ) );          /* Q25 */
     396    11008960 :         fixed_bits[0][k] = round_fx( L_tmp );                  /* Q9 */
     397    11008960 :         move16();
     398             :         /* fixed_bits[1][k] = 1 - s*0.5f*LOG2_E - log2f(1 - (exps[k]/65536.0f) * (exps[k]/65536.0f)); */
     399    11008960 :         L_tmp = L_msu( 0x7FFFFFFF, exps[k], exps[k] ); /* Q31 */
     400    11008960 :         L_tmp = BASOP_Util_Log2( L_tmp );              /* Q25 */
     401    11008960 :         L_tmp = L_sub( 1 << 25, L_tmp );
     402    11008960 :         L_tmp = L_sub( L_tmp, L_shl( L_mult0( mult_r( envelope[k], LOG2_E ), 1 << 10 ), envelope_e ) );
     403    11008960 :         fixed_bits[1][k] = round_fx( L_tmp ); /* Q9 */
     404    11008960 :         move16();
     405             :     }
     406             : 
     407       17444 :     tmp2 = L_msu0( L_sub( max_complexity, 48 ), L_frame, 11 );
     408      285901 :     WHILE( LT_32( complexity, tmp2 ) )
     409             :     {
     410      268457 :         kMax = tcx_arith_find_kMax( abs_spectrum, abs_spectrum_e, L_frame, scale, *scale_e, deadzone, deadzone_flags );
     411             : 
     412      268457 :         complexity = L_mac0( L_mac0( L_add( complexity, 16 + 2 ), sub( L_frame, kMax ), 5 ), kMax, 2 );
     413             : 
     414      268457 :         bits = /*estimator_undershoot * kMax +*/ L_deposit_l( 1 << 9 ); /* Q9 */
     415             : 
     416      268457 :         L_tmp = L_mult( deadzone, 1 ); /* Q16 */
     417      268457 :         tmp = add( sub( abs_spectrum_e, 15 ), *scale_e );
     418      268457 :         tmp3 = add( 2 + 9, envelope_e );
     419    34805889 :         FOR( k = 0; k <= kMax; k++ )
     420             :         {
     421    34537432 :             q = extract_h( L_add( L_shl( Mpy_32_16_1( abs_spectrum[k], scale ), tmp ), L_tmp ) );
     422    34537432 :             bits = L_mac0( bits, fixed_bits[s_min( 1, q )][k], 1 ); /* Q9 */
     423    34537432 :             bits = L_mac0( bits, round_fx( L_shl( L_mult0( mult_r( envelope[k], LOG2_E ), q ), tmp3 ) ), 1 );
     424             :         }
     425      268457 :         complexity = L_mac0( L_add( complexity, 32 ), 6, kMax );
     426             : 
     427      268457 :         IF( iter == 0 ) /* First rate loop iteration */
     428             :         {
     429       17444 :             IF( LT_16( scale, scale_max ) ) /* Only update in non-degenerate case */
     430             :             {
     431             :                 /* Update estimator temporal compensation factor */
     432        4920 :                 tmp = BASOP_Util_Divide3232_Scale( L_mult0( target_bits, 1 << 9 ), bits, &s );
     433        4920 :                 tmp = shl_sat( mult_r( *target_bits_fac, tmp ), s );
     434        4920 :                 tmp = s_min( tmp, 20480 /*1.25f Q14*/ );
     435        4920 :                 tmp = s_max( tmp, 12288 /*0.75f Q14*/ );
     436        4920 :                 *target_bits_fac = tmp;
     437        4920 :                 move16();
     438             :             }
     439             :         }
     440             : 
     441      268457 :         IF( LE_32( bits, L_mult0( target_bits, 1 << 9 ) ) ) /* Bits leftover => scale is too small */
     442             :         {
     443      158636 :             test();
     444      158636 :             IF( flag <= 0 || GE_16( scale, scale_best ) )
     445             :             {
     446      158636 :                 scale_best = scale;
     447      158636 :                 move16();
     448      158636 :                 flag = 1;
     449      158636 :                 move16();
     450             :             }
     451             : 
     452      158636 :             lob = scale;
     453      158636 :             move16();
     454             : 
     455      158636 :             IF( hib > 0 ) /* Bisection search */
     456             :             {
     457      122097 :                 scale = add( shr( lob, 1 ), shr( hib, 1 ) );
     458             :             }
     459             :             ELSE /* Initial scale adaptation */
     460             :             {
     461             :                 /* adjust = 1.25f * target_bits / (float)bits; */
     462       36539 :                 tmp = BASOP_Util_Divide3232_Scale( L_mult0( target_bits, 0x280 ), bits, &s );
     463       36539 :                 adjust = shl_sat( tmp, sub( s, 1 ) ); /* Q14 */
     464       36539 :                 scale = shl_sat( mult_r( scale, adjust ), 1 );
     465       36539 :                 scale = s_min( scale, scale_max );
     466             :             }
     467             :         }
     468             :         ELSE /* Ran out of bits => scale is too large */
     469             :         {
     470      109821 :             hib = scale;
     471      109821 :             move16();
     472             : 
     473      109821 :             IF( lob > 0 ) /* Bisection search */
     474             :             {
     475       93991 :                 scale = add( shr( lob, 1 ), shr( hib, 1 ) );
     476             :             }
     477             :             ELSE
     478             :             { /* Initial scale adaptation */
     479             :                 /* adjust = 0.8f * target_bits / (float)bits; */
     480       15830 :                 tmp = BASOP_Util_Divide3232_Scale( L_mult0( target_bits, 0x19A ), bits, &s );
     481       15830 :                 adjust = shl( tmp, s ); /* Q15 */
     482       15830 :                 adjust = s_max( adjust, 16384 /*0.5f Q15*/ );
     483       15830 :                 scale = mult_r( scale, adjust );
     484             :             }
     485             : 
     486      109821 :             IF( flag <= 0 )
     487             :             {
     488       15830 :                 scale_best = scale;
     489       15830 :                 move16();
     490       15830 :                 flag = 0;
     491       15830 :                 move16();
     492             :             }
     493             :         }
     494      268457 :         iter = add( iter, 1 );
     495             :     }
     496             : 
     497             : 
     498       17444 :     return scale_best;
     499             : }
     500             : /*-------------------------------------------------------------------*
     501             :  * tcx_arith_encode()
     502             :  *
     503             :  *
     504             :  * Returns: number of bits consumed
     505             :  *-------------------------------------------------------------------*/
     506       17444 : static Word16 tcx_arith_encode(
     507             :     Word16 q_abs_spectrum[], /* i/o: scalar quantized absolute spectrum      Q0 */
     508             :     const Word16 signs[],    /* i: signs                                        */
     509             :     const Word16 kMax,       /* i: number of nonzero spectral lines to code  Q0 */
     510             :     Word16 L_frame,          /* i: nominal number of spectral lines          Q0 */
     511             :     const Word16 exps[],     /* i: expfp(-(int)envelope[]/2)                 Q15 */
     512             :     Word16 target_bits,      /* i: target bit budget                         Q0 */
     513             :     Word16 prm[]             /* o: bit-stream                                Q0 */
     514             : )
     515             : {
     516             :     TastatEnc as, as_lastgood;
     517             :     Word16 bp, bp_lastgood;
     518             :     Word16 k;
     519             :     Word16 kEncoded;
     520             :     Word16 tmpi1, tmpi2;
     521             : 
     522             : 
     523             :     /* Final coding */
     524       17444 :     ari_start_encoding_14bits_fx( &as );
     525       17444 :     ari_copy_states_fx( &as, &as_lastgood );
     526       17444 :     bp = 0;
     527       17444 :     move16();
     528       17444 :     bp_lastgood = 0;
     529       17444 :     move16();
     530       17444 :     kEncoded = kMax;
     531       17444 :     move16();
     532             : 
     533     2228990 :     FOR( k = 0; k <= kMax; k++ )
     534             :     {
     535     2211616 :         IF( q_abs_spectrum[k] == 0 )
     536             :         {
     537     1706560 :             assert( exps[k] >= 2 );
     538     1706560 :             bp = ari_encode_14bits_range_fx( prm, bp, target_bits, &as, shr( exps[k], 1 ), 16384 );
     539             :         }
     540             :         ELSE /* q_abs_spectrum[k] != 0 */
     541             :         {
     542      505056 :             powfp_odd2( exps[k], q_abs_spectrum[k], &tmpi1, &tmpi2 );
     543             : 
     544      505056 :             WHILE( LT_16( tmpi1, add( tmpi2, 2 ) ) )
     545             :             {
     546           0 :                 q_abs_spectrum[k] = sub( q_abs_spectrum[k], 1 );
     547           0 :                 move16();
     548           0 :                 powfp_odd2( exps[k], q_abs_spectrum[k], &tmpi1, &tmpi2 );
     549             :             }
     550             : 
     551      505056 :             bp = ari_encode_14bits_range_fx( prm, bp, target_bits, &as, shr( tmpi2, 1 ), shr( tmpi1, 1 ) );
     552      505056 :             bp = ari_encode_14bits_sign_fx( prm, bp, target_bits, &as, signs[k] );
     553             :         }
     554             :         /* Check bit budget status */
     555     2211616 :         IF( ari_encode_overflow_fx( &as ) ) /* no bits left */
     556             :         {
     557             :             /* printf("\noverflow at %d\n\n", k); */
     558             : 
     559          70 :             IF( GT_16( q_abs_spectrum[k], 1 ) ) /* Lower magnitude is still > 0 */
     560             :             {
     561             :                 /* Restore state */
     562          10 :                 ari_copy_states_fx( &as_lastgood, &as );
     563          10 :                 bp = bp_lastgood;
     564          10 :                 move16();
     565             : 
     566             :                 /* Quantize to lower magnitude */
     567          10 :                 q_abs_spectrum[k] = sub( q_abs_spectrum[k], 1 );
     568          10 :                 move16();
     569             : 
     570             :                 /* Retry encoding */
     571          10 :                 powfp_odd2( exps[k], q_abs_spectrum[k], &tmpi1, &tmpi2 );
     572             : 
     573          10 :                 bp = ari_encode_14bits_range_fx( prm, bp, target_bits, &as, shr( tmpi2, 1 ), shr( tmpi1, 1 ) );
     574          10 :                 bp = ari_encode_14bits_sign_fx( prm, bp, target_bits, &as, signs[k] );
     575             : 
     576          10 :                 IF( !ari_encode_overflow_fx( &as ) ) /* Success */
     577             :                 {
     578          10 :                     ari_copy_states_fx( &as, &as_lastgood );
     579          10 :                     bp_lastgood = bp;
     580          10 :                     move16();
     581          10 :                     kEncoded = k;
     582          10 :                     move16();
     583             : 
     584          10 :                     set16_fx( q_abs_spectrum + k + 1, 0, sub( kMax, k ) );
     585          10 :                     BREAK;
     586             :                 }
     587             :             }
     588          60 :             ari_copy_states_fx( &as_lastgood, &as );
     589          60 :             bp = bp_lastgood;
     590          60 :             move16();
     591          60 :             kEncoded = sub( k, 1 );
     592             : 
     593          60 :             set16_fx( q_abs_spectrum + k, 0, sub( kMax, kEncoded ) );
     594          60 :             BREAK;
     595             :         }
     596             :         ELSE
     597             :         {
     598     2211546 :             ari_copy_states_fx( &as, &as_lastgood );
     599     2211546 :             bp_lastgood = bp;
     600     2211546 :             move16();
     601             :         }
     602             :     }
     603             : 
     604             :     /* Send zeros until L_frame */
     605       17444 :     tmpi1 = add( kEncoded, 1 );
     606       17444 :     kEncoded = sub( L_frame, 1 );
     607     8641595 :     FOR( k = tmpi1; k < L_frame; k++ )
     608             :     {
     609     8624580 :         assert( exps[k] >= 1 );
     610             : 
     611     8624580 :         bp = ari_encode_14bits_range_fx( prm, bp, target_bits, &as, shr( exps[k], 1 ), 16384 );
     612             :         /* Check bit budget status */
     613     8624580 :         IF( ari_encode_overflow_fx( &as ) ) /* no bits left */
     614             :         {
     615         429 :             ari_copy_states_fx( &as_lastgood, &as );
     616         429 :             bp = bp_lastgood;
     617         429 :             move16();
     618         429 :             kEncoded = sub( k, 1 );
     619         429 :             BREAK;
     620             :         }
     621             :         ELSE
     622             :         {
     623     8624151 :             ari_copy_states_fx( &as, &as_lastgood );
     624     8624151 :             bp_lastgood = bp;
     625     8624151 :             move16();
     626             :         }
     627             :     }
     628             : 
     629       17444 :     IF( EQ_16( kEncoded, sub( L_frame, 1 ) ) ) /* RESQ bits possibly available */
     630             :     {
     631             :         /* Limit target bits to actually needed bits */
     632       17015 :         target_bits = add( add( bp, 16 ), extract_l( as.value ) );
     633             :     }
     634       17444 :     return ari_done_cbr_encoding_14bits_fx( prm, bp, target_bits, &as );
     635             : }
     636             : /*-------------------------------------------------------------------*
     637             :  * tcx_arith_encode_envelope_fx()
     638             :  *
     639             :  *
     640             :  *-------------------------------------------------------------------*/
     641           0 : void tcx_arith_encode_envelope_fx(
     642             :     Word32 spectrum[],          /* i/o: MDCT coefficients           Q31-e */
     643             :     Word16 *spectrum_e,         /* i/o: MDCT exponent               Q0 */
     644             :     Word16 signs[],             /* o: signs (spectrum[.]<0)         Q0 */
     645             :     const Word16 L_frame,       /* i: frame or MDCT length          Q0 */
     646             :     const Word16 L_spec,        /* i: frame or MDCT length          Q0 */
     647             :     Encoder_State *st,          /* i/o: coder state                 */
     648             :     const Word16 A_ind[],       /* i: quantised LPC coefficients    Q12 */
     649             :     Word16 target_bits,         /* i: number of available bits      Q0 */
     650             :     Word16 prm[],               /* o: bitstream parameters          Q0 */
     651             :     const Word8 use_hm,         /* i: use HM in current frame?      */
     652             :     Word16 prm_hm[],            /* o: HM parameter area             Q0 */
     653             :     const Word16 tcxltp_pitch,  /* i: TCX LTP pitch in FD, -1 if n/a  Q0*/
     654             :     Word16 *arith_bits,         /* o: bits used for ari. coding     Q0 */
     655             :     Word16 *signaling_bits,     /* o: bits used for signaling       Q0 */
     656             :     Word16 *nf_seed,            /* o: noise filling seed            Q0 */
     657             :     const Word16 low_complexity /* i: low-complexity flag           Q0 */
     658             : )
     659             : {
     660             :     Word32 env[N_MAX_ARI]; /* unscaled envelope (Q16) */
     661             :     Word16 *envelope;      /* scaled envelope (Q15-e) */
     662             :     Word16 envelope_e;
     663             :     Word16 exponents[N_MAX_ARI]; /* Q15 */
     664             :     Word16 L_spec_core;
     665             :     Word16 *q_spectrum;
     666             :     TCX_CONFIG_HANDLE hTcxCfg;
     667             :     Word16 scale, scale_e;
     668             :     Word16 k, kMax;
     669             :     Word16 deadzone;
     670             :     const Word8 *deadzone_flags;
     671             :     Word16 gamma_w, gamma_uw;
     672             :     Word16 hm_bits;
     673             :     Word32 L_tmp;
     674             :     Word64 W_tmp2;
     675             :     Word16 tmp;
     676           0 :     TCX_ENC_HANDLE hTcxEnc = st->hTcxEnc;
     677             : 
     678           0 :     assert( L_spec <= N_MAX_ARI );
     679             : 
     680           0 :     hTcxCfg = st->hTcxCfg;
     681           0 :     deadzone = hTcxCfg->sq_rounding;
     682           0 :     move16();
     683           0 :     deadzone_flags = hTcxEnc->memQuantZeros;
     684           0 :     *signaling_bits = 0;
     685           0 :     move16();
     686             : 
     687           0 :     assert( st->enableTcxLpc );
     688           0 :     gamma_w = 32767 /*1.0f Q15*/;
     689           0 :     move16();
     690           0 :     gamma_uw = st->inv_gamma;
     691           0 :     move16();
     692             : 
     693           0 :     tcx_arith_render_envelope( A_ind, L_frame, L_spec, hTcxCfg->preemph_fac, gamma_w, gamma_uw, env );
     694             : 
     695           0 :     FOR( k = 0; k < L_spec; k++ )
     696             :     {
     697           0 :         signs[k] = extract_l( L_lshr( spectrum[k], 31 ) );
     698           0 :         move16();
     699           0 :         if ( spectrum[k] < 0 )
     700             :         {
     701           0 :             spectrum[k] = L_abs( spectrum[k] );
     702           0 :             move32();
     703             :         }
     704             :     }
     705             : 
     706           0 :     IF( use_hm != 0 )
     707             :     {
     708           0 :         tcx_hm_analyse_fx( spectrum, spectrum_e, L_spec, env, target_bits, hTcxCfg->coder_type, prm_hm, tcxltp_pitch, hTcxEnc->tcxltp_gain, &hm_bits );
     709             : 
     710           0 :         target_bits = sub( target_bits, hm_bits );
     711           0 :         *signaling_bits = add( *signaling_bits, hm_bits );
     712           0 :         move16();
     713             :     }
     714             :     ELSE
     715             :     {
     716           0 :         prm_hm[0] = 0; /* just to be sure */
     717           0 :         move16();
     718           0 :         hm_bits = 0;
     719           0 :         move16();
     720             :     }
     721             : 
     722           0 :     L_spec_core = L_spec;
     723           0 :     move16();
     724           0 :     if ( st->igf )
     725             :     {
     726           0 :         L_spec_core = s_min( L_spec_core, st->hIGFEnc->infoStartLine );
     727             :     }
     728           0 :     envelope = (Word16 *) env;
     729             : 
     730           0 :     tcx_arith_scale_envelope( L_spec, L_spec_core, env, target_bits, low_complexity, envelope, &envelope_e );
     731             : 
     732           0 :     tmp = sub( envelope_e, 1 + 15 );
     733           0 :     FOR( k = 0; k < L_spec; k++ )
     734             :     {
     735           0 :         exponents[k] = round_fx( expfp( envelope[k], tmp ) );
     736           0 :         move16();
     737             :     }
     738             : 
     739           0 :     scale = tcx_arith_rateloop( spectrum, *spectrum_e, L_spec, envelope, envelope_e, exponents, target_bits, deadzone, deadzone_flags, &( hTcxEnc->tcx_target_bits_fac ), &scale_e );
     740             : 
     741             :     /* Final quantization */
     742           0 :     kMax = tcx_arith_find_kMax( spectrum, *spectrum_e, L_spec, scale, scale_e, deadzone, deadzone_flags );
     743             : 
     744           0 :     q_spectrum = (Word16 *) env; /* Reuse buffer */
     745             : 
     746           0 :     L_tmp = L_mult( deadzone, 1 ); /* Q16 */
     747           0 :     tmp = add( sub( *spectrum_e, 15 ), scale_e );
     748           0 :     FOR( k = 0; k <= kMax; k++ )
     749             :     {
     750             :         /* quantise using dead-zone */
     751           0 :         q_spectrum[k] = extract_h( L_add( L_shl( Mpy_32_16_1( spectrum[k], scale ), tmp ), L_tmp ) );
     752           0 :         move16();
     753             :     }
     754             : 
     755             :     /* Final encoding */
     756           0 :     *arith_bits = tcx_arith_encode( q_spectrum, signs, kMax, L_spec, exponents, target_bits, prm );
     757           0 :     move16();
     758             : 
     759             :     /* Multiply back the signs */
     760           0 :     W_tmp2 = 0;
     761           0 :     FOR( k = 0; k <= kMax; k++ )
     762             :     {
     763           0 :         W_tmp2 = W_mac_16_16( W_tmp2, q_spectrum[k], k );
     764             : 
     765           0 :         if ( signs[k] != 0 )
     766           0 :             L_tmp = L_mult( q_spectrum[k], -( 1 << ( 30 - SPEC_EXP_DEC ) ) );
     767           0 :         if ( signs[k] == 0 )
     768           0 :             L_tmp = L_mult( q_spectrum[k], 1 << ( 30 - SPEC_EXP_DEC ) );
     769           0 :         spectrum[k] = L_tmp;
     770           0 :         move32();
     771             :     }
     772           0 :     *spectrum_e = SPEC_EXP_DEC;
     773           0 :     move16();
     774           0 :     set32_fx( spectrum + k, 0, sub( s_max( L_frame, L_spec ), k ) );
     775             : 
     776             :     /* noise filling seed */
     777           0 :     *nf_seed = extract_l( W_extract_l( W_tmp2 ) );
     778           0 :     move16();
     779           0 : }
     780             : 
     781       17444 : void tcx_arith_encode_envelope_ivas_fx(
     782             :     Word32 spectrum[],          /* i/o: MDCT coefficients           Q31-e */
     783             :     Word16 *spectrum_e,         /* i/o: MDCT exponent               Q0 */
     784             :     Word16 signs[],             /* o: signs (spectrum[.]<0)         Q0 */
     785             :     const Word16 L_frame,       /* i: frame or MDCT length          Q0 */
     786             :     const Word16 L_spec,        /* i: frame or MDCT length          Q0 */
     787             :     Encoder_State *st,          /* i/o: coder state                 */
     788             :     const Word16 A_ind[],       /* i: quantised LPC coefficients    Q12 */
     789             :     Word16 target_bits,         /* i: number of available bits      Q0 */
     790             :     Word16 prm[],               /* o: bitstream parameters          Q0 */
     791             :     const Word8 use_hm,         /* i: use HM in current frame?      */
     792             :     Word16 prm_hm[],            /* o: HM parameter area             Q0 */
     793             :     const Word16 tcxltp_pitch,  /* i: TCX LTP pitch in FD, -1 if n/a  Q0*/
     794             :     Word16 *arith_bits,         /* o: bits used for ari. coding     Q0 */
     795             :     Word16 *signaling_bits,     /* o: bits used for signaling       Q0 */
     796             :     const Word16 low_complexity /* i: low-complexity flag           Q0 */
     797             : )
     798             : {
     799             :     Word32 env[N_MAX_ARI]; /* unscaled envelope (Q16) */
     800             :     Word16 *envelope;      /* scaled envelope (Q15-e) */
     801             :     Word16 envelope_e;
     802             :     Word16 exponents[N_MAX_ARI]; /* Q15 */
     803             :     Word16 L_spec_core;
     804             :     Word16 *q_spectrum;
     805             :     TCX_CONFIG_HANDLE hTcxCfg;
     806             :     Word16 scale, scale_e;
     807             :     Word16 k, kMax;
     808             :     Word16 deadzone;
     809             :     const Word8 *deadzone_flags;
     810             :     Word16 gamma_w, gamma_uw;
     811             :     Word16 hm_bits;
     812             :     Word32 L_tmp;
     813             :     Word16 tmp;
     814       17444 :     TCX_ENC_HANDLE hTcxEnc = st->hTcxEnc;
     815             : 
     816       17444 :     assert( L_spec <= N_MAX_ARI );
     817             : 
     818       17444 :     hTcxCfg = st->hTcxCfg;
     819       17444 :     deadzone = hTcxCfg->sq_rounding;
     820       17444 :     move16();
     821       17444 :     deadzone_flags = hTcxEnc->memQuantZeros;
     822       17444 :     *signaling_bits = 0;
     823       17444 :     move16();
     824             : 
     825       17444 :     assert( st->enableTcxLpc );
     826       17444 :     gamma_w = 32767 /*1.0f Q15*/;
     827       17444 :     move16();
     828       17444 :     gamma_uw = st->inv_gamma;
     829       17444 :     move16();
     830             : 
     831       17444 :     tcx_arith_render_envelope( A_ind, L_frame, L_spec, hTcxCfg->preemph_fac, gamma_w, gamma_uw, env );
     832             : 
     833    11026404 :     FOR( k = 0; k < L_spec; k++ )
     834             :     {
     835    11008960 :         signs[k] = extract_l( L_lshr( spectrum[k], 31 ) );
     836    11008960 :         move16();
     837    11008960 :         if ( spectrum[k] < 0 )
     838             :         {
     839     1818375 :             spectrum[k] = L_abs( spectrum[k] );
     840     1818375 :             move32();
     841             :         }
     842             :     }
     843             : 
     844       17444 :     IF( use_hm != 0 )
     845             :     {
     846       15794 :         tcx_hm_analyse_fx( spectrum, spectrum_e, L_spec, env, target_bits, hTcxCfg->coder_type, prm_hm, tcxltp_pitch, hTcxEnc->tcxltp_gain, &hm_bits );
     847             : 
     848       15794 :         target_bits = sub( target_bits, hm_bits );
     849       15794 :         *signaling_bits = add( *signaling_bits, hm_bits );
     850       15794 :         move16();
     851             :     }
     852             :     ELSE
     853             :     {
     854        1650 :         prm_hm[0] = 0; /* just to be sure */
     855        1650 :         move16();
     856        1650 :         hm_bits = 0;
     857        1650 :         move16();
     858             :     }
     859             : 
     860       17444 :     L_spec_core = L_spec;
     861       17444 :     move16();
     862       17444 :     if ( st->igf )
     863             :     {
     864       17444 :         L_spec_core = s_min( L_spec_core, st->hIGFEnc->infoStartLine );
     865             :     }
     866       17444 :     envelope = (Word16 *) env;
     867             : 
     868       17444 :     tcx_arith_scale_envelope( L_spec, L_spec_core, env, target_bits, low_complexity, envelope, &envelope_e );
     869             : 
     870       17444 :     tmp = sub( envelope_e, 1 + 15 );
     871    11026404 :     FOR( k = 0; k < L_spec; k++ )
     872             :     {
     873    11008960 :         exponents[k] = round_fx( expfp( envelope[k], tmp ) );
     874    11008960 :         move16();
     875             :     }
     876             : 
     877       17444 :     scale = tcx_arith_rateloop( spectrum, *spectrum_e, L_spec, envelope, envelope_e, exponents, target_bits, deadzone, deadzone_flags, &( hTcxEnc->tcx_target_bits_fac ), &scale_e );
     878             : 
     879             :     /* Final quantization */
     880       17444 :     kMax = tcx_arith_find_kMax( spectrum, *spectrum_e, L_spec, scale, scale_e, deadzone, deadzone_flags );
     881             : 
     882       17444 :     q_spectrum = (Word16 *) env; /* Reuse buffer */
     883             : 
     884       17444 :     L_tmp = L_mult( deadzone, 1 ); /* Q16 */
     885       17444 :     tmp = add( sub( *spectrum_e, 15 ), scale_e );
     886     2229060 :     FOR( k = 0; k <= kMax; k++ )
     887             :     {
     888             :         /* quantise using dead-zone */
     889     2211616 :         q_spectrum[k] = extract_h( L_add( L_shl( Mpy_32_16_1( spectrum[k], scale ), tmp ), L_tmp ) );
     890     2211616 :         move16();
     891             :     }
     892             : 
     893             :     /* Final encoding */
     894       17444 :     *arith_bits = tcx_arith_encode( q_spectrum, signs, kMax, L_spec, exponents, target_bits, prm );
     895       17444 :     move16();
     896             : 
     897             :     /* Multiply back the signs */
     898     2229060 :     FOR( k = 0; k <= kMax; k++ )
     899             :     {
     900     2211616 :         if ( signs[k] != 0 )
     901     1072395 :             L_tmp = L_mult( q_spectrum[k], -( 1 << ( 30 - SPEC_EXP_DEC ) ) );
     902     2211616 :         if ( signs[k] == 0 )
     903     1139221 :             L_tmp = L_mult( q_spectrum[k], 1 << ( 30 - SPEC_EXP_DEC ) );
     904     2211616 :         spectrum[k] = L_tmp;
     905     2211616 :         move32();
     906             :     }
     907       17444 :     *spectrum_e = SPEC_EXP_DEC;
     908       17444 :     move16();
     909       17444 :     set32_fx( spectrum + k, 0, sub( s_max( L_frame, L_spec ), k ) );
     910       17444 : }

Generated by: LCOV version 1.14