LCOV - code coverage report
Current view: top level - lib_com - low_rate_band_att_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main enc/dec/rend @ 3b2f07138c61dcf997bbf4165d0882f794b2995f Lines: 135 139 97.1 %
Date: 2025-05-03 01:55:50 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             : 
       5             : #include <stdint.h>
       6             : #include "options.h" /* Compilation switches                   */
       7             : #include "rom_com.h" /* Static table prototypes                */
       8             : #include "prot_fx.h"
       9             : #include "ivas_prot_fx.h"
      10             : 
      11             : 
      12             : /*--------------------------------------------------------------------------*
      13             :  * fine_gain_pred()
      14             :  *
      15             :  * Fine gain prediction
      16             :  *--------------------------------------------------------------------------*/
      17       35150 : void ivas_fine_gain_pred_fx(
      18             :     const Word16 *sfm_start, /* i  : Sub band start indices          */
      19             :     const Word16 *sfm_end,   /* i  : Sub band end indices            */
      20             :     const Word16 *sfm_size,  /* i  : Sub band bandwidths             */
      21             :     const Word16 *i_sort,    /* i  : Energy sorting indices          */
      22             :     const Word16 *K,         /* i  : Number of pulses per band       */
      23             :     const Word16 *maxpulse,  /* i  : Maximum pulse per band          */
      24             :     const Word16 *R,         /* i  : Bits per sub band           Q3  */
      25             :     const Word16 num_sfm,    /* i  : Number of sub bands             */
      26             :     Word16 *xq,              /* i/o: Quantized vector /quantized vector with finegain adj Q15*/
      27             :     Word16 *y,               /* i/o: Quantized vector (int)          Q0*/
      28             :     Word16 *fg_pred,         /* o  : Predicted fine gains        Q12 */
      29             :     const Word16 core        /* i  : Core                            */
      30             : )
      31             : {
      32             :     Word16 i, band;
      33             :     Word16 gp;
      34             :     Word32 xx;
      35             :     Word16 accuracy;
      36             :     Word16 k, bw;
      37             : 
      38             :     Word16 shift, bw_idx;
      39             :     Word16 tmp, exp, exp2;
      40             :     Word32 L_tmp;
      41             :     UWord16 lsb;
      42             : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
      43       35150 :     Flag Overflow = 0;
      44       35150 :     move16();
      45             : #endif
      46             : 
      47      700483 :     FOR( band = 0; band < num_sfm; band++ )
      48             :     {
      49      665333 :         k = K[i_sort[band]];
      50      665333 :         move16();
      51             : 
      52      665333 :         IF( k > 0 )
      53             :         {
      54             :             /*  bw, bw_idx  only used if  k>0   */
      55      374032 :             bw = sfm_size[i_sort[band]];
      56      374032 :             move16(); // Extending for IVAS /* allowed. 8, 16, 24,32,40,48,64,80,96*/
      57             : 
      58      374032 :             bw_idx = ivas_band_len_idx[shr( bw, 3 )];
      59      374032 :             move16(); /* bw_idx=  0:                     8 */
      60      374032 :             xx = L_deposit_l( 0 );
      61      374032 :             shift = ivas_band_len_ener_shift[bw_idx];
      62      374032 :             move16();
      63     5486614 :             FOR( i = sfm_start[i_sort[band]]; i < sfm_end[i_sort[band]]; i++ )
      64             :             {
      65             :                 /*xx += xq[i] * xq[i]; */
      66     5112582 :                 tmp = shr( xq[i], shift );   /*15-shift */
      67     5112582 :                 xx = L_mac0( xx, tmp, tmp ); /*30-2*shift */
      68             :             }
      69             : 
      70      374032 :             IF( xx > 0 )
      71             :             {
      72             :                 /* Normalize synthesis to RMS=1.0 */
      73             :                 /*gp = (float) sqrt(bw / xx); */
      74      374032 :                 exp = norm_l( xx );
      75      374032 :                 L_tmp = L_shl( xx, exp ); /*2*(15-shift)+exp */
      76      374032 :                 exp = sub( 31, add( exp, sub( 30, shl( shift, 1 ) ) ) );
      77      374032 :                 L_tmp = Isqrt_lc( L_tmp, &exp ); /*31 - exp */
      78      374032 :                 Word16 norm = norm_s( bw );
      79      374032 :                 Word16 tmp1, tmp_exp = sub( 15, norm );
      80      374032 :                 tmp1 = Sqrt16( shl( bw, norm ), &tmp_exp );
      81      374032 :                 tmp1 = shr( tmp1, sub( sub( 15, tmp_exp ), Q11 ) );
      82      374032 :                 Mpy_32_16_ss( L_tmp, tmp1, &L_tmp, &lsb ); /*31-exp+11-15=27-exp */
      83             : 
      84      374032 :                 gp = round_fx_o( L_shl_o( L_tmp, add( 1, exp ), &Overflow ), &Overflow ); /*27-exp+1+exp-16=12 */
      85      374032 :                 test();
      86      374032 :                 test();
      87      374032 :                 IF( EQ_16( core, HQ_CORE ) && R != NULL && LE_16( R[i_sort[band]], 256 ) ) /* 256 is 32 in Q3 */
      88             :                 {
      89             :                     /*accuracy = ((float)k/(float)bw)*maxpulse[i_sort[band]]; */
      90      241825 :                     L_tmp = L_mult( k, inv_tbl_fx[bw] ); /*0+15+1 */
      91      241825 :                     exp2 = norm_l( L_tmp );
      92      241825 :                     tmp = round_fx( L_shl( L_tmp, exp2 ) );         /*16+exp2-16 */
      93      241825 :                     L_tmp = L_mult0( maxpulse[i_sort[band]], tmp ); /*0+exp2 */
      94      241825 :                     exp = norm_l( L_tmp );
      95      241825 :                     accuracy = round_fx( L_shl( L_tmp, exp ) ); /*exp2+exp-16=exp-16 */
      96      241825 :                     exp = add( exp, exp2 );
      97             : 
      98             :                     /*gp *= 1.0f - 0.05f / accuracy; */
      99      241825 :                     tmp = div_s( 13107, accuracy );                /* 0.05 in Q18 */
     100      241825 :                     tmp = shr_o( tmp, sub( 34, exp ), &Overflow ); /*15+18-exp+16-15=34-exp */
     101      241825 :                     tmp = sub( 32767, tmp );
     102      241825 :                     tmp = s_max( 27554, tmp ); /* Limit attenuation to norm quantizer error, 2^-0.25 in Q15 */
     103      241825 :                     gp = mult_r( tmp, gp );    /*15+12+1-16=12 */
     104             :                 }
     105             : 
     106      374032 :                 fg_pred[band] = gp;
     107      374032 :                 move16();
     108             :             }
     109             :             ELSE
     110             :             {
     111           0 :                 fg_pred[band] = 0;
     112           0 :                 move16();
     113             :             }
     114             :         }
     115             :         ELSE
     116             :         {
     117      291301 :             fg_pred[band] = 0;
     118      291301 :             move16();
     119     6961127 :             FOR( i = sfm_start[i_sort[band]]; i < sfm_end[i_sort[band]]; i++ )
     120             :             {
     121     6669826 :                 y[i] = 0;
     122     6669826 :                 move16();
     123     6669826 :                 xq[i] = 0;
     124     6669826 :                 move16();
     125             :             }
     126             :         }
     127             :     }
     128             : 
     129       35150 :     return;
     130             : }
     131             : 
     132       24026 : void fine_gain_pred_fx(
     133             :     const Word16 *sfm_start, /* i  : Sub band start indices          */
     134             :     const Word16 *sfm_end,   /* i  : Sub band end indices            */
     135             :     const Word16 *sfm_size,  /* i  : Sub band bandwidths             */
     136             :     const Word16 *i_sort,    /* i  : Energy sorting indices          */
     137             :     const Word16 *K,         /* i  : Number of pulses per band       */
     138             :     const Word16 *maxpulse,  /* i  : Maximum pulse per band          */
     139             :     const Word16 *R,         /* i  : Bits per sub band           Q3  */
     140             :     const Word16 num_sfm,    /* i  : Number of sub bands             */
     141             :     Word16 *xq,              /* i/o: Quantized vector /quantized vector with finegain adj Q15*/
     142             :     Word16 *y,               /* i/o: Quantized vector (int)          */
     143             :     Word16 *fg_pred,         /* o  : Predicted fine gains        Q12 */
     144             :     const Word16 core        /* i  : Core                            */
     145             : )
     146             : {
     147             :     Word16 i, band;
     148             :     Word16 gp;
     149             :     Word32 xx;
     150             :     Word16 accuracy;
     151             :     Word16 k, bw;
     152             : 
     153             :     Word16 shift, bw_idx;
     154             :     Word16 tmp, exp, exp2;
     155             :     Word32 L_tmp;
     156             :     UWord16 lsb;
     157             : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
     158       24026 :     Flag Overflow = 0;
     159       24026 :     move32();
     160             : #endif
     161             : 
     162      205771 :     FOR( band = 0; band < num_sfm; band++ )
     163             :     {
     164      181745 :         k = K[i_sort[band]];
     165      181745 :         move16();
     166             : 
     167      181745 :         IF( k > 0 )
     168             :         {
     169             :             /*  bw, bw_idx  only used if  k>0   */
     170      131767 :             bw = sfm_size[i_sort[band]];
     171      131767 :             move16(); /* allowed. 8, 16, 24,32,48,64,80,96 */
     172      131767 :             bw_idx = band_len_idx[shr( bw, 3 )];
     173      131767 :             move16(); /* bw_idx=  0:                     7 */
     174      131767 :             xx = L_deposit_l( 0 );
     175      131767 :             shift = band_len_ener_shift[bw_idx];
     176     2281063 :             FOR( i = sfm_start[i_sort[band]]; i < sfm_end[i_sort[band]]; i++ )
     177             :             {
     178             :                 /*xx += xq[i] * xq[i]; */
     179     2149296 :                 tmp = shr( xq[i], shift );   /*15-shift */
     180     2149296 :                 xx = L_mac0( xx, tmp, tmp ); /*30-2*shift */
     181             :             }
     182             : 
     183      131767 :             IF( xx > 0 )
     184             :             {
     185             :                 /* Normalize synthesis to RMS=1.0 */
     186             :                 /*gp = (float) sqrt(bw / xx); */
     187      131767 :                 exp = norm_l( xx );
     188      131767 :                 L_tmp = L_shl( xx, exp ); /*2*(15-shift)+exp */
     189      131767 :                 exp = sub( 31, add( exp, sub( 30, shl( shift, 1 ) ) ) );
     190      131767 :                 L_tmp = Isqrt_lc( L_tmp, &exp );                                          /*31 - exp */
     191      131767 :                 Mpy_32_16_ss( L_tmp, fine_gain_pred_sqrt_bw[bw_idx], &L_tmp, &lsb );      /*31-exp+11-15=27-exp */
     192      131767 :                 gp = round_fx_o( L_shl_o( L_tmp, add( 1, exp ), &Overflow ), &Overflow ); /*27-exp+1+exp-16=12 */
     193      131767 :                 test();
     194      131767 :                 test();
     195      131767 :                 IF( EQ_16( core, HQ_CORE ) && R != NULL && LE_16( R[i_sort[band]], 256 ) ) /* 256 is 32 in Q3 */
     196             :                 {
     197             :                     /*accuracy = ((float)k/(float)bw)*maxpulse[i_sort[band]]; */
     198       18590 :                     L_tmp = L_mult( k, inv_tbl_fx[bw] ); /*0+15+1 */
     199       18590 :                     exp2 = norm_l( L_tmp );
     200       18590 :                     tmp = round_fx( L_shl( L_tmp, exp2 ) );         /*16+exp2-16 */
     201       18590 :                     L_tmp = L_mult0( maxpulse[i_sort[band]], tmp ); /*0+exp2 */
     202       18590 :                     exp = norm_l( L_tmp );
     203       18590 :                     accuracy = round_fx( L_shl( L_tmp, exp ) ); /*exp2+exp-16=exp-16 */
     204       18590 :                     exp = add( exp, exp2 );
     205             : 
     206             :                     /*gp *= 1.0f - 0.05f / accuracy; */
     207       18590 :                     tmp = div_s( 13107, accuracy );                /* 0.05 in Q18 */
     208       18590 :                     tmp = shr_o( tmp, sub( 34, exp ), &Overflow ); /*15+18-exp+16-15=34-exp */
     209       18590 :                     tmp = sub( 32767, tmp );
     210       18590 :                     tmp = s_max( 27554, tmp ); /* Limit attenuation to norm quantizer error, 2^-0.25 in Q15 */
     211       18590 :                     gp = mult_r( tmp, gp );    /*15+12+1-16=12 */
     212             :                 }
     213             : 
     214      131767 :                 fg_pred[band] = gp;
     215      131767 :                 move16();
     216             :             }
     217             :             ELSE
     218             :             {
     219           0 :                 fg_pred[band] = 0;
     220           0 :                 move16();
     221             :             }
     222             :         }
     223             :         ELSE
     224             :         {
     225       49978 :             fg_pred[band] = 0;
     226       49978 :             move16();
     227      879970 :             FOR( i = sfm_start[i_sort[band]]; i < sfm_end[i_sort[band]]; i++ )
     228             :             {
     229      829992 :                 y[i] = 0;
     230      829992 :                 move16();
     231      829992 :                 xq[i] = 0;
     232      829992 :                 move16();
     233             :             }
     234             :         }
     235             :     }
     236             : 
     237       24026 :     return;
     238             : }
     239             : 
     240             : /*--------------------------------------------------------------------------*
     241             :  * get_max_pulses()
     242             :  *
     243             :  * Find the maximum pulse height (in unit pulses) in each band
     244             :  *--------------------------------------------------------------------------*/
     245             : 
     246       56484 : void get_max_pulses_fx(
     247             :     const Word16 *band_start, /* i  : Sub band start indices    */
     248             :     const Word16 *band_end,   /* i  : Sub band end indices      */
     249             :     const Word16 *k_sort,     /* i  : Indices for sorting by energy */
     250             :     const Word16 *npulses,    /* i  : Pulses per sub band       */
     251             :     const Word16 BANDS,       /* i  : Number of bands           */
     252             :     Word16 *inp_vector,       /* i/o: Encoded shape vectors (int)Q0*/
     253             :     Word16 *maxpulse          /* o  : Maximum pulse height per band Q0*/
     254             : )
     255             : {
     256             :     Word16 i, k;
     257             :     Word16 npul;
     258             :     Word16 maxp;
     259             :     Word16 tmp;
     260             : 
     261      898282 :     FOR( k = 0; k < BANDS; k++ )
     262             :     {
     263      841798 :         npul = npulses[k_sort[k]];
     264      841798 :         move16();
     265      841798 :         maxp = 0;
     266      841798 :         move16();
     267      841798 :         IF( npul > 0 )
     268             :         {
     269     7622917 :             FOR( i = band_start[k_sort[k]]; i < band_end[k_sort[k]]; i++ )
     270             :             {
     271     7122398 :                 tmp = abs_s( inp_vector[i] );
     272     7122398 :                 if ( GT_16( tmp, maxp ) )
     273             :                 {
     274      756909 :                     maxp = tmp;
     275      756909 :                     move16();
     276             :                 }
     277             :             }
     278             :         }
     279      841798 :         maxpulse[k_sort[k]] = maxp;
     280      841798 :         move16();
     281             :     }
     282             : 
     283       56484 :     return;
     284             : }
     285             : 
     286             : /*--------------------------------------------------------------------------*
     287             :  * fine_gain_dec()
     288             :  *
     289             :  * Fine gain decoder. Decodes fine gain adjustments and applies correction to
     290             :  * predicted fine gains
     291             :  *--------------------------------------------------------------------------*/
     292             : 
     293       28288 : void fine_gain_dec_fx(
     294             :     Decoder_State *st,
     295             :     const Word16 *ord,       /* i  : Indices for energy order             */
     296             :     const Word16 num_sfm,    /* i  : Number of bands                      */
     297             :     const Word16 *gain_bits, /* i  : Gain adjustment bits per sub band    */
     298             :     Word16 *fg_pred          /* i/o: Predicted gains / Corrected gains    Q12*/
     299             : )
     300             : {
     301             :     Word16 band;
     302             :     Word16 gbits;
     303             :     Word16 idx, tmp1, exp1;
     304             :     Word16 gain_dbq;
     305             :     Word32 L_tmp;
     306             : 
     307             : 
     308      437860 :     FOR( band = 0; band < num_sfm; band++ )
     309             :     {
     310      409572 :         gbits = gain_bits[ord[band]];
     311      409572 :         move16();
     312      409572 :         IF( gbits > 0 )
     313             :         {
     314       33523 :             IF( fg_pred[band] != 0 )
     315             :             {
     316       33311 :                 idx = get_next_indice_fx( st, gbits );
     317       33311 :                 gain_dbq = finegain_fx[gbits - 1][idx];
     318       33311 :                 move16();
     319             : 
     320             :                 /* Update predicted gain with quantized correction */
     321       33311 :                 L_tmp = L_mult0( gain_dbq, 21771 ); /* 21771=0.05*log2(10) */ /* 14+17=31 */
     322       33311 :                 L_tmp = L_shr( L_tmp, 15 );
     323       33311 :                 tmp1 = L_Extract_lc( L_tmp, &exp1 );
     324       33311 :                 tmp1 = abs_s( tmp1 );
     325       33311 :                 tmp1 = extract_l( Pow2( 14, tmp1 ) );
     326       33311 :                 exp1 = sub( 14, exp1 );
     327             : 
     328       33311 :                 L_tmp = L_mult0( fg_pred[band], tmp1 );                              /*12+exp1 */
     329       33311 :                 fg_pred[band] = round_fx_sat( L_shl_sat( L_tmp, sub( 16, exp1 ) ) ); /*12+exp1+16-exp1-16=12 */
     330       33311 :                 move16();
     331             :             }
     332             :         }
     333             :     }
     334             : 
     335       28288 :     return;
     336             : }

Generated by: LCOV version 1.14