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

Generated by: LCOV version 1.14