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