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 : }
|