LCOV - code coverage report
Current view: top level - lib_enc - vbr_average_rate_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main @ e95243e9e67ddeb69dddf129509de1b3d95b402e Lines: 37 89 41.6 %
Date: 2025-09-14 03:13:15 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 "cnst.h"    /* Common constants                       */
       8             : //#include "prot_fx.h"     /* Function prototypes                    */
       9             : #include "rom_com_fx.h"  /* Static table prototypes                */
      10             : #include "stat_enc.h"    /* Static table prototypes                */
      11             : #include "rom_com.h"     /* Common constants                       */
      12             : #include "prot_fx.h"     /* Function prototypes                    */
      13             : #include "prot_fx_enc.h" /* Function prototypes                    */
      14             : #include "basop_util.h"  /* Function prototypes                    */
      15             : 
      16             : 
      17             : #define RATEWIN 600 /* length of the rate control window. This is 600 active speech frames. This equals roughly 12s of active speech */
      18             : 
      19             : /*=================================================================================*/
      20             : /* FUNCTION      :  update_average_rate_fx                                                                                 */
      21             : /*---------------------------------------------------------------------------------*/
      22             : /* PURPOSE       :  SC-VBR update average data rate                                                                */
      23             : /*---------------------------------------------------------------------------------*/
      24             : /* INPUT ARGUMENTS  :                                                              */
      25             : /*   _ (struct DTFS_STRUCTURE_FX)                                                                                                  */
      26             : /*---------------------------------------------------------------------------------*/
      27             : /* INPUT/OUTPUT ARGUMENTS :                                                        */
      28             : /*  hSC_VBR->global_avr_rate_fx                                                                                  Q13            */
      29             : /*      hSC_VBR->sum_of_rates_fx                                                                                     Q13                */
      30             : /*      hSC_VBR->SNR_THLD_fx                                                                                         Q8                 */
      31             : /*      hSC_VBR->Q_to_F_fx                                                                                               Q0             */
      32             : /*      hSC_VBR->pattern_m_fx                                                                                                Q0                 */
      33             : /*      hSC_VBR->rate_control_fx                                                                                     Q0                 */
      34             : /*---------------------------------------------------------------------------------*/
      35             : /*/* OUTPUT ARGUMENTS :                                                                                                                    */
      36             : /*                    _ None                                                       */
      37             : /*---------------------------------------------------------------------------------*/
      38             : /* RETURN ARGUMENTS : _ None.                                                      */
      39             : /*---------------------------------------------------------------------------------*/
      40             : /* CALLED FROM :                                                                                                                                   */
      41             : /*=================================================================================*/
      42        1414 : void update_average_rate_fx(
      43             :     SC_VBR_ENC_HANDLE hSC_VBR, /* i/o: SC-VBR state structure  */
      44             :     const Word32 core_brate_fx /* i  : core bitrate         Q0 */
      45             : )
      46             : {
      47             :     Word32 avratetarg_fx; /* target rate for next RATEWIN active frames */
      48             :     Word32 target_fx;     /* target set by VBR_ADR_MAX_TARGET*RATEWIN*10 */
      49             :     Word16 tmp;
      50             :     Word32 L_tmp;
      51             :     Word32 L_tmp1, L_tmp2;
      52             : #ifndef ISSUE_1867_replace_overflow_libenc
      53             : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
      54             :     Flag Overflow = 0;
      55             :     move32();
      56             : #endif
      57             : #endif
      58             : 
      59             :     Word16 exp, recip, Qrecip;
      60             : 
      61        1414 :     IF( EQ_16( hSC_VBR->numactive, RATEWIN ) ) /* goes into rate control only the numactive ==RATEWIN. So rate control is triggered after each RATEWIN avtive frames */
      62             :     {
      63             :         /* after 1000 blocks of RATEWIN frames, we change the way we control the average rate by using
      64             :            st->global_avr_rate=0.99*st->global_avr_rate+0.01*st->sum_of_rates. This will avoid
      65             :            veriables growing indefinitely while providing a good long term average rate */
      66             : 
      67           2 :         IF( LT_32( hSC_VBR->global_frame_cnt, 1000 ) )
      68             :         {
      69           2 :             hSC_VBR->global_frame_cnt = add( hSC_VBR->global_frame_cnt, 1 );
      70           2 :             move16();
      71             : 
      72             :             /*st->global_avr_rate = (st->global_avr_rate * (st->global_frame_cnt-1) + st->sum_of_rates) / st->global_frame_cnt; */
      73           2 :             exp = norm_s( hSC_VBR->global_frame_cnt );
      74           2 :             tmp = shl( hSC_VBR->global_frame_cnt, exp ); /*Q0 + exp = exp*/
      75           2 :             recip = div_s( 16384, tmp );
      76           2 :             Qrecip = sub( 15, sub( exp, 14 ) );
      77             : 
      78           2 :             IF( GT_32( hSC_VBR->global_frame_cnt, 1 ) )
      79             :             {
      80           0 :                 tmp = div_s( sub( hSC_VBR->global_frame_cnt, 1 ), hSC_VBR->global_frame_cnt ); /*Q15*/
      81           0 :                 L_tmp1 = Mult_32_16( hSC_VBR->global_avr_rate_fx, tmp );                       /* Q13*Q15 = Q13 */
      82             : 
      83           0 :                 L_tmp2 = Mult_32_16( hSC_VBR->sum_of_rates_fx, recip ); /*Q13*Qrecip = 13+Qrecip+1-16 = Qrecip-2 */
      84             : 
      85           0 :                 hSC_VBR->global_avr_rate_fx = L_add( L_tmp1, L_shl( L_tmp2, sub( 13, ( sub( Qrecip, 2 ) ) ) ) ); /*Q13 */
      86           0 :                 move32();
      87             :             }
      88             :             ELSE
      89             :             {
      90           2 :                 hSC_VBR->global_avr_rate_fx = hSC_VBR->sum_of_rates_fx; /*handle the first frame*/
      91           2 :                 move32();
      92             :             }
      93             :             /* Q13 */
      94             :         }
      95             :         ELSE
      96             :         {
      97             :             /* st->global_avr_rate = 0.01f * st->sum_of_rates + 0.99f * st->global_avr_rate;
      98             :                         0.01f=328 (Q15) , .99f=32441 (Q15)
      99             :                         */
     100           0 :             hSC_VBR->global_avr_rate_fx = L_add( Mult_32_16( hSC_VBR->sum_of_rates_fx, 328 ), Mult_32_16( hSC_VBR->global_avr_rate_fx, 32441 ) ); /*Q13 */
     101           0 :             move32();
     102             :         }
     103             : 
     104             : 
     105           2 :         IF( hSC_VBR->sum_of_rates_fx == 0 )
     106             :         {
     107             :             /* st->sum_of_rates = (float) (RATEWIN * VBR_ADR_MAX_TARGET * 10); */
     108           0 :             hSC_VBR->sum_of_rates_fx = L_shl( L_mult0( RATEWIN, VBR_ADR_MAX_TARGET_x10_Q1 ), 12 ); /*Q13 */
     109           0 :             move32();
     110             :         }
     111             : 
     112             :         /* target = VBR_ADR_MAX_TARGET * 10 * RATEWIN; */
     113           2 :         target_fx = L_shl( L_mult0( VBR_ADR_MAX_TARGET_x10_Q1, RATEWIN ), 12 ); /*Q13 */
     114             : 
     115           2 :         IF( LT_32( target_fx, hSC_VBR->global_avr_rate_fx ) ) /* Action is taken to reduce the averge rate. Only initiated if the global rate > target rate */
     116             :         {
     117             :             /* Check the vad snr values to table the noisey/not noisey decision */
     118             : 
     119           2 :             test();
     120             :             /*67=17152 (Q8)*/
     121           2 :             IF( LT_16( hSC_VBR->SNR_THLD_fx, 17152 ) )
     122             :             /*Q8  */ /* Currently in QFF mode. The bumpup thresholds are slightly relaxed for noisy speech. */
     123             :             {
     124             :                 /*  Increase the threshold so the the bumpup procedure is done using the noisy thresholds.
     125             :                     Use 3.5 steps to quickly ramp up the rate control to reduce the settling time */
     126             : 
     127             :                 /*  st->SNR_THLD += 3.5f;  */
     128             :                 /*896=3.5 (Q8)*/
     129           0 :                 hSC_VBR->SNR_THLD_fx = add( hSC_VBR->SNR_THLD_fx, 896 ); /*Q8 */
     130           0 :                 move16();
     131             :             }
     132           2 :             ELSE IF( hSC_VBR->mode_QQF == 0 && GT_32( hSC_VBR->sum_of_rates_fx, target_fx ) ) /* Now SNR_THLD is in the max allowed. Sill the global average is higher and
     133             :                                                                             last RATEWIN frames have a higher agerage than the target rate. Now slightly
     134             :                                                                             more aggresive rate control is used by changing the mode to QQF. Still the
     135             :                                                                             same strict bumpups (more bumpups,higher rate) are used. */
     136             :             {
     137             :                 /* Kick in QQF mode */
     138           0 :                 hSC_VBR->mode_QQF = 1;
     139           0 :                 move16();
     140             :             }
     141           2 :             ELSE IF( GT_32( hSC_VBR->sum_of_rates_fx, target_fx ) ) /* Actions (1) and (2) are not sufficient to control the rate. Still the last RATEWIN active
     142             :                                                       frames have a higher average rate than the target rate. More aggresive rate control is
     143             :                                                       needed. At this point the rate_control flag is set. This will enable the more relaxed
     144             :                                                       bump up thresholds (less bump ups->reduced rate)*/
     145             :             {
     146             :                 /* Relaxed bump ups are used */
     147           2 :                 hSC_VBR->rate_control = 1;
     148           2 :                 move16();
     149             :                 /* This will be triggered only if the gloabl average rate is considerablly higher than the target rate.
     150             :                    Keep a higher threshold to avoid short term rate increases over the target rate. */
     151             :                 /* 3440640=420.0f Q(13) */
     152           2 :                 IF( GT_32( hSC_VBR->global_avr_rate_fx, L_add( target_fx, 3440640 ) ) ) /* Last resort rate control. This is a safer rate control mechanism by increasing NELPS */
     153             :                 {
     154           2 :                     hSC_VBR->Last_Resort = 1;
     155           2 :                     move16(); /* compute based on a larger window as the last resort */
     156             :                 }
     157             :                 ELSE
     158             :                 {
     159           0 :                     hSC_VBR->Last_Resort = 0;
     160           0 :                     move16();
     161             :                 }
     162             :             }
     163           0 :             ELSE IF( LT_32( hSC_VBR->sum_of_rates_fx, target_fx ) ) /* If the average rate of last RATEWIN frames is controlled by above actions, disable the most
     164             :                                                       aggresive rate control mechanisms. Still keep QQF mode as the global rate is not under
     165             :                                                       the target rate*/
     166             :             {
     167           0 :                 hSC_VBR->Last_Resort = 0;
     168           0 :                 move16();
     169           0 :                 hSC_VBR->mode_QQF = 1;
     170           0 :                 move16();
     171           0 :                 hSC_VBR->rate_control = 0;
     172           0 :                 move16();
     173             :             }
     174             :         }
     175             :         ELSE
     176             :         {
     177             :             /* floding back to lesser and leser aggresive rate control mechanisms gradually if global rate is under control */
     178           0 :             hSC_VBR->Last_Resort = 0;
     179           0 :             move16();
     180             : 
     181           0 :             IF( EQ_16( hSC_VBR->rate_control, 1 ) )
     182             :             {
     183           0 :                 hSC_VBR->rate_control = 0;
     184           0 :                 move16();
     185             :             }
     186           0 :             ELSE IF( EQ_16( hSC_VBR->mode_QQF, 1 ) ) /* now rate control is not active and still the global rate is below the target. so go to QFF mode */
     187             :             {
     188           0 :                 hSC_VBR->mode_QQF = 0;
     189           0 :                 move16();
     190             :             }
     191             :             ELSE
     192             :             { /*15360=60 (Q8)*/
     193           0 :                 IF( GE_16( hSC_VBR->SNR_THLD_fx, 15360 ) )
     194             :                 {                                                            /*384=1.5 (Q8)*/
     195           0 :                     hSC_VBR->SNR_THLD_fx = sub( hSC_VBR->SNR_THLD_fx, 384 ); /*Q8 */
     196           0 :                     move16();
     197             :                 }
     198             :                 ELSE
     199             :                 { /*15360=60 (Q8)*/
     200           0 :                     hSC_VBR->SNR_THLD_fx = 15360;
     201           0 :                     move16();
     202             :                 }
     203             :             }
     204             :         }
     205             :         /*983040=120 (Q13)*/
     206           2 :         IF( LT_32( hSC_VBR->global_avr_rate_fx, L_sub( target_fx, 983040 ) ) ) /* In QFF mode and global rate is less than target rate-0.2kbps. We can send some Q frames
     207             :                                                        to F frames to improve the quality */
     208             :         {
     209             :             /* kick in bouncing back from Q to F */
     210           0 :             hSC_VBR->Q_to_F = 1;
     211           0 :             move16();
     212             : 
     213             :             /* average rate for next 600ms = global_rate * 2 - rate of the past RATEWIN active frames */
     214             :             /* avratetarg = (float)((RATEWIN * 10) * 2 * VBR_ADR_MAX_TARGET - st->global_avr_rate); */
     215           0 :             avratetarg_fx = L_sub( L_shl( L_mult0( RATEWIN, VBR_ADR_MAX_TARGET_x10_Q1 ), 13 ), hSC_VBR->global_avr_rate_fx );
     216             :             /* Q13 */
     217             : 
     218             : 
     219             :             /* compute the percentage of frames that needed to be sent to F. st->pattern_m is computed as % val * 1000. eg. if % is 10%, then
     220             :                st->pattern_m=100 . Later this value is used in voiced.enc to bump up 10% of PPP frames to F frames. */
     221             :             /*  st->pattern_m = (short)(1000 * (avratetarg - 6.15f * RATEWIN * 10)/(10 * RATEWIN * 0.1f) ); */
     222             : 
     223           0 :             L_tmp = RATEWIN * VBR_ADR_MAX_TARGET_x10_Q1; /* Q0 * Q1 = Q1 */
     224           0 :             L_tmp = L_shl( L_tmp, 12 );                  /* Q1<<12 = Q13*/
     225           0 :             L_tmp = L_sub( avratetarg_fx, L_tmp );
     226             :             /*27307=(1000/(RATEWIN))Q14  */
     227           0 :             tmp = extract_h( L_shl( Mult_32_16( L_tmp, 27307 ), 4 ) ); /*(((Q13*Q0)<<4)>>16) = Q18>>16 = Q2*/
     228           0 :             hSC_VBR->pattern_m = tmp;
     229           0 :             move16();
     230             : 
     231           0 :             if ( hSC_VBR->pattern_m < 0 )
     232             :             {
     233           0 :                 hSC_VBR->pattern_m = 0;
     234           0 :                 move16(); /* no bump up will ever happen */
     235             :             }
     236             : 
     237           0 :             if ( GT_16( hSC_VBR->pattern_m, 1000 ) )
     238             :             {
     239           0 :                 hSC_VBR->pattern_m = 1000;
     240           0 :                 move16(); /* 10% of bump ups */
     241             :             }
     242             : 
     243           0 :             hSC_VBR->patterncount = 0;
     244           0 :             move16();
     245             :         }
     246             :         ELSE
     247             :         {
     248           2 :             hSC_VBR->Q_to_F = 0;
     249           2 :             move16();
     250             :         }
     251             : 
     252           2 :         hSC_VBR->sum_of_rates_fx = 0;
     253           2 :         move32();
     254           2 :         hSC_VBR->numactive = 0;
     255           2 :         move16();
     256             :     }
     257             : 
     258        1414 :     hSC_VBR->numactive = add( hSC_VBR->numactive, 1 );
     259        1414 :     move16();
     260             :     /* sum the total number of bits (in kbytes) * 10 here */
     261             :     /*st->sum_of_rates += (hSC_VBR->core_brate / 1000.0f) * 10; */
     262        1414 :     L_tmp = L_shl( Mult_32_16( core_brate_fx, 20972 ), 7 ); /*Q13*/
     263             : #ifdef ISSUE_1867_replace_overflow_libenc
     264        1414 :     hSC_VBR->sum_of_rates_fx = L_add_sat( hSC_VBR->sum_of_rates_fx, L_tmp );
     265             : #else
     266             :     hSC_VBR->sum_of_rates_fx = L_add_o( hSC_VBR->sum_of_rates_fx, L_tmp, &Overflow );
     267             : #endif
     268        1414 :     move32();
     269        1414 :     return;
     270             : }

Generated by: LCOV version 1.14