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"
7 : #include "cnst.h"
8 : //#include "prot_fx.h"
9 : #include "rom_com.h"
10 : #include "prot_fx.h" /* Function prototypes */
11 : #include "prot_fx_enc.h" /* Function prototypes */
12 : #include "prot_fx_enc.h" /* Function prototypes */
13 : #include "ivas_prot_fx.h" /* Function prototypes */
14 :
15 : /*--------------------------------------------------------------------------*
16 : * Local constants
17 : *--------------------------------------------------------------------------*/
18 :
19 : #define MDCT_CLASSIFER_SMOOTH_FILT_COEFF 26214 /* 0.8 in Q15 */
20 : #define MDCT_CLASSIFER_THRESH_UP 13107 /* 1.6 in Q13 */
21 : #define MDCT_CLASSIFER_THRESH_DOWN 9011 /* 1.1 in Q13 */
22 : #define MDCT_CLASSIFER_HQ_LOCAL ( 3 << 13 ) /* Q13, Define those local to make the filtering operation robust in case classes numbers are changed */
23 : #define MDCT_CLASSIFER_TCX_LOCAL ( 1 << 13 ) /* Q13 */
24 : // IVAS_CODE
25 : #define GAIN2_START_WB 6
26 : #define GAIN3_START_WB 12
27 : #define GAIN4_START_WB 9
28 : #define H1_START_WB 17
29 : #define H2_START_WB 14
30 : #define H_LENGTH_WB 3
31 :
32 : #define GAIN2_START_SWB 8
33 : #define GAIN3_START_SWB 16
34 :
35 : #define GAIN2_START_SWB_RS 3
36 : #define GAIN3_START_SWB_RS 4
37 :
38 : #define GAIN4_START_SWB 12
39 : #define H1_START_SWB 25
40 : #define H2_START_SWB 20
41 : #define H_LENGTH_SWB 5
42 :
43 : /*-----------------------------------------------------------------------------
44 : * dft_mag_square_fx()
45 : *
46 : * Square magnitude of fft spectrum
47 : *----------------------------------------------------------------------------*/
48 82128 : static void dft_mag_square_fx(
49 : const Word16 x[], /* i : Input vector: re[0], re[1], ..., re[n/2], im[n/2 - 1], im[n/2 - 2], ..., im[1] Qx*/
50 : Word32 magSq[], /* o : Magnitude square spectrum */
51 : const Word16 n /* i : Input vector length */
52 : )
53 : {
54 : Word16 i, l;
55 : const Word16 *pRe, *pIm;
56 : Word32 *pMagSq, acc;
57 :
58 : /* Magnitude square at 0. */
59 82128 : pMagSq = &magSq[0];
60 82128 : pRe = &x[0]; // Qx
61 82128 : *pMagSq++ = L_mult0( *pRe, *pRe );
62 82128 : pRe++;
63 82128 : move32();
64 :
65 : /* From 1 to (N/2 - 1). */
66 82128 : l = sub( shr( n, 1 ), 1 ); /* N/2 - 1. */
67 82128 : pIm = &x[n];
68 82128 : pIm--;
69 10512384 : FOR( i = 0; i < l; i++ )
70 : {
71 10430256 : acc = L_mult0( *pRe, *pRe );
72 10430256 : pRe++;
73 10430256 : *pMagSq++ = L_mac0( acc, *pIm, *pIm ); // 2*Qx
74 10430256 : pIm--;
75 10430256 : move32();
76 : }
77 :
78 : /* The magnitude square at N/2 */
79 82128 : *pMagSq = L_mult0( *pRe, *pRe ); // 2*Qx
80 82128 : move32();
81 82128 : return;
82 : }
83 : /*-------------------------------------------------------------------*
84 : * mdct_classifier()
85 : *
86 : * MDCT signal classifier for HQ_CORE/TCX_20_CORE
87 : *-------------------------------------------------------------------*/
88 :
89 446 : Word16 mdct_classifier_fx( /* o: MDCT A/B decision */
90 : const Word16 *fft_buff, /* i: re[0], re[1], ..., re[n/2], im[n/2 - 1], im[n/2 - 2], ..., im[1] */
91 : Encoder_State *st_fx, /* i/o: Encoder state variable */
92 : Word32 *cldfbBuf_Ener, // enerBuffer_exp
93 : Word16 enerBuffer_exp,
94 : const Word32 brate /* i : current brate, IVAS: nominal bitrate, EVS: st->total_brate */
95 : )
96 : {
97 : Word16 c;
98 : Word32 magSq[129], *pMagSq, nf, pe;
99 : Word16 k;
100 : Word16 np;
101 : Word32 max_cand;
102 : Word16 max_i;
103 : Word32 p_energy_man, n_energy_man, man;
104 : Word16 p_energy_exp, n_energy_exp, expo;
105 : Word16 d_acc;
106 : Word16 pos_last;
107 : Word16 clas_sec;
108 : Word16 clas_final;
109 : Word16 condition1, condition2;
110 : Word16 factor;
111 : Word32 acc;
112 : UWord16 lsb16;
113 : UWord32 lsb32;
114 : Word32 gain1, gain2, gain3, gain11, gain4;
115 : Word32 peak_l, peak_h, avrg_l, avrg_h, peak_H1, avrg_H1, peak_H2, avrg_H2;
116 : Word16 condition3, condition4;
117 446 : Word32 gain1_tmp = 0, gain2_tmp = 0;
118 : Word16 exp, exp1, exp2, exp3;
119 : Word32 L_tmp, L_tmp1;
120 446 : TCX_ENC_HANDLE hTcxEnc = st_fx->hTcxEnc;
121 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
122 446 : Flag Overflow = 0;
123 : #endif
124 446 : test();
125 : {
126 :
127 446 : dft_mag_square_fx( fft_buff, magSq, 256 );
128 : }
129 446 : nf = L_add( magSq[0], 0 );
130 446 : pe = L_add( magSq[0], 0 );
131 446 : np = 0;
132 446 : move16();
133 446 : max_cand = L_negate( 1 );
134 446 : max_i = 0;
135 446 : move16();
136 446 : p_energy_man = L_deposit_l( 0 );
137 446 : n_energy_man = L_deposit_l( 0 );
138 446 : p_energy_exp = n_energy_exp = 32;
139 446 : move16();
140 446 : move16();
141 446 : d_acc = 0;
142 446 : move16();
143 446 : pos_last = -1;
144 446 : move16();
145 :
146 446 : pMagSq = magSq;
147 57534 : FOR( k = 0; k < 128; k++ )
148 : {
149 : /* NB: a*f + b*(1 - f) needs two multiplies
150 : * = (a - b)*f + b saves one multiply */
151 57088 : IF( GT_32( *( ++pMagSq ), nf ) )
152 : {
153 30701 : factor = 31385;
154 30701 : move16(); /* 0.9578 in Q15 */
155 : }
156 : ELSE
157 : {
158 26387 : factor = 21207;
159 26387 : move16(); /* 0.6472 in Q15 */
160 : }
161 57088 : acc = L_sub( nf, *pMagSq );
162 57088 : Mpy_32_16_ss( acc, factor, &acc, &lsb16 );
163 57088 : nf = L_add( acc, *pMagSq );
164 57088 : IF( GT_32( *pMagSq, pe ) )
165 : {
166 10758 : factor = 13840;
167 10758 : move16(); /* 0.42237 in Q15 */
168 : }
169 : ELSE
170 : {
171 46330 : factor = 26308;
172 46330 : move16(); /* 0.80285 in Q15 */
173 : }
174 57088 : acc = L_sub( pe, *pMagSq );
175 57088 : Mpy_32_16_ss( acc, factor, &acc, &lsb16 );
176 57088 : pe = L_add( acc, *pMagSq );
177 57088 : Mpy_32_16_ss( pe, 20972, &acc, &lsb16 ); /* 0.64 in Q15 */
178 57088 : IF( GT_32( *pMagSq, acc ) )
179 : {
180 17354 : IF( GT_32( *pMagSq, max_cand ) )
181 : {
182 13798 : max_cand = L_add( *pMagSq, 0 );
183 13798 : max_i = add( 2, k );
184 : }
185 : }
186 : ELSE
187 : {
188 39734 : IF( max_i > 0 )
189 : {
190 8535 : IF( ( np > 0 ) )
191 : {
192 8089 : d_acc = sub( add( d_acc, max_i ), pos_last );
193 : }
194 8535 : np = add( np, 1 );
195 8535 : pos_last = max_i;
196 8535 : move16();
197 : }
198 :
199 39734 : max_cand = L_negate( 1 );
200 39734 : max_i = 0;
201 39734 : move16();
202 : }
203 :
204 57088 : IF( pe != 0 )
205 : {
206 57088 : expo = norm_l( pe );
207 57088 : man = L_shl( pe, expo ); // expo
208 57088 : Mpy_32_32_ss( man, man, &man, &lsb32 ); /* pe square */
209 57088 : expo = shl( expo, 1 ); /* Multiply by 2 due to squaring. */
210 57088 : floating_point_add( &p_energy_man, &p_energy_exp, man, expo );
211 : }
212 57088 : IF( nf != 0 )
213 : {
214 57082 : expo = norm_l( nf );
215 57082 : man = L_shl( nf, expo );
216 57082 : Mpy_32_32_ss( man, man, &man, &lsb32 ); /* nf square */
217 57082 : expo = shl( expo, 1 ); /* Multiply by 2 due to squaring. */
218 57082 : floating_point_add( &n_energy_man, &n_energy_exp, man, expo );
219 : }
220 : }
221 :
222 446 : gain1 = L_deposit_l( 0 );
223 446 : gain2 = L_deposit_l( 0 );
224 446 : gain3 = L_deposit_l( 0 );
225 :
226 4014 : FOR( k = 0; k < 8; k++ )
227 : {
228 3568 : gain1 = L_add( gain1, L_shr( cldfbBuf_Ener[k], 3 ) );
229 3568 : gain2 = L_add( gain2, L_shr( cldfbBuf_Ener[k + 8], 3 ) );
230 3568 : gain3 = L_add( gain3, L_shr( cldfbBuf_Ener[k + 16], 3 ) );
231 : }
232 :
233 : /* gain11 = 8*(gain1 - cldfbBuf_Ener[0]/8)/7; */
234 446 : acc = L_shr( cldfbBuf_Ener[0], 3 );
235 446 : acc = L_sub( gain1, acc );
236 446 : acc = Mult_32_16( acc, 4681 /*(1/7).Q15*/ );
237 446 : gain11 = L_shl( acc, 3 );
238 446 : gain4 = L_deposit_l( 0 );
239 5798 : FOR( k = 0; k < 12; k++ )
240 : {
241 5352 : gain4 = L_add( gain4, Mult_32_16( cldfbBuf_Ener[k + 12], 2731 /*(1/12).Q15*/ ) );
242 : }
243 :
244 :
245 446 : peak_H1 = L_add( cldfbBuf_Ener[25], 0 );
246 446 : Mpy_32_16_ss( cldfbBuf_Ener[25], 6554 /*0.4.Q15*/, &avrg_H1, &lsb16 );
247 2230 : FOR( k = 1; k < 5; k++ )
248 : {
249 1784 : IF( GT_32( cldfbBuf_Ener[k + 25], peak_H1 ) )
250 : {
251 452 : peak_H1 = L_add( cldfbBuf_Ener[k + 25], 0 );
252 : }
253 1784 : avrg_H1 = L_add( avrg_H1, Mult_32_16( cldfbBuf_Ener[k + 25], 6554 /*0.4.Q15*/ ) );
254 : }
255 :
256 446 : peak_H2 = L_add( cldfbBuf_Ener[20], 0 );
257 446 : Mpy_32_16_ss( cldfbBuf_Ener[20], 6554 /*0.4.Q15*/, &avrg_H2, &lsb16 );
258 2230 : FOR( k = 1; k < 5; k++ )
259 : {
260 1784 : IF( GT_32( cldfbBuf_Ener[k + 20], peak_H2 ) )
261 : {
262 457 : peak_H2 = L_add( cldfbBuf_Ener[k + 20], 0 );
263 : }
264 1784 : avrg_H2 = L_add( avrg_H2, Mult_32_16( cldfbBuf_Ener[k + 20], 6554 /*0.4.Q15*/ ) );
265 : }
266 : // End
267 446 : peak_l = L_deposit_l( 0 );
268 446 : avrg_l = L_deposit_l( 0 );
269 446 : peak_h = L_deposit_l( 0 );
270 446 : avrg_h = L_deposit_l( 0 );
271 14718 : FOR( k = 0; k < 32; k++ )
272 : {
273 14272 : avrg_l = L_add( avrg_l, L_shr( magSq[k + 20], 5 ) );
274 14272 : avrg_h = L_add( avrg_h, L_shr( magSq[k + 96], 5 ) );
275 14272 : IF( GT_32( magSq[k + 20], peak_l ) )
276 : {
277 2130 : peak_l = L_add( magSq[k + 20], 0 );
278 : }
279 14272 : IF( GT_32( magSq[k + 96], peak_h ) )
280 : {
281 1954 : peak_h = L_add( magSq[k + 96], 0 );
282 : }
283 : }
284 :
285 : /* Compute: d_acc - 12*(np -1). */
286 446 : acc = L_deposit_l( d_acc );
287 446 : IF( L_msu( acc, 12 / 2, sub( np, 1 ) ) > 0 ) /* 12/2 is to compensate the fractional mode multiply */
288 : {
289 1 : condition1 = 1; /* Signifies: d_acc/(np - 1) > 12 */
290 1 : move16();
291 : }
292 : ELSE
293 : {
294 445 : condition1 = 0; /* Signifies: d_acc/(np - 1) <= 12 */
295 445 : move16();
296 : /* NB: For np = 0 or 1, it fits this condition. */
297 : }
298 :
299 : /* Compute: p_energy - 147.87276*n_energy. */
300 446 : IF( n_energy_man != 0 )
301 : {
302 446 : Mpy_32_16_ss( n_energy_man, 18928, &acc, &lsb16 ); /* 147.87276 in Q7 */
303 446 : expo = sub( n_energy_exp, 15 - 7 ); /* Due to 18928 in Q7 */
304 446 : acc = L_negate( acc ); /* To facilitate the following floating_point_add() to perform subtraction. */
305 446 : floating_point_add( &acc, &expo, p_energy_man, p_energy_exp );
306 : }
307 : ELSE
308 : {
309 0 : acc = L_deposit_l( 0 );
310 : }
311 446 : IF( acc > 0 )
312 : {
313 39 : condition2 = 1; /* Signifies: p_energy / n_energy > 147.87276 */
314 39 : move16();
315 : }
316 : ELSE
317 : {
318 407 : condition2 = 0; /* Signifies: p_energy / n_energy <= 147.87276 */
319 407 : move16();
320 : }
321 :
322 446 : condition3 = 0;
323 446 : move16();
324 446 : condition4 = 0;
325 446 : move16();
326 :
327 446 : L_tmp = Mult_32_16( peak_h, 12603 /*1/2.56.Q15*/ );
328 446 : IF( GT_32( peak_l, L_tmp ) )
329 : {
330 357 : exp = norm_l( peak_l );
331 : }
332 : ELSE
333 : {
334 89 : exp = norm_l( L_tmp );
335 : }
336 446 : IF( GT_32( avrg_h, avrg_l ) )
337 : {
338 187 : exp1 = norm_l( avrg_h );
339 : }
340 : ELSE
341 : {
342 259 : exp1 = norm_l( avrg_l );
343 : }
344 :
345 446 : L_tmp1 = Mult_32_16( peak_l, 12603 /*1/2.56.Q15*/ );
346 446 : IF( GT_32( peak_h, L_tmp1 ) )
347 : {
348 217 : exp2 = norm_l( peak_h );
349 : }
350 : ELSE
351 : {
352 229 : exp2 = norm_l( L_tmp1 );
353 : }
354 :
355 446 : test();
356 446 : test();
357 446 : test();
358 446 : test();
359 446 : IF( GT_32( Mult_32_16( gain3, 27307 ), gain2 ) || ( GE_32( gain3, Mult_32_16( gain2, 26214 ) ) && GT_32( peak_H1, L_shl_o( avrg_H1, 1, &Overflow ) ) ) || ( LT_32( Mult_32_32( L_shl_o( peak_l, exp, &Overflow ), L_shl_o( avrg_h, exp1, &Overflow ) ), Mult_32_32( L_shl_o( L_tmp, exp, &Overflow ), L_shl_o( avrg_l, exp1, &Overflow ) ) ) || GT_32( Mult_32_32( L_shl_o( L_tmp1, exp2, &Overflow ), L_shl_o( avrg_h, exp1, &Overflow ) ), Mult_32_32( L_shl_o( peak_h, exp2, &Overflow ), L_shl_o( avrg_l, exp1, &Overflow ) ) ) ) )
360 : {
361 134 : condition3 = 1;
362 134 : move16();
363 : }
364 :
365 446 : L_tmp = Mult_32_16( peak_h, 12800 /*(1/2.56).Q15*/ );
366 446 : IF( GT_32( peak_l, L_tmp ) )
367 : {
368 356 : exp = norm_l( peak_l );
369 : }
370 : ELSE
371 : {
372 90 : exp = norm_l( L_tmp );
373 : }
374 :
375 446 : L_tmp1 = Mult_32_16( peak_l, 6400 /*(1/5.12).Q15*/ );
376 446 : IF( GT_32( peak_h, L_tmp1 ) )
377 : {
378 253 : exp2 = norm_l( peak_h );
379 : }
380 : ELSE
381 : {
382 193 : exp2 = norm_l( L_tmp1 );
383 : }
384 :
385 446 : IF( GT_32( peak_h, L_shl( L_tmp1, 1 ) ) )
386 : {
387 217 : exp3 = norm_l( peak_h );
388 : }
389 : ELSE
390 : {
391 229 : exp3 = sub( norm_l( L_tmp1 ), 1 );
392 : }
393 :
394 446 : test();
395 446 : test();
396 446 : test();
397 446 : test();
398 446 : test();
399 446 : test();
400 446 : test();
401 446 : test();
402 446 : test();
403 446 : IF( ( GT_32( gain4, Mult_32_16( gain11, 26214 /*0.8.Q15*/ ) ) && GT_32( Mult_32_32( L_shl( peak_l, exp ), L_shl( avrg_h, exp1 ) ), Mult_32_32( L_shl( Mult_32_16( peak_h, 12800 /*(1/2.56).Q15*/ ), exp ), L_shl( avrg_l, exp1 ) ) ) && LT_32( Mult_32_32( L_shl( Mult_32_16( peak_l, 6400 /*(1/5.12).Q15*/ ), exp2 ), L_shl( avrg_h, exp1 ) ), Mult_32_32( L_shl( peak_h, exp2 ), L_shl( avrg_l, exp1 ) ) ) ) || ( GT_32( gain4, Mult_32_16( gain11, 9830 /*0.3.Q15*/ ) ) && LT_32( Mult_32_16( peak_h, 21845 /*(1/1.5).Q15*/ ), avrg_h ) && LT_32( Mult_32_16( peak_H2, 21845 /*(1/1.5).Q15*/ ), avrg_H2 ) ) || ( LT_32( Mult_32_32( L_shl( peak_l, exp ), L_shl( avrg_h, exp1 ) ), Mult_32_32( L_shl( Mult_32_16( peak_h, 12800 /*(1/2.56).Q15*/ ), exp ), L_shl( avrg_l, exp1 ) ) ) && GT_32( Mult_32_16( peak_h, 21845 /*(1/1.5).Q15*/ ), avrg_h ) ) || ( GT_32( Mult_32_32( L_shl( Mult_32_16( peak_l, 12800 /*(1/2.56).Q15*/ ), exp3 ), L_shl( avrg_h, exp1 ) ), Mult_32_32( L_shl( peak_h, exp3 ), L_shl( avrg_l, exp1 ) ) ) > 0 && LT_32( Mult_32_16( peak_h, 21845 /*(1/1.5).Q15*/ ), avrg_h ) ) )
404 : {
405 25 : condition4 = 1;
406 25 : move16();
407 : }
408 :
409 446 : test();
410 446 : test();
411 446 : test();
412 446 : test();
413 446 : IF( ( GE_32( brate, HQ_MDCTCLASS_CROSSOVER_BRATE ) && GT_32( st_fx->input_Fs, 16000 ) && ( s_xor( condition1, condition2 ) != 0 || condition3 ) ) || ( ( LT_32( brate, HQ_MDCTCLASS_CROSSOVER_BRATE ) || EQ_32( st_fx->input_Fs, 16000 ) ) && condition4 ) )
414 : {
415 25 : c = MDCT_CLASSIFER_HQ_LOCAL; /* Q13 */
416 25 : move16();
417 : }
418 : ELSE
419 : {
420 421 : c = MDCT_CLASSIFER_TCX_LOCAL; /* Q13 */
421 421 : move16();
422 : }
423 :
424 : /* Smooth decision from instantaneous decision*/
425 446 : acc = L_mult( hTcxEnc->clas_sec_old_fx, MDCT_CLASSIFER_SMOOTH_FILT_COEFF ); /* st_fx->clas_sec_old_fx in Q13 */
426 446 : clas_sec = mac_r( acc, c, 0x7fff /*1.Q15*/ - MDCT_CLASSIFER_SMOOTH_FILT_COEFF ); /* clas_sec and c are in Q13 */
427 : /* Do thresholding with hysteresis */
428 446 : IF( GT_16( st_fx->last_enerBuffer_exp, enerBuffer_exp ) )
429 : {
430 154 : gain1_tmp = L_shr( gain1, sub( st_fx->last_enerBuffer_exp, enerBuffer_exp ) ); // st_fx->last_enerBuffer_exp
431 154 : move32();
432 154 : gain2_tmp = L_shr( gain2, sub( st_fx->last_enerBuffer_exp, enerBuffer_exp ) ); // st_fx->last_enerBuffer_exp
433 154 : move32();
434 : }
435 : ELSE
436 : {
437 292 : hTcxEnc->last_gain1 = L_shr( hTcxEnc->last_gain1, sub( enerBuffer_exp, st_fx->last_enerBuffer_exp ) ); // enerBuffer_exp
438 292 : move32();
439 292 : hTcxEnc->last_gain2 = L_shr( hTcxEnc->last_gain2, sub( enerBuffer_exp, st_fx->last_enerBuffer_exp ) ); // enerBuffer_exp
440 292 : move32();
441 292 : gain1_tmp = gain1;
442 292 : move32();
443 292 : gain2_tmp = gain2;
444 292 : move32();
445 : }
446 :
447 446 : test();
448 446 : test();
449 446 : test();
450 446 : test();
451 446 : test();
452 446 : test();
453 446 : IF( ( EQ_16( hTcxEnc->clas_final_old, HQ_CORE ) || EQ_16( hTcxEnc->clas_final_old, TCX_20_CORE ) ) && ( ( GT_32( hTcxEnc->last_gain1, L_shr( gain1_tmp, 1 ) ) && LT_32( hTcxEnc->last_gain1, L_shl_o( gain1_tmp, 1, &Overflow ) ) ) && ( GT_32( hTcxEnc->last_gain2, L_shr( gain2_tmp, 1 ) ) && LT_32( hTcxEnc->last_gain2, L_shl_o( gain2_tmp, 1, &Overflow ) ) ) ) )
454 : {
455 205 : clas_final = hTcxEnc->clas_final_old;
456 205 : move16();
457 : }
458 241 : ELSE IF( GT_16( clas_sec, hTcxEnc->clas_sec_old_fx ) && GT_16( clas_sec, MDCT_CLASSIFER_THRESH_UP ) ) /* Going up? */
459 : {
460 7 : clas_final = HQ_CORE; /* Q0 */
461 7 : move16();
462 : }
463 234 : ELSE IF( LT_16( clas_sec, MDCT_CLASSIFER_THRESH_DOWN ) ) /* Going down */
464 : {
465 166 : clas_final = TCX_20_CORE;
466 166 : move16();
467 : }
468 : ELSE
469 : {
470 68 : clas_final = hTcxEnc->clas_final_old;
471 68 : move16();
472 : }
473 :
474 446 : test();
475 446 : test();
476 446 : test();
477 : /* Prevent the usage of MDCTA on noisy-speech or inactive */
478 446 : if ( EQ_16( st_fx->mdct_sw_enable, MODE2 ) && ( EQ_16( st_fx->flag_noisy_speech_snr, 1 ) || st_fx->vad_flag == 0 ) && EQ_16( clas_final, HQ_CORE ) )
479 : {
480 0 : clas_final = TCX_20_CORE;
481 0 : move16();
482 : }
483 : /* Restrict usage of HQ_core to supported operating range */
484 : /* EVS: brate == st->total_brate */
485 : /* IVAS: brate is the nominal bitrate while st->total_brate may fluctuate. This sets a hard limit for HQ at HQ_16k40 */
486 446 : test();
487 446 : test();
488 446 : test();
489 446 : if ( LE_32( st_fx->total_brate, HQ_16k40 ) || LT_32( brate, HQ_16k40 ) || EQ_16( st_fx->bwidth, NB ) || GT_32( brate, IVAS_48k ) )
490 : {
491 0 : clas_final = TCX_20_CORE;
492 0 : move16();
493 : }
494 :
495 : /* Memory update */
496 446 : hTcxEnc->clas_sec_old_fx = clas_sec;
497 446 : move16(); /* Q13 */
498 446 : hTcxEnc->clas_final_old = clas_final;
499 446 : move16(); /* Q0 */
500 446 : hTcxEnc->last_gain1 = gain1;
501 446 : move32();
502 446 : hTcxEnc->last_gain2 = gain2;
503 446 : move32();
504 446 : st_fx->last_enerBuffer_exp = enerBuffer_exp;
505 446 : move16();
506 :
507 446 : return clas_final; /* Q0 */
508 : }
509 :
510 90247 : Word16 mdct_classifier_ivas_fx(
511 : Encoder_State *st, /* i/o: Encoder state variable */
512 : const Word16 *fft_buff, /* i : FFT spectrum from fft_rel */
513 : const Word32 enerBuffer[], /* i : energy buffer enerBuffer_exp*/
514 : Word16 enerBuffer_exp,
515 : const Word32 brate /* i : current brate, IVAS: nominal bitrate, EVS: st->total_brate */
516 : )
517 : {
518 : Word16 c;
519 : Word32 X[129];
520 : Word16 k;
521 : Word32 nf;
522 : Word32 pe;
523 : Word16 np;
524 : Word32 max_cand;
525 : Word16 max_i;
526 : Word32 p_energy_man, n_energy_man, man;
527 : Word16 p_energy_exp, n_energy_exp, expo;
528 : Word16 d_acc;
529 : Word16 pos_last;
530 : Word16 clas_sec;
531 : Word16 clas_final;
532 : Word16 i;
533 : Word32 gain1, gain2, gain3, gain11, gain4;
534 : Word32 peak_l, peak_h, avrg_l, avrg_h, peak_H1, avrg_H1, peak_H2, avrg_H2;
535 : Word16 condition1, condition2;
536 : Word16 condition3, condition4;
537 : Word16 gain2_start, gain3_start, gain4_start, H1_start, H2_start, H_length;
538 : Word16 factor;
539 : Word32 acc;
540 : UWord16 lsb16;
541 : UWord32 lsb32;
542 90247 : TCX_ENC_HANDLE hTcxEnc = st->hTcxEnc;
543 : Word16 exp, exp1, exp2, exp3;
544 90247 : Word32 gain1_tmp = 0, gain2_tmp = 0;
545 : Word32 L_tmp, L_tmp1;
546 90247 : Flag Overflow = 0;
547 90247 : move16();
548 90247 : move16();
549 90247 : move16();
550 :
551 90247 : test();
552 90247 : IF( EQ_32( st->input_Fs, 32000 ) || EQ_32( st->input_Fs, 48000 ) )
553 : {
554 87181 : gain2_start = GAIN2_START_SWB;
555 87181 : gain3_start = GAIN3_START_SWB;
556 87181 : gain4_start = GAIN4_START_SWB;
557 87181 : H1_start = H1_START_SWB;
558 87181 : H2_start = H2_START_SWB;
559 87181 : H_length = H_LENGTH_SWB;
560 87181 : move16();
561 87181 : move16();
562 87181 : move16();
563 87181 : move16();
564 87181 : move16();
565 87181 : move16();
566 : }
567 3066 : ELSE IF( EQ_32( st->input_Fs, 16000 ) )
568 : {
569 3066 : gain2_start = GAIN2_START_WB;
570 3066 : gain3_start = GAIN3_START_WB;
571 3066 : gain4_start = GAIN4_START_WB;
572 3066 : H1_start = H1_START_WB;
573 3066 : H2_start = H2_START_WB;
574 3066 : H_length = H_LENGTH_WB;
575 3066 : move16();
576 3066 : move16();
577 3066 : move16();
578 3066 : move16();
579 3066 : move16();
580 3066 : move16();
581 : }
582 : ELSE
583 : {
584 0 : assert( !"Unknown sampling frequency in MDCT_classifier" );
585 : H1_start = -1; /* to avoid compilation warning */
586 : H2_start = -1; /* to avoid compilation warning */
587 : H_length = -1; /* to avoid compilation warning */
588 : gain2_start = -1; /* to avoid compilation warning */
589 : gain3_start = -1; /* to avoid compilation warning */
590 : gain4_start = -1; /* to avoid compilation warning */
591 : move16();
592 : move16();
593 : move16();
594 : move16();
595 : move16();
596 : move16();
597 : }
598 :
599 90247 : IF( NE_16( st->element_mode, IVAS_CPE_DFT ) )
600 : {
601 81682 : dft_mag_square_fx( fft_buff, X, 256 );
602 : }
603 : ELSE
604 : {
605 : Word16 norm_val;
606 :
607 8565 : norm_val = i_mult( L_FFT, shr( L_FFT, 2 ) );
608 1104885 : FOR( k = 0; k < 128; k++ )
609 : {
610 1096320 : X[k + 1] = Mpy_32_16_1( st->Bin_E_old_fx[k], norm_val );
611 : }
612 8565 : X[0] = X[1];
613 8565 : move32();
614 : }
615 :
616 90247 : nf = L_add( X[0], 0 );
617 90247 : pe = L_add( X[0], 0 );
618 90247 : np = 0;
619 90247 : move16();
620 :
621 90247 : max_cand = L_negate( 1 );
622 90247 : max_i = 0;
623 90247 : move16();
624 :
625 90247 : p_energy_man = L_deposit_l( 0 );
626 90247 : n_energy_man = L_deposit_l( 0 );
627 90247 : p_energy_exp = n_energy_exp = 32;
628 90247 : move16();
629 90247 : move16();
630 90247 : d_acc = 0;
631 90247 : move16();
632 90247 : pos_last = -1;
633 90247 : move16();
634 :
635 11641863 : FOR( k = 0; k < 128; k++ )
636 : {
637 : /* NB: a*f + b*(1 - f) needs two multiplies
638 : * = (a - b)*f + b saves one multiply */
639 11551616 : IF( GT_32( X[k + 1], nf ) )
640 : {
641 5616217 : factor = 31385;
642 5616217 : move16(); /* 0.9578 in Q15 */
643 : }
644 : ELSE
645 : {
646 5935399 : factor = 21207;
647 5935399 : move16(); /* 0.6472 in Q15 */
648 : }
649 :
650 11551616 : acc = L_sub( nf, X[k + 1] );
651 11551616 : Mpy_32_16_ss( acc, factor, &acc, &lsb16 );
652 11551616 : nf = L_add( acc, X[k + 1] );
653 :
654 11551616 : IF( GT_32( X[k + 1], pe ) )
655 : {
656 1993322 : factor = 13840;
657 1993322 : move16(); /* 0.42237 in Q15 */
658 : }
659 : ELSE
660 : {
661 9558294 : factor = 26308;
662 9558294 : move16(); /* 0.80285 in Q15 */
663 : }
664 :
665 11551616 : acc = L_sub( pe, X[k + 1] );
666 11551616 : Mpy_32_16_ss( acc, factor, &acc, &lsb16 );
667 11551616 : pe = L_add( acc, X[k + 1] );
668 11551616 : Mpy_32_16_ss( pe, 20972, &acc, &lsb16 ); /* 0.64 in Q15 */
669 :
670 11551616 : IF( GT_32( X[k + 1], acc ) )
671 : {
672 3127775 : IF( GT_32( X[k + 1], max_cand ) )
673 : {
674 2551637 : max_cand = X[k + 1];
675 2551637 : move32();
676 2551637 : max_i = add( 2, k );
677 : }
678 : }
679 : ELSE
680 : {
681 8423841 : IF( max_i > 0 )
682 : {
683 1614813 : IF( np > 0 )
684 : {
685 1524566 : d_acc = sub( add( d_acc, max_i ), pos_last );
686 : }
687 1614813 : np = add( np, 1 );
688 1614813 : pos_last = max_i;
689 1614813 : move16();
690 : }
691 :
692 8423841 : max_cand = L_negate( 1 );
693 8423841 : max_i = 0;
694 8423841 : move16();
695 : }
696 :
697 11551616 : IF( pe != 0 )
698 : {
699 11551616 : expo = norm_l( pe );
700 11551616 : man = L_shl( pe, expo ); // expo
701 11551616 : Mpy_32_32_ss( man, man, &man, &lsb32 ); /* pe square */
702 11551616 : expo = shl( expo, 1 ); /* Multiply by 2 due to squaring. */
703 11551616 : floating_point_add( &p_energy_man, &p_energy_exp, man, expo );
704 : }
705 11551616 : IF( nf != 0 )
706 : {
707 11551603 : expo = norm_l( nf );
708 11551603 : man = L_shl( nf, expo );
709 11551603 : Mpy_32_32_ss( man, man, &man, &lsb32 ); /* nf square */
710 11551603 : expo = shl( expo, 1 ); /* Multiply by 2 due to squaring. */
711 11551603 : floating_point_add( &n_energy_man, &n_energy_exp, man, expo );
712 : }
713 : }
714 :
715 90247 : gain1 = L_deposit_l( 0 );
716 90247 : gain2 = L_deposit_l( 0 );
717 90247 : gain3 = L_deposit_l( 0 );
718 :
719 806091 : FOR( i = 0; i < gain2_start; i++ )
720 : {
721 715844 : IF( EQ_16( gain2_start, GAIN2_START_SWB ) )
722 : {
723 697448 : gain1 = L_add( gain1, L_shr( enerBuffer[i], 3 ) ); // enerBuffer_exp - 3
724 697448 : gain2 = L_add( gain2, L_shr( enerBuffer[gain2_start + i], 3 ) ); // enerBuffer_exp - 3
725 697448 : gain3 = L_add( gain3, L_shr( enerBuffer[gain3_start + i], 3 ) ); // enerBuffer_exp - 3
726 : }
727 : ELSE
728 : {
729 18396 : gain1 = L_add( gain1, Mult_32_16( enerBuffer[i], 5461 ) ); // enerBuffer_exp
730 18396 : gain2 = L_add( gain2, Mult_32_16( enerBuffer[gain2_start + i], 5461 /*0.16.Q15*/ ) ); // enerBuffer_exp
731 18396 : gain3 = L_add( gain3, Mult_32_16( enerBuffer[gain3_start + i], 5461 /*0.16.Q15*/ ) ); // enerBuffer_exp
732 : }
733 : }
734 :
735 :
736 90247 : IF( EQ_16( gain2_start, GAIN2_START_SWB ) )
737 : {
738 87181 : acc = L_shr( enerBuffer[0], 3 ); // enerBuffer_exp - 3
739 87181 : acc = L_sub( gain1, acc ); // enerBuffer_exp - 3
740 87181 : acc = Mult_32_16( acc, 4681 /*(1/7).Q15*/ ); // enerBuffer_exp - 3
741 87181 : gain11 = L_shl( acc, 3 ); // enerBuffer_exp
742 87181 : gain4 = L_deposit_l( 0 );
743 : }
744 : ELSE
745 : {
746 3066 : acc = Mult_32_16( enerBuffer[0], 5461 /*0.16.Q15*/ ); // enerBuffer_exp
747 3066 : acc = L_sub( gain1, acc ); // enerBuffer_exp
748 3066 : acc = Mult_32_16( acc, 6553 /*0.4.Q15*/ ); // enerBuffer_exp
749 3066 : gain11 = (Word32) W_mult_32_16( acc, 6 );
750 3066 : gain4 = L_deposit_l( 0 );
751 : }
752 :
753 90247 : gain4 = L_deposit_l( 0 );
754 1164013 : FOR( i = 0; i < gain4_start; i++ )
755 : {
756 1073766 : IF( EQ_16( gain4_start, GAIN4_START_SWB ) )
757 : {
758 1046172 : gain4 = L_add( gain4, Mult_32_16( enerBuffer[gain4_start + i], 2731 /*(1/12).Q15*/ ) );
759 : }
760 : ELSE
761 : {
762 27594 : gain4 = L_add( gain4, Mult_32_16( enerBuffer[gain4_start + i], 3641 /*(1/9).Q1.15*/ ) );
763 : }
764 : }
765 :
766 90247 : peak_H1 = enerBuffer[H1_start]; // enerBuffer_exp
767 90247 : move32();
768 :
769 90247 : avrg_H1 = enerBuffer[H1_start]; // enerBuffer_exp
770 90247 : move32();
771 :
772 445103 : FOR( i = 1; i < H_length; i++ )
773 : {
774 354856 : IF( GT_32( enerBuffer[H1_start + i], peak_H1 ) )
775 : {
776 95921 : peak_H1 = enerBuffer[H1_start + i]; // enerBuffer_exp
777 95921 : move32();
778 : }
779 354856 : avrg_H1 = L_add( avrg_H1, enerBuffer[H1_start + i] ); // enerBuffer_exp
780 : }
781 :
782 90247 : peak_H2 = enerBuffer[H2_start];
783 90247 : move32();
784 :
785 90247 : avrg_H2 = enerBuffer[H2_start];
786 90247 : move32();
787 :
788 445103 : FOR( i = 1; i < H_length; i++ )
789 : {
790 354856 : IF( GT_32( enerBuffer[H2_start + i], peak_H2 ) )
791 : {
792 88243 : peak_H2 = enerBuffer[H2_start + i];
793 88243 : move32();
794 : }
795 354856 : avrg_H2 = L_add( avrg_H2, enerBuffer[H2_start + i] );
796 : }
797 :
798 90247 : peak_l = L_deposit_l( 0 );
799 90247 : avrg_l = L_deposit_l( 0 );
800 90247 : peak_h = L_deposit_l( 0 );
801 90247 : avrg_h = L_deposit_l( 0 );
802 :
803 2978151 : FOR( i = 0; i < 32; i++ )
804 : {
805 2887904 : avrg_l = L_add( avrg_l, L_shr( X[20 + i], 5 ) );
806 2887904 : avrg_h = L_add( avrg_h, L_shr( X[96 + i], 5 ) );
807 2887904 : IF( GT_32( X[20 + i], peak_l ) )
808 : {
809 352377 : peak_l = L_add( X[20 + i], 0 );
810 : }
811 2887904 : IF( GT_32( X[96 + i], peak_h ) )
812 : {
813 395246 : peak_h = L_add( X[96 + i], 0 );
814 : }
815 : }
816 :
817 : /* Compute: d_acc - 12*(np -1). */
818 90247 : acc = L_deposit_l( d_acc );
819 90247 : IF( L_msu( acc, 12 / 2, sub( np, 1 ) ) > 0 ) /* 12/2 is to compensate the fractional mode multiply */
820 : {
821 3276 : condition1 = 1; /* Signifies: d_acc/(np - 1) > 12 */
822 3276 : move16();
823 : }
824 : ELSE
825 : {
826 86971 : condition1 = 0; /* Signifies: d_acc/(np - 1) <= 12 */
827 86971 : move16();
828 : /* NB: For np = 0 or 1, it fits this condition. */
829 : }
830 :
831 : /* Compute: p_energy - 147.87276*n_energy. */
832 90247 : IF( n_energy_man != 0 )
833 : {
834 90247 : Mpy_32_16_ss( n_energy_man, 18928, &acc, &lsb16 ); /* 147.87276 in Q7 */
835 90247 : expo = sub( n_energy_exp, 15 - 7 ); /* Due to 18928 in Q7 */
836 90247 : acc = L_negate( acc ); /* To facilitate the following floating_point_add() to perform subtraction. */
837 90247 : floating_point_add( &acc, &expo, p_energy_man, p_energy_exp );
838 : }
839 : ELSE
840 : {
841 0 : acc = L_deposit_l( 0 );
842 : }
843 90247 : IF( acc > 0 )
844 : {
845 8157 : condition2 = 1; /* Signifies: p_energy / n_energy > 147.87276 */
846 8157 : move16();
847 : }
848 : ELSE
849 : {
850 82090 : condition2 = 0; /* Signifies: p_energy / n_energy <= 147.87276 */
851 82090 : move16();
852 : }
853 :
854 90247 : condition3 = 0;
855 90247 : move16();
856 90247 : condition4 = 0;
857 90247 : move16();
858 :
859 90247 : L_tmp = Mult_32_16( peak_h, 12603 );
860 90247 : IF( GT_32( peak_l, L_tmp ) )
861 : {
862 81922 : exp = norm_l( peak_l );
863 : }
864 : ELSE
865 : {
866 8325 : exp = norm_l( L_tmp );
867 : }
868 90247 : IF( GT_32( avrg_h, avrg_l ) )
869 : {
870 18698 : exp1 = norm_l( avrg_h );
871 : }
872 : ELSE
873 : {
874 71549 : exp1 = norm_l( avrg_l );
875 : }
876 :
877 90247 : L_tmp1 = Mult_32_16( peak_l, 12603 );
878 90247 : IF( GT_32( peak_h, L_tmp1 ) )
879 : {
880 24904 : exp2 = norm_l( peak_h );
881 : }
882 : ELSE
883 : {
884 65343 : exp2 = norm_l( L_tmp1 );
885 : }
886 :
887 90247 : test();
888 90247 : test();
889 90247 : test();
890 90247 : test();
891 90247 : IF( GT_32( Mult_32_16( gain3, 27307 ), gain2 ) || ( GE_32( gain3, Mult_32_16( gain2, 26214 ) ) && GT_32( peak_H1, L_shl_o( avrg_H1, 1, &Overflow ) ) ) || ( LT_32( Mult_32_32( L_shl_o( peak_l, exp, &Overflow ), L_shl_o( avrg_h, exp1, &Overflow ) ), Mult_32_32( L_shl_o( L_tmp, exp, &Overflow ), L_shl_o( avrg_l, exp1, &Overflow ) ) ) || GT_32( Mult_32_32( L_shl_o( L_tmp1, exp2, &Overflow ), L_shl_o( avrg_h, exp1, &Overflow ) ), Mult_32_32( L_shl_o( peak_h, exp2, &Overflow ), L_shl_o( avrg_l, exp1, &Overflow ) ) ) ) )
892 : {
893 22801 : condition3 = 1;
894 22801 : move16();
895 : }
896 :
897 90247 : L_tmp = Mult_32_16( peak_h, 12800 /*(1/2.56).Q15*/ );
898 90247 : IF( GT_32( peak_l, L_tmp ) )
899 : {
900 81804 : exp = norm_l( peak_l );
901 : }
902 : ELSE
903 : {
904 8443 : exp = norm_l( L_tmp );
905 : }
906 :
907 90247 : L_tmp1 = Mult_32_16( peak_l, 6400 /*(1/5.12).Q15*/ );
908 90247 : IF( GT_32( peak_h, L_tmp1 ) )
909 : {
910 31652 : exp2 = norm_l( peak_h );
911 : }
912 : ELSE
913 : {
914 58595 : exp2 = norm_l( L_tmp1 );
915 : }
916 :
917 90247 : IF( GT_32( peak_h, L_shl( L_tmp1, 1 ) ) )
918 : {
919 24766 : exp3 = norm_l( peak_h );
920 : }
921 : ELSE
922 : {
923 65481 : exp3 = sub( norm_l( L_tmp1 ), 1 );
924 : }
925 :
926 90247 : test();
927 90247 : test();
928 90247 : test();
929 90247 : test();
930 90247 : test();
931 90247 : test();
932 90247 : test();
933 90247 : test();
934 90247 : test();
935 90247 : IF( ( GT_32( gain4, Mult_32_16( gain11, 26214 /*0.8.Q15*/ ) ) && GT_32( Mult_32_32( L_shl( peak_l, exp ), L_shl( avrg_h, exp1 ) ), Mult_32_32( L_shl( Mult_32_16( peak_h, 12800 /*(1/2.56).Q15*/ ), exp ), L_shl( avrg_l, exp1 ) ) ) && LT_32( Mult_32_32( L_shl( Mult_32_16( peak_l, 6400 /*(1/5.12).Q15*/ ), exp2 ), L_shl( avrg_h, exp1 ) ), Mult_32_32( L_shl( peak_h, exp2 ), L_shl( avrg_l, exp1 ) ) ) ) || ( GT_32( gain4, Mult_32_16( gain11, 9830 /*0.3.Q15*/ ) ) && LT_32( Mult_32_16( peak_h, 21845 /*(1/1.5).Q15*/ ), avrg_h ) && LT_32( Mult_32_16( peak_H2, 21845 /*(1/1.5).Q15*/ ), avrg_H2 ) ) ||
936 : ( LT_32( Mult_32_32( L_shl( peak_l, exp ), L_shl( avrg_h, exp1 ) ), Mult_32_32( L_shl( Mult_32_16( peak_h, 12800 /*(1/2.56).Q15*/ ), exp ), L_shl( avrg_l, exp1 ) ) ) && GT_32( Mult_32_16( peak_h, 21845 /*(1/1.5).Q15*/ ), avrg_h ) ) || ( GT_32( Mult_32_32( L_shl( Mult_32_16( peak_l, 12800 /*(1/2.56).Q15*/ ), exp3 ), L_shl( avrg_h, exp1 ) ), Mult_32_32( L_shl( peak_h, exp3 ), L_shl( avrg_l, exp1 ) ) ) > 0 && LT_32( Mult_32_16( peak_h, 21845 /*(1/1.5).Q15*/ ), avrg_h ) ) )
937 : {
938 7381 : condition4 = 1;
939 7381 : move16();
940 : }
941 :
942 90247 : test();
943 90247 : test();
944 90247 : test();
945 90247 : test();
946 90247 : test();
947 90247 : test();
948 :
949 90247 : IF( ( GE_32( brate, HQ_MDCTCLASS_CROSSOVER_BRATE ) && GT_32( st->input_Fs, 16000 ) && ( s_xor( condition1, condition2 ) != 0 || condition3 ) ) || ( ( LT_32( brate, HQ_MDCTCLASS_CROSSOVER_BRATE ) || EQ_32( st->input_Fs, 16000 ) ) && condition4 ) )
950 : {
951 8519 : c = MDCT_CLASSIFER_HQ_LOCAL; /* Q13 */
952 8519 : move16();
953 : }
954 : ELSE
955 : {
956 81728 : c = MDCT_CLASSIFER_TCX_LOCAL; /* Q13 */
957 81728 : move16();
958 : }
959 :
960 : /* Smooth decision from instantaneous decision*/
961 90247 : acc = L_mult( hTcxEnc->clas_sec_old_fx, MDCT_CLASSIFER_SMOOTH_FILT_COEFF ); /* st_fx->clas_sec_old_fx in Q13 */
962 90247 : clas_sec = mac_r( acc, c, 0x7fff - MDCT_CLASSIFER_SMOOTH_FILT_COEFF ); /* clas_sec and c are in Q13 */
963 :
964 : /* Do thresholding with hysteresis */
965 :
966 90247 : IF( GT_16( st->last_enerBuffer_exp, enerBuffer_exp ) )
967 : {
968 25789 : gain1_tmp = L_shr( gain1, sub( st->last_enerBuffer_exp, enerBuffer_exp ) );
969 25789 : move32();
970 25789 : gain2_tmp = L_shr( gain2, sub( st->last_enerBuffer_exp, enerBuffer_exp ) );
971 25789 : move32();
972 : }
973 : ELSE
974 : {
975 64458 : hTcxEnc->last_gain1 = L_shr( hTcxEnc->last_gain1, sub( enerBuffer_exp, st->last_enerBuffer_exp ) );
976 64458 : move32();
977 64458 : hTcxEnc->last_gain2 = L_shr( hTcxEnc->last_gain2, sub( enerBuffer_exp, st->last_enerBuffer_exp ) );
978 64458 : move32();
979 64458 : gain1_tmp = gain1;
980 64458 : move32();
981 64458 : gain2_tmp = gain2;
982 64458 : move32();
983 : }
984 :
985 90247 : test();
986 90247 : test();
987 90247 : test();
988 90247 : test();
989 90247 : test();
990 90247 : test();
991 :
992 90247 : IF( ( EQ_16( hTcxEnc->clas_final_old, HQ_CORE ) || EQ_16( hTcxEnc->clas_final_old, TCX_20_CORE ) ) && ( ( GT_32( hTcxEnc->last_gain1, L_shr( gain1_tmp, 1 ) ) && LT_32( hTcxEnc->last_gain1, L_shl_o( gain1_tmp, 1, &Overflow ) ) ) && ( GT_32( hTcxEnc->last_gain2, L_shr( gain2_tmp, 1 ) ) && LT_32( hTcxEnc->last_gain2, L_shl_o( gain2_tmp, 1, &Overflow ) ) ) ) )
993 : {
994 52814 : clas_final = hTcxEnc->clas_final_old;
995 52814 : move16();
996 : }
997 37433 : ELSE IF( GT_16( clas_sec, hTcxEnc->clas_sec_old_fx ) && GT_16( clas_sec, MDCT_CLASSIFER_THRESH_UP ) ) /* Going up? */
998 : {
999 2960 : clas_final = HQ_CORE; /* Q0 */
1000 2960 : move16();
1001 : }
1002 34473 : ELSE IF( LT_16( clas_sec, MDCT_CLASSIFER_THRESH_DOWN ) ) /* Going down */
1003 : {
1004 24934 : clas_final = TCX_20_CORE;
1005 24934 : move16();
1006 : }
1007 : ELSE
1008 : {
1009 9539 : clas_final = hTcxEnc->clas_final_old;
1010 9539 : move16();
1011 : }
1012 :
1013 :
1014 : /* Prevent the usage of HQ_CORE on noisy-speech or inactive */
1015 90247 : test();
1016 90247 : test();
1017 90247 : test();
1018 90247 : if ( EQ_16( st->mdct_sw_enable, MODE2 || st->element_mode > EVS_MONO ) && ( EQ_16( st->flag_noisy_speech_snr, 1 ) || st->vad_flag == 0 ) && EQ_16( clas_final, HQ_CORE ) )
1019 : {
1020 142 : clas_final = TCX_20_CORE;
1021 142 : move16();
1022 : }
1023 :
1024 : /* Restrict usage of HQ_core to supported operating range */
1025 : /* EVS: brate == st->total_brate */
1026 : /* IVAS: brate is the nominal bitrate while st->total_brate may fluctuate. This sets a hard limit for HQ at HQ_16k40 */
1027 90247 : test();
1028 90247 : test();
1029 90247 : test();
1030 90247 : if ( LE_32( st->total_brate, HQ_16k40 ) || LT_32( brate, HQ_16k40 ) || EQ_16( st->bwidth, NB ) || GT_32( brate, IVAS_48k ) )
1031 : {
1032 47836 : clas_final = TCX_20_CORE;
1033 47836 : move16();
1034 : }
1035 :
1036 :
1037 : /* Memory update */
1038 :
1039 90247 : hTcxEnc->clas_sec_old_fx = clas_sec;
1040 90247 : move16(); /* Q13 */
1041 90247 : hTcxEnc->clas_final_old = clas_final;
1042 90247 : move16(); /* Q0 */
1043 90247 : hTcxEnc->last_gain1 = gain1;
1044 90247 : move32();
1045 90247 : hTcxEnc->last_gain2 = gain2;
1046 90247 : move32();
1047 90247 : st->last_enerBuffer_exp = enerBuffer_exp;
1048 90247 : move16();
1049 :
1050 90247 : return clas_final;
1051 : }
|