Line data Source code
1 : /*====================================================================================
2 : EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0
3 : ====================================================================================*/
4 : #include <stdint.h>
5 : #include "options.h" /* Compilation switches */
6 : #include "cnst.h" /* Common constants */
7 : //#include "prot_fx.h" /* Function prototypes */
8 : #include "rom_com.h" /* Function prototypes */
9 : #include "prot_fx.h" /* Function prototypes */
10 : #include "prot_fx_enc.h" /* Function prototypes */
11 :
12 : /*-------------------------------------------------------------------*
13 : * Local constants
14 : *-------------------------------------------------------------------*/
15 :
16 : #define L_ENR ( NB_SSF + 2 )
17 :
18 :
19 : /*-------------------------------------------------------------------*
20 : * find_ener_decrease_fx()
21 : *
22 : * Find maximum energy ration between short subblocks in case
23 : * energy is trailing off after a spike
24 : *-------------------------------------------------------------------*/
25 :
26 20748 : static Word16 find_ener_decrease_fx( /* o : maximum energy ratio Q10*/
27 : const Word16 ind_deltaMax, /* i : index of the beginning of maximum energy search Q0*/
28 : const Word32 *pt_enr_ssf /* i : Pointer to the energy buffer Qx*/
29 : )
30 : {
31 : Word16 i, j, end, flag;
32 : Word16 wtmp0, wtmp1;
33 : Word32 maxEnr, minEnr;
34 : Word16 dE2, exp0, exp1;
35 :
36 20748 : dE2 = 0;
37 20748 : move16();
38 :
39 20748 : j = ind_deltaMax + 2;
40 20748 : move16();
41 20748 : end = j + L_ENR;
42 20748 : move16();
43 20748 : maxEnr = L_add( pt_enr_ssf[j], 0 );
44 20748 : j = add( j, 1 );
45 20748 : flag = 0;
46 20748 : move16();
47 207480 : FOR( i = j; i < end; i++ )
48 : {
49 186732 : test();
50 186732 : IF( ( GT_32( pt_enr_ssf[i], maxEnr ) ) && ( flag == 0 ) )
51 : {
52 8199 : maxEnr = L_add( pt_enr_ssf[i], 0 ); /*Qx*/
53 8199 : j = add( j, 1 );
54 : }
55 : ELSE
56 : {
57 178533 : flag = 1;
58 178533 : move16();
59 : }
60 : }
61 :
62 20748 : minEnr = L_add( maxEnr, 0 );
63 199281 : FOR( i = j; i < end; i++ )
64 : {
65 178533 : minEnr = L_min( minEnr, pt_enr_ssf[i] ); /* Qx */
66 : }
67 :
68 :
69 20748 : minEnr = L_add_sat( minEnr, 100000 );
70 20748 : exp0 = norm_l( minEnr );
71 20748 : wtmp0 = extract_h( L_shl( minEnr, exp0 ) );
72 20748 : exp1 = sub( norm_l( maxEnr ), 1 );
73 20748 : wtmp1 = extract_h( L_shl( maxEnr, exp1 ) );
74 20748 : wtmp1 = div_s( wtmp1, wtmp0 );
75 20748 : dE2 = shr_r_sat( wtmp1, add( sub( exp1, exp0 ), 15 - 10 ) ); /*Q10*/
76 :
77 20748 : return dE2;
78 : }
79 :
80 : /*-------------------------------------------------------------------*
81 : * find_uv_fx()
82 : *
83 : * Decision about coder type
84 : *-------------------------------------------------------------------*/
85 :
86 3100 : Word16 find_uv_fx( /* o : coding type */
87 : Encoder_State *st_fx, /* i/o: encoder state structure */
88 : const Word16 *T_op_fr, /* i : pointer to adjusted fractional pitch (4 val.) Q6*/
89 : const Word16 *voicing_fr, /* i : refined correlation for each subframes Q15*/
90 : const Word16 *speech, /* i : pointer to speech signal for E computation Q_new*/
91 : const Word32 *ee, /* i : lf/hf Energy ratio for present frame Q6*/
92 : const Word16 corr_shift, /* i : normalized correlation correction in noise Q15*/
93 : const Word16 relE, /* i : relative frame energy Q8*/
94 : const Word16 Etot, /* i : total energy Q8*/
95 : const Word32 hp_E[], /* i : energy in HF Q_new + Q_SCALE*/
96 : const Word16 Q_new,
97 : Word16 *flag_spitch, /* i/o: flag to indicate very short stable pitch and high correlation Q0*/
98 : const Word16 shift,
99 : const Word16 last_core_orig /* i : original last core Q0*/
100 : )
101 : {
102 : Word16 coder_type, i;
103 : Word32 mean_ee, dE1, fac_32;
104 : const Word16 *pt_speech;
105 : Word32 L_tmp, enr_ssf[2 * NB_SSF + 2 * NB_SSF + 2], E_min_th;
106 : Word16 dE2;
107 : Word16 ind_deltaMax, tmp_offset_flag;
108 : Word32 Ltmp0, *pt_enr_ssf, *pt_enr_ssf1, dE2_th;
109 : Word16 exp0, exp1, Q_in;
110 : Word16 wtmp0, wtmp1;
111 : Word16 fac, mean_voi3, dE3;
112 : Word16 relE_thres;
113 : Word16 mean_voi3_offset;
114 : Word16 voicing_m, dpit1, dpit2, dpit3;
115 : Word16 ee0_th, ee1_th, voi_th, nb_cond, flag_low_relE;
116 3100 : NOISE_EST_HANDLE hNoiseEst = st_fx->hNoiseEst;
117 3100 : SC_VBR_ENC_HANDLE hSC_VBR = st_fx->hSC_VBR;
118 : #ifndef ISSUE_1867_replace_overflow_libenc
119 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
120 : Flag Overflow = 0;
121 : move32();
122 : #endif
123 : #endif
124 :
125 : Word16 Last_Resort;
126 : Word16 vadnoise;
127 :
128 3100 : IF( hSC_VBR != NULL )
129 : {
130 3100 : Last_Resort = hSC_VBR->Last_Resort; /* Q0 */
131 3100 : vadnoise = hSC_VBR->vadnoise_fx;
132 3100 : move16();
133 3100 : move16();
134 : }
135 : ELSE
136 : {
137 0 : Last_Resort = 0;
138 0 : vadnoise = 0;
139 0 : move16();
140 0 : move16();
141 : }
142 :
143 3100 : Q_in = sub( Q_new, 1 );
144 :
145 : /*-----------------------------------------------------------------*
146 : * Detect sudden energy increases to catch voice and music
147 : * temporal events (dE1)
148 : *
149 : * - Find maximum energy per short subblocks.
150 : * Two subblock sets are used shifted by half the subblock length
151 : * - Find maximum energy ratio between adjacent subblocks
152 : *-----------------------------------------------------------------*/
153 :
154 : /* Find maximum energy per short subblocks */
155 3100 : pt_speech = speech - SSF; /* Q_new */
156 3100 : pt_enr_ssf = enr_ssf + 2 * NB_SSF;
157 58900 : FOR( i = 0; i < 2 * ( NB_SSF + 1 ); i++ )
158 : {
159 55800 : emaximum_fx( Q_in, pt_speech, SSF, pt_enr_ssf );
160 55800 : pt_speech += ( SSF / 2 );
161 55800 : pt_enr_ssf++;
162 : }
163 :
164 3100 : dE1 = 0;
165 3100 : move16();
166 3100 : ind_deltaMax = 0;
167 3100 : move16();
168 3100 : pt_enr_ssf = enr_ssf + 2 * NB_SSF;
169 3100 : pt_enr_ssf1 = pt_enr_ssf + 2;
170 :
171 : /* Test on energy increase between adjacent sub-subframes */
172 3100 : exp1 = 0;
173 3100 : move16();
174 52700 : FOR( i = 0; i < 2 * NB_SSF; i++ )
175 : {
176 : /*fac = *pt_enr_ssf1 / (*pt_enr_ssf + 1);*/
177 49600 : Ltmp0 = L_max( *pt_enr_ssf, 1 );
178 49600 : exp0 = norm_l( Ltmp0 );
179 49600 : wtmp0 = extract_h( L_shl( Ltmp0, exp0 ) );
180 49600 : exp1 = sub( norm_l( *pt_enr_ssf1 ), 1 );
181 49600 : wtmp1 = extract_h( L_shl( *pt_enr_ssf1, exp1 ) );
182 49600 : fac = div_s( wtmp1, wtmp0 );
183 49600 : fac_32 = L_shr_sat( L_deposit_l( fac ), add( sub( exp1, exp0 ), 15 - 13 ) ); /* fac32 in Q13*/
184 :
185 49600 : if ( GT_32( fac_32, dE1 ) )
186 : {
187 10465 : ind_deltaMax = i;
188 10465 : move16();
189 : }
190 :
191 49600 : dE1 = L_max( dE1, fac_32 ); /* Q13 */
192 :
193 49600 : pt_enr_ssf++;
194 49600 : pt_enr_ssf1++;
195 : }
196 :
197 : /*-----------------------------------------------------------------*
198 : * Average spectral tilt
199 : * Average voicing (normalized correlation)
200 : *-----------------------------------------------------------------*/
201 :
202 : /*mean_ee = 1.0f/3.0f * (st->ee_old + ee[0] + ee[1]); */ /* coefficients take into account the position of the window */
203 : #ifdef ISSUE_1867_replace_overflow_libenc
204 3100 : mean_ee = L_add_sat( L_add_sat( st_fx->ee_old_fx, ee[0] ), ee[1] ); /* Q6 */
205 : #else
206 : mean_ee = L_add_o( L_add_o( st_fx->ee_old_fx, ee[0], &Overflow ), ee[1], &Overflow ); /* Q6 */
207 : #endif
208 3100 : mean_ee = Mult_32_16( mean_ee, 10923 /* 1/3 in Q15 */ ); /*Q6*/
209 :
210 : /* mean_voi3 = 1.0f/3.0f * (voicing[0] + voicing[1] + voicing[2]);*/
211 3100 : Ltmp0 = L_mult( st_fx->voicing_fx[0], 10923 /* 1/3 in Q15 */ ); /* Q31 */
212 3100 : Ltmp0 = L_mac( Ltmp0, st_fx->voicing_fx[1], 10923 /* 1/3 in Q15 */ ); /* Q31 */
213 3100 : mean_voi3 = mac_r_sat( Ltmp0, st_fx->voicing_fx[2], 10923 /* 1/3 in Q15 */ ); /*Q15*/
214 : /*-----------------------------------------------------------------*
215 : * Total frame energy difference (dE3)
216 : *-----------------------------------------------------------------*/
217 :
218 3100 : dE3 = sub( Etot, hNoiseEst->Etot_last_fx ); /*Q8*/
219 :
220 : /*-----------------------------------------------------------------*
221 : * Energy decrease after spike (dE2)
222 : *-----------------------------------------------------------------*/
223 :
224 : /* set different thresholds and conditions for NB and WB input */
225 3100 : dE2_th = 30 << 10;
226 3100 : move32();
227 3100 : nb_cond = 1;
228 3100 : move16(); /* no additional condition for WB input */
229 3100 : IF( EQ_16( st_fx->input_bwidth, NB ) )
230 : {
231 0 : dE2_th = 21 << 10;
232 0 : move32();
233 : #ifdef ISSUE_1867_replace_overflow_libenc
234 0 : if ( GE_16( add_sat( mean_voi3, corr_shift ), 22282 /* 0.68 in Q15 */ ) ) /*( mean_voi3 + corr_shift ) >= 0.68f*/
235 : #else
236 : if ( GE_16( add_o( mean_voi3, corr_shift, &Overflow ), 22282 /* 0.68 in Q15 */ ) ) /*( mean_voi3 + corr_shift ) >= 0.68f*/
237 : #endif
238 : {
239 0 : nb_cond = 0;
240 0 : move16();
241 : }
242 : }
243 :
244 : /* calcualte maximum energy decrease */
245 3100 : dE2 = 0;
246 3100 : move16(); /* Test on energy decrease after an energy spike */
247 3100 : pt_enr_ssf = enr_ssf + 2 * NB_SSF;
248 :
249 3100 : test();
250 3100 : IF( GT_32( dE1, 30 << 13 ) && nb_cond ) /*>30 Q13*/
251 : {
252 80 : IF( LT_16( sub( shl( NB_SSF, 1 ), ind_deltaMax ), L_ENR ) )
253 : {
254 57 : st_fx->old_ind_deltaMax = ind_deltaMax; /* Q0 */
255 57 : move16();
256 57 : Copy32( pt_enr_ssf, st_fx->old_enr_ssf_fx, 2 * NB_SSF ); /* Qx */
257 : }
258 : ELSE
259 : {
260 23 : st_fx->old_ind_deltaMax = -1;
261 23 : move16();
262 23 : dE2 = find_ener_decrease_fx( ind_deltaMax, pt_enr_ssf ); /*Q10*/
263 :
264 23 : if ( GT_32( dE2, dE2_th ) )
265 : {
266 2 : st_fx->spike_hyst = 0;
267 2 : move16();
268 : }
269 : }
270 : }
271 : ELSE
272 : {
273 3020 : IF( st_fx->old_ind_deltaMax >= 0 )
274 : {
275 57 : Copy32( st_fx->old_enr_ssf_fx, enr_ssf, 2 * NB_SSF ); /* Qx */
276 57 : dE2 = find_ener_decrease_fx( st_fx->old_ind_deltaMax, enr_ssf ); /* Q10 */
277 :
278 57 : if ( GT_32( dE2, dE2_th ) )
279 : {
280 3 : st_fx->spike_hyst = 1;
281 3 : move16();
282 : }
283 : }
284 :
285 3020 : st_fx->old_ind_deltaMax = -1;
286 3020 : move16();
287 : }
288 :
289 : /*-----------------------------------------------------------------*
290 : * Detection of voiced offsets (tmp_offset_flag)
291 : *-----------------------------------------------------------------*/
292 :
293 3100 : tmp_offset_flag = 1;
294 3100 : move16();
295 :
296 3100 : IF( NE_16( st_fx->input_bwidth, NB ) )
297 : {
298 3100 : ee0_th = 154; /*2.4 in Q6 */
299 3100 : move16();
300 3100 : voi_th = 24248; /*0.74f Q15 */
301 3100 : move16();
302 : }
303 : ELSE
304 : {
305 0 : ee0_th = 627; /*9.8f Q6 */
306 0 : move16();
307 0 : voi_th = 24904; /*0.76f Q15*/
308 0 : move16();
309 : }
310 :
311 3100 : test();
312 3100 : test();
313 3100 : test();
314 6063 : if ( ( EQ_16( st_fx->last_coder_type_raw, UNVOICED ) ) || /* previous frame was unvoiced */
315 4005 : ( ( LT_32( ee[0], ee0_th ) ) && ( GT_32( hp_E[0], L_shl( E_MIN_FX, Q_new ) ) ) && /* energy is concentrated in high frequencies provided that some energy is present in HF */
316 : #ifdef ISSUE_1867_replace_overflow_libenc
317 496 : ( LT_16( add_sat( st_fx->voicing_fx[0], corr_shift ), voi_th ) ) ) ) /* normalized correlation is low */
318 : #else
319 : ( LT_16( add_o( st_fx->voicing_fx[0], corr_shift, &Overflow ), voi_th ) ) ) ) /* normalized correlation is low */
320 : #endif
321 : {
322 322 : tmp_offset_flag = 0;
323 322 : move16();
324 : }
325 :
326 : /*-----------------------------------------------------------------*
327 : * Decision about UC
328 : *-----------------------------------------------------------------*/
329 :
330 : /* SC-VBR - set additional parameters and thresholds for SC-VBR */
331 3100 : mean_voi3_offset = 0;
332 3100 : move16();
333 3100 : flag_low_relE = 0;
334 3100 : move16();
335 3100 : ee1_th = 608; /*9.5 Q6*/
336 3100 : move16();
337 3100 : IF( st_fx->Opt_SC_VBR || ( EQ_16( st_fx->idchan, 1 ) && EQ_16( st_fx->element_mode, IVAS_CPE_TD ) ) ) /* Allow the low energy flag for the secondary channel */
338 : {
339 0 : ee1_th = 544; /*8.5f Q6*/
340 0 : move16();
341 :
342 : /* SC-VBR - determine the threshold on relative energy as a function of lp_noise */
343 0 : IF( NE_16( st_fx->input_bwidth, NB ) )
344 : {
345 : /*relE_thres = 0.700f * st->lp_noise - 33.5f; (lp_noise in Q8, constant Q8<<16) */
346 0 : L_tmp = L_mac( -562036736 /* 33.5f in Q24 */, 22938 /* 0.7 in Q15 */, st_fx->lp_noise_fx ); // Q24
347 0 : if ( Last_Resort == 0 )
348 : {
349 : /*relE_thres = 0.650f * st->lp_noise - 33.5f; (lp_noise in Q8, constant Q8<<16)*/
350 0 : L_tmp = L_mac( -562036736 /* 33.5f in Q24 */, 21299 /* 0.650f in Q15 */, st_fx->lp_noise_fx ); // Q24
351 : }
352 0 : relE_thres = round_fx( L_tmp );
353 : }
354 : ELSE
355 : {
356 :
357 : /*relE_thres = 0.60f * st->lp_noise - 28.2f; (lp_noise in Q8, constant Q8<<16)*/
358 0 : L_tmp = L_mac( -473117491 /* 28.2f in Q24 */, 19661 /* 0.6f in Q15 */, st_fx->lp_noise_fx ); // Q24
359 0 : relE_thres = round_fx( L_tmp );
360 : }
361 0 : relE_thres = s_max( relE_thres, -6400 /* -25.0f in Q8 */ ); /* Q8 */
362 :
363 : /* SC-VBR = set flag on low relative energy */
364 0 : if ( LT_16( relE, relE_thres ) )
365 : {
366 0 : flag_low_relE = 1;
367 0 : move16();
368 : }
369 :
370 : /* SC-VBR - correction of voicing threshold for NB inputs (important only in noisy conditions) */
371 0 : test();
372 0 : if ( EQ_16( st_fx->input_bwidth, NB ) && LT_16( vadnoise, 20 << 8 ) ) /* vadnoise in Q8, constant Q0<<8 */
373 : {
374 0 : mean_voi3_offset = 1638; /*0.05f Q15*/
375 0 : move16();
376 : }
377 : }
378 :
379 : /* make decision whether frame is unvoiced */
380 3100 : E_min_th = L_shl( E_MIN_FX, Q_new );
381 3100 : coder_type = GENERIC;
382 3100 : move16();
383 3100 : IF( EQ_16( st_fx->input_bwidth, NB ) )
384 : {
385 0 : test();
386 0 : test();
387 0 : test();
388 0 : test();
389 0 : test();
390 0 : test();
391 0 : test();
392 0 : test();
393 0 : test();
394 0 : test();
395 0 : test();
396 : #ifdef ISSUE_1867_replace_overflow_libenc
397 0 : if ( ( ( LT_16( add_sat( mean_voi3, corr_shift ), add( 22282 /* 0.68 in Q15 */, mean_voi3_offset ) ) ) && /* normalized correlation low */
398 0 : ( LT_16( add_sat( st_fx->voicing_fx[2], corr_shift ), 25887 /* 0.79 in Q15 */ ) ) && /* normalized correlation low on look-ahead - onset detection */
399 : #else
400 : if ( ( ( LT_16( add_o( mean_voi3, corr_shift, &Overflow ), add( 22282 /* 0.68 in Q15 */, mean_voi3_offset ) ) ) && /* normalized correlation low */
401 : ( LT_16( add_o( st_fx->voicing_fx[2], corr_shift, &Overflow ), 25887 /* 0.79 in Q15 */ ) ) && /* normalized correlation low on look-ahead - onset detection */
402 : #endif
403 0 : ( LT_32( ee[0], 640 /* 10.0f in Q6 */ ) ) && ( GT_32( hp_E[0], E_min_th ) ) && /* energy concentrated in high frequencies provided that some energy is present in HF... */
404 0 : ( LT_32( ee[1], ee1_th ) ) && ( GT_32( hp_E[1], E_min_th ) ) && /* ... biased towards look-ahead to detect onsets */
405 0 : ( tmp_offset_flag == 0 ) && /* Take care of voiced offsets */
406 : /*( st_fx->music_hysteresis_fx == 0 ) &&*/ /* ... and in segment after AUDIO frames */
407 0 : ( LE_32( dE1, 237568 /* 29.0f in Q13 */ ) ) && /* Avoid on sharp energy spikes */
408 0 : ( LE_32( st_fx->old_dE1_fx, 237568 /* 29.0f in Q13 */ ) ) && /* + one frame hysteresis */
409 0 : ( st_fx->spike_hyst < 0 ) ) || /* Avoid after sharp energy spikes followed by decay (e.g. castanets) */
410 : flag_low_relE ) /* low relative frame energy (only for SC-VBR) */
411 : {
412 0 : coder_type = UNVOICED;
413 0 : move16();
414 : }
415 : }
416 : ELSE
417 : {
418 3100 : test();
419 3100 : test();
420 3100 : test();
421 3100 : test();
422 3100 : test();
423 3100 : test();
424 3100 : test();
425 3100 : test();
426 3100 : test();
427 3100 : test();
428 3100 : test();
429 3100 : test();
430 : #ifdef ISSUE_1867_replace_overflow_libenc
431 4033 : if ( ( ( LT_16( add_sat( mean_voi3, corr_shift ), add( 22774 /* 0.695f in Q15 */, mean_voi3_offset ) ) ) && /* normalized correlation low */
432 : #else
433 : if ( ( ( LT_16( add_o( mean_voi3, corr_shift, &Overflow ), add( 22774 /* 0.695f in Q15 */, mean_voi3_offset ) ) ) && /* normalized correlation low */
434 : #endif
435 1769 : ( LT_16( add_sat( st_fx->voicing_fx[2], corr_shift ), 25887 /* 0.8 in Q15 */ ) ) && /* normalized correlation low on look-ahead - onset detection */
436 1369 : ( LT_32( ee[0], 397 /* 6.2f in Q6 */ ) ) && ( GT_32( hp_E[0], E_min_th ) ) && /* energy concentrated in high frequencies provided that some energy is present in HF... */
437 478 : ( LT_32( ee[1], 397 /* 6.2f in Q6 */ ) ) && ( GT_32( hp_E[1], E_min_th ) ) && /* ... biased towards look-ahead to detect onsets */
438 158 : ( tmp_offset_flag == 0 ) && /* Take care of voiced offsets */
439 : /*( st_fx->music_hysteresis_fx == 0 ) && */ /* ... and in segment after AUDIO frames */
440 306 : ( LE_32( dE1, 245760 /* 30.0f in Q13 */ ) ) && /* Avoid on sharp energy spikes */
441 148 : ( LE_32( st_fx->old_dE1_fx, 245760 /* 30.0f in Q13 */ ) ) && /* + one frame hysteresis */
442 138 : ( st_fx->spike_hyst < 0 ) ) /* Avoid after sharp energy spikes followed by decay (e.g. castanets) */
443 2963 : || ( flag_low_relE && ( LE_32( st_fx->old_dE1_fx, 245760 /* 30.0f in Q13 */ ) ) ) ) /* low relative frame energy (only for SC-VBR) */
444 : {
445 137 : coder_type = UNVOICED;
446 137 : move16();
447 : }
448 : }
449 :
450 : /*-----------------------------------------------------------------*
451 : * Decision about VC
452 : *-----------------------------------------------------------------*/
453 3100 : if ( st_fx->Opt_SC_VBR )
454 : {
455 0 : hSC_VBR->set_ppp_generic = 0;
456 : }
457 3100 : move16();
458 :
459 3100 : test();
460 3100 : test();
461 3100 : IF( EQ_16( st_fx->localVAD, 1 ) && EQ_16( coder_type, GENERIC ) && NE_16( last_core_orig, AMR_WB_CORE ) )
462 : {
463 2858 : dpit1 = abs_s( sub( T_op_fr[1], T_op_fr[0] ) ); // Q6
464 2858 : dpit2 = abs_s( sub( T_op_fr[2], T_op_fr[1] ) ); // Q6
465 2858 : dpit3 = abs_s( sub( T_op_fr[3], T_op_fr[2] ) ); // Q6
466 :
467 2858 : test();
468 2858 : test();
469 2858 : test();
470 2858 : test();
471 2858 : test();
472 2858 : test();
473 2858 : test();
474 2858 : test();
475 2858 : test();
476 2858 : IF( ( GT_16( voicing_fr[0], 19825 /* 0.605 in Q15 */ ) ) && /* normalized correlation high in 1st sf. */
477 : ( GT_16( voicing_fr[1], 19825 /* 0.605 in Q15 */ ) ) && /* normalized correlation high in 2st sf. */
478 : ( GT_16( voicing_fr[2], 19825 /* 0.605 in Q15 */ ) ) && /* normalized correlation high in 3st sf. */
479 : ( GT_16( voicing_fr[3], 19825 /* 0.605 in Q15 */ ) ) && /* normalized correlation high in 4st sf. */
480 : ( GT_32( mean_ee, 256 /* 4.0f in Q6 */ ) ) && /* energy concentrated in low frequencies */
481 : ( LT_16( dpit1, 3 << 6 ) ) &&
482 : ( LT_16( dpit2, 3 << 6 ) ) &&
483 : ( LT_16( dpit3, 3 << 6 ) ) )
484 : {
485 1387 : coder_type = VOICED;
486 1387 : move16();
487 : }
488 1471 : ELSE IF( st_fx->Opt_SC_VBR && EQ_16( st_fx->input_bwidth, NB ) && LT_16( vadnoise, 20 << 8 ) )
489 : {
490 0 : test();
491 0 : test();
492 0 : test();
493 0 : test();
494 0 : test();
495 0 : test();
496 0 : test();
497 0 : IF( GT_16( voicing_fr[0], 8192 /* 0.25 in Q15 */ ) && /* normalized correlation high in 1st sf. */
498 : ( GT_16( voicing_fr[1], 8192 /* 0.25 in Q15 */ ) ) && /* normalized correlation high in 2st sf. */
499 : ( GT_16( voicing_fr[2], 8192 /* 0.25 in Q15 */ ) ) && /* normalized correlation high in 3st sf. */
500 : ( GT_16( voicing_fr[3], 8192 /* 0.25 in Q15 */ ) ) && /* normalized correlation high in 4st sf. */
501 : ( GT_32( mean_ee, 64 ) ) && /* energy concentrated in low frequencies */
502 : ( LT_16( dpit1, 5 << 6 ) ) &&
503 : ( LT_16( dpit2, 5 << 6 ) ) &&
504 : ( LT_16( dpit3, 5 << 6 ) ) )
505 : {
506 0 : hSC_VBR->set_ppp_generic = 1;
507 0 : move16();
508 0 : coder_type = VOICED;
509 0 : move16();
510 : }
511 : }
512 :
513 : /* set VOICED mode for frames with very stable pitch and high correlation
514 : and avoid to switch to AUDIO/MUSIC later */
515 2858 : voicing_m = mac_r( L_mac( L_mac( L_mult( voicing_fr[3], 8192 /* 0.25 in Q15 */ ), voicing_fr[2], 8192 /* 0.25 in Q15 */ ), voicing_fr[1], 8192 /* 0.25 in Q15 */ ), voicing_fr[0], 8192 /* 0.25 in Q15 */ );
516 2858 : test();
517 2858 : test();
518 2858 : test();
519 2858 : test();
520 2858 : test();
521 2858 : IF( *flag_spitch || ( LE_16( dpit1, 3 << 6 ) && LE_16( dpit2, 3 << 6 ) && LE_16( dpit3, 3 << 6 ) &&
522 : GT_16( voicing_m, 31130 /* 0.95f in Q15 */ ) && GT_16( st_fx->voicing_sm_fx, 31785 /* 0.97f in Q15 */ ) ) )
523 : {
524 48 : coder_type = VOICED;
525 48 : move16();
526 48 : *flag_spitch = 1;
527 48 : move16(); /*to avoid switch to AUDIO/MUSIC later*/
528 : }
529 : }
530 :
531 : /*-----------------------------------------------------------------*
532 : * Channel-aware mode - set RF mode and total bitrate
533 : *-----------------------------------------------------------------*/
534 :
535 3100 : st_fx->rf_mode = st_fx->Opt_RF_ON; /* Q0 */
536 3100 : move16();
537 :
538 3100 : IF( EQ_16( coder_type, GENERIC ) )
539 : {
540 1576 : test();
541 1576 : test();
542 1576 : test();
543 1576 : test();
544 1576 : IF( ( LT_16( voicing_fr[0], 6554 /* 0.2f in Q15 */ ) ) && /* normalized correlation high in 2st sf. */
545 : ( LT_16( voicing_fr[1], 6554 /* 0.2f in Q15 */ ) ) && /* normalized correlation high in 2st sf. */
546 : ( LT_16( voicing_fr[2], 6554 /* 0.2f in Q15 */ ) ) && /* normalized correlation high in 3rd sf. */
547 : ( LT_16( voicing_fr[3], 6554 /* 0.2f in Q15 */ ) ) && /* normalized correlation high in 4th sf. */
548 : ( GT_16( vadnoise, 25 << 8 ) ) ) /* when speech is clean */
549 :
550 : {
551 0 : st_fx->rf_mode = 0;
552 0 : move16();
553 : /* Current frame cannot be compressed to pack the partial redundancy;*/
554 :
555 0 : if ( st_fx->rf_mode != st_fx->Opt_RF_ON )
556 : {
557 0 : core_coder_mode_switch_fx( st_fx, st_fx->last_total_brate, 0, shift );
558 : }
559 : }
560 : }
561 :
562 : /*-----------------------------------------------------------------*
563 : * Updates
564 : *-----------------------------------------------------------------*/
565 :
566 : /* update spike hysteresis parameters */
567 3100 : test();
568 3100 : if ( st_fx->spike_hyst >= 0 && LT_16( st_fx->spike_hyst, 2 ) )
569 : {
570 7 : st_fx->spike_hyst = add( st_fx->spike_hyst, 1 ); /* Q0 */
571 : }
572 :
573 : /* reset spike hysteresis */
574 3100 : test();
575 3100 : test();
576 3100 : test();
577 3146 : if ( ( GT_16( st_fx->spike_hyst, 1 ) ) &&
578 89 : ( GT_16( dE3, 5 << 8 ) || /* energy increases */
579 61 : ( GT_16( relE, -3328 ) && ( GT_16( add_sat( mean_voi3, corr_shift ), 22774 ) ) ) ) ) /* normalized correlation is high */
580 : {
581 5 : st_fx->spike_hyst = -1;
582 5 : move16();
583 : }
584 :
585 : /* update tilt parameters */
586 3100 : st_fx->ee_old_fx = ee[1];
587 3100 : move32(); /*Q6*/
588 3100 : st_fx->old_dE1_fx = dE1;
589 3100 : move32(); /*Q13*/
590 :
591 : /* save the raw coder_type for various modules later in the codec (the reason is that e.g. UNVOICED is lost at higher rates) */
592 3100 : st_fx->coder_type_raw = coder_type;
593 3100 : move16();
594 :
595 3100 : return coder_type;
596 : }
597 :
598 : /*-------------------------------------------------------------------*
599 : * find_uv()
600 : *
601 : * Decision about coder type
602 : *-------------------------------------------------------------------*/
603 1132964 : Word16 find_uv_ivas_fx( /* o : coding type */
604 : Encoder_State *st_fx, /* i/o: encoder state structure */
605 : const Word16 *T_op_fr, /* i : pointer to adjusted fractional pitch (4 val.) Q6*/
606 : const Word16 *voicing_fr, /* i : refined correlation for each subframes Q15*/
607 : const Word16 *speech, /* i : pointer to speech signal for E computation Q_new*/
608 : const Word32 *ee, /* i : lf/hf Energy ratio for present frame Q6*/
609 : Word32 *dE1X, /* o : sudden energy increase for S/M classifier Q13*/
610 : const Word16 corr_shift, /* i : normalized correlation correction in noise Q15*/
611 : const Word16 relE, /* i : relative frame energy Q8*/
612 : const Word16 Etot, /* i : total energy Q8*/
613 : const Word32 hp_E[], /* i : energy in HF q_hp_E*/
614 : Word16 *flag_spitch, /* i/o: flag to indicate very short stable pitch and high correlation Q0*/
615 : const Word16 last_core_orig, /* i : original last core Q0*/
616 : STEREO_CLASSIF_HANDLE hStereoClassif, /* i/o: stereo classifier structure */
617 : const Word16 Q_new,
618 : const Word16 q_hp_E )
619 : {
620 : Word16 coder_type, i;
621 : Word32 mean_ee, dE1, fac_32;
622 : const Word16 *pt_speech;
623 : Word32 L_tmp, enr_ssf[2 * NB_SSF + 2 * NB_SSF + 2], E_min_th;
624 : Word16 dE2;
625 : Word16 ind_deltaMax, tmp_offset_flag;
626 : Word32 Ltmp0, *pt_enr_ssf, *pt_enr_ssf1, dE2_th;
627 : Word16 exp0, exp1;
628 : Word16 wtmp0, wtmp1;
629 : Word16 fac, mean_voi3, dE3;
630 : Word16 relE_thres;
631 : Word16 mean_voi3_offset;
632 : Word16 voicing_m, dpit1, dpit2, dpit3;
633 : Word16 ee0_th, ee1_th, voi_th, nb_cond, flag_low_relE;
634 1132964 : NOISE_EST_HANDLE hNoiseEst = st_fx->hNoiseEst;
635 1132964 : SC_VBR_ENC_HANDLE hSC_VBR = st_fx->hSC_VBR;
636 : #ifndef ISSUE_1867_replace_overflow_libenc
637 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
638 : Flag Overflow = 0;
639 : move32();
640 : #endif
641 : #endif
642 : Word16 Last_Resort;
643 : Word16 vadnoise;
644 :
645 1132964 : IF( hSC_VBR != NULL )
646 : {
647 0 : Last_Resort = hSC_VBR->Last_Resort; /* Q0 */
648 0 : move16();
649 0 : vadnoise = hSC_VBR->vadnoise_fx; /* Q8 */
650 0 : move16();
651 : }
652 : ELSE
653 : {
654 1132964 : Last_Resort = 0;
655 1132964 : move16();
656 1132964 : vadnoise = 0;
657 1132964 : move16();
658 : }
659 :
660 : /*-----------------------------------------------------------------*
661 : * Detect sudden energy increases to catch voice and music
662 : * temporal events (dE1)
663 : *
664 : * - Find maximum energy per short subblocks.
665 : * Two subblock sets are used shifted by half the subblock length
666 : * - Find maximum energy ratio between adjacent subblocks
667 : *-----------------------------------------------------------------*/
668 :
669 : /* Find maximum energy per short subblocks */
670 1132964 : pt_speech = speech - SSF;
671 1132964 : pt_enr_ssf = enr_ssf + 2 * NB_SSF;
672 21526316 : FOR( i = 0; i < 2 * ( NB_SSF + 1 ); i++ )
673 : {
674 20393352 : emaximum_fx( Q_new, pt_speech, SSF, pt_enr_ssf );
675 20393352 : pt_speech += ( SSF / 2 );
676 20393352 : pt_enr_ssf++;
677 : }
678 :
679 1132964 : dE1 = 0;
680 1132964 : move16();
681 1132964 : ind_deltaMax = 0;
682 1132964 : move16();
683 1132964 : pt_enr_ssf = enr_ssf + 2 * NB_SSF;
684 1132964 : pt_enr_ssf1 = pt_enr_ssf + 2;
685 :
686 : /* Test on energy increase between adjacent sub-subframes */
687 1132964 : exp1 = 0;
688 1132964 : move16();
689 19260388 : FOR( i = 0; i < 2 * NB_SSF; i++ )
690 : {
691 : /*fac = *pt_enr_ssf1 / (*pt_enr_ssf + 1);*/
692 18127424 : Ltmp0 = L_max( *pt_enr_ssf, 1 );
693 18127424 : exp0 = norm_l( Ltmp0 );
694 18127424 : wtmp0 = extract_h( L_shl( Ltmp0, exp0 ) );
695 18127424 : exp1 = sub( norm_l( *pt_enr_ssf1 ), 1 );
696 18127424 : wtmp1 = extract_h( L_shl( *pt_enr_ssf1, exp1 ) );
697 18127424 : fac = div_s( wtmp1, wtmp0 );
698 18127424 : fac_32 = L_shr_sat( L_deposit_l( fac ), add( sub( exp1, exp0 ), 15 - 13 ) ); /* fac32 in Q13*/
699 :
700 18127424 : if ( GT_32( fac_32, dE1 ) )
701 : {
702 3535136 : ind_deltaMax = i;
703 3535136 : move16();
704 : }
705 :
706 18127424 : dE1 = L_max( dE1, fac_32 ); /* Q13 */
707 :
708 18127424 : pt_enr_ssf++;
709 18127424 : pt_enr_ssf1++;
710 : }
711 :
712 1132964 : IF( hStereoClassif != NULL )
713 : {
714 782051 : IF( st_fx->idchan == 0 )
715 : {
716 420855 : hStereoClassif->dE1_ch1_fx = dE1; /* Q13 */
717 420855 : move32();
718 420855 : hStereoClassif->dE1_ch1_e = 31 - Q13;
719 420855 : move16();
720 : }
721 : ELSE
722 : {
723 361196 : hStereoClassif->dE1_ch2_fx = dE1; /* Q13 */
724 361196 : move32();
725 361196 : hStereoClassif->dE1_ch2_e = 31 - Q13;
726 361196 : move16();
727 : }
728 : }
729 :
730 1132964 : if ( dE1X != NULL )
731 : {
732 1132964 : *dE1X = dE1; /* Q13 */
733 1132964 : move32();
734 : }
735 :
736 : /*-----------------------------------------------------------------*
737 : * Average spectral tilt
738 : * Average voicing (normalized correlation)
739 : *-----------------------------------------------------------------*/
740 :
741 : /*mean_ee = 1.0f/3.0f * (st->ee_old + ee[0] + ee[1]); */ /* coefficients take into account the position of the window */
742 : #ifdef ISSUE_1867_replace_overflow_libenc
743 1132964 : mean_ee = L_add_sat( L_add_sat( st_fx->ee_old_fx, ee[0] ), ee[1] ); /* Q6 */
744 : #else
745 : mean_ee = L_add_o( L_add_o( st_fx->ee_old_fx, ee[0], &Overflow ), ee[1], &Overflow ); /* Q6 */
746 : #endif
747 1132964 : mean_ee = Mult_32_16( mean_ee, 10923 ); /*Q6*/
748 :
749 : /* mean_voi3 = 1.0f/3.0f * (voicing[0] + voicing[1] + voicing[2]);*/
750 1132964 : Ltmp0 = L_mult( st_fx->voicing_fx[0], 10923 /* 1/3 in Q15 */ ); /* Q31 */
751 1132964 : Ltmp0 = L_mac( Ltmp0, st_fx->voicing_fx[1], 10923 /* 1/3 in Q15 */ ); /* Q31 */
752 1132964 : mean_voi3 = mac_r_sat( Ltmp0, st_fx->voicing_fx[2], 10923 /* 1/3 in Q15 */ ); /*Q15*/
753 : /*-----------------------------------------------------------------*
754 : * Total frame energy difference (dE3)
755 : *-----------------------------------------------------------------*/
756 :
757 1132964 : dE3 = sub( Etot, extract_h( hNoiseEst->Etot_last_32fx ) ); /*Q8*/
758 :
759 : /*-----------------------------------------------------------------*
760 : * Energy decrease after spike (dE2)
761 : *-----------------------------------------------------------------*/
762 :
763 : /* set different thresholds and conditions for NB and WB input */
764 1132964 : dE2_th = 30 << 10;
765 1132964 : move32();
766 1132964 : nb_cond = 1;
767 1132964 : move16(); /* no additional condition for WB input */
768 1132964 : IF( st_fx->input_bwidth == NB )
769 : {
770 4290 : dE2_th = 21 << 10;
771 4290 : move32();
772 : #ifdef ISSUE_1867_replace_overflow_libenc
773 4290 : if ( GE_16( add_sat( mean_voi3, corr_shift ), 22282 ) ) /*( mean_voi3 + corr_shift ) >= 0.68f*/
774 : #else
775 : if ( GE_16( add_o( mean_voi3, corr_shift, &Overflow ), 22282 ) ) /*( mean_voi3 + corr_shift ) >= 0.68f*/
776 : #endif
777 : {
778 2880 : nb_cond = 0;
779 2880 : move16();
780 : }
781 : }
782 :
783 : /* calcualte maximum energy decrease */
784 1132964 : dE2 = 0;
785 1132964 : move16(); /* Test on energy decrease after an energy spike */
786 1132964 : pt_enr_ssf = enr_ssf + 2 * NB_SSF;
787 :
788 1132964 : test();
789 1132964 : IF( GT_32( dE1, 30 << 13 ) && nb_cond ) /*>30 Q13*/
790 : {
791 19696 : IF( LT_16( sub( shl( NB_SSF, 1 ), ind_deltaMax ), L_ENR ) )
792 : {
793 8233 : st_fx->old_ind_deltaMax = ind_deltaMax; /* Q0 */
794 8233 : move16();
795 8233 : Copy32( pt_enr_ssf, st_fx->old_enr_ssf_fx, 2 * NB_SSF ); /* Qx */
796 : }
797 : ELSE
798 : {
799 11463 : st_fx->old_ind_deltaMax = -1;
800 11463 : move16();
801 11463 : dE2 = find_ener_decrease_fx( ind_deltaMax, pt_enr_ssf ); /*Q10*/
802 :
803 11463 : if ( GT_32( dE2, dE2_th ) )
804 : {
805 150 : st_fx->spike_hyst = 0;
806 150 : move16();
807 : }
808 : }
809 : }
810 : ELSE
811 : {
812 1113268 : IF( st_fx->old_ind_deltaMax >= 0 )
813 : {
814 9205 : Copy32( st_fx->old_enr_ssf_fx, enr_ssf, 2 * NB_SSF ); /* Qx */
815 9205 : dE2 = find_ener_decrease_fx( st_fx->old_ind_deltaMax, enr_ssf ); /* Q10 */
816 :
817 9205 : if ( GT_32( dE2, dE2_th ) )
818 : {
819 111 : st_fx->spike_hyst = 1;
820 111 : move16();
821 : }
822 : }
823 :
824 1113268 : st_fx->old_ind_deltaMax = -1;
825 1113268 : move16();
826 : }
827 :
828 : /*-----------------------------------------------------------------*
829 : * Detection of voiced offsets (tmp_offset_flag)
830 : *-----------------------------------------------------------------*/
831 :
832 1132964 : tmp_offset_flag = 1;
833 1132964 : move16();
834 :
835 1132964 : IF( st_fx->input_bwidth != NB )
836 : {
837 1128674 : ee0_th = 154; /*2.4 in Q6 */
838 1128674 : move16();
839 1128674 : voi_th = 24248; /*0.74f Q15 */
840 1128674 : move16();
841 : }
842 : ELSE
843 : {
844 4290 : ee0_th = 627; /*9.8f Q6 */
845 4290 : move16();
846 4290 : voi_th = 24904; /*0.76f Q15*/
847 4290 : move16();
848 : }
849 :
850 1132964 : E_min_th = L_shl( E_MIN_IVAS_FX_Q31, sub( q_hp_E, Q31 ) );
851 :
852 1132964 : test();
853 1132964 : test();
854 1132964 : test();
855 : #ifdef ISSUE_1867_replace_overflow_libenc
856 1132964 : IF( ( EQ_16( st_fx->last_coder_type_raw, UNVOICED ) ) || /* previous frame was unvoiced */
857 : ( ( LT_32( ee[0], ee0_th ) ) && ( GT_32( hp_E[0], E_min_th ) ) && /* energy is concentrated in high frequencies provided that some energy is present in HF */
858 : ( LT_16( add_sat( st_fx->voicing_fx[0], corr_shift ), voi_th ) ) ) )
859 : /* normalized correlation is low */
860 : #else
861 : IF( ( EQ_16( st_fx->last_coder_type_raw, UNVOICED ) ) || /* previous frame was unvoiced */
862 : ( ( LT_32( ee[0], ee0_th ) ) && ( GT_32( hp_E[0], E_min_th ) ) && /* energy is concentrated in high frequencies provided that some energy is present in HF */
863 : ( LT_16( add_o( st_fx->voicing_fx[0], corr_shift, &Overflow ), voi_th ) ) ) ) /* normalized correlation is low */
864 : #endif
865 : {
866 131705 : tmp_offset_flag = 0;
867 131705 : move16();
868 : }
869 :
870 : /*-----------------------------------------------------------------*
871 : * Decision about UC
872 : *-----------------------------------------------------------------*/
873 :
874 : /* SC-VBR - set additional parameters and thresholds for SC-VBR */
875 1132964 : mean_voi3_offset = 0;
876 1132964 : move16();
877 1132964 : flag_low_relE = 0;
878 1132964 : move16();
879 1132964 : ee1_th = 608; /*9.5 Q6*/
880 1132964 : move16();
881 1132964 : test();
882 1132964 : test();
883 1132964 : IF( st_fx->Opt_SC_VBR || ( EQ_16( st_fx->idchan, 1 ) && EQ_16( st_fx->element_mode, IVAS_CPE_TD ) ) ) /* Allow the low energy flag for the secondary channel */
884 : {
885 3811 : ee1_th = 544; /*8.5f Q6*/
886 3811 : move16();
887 :
888 : /* SC-VBR - determine the threshold on relative energy as a function of lp_noise */
889 3811 : IF( st_fx->input_bwidth != NB )
890 : {
891 : /*relE_thres = 0.700f * st->lp_noise - 33.5f; (lp_noise in Q8, constant Q8<<16) */
892 3811 : L_tmp = L_mac( -562036736 /* 33.5f in Q24 */, 22938 /* 0.7 in Q15 */, extract_h( st_fx->lp_noise_32fx ) ); // Q24
893 3811 : IF( Last_Resort == 0 )
894 : {
895 : /*relE_thres = 0.650f * st->lp_noise - 33.5f; (lp_noise in Q8, constant Q8<<16)*/
896 3811 : L_tmp = L_mac( -562036736 /* 33.5f in Q24 */, 21299 /* 0.650f in Q15 */, extract_h( st_fx->lp_noise_32fx ) ); // Q24
897 : }
898 3811 : relE_thres = round_fx( L_tmp );
899 : }
900 : ELSE
901 : {
902 :
903 : /*relE_thres = 0.60f * st->lp_noise - 28.2f; (lp_noise in Q8, constant Q8<<16)*/
904 0 : L_tmp = L_mac( -473117491 /* 28.2f in Q24 */, 19661 /* 0.6f in Q15 */, extract_h( st_fx->lp_noise_32fx ) ); // Q24
905 0 : relE_thres = round_fx( L_tmp );
906 : }
907 3811 : relE_thres = s_max( relE_thres, -6400 /* -25.0f in Q8 */ ); /* Q8 */
908 :
909 : /* SC-VBR = set flag on low relative energy */
910 3811 : if ( LT_16( relE, relE_thres ) )
911 : {
912 332 : flag_low_relE = 1;
913 332 : move16();
914 : }
915 :
916 : /* SC-VBR - correction of voicing threshold for NB inputs (important only in noisy conditions) */
917 3811 : test();
918 3811 : if ( st_fx->input_bwidth == NB && LT_16( vadnoise, 20 << 8 ) ) /* vadnoise in Q8, constant Q0<<8 */
919 : {
920 0 : mean_voi3_offset = 1638; /*0.05f Q15*/
921 0 : move16();
922 : }
923 : }
924 :
925 : /* make decision whether frame is unvoiced */
926 1132964 : coder_type = GENERIC;
927 1132964 : move16();
928 1132964 : IF( st_fx->input_bwidth == NB )
929 : {
930 4290 : test();
931 4290 : test();
932 4290 : test();
933 4290 : test();
934 4290 : test();
935 4290 : test();
936 4290 : test();
937 4290 : test();
938 4290 : test();
939 4290 : test();
940 : #ifdef ISSUE_1867_replace_overflow_libenc
941 4290 : IF( ( ( LT_16( add_sat( mean_voi3, corr_shift ), add( 22282 /* 0.68 in Q15 */, mean_voi3_offset ) ) ) && /* normalized correlation low */
942 : ( LT_16( add_sat( st_fx->voicing_fx[2], corr_shift ), 25887 /* 0.79 in Q15 */ ) ) && /* normalized correlation low on look-ahead - onset detection */
943 : ( LT_32( ee[0], 640 /* 10.0f in Q6 */ ) ) && ( GT_32( hp_E[0], E_min_th ) ) && /* energy concentrated in high frequencies provided that some energy is present in HF... */
944 : ( LT_32( ee[1], ee1_th ) ) && ( GT_32( hp_E[1], E_min_th ) ) && /* ... biased towards look-ahead to detect onsets */
945 : ( tmp_offset_flag == 0 ) && /* Take care of voiced offsets */
946 : /*( st_fx->music_hysteresis_fx == 0 ) &&*/ /* ... and in segment after AUDIO frames */
947 : ( LE_32( dE1, 237568 /* 29.0f in Q13 */ ) ) && /* Avoid on sharp energy spikes */
948 : ( LE_32( st_fx->old_dE1_fx, 237568 /* 29.0f in Q13 */ ) ) && /* + one frame hysteresis */
949 : ( st_fx->spike_hyst < 0 ) ) || /* Avoid after sharp energy spikes followed by decay (e.g. castanets) */
950 : flag_low_relE )
951 : #else
952 : IF( ( ( LT_16( add_o( mean_voi3, corr_shift, &Overflow ), add( 22282 /* 0.68 in Q15 */, mean_voi3_offset ) ) ) && /* normalized correlation low */
953 : ( LT_16( add_o( st_fx->voicing_fx[2], corr_shift, &Overflow ), 25887 /* 0.79 in Q15 */ ) ) && /* normalized correlation low on look-ahead - onset detection */
954 : ( LT_32( ee[0], 640 /* 10.0f in Q6 */ ) ) && ( GT_32( hp_E[0], E_min_th ) ) && /* energy concentrated in high frequencies provided that some energy is present in HF... */
955 : ( LT_32( ee[1], ee1_th ) ) && ( GT_32( hp_E[1], E_min_th ) ) && /* ... biased towards look-ahead to detect onsets */
956 : ( tmp_offset_flag == 0 ) && /* Take care of voiced offsets */
957 : /*( st_fx->music_hysteresis_fx == 0 ) &&*/ /* ... and in segment after AUDIO frames */
958 : ( LE_32( dE1, 237568 /* 29.0f in Q13 */ ) ) && /* Avoid on sharp energy spikes */
959 : ( LE_32( st_fx->old_dE1_fx, 237568 /* 29.0f in Q13 */ ) ) && /* + one frame hysteresis */
960 : ( st_fx->spike_hyst < 0 ) ) || /* Avoid after sharp energy spikes followed by decay (e.g. castanets) */
961 : flag_low_relE )
962 : #endif
963 : /* low relative frame energy (only for SC-VBR) */
964 : {
965 119 : coder_type = UNVOICED;
966 119 : move16();
967 : }
968 : }
969 : ELSE
970 : {
971 1128674 : test();
972 1128674 : test();
973 1128674 : test();
974 1128674 : test();
975 1128674 : test();
976 1128674 : test();
977 1128674 : test();
978 1128674 : test();
979 1128674 : test();
980 : #ifdef ISSUE_1867_replace_overflow_libenc
981 1718667 : if ( ( ( LT_16( add_sat( mean_voi3, corr_shift ), add( 22774 /* 0.695f in Q15 */, mean_voi3_offset ) ) ) && /* normalized correlation low */
982 : #else
983 : if ( ( ( LT_16( add_o( mean_voi3, corr_shift, &Overflow ), add( 22774 /* 0.695f in Q15 */, mean_voi3_offset ) ) ) && /* normalized correlation low */
984 : #endif
985 : /*( LT_16( add_o( st_fx->voicing_fx[2], corr_shift, &Overflow ), 25887 ) ) && */ /* normalized correlation low on look-ahead - onset detection */
986 964320 : ( LT_32( ee[0], 397 /* 6.2f in Q6 */ ) ) && ( GT_32( hp_E[0], E_min_th ) ) && /* energy concentrated in high frequencies provided that some energy is present in HF... */
987 237863 : ( LT_32( ee[1], 397 /* 6.2f in Q16 */ ) ) && ( GT_32( hp_E[1], E_min_th ) ) && /* ... biased towards look-ahead to detect onsets */
988 85595 : ( tmp_offset_flag == 0 ) && /* Take care of voiced offsets */
989 : /*( st_fx->music_hysteresis_fx == 0 ) && */ /* ... and in segment after AUDIO frames */
990 167769 : ( LE_32( dE1, 245760 /* 30.0f in Q13 */ ) ) && /* Avoid on sharp energy spikes */
991 82174 : ( LE_32( st_fx->old_dE1_fx, 245760 /* 30.0f in Q13 */ ) ) && /* + one frame hysteresis */
992 79688 : ( st_fx->spike_hyst < 0 ) ) /* Avoid after sharp energy spikes followed by decay (e.g. castanets) */
993 1049260 : || ( flag_low_relE && ( LE_32( st_fx->old_dE1_fx, 245760 /* 30.0f in Q13 */ ) ) ) ) /* low relative frame energy (only for SC-VBR) */
994 : {
995 79694 : coder_type = UNVOICED;
996 79694 : move16();
997 : }
998 : }
999 :
1000 : /*-----------------------------------------------------------------*
1001 : * Decision about VC
1002 : *-----------------------------------------------------------------*/
1003 1132964 : if ( st_fx->Opt_SC_VBR )
1004 : {
1005 0 : hSC_VBR->set_ppp_generic = 0;
1006 : }
1007 1132964 : move16();
1008 :
1009 1132964 : test();
1010 1132964 : test();
1011 1132964 : IF( EQ_16( st_fx->localVAD, 1 ) && EQ_16( coder_type, GENERIC ) && NE_16( last_core_orig, AMR_WB_CORE ) )
1012 : {
1013 900032 : dpit1 = abs_s( sub( T_op_fr[1], T_op_fr[0] ) ); /* Q6 */
1014 900032 : dpit2 = abs_s( sub( T_op_fr[2], T_op_fr[1] ) ); /* Q6 */
1015 900032 : dpit3 = abs_s( sub( T_op_fr[3], T_op_fr[2] ) ); /* Q6 */
1016 :
1017 900032 : test();
1018 900032 : test();
1019 900032 : test();
1020 900032 : test();
1021 900032 : test();
1022 900032 : test();
1023 900032 : test();
1024 900032 : test();
1025 900032 : test();
1026 900032 : IF( ( GT_16( voicing_fr[0], 19825 /* 0.605 in Q15 */ ) ) && /* normalized correlation high in 1st sf. */
1027 : ( GT_16( voicing_fr[1], 19825 /* 0.605 in Q15 */ ) ) && /* normalized correlation high in 2st sf. */
1028 : ( GT_16( voicing_fr[2], 19825 /* 0.605 in Q15 */ ) ) && /* normalized correlation high in 3st sf. */
1029 : ( GT_16( voicing_fr[3], 19825 /* 0.605 in Q15 */ ) ) && /* normalized correlation high in 4st sf. */
1030 : ( GT_32( mean_ee, 256 /* 4.0f in Q6 */ ) ) && /* energy concentrated in low frequencies */
1031 : ( LT_16( dpit1, 3 << 6 ) ) &&
1032 : ( LT_16( dpit2, 3 << 6 ) ) &&
1033 : ( LT_16( dpit3, 3 << 6 ) ) )
1034 : {
1035 376537 : coder_type = VOICED;
1036 376537 : move16();
1037 : }
1038 523495 : ELSE IF( st_fx->Opt_SC_VBR && st_fx->input_bwidth == NB && LT_16( vadnoise, 20 << 8 ) )
1039 : {
1040 0 : test();
1041 0 : test();
1042 0 : test();
1043 0 : test();
1044 0 : test();
1045 0 : test();
1046 0 : test();
1047 0 : IF( GT_16( voicing_fr[0], 8192 /* 0.25 in Q15 */ ) && /* normalized correlation high in 1st sf. */
1048 : ( GT_16( voicing_fr[1], 8192 /* 0.25 in Q15 */ ) ) && /* normalized correlation high in 2st sf. */
1049 : ( GT_16( voicing_fr[2], 8192 /* 0.25 in Q15 */ ) ) && /* normalized correlation high in 3st sf. */
1050 : ( GT_16( voicing_fr[3], 8192 /* 0.25 in Q15 */ ) ) && /* normalized correlation high in 4st sf. */
1051 : ( GT_32( mean_ee, 64 /* 1.0f in Q6 */ ) ) && /* energy concentrated in low frequencies */
1052 : ( LT_16( dpit1, 5 << 6 ) ) &&
1053 : ( LT_16( dpit2, 5 << 6 ) ) &&
1054 : ( LT_16( dpit3, 5 << 6 ) ) )
1055 : {
1056 0 : hSC_VBR->set_ppp_generic = 1;
1057 0 : move16();
1058 0 : coder_type = VOICED;
1059 0 : move16();
1060 : }
1061 : }
1062 :
1063 : /* set VOICED mode for frames with very stable pitch and high correlation
1064 : and avoid to switch to AUDIO/MUSIC later */
1065 900032 : voicing_m = mac_r( L_mac( L_mac( L_mult( voicing_fr[3], 8192 /* 0.25 in Q15 */ ), voicing_fr[2], 8192 /* 0.25 in Q15 */ ), voicing_fr[1], 8192 /* 0.25 in Q15 */ ), voicing_fr[0], 8192 /* 0.25 in Q15 */ ); /* Q15 */
1066 900032 : test();
1067 900032 : test();
1068 900032 : test();
1069 900032 : test();
1070 900032 : test();
1071 900032 : IF( *flag_spitch || ( LE_16( dpit1, 3 << 6 ) && LE_16( dpit2, 3 << 6 ) && LE_16( dpit3, 3 << 6 ) &&
1072 : GT_16( voicing_m, 31130 /* 0.95f in Q15 */ ) && GT_16( st_fx->voicing_sm_fx, 31785 /* 0.97f in Q15 */ ) ) )
1073 : {
1074 39256 : coder_type = VOICED;
1075 39256 : move16();
1076 39256 : *flag_spitch = 1;
1077 39256 : move16(); /*to avoid switch to AUDIO/MUSIC later*/
1078 : }
1079 : }
1080 :
1081 : /*-----------------------------------------------------------------*
1082 : * Channel-aware mode - set RF mode and total bitrate
1083 : *-----------------------------------------------------------------*/
1084 :
1085 1132964 : st_fx->rf_mode = st_fx->Opt_RF_ON; /* Q0 */
1086 1132964 : move16();
1087 :
1088 1132964 : IF( EQ_16( coder_type, GENERIC ) )
1089 : {
1090 671394 : test();
1091 671394 : test();
1092 671394 : test();
1093 671394 : test();
1094 671394 : IF( ( LT_16( voicing_fr[0], 6554 /* 0.2f in Q15 */ ) ) && /* normalized correlation high in 2st sf. */
1095 : ( LT_16( voicing_fr[1], 6554 /* 0.2f in Q15 */ ) ) && /* normalized correlation high in 2st sf. */
1096 : ( LT_16( voicing_fr[2], 6554 /* 0.2f in Q15 */ ) ) && /* normalized correlation high in 3rd sf. */
1097 : ( LT_16( voicing_fr[3], 6554 /* 0.2f in Q15 */ ) ) && /* normalized correlation high in 4th sf. */
1098 : ( GT_16( vadnoise, 25 << 8 ) ) ) /* when speech is clean */
1099 :
1100 : {
1101 0 : st_fx->rf_mode = 0;
1102 0 : move16();
1103 : /* Current frame cannot be compressed to pack the partial redundancy;*/
1104 :
1105 0 : IF( NE_16( st_fx->rf_mode, st_fx->Opt_RF_ON ) )
1106 : {
1107 0 : core_coder_mode_switch_ivas_fx( st_fx, st_fx->last_total_brate, 0 );
1108 : }
1109 : }
1110 : }
1111 :
1112 : /*-----------------------------------------------------------------*
1113 : * UNCLR classifier
1114 : *-----------------------------------------------------------------*/
1115 :
1116 1132964 : IF( hStereoClassif != NULL )
1117 : {
1118 782051 : test();
1119 782051 : test();
1120 782051 : test();
1121 782051 : test();
1122 782051 : test();
1123 782051 : IF( st_fx->element_mode > EVS_MONO && ( EQ_16( coder_type, GENERIC ) || EQ_16( coder_type, UNVOICED ) || coder_type == INACTIVE || st_fx->localVAD == 0 ) && LT_16( hStereoClassif->unclr_sw_enable_cnt[st_fx->idchan], MAX_UV_CNT ) )
1124 : {
1125 491564 : hStereoClassif->unclr_sw_enable_cnt[st_fx->idchan] = add( hStereoClassif->unclr_sw_enable_cnt[st_fx->idchan], 1 );
1126 491564 : move16();
1127 : }
1128 : ELSE
1129 : {
1130 290487 : hStereoClassif->unclr_sw_enable_cnt[st_fx->idchan] = 0;
1131 290487 : move16();
1132 : }
1133 : }
1134 :
1135 : /*-----------------------------------------------------------------*
1136 : * Updates
1137 : *-----------------------------------------------------------------*/
1138 :
1139 : /* update spike hysteresis parameters */
1140 1132964 : test();
1141 1132964 : if ( st_fx->spike_hyst >= 0 && LT_16( st_fx->spike_hyst, 2 ) )
1142 : {
1143 411 : st_fx->spike_hyst = add( st_fx->spike_hyst, 1 ); /* Q0 */
1144 411 : move16();
1145 : }
1146 :
1147 : /* reset spike hysteresis */
1148 1132964 : test();
1149 1132964 : test();
1150 1132964 : test();
1151 1136235 : if ( ( GT_16( st_fx->spike_hyst, 1 ) ) &&
1152 6403 : ( GT_16( dE3, 5 << 8 ) || /* energy increases */
1153 5280 : ( GT_16( relE, -3328 /* 13 in Q8 */ ) && ( GT_16( add_sat( mean_voi3, corr_shift ), 22774 /* 0.695 in Q15 */ ) ) ) ) ) /* normalized correlation is high */
1154 : {
1155 248 : st_fx->spike_hyst = -1;
1156 248 : move16();
1157 : }
1158 :
1159 : /* update tilt parameters */
1160 1132964 : st_fx->ee_old_fx = ee[1];
1161 1132964 : move32(); /*Q6*/
1162 1132964 : st_fx->old_dE1_fx = dE1;
1163 1132964 : move32(); /*Q13*/
1164 :
1165 : /* save the raw coder_type for various modules later in the codec (the reason is that e.g. UNVOICED is lost at higher rates) */
1166 1132964 : st_fx->coder_type_raw = coder_type; /* Q0 */
1167 1132964 : move16();
1168 :
1169 1132964 : return coder_type;
1170 : }
|