LCOV - code coverage report
Current view: top level - lib_dec - pvq_decode_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main enc/dec/rend @ 3b2f07138c61dcf997bbf4165d0882f794b2995f Lines: 37 43 86.0 %
Date: 2025-05-03 01:55:50 Functions: 1 1 100.0 %

          Line data    Source code
       1             : /*====================================================================================
       2             :     EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0
       3             :   ====================================================================================*/
       4             : 
       5             : #include <stdint.h>
       6             : #include "options.h" /* Compilation switches                   */
       7             : #include "prot_fx.h"
       8             : #include "rom_com.h"
       9             : 
      10             : /*-------------------------------------------------------------------*
      11             :  * Function pvq_decode_fx()                                             *
      12             :  *                                                                   *
      13             :  * PVQ subvector decoding algorithm                                  *
      14             :  *-------------------------------------------------------------------*/
      15             : 
      16      273683 : void pvq_decode_fx(
      17             :     Decoder_State *st_fx,
      18             :     PVQ_DEC_HANDLE hPVQ,  /* i/o: PVQ decoder handle */
      19             :     Word16 *xq,           /* o:   decoded vector (Q15)             */
      20             :     Word16 *y,            /* o:   decoded vector (non-scaled int)  */
      21             :     const Word16 k_val,   /* i:   number of allocated pulses       */
      22             :     const Word16 dim,     /* i:   Length of vector                 */
      23             :     const Word16 neg_gain /* i:   Gain    (negated to fit 1.0 in Q15 as -1.0)  */
      24             : )
      25             : {
      26             :     Word16 i;
      27             : 
      28             :     UWord32 h_mem[1 + KMAX_NON_DIRECT_FX + 1]; /* allocate max offset memory for dim  6 */
      29             : 
      30             :     PvqEntry entry;
      31             : 
      32             :     Word16 neg_gain_norm, shift_num, shift_den, shift_tot;
      33             :     Word32 L_yy, L_isqrt, L_tmp;
      34             : 
      35             :     UWord16 u16_tmp;
      36             : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
      37      273683 :     Flag Overflow = 0;
      38      273683 :     move16();
      39             : #endif
      40             : 
      41      273683 :     entry = get_size_mpvq_calc_offset_fx( dim, k_val, h_mem ); /* get size & prepare H(adaptive table for entry.size=N_MPVQ(dim,k_val) */
      42             : 
      43             : 
      44      273683 :     IF( NE_16( dim, 1 ) )
      45             :     {
      46      273641 :         entry.lead_sign_ind = (Word16) rc_dec_bits_fx( st_fx, hPVQ, 1 );
      47      273641 :         entry.index = rc_dec_uniform_fx( st_fx, hPVQ, entry.size );
      48      273641 :         move16();
      49      273641 :         move32();
      50             : 
      51      273641 :         IF( st_fx->hHQ_core != NULL )
      52             :         {
      53             :             /* safety check in case of bit errors */
      54      273514 :             test();
      55      273514 :             IF( GE_32( entry.index, entry.size ) || st_fx->hHQ_core->ber_occured_in_pvq != 0 )
      56             :             {
      57           0 :                 st_fx->hHQ_core->ber_occured_in_pvq = 1;
      58           0 :                 move16();
      59           0 :                 st_fx->BER_detect = 1;
      60           0 :                 move16();
      61           0 :                 entry.index = 0;
      62           0 :                 move16(); /* a zero index will essentially disable PVQ index decompostion complexity */
      63             :             }
      64             :         }
      65             :     }
      66             :     ELSE
      67             :     {
      68          42 :         entry.lead_sign_ind = (Word16) rc_dec_bits_fx( st_fx, hPVQ, 1 ); /* always a single sign bit */
      69          42 :         entry.index = L_deposit_l( 0 );
      70          42 :         move16();
      71          42 :         move32();
      72             :     }
      73             : 
      74      273683 :     mpvq_decode_vec_fx( &entry, h_mem, y );
      75             : 
      76      273683 :     IF( neg_gain == 0 )
      77             :     {
      78        5614 :         FOR( i = 0; i < dim; i++ )
      79             :         {
      80        5210 :             xq[i] = 0;
      81        5210 :             move16();
      82             :         }
      83             :     }
      84             :     ELSE
      85             :     {
      86      273279 :         L_yy = L_deposit_l( 0 );
      87     3753879 :         FOR( i = 0; i < dim; i++ )
      88             :         {
      89     3480600 :             L_yy = L_mac( L_yy, y[i], y[i] ); /* Q1 */
      90             :         }
      91             : 
      92      273279 :         L_isqrt = Isqrt( L_shr( L_yy, 1 ) ); /*Q31*/ /* one single gain fac  as in flt not computed  for now */
      93             : 
      94      273279 :         shift_num = norm_s( k_val );                /* account for max possible pulseamp in y */
      95      273279 :         shift_den = norm_s( neg_gain );             /* account for downscaling shift         */
      96      273279 :         neg_gain_norm = shl( neg_gain, shift_den ); /* 10 db loss in minSNR without this in L_qx , at HQ128 FB*/
      97      273279 :         shift_tot = sub( add( shift_num, shift_den ), 15 );
      98             : 
      99      273279 :         L_isqrt = L_negate( L_isqrt );
     100     3753879 :         FOR( i = 0; i < dim; i++ )
     101             :         {
     102             :             /* upshifted y[i]  used    */
     103             : 
     104     3480600 :             Mpy_32_16_ss( L_isqrt, shl( y[i], shift_num ), &L_tmp, &u16_tmp ); /*  Q31*Q(0+x)  *2*/
     105     3480600 :             Mpy_32_16_ss( L_tmp, neg_gain_norm, &L_tmp, &u16_tmp );            /*  Q31*Q(0+x) *Q15 *2*/
     106     3480600 :             L_tmp = L_shr_o( L_tmp, shift_tot, &Overflow );
     107     3480600 :             xq[i] = round_fx_o( L_tmp, &Overflow ); /* Q15 , array move   */
     108     3480600 :             move16();
     109             :         }
     110             :     }
     111             : 
     112             : 
     113      273683 :     return;
     114             : }

Generated by: LCOV version 1.14