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