LCOV - code coverage report
Current view: top level - lib_dec - pvq_decode_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main @ e95243e9e67ddeb69dddf129509de1b3d95b402e Lines: 31 41 75.6 %
Date: 2025-09-16 02:47:18 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      269600 : 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             : 
      37      269600 :     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) */
      38             : 
      39             : 
      40      269600 :     IF( NE_16( dim, 1 ) )
      41             :     {
      42      269600 :         entry.lead_sign_ind = (Word16) rc_dec_bits_fx( st_fx, hPVQ, 1 );
      43      269600 :         entry.index = rc_dec_uniform_fx( st_fx, hPVQ, entry.size );
      44      269600 :         move16();
      45      269600 :         move32();
      46             : 
      47      269600 :         IF( st_fx->hHQ_core != NULL )
      48             :         {
      49             :             /* safety check in case of bit errors */
      50      269470 :             test();
      51      269470 :             IF( GE_32( entry.index, entry.size ) || st_fx->hHQ_core->ber_occured_in_pvq != 0 )
      52             :             {
      53           0 :                 st_fx->hHQ_core->ber_occured_in_pvq = 1;
      54           0 :                 move16();
      55           0 :                 st_fx->BER_detect = 1;
      56           0 :                 move16();
      57           0 :                 entry.index = 0;
      58           0 :                 move16(); /* a zero index will essentially disable PVQ index decompostion complexity */
      59             :             }
      60             :         }
      61             :     }
      62             :     ELSE
      63             :     {
      64           0 :         entry.lead_sign_ind = (Word16) rc_dec_bits_fx( st_fx, hPVQ, 1 ); /* always a single sign bit */
      65           0 :         entry.index = L_deposit_l( 0 );
      66           0 :         move16();
      67           0 :         move32();
      68             :     }
      69             : 
      70      269600 :     mpvq_decode_vec_fx( &entry, h_mem, y );
      71             : 
      72      269600 :     IF( neg_gain == 0 )
      73             :     {
      74        5610 :         FOR( i = 0; i < dim; i++ )
      75             :         {
      76        5206 :             xq[i] = 0;
      77        5206 :             move16();
      78             :         }
      79             :     }
      80             :     ELSE
      81             :     {
      82      269196 :         L_yy = L_deposit_l( 0 );
      83     3710120 :         FOR( i = 0; i < dim; i++ )
      84             :         {
      85     3440924 :             L_yy = L_mac( L_yy, y[i], y[i] ); /* Q1 */
      86             :         }
      87             : 
      88      269196 :         L_isqrt = Isqrt( L_shr( L_yy, 1 ) ); /*Q31*/ /* one single gain fac  as in flt not computed  for now */
      89             : 
      90      269196 :         shift_num = norm_s( k_val );                /* account for max possible pulseamp in y */
      91      269196 :         shift_den = norm_s( neg_gain );             /* account for downscaling shift         */
      92      269196 :         neg_gain_norm = shl( neg_gain, shift_den ); /* 10 db loss in minSNR without this in L_qx , at HQ128 FB*/
      93      269196 :         shift_tot = sub( add( shift_num, shift_den ), 15 );
      94             : 
      95      269196 :         L_isqrt = L_negate( L_isqrt );
      96     3710120 :         FOR( i = 0; i < dim; i++ )
      97             :         {
      98             :             /* upshifted y[i]  used    */
      99             : 
     100     3440924 :             Mpy_32_16_ss( L_isqrt, shl( y[i], shift_num ), &L_tmp, &u16_tmp ); /*  Q31*Q(0+x)  *2*/
     101     3440924 :             Mpy_32_16_ss( L_tmp, neg_gain_norm, &L_tmp, &u16_tmp );            /*  Q31*Q(0+x) *Q15 *2*/
     102     3440924 :             L_tmp = L_shr_sat( L_tmp, shift_tot );
     103     3440924 :             xq[i] = round_fx_sat( L_tmp ); /* Q15 , array move   */
     104     3440924 :             move16();
     105             :         }
     106             :     }
     107             : 
     108             : 
     109      269600 :     return;
     110             : }

Generated by: LCOV version 1.14