LCOV - code coverage report
Current view: top level - lib_enc - vbr_average_rate_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main enc/dec/rend @ 3b2f07138c61dcf997bbf4165d0882f794b2995f Lines: 39 91 42.9 %
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 "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        1418 : 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             : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
      53        1418 :     Flag Overflow = 0;
      54        1418 :     move32();
      55             : #endif
      56             : 
      57             :     Word16 exp, recip, Qrecip;
      58             : 
      59        1418 :     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 */
      60             :     {
      61             :         /* after 1000 blocks of RATEWIN frames, we change the way we control the average rate by using
      62             :            st->global_avr_rate=0.99*st->global_avr_rate+0.01*st->sum_of_rates. This will avoid
      63             :            veriables growing indefinitely while providing a good long term average rate */
      64             : 
      65           2 :         IF( LT_32( hSC_VBR->global_frame_cnt, 1000 ) )
      66             :         {
      67           2 :             hSC_VBR->global_frame_cnt = add( hSC_VBR->global_frame_cnt, 1 );
      68           2 :             move16();
      69             : 
      70             :             /*st->global_avr_rate = (st->global_avr_rate * (st->global_frame_cnt-1) + st->sum_of_rates) / st->global_frame_cnt; */
      71           2 :             exp = norm_s( hSC_VBR->global_frame_cnt );
      72           2 :             tmp = shl( hSC_VBR->global_frame_cnt, exp ); /*Q0 + exp = exp*/
      73           2 :             recip = div_s( 16384, tmp );
      74           2 :             Qrecip = sub( 15, sub( exp, 14 ) );
      75             : 
      76           2 :             IF( GT_32( hSC_VBR->global_frame_cnt, 1 ) )
      77             :             {
      78           0 :                 tmp = div_s( sub( hSC_VBR->global_frame_cnt, 1 ), hSC_VBR->global_frame_cnt ); /*Q15*/
      79           0 :                 L_tmp1 = Mult_32_16( hSC_VBR->global_avr_rate_fx, tmp );                       /* Q13*Q15 = Q13 */
      80             : 
      81           0 :                 L_tmp2 = Mult_32_16( hSC_VBR->sum_of_rates_fx, recip ); /*Q13*Qrecip = 13+Qrecip+1-16 = Qrecip-2 */
      82             : 
      83           0 :                 hSC_VBR->global_avr_rate_fx = L_add( L_tmp1, L_shl( L_tmp2, sub( 13, ( sub( Qrecip, 2 ) ) ) ) ); /*Q13 */
      84           0 :                 move32();
      85             :             }
      86             :             ELSE
      87             :             {
      88           2 :                 hSC_VBR->global_avr_rate_fx = hSC_VBR->sum_of_rates_fx; /*handle the first frame*/
      89           2 :                 move32();
      90             :             }
      91             :             /* Q13 */
      92             :         }
      93             :         ELSE
      94             :         {
      95             :             /* st->global_avr_rate = 0.01f * st->sum_of_rates + 0.99f * st->global_avr_rate;
      96             :                         0.01f=328 (Q15) , .99f=32441 (Q15)
      97             :                         */
      98           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 */
      99           0 :             move32();
     100             :         }
     101             : 
     102             : 
     103           2 :         IF( hSC_VBR->sum_of_rates_fx == 0 )
     104             :         {
     105             :             /* st->sum_of_rates = (float) (RATEWIN * VBR_ADR_MAX_TARGET * 10); */
     106           0 :             hSC_VBR->sum_of_rates_fx = L_shl( L_mult0( RATEWIN, VBR_ADR_MAX_TARGET_x10_Q1 ), 12 ); /*Q13 */
     107           0 :             move32();
     108             :         }
     109             : 
     110             :         /* target = VBR_ADR_MAX_TARGET * 10 * RATEWIN; */
     111           2 :         target_fx = L_shl( L_mult0( VBR_ADR_MAX_TARGET_x10_Q1, RATEWIN ), 12 ); /*Q13 */
     112             : 
     113           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 */
     114             :         {
     115             :             /* Check the vad snr values to table the noisey/not noisey decision */
     116             : 
     117           2 :             test();
     118             :             /*67=17152 (Q8)*/
     119           2 :             IF( LT_16( hSC_VBR->SNR_THLD_fx, 17152 ) )
     120             :             /*Q8  */ /* Currently in QFF mode. The bumpup thresholds are slightly relaxed for noisy speech. */
     121             :             {
     122             :                 /*  Increase the threshold so the the bumpup procedure is done using the noisy thresholds.
     123             :                     Use 3.5 steps to quickly ramp up the rate control to reduce the settling time */
     124             : 
     125             :                 /*  st->SNR_THLD += 3.5f;  */
     126             :                 /*896=3.5 (Q8)*/
     127           0 :                 hSC_VBR->SNR_THLD_fx = add( hSC_VBR->SNR_THLD_fx, 896 ); /*Q8 */
     128           0 :                 move16();
     129             :             }
     130           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
     131             :                                                                             last RATEWIN frames have a higher agerage than the target rate. Now slightly
     132             :                                                                             more aggresive rate control is used by changing the mode to QQF. Still the
     133             :                                                                             same strict bumpups (more bumpups,higher rate) are used. */
     134             :             {
     135             :                 /* Kick in QQF mode */
     136           0 :                 hSC_VBR->mode_QQF = 1;
     137           0 :                 move16();
     138             :             }
     139           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
     140             :                                                       frames have a higher average rate than the target rate. More aggresive rate control is
     141             :                                                       needed. At this point the rate_control flag is set. This will enable the more relaxed
     142             :                                                       bump up thresholds (less bump ups->reduced rate)*/
     143             :             {
     144             :                 /* Relaxed bump ups are used */
     145           2 :                 hSC_VBR->rate_control = 1;
     146           2 :                 move16();
     147             :                 /* This will be triggered only if the gloabl average rate is considerablly higher than the target rate.
     148             :                    Keep a higher threshold to avoid short term rate increases over the target rate. */
     149             :                 /* 3440640=420.0f Q(13) */
     150           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 */
     151             :                 {
     152           2 :                     hSC_VBR->Last_Resort = 1;
     153           2 :                     move16(); /* compute based on a larger window as the last resort */
     154             :                 }
     155             :                 ELSE
     156             :                 {
     157           0 :                     hSC_VBR->Last_Resort = 0;
     158           0 :                     move16();
     159             :                 }
     160             :             }
     161           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
     162             :                                                       aggresive rate control mechanisms. Still keep QQF mode as the global rate is not under
     163             :                                                       the target rate*/
     164             :             {
     165           0 :                 hSC_VBR->Last_Resort = 0;
     166           0 :                 move16();
     167           0 :                 hSC_VBR->mode_QQF = 1;
     168           0 :                 move16();
     169           0 :                 hSC_VBR->rate_control = 0;
     170           0 :                 move16();
     171             :             }
     172             :         }
     173             :         ELSE
     174             :         {
     175             :             /* floding back to lesser and leser aggresive rate control mechanisms gradually if global rate is under control */
     176           0 :             hSC_VBR->Last_Resort = 0;
     177           0 :             move16();
     178             : 
     179           0 :             IF( EQ_16( hSC_VBR->rate_control, 1 ) )
     180             :             {
     181           0 :                 hSC_VBR->rate_control = 0;
     182           0 :                 move16();
     183             :             }
     184           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 */
     185             :             {
     186           0 :                 hSC_VBR->mode_QQF = 0;
     187           0 :                 move16();
     188             :             }
     189             :             ELSE
     190             :             { /*15360=60 (Q8)*/
     191           0 :                 IF( GE_16( hSC_VBR->SNR_THLD_fx, 15360 ) )
     192             :                 {                                                            /*384=1.5 (Q8)*/
     193           0 :                     hSC_VBR->SNR_THLD_fx = sub( hSC_VBR->SNR_THLD_fx, 384 ); /*Q8 */
     194           0 :                     move16();
     195             :                 }
     196             :                 ELSE
     197             :                 { /*15360=60 (Q8)*/
     198           0 :                     hSC_VBR->SNR_THLD_fx = 15360;
     199           0 :                     move16();
     200             :                 }
     201             :             }
     202             :         }
     203             :         /*983040=120 (Q13)*/
     204           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
     205             :                                                        to F frames to improve the quality */
     206             :         {
     207             :             /* kick in bouncing back from Q to F */
     208           0 :             hSC_VBR->Q_to_F = 1;
     209           0 :             move16();
     210             : 
     211             :             /* average rate for next 600ms = global_rate * 2 - rate of the past RATEWIN active frames */
     212             :             /* avratetarg = (float)((RATEWIN * 10) * 2 * VBR_ADR_MAX_TARGET - st->global_avr_rate); */
     213           0 :             avratetarg_fx = L_sub( L_shl( L_mult0( RATEWIN, VBR_ADR_MAX_TARGET_x10_Q1 ), 13 ), hSC_VBR->global_avr_rate_fx );
     214             :             /* Q13 */
     215             : 
     216             : 
     217             :             /* 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
     218             :                st->pattern_m=100 . Later this value is used in voiced.enc to bump up 10% of PPP frames to F frames. */
     219             :             /*  st->pattern_m = (short)(1000 * (avratetarg - 6.15f * RATEWIN * 10)/(10 * RATEWIN * 0.1f) ); */
     220             : 
     221           0 :             L_tmp = RATEWIN * VBR_ADR_MAX_TARGET_x10_Q1; /* Q0 * Q1 = Q1 */
     222           0 :             L_tmp = L_shl( L_tmp, 12 );                  /* Q1<<12 = Q13*/
     223           0 :             L_tmp = L_sub( avratetarg_fx, L_tmp );
     224             :             /*27307=(1000/(RATEWIN))Q14  */
     225           0 :             tmp = extract_h( L_shl( Mult_32_16( L_tmp, 27307 ), 4 ) ); /*(((Q13*Q0)<<4)>>16) = Q18>>16 = Q2*/
     226           0 :             hSC_VBR->pattern_m = tmp;
     227           0 :             move16();
     228             : 
     229           0 :             if ( hSC_VBR->pattern_m < 0 )
     230             :             {
     231           0 :                 hSC_VBR->pattern_m = 0;
     232           0 :                 move16(); /* no bump up will ever happen */
     233             :             }
     234             : 
     235           0 :             if ( GT_16( hSC_VBR->pattern_m, 1000 ) )
     236             :             {
     237           0 :                 hSC_VBR->pattern_m = 1000;
     238           0 :                 move16(); /* 10% of bump ups */
     239             :             }
     240             : 
     241           0 :             hSC_VBR->patterncount = 0;
     242           0 :             move16();
     243             :         }
     244             :         ELSE
     245             :         {
     246           2 :             hSC_VBR->Q_to_F = 0;
     247           2 :             move16();
     248             :         }
     249             : 
     250           2 :         hSC_VBR->sum_of_rates_fx = 0;
     251           2 :         move32();
     252           2 :         hSC_VBR->numactive = 0;
     253           2 :         move16();
     254             :     }
     255             : 
     256        1418 :     hSC_VBR->numactive = add( hSC_VBR->numactive, 1 );
     257        1418 :     move16();
     258             :     /* sum the total number of bits (in kbytes) * 10 here */
     259             :     /*st->sum_of_rates += (hSC_VBR->core_brate / 1000.0f) * 10; */
     260        1418 :     L_tmp = L_shl( Mult_32_16( core_brate_fx, 20972 ), 7 ); /*Q13*/
     261        1418 :     hSC_VBR->sum_of_rates_fx = L_add_o( hSC_VBR->sum_of_rates_fx, L_tmp, &Overflow );
     262        1418 :     move32();
     263        1418 :     return;
     264             : }

Generated by: LCOV version 1.14