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 -- dec/rend @ 633e3f2e309758d10805ef21e0436356fe719b7a Lines: 131 135 97.0 %
Date: 2025-08-23 01:22:27 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        6201 : 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             : #ifndef ISSUE_1836_replace_overflow_libcom
      43             : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
      44             :     Flag Overflow = 0;
      45             :     move16();
      46             : #endif
      47             : #endif
      48             : 
      49      255221 :     FOR( band = 0; band < num_sfm; band++ )
      50             :     {
      51      249020 :         k = K[i_sort[band]];
      52      249020 :         move16();
      53             : 
      54      249020 :         IF( k > 0 )
      55             :         {
      56             :             /*  bw, bw_idx  only used if  k>0   */
      57      129046 :             bw = sfm_size[i_sort[band]];
      58      129046 :             move16(); // Extending for IVAS /* allowed. 8, 16, 24,32,40,48,64,80,96*/
      59             : 
      60      129046 :             bw_idx = ivas_band_len_idx[shr( bw, 3 )];
      61      129046 :             move16(); /* bw_idx=  0:                     8 */
      62      129046 :             xx = L_deposit_l( 0 );
      63      129046 :             shift = ivas_band_len_ener_shift[bw_idx];
      64      129046 :             move16();
      65     1760456 :             FOR( i = sfm_start[i_sort[band]]; i < sfm_end[i_sort[band]]; i++ )
      66             :             {
      67             :                 /*xx += xq[i] * xq[i]; */
      68     1631410 :                 tmp = shr( xq[i], shift );   /*15-shift */
      69     1631410 :                 xx = L_mac0( xx, tmp, tmp ); /*30-2*shift */
      70             :             }
      71             : 
      72      129046 :             IF( xx > 0 )
      73             :             {
      74             :                 /* Normalize synthesis to RMS=1.0 */
      75             :                 /*gp = (float) sqrt(bw / xx); */
      76      129046 :                 exp = norm_l( xx );
      77      129046 :                 L_tmp = L_shl( xx, exp ); /*2*(15-shift)+exp */
      78      129046 :                 exp = sub( 31, add( exp, sub( 30, shl( shift, 1 ) ) ) );
      79      129046 :                 L_tmp = Isqrt_lc( L_tmp, &exp ); /*31 - exp */
      80      129046 :                 Word16 norm = norm_s( bw );
      81      129046 :                 Word16 tmp1, tmp_exp = sub( 15, norm );
      82      129046 :                 tmp1 = Sqrt16( shl( bw, norm ), &tmp_exp );
      83      129046 :                 tmp1 = shr( tmp1, sub( sub( 15, tmp_exp ), Q11 ) );
      84      129046 :                 Mpy_32_16_ss( L_tmp, tmp1, &L_tmp, &lsb ); /*31-exp+11-15=27-exp */
      85             : 
      86             : #ifdef ISSUE_1836_replace_overflow_libcom
      87      129046 :                 gp = round_fx_sat( L_shl_sat( L_tmp, add( 1, exp ) ) ); /*27-exp+1+exp-16=12 */
      88             : #else
      89             :                 gp = round_fx_o( L_shl_o( L_tmp, add( 1, exp ), &Overflow ), &Overflow ); /*27-exp+1+exp-16=12 */
      90             : #endif
      91      129046 :                 test();
      92      129046 :                 test();
      93      129046 :                 IF( EQ_16( core, HQ_CORE ) && R != NULL && LE_16( R[i_sort[band]], 256 ) ) /* 256 is 32 in Q3 */
      94             :                 {
      95             :                     /*accuracy = ((float)k/(float)bw)*maxpulse[i_sort[band]]; */
      96      118805 :                     L_tmp = L_mult( k, inv_tbl_fx[bw] ); /*0+15+1 */
      97      118805 :                     exp2 = norm_l( L_tmp );
      98      118805 :                     tmp = round_fx( L_shl( L_tmp, exp2 ) );         /*16+exp2-16 */
      99      118805 :                     L_tmp = L_mult0( maxpulse[i_sort[band]], tmp ); /*0+exp2 */
     100      118805 :                     exp = norm_l( L_tmp );
     101      118805 :                     accuracy = round_fx( L_shl( L_tmp, exp ) ); /*exp2+exp-16=exp-16 */
     102      118805 :                     exp = add( exp, exp2 );
     103             : 
     104             :                     /*gp *= 1.0f - 0.05f / accuracy; */
     105      118805 :                     tmp = div_s( 13107, accuracy ); /* 0.05 in Q18 */
     106             : #ifdef ISSUE_1836_replace_overflow_libcom
     107      118805 :                     tmp = shr_sat( tmp, sub( 34, exp ) ); /*15+18-exp+16-15=34-exp */
     108             : #else
     109             :                     tmp = shr_sat( tmp, sub( 34, exp ) );                                 /*15+18-exp+16-15=34-exp */
     110             : #endif
     111      118805 :                     tmp = sub( 32767, tmp );
     112      118805 :                     tmp = s_max( 27554, tmp ); /* Limit attenuation to norm quantizer error, 2^-0.25 in Q15 */
     113      118805 :                     gp = mult_r( tmp, gp );    /*15+12+1-16=12 */
     114             :                 }
     115             : 
     116      129046 :                 fg_pred[band] = gp;
     117      129046 :                 move16();
     118             :             }
     119             :             ELSE
     120             :             {
     121           0 :                 fg_pred[band] = 0;
     122           0 :                 move16();
     123             :             }
     124             :         }
     125             :         ELSE
     126             :         {
     127      119974 :             fg_pred[band] = 0;
     128      119974 :             move16();
     129     3017044 :             FOR( i = sfm_start[i_sort[band]]; i < sfm_end[i_sort[band]]; i++ )
     130             :             {
     131     2897070 :                 y[i] = 0;
     132     2897070 :                 move16();
     133     2897070 :                 xq[i] = 0;
     134     2897070 :                 move16();
     135             :             }
     136             :         }
     137             :     }
     138             : 
     139        6201 :     return;
     140             : }
     141             : 
     142       22228 : void fine_gain_pred_fx(
     143             :     const Word16 *sfm_start, /* i  : Sub band start indices          */
     144             :     const Word16 *sfm_end,   /* i  : Sub band end indices            */
     145             :     const Word16 *sfm_size,  /* i  : Sub band bandwidths             */
     146             :     const Word16 *i_sort,    /* i  : Energy sorting indices          */
     147             :     const Word16 *K,         /* i  : Number of pulses per band       */
     148             :     const Word16 *maxpulse,  /* i  : Maximum pulse per band          */
     149             :     const Word16 *R,         /* i  : Bits per sub band           Q3  */
     150             :     const Word16 num_sfm,    /* i  : Number of sub bands             */
     151             :     Word16 *xq,              /* i/o: Quantized vector /quantized vector with finegain adj Q15*/
     152             :     Word16 *y,               /* i/o: Quantized vector (int)          */
     153             :     Word16 *fg_pred,         /* o  : Predicted fine gains        Q12 */
     154             :     const Word16 core        /* i  : Core                            */
     155             : )
     156             : {
     157             :     Word16 i, band;
     158             :     Word16 gp;
     159             :     Word32 xx;
     160             :     Word16 accuracy;
     161             :     Word16 k, bw;
     162             : 
     163             :     Word16 shift, bw_idx;
     164             :     Word16 tmp, exp, exp2;
     165             :     Word32 L_tmp;
     166             :     UWord16 lsb;
     167             : #ifndef ISSUE_1836_replace_overflow_libcom
     168             : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
     169             :     Flag Overflow = 0;
     170             :     move32();
     171             : #endif
     172             : #endif
     173             : 
     174      187285 :     FOR( band = 0; band < num_sfm; band++ )
     175             :     {
     176      165057 :         k = K[i_sort[band]];
     177      165057 :         move16();
     178             : 
     179      165057 :         IF( k > 0 )
     180             :         {
     181             :             /*  bw, bw_idx  only used if  k>0   */
     182      116921 :             bw = sfm_size[i_sort[band]];
     183      116921 :             move16(); /* allowed. 8, 16, 24,32,48,64,80,96 */
     184      116921 :             bw_idx = band_len_idx[shr( bw, 3 )];
     185      116921 :             move16(); /* bw_idx=  0:                     7 */
     186      116921 :             xx = L_deposit_l( 0 );
     187      116921 :             shift = band_len_ener_shift[bw_idx];
     188     2004873 :             FOR( i = sfm_start[i_sort[band]]; i < sfm_end[i_sort[band]]; i++ )
     189             :             {
     190             :                 /*xx += xq[i] * xq[i]; */
     191     1887952 :                 tmp = shr( xq[i], shift );   /*15-shift */
     192     1887952 :                 xx = L_mac0( xx, tmp, tmp ); /*30-2*shift */
     193             :             }
     194             : 
     195      116921 :             IF( xx > 0 )
     196             :             {
     197             :                 /* Normalize synthesis to RMS=1.0 */
     198             :                 /*gp = (float) sqrt(bw / xx); */
     199      116921 :                 exp = norm_l( xx );
     200      116921 :                 L_tmp = L_shl( xx, exp ); /*2*(15-shift)+exp */
     201      116921 :                 exp = sub( 31, add( exp, sub( 30, shl( shift, 1 ) ) ) );
     202      116921 :                 L_tmp = Isqrt_lc( L_tmp, &exp );                                     /*31 - exp */
     203      116921 :                 Mpy_32_16_ss( L_tmp, fine_gain_pred_sqrt_bw[bw_idx], &L_tmp, &lsb ); /*31-exp+11-15=27-exp */
     204             : #ifdef ISSUE_1836_replace_overflow_libcom
     205      116921 :                 gp = round_fx_sat( L_shl_sat( L_tmp, add( 1, exp ) ) ); /*27-exp+1+exp-16=12 */
     206             : #else
     207             :                 gp = round_fx_o( L_shl_o( L_tmp, add( 1, exp ), &Overflow ), &Overflow ); /*27-exp+1+exp-16=12 */
     208             : #endif
     209      116921 :                 test();
     210      116921 :                 test();
     211      116921 :                 IF( EQ_16( core, HQ_CORE ) && R != NULL && LE_16( R[i_sort[band]], 256 ) ) /* 256 is 32 in Q3 */
     212             :                 {
     213             :                     /*accuracy = ((float)k/(float)bw)*maxpulse[i_sort[band]]; */
     214        9713 :                     L_tmp = L_mult( k, inv_tbl_fx[bw] ); /*0+15+1 */
     215        9713 :                     exp2 = norm_l( L_tmp );
     216        9713 :                     tmp = round_fx( L_shl( L_tmp, exp2 ) );         /*16+exp2-16 */
     217        9713 :                     L_tmp = L_mult0( maxpulse[i_sort[band]], tmp ); /*0+exp2 */
     218        9713 :                     exp = norm_l( L_tmp );
     219        9713 :                     accuracy = round_fx( L_shl( L_tmp, exp ) ); /*exp2+exp-16=exp-16 */
     220        9713 :                     exp = add( exp, exp2 );
     221             : 
     222             :                     /*gp *= 1.0f - 0.05f / accuracy; */
     223        9713 :                     tmp = div_s( 13107, accuracy ); /* 0.05 in Q18 */
     224             : #ifdef ISSUE_1836_replace_overflow_libcom
     225        9713 :                     tmp = shr_sat( tmp, sub( 34, exp ) ); /*15+18-exp+16-15=34-exp */
     226             : #else
     227             :                     tmp = shr_sat( tmp, sub( 34, exp ) );                                 /*15+18-exp+16-15=34-exp */
     228             : #endif
     229        9713 :                     tmp = sub( 32767, tmp );
     230        9713 :                     tmp = s_max( 27554, tmp ); /* Limit attenuation to norm quantizer error, 2^-0.25 in Q15 */
     231        9713 :                     gp = mult_r( tmp, gp );    /*15+12+1-16=12 */
     232             :                 }
     233             : 
     234      116921 :                 fg_pred[band] = gp;
     235      116921 :                 move16();
     236             :             }
     237             :             ELSE
     238             :             {
     239           0 :                 fg_pred[band] = 0;
     240           0 :                 move16();
     241             :             }
     242             :         }
     243             :         ELSE
     244             :         {
     245       48136 :             fg_pred[band] = 0;
     246       48136 :             move16();
     247      836304 :             FOR( i = sfm_start[i_sort[band]]; i < sfm_end[i_sort[band]]; i++ )
     248             :             {
     249      788168 :                 y[i] = 0;
     250      788168 :                 move16();
     251      788168 :                 xq[i] = 0;
     252      788168 :                 move16();
     253             :             }
     254             :         }
     255             :     }
     256             : 
     257       22228 :     return;
     258             : }
     259             : 
     260             : /*--------------------------------------------------------------------------*
     261             :  * get_max_pulses()
     262             :  *
     263             :  * Find the maximum pulse height (in unit pulses) in each band
     264             :  *--------------------------------------------------------------------------*/
     265             : 
     266       27198 : void get_max_pulses_fx(
     267             :     const Word16 *band_start, /* i  : Sub band start indices    */
     268             :     const Word16 *band_end,   /* i  : Sub band end indices      */
     269             :     const Word16 *k_sort,     /* i  : Indices for sorting by energy */
     270             :     const Word16 *npulses,    /* i  : Pulses per sub band       */
     271             :     const Word16 BANDS,       /* i  : Number of bands           */
     272             :     Word16 *inp_vector,       /* i/o: Encoded shape vectors (int)Q0*/
     273             :     Word16 *maxpulse          /* o  : Maximum pulse height per band Q0*/
     274             : )
     275             : {
     276             :     Word16 i, k;
     277             :     Word16 npul;
     278             :     Word16 maxp;
     279             :     Word16 tmp;
     280             : 
     281      438837 :     FOR( k = 0; k < BANDS; k++ )
     282             :     {
     283      411639 :         npul = npulses[k_sort[k]];
     284      411639 :         move16();
     285      411639 :         maxp = 0;
     286      411639 :         move16();
     287      411639 :         IF( npul > 0 )
     288             :         {
     289     3698371 :             FOR( i = band_start[k_sort[k]]; i < band_end[k_sort[k]]; i++ )
     290             :             {
     291     3454842 :                 tmp = abs_s( inp_vector[i] );
     292     3454842 :                 if ( GT_16( tmp, maxp ) )
     293             :                 {
     294      369399 :                     maxp = tmp;
     295      369399 :                     move16();
     296             :                 }
     297             :             }
     298             :         }
     299      411639 :         maxpulse[k_sort[k]] = maxp;
     300      411639 :         move16();
     301             :     }
     302             : 
     303       27198 :     return;
     304             : }
     305             : 
     306             : /*--------------------------------------------------------------------------*
     307             :  * fine_gain_dec()
     308             :  *
     309             :  * Fine gain decoder. Decodes fine gain adjustments and applies correction to
     310             :  * predicted fine gains
     311             :  *--------------------------------------------------------------------------*/
     312             : 
     313       28429 : void fine_gain_dec_fx(
     314             :     Decoder_State *st,
     315             :     const Word16 *ord,       /* i  : Indices for energy order             */
     316             :     const Word16 num_sfm,    /* i  : Number of bands                      */
     317             :     const Word16 *gain_bits, /* i  : Gain adjustment bits per sub band    */
     318             :     Word16 *fg_pred          /* i/o: Predicted gains / Corrected gains    Q12*/
     319             : )
     320             : {
     321             :     Word16 band;
     322             :     Word16 gbits;
     323             :     Word16 idx, tmp1, exp1;
     324             :     Word16 gain_dbq;
     325             :     Word32 L_tmp;
     326             : 
     327             : 
     328      442506 :     FOR( band = 0; band < num_sfm; band++ )
     329             :     {
     330      414077 :         gbits = gain_bits[ord[band]];
     331      414077 :         move16();
     332      414077 :         IF( gbits > 0 )
     333             :         {
     334       33802 :             IF( fg_pred[band] != 0 )
     335             :             {
     336       33587 :                 idx = get_next_indice_fx( st, gbits );
     337       33587 :                 gain_dbq = finegain_fx[gbits - 1][idx];
     338       33587 :                 move16();
     339             : 
     340             :                 /* Update predicted gain with quantized correction */
     341       33587 :                 L_tmp = L_mult0( gain_dbq, 21771 ); /* 21771=0.05*log2(10) */ /* 14+17=31 */
     342       33587 :                 L_tmp = L_shr( L_tmp, 15 );
     343       33587 :                 tmp1 = L_Extract_lc( L_tmp, &exp1 );
     344       33587 :                 tmp1 = abs_s( tmp1 );
     345       33587 :                 tmp1 = extract_l( Pow2( 14, tmp1 ) );
     346       33587 :                 exp1 = sub( 14, exp1 );
     347             : 
     348       33587 :                 L_tmp = L_mult0( fg_pred[band], tmp1 );                              /*12+exp1 */
     349       33587 :                 fg_pred[band] = round_fx_sat( L_shl_sat( L_tmp, sub( 16, exp1 ) ) ); /*12+exp1+16-exp1-16=12 */
     350       33587 :                 move16();
     351             :             }
     352             :         }
     353             :     }
     354             : 
     355       28429 :     return;
     356             : }

Generated by: LCOV version 1.14