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