LCOV - code coverage report
Current view: top level - lib_enc - avq_cod_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main @ e95243e9e67ddeb69dddf129509de1b3d95b402e Lines: 362 367 98.6 %
Date: 2025-09-14 03:13:15 Functions: 4 4 100.0 %

          Line data    Source code
       1             : /*====================================================================================
       2             :     EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0
       3             :   ====================================================================================*/
       4             : #include <stdint.h>
       5             : #include <math.h>
       6             : #include "options.h" /* Compilation switches                   */
       7             : #include "cnst.h"
       8             : #include <assert.h>      /* Compilation switches                   */
       9             : #include "prot_fx.h"     /* Function prototypes                    */
      10             : #include "prot_fx_enc.h" /* Function prototypes                    */
      11             : #include "rom_com.h"     /* Static table prototypes                */
      12             : 
      13             : /*-------------------------------------------------------------------*
      14             :  * Local prototypes
      15             :  *-------------------------------------------------------------------*/
      16             : static void wrte_cv( BSTR_ENC_HANDLE hBstr, const Word16 nq, const Word16 i_ind, const Word16 kv_ind, UWord16 I, Word16 kv[], Word16 *bits );
      17             : /*-------------------------------------------------------------------*
      18             :  * Function AVQ_cod()                                                *
      19             :  *                                                                   *
      20             :  * Split algevraic vector quantizer (AVQ) base on RE8 latice         *
      21             :  *-------------------------------------------------------------------*/
      22             : 
      23       75480 : void AVQ_cod_fx(                       /* o:   comfort noise gain factor        */
      24             :                  const Word16 xri[],   /* i:   vector to quantize               Qx*/
      25             :                  Word16 xriq[],        /* o:   quantized normalized vector (assuming the bit budget is enough) */
      26             :                  const Word16 NB_BITS, /* i:   number of allocated bits         */
      27             :                  const Word16 Nsv,     /* i:   number of subvectors (lg=Nsv*8)  */
      28             :                  const Word16 Q_in_ref /* i:   Scaling input    */
      29             : )
      30             : {
      31             :     Word16 i, l, iter, c[8];
      32             :     Word16 gain_inv, tmp, nbits, nbits_max, fac, offset;
      33             :     Word16 ebits[NSV_MAX], e_ebits, f_ebits, e_tmp, f_tmp, tmp16, l_8;
      34             :     Word32 Lener, Ltmp, Lgain, x1[8];
      35             :     Word16 tot_est_bits, Q_in;
      36             : #ifndef ISSUE_1867_replace_overflow_libenc
      37             : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
      38             :     Flag Overflow = 0;
      39             : #endif
      40             : #endif
      41       75480 :     Q_in = sub( Q_in_ref, 1 );
      42       75480 :     move16();
      43             : 
      44             :     /* find energy of each subvector in log domain (scaled for bits estimation) */
      45             :     /* if the number of allocated bits is high, recompute the energy of sub vectors with a different scaling factor (applicable only in BASOP code) */
      46             :     DO
      47             :     {
      48       75480 :         Q_in = add( Q_in, 1 );
      49       75480 :         tot_est_bits = 0;
      50       75480 :         move16();
      51      687575 :         FOR( l = 0; l < Nsv; l++ )
      52             :         {
      53      612095 :             Lener = L_shl( 4, shl( Q_in, 1 ) ); /* to set ebits >= 0 */
      54     5508855 :             FOR( i = 0; i < 8; i++ )
      55             :             {
      56             : #ifdef ISSUE_1867_replace_overflow_libenc
      57     4896760 :                 Lener = L_mac_sat( Lener, xri[l * 8 + i], xri[l * 8 + i] );
      58             : #else
      59             :                 Lener = L_mac_o( Lener, xri[l * 8 + i], xri[l * 8 + i], &Overflow );
      60             : #endif
      61             :             }
      62             :             /* estimated bit consumption when gain=1 */
      63             :             /* ebits[l] = 5.0 * FAC_LOG2 * (Word16)log10(ener * 0.5) */
      64      612095 :             e_ebits = norm_l( Lener );
      65      612095 :             f_ebits = Log2_norm_lc( L_shl( Lener, e_ebits ) );
      66      612095 :             e_ebits = sub( 30 - 2, e_ebits ); /* -2 = *0.25 */
      67      612095 :             e_ebits = sub( e_ebits, shl( Q_in, 1 ) );
      68             : 
      69      612095 :             Ltmp = L_deposit_h( e_ebits );
      70      612095 :             Ltmp = L_mac( Ltmp, f_ebits, 1 );
      71      612095 :             Ltmp = L_add( L_shl( Ltmp, 6 ), L_shl( Ltmp, 4 ) ); /* Mult by 5.0 and then by 16 (To go to Q4). Do it using Mult by 80 (which is 64+16) */
      72      612095 :             ebits[l] = round_fx( Ltmp );                        /*Q4*/
      73      612095 :             move16();
      74      612095 :             tot_est_bits = add( tot_est_bits, shr( ebits[l], 4 ) ); // Q0
      75             :         }
      76       75480 :         test();
      77       75480 :         test();
      78             :     }
      79       75480 :     WHILE( ( LE_16( Q_in, Q_in_ref ) ) && LE_16( tot_est_bits, mult( 26214, NB_BITS ) ) && GT_16( tot_est_bits, 600 ) ); /* limited to 1 possible iteration */
      80             : 
      81             :     /*----------------------------------------------------------------*
      82             :      * subvector energy worst case:
      83             :      * - typically, it's a tone with maximum of amplitude (RMS=23170).
      84             :      * - fft length max = 1024 (N/2 is 512)
      85             :      * log10(energy) = log10(23710*23710*1024*(N/2)) = 14.45
      86             :      * ebits --> 5.0*FAC_LOG2*14.45 = 240 bits
      87             :      *----------------------------------------------------------------*/
      88             : 
      89             :     /* estimate gain according to number of bits allowed */
      90             :     /* start at the middle (offset range = 0 to 255.75) Q6 */
      91       75480 :     fac = 2048; // 128.0f in Q4
      92       75480 :     move16();
      93       75480 :     offset = 0;
      94       75480 :     move16();
      95             : 
      96       75480 :     Ltmp = L_mult( 31130 /*.95f in Q15*/, sub( NB_BITS, Nsv ) ); /* (1810 - 8 - 1152/8)*.95*/
      97       75480 :     nbits_max = round_fx( L_shl( Ltmp, 4 ) );
      98             : 
      99             :     /* tree search with 10 iterations : offset with step of 0.25 bits (0.3 dB) */
     100      830280 :     FOR( iter = 0; iter < 10; iter++ )
     101             :     {
     102      754800 :         offset = add( fac, offset );
     103             :         /* calculate the required number of bits */
     104      754800 :         nbits = 0;
     105      754800 :         move16();
     106     6875750 :         FOR( l = 0; l < Nsv; l++ )
     107             :         {
     108     6120950 :             tmp = sub( ebits[l], offset );
     109     6120950 :             tmp = s_max( tmp, 0 );
     110     6120950 :             nbits = add( tmp, nbits );
     111             :         }
     112             :         /* decrease gain when no overflow occurs */
     113      754800 :         if ( LE_16( nbits, nbits_max ) )
     114             :         {
     115      429335 :             offset = sub( offset, fac );
     116             :         }
     117      754800 :         fac = mult( fac, 16384 /*.5 in Q15*/ );
     118             :     }
     119             : 
     120       75480 :     Ltmp = L_shr( L_mult( offset, 13107 ), 6 ); /* offset((2^21)/160 */
     121             : 
     122             :     /* estimated gain (when offset=0, estimated gain=1) */
     123       75480 :     f_tmp = L_Extract_lc( Ltmp, &e_tmp );
     124       75480 :     tmp16 = extract_l( Pow2( 14, f_tmp ) );
     125       75480 :     Lgain = L_shl_sat( tmp16, e_tmp );
     126             :     /* gain_inv = 1.0f / gain */
     127       75480 :     e_tmp = norm_l( Lgain );
     128       75480 :     tmp16 = extract_h( L_shl( Lgain, e_tmp ) );
     129       75480 :     e_tmp = sub( 31 - 14, e_tmp );
     130       75480 :     gain_inv = div_s( 16384, tmp16 );
     131       75480 :     e_tmp = sub( 0, e_tmp );
     132       75480 :     e_tmp = sub( e_tmp, Q_in );
     133             :     /* quantize all subvector using estimated gain */
     134      687575 :     FOR( l = 0; l < Nsv; l++ )
     135             :     {
     136      612095 :         l_8 = shl( l, 3 );
     137     5508855 :         FOR( i = 0; i < 8; i++ )
     138             :         {
     139     4896760 :             x1[i] = L_shl( L_mult( xri[l_8 + i], gain_inv ), e_tmp ); // Q15
     140     4896760 :             move32();
     141             :         }
     142             : 
     143      612095 :         re8_PPV_fx( x1, c );
     144             : 
     145     5508855 :         FOR( i = 0; i < 8; i++ )
     146             :         {
     147     4896760 :             xriq[l_8 + i] = c[i]; // Q0
     148     4896760 :             move16();
     149             :         }
     150             :     }
     151             : 
     152             :     /* round_fx bit allocations and save */
     153      687575 :     FOR( i = 0; i < Nsv; i++ )
     154             :     {
     155      612095 :         xriq[( Nsv * 8 ) + i] = shl( ebits[i], 7 - 4 ); // Q0
     156      612095 :         move16();
     157             :     }
     158             : 
     159       75480 :     return;
     160             : }
     161             : 
     162             : 
     163             : /*-----------------------------------------------------------------*
     164             :  * AVQ_encmux()
     165             :  *
     166             :  * Encode subvectors and write indexes into the bitstream
     167             :  *-----------------------------------------------------------------*/
     168       75480 : void AVQ_encmux_fx(
     169             :     BSTR_ENC_HANDLE hBstr, /* i/o: bitstream handle            */
     170             :     const Word16 extl,     /* i  : extension layer                                 */
     171             :     Word16 xriq[],         /* i/o: rounded subvectors [0..8*Nsv-1] followed
     172             :                                by rounded bit allocations [8*Nsv..8*Nsv+Nsv-1] */
     173             :     Word16 *nb_bits,       /* i/o: number of allocated bits                        */
     174             :     const Word16 Nsv,      /* i:   number of subvectors                            */
     175             :     Word16 nq_out[],       /* o  : AVQ nq index                                    */
     176             :     Word16 avq_bit_sFlag,  /* i  : flag for AVQ bit saving solution                */
     177             :     Word16 trgtSvPos       /* i  : target SV for AVQ bit savings                   */
     178             : )
     179             : {
     180       75480 :     Word16 i, j = 0, bits, pos, pos_max, overflow, pos_tmp, bit_tmp;
     181             :     Word16 sort_idx[NSV_MAX], nq[NSV_MAX], kv[NSV_MAX * 8];
     182             :     Word16 *t;
     183             :     UWord16 I[NSV_MAX];
     184             :     Word16 nq_ind, i_ind, kv_ind;
     185             :     Word16 nq_est, unused_bits, unused_bits_idx;
     186             :     Word16 bitsMod, Nsvm1, Nsvm2;
     187             :     Word16 unusedbitsFlag;
     188             :     Word16 svOrder[NSV_MAX], k, nullVec, dummy_bits;
     189             :     Word16 tmp;
     190       75480 :     test();
     191       75480 :     IF( EQ_16( extl, SWB_BWE_HIGHRATE ) || EQ_16( extl, FB_BWE_HIGHRATE ) )
     192             :     {
     193        1470 :         nq_ind = IND_NQ2;
     194        1470 :         move16();
     195        1470 :         i_ind = IND_I2;
     196        1470 :         move16();
     197        1470 :         kv_ind = IND_KV2;
     198        1470 :         move16();
     199             :     }
     200             :     ELSE
     201             :     {
     202       74010 :         nq_ind = IND_NQ;
     203       74010 :         move16();
     204       74010 :         i_ind = IND_I;
     205       74010 :         move16();
     206       74010 :         kv_ind = IND_KV;
     207       74010 :         move16();
     208             :     }
     209             : 
     210     2641800 :     FOR( i = 0; i < NSV_MAX; i++ )
     211             :     {
     212     2566320 :         I[i] = (UWord16) -1;
     213     2566320 :         move16();
     214             :     }
     215       75480 :     unusedbitsFlag = 0;
     216       75480 :     bitsMod = 0;
     217       75480 :     move16();
     218       75480 :     move16();
     219             :     /*-----------------------------------------------------------------
     220             :      * Encode subvectors and fix possible overflows in total bit budget,
     221             :      * i.e. find for each subvector a codebook index nq (nq=0,2,3,4,...,NSV_MAX),
     222             :      * a base codebook index (I), and a Voronoi index (kv)
     223             :      *-----------------------------------------------------------------*/
     224             : 
     225             :     /* sort subvectors by estimated bit allocations in decreasing order */
     226       75480 :     t = kv;
     227             :     /* reuse vector to save memory */
     228             :     /*ptr init*/
     229      687575 :     FOR( i = 0; i < Nsv; i++ )
     230             :     {
     231      612095 :         t[i] = xriq[8 * Nsv + i];
     232      612095 :         move16();
     233             :     }
     234             : 
     235      687575 :     FOR( i = 0; i < Nsv; i++ )
     236             :     {
     237      612095 :         bits = t[0];
     238      612095 :         move16();
     239      612095 :         pos = 0;
     240      612095 :         move16();
     241     5151813 :         FOR( j = 1; j < Nsv; j++ )
     242             :         {
     243     4539718 :             if ( GT_16( t[j], bits ) )
     244             :             {
     245      901581 :                 pos = j;
     246      901581 :                 move16();
     247             :             }
     248     4539718 :             bits = s_max( t[j], bits );
     249             :         }
     250      612095 :         sort_idx[i] = pos;
     251      612095 :         move16();
     252      612095 :         t[pos] = -1;
     253      612095 :         move16();
     254             :     }
     255             : 
     256             :     /* compute multi-rate indices and avoid bit budget overflow */
     257       75480 :     pos_max = 0;
     258       75480 :     move16();
     259       75480 :     bits = 0;
     260       75480 :     move16();
     261      687575 :     FOR( i = 0; i < Nsv; i++ )
     262             :     {
     263             :         /* find vector to quantize (criteria: nb of estimated bits) */
     264      612095 :         pos = sort_idx[i];
     265      612095 :         move16();
     266             : 
     267             :         /* compute multi-rate index of rounded subvector (nq,I,kv[]) */
     268      612095 :         re8_cod_fx( &xriq[pos * 8], &nq[pos], &I[pos], &kv[8 * pos] );
     269             : 
     270      612095 :         IF( nq[pos] > 0 )
     271             :         {
     272      524991 :             j = pos_max;
     273      524991 :             move16();
     274      524991 :             j = s_max( pos, j );
     275             : 
     276             :             /* compute (number of bits -1) to describe Q #nq */
     277      524991 :             IF( GE_16( nq[pos], 2 ) )
     278             :             {
     279      524991 :                 overflow = sub( i_mult2( nq[pos], 5 ), 1 );
     280             :             }
     281             :             ELSE
     282             :             {
     283           0 :                 overflow = 0;
     284           0 :                 move16();
     285             :             }
     286             : 
     287             :             /* check for overflow and compute number of bits-1 (n) */
     288      524991 :             IF( GT_16( add( bits, add( overflow, j ) ), *nb_bits ) )
     289             :             {
     290             :                 /* if budget overflow */
     291       85073 :                 pos_tmp = add( shl( pos, 3 ), 8 ); /*(pos*8)+8*/
     292      765657 :                 FOR( j = pos * 8; j < pos_tmp; j++ )
     293             :                 {
     294      680584 :                     xriq[j] = 0;
     295      680584 :                     move16();
     296             :                 }
     297       85073 :                 nq[pos] = 0;
     298       85073 :                 move16(); /* force Q0 */
     299             :             }
     300             :             ELSE
     301             :             {
     302      439918 :                 bits = add( bits, overflow );
     303      439918 :                 pos_max = j;
     304      439918 :                 move16(); /* update index of the last described subvector */
     305             :             }
     306             :         }
     307             :     }
     308       75480 :     nullVec = 0;
     309       75480 :     Nsvm1 = sub( Nsv, 1 );
     310       75480 :     Nsvm2 = sub( Nsvm1, 1 );
     311       75480 :     dummy_bits = 0;
     312       75480 :     svOrder[Nsvm1] = trgtSvPos;
     313       75480 :     svOrder[0] = 0;
     314       75480 :     svOrder[1] = 1;
     315       75480 :     i = 2;
     316       75480 :     j = i;
     317       75480 :     move16();
     318       75480 :     move16();
     319       75480 :     move16();
     320       75480 :     move16();
     321       75480 :     move16();
     322       75480 :     move16();
     323       75480 :     move16();
     324       75480 :     if ( EQ_16( avq_bit_sFlag, 2 ) )
     325             :     {
     326       19950 :         j = add( i, 1 );
     327             :     }
     328      461299 :     WHILE( i < Nsvm1 )
     329             :     {
     330      385819 :         svOrder[i] = j;
     331      385819 :         move16();
     332      385819 :         i++; /*ptr*/
     333      385819 :         j = add( j, 1 );
     334             :     }
     335             :     /* write indexes to the bitstream */
     336             :     /* ============================== */
     337             : 
     338       75480 :     bits = *nb_bits;
     339       75480 :     move16();
     340       75480 :     overflow = 0;
     341       75480 :     move16();
     342      642741 :     FOR( i = 0; i < Nsv; i++ )
     343             :     {
     344      612095 :         k = svOrder[i];
     345      612095 :         move16();
     346      612095 :         test();
     347      612095 :         test();
     348      612095 :         test();
     349      612095 :         test();
     350      612095 :         test();
     351      612095 :         tmp = bits;
     352      612095 :         move16();
     353     6254966 :         WHILE( GE_16( tmp, 5 ) )
     354             :         {
     355     5642871 :             tmp = sub( tmp, 5 );
     356             :         }
     357      612095 :         assert( tmp == bits % 5 );
     358      612095 :         IF( EQ_16( avq_bit_sFlag, 2 ) && EQ_16( tmp, 4 ) && GT_16( bits, 8 ) && LT_16( bits, 30 ) && GE_16( k, trgtSvPos ) && LT_16( i, Nsvm1 ) )
     359             : 
     360             :         {
     361        2925 :             ordr_esti( sub( Nsv, i ), &trgtSvPos, &svOrder[i], Nsv );
     362        2925 :             k = svOrder[i];
     363        2925 :             move16();
     364        2925 :             avq_bit_sFlag = 1;
     365        2925 :             move16();
     366             :         }
     367             : 
     368      612095 :         test();
     369      612095 :         IF( EQ_16( k, trgtSvPos ) && avq_bit_sFlag > 0 )
     370             :         {
     371       70640 :             test();
     372       70640 :             test();
     373       70640 :             IF( EQ_16( sub( *nb_bits, bits ), 7 ) || LT_16( bits, BIT_SAVING_LOW_THR ) || GE_16( bits, BIT_SAVING_HIGH_THR ) )
     374             :             {
     375       25806 :                 avq_bit_sFlag = 0;
     376       25806 :                 move16();
     377             :             }
     378             :             ELSE
     379             :             {
     380             :                 BREAK;
     381             :             }
     382             :         }
     383             : 
     384      567261 :         if ( EQ_16( sub( i_mult2( 5, nq[k] ), 1 ), bits ) ) /* check the overflow */
     385             :         {
     386        6670 :             overflow = 1;
     387        6670 :             move16();
     388             :         }
     389             : 
     390      567261 :         IF( GT_16( bits, 8 ) )
     391             :         {
     392             :             /* write the unary code for nq[i] */
     393      535551 :             j = sub( nq[k], 1 );
     394      535551 :             IF( nq[k] > 0 )
     395             :             {
     396             :                 /* write the unary code */
     397      395346 :                 FOR( ; j > 16; j -= 16 )
     398             :                 {
     399           0 :                     push_indice( hBstr, nq_ind, 65535, 16 );
     400           0 :                     bits = sub( bits, 16 );
     401             :                 }
     402             : 
     403      395346 :                 IF( j > 0 )
     404             :                 {
     405      395346 :                     push_indice( hBstr, nq_ind, extract_l( L_sub( L_shl( 1L, j ), 1L ) ), j );
     406      395346 :                     bits = sub( bits, j );
     407             :                 }
     408             :             }
     409      535551 :             IF( !overflow )
     410             :             {
     411             :                 /* write the stop bit */
     412      528881 :                 push_indice( hBstr, nq_ind, 0, 1 );
     413      528881 :                 bits = sub( bits, 1 );
     414             :             }
     415             : 
     416      535551 :             wrte_cv( hBstr, nq[k], i_ind, kv_ind, I[k], &kv[k * 8], &bits );
     417             :         }
     418             :     } /* for */
     419             :     /* Bit Saving Solution */
     420       75480 :     test();
     421       75480 :     IF( avq_bit_sFlag > 0 && GT_16( bits, 8 ) )
     422             :     {
     423             :         /* bitsMod = bits % 5;*/
     424       44834 :         bitsMod = bits;
     425       44834 :         move16();
     426      177447 :         WHILE( bitsMod >= 5 )
     427             :         {
     428      132613 :             bitsMod = sub( bitsMod, 5 );
     429             :         }
     430       44834 :         assert( bitsMod == bits % 5 );
     431       44834 :         i = svOrder[Nsvm1];
     432       44834 :         move16();
     433       44834 :         IF( NE_16( i, Nsvm1 ) )
     434             :         {
     435       15541 :             nullVec = 0;
     436       15541 :             move16();
     437       93246 :             FOR( j = i; j < Nsv - 1; j++ )
     438             :             {
     439       77705 :                 if ( nq[svOrder[j]] == 0 )
     440             :                 {
     441       11006 :                     nullVec = add( nullVec, 1 );
     442             :                 }
     443             :             }
     444             :             /*nq_est = bits / 5;*/
     445       15541 :             nq_est = mult( bits, 6554 );
     446       15541 :             assert( nq_est == bits / 5 );
     447             : 
     448       15541 :             test();
     449       15541 :             test();
     450       15541 :             test();
     451       15541 :             test();
     452       15541 :             test();
     453       15541 :             test();
     454       15541 :             test();
     455       15541 :             test();
     456       15541 :             test();
     457       15541 :             test();
     458       15541 :             test();
     459       15541 :             IF( ( bitsMod > 0 || ( EQ_16( nullVec, 4 ) && EQ_16( nq_est, 5 ) ) ) && NE_16( bitsMod, 4 ) && GE_16( add( bits, nullVec ), add( add( shl( nq_est, 2 ), nq_est ), 4 ) ) /*5 * nq_est + 4*/ && nq[svOrder[Nsvm2]] == 0 ) /* detect need for dummy bits */
     460             :             {
     461         116 :                 dummy_bits = sub( 5, bitsMod );
     462         116 :                 bits = add( bits, dummy_bits ); /* add dummy bits */
     463         116 :                 bitsMod = 0;
     464         116 :                 move16();
     465             :             }
     466       15425 :             ELSE IF( GT_16( nq_est, 4 ) && ( ( bitsMod == 0 && GT_16( nullVec, 3 ) && LT_16( nullVec, 6 ) ) || ( EQ_16( bitsMod, 4 ) && EQ_16( nullVec, 5 ) ) ) && nq[svOrder[Nsvm2]] == 0 ) /* wasted bits 4, 5 for nq 6,7..*/
     467             :             {
     468           3 :                 overflow = 0;
     469           3 :                 move16();
     470           3 :                 tmp = add( bitsMod, nullVec );
     471           4 :                 WHILE( tmp >= 5 )
     472             :                 {
     473           1 :                     tmp = sub( tmp, 5 );
     474             :                 }
     475           3 :                 assert( tmp == add( bitsMod, nullVec ) % 5 );
     476           3 :                 if ( tmp != 0 )
     477             :                 {
     478           3 :                     overflow = 1;
     479           3 :                     move16();
     480             :                 }
     481           3 :                 dummy_bits = add( nullVec, overflow );
     482           3 :                 bits = add( bits, dummy_bits ); /* add dummy bits */
     483           3 :                 bitsMod = 0;
     484           3 :                 move16();
     485             :             }
     486             :         }
     487             : 
     488       44834 :         overflow = 1;
     489       44834 :         move16();
     490       44834 :         IF( NE_16( bitsMod, 4 ) )
     491             :         {
     492       37586 :             overflow = 0;
     493       37586 :             move16();
     494       37586 :             bits = sub( bits, bitsMod );
     495             :         }
     496       44834 :         bits = add( bits, overflow ); /*add fake bit */
     497       44834 :         unused_bits = sub( bits, add( shl( nq[i], 2 ), nq[i] ) );
     498       44834 :         if ( nq[i] == 0 ) /*no bit savings*/
     499             :         {
     500         262 :             unused_bits = sub( unused_bits, 1 ); /*Stop Bit*/
     501             :         }
     502             :         /*unused_bits_idx = (int16_t)unused_bits / 5;*/
     503       44834 :         IF( unused_bits >= 0 )
     504             :         {
     505       44834 :             unused_bits_idx = mult( unused_bits, 6554 /*1/5 in Q15*/ );
     506             :         }
     507             :         ELSE
     508             :         {
     509           0 :             unused_bits_idx = negate( mult( negate( unused_bits ), 6554 /*1/5 in Q15*/ ) );
     510             :         }
     511       44834 :         assert( unused_bits_idx == unused_bits / 5 );
     512       44834 :         unusedbitsFlag = 0;
     513       44834 :         move16();
     514       44834 :         IF( dummy_bits == 0 )
     515             :         {
     516       44715 :             test();
     517       44715 :             test();
     518       44715 :             IF( EQ_16( unused_bits_idx, 1 ) && GT_16( bits, BIT_SAVING_LOW_THR ) )
     519             :             {
     520       20373 :                 unused_bits_idx = 0;
     521       20373 :                 unusedbitsFlag = 1;
     522       20373 :                 move16();
     523       20373 :                 move16();
     524             :             }
     525       24342 :             ELSE IF( unused_bits_idx == 0 && GT_16( bits, BIT_SAVING_LOW_THR ) )
     526             :             {
     527        8647 :                 unused_bits_idx = 1;
     528        8647 :                 unusedbitsFlag = -1;
     529        8647 :                 move16();
     530        8647 :                 move16();
     531             :             }
     532             :         }
     533             : 
     534       44834 :         j = unused_bits_idx;
     535       44834 :         move16();
     536             :         /*Encode Unused Bit Unary Codeword */
     537       44834 :         IF( j > 0 )
     538             :         {
     539             :             /* write the unary code */
     540       11004 :             push_indice( hBstr, nq_ind, u_extract_l( L_sub( L_shl_sat( 1, j ), 1 ) ), j );
     541             :         }
     542             : 
     543       44834 :         IF( nq[i] != 0 )
     544             :         {
     545             :             /* write the stop bit */
     546       44572 :             push_indice( hBstr, nq_ind, 0, 1 );
     547             :         }
     548             : 
     549             :         /*Compute AVQ code book number from unused Bits */
     550       44834 :         bit_tmp = add( unusedbitsFlag, unused_bits_idx );
     551             :         /*nq_est = (int16_t)ceil(0.2f * (bits - 5 * (unusedbitsFlag + unused_bits_idx)));*/
     552       44834 :         nq_est = mult( 6554, sub( bits, add( shl( bit_tmp, 2 ), bit_tmp ) ) );
     553       44834 :         assert( (Word16) ceil( 0.2f * ( bits - 5 * ( unusedbitsFlag + unused_bits_idx ) ) ) == nq_est );
     554             : 
     555       44834 :         if ( EQ_16( nq_est, 1 ) )
     556             :         {
     557         262 :             nq_est = 0;
     558         262 :             move16();
     559             :         }
     560       44834 :         bits = sub( bits, overflow );
     561             : 
     562       44834 :         bits = sub( bits, j );
     563             : 
     564       44834 :         if ( nq_est != 0 )
     565             :         {
     566       44572 :             bits = sub( bits, 1 );
     567             :         }
     568       44834 :         nq[i] = nq_est;
     569       44834 :         move16();
     570             : 
     571             :         /* write codebook indices (rank I and event. Voronoi index kv) */
     572       44834 :         wrte_cv( hBstr, nq[i], i_ind, kv_ind, I[i], &kv[i * 8], &bits );
     573             : 
     574       44834 :         bits = sub( bits, dummy_bits );
     575             : 
     576       44834 :         if ( NE_16( bitsMod, 4 ) )
     577             :         {
     578       37586 :             bits = add( bits, bitsMod );
     579             :         }
     580             :     }
     581       75480 :     *nb_bits = bits;
     582       75480 :     move16();
     583             : 
     584      687575 :     FOR( i = 0; i < Nsv; i++ )
     585             :     {
     586      612095 :         nq_out[i] = nq[i];
     587      612095 :         move16();
     588             :     }
     589             : 
     590       75480 :     return;
     591             : }
     592             : /*-------------------------------------------------------------------*
     593             :  * Function AVQ_cod_lpc_fx()                                            *
     594             :  *                                                                   *
     595             :  * Split algebraic vector quantizer (AVQ) for LPC quantization       *
     596             :  *-------------------------------------------------------------------*/
     597             : 
     598      677768 : void AVQ_cod_lpc_fx(
     599             :     Word16 *nvec,  /* input:  vector to quantize (normalized) (5Q10)*/
     600             :     Word16 *nvecq, /* output: quantized vector                (5Q10)*/
     601             :     Word16 *indx,  /* output: index[] (4 bits per words)      (15Q0)*/
     602             :     Word16 Nsv     /* input:  number of subvectors (lg=Nsv*8)       */
     603             : )
     604             : {
     605             :     Word16 ival, n, nq, nk, c[8], kv[8];
     606             :     Word16 i, l, pos;
     607             :     Word32 I;
     608             :     Word32 x1[8];
     609             :     UWord16 I16;
     610             : 
     611             : 
     612             :     /* quantize all subvector using estimated gain */
     613      677768 :     pos = Nsv;
     614      677768 :     move16();
     615     2033304 :     FOR( l = 0; l < Nsv; l++ )
     616             :     {
     617    12199824 :         FOR( i = 0; i < 8; i++ )
     618             :         {
     619    10844288 :             x1[i] = L_mult( nvec[l * 8 + i], 1 << 4 ); /* 5Q10 -> 16Q15*/
     620    10844288 :             move32();
     621             :         }
     622     1355536 :         re8_PPV_fx( x1, c ); /*x1:8Q15, c:15Q0*/
     623     1355536 :         re8_cod_fx( c, &nq, &I16, kv );
     624     1355536 :         I = UL_deposit_l( I16 );
     625             : 
     626    12199824 :         FOR( i = 0; i < 8; i++ )
     627             :         {
     628    10844288 :             nvecq[l * 8 + i] = shl( c[i], 10 ); /*15Q0->5Q10*/
     629    10844288 :             move16();
     630             :         }
     631             : 
     632     1355536 :         indx[l] = nq; /* index[0..Nsv-1] = quantizer number (0,2,3,4...) */
     633     1355536 :         move16();
     634     1355536 :         nk = 0;
     635     1355536 :         move16();
     636     1355536 :         n = nq;
     637     1355536 :         move16();
     638             : 
     639     1355536 :         IF( GT_16( nq, 4 ) )
     640             :         {
     641      210563 :             nk = shr( sub( nq, 3 ), 1 ); /*nk = (nq-3)>>1;*/
     642      210563 :             n = sub( nq, shl( nk, 1 ) ); /*n = nq - nk*2; */
     643             :         }
     644             : 
     645             :         /* write n groups of 4-bit for base codebook index (I) */
     646     4967982 :         FOR( ; n > 0; n-- )
     647             :         {
     648     3612446 :             indx[pos++] = s_and( extract_l( I ), 0x000F );
     649     3612446 :             move16();
     650     3612446 :             I = L_shr( I, 4 );
     651             :         }
     652             : 
     653             :         /* write n groups of 4-bit for Voronoi index (k[]) */
     654     1647544 :         FOR( ; nk > 0; nk-- )
     655             :         {
     656      292008 :             ival = 0;
     657      292008 :             move16();
     658     2628072 :             FOR( i = 0; i < 8; i++ )
     659             :             {
     660     2336064 :                 ival = shl( ival, 1 );                      /*ival <<= 1;*/
     661     2336064 :                 ival = add( ival, s_and( kv[i], 0x0001 ) ); /*ival += (kv[i] & 0x01);*/
     662     2336064 :                 kv[i] = shr( kv[i], 1 );                    /*kv[i] >>= 1;*/
     663     2336064 :                 move16();
     664             :             }
     665      292008 :             indx[pos++] = s_and( ival, 0x000F );
     666      292008 :             move16();
     667      292008 :             ival = shr( ival, 4 );
     668      292008 :             indx[pos++] = s_and( ival, 0x000F );
     669      292008 :             move16();
     670             :         }
     671             :     }
     672             : 
     673             : 
     674      677768 :     return;
     675             : }
     676             : /*------------------------------------------------------------------ - *
     677             :  * Function wrte_cv()
     678             :  *
     679             :  * write codebook indices(rank I and event.Voronoi index kv) *
     680             :  *------------------------------------------------------------------ - */
     681      580385 : static void wrte_cv(
     682             :     BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle         */
     683             :     const Word16 nq,       /* i  : AVQ nq index                     */
     684             :     const Word16 i_ind,    /* i  : Base Bitstream index             */
     685             :     const Word16 kv_ind,   /* i  : Vornoi Bitstream index           */
     686             :     UWord16 I,             /* o  : rank I code book index           */
     687             :     Word16 kv[],           /* o  : Vornoi index kv                  */
     688             :     Word16 *nbits          /* i/o: bits                             */
     689             : )
     690             : {
     691             :     Word16 pos, j;
     692             :     Word16 bits, nq4;
     693             : 
     694      580385 :     bits = *nbits;
     695      580385 :     move16();
     696             : 
     697             :     /* write codebook indices (rank I and event. Voronoi index kv) */
     698      580385 :     IF( nq == 0 ) /* Q0 */
     699             :     {
     700             :         /* nothing to write */
     701             :     }
     702      439918 :     ELSE IF( LT_16( nq, 5 ) ) /* Q2, Q3, Q4 */
     703             :     {
     704      434521 :         nq4 = shl( nq, 2 );
     705      434521 :         push_indice( hBstr, i_ind, I, nq4 );
     706      434521 :         bits = sub( bits, nq4 );
     707             :     }
     708        5397 :     ELSE IF( EQ_16( s_and( nq, 1 ), 0 ) ) /* Q4 + Voronoi extensions r=1,2,3,... */
     709             :     {
     710        2059 :         push_indice( hBstr, i_ind, I, 4 * 4 );
     711        2059 :         bits = sub( bits, 4 * 4 );
     712             :         /*pos = (int16_t)(nq / 2 - 2);*/ /* Voronoi order determination */
     713        2059 :         pos = sub( shr( nq, 1 ), 2 );
     714       18531 :         FOR( j = 0; j < 8; j++ )
     715             :         {
     716       16472 :             push_indice( hBstr, kv_ind, kv[j], pos );
     717             :         }
     718             : 
     719        2059 :         bits = sub( bits, shl( pos, 3 ) );
     720             :     }
     721             :     ELSE /* Q3 + Voronoi extensions r=1,2,3,... */
     722             :     {
     723        3338 :         push_indice( hBstr, i_ind, I, 4 * 3 );
     724        3338 :         bits = sub( bits, 4 * 3 );
     725             : 
     726             :         /*pos = (int16_t)(nq / 2 - 1);*/ /* Voronoi order determination */
     727        3338 :         pos = sub( shr( nq, 1 ), 1 );
     728       30042 :         FOR( j = 0; j < 8; j++ )
     729             :         {
     730       26704 :             push_indice( hBstr, kv_ind, kv[j], pos );
     731             :         }
     732             : 
     733        3338 :         bits = sub( bits, shl( pos, 3 ) );
     734             :     }
     735             : 
     736      580385 :     *nbits = bits;
     737      580385 :     move16();
     738      580385 :     return;
     739             : }

Generated by: LCOV version 1.14