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"
6 : #include "cnst.h" /* Common constants */
7 : //#include "prot_fx.h" /* Function prototypes */
8 : #include "rom_enc.h"
9 : #include "prot_fx.h" /* Function prototypes */
10 : #include "prot_fx_enc.h" /* Function prototypes */
11 :
12 :
13 : /*-----------------------------------------------------------------*
14 : * Local constants
15 : *-----------------------------------------------------------------*/
16 : /* old fx constants */
17 : #define HANGOVER_LONG 10 /* Hangover for CNG */
18 : #define HANGOVER_LONG_HE 20 /* Hangover of CNG */
19 : #define HANGOVER_LONG_NB 8 /* Hangover for CNG */
20 : #define ACTIVE_FRAMES 3 /* Number of consecutive active SPEECH frames necessary to trigger HO */
21 :
22 : /* SNR threshold curve constants for WB input */
23 : #define SK16_2_FX 16930 /* Q14 (1.0333f)-> Linear function for clean speech */
24 : #define SC16_2_FX -4608 /* Q8 (-18)*/
25 : #define NK16_2_FX 13529 /* Q15 (.41287)-> Linear function for noisy speech */
26 : #define NC16_2_FX 3394 /* Q8 (13.259625)*/
27 : /* SNR threshold curve constants for NB input */
28 : #define NK8_1_FX 3509 /*Q15 (0.1071f) Linear function for noisy speech */
29 : #define NC8_1_FX 4224 /*Q8 (16.5f) */
30 : #define SK8_1_FX 12406 /*Q15 (0.3786f) Linear function for clean speech */
31 : #define SC8_1_FX 2834 /*Q8 (11.07f) */
32 : #define SIGN_THR_FX 40 /*Q4 (2.5f) Significanse threshold for per band snr calculation */
33 : #define MIN_SNR_FX 2 /*Q4 Minimum snr used for per band snr calculation */
34 :
35 :
36 : #define THR_M0_FX 3379 /* Q8 (13.2) Zero ofset for threshod */
37 : #define THR_K_BG_FX -8192 /* Q15(-0.25) Coefficient for dependence on background level */
38 : #define THR_K_BG_OFS_FX 5120 /* Q8 (20.0f) Zero offset for background level */
39 : #define THR_K_SNR_FX 3277 /* Q15 (0.1f) Coefficient for dependence on SNR */
40 : #define THR_K_EV_FX 18022 /* Q15 (0.55) Coefficient for dependence on noise variations */
41 :
42 :
43 : #define HO_DTX_CLEAN 1 /* Hangover for dtx in clean conditions */
44 : #define HO_DTX_NOISY 10 /* Hangover for dtx in noisy conditions */
45 : #define HO_DTX_NOISY2 4 /* Hangover for dtx in very noisy conditions */
46 : #define VAD_THR_MIN_FX 2688
47 :
48 : #define ONE_LG10 2466 /* 1.0*log10(2) in Q13 */
49 :
50 :
51 : #define HANGOVER_LONG_FX 10 /* Hangover for CNG */
52 : #define HANGOVER_LONG_MUSIC_FX 20 /* Hangover of CNG */
53 : #define HANGOVER_LONG_HE_FX 20 /* Hangover of CNG */
54 : #define HANGOVER_LONG_NB_FX 8 /* Hangover for CNG */
55 : #define ACTIVE_FRAMES_FX 3 /* Number of consecutive active SPEECH frames necessary to trigger HO */
56 :
57 : /* SNR threshold curve constants for WB input */
58 : #define TH16_2_FX 8960 /* Q8 (35) -> lp SNR that separates the curves for clean speech and noisy speech */
59 : #define TH8_1_FX 5120 /*Q8 (20.0f) long-term SNR that separates the curves for clean speech and noisy speech */
60 :
61 : #define TH16_2_NFLAG_FX 8960 /* Q8 (35) */
62 : #define TH8_1_NFLAG_FX 8960 /* Q8 (35) */
63 :
64 :
65 : #define SNR_OUTLIER_WGHT_1_FX 16384 /* Q14 (1.00)*/
66 : #define SNR_OUTLIER_WGHT_2_FX 16548 /* Q14 (1.01)*/
67 : #define SNR_OUTLIER_WGHT_3_FX 16712 /* Q14 (1.02)*/
68 : #define INV_OUTLIER_THR_1_FX 3277 /* (1/10.0f) in Q15*/
69 : #define INV_OUTLIER_THR_2_FX 5461 /* (1/6.0f) in Q15 */
70 :
71 : #define MAX_SNR_OUTLIER_IND_FX 17 /*Q0 */
72 : #define MAX_SNR_OUTLIER_1_FX 160 /*Q4 (10.0f)*/
73 : #define MAX_SNR_OUTLIER_2_FX 400 /*Q4 (25.0f)*/
74 : #define MAX_SNR_OUTLIER_3_FX 800 /*Q4 (50.0f)*/
75 :
76 :
77 : /* snr_sum = "scale" * (float)log10( L_snr_sum ) ;*/
78 1282890 : static Word16 vad_snr_log_fx( /* o: Q8 */
79 : Word32 L_snr, /* i: Q4 */
80 : Word16 scale /* i: scale Q13 , 10.0*log10(2) or 1.0*log10(2) */
81 : )
82 : {
83 : Word16 e_snr, f_snr;
84 : Word32 L_tmp;
85 :
86 1282890 : e_snr = norm_l( L_snr );
87 1282890 : f_snr = Log2_norm_lc( L_shl( L_snr, e_snr ) );
88 1282890 : e_snr = sub( 30 - 4, e_snr );
89 1282890 : L_tmp = Mpy_32_16( e_snr, f_snr, scale );
90 1282890 : return round_fx( L_shl( L_tmp, 10 ) ); /* Q8 */
91 : }
92 :
93 :
94 : /*-----------------------------------------------------------------*
95 : * wb_vad_init_fx()
96 : *
97 : *
98 : *-----------------------------------------------------------------*/
99 :
100 9717 : void wb_vad_init_fx(
101 : VAD_HANDLE hVAD /* i/o: VAD data handle */
102 : )
103 : {
104 9717 : hVAD->L_snr_sum_vad_fx = 0;
105 9717 : move32();
106 9717 : hVAD->q_L_snr_sum_vad = Q31;
107 9717 : move16();
108 9717 : hVAD->hangover_cnt = 0;
109 9717 : move16(); /* Hangover counter initialized to 0 */
110 9717 : hVAD->nb_active_frames = ACTIVE_FRAMES_FX;
111 9717 : move16(); /* The counter of SPEECH frames necessary to trigger HO */
112 : /* is set to max (-> start with hangover) */
113 :
114 9717 : hVAD->vad_flag_reg_H = L_deposit_l( 0 );
115 9717 : move32();
116 9717 : hVAD->vad_flag_reg_L = L_deposit_l( 0 );
117 9717 : move32();
118 9717 : hVAD->vad_prim_reg = L_deposit_l( 0 );
119 9717 : move32();
120 9717 : hVAD->vad_flag_cnt_50 = 0;
121 9717 : move16();
122 9717 : hVAD->vad_prim_cnt_16 = 0;
123 9717 : move16();
124 :
125 9717 : hVAD->hangover_cnt_dtx = HANGOVER_LONG_FX;
126 9717 : move16(); /* hangover for DTX */
127 9717 : hVAD->hangover_cnt_music = HANGOVER_LONG_MUSIC_FX;
128 9717 : move16(); /* hangover for MUSIC DTX */
129 :
130 9717 : hVAD->hangover_cnt_he = 0;
131 9717 : move16(); /* Hangover counter initialized to 0 */
132 9717 : hVAD->nb_active_frames_he = ACTIVE_FRAMES_FX;
133 9717 : move16(); /* The counter of SPEECH frames necessary to trigger HO */
134 9717 : hVAD->bcg_flux_fx = 1120;
135 9717 : move16(); /*70 in Q4 */
136 9717 : hVAD->soft_hangover = 0;
137 9717 : move16();
138 9717 : hVAD->voiced_burst = 0;
139 9717 : move16();
140 9717 : hVAD->bcg_flux_init = 50;
141 9717 : move16();
142 9717 : hVAD->nb_active_frames_he1 = ACTIVE_FRAMES_FX;
143 9717 : move16();
144 9717 : hVAD->hangover_cnt_he1 = 0;
145 9717 : move16();
146 :
147 9717 : hVAD->prim_act_quick_fx = 0;
148 9717 : move16();
149 9717 : hVAD->prim_act_slow_fx = 0;
150 9717 : move16();
151 9717 : hVAD->prim_act_fx = 0;
152 9717 : move16();
153 9717 : hVAD->prim_act_quick_he_fx = 0;
154 9717 : move16();
155 9717 : hVAD->prim_act_slow_he_fx = 0;
156 9717 : move16();
157 9717 : hVAD->prim_act_he_fx = 0;
158 9717 : move16();
159 9717 : hVAD->consec_inactive = 0;
160 9717 : move16();
161 9717 : hVAD->spectral_tilt_reset = 1;
162 9717 : move16();
163 9717 : hVAD->running_avg_fx = 0;
164 9717 : move16();
165 9717 : hVAD->ra_deltasum_fx = 0;
166 9717 : move16();
167 9717 : hVAD->trigger_SID = 0;
168 9717 : move16();
169 9717 : hVAD->hangover_terminate_flag = 0;
170 9717 : move16();
171 9717 : return;
172 : }
173 :
174 : /*-----------------------------------------------------------------*
175 : * sign_thr_snr_acc_fx()
176 : *
177 : * accumulate snr_sum with significance thresholds
178 : *-----------------------------------------------------------------*/
179 48553488 : static void sign_thr_snr_acc_ivas_fx(
180 : Word32 *L_snr_sum, /* o: q_snr_sum */
181 : Word16 *q_snr_sum,
182 : Word32 L_snr, /* i: q_snr */
183 : Word16 q_snr,
184 : Word32 sign_thr, /* i: q_snr */
185 : Word32 min_snr /* i: q_snr */
186 : )
187 : {
188 : /*if( snr >= sign_thr ) */
189 : Word32 L_tmp;
190 48553488 : Word16 exp_snr_sum = sub( 31, *q_snr_sum );
191 48553488 : L_tmp = min_snr;
192 48553488 : move32();
193 48553488 : IF( GE_32( L_snr, sign_thr ) )
194 : {
195 39060118 : L_tmp = L_add( L_snr, 0 ); /* q_snr */
196 : }
197 48553488 : *L_snr_sum = BASOP_Util_Add_Mant32Exp( *L_snr_sum, exp_snr_sum, L_tmp, sub( 31, q_snr ), &exp_snr_sum ); /* q_snr */
198 48553488 : *q_snr_sum = sub( 31, exp_snr_sum );
199 48553488 : move32();
200 48553488 : move32();
201 48553488 : }
202 124000 : static void sign_thr_snr_acc_fx(
203 : Word32 *L_snr_sum, /* o: Q4 */
204 : Word32 L_snr, /* i: Q4 */
205 : Word16 sign_thr, /* i: Q4 */
206 : Word16 min_snr /* i: Q4 */
207 : )
208 : {
209 : /*if( snr >= sign_thr ) */
210 : Word32 L_tmp;
211 : #ifndef ISSUE_1867_replace_overflow_libenc
212 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
213 : Flag Overflow = 0;
214 : move32();
215 : #endif
216 : #endif
217 :
218 124000 : L_tmp = L_deposit_l( min_snr );
219 124000 : IF( GE_32( L_snr, L_deposit_l( sign_thr ) ) )
220 : {
221 121433 : L_tmp = L_add( L_snr, 0 ); /* Q4 */
222 : }
223 : BASOP_SATURATE_WARNING_OFF_EVS /* may saturate in BASOP */
224 : #ifdef ISSUE_1867_replace_overflow_libenc
225 124000 : *L_snr_sum = L_add_sat( *L_snr_sum, L_tmp );
226 : /* Q4 */
227 : #else
228 : *L_snr_sum = L_add_o( *L_snr_sum, L_tmp, &Overflow ); /* Q4 */
229 : #endif
230 124000 : move32();
231 : BASOP_SATURATE_WARNING_ON_EVS
232 124000 : }
233 :
234 : /*-----------------------------------------------------------------*
235 : * dtx_hangover_addition_fx()
236 : *
237 : *-----------------------------------------------------------------*/
238 :
239 3100 : Word16 dtx_hangover_addition_fx(
240 : Encoder_State *st_fx, /* i/o: encoder state structure */
241 : const Word16 vad_flag, /* i Q0 */
242 : const Word16 lp_snr, /* i Q8 */
243 : const Word16 cldfb_subtraction, /* i Q0 number of DTX-HO frames CLDFB wants to reduce */
244 : Word16 *vad_hover_flag_ptr,
245 : VAD_HANDLE hVAD, /* i/o: VAD data handle */
246 : NOISE_EST_HANDLE hNoiseEst /* i : Noise estimation handle */
247 : )
248 : {
249 : Word16 hangover_short_dtx; /* Q0 */
250 : Word16 flag_dtx; /* Q0 */
251 : Word16 tmp; /* Q0 */
252 3100 : if ( hNoiseEst == NULL )
253 : {
254 0 : hNoiseEst = st_fx->hNoiseEst;
255 0 : move16();
256 : }
257 :
258 3100 : if ( hVAD == NULL )
259 : {
260 0 : move16();
261 0 : hVAD = st_fx->hVAD;
262 : }
263 :
264 :
265 3100 : flag_dtx = 0;
266 3100 : move16();
267 :
268 : /* Determine initial hangover length */
269 3100 : hangover_short_dtx = 2;
270 3100 : move16();
271 :
272 3100 : test();
273 3100 : test();
274 3100 : if ( ( ( LT_16( lp_snr, ( 16 * 256 ) ) ) && ( st_fx->input_bwidth != NB ) ) || ( GT_16( hVAD->prim_act_he_fx, 31130 ) ) ) /*.95*Q15*/
275 : {
276 1785 : hangover_short_dtx = 3;
277 1785 : move16();
278 : }
279 :
280 : /* Adjust hangover according to activity history */
281 3100 : IF( GT_16( hVAD->vad_prim_cnt_16, 12 ) ) /* 12 requires roughly > 80% primary activity */
282 : {
283 2911 : hangover_short_dtx = add( hangover_short_dtx, 2 );
284 : }
285 :
286 3100 : IF( GT_16( hVAD->vad_flag_cnt_50, 40 ) ) /* 40 requires roughtly > 80% flag activity */
287 : {
288 2918 : hangover_short_dtx = add( hangover_short_dtx, 5 );
289 : }
290 :
291 : /* Keep hangover_short lower than maximum hangover count */
292 3100 : if ( GT_16( hangover_short_dtx, HANGOVER_LONG_FX - 1 ) )
293 : {
294 1785 : hangover_short_dtx = ( HANGOVER_LONG_FX - 1 );
295 1785 : move16();
296 : }
297 :
298 : /* Only allow short HO if not sufficient active frames in clean speech*/
299 :
300 3100 : tmp = 3;
301 3100 : move16(); /* default for EVS*/
302 3100 : if ( EQ_16( st_fx->core, AMR_WB_CORE ) )
303 : {
304 0 : tmp = 2;
305 0 : move16(); /* default for AMRWBIO*/
306 : }
307 :
308 : /* need to be a bit stricter with the DTXHO in very clean WB, SWB cond for EVS12k8VAD section */
309 3100 : test();
310 3100 : test();
311 3100 : if ( ( NE_16( st_fx->input_bwidth, NB ) ) /* WB or SWB or FB */
312 3100 : && ( NE_16( st_fx->core, AMR_WB_CORE ) ) && ( GT_16( lp_snr, 25 * 256 ) ) )
313 : {
314 3100 : tmp = 2;
315 3100 : move16();
316 : }
317 :
318 : /* limit dtx hangover addition up to "tmp" frames in clean cond */
319 3100 : IF( tmp != 0 )
320 : {
321 3100 : test();
322 3100 : test();
323 3100 : test();
324 3100 : if ( ( GT_16( hangover_short_dtx, tmp ) ) && ( ( LT_16( hVAD->vad_prim_cnt_16, 7 ) ) || ( ( GT_16( lp_snr, ( 16 * 256 ) ) ) && ( LT_16( hVAD->prim_act_he_fx, 27853 ) ) /*0.85f*2^15 */
325 : ) ) )
326 : {
327 680 : hangover_short_dtx = tmp;
328 680 : move16();
329 : }
330 : }
331 :
332 :
333 : /* hangover adjustment from combined FFT+CLDFBVAD */
334 3100 : IF( NE_16( st_fx->core, AMR_WB_CORE ) )
335 : {
336 3100 : hangover_short_dtx = sub( hangover_short_dtx, cldfb_subtraction ); /* Q0 */
337 3100 : hangover_short_dtx = s_max( hangover_short_dtx, 0 );
338 : }
339 :
340 3100 : IF( vad_flag != 0 ) /* Speech present */
341 : {
342 3081 : flag_dtx = 1;
343 3081 : move16();
344 :
345 : /* Add hangover after sufficient # of active frames or sufficient activity during last second */
346 3081 : test();
347 3081 : if ( ( GE_16( hVAD->nb_active_frames, ACTIVE_FRAMES_FX ) ) || ( GT_16( hVAD->vad_flag_cnt_50, 45 ) ) ) /* 45 requires roughly > 90% flag activity */
348 : {
349 3007 : hVAD->hangover_cnt_dtx = 0;
350 3007 : move16();
351 : }
352 :
353 : /* inside HO period */
354 3081 : test();
355 3081 : IF( ( LT_16( hVAD->hangover_cnt_dtx, HANGOVER_LONG_FX ) ) && ( hVAD->hangover_cnt_dtx != 0 ) )
356 : {
357 4 : hVAD->hangover_cnt_dtx = add( hVAD->hangover_cnt_dtx, 1 ); /* Q0 */
358 4 : move16();
359 : }
360 3081 : hVAD->hangover_terminate_flag = 0;
361 3081 : move16(); /* float fix FIX_HO_TERMINATE */
362 :
363 : /* Music hangover when music detected */
364 3081 : test();
365 3081 : test();
366 3081 : test();
367 3081 : if ( ( GT_16( hVAD->prim_act_he_fx, 31129 ) ) && ( GT_16( hNoiseEst->Etot_lp_fx, 40 * 256 ) ) && ( GT_16( hVAD->vad_prim_cnt_16, 14 ) ) && ( GT_16( hVAD->vad_flag_cnt_50, 48 ) ) ) /* 45 requires roughly > 95% flag activity */
368 : {
369 1211 : hVAD->hangover_cnt_music = 0;
370 1211 : move16();
371 : }
372 :
373 : /* inside Music HO period */
374 3081 : test();
375 3081 : IF( ( LT_16( hVAD->hangover_cnt_music, HANGOVER_LONG_MUSIC_FX ) ) && ( hVAD->hangover_cnt_music != 0 ) )
376 : {
377 64 : hVAD->hangover_cnt_music = add( hVAD->hangover_cnt_music, 1 );
378 64 : move16();
379 : }
380 : }
381 : ELSE
382 : {
383 : /* Reset the counter of speech frames necessary to start hangover algorithm */
384 19 : IF( LT_16( hVAD->hangover_cnt_dtx, HANGOVER_LONG_FX ) ) /* inside HO period */
385 : {
386 19 : hVAD->hangover_cnt_dtx = add( hVAD->hangover_cnt_dtx, 1 );
387 19 : move16();
388 : }
389 19 : IF( LT_16( hVAD->hangover_cnt_music, HANGOVER_LONG_MUSIC_FX ) ) /* inside HO period */
390 : {
391 16 : hVAD->hangover_cnt_music = add( hVAD->hangover_cnt_music, 1 );
392 16 : move16();
393 : }
394 :
395 : /* fast terminate DTX hangover if st->hangover_terminate_flag is set */
396 19 : IF( hVAD->hangover_terminate_flag != 0 )
397 : {
398 0 : hVAD->hangover_cnt = HANGOVER_LONG_FX;
399 0 : move16();
400 0 : hVAD->hangover_cnt_dtx = HANGOVER_LONG_FX;
401 0 : move16();
402 0 : hVAD->hangover_terminate_flag = 0;
403 0 : move16();
404 : /* Only shorten music hangover when low energy frames */
405 0 : if ( LT_16( hNoiseEst->Etot_lp_fx, 20 * 256 ) )
406 : {
407 0 : hVAD->hangover_cnt_music = HANGOVER_LONG_MUSIC_FX;
408 0 : move16();
409 : }
410 : }
411 :
412 19 : if ( LE_16( hVAD->hangover_cnt_dtx, hangover_short_dtx ) ) /* "hard" hangover */
413 : {
414 4 : flag_dtx = 1;
415 4 : move16();
416 : }
417 :
418 19 : if ( LE_16( hVAD->hangover_cnt_music, 15 ) ) /* "hard" hangover music */
419 : {
420 16 : flag_dtx = 1;
421 16 : move16();
422 : }
423 : }
424 :
425 :
426 3100 : test();
427 3100 : if ( flag_dtx != 0 && st_fx->localVAD == 0 )
428 : {
429 107 : *vad_hover_flag_ptr = 1;
430 107 : move16();
431 : }
432 :
433 3100 : return flag_dtx;
434 : }
435 1182722 : Word16 ivas_dtx_hangover_addition_fx(
436 : Encoder_State *st_fx, /* i/o: encoder state structure */
437 : const Word16 vad_flag, /* i Q0 */
438 : const Word16 lp_snr, /* i Q8 */
439 : const Word16 cldfb_subtraction, /* i Q0 number of DTX-HO frames CLDFB wants to reduce */
440 : Word16 *vad_hover_flag_ptr,
441 : VAD_HANDLE hVAD, /* i/o: VAD data handle */
442 : NOISE_EST_HANDLE hNoiseEst, /* i : Noise estimation handle */
443 : Word16 *rem_dtx_ho )
444 : {
445 : Word16 hangover_short_dtx; /* Q0 */
446 : Word16 flag_dtx; /* Q0 */
447 : Word16 tmp; /* Q0 */
448 1182722 : if ( hNoiseEst == NULL )
449 : {
450 1100996 : hNoiseEst = st_fx->hNoiseEst;
451 1100996 : move16();
452 : }
453 :
454 1182722 : if ( hVAD == NULL )
455 : {
456 1100996 : move16();
457 1100996 : hVAD = st_fx->hVAD;
458 : }
459 :
460 :
461 1182722 : flag_dtx = 0;
462 1182722 : move16();
463 :
464 : /* Determine initial hangover length */
465 1182722 : hangover_short_dtx = 2;
466 1182722 : move16();
467 :
468 1182722 : test();
469 1182722 : test();
470 1182722 : if ( ( ( LT_16( lp_snr, ( 16 * 256 ) ) ) && ( NE_16( st_fx->input_bwidth, NB ) ) ) || ( GT_16( hVAD->prim_act_he_fx, 31130 ) ) ) /*.95*Q15*/
471 : {
472 470220 : hangover_short_dtx = 3;
473 470220 : move16();
474 : }
475 :
476 : /* Adjust hangover according to activity history */
477 1182722 : IF( GT_16( hVAD->vad_prim_cnt_16, 12 ) ) /* 12 requires roughly > 80% primary activity */
478 : {
479 900906 : hangover_short_dtx = add( hangover_short_dtx, 2 );
480 : }
481 :
482 1182722 : IF( GT_16( hVAD->vad_flag_cnt_50, 40 ) ) /* 40 requires roughtly > 80% flag activity */
483 : {
484 837966 : hangover_short_dtx = add( hangover_short_dtx, 5 );
485 : }
486 :
487 : /* Keep hangover_short lower than maximum hangover count */
488 1182722 : if ( GT_16( hangover_short_dtx, HANGOVER_LONG_FX - 1 ) )
489 : {
490 417428 : hangover_short_dtx = ( HANGOVER_LONG_FX - 1 );
491 417428 : move16();
492 : }
493 :
494 : /* Only allow short HO if not sufficient active frames in clean speech*/
495 :
496 1182722 : tmp = 3;
497 1182722 : move16(); /* default for EVS*/
498 1182722 : if ( EQ_16( st_fx->core, AMR_WB_CORE ) )
499 : {
500 0 : tmp = 2;
501 0 : move16(); /* default for AMRWBIO*/
502 : }
503 :
504 : /* need to be a bit stricter with the DTXHO in very clean WB, SWB cond for EVS12k8VAD section */
505 1182722 : test();
506 1182722 : test();
507 1182722 : if ( ( st_fx->input_bwidth != NB ) /* WB or SWB or FB */
508 1178458 : && ( NE_16( st_fx->core, AMR_WB_CORE ) ) && ( GT_16( lp_snr, 25 * 256 ) ) )
509 : {
510 1046907 : tmp = 2;
511 1046907 : move16();
512 : }
513 :
514 : /* limit dtx hangover addition up to "tmp" frames in clean cond */
515 1182722 : IF( tmp != 0 )
516 : {
517 1182722 : test();
518 1182722 : test();
519 1182722 : test();
520 1182722 : if ( ( GT_16( hangover_short_dtx, tmp ) ) && ( ( LT_16( hVAD->vad_prim_cnt_16, 7 ) ) || ( ( GT_16( lp_snr, ( 16 * 256 ) ) ) && ( LT_16( hVAD->prim_act_he_fx, 27853 ) ) /*0.85f*2^15 */
521 : ) ) )
522 : {
523 365257 : hangover_short_dtx = tmp;
524 365257 : move16();
525 : }
526 : }
527 :
528 :
529 : /* hangover adjustment from combined FFT+CLDFBVAD */
530 1182722 : IF( NE_16( st_fx->core, AMR_WB_CORE ) )
531 : {
532 1182722 : hangover_short_dtx = sub( hangover_short_dtx, cldfb_subtraction ); /*Q0*/
533 1182722 : hangover_short_dtx = s_max( hangover_short_dtx, 0 );
534 : }
535 1182722 : IF( vad_flag != 0 ) /* Speech present */
536 : {
537 1023240 : flag_dtx = 1;
538 1023240 : move16();
539 :
540 : /* Add hangover after sufficient # of active frames or sufficient activity during last second */
541 1023240 : test();
542 1023240 : if ( ( GE_16( hVAD->nb_active_frames, ACTIVE_FRAMES_FX ) ) || ( GT_16( hVAD->vad_flag_cnt_50, 45 ) ) ) /* 45 requires roughly > 90% flag activity */
543 : {
544 1000621 : hVAD->hangover_cnt_dtx = 0;
545 1000621 : move16();
546 : }
547 :
548 : /* inside HO period */
549 1023240 : test();
550 1023240 : IF( ( LT_16( hVAD->hangover_cnt_dtx, HANGOVER_LONG_FX ) ) && ( hVAD->hangover_cnt_dtx != 0 ) )
551 : {
552 3549 : hVAD->hangover_cnt_dtx = add( hVAD->hangover_cnt_dtx, 1 ); /*Q0*/
553 3549 : move16();
554 : }
555 1023240 : hVAD->hangover_terminate_flag = 0;
556 1023240 : move16(); /* float fix FIX_HO_TERMINATE */
557 :
558 : /* Music hangover when music detected */
559 1023240 : test();
560 1023240 : test();
561 1023240 : test();
562 1023240 : if ( ( GT_16( hVAD->prim_act_he_fx, 32113 ) ) && ( GT_16( hNoiseEst->Etot_lp_fx, 40 * 256 ) ) && ( GT_16( hVAD->vad_prim_cnt_16, 14 ) ) && ( GT_16( hVAD->vad_flag_cnt_50, 48 ) ) ) /* 45 requires roughly > 95% flag activity */
563 : {
564 174268 : hVAD->hangover_cnt_music = 0;
565 174268 : move16();
566 : }
567 :
568 : /* inside Music HO period */
569 1023240 : test();
570 1023240 : IF( ( LT_16( hVAD->hangover_cnt_music, HANGOVER_LONG_MUSIC_FX ) ) && ( hVAD->hangover_cnt_music != 0 ) )
571 : {
572 6605 : hVAD->hangover_cnt_music = add( hVAD->hangover_cnt_music, 1 );
573 6605 : move16();
574 : }
575 : }
576 : ELSE
577 : {
578 : /* Reset the counter of speech frames necessary to start hangover algorithm */
579 159482 : IF( LT_16( hVAD->hangover_cnt_dtx, HANGOVER_LONG_FX ) ) /* inside HO period */
580 : {
581 19406 : hVAD->hangover_cnt_dtx = add( hVAD->hangover_cnt_dtx, 1 );
582 19406 : move16();
583 : }
584 159482 : IF( LT_16( hVAD->hangover_cnt_music, HANGOVER_LONG_MUSIC_FX ) ) /* inside HO period */
585 : {
586 5095 : hVAD->hangover_cnt_music = add( hVAD->hangover_cnt_music, 1 );
587 5095 : move16();
588 : }
589 :
590 : /* fast terminate DTX hangover if st->hangover_terminate_flag is set */
591 159482 : IF( hVAD->hangover_terminate_flag != 0 )
592 : {
593 1 : hVAD->hangover_cnt = HANGOVER_LONG_FX;
594 1 : move16();
595 1 : hVAD->hangover_cnt_dtx = HANGOVER_LONG_FX;
596 1 : move16();
597 1 : hVAD->hangover_terminate_flag = 0;
598 1 : move16();
599 : /* Only shorten music hangover when low energy frames */
600 1 : if ( LT_16( hNoiseEst->Etot_lp_fx, 20 * 256 ) )
601 : {
602 0 : hVAD->hangover_cnt_music = HANGOVER_LONG_MUSIC_FX;
603 0 : move16();
604 : }
605 : }
606 :
607 159482 : if ( LE_16( hVAD->hangover_cnt_dtx, hangover_short_dtx ) ) /* "hard" hangover */
608 : {
609 7423 : flag_dtx = 1;
610 7423 : move16();
611 : }
612 :
613 159482 : if ( LE_16( hVAD->hangover_cnt_music, 15 ) ) /* "hard" hangover music */
614 : {
615 4819 : flag_dtx = 1;
616 4819 : move16();
617 : }
618 : }
619 :
620 :
621 1182722 : test();
622 :
623 1182722 : IF( flag_dtx != 0 && st_fx->localVAD == 0 )
624 : {
625 26998 : *vad_hover_flag_ptr = 1;
626 26998 : move16();
627 26998 : if ( rem_dtx_ho != NULL )
628 : {
629 4519 : *rem_dtx_ho = s_max( sub( hangover_short_dtx, hVAD->hangover_cnt_dtx ), 0 );
630 4519 : move16();
631 : }
632 : }
633 :
634 1182722 : return flag_dtx;
635 : }
636 : /*-----------------------------------------------------------------*
637 : * wb_vad()
638 : *
639 : * Voice Activity Detector
640 : *-----------------------------------------------------------------*/
641 : /* new simplified and harmonized code */
642 3100 : Word16 wb_vad_fx(
643 : Encoder_State *st_fx, /* i/o: encoder state structure */
644 : const Word32 fr_bands[], /* i : per band input energy (contains 2 vectors) Q_new+QSCALE*/
645 : Word16 *noisy_speech_HO, /* o : SC-VBR noisy speech HO flag */
646 : Word16 *clean_speech_HO, /* o : SC-VBR clean speech HO flag */
647 : Word16 *NB_speech_HO, /* o : SC-VBR NB speech HO flag */
648 : Word16 *snr_sum_he, /* o : Output snr_sum as weighted spectral measure*/
649 : Word16 *localVAD_HE_SAD,
650 : Word16 *flag_noisy_speech_snr, /* o : */
651 : const Word16 Q_new, /* i : scaling factor Q0 */
652 : VAD_HANDLE hVAD, /* i/o: VAD data handle */
653 : NOISE_EST_HANDLE hNoiseEst, /* i : Noise estimation handle */
654 : Word16 lp_speech_fx, /* i : long term active speech energy average Q8 */
655 : Word16 lp_noise_fx /* i : long term noise energy Q8 */
656 : )
657 : {
658 3100 : Word16 i, flag = 0, hangover_short;
659 :
660 3100 : Word16 snr_sum, thr1 = 0, thr1_nb_mod, thr2 = 0, nk = 0, nc = 0, th_clean = 0;
661 : Word16 lp_snr; /* Q8 */
662 : const Word32 *pt1;
663 : const Word32 *pt2;
664 : const Word32 *pt3;
665 :
666 : Word16 min_snr, sign_thr;
667 :
668 : Word32 L_snr, L_snr_sum;
669 : Word32 ftmp, ftmp1, ftmp2;
670 : Word16 m_noise_local, e_noise, e_num, m_num, snr, snr_tmp, shift_snr;
671 :
672 : Word16 snr_sumt;
673 : Word32 L_vad_thr;
674 : Word16 hangover_hd;
675 : Word16 snr_idx;
676 : Word16 delta1, delta2, delta3, delta4;
677 :
678 : Word16 flag_he1;
679 : Word16 stmp;
680 3100 : Word32 L_msnr, L_mssnr = 0, L_mssnr_hov;
681 : Word16 j, tmp, tmp1, tmp2;
682 : Word32 L_tmp, L_tmp1, L_tmp2;
683 :
684 : Word32 L_snr18, L_snr19; /* Q4 */
685 : Word32 L_msnr18, L_msnr19; /* Q13 */
686 : Word16 nb_sig_snr; /* Q0 */
687 :
688 : Word16 nv;
689 : Word16 nv_ofs; /* Q8 */
690 : Word32 L_snr_sum_HE_SAD; /* Q4 */
691 : Word16 snr_sum_HE_SAD; /*Q8 log */
692 : Word16 sign_thr_HE_SAD, min_snr_HE_SAD;
693 :
694 :
695 : Word16 thr1_ol;
696 : Word32 L_snr_sum_ol;
697 : Word16 snr_sum_ol; /* Q8 log */
698 :
699 : Word32 L_snr_outlier;
700 : Word16 snr_outlier_index;
701 : Word32 L_accum_ener_L;
702 : Word32 L_accum_ener_H;
703 : Word16 vad_bwidth_fx;
704 : Word16 last_7k2_coder_type;
705 : #if !defined( ISSUE_1867_replace_overflow_libenc )
706 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
707 : Flag Overflow = 0;
708 : move32();
709 : #endif
710 : #endif
711 :
712 3100 : if ( hNoiseEst == NULL )
713 : {
714 0 : hNoiseEst = st_fx->hNoiseEst;
715 0 : move16();
716 : }
717 :
718 3100 : if ( hVAD == NULL )
719 : {
720 0 : move16();
721 0 : hVAD = st_fx->hVAD;
722 : }
723 3100 : if ( LT_16( lp_speech_fx, -100 * 256 ) )
724 : {
725 0 : lp_speech_fx = st_fx->lp_speech_fx;
726 0 : move16();
727 : }
728 :
729 3100 : if ( LT_16( lp_noise_fx, -100 * 256 ) )
730 : {
731 0 : lp_noise_fx = st_fx->lp_noise_fx;
732 0 : move16();
733 : }
734 :
735 3100 : vad_bwidth_fx = st_fx->input_bwidth;
736 3100 : move16();
737 :
738 3100 : L_snr_outlier = L_deposit_l( 0 );
739 3100 : snr_outlier_index = 0;
740 3100 : move16();
741 3100 : L_accum_ener_L = L_deposit_l( 0 );
742 3100 : L_accum_ener_H = L_deposit_l( 0 );
743 3100 : L_snr18 = L_deposit_l( 0 ); /* Q4*/
744 3100 : L_snr19 = L_deposit_l( 0 ); /* Q4 */
745 3100 : L_msnr18 = L_deposit_l( 8192 ); /* 1.0 Q13*/
746 3100 : L_msnr19 = L_deposit_l( 8192 ); /* 1.0 Q13 */
747 :
748 3100 : IF( vad_bwidth_fx == NB )
749 : {
750 0 : st_fx->min_band = 1;
751 0 : move16();
752 0 : st_fx->max_band = 16;
753 0 : move16();
754 : }
755 : ELSE
756 : {
757 3100 : st_fx->min_band = 0;
758 3100 : move16();
759 3100 : st_fx->max_band = 19;
760 3100 : move16();
761 : }
762 : /*_DIFF_FLOAT_FIX_ -> see around Ln1570, inversion in if conditions compared to float*/
763 : // PMT("Error in EVS fixed point ?")
764 : /*FIXED EVS */
765 : /* ELSE IF(((LE_16(st_fx->last_coder_type, UNVOICED)) && (LT_32(L_snr_outlier, MAX_SNR_OUTLIER_2_FX)) && (st_fx->Opt_SC_VBR != 0)) ||
766 : ((LE_16(last_7k2_coder_type, UNVOICED)) && (LT_32(L_snr_outlier, MAX_SNR_OUTLIER_2_FX)) && (st_fx->Opt_SC_VBR == 0)))*/
767 :
768 : /*FLOAT both IVAS and EVS */
769 : /*if ((snr_outlier_index <= 4 && (st->last_coder_type > UNVOICED) && !st->Opt_SC_VBR) ||
770 : (snr_outlier_index <= 4 && (last_7k2_coder_type > UNVOICED) && st->Opt_SC_VBR))*/
771 : IF( 1 ) // st_fx->Opt_SC_VBR)
772 : {
773 3100 : last_7k2_coder_type = st_fx->hSC_VBR->last_7k2_coder_type;
774 3100 : move16();
775 : }
776 : ELSE
777 : {
778 : last_7k2_coder_type = -1;
779 : move16();
780 : }
781 : /*---------------------------------------------------------------------*
782 : * set SNR thresholds depending on the input bandwitdh
783 : *---------------------------------------------------------------------*/
784 3100 : IF( EQ_16( st_fx->max_band, 19 ) )
785 : /* WB input */ /* or SWB input */
786 : {
787 3100 : nk = 3277;
788 3100 : move16(); /*0.1 Q15 */
789 3100 : nc = 4122;
790 3100 : move16(); /*16.1 Q8 */
791 3100 : nv = 525;
792 3100 : move16(); /* 2.05 Q8*/
793 3100 : nv_ofs = 422;
794 3100 : move16(); /* 1.65 Q8*/
795 3100 : th_clean = TH16_2_FX;
796 3100 : move16(); /* 35 Q8 */
797 3100 : sign_thr = 21;
798 3100 : move16(); /*1.3 Q4 */
799 3100 : tmp = sub( vad_bwidth_fx, WB );
800 3100 : if ( tmp != 0 )
801 : {
802 3100 : sign_thr = 28;
803 3100 : move16(); /*1.75f; Q4 SWB */
804 : }
805 3100 : min_snr = 13;
806 3100 : move16(); /*0.8 Q4 WB */
807 3100 : if ( tmp != 0 )
808 : {
809 3100 : min_snr = 4;
810 3100 : move16(); /*0.25f; Q4 SWB */
811 : }
812 :
813 3100 : sign_thr_HE_SAD = 40;
814 3100 : move16(); /* 2.5f Q4 */
815 : ;
816 3100 : min_snr_HE_SAD = 3;
817 3100 : move16(); /* 0.2f Q4 */
818 : ;
819 : }
820 : ELSE /* NB input */
821 : {
822 0 : move16();
823 0 : nk = 3277;
824 0 : move16(); /* 0.1 Q15 */
825 0 : nc = 4096;
826 0 : move16(); /* 16.0 Q8 */
827 0 : nv = 1024;
828 0 : move16(); /* 4.0 Q8 */
829 0 : nv_ofs = 294;
830 0 : move16(); /*1.15 Q8*/
831 0 : th_clean = TH8_1_FX;
832 0 : move16(); /*20 Q8 */
833 0 : sign_thr = 28;
834 0 : move16(); /* 1.75 * Q4 SIGN_THR */
835 0 : min_snr = 4;
836 0 : move16(); /* .25 *Q4 MIN_SNR */
837 0 : sign_thr_HE_SAD = 42;
838 0 : move16(); /* 2.65f Q4 */
839 : ;
840 0 : min_snr_HE_SAD = 1;
841 0 : move16(); /* 0.05f Q4 */
842 : ;
843 : }
844 :
845 3100 : hangover_short = 0;
846 3100 : move16();
847 :
848 : /* IF( st_fx->Opt_SC_VBR != 0 ) */
849 3100 : *noisy_speech_HO = 0;
850 3100 : move16();
851 3100 : *clean_speech_HO = 0;
852 3100 : move16();
853 3100 : *NB_speech_HO = 0;
854 3100 : move16();
855 : /* } */
856 :
857 : /*---------------------------------------------------------------------*
858 : * compute SNR for each band & total
859 : *---------------------------------------------------------------------*/
860 :
861 3100 : lp_snr = sub( lp_speech_fx, lp_noise_fx ); /*Q8 */
862 :
863 3100 : snr_idx = 2;
864 3100 : move16();
865 3100 : if ( GT_16( lp_snr, 4608 ) ) /*18.0 Q8*/
866 : {
867 3100 : snr_idx = 1;
868 3100 : move16();
869 : }
870 3100 : if ( GT_16( lp_snr, 6144 ) ) /*24.0 Q8*/
871 : {
872 3100 : snr_idx = 0;
873 3100 : move16();
874 : }
875 :
876 :
877 3100 : IF( snr_idx == 0 )
878 : {
879 3100 : stmp = 6;
880 3100 : move16();
881 3100 : delta1 = 0;
882 3100 : move16(); /*0.0f in Q13 */
883 3100 : delta2 = 0;
884 3100 : move16(); /*0.0f in Q13 */
885 3100 : delta3 = 0;
886 3100 : move16(); /*0.0f in Q13 */
887 3100 : delta4 = 0;
888 3100 : move16();
889 :
890 :
891 : /*vad_thr = 2.4f*lp_snr - 42.2f;
892 : vad_thr = min(vad_thr, 80 ); */
893 :
894 3100 : L_vad_thr = -345702;
895 3100 : move32(); /* -42.2 Q13*/
896 3100 : L_vad_thr = L_mac0( L_vad_thr, 77, lp_snr ); /* (2.4)Q5*(lp_snr)Q8 */
897 3100 : L_vad_thr = L_min( L_vad_thr, 80 * ( 1 << 13 ) );
898 : }
899 0 : ELSE IF( EQ_16( snr_idx, 1 ) )
900 : {
901 0 : stmp = 6;
902 0 : move16();
903 0 : delta1 = 819;
904 0 : move16(); /*0.1f in Q13 */
905 0 : delta2 = 1638;
906 0 : move16(); /*0.2f in Q13 */
907 0 : delta3 = 1638;
908 0 : move16(); /*0.2f in Q13 */
909 0 : delta4 = 1638;
910 0 : move16(); /*0.2f in Q13 */
911 :
912 : /* vad_thr = 2.4f*lp_snr - 40.2f;
913 : vad_thr = min(vad_thr, 80);
914 : */
915 0 : L_vad_thr = -329318;
916 0 : move32(); /* -40.2 Q13*/
917 0 : L_vad_thr = L_mac0( L_vad_thr, 77, lp_snr ); /* (2.4)Q5*(lp_snr)Q8 */
918 0 : L_vad_thr = L_min( L_vad_thr, 80 * ( 1 << 13 ) );
919 : }
920 : ELSE
921 : {
922 0 : stmp = 9;
923 0 : move16();
924 0 : delta1 = 1638;
925 0 : move16(); /*0.2f in Q13 */
926 0 : delta2 = 3277;
927 0 : move16(); /*0.4f in Q13 */
928 0 : delta3 = 2458;
929 0 : move16(); /*0.3f in Q13 */
930 0 : delta4 = 3277;
931 0 : move16(); /*0.4f in Q13 */
932 : /* vad_thr = 2.5f*lp_snr - 10.0f;
933 : vad_thr = max(vad_thr, 1);
934 : */
935 0 : L_vad_thr = -81920;
936 0 : move32(); /* -10 Q13*/
937 0 : L_vad_thr = L_mac0( L_vad_thr, 80, lp_snr ); /* (2.5)Q5*(lp_snr)Q8 */
938 0 : L_vad_thr = L_max( L_vad_thr, 1 * ( 1 << 13 ) );
939 : }
940 :
941 3100 : nb_sig_snr = 20;
942 3100 : move16();
943 :
944 3100 : pt1 = fr_bands;
945 3100 : pt2 = fr_bands + NB_BANDS;
946 3100 : pt3 = hNoiseEst->bckr_fx;
947 :
948 3100 : L_snr_sum = L_deposit_l( 0 );
949 3100 : L_snr_sum_HE_SAD = L_deposit_l( 0 );
950 3100 : snr_sumt = 0;
951 3100 : move16();
952 3100 : L_mssnr_hov = L_deposit_l( 0 );
953 3100 : *snr_sum_he = 0;
954 3100 : move16();
955 3100 : snr_sum_HE_SAD = 0;
956 3100 : move16();
957 :
958 :
959 65100 : FOR( i = st_fx->min_band; i <= st_fx->max_band; i++ )
960 : {
961 62000 : ftmp = L_add( *pt1++, 0 );
962 62000 : ftmp1 = L_add( *pt2++, 0 );
963 62000 : ftmp2 = L_add( *pt3++, 0 );
964 :
965 : /*fr_enr = ( 0.2f * st->enrO[i] + 0.4f * ftmp + 0.4f * ftmp1 );*/
966 62000 : L_tmp = Mult_32_16( hNoiseEst->enrO_fx[i], 13107 ); /* L_tmp(high word) = Qenr0fx*Q16+1 -16 -> Qener0+1 */
967 62000 : L_tmp1 = Madd_32_16( L_tmp, ftmp, 26214 ); /* 26214 = .4 in Q16 */
968 62000 : L_tmp1 = Madd_32_16( L_tmp1, ftmp1, 26214 ); /* L_tmp1 re_used a bit later for final snr[i]*/
969 :
970 62000 : L_tmp2 = Madd_32_16( L_tmp, ftmp, 19661 ); /* 19661 = 0.3 in Q16 */
971 62000 : L_tmp2 = Msub_32_16( L_tmp2, ftmp1, -32768 ); /* -32768= -0.5 in Q16 */
972 :
973 62000 : IF( GT_32( ftmp, ftmp1 ) )
974 : {
975 : /*snr[i] = ( 0.2f * st->enrO[i] + 0.4f * ftmp + 0.4f * ftmp1 ) / ftmp2 ;*/
976 : /*snr[i] = L_tmp1/(ftmp2) */
977 33413 : IF( ftmp2 != 0 )
978 : {
979 33413 : e_num = norm_l( L_tmp1 );
980 33413 : m_num = extract_h( L_shl( L_tmp1, e_num ) );
981 33413 : e_noise = norm_l( ftmp2 );
982 33413 : m_noise_local = extract_h( L_shl( ftmp2, e_noise ) );
983 :
984 33413 : m_num = shr( m_num, 1 );
985 33413 : shift_snr = add( sub( e_num, e_noise ), 15 - 4 );
986 33413 : snr_tmp = div_s( m_num, m_noise_local );
987 33413 : L_snr = L_shr_sat( snr_tmp, shift_snr ); /* L_snr in Q4 */
988 : }
989 : ELSE
990 : {
991 0 : e_num = norm_l( L_tmp1 );
992 0 : m_num = extract_h( L_shl( L_tmp1, e_num ) );
993 :
994 : /* if bckr[i] == 0; approx. L_snr */
995 0 : e_noise = add( 30 + 1, abs_s( Q_new ) );
996 :
997 0 : m_num = shr( m_num, 1 );
998 0 : shift_snr = add( sub( e_num, e_noise ), 15 - 4 );
999 :
1000 0 : snr_tmp = div_s( m_num, 32767 );
1001 0 : L_snr = L_shr( snr_tmp, shift_snr ); /*L_snr in Q4*/
1002 : }
1003 : }
1004 : ELSE
1005 : {
1006 : /*snr[i] = ( 0.2f * st->enrO[i] + 0.3f * ftmp + 0.5f * ftmp1 ) / ftmp2 ;*/
1007 : /*snr[i] =L_tmp2/( ftmp2 ) */
1008 28587 : IF( ftmp2 != 0 )
1009 : {
1010 28587 : e_num = norm_l( L_tmp2 );
1011 28587 : m_num = extract_h( L_shl( L_tmp2, e_num ) );
1012 :
1013 28587 : e_noise = norm_l( ftmp2 );
1014 28587 : m_noise_local = extract_h( L_shl( ftmp2, e_noise ) );
1015 :
1016 28587 : m_num = shr( m_num, 1 );
1017 28587 : shift_snr = add( sub( e_num, e_noise ), 15 - 4 );
1018 :
1019 28587 : snr_tmp = div_s( m_num, m_noise_local );
1020 28587 : L_snr = L_shr_sat( snr_tmp, shift_snr ); /* L_snr in Q4 */
1021 : }
1022 : ELSE
1023 : {
1024 0 : e_num = norm_l( L_tmp2 );
1025 0 : m_num = extract_h( L_shl( L_tmp2, e_num ) );
1026 :
1027 : /* if bckr[i] == 0; approx. L_snr */
1028 0 : e_noise = add( 30 + 1, abs_s( Q_new ) );
1029 :
1030 0 : m_num = shr( m_num, 1 );
1031 0 : shift_snr = add( sub( e_num, e_noise ), 15 - 4 );
1032 :
1033 0 : snr_tmp = div_s( m_num, 32767 );
1034 0 : L_snr = L_shr( snr_tmp, shift_snr ); /*L_snr in Q4*/
1035 : }
1036 : }
1037 :
1038 62000 : if ( LT_32( L_snr, 2 * ( 1 << 4 ) ) )
1039 : {
1040 1178 : nb_sig_snr = sub( nb_sig_snr, 1 ); /* nb_sig_snr--; */
1041 : }
1042 62000 : L_snr = L_max( L_snr, 1 * ( 1 << 4 ) ); /* if ( snr[i] < 1 ){snr[i] = 1;}*/
1043 :
1044 :
1045 : /* snr[i] = (float)log10(snr[i]); */
1046 62000 : snr = vad_snr_log_fx( L_snr, ONE_LG10 );
1047 :
1048 : /* snr_sumt += snr[i];*/
1049 62000 : snr_sumt = add( snr_sumt, shr( snr, 4 ) ); /*Q4 */
1050 :
1051 :
1052 62000 : tmp = shl_sat( snr, 5 ); /* Q8 -> Q13 */
1053 62000 : IF( LT_16( i, 2 ) )
1054 : {
1055 : #ifdef ISSUE_1867_replace_overflow_libenc
1056 6200 : tmp = add_sat( tmp, delta1 ); /*Q13 */
1057 : #else
1058 : tmp = add_o( tmp, delta1, &Overflow ); /*Q13 */
1059 : #endif
1060 : }
1061 55800 : ELSE IF( LT_16( i, 7 ) )
1062 : {
1063 : #ifdef ISSUE_1867_replace_overflow_libenc
1064 15500 : tmp = add_sat( tmp, delta2 ); /*Q13 */
1065 : #else
1066 : tmp = add_o( tmp, delta2, &Overflow ); /*Q13 */
1067 : #endif
1068 : }
1069 40300 : ELSE IF( LT_16( i, 18 ) )
1070 : {
1071 : #ifdef ISSUE_1867_replace_overflow_libenc
1072 34100 : tmp = add_sat( tmp, delta3 ); /*Q13 */
1073 : #else
1074 : tmp = add_o( tmp, delta3, &Overflow ); /*Q13 */
1075 : #endif
1076 : }
1077 : ELSE
1078 : {
1079 : #ifdef ISSUE_1867_replace_overflow_libenc
1080 6200 : tmp = add_sat( tmp, delta4 ); /*Q13 */
1081 : #else
1082 : tmp = add_o( tmp, delta4, &Overflow ); /*Q13 */
1083 : #endif
1084 : }
1085 :
1086 62000 : tmp1 = tmp;
1087 62000 : move16(); /* ftmp1 = ftmp; */
1088 62000 : sub( 0, 0 );
1089 62000 : if ( LT_16( i, 7 ) )
1090 : {
1091 : #ifdef ISSUE_1867_replace_overflow_libenc
1092 21700 : tmp1 = add_sat( tmp, 3277 ); /*.4 in Q13 ftmp1 = ftmp + 0.4f; */
1093 : #else
1094 : tmp1 = add_o( tmp, 3277, &Overflow ); /*.4 in Q13 ftmp1 = ftmp + 0.4f; */
1095 : #endif
1096 : }
1097 :
1098 62000 : tmp = s_min( tmp, 16384 ); /* Q13, ftmp = min(ftmp, 2.0f); */
1099 62000 : tmp1 = s_min( tmp1, 16384 ); /* Q13, ftmp1 = min(ftmp1, 2.0f); */
1100 :
1101 62000 : L_msnr = L_deposit_l( tmp ); /*msnr = 1*tmp;*/
1102 372000 : FOR( j = 1; j < stmp; j++ )
1103 : {
1104 : /* Q13*Q13 +1 -16 +2 = Q13 */
1105 310000 : L_msnr = L_shl( Mult_32_16( L_msnr, tmp ), 2 ); /*Q13 , msnr *= ftmp;*/
1106 : }
1107 62000 : L_mssnr = L_add( L_mssnr, L_msnr ); /*Q13 mssnr += msnr;*/
1108 :
1109 62000 : if ( EQ_16( i, 18 ) )
1110 : {
1111 3100 : L_msnr18 = L_add( L_msnr, 0 ); /*Q13 msnr18 = msnr; */
1112 : }
1113 :
1114 62000 : if ( EQ_16( i, 19 ) )
1115 : {
1116 3100 : L_msnr19 = L_add( L_msnr, 0 ); /* Q13 , msnr19 = msnr; */
1117 : }
1118 :
1119 62000 : L_msnr = L_deposit_l( tmp1 ); /* Q13, msnr = 1*tmp1 ;*/
1120 :
1121 372000 : FOR( j = 1; j < stmp; j++ )
1122 : {
1123 310000 : L_msnr = L_shl( Mult_32_16( L_msnr, tmp1 ), 2 ); /*Q13 msnr *= ftmp1;*/
1124 : }
1125 62000 : L_mssnr_hov = L_add( L_mssnr_hov, L_msnr ); /*Q13 mssnr_hov += msnr; */
1126 :
1127 : /* recompute after he1 modifications */
1128 : /* snr[i] = fr_enr / st->bckr[i] = L_tmp1/st->bckr[i];*/
1129 62000 : IF( hNoiseEst->bckr_fx[i] != 0 )
1130 : {
1131 62000 : e_num = norm_l( L_tmp1 );
1132 62000 : m_num = extract_h( L_shl( L_tmp1, e_num ) );
1133 :
1134 62000 : e_noise = norm_l( hNoiseEst->bckr_fx[i] );
1135 62000 : m_noise_local = extract_h( L_shl( hNoiseEst->bckr_fx[i], e_noise ) );
1136 :
1137 62000 : m_num = shr( m_num, 1 );
1138 62000 : shift_snr = add( sub( e_num, e_noise ), 15 - 4 );
1139 :
1140 62000 : snr_tmp = div_s( m_num, m_noise_local );
1141 62000 : L_snr = L_shr_sat( snr_tmp, shift_snr ); /* L_snr in Q4 */
1142 : }
1143 : ELSE
1144 : {
1145 0 : e_num = norm_l( L_tmp1 );
1146 0 : m_num = extract_h( L_shl( L_tmp1, e_num ) );
1147 :
1148 : /* if bckr[i] == 0; approx. L_snr */
1149 0 : e_noise = add( 30 + 1, abs_s( Q_new ) );
1150 :
1151 0 : m_num = shr( m_num, 1 );
1152 0 : shift_snr = add( sub( e_num, e_noise ), 15 - 4 );
1153 :
1154 0 : snr_tmp = div_s( m_num, 32767 );
1155 0 : L_snr = L_shr( snr_tmp, shift_snr ); /*L_snr in Q4*/
1156 : }
1157 :
1158 :
1159 : /* conditional snrsum, snr_sum = snr_sum + snr[i];*/
1160 62000 : sign_thr_snr_acc_fx( &L_snr_sum_HE_SAD, L_snr, sign_thr_HE_SAD, min_snr_HE_SAD );
1161 62000 : sign_thr_snr_acc_fx( &L_snr_sum, L_snr, sign_thr, min_snr );
1162 :
1163 62000 : L_snr = L_max( L_snr, 16 ); /*Q4, if( snr[i] < 1.0f ) { snr[i] = 1.0f;} */
1164 :
1165 : /* float saves all snrs in an snr[] vector ,
1166 : in fix we only save two bands */
1167 62000 : if ( EQ_16( i, 18 ) )
1168 : {
1169 3100 : L_snr18 = L_add( L_snr, 0 ); /*Q4 */
1170 : }
1171 62000 : if ( EQ_16( i, 19 ) )
1172 : {
1173 3100 : L_snr19 = L_add( L_snr, 0 ); /* Q4 */
1174 : }
1175 :
1176 : /* accumulate background noise energy in bands [0-2] and in bands [3-19]*/
1177 62000 : IF( LT_16( i, 3 ) )
1178 : {
1179 : #ifdef ISSUE_1867_replace_overflow_libenc
1180 9300 : L_accum_ener_L = L_add_sat( L_accum_ener_L, hNoiseEst->bckr_fx[i] ); /*Q_new+QSCALE */
1181 : #else
1182 : L_accum_ener_L = L_add_o( L_accum_ener_L, hNoiseEst->bckr_fx[i], &Overflow ); /*Q_new+QSCALE */
1183 : #endif
1184 : }
1185 : ELSE
1186 : {
1187 : #ifdef ISSUE_1867_replace_overflow_libenc
1188 52700 : L_accum_ener_H = L_add_sat( L_accum_ener_H, hNoiseEst->bckr_fx[i] ); /*Q_new+QSCALE */
1189 : #else
1190 : L_accum_ener_H = L_add_o( L_accum_ener_H, hNoiseEst->bckr_fx[i], &Overflow ); /*Q_new+QSCALE */
1191 : #endif
1192 : }
1193 :
1194 : /* Identify the outlier band */
1195 62000 : IF( GT_32( L_snr, L_snr_outlier ) )
1196 : {
1197 9825 : L_snr_outlier = L_add( L_snr, 0 ); /*Q4*/
1198 9825 : snr_outlier_index = i;
1199 9825 : move16();
1200 : }
1201 : } /* end of band loop */
1202 :
1203 3100 : test();
1204 3100 : test();
1205 3100 : test(); /* one additional test for ELSE IF */
1206 3100 : IF( ( EQ_16( st_fx->max_band, 19 ) ) && ( GT_32( L_snr18, 5 * ( 1 << 4 ) ) ) && ( GT_32( L_snr19, 5 * ( 1 << 4 ) ) ) )
1207 : {
1208 : /* mssnr = (mssnr + 3*(msnr18 + msnr19)) * 0.77f; */
1209 : /* mssnr = (mssnr*.77f + 2.31f*(msnr18 + msnr19)); */
1210 2984 : L_tmp1 = Mult_32_16( L_mssnr, 25231 ); /* Q13+Q15+1-16 --> Q13 */
1211 2984 : L_tmp = Mult_32_16( L_shl( L_add( L_msnr18, L_msnr19 ), 2 ), 18924 ); /* Q(13+2)+Q(15-2)+1-16 --> Q13 */
1212 2984 : L_tmp = L_add( L_tmp1, L_tmp );
1213 2984 : if ( GT_32( L_tmp, L_mssnr ) )
1214 : {
1215 2715 : L_mssnr = L_tmp; /*Q13*/
1216 : }
1217 : }
1218 116 : ELSE IF( ( snr_idx != 0 ) && GT_16( nb_sig_snr, 13 ) )
1219 : {
1220 0 : L_tmp = -126976;
1221 0 : move32(); /* -15.5 Q13 */
1222 0 : L_tmp = L_mac0( L_tmp, 80, lp_snr ); /* 2.5f(Q5)*lp_snr(Q8) - 15.5f */
1223 0 : if ( L_tmp > 0 ) /* 2.5f*lp_snr - 15.5f > 0 */
1224 : {
1225 0 : L_mssnr = L_add( L_mssnr, L_tmp ); /* mssnr += 2.5f*lp_snr - 15.5f; */
1226 : }
1227 : }
1228 :
1229 :
1230 : /* Separated SNR_SUM outlier modification */
1231 3100 : L_snr_sum_ol = L_snr_sum; /* snr_sum_ol = snr_sum; */
1232 :
1233 3100 : test();
1234 3100 : test();
1235 3100 : test();
1236 3100 : IF( ( EQ_16( st_fx->max_band, 19 ) ) && LT_32( L_snr_outlier, MAX_SNR_OUTLIER_3_FX ) && GT_16( snr_outlier_index, 3 ) && LT_16( snr_outlier_index, MAX_SNR_OUTLIER_IND_FX ) )
1237 : {
1238 : /* Update the total SNR only for WB signals */
1239 :
1240 :
1241 : /* corresponding float section
1242 : if( (accum_ener_L > OUTLIER_THR_1 * accum_ener_H ) || (snr_outlier < MAX_SNR_OUTLIER_1) )
1243 : {
1244 : snr_sum_ol = SNR_OUTLIER_WGHT_1 * (snr_sum_ol - snr_outlier);
1245 : }
1246 : else if( (accum_ener_L > OUTLIER_THR_2 * accum_ener_H ) || (snr_outlier < MAX_SNR_OUTLIER_2) )
1247 : {
1248 : snr_sum_ol = SNR_OUTLIER_WGHT_2 * (snr_sum_ol - snr_outlier);
1249 : }
1250 : else
1251 : {
1252 : snr_sum_ol = SNR_OUTLIER_WGHT_3 * (snr_sum_ol - snr_outlier);
1253 : }
1254 : } */
1255 :
1256 0 : test();
1257 0 : test();
1258 0 : IF( LT_32( L_accum_ener_H, Mult_32_16( L_accum_ener_L, INV_OUTLIER_THR_1_FX ) ) /* float:: (accum_ener_L*INV_OUTLIER_THR_1 > accum_ener_H ) !!! */
1259 : || LT_32( L_snr_outlier, MAX_SNR_OUTLIER_1_FX ) )
1260 :
1261 : {
1262 : /* as weight1 is 1.0 we do not need to multiply here , i.e. no need to loose any precisison */
1263 0 : L_snr_sum_ol = L_sub( L_snr_sum_ol, L_snr_outlier ); /*Q4 */
1264 : }
1265 0 : ELSE IF( LT_32( L_accum_ener_H, Mult_32_16( L_accum_ener_L, INV_OUTLIER_THR_2_FX ) ) /* float:: (accum_ener_L *INV_OUTLIER_THR_2 > accum_ener_H ) !!! */
1266 : || LT_32( L_snr_outlier, MAX_SNR_OUTLIER_2_FX ) )
1267 : {
1268 : /* L_snr_sum = SNR_OUTLIER_WGHT_2 * (snr_sum - snr_outlier); */
1269 :
1270 : /* 1.01*x -> (1*x + 0.01*x) to not drop down to Q3 */
1271 0 : L_tmp = L_sub( L_snr_sum_ol, L_snr_outlier );
1272 0 : L_tmp2 = Mult_32_16( L_tmp, 20972 ); /* 0.01(in Q21)= 20972 Q4*Q21+1-16 -> Q10 */
1273 0 : L_snr_sum_ol = L_add( L_tmp, L_shr( L_tmp2, 6 ) ); /* Q4 */
1274 : }
1275 : ELSE
1276 : {
1277 : /* L_snr_sum = SNR_OUTLIER_WGHT_3 * (snr_sum - snr_outlier);*/
1278 : /* 1.02*x -> (1*x + 0.02*x) to not drop down to Q3 */
1279 0 : L_tmp = L_sub( L_snr_sum_ol, L_snr_outlier );
1280 0 : L_tmp2 = Mult_32_16( L_tmp, 20972 ); /* 0.02(in Q20)= 20972 Q4*Q20+1-16 -> Q9 */
1281 0 : L_snr_sum_ol = L_add( L_tmp, L_shr( L_tmp2, 5 ) ); /* Q4 */
1282 : }
1283 : }
1284 : /*st_fx->snr_sum_vad_fx = 0.5f * st->snr_sum_vad + 0.5f * snr_sum_ol;*/
1285 : #ifdef ISSUE_1867_replace_overflow_libenc
1286 3100 : hVAD->L_snr_sum_vad_fx = L_shr( L_add_sat( hVAD->L_snr_sum_vad_fx, L_snr_sum_ol ), 1 ); /*Q4*/
1287 : #else
1288 : hVAD->L_snr_sum_vad_fx = L_shr( L_add_o( hVAD->L_snr_sum_vad_fx, L_snr_sum_ol, &Overflow ), 1 ); /*Q4*/
1289 : #endif
1290 3100 : move32();
1291 :
1292 : /* snr_sum_ol = 10.0f * (float)log10( snr_sum_ol ); */
1293 3100 : snr_sum_ol = vad_snr_log_fx( L_snr_sum_ol, LG10 );
1294 3100 : snr_sum = snr_sum_ol;
1295 3100 : move16(); /* note for NB no outlier modification */
1296 :
1297 : /* snr_sum_HE_SAD = 10.0f * (float)log10( snr_sum_HE_SAD ); */
1298 3100 : snr_sum_HE_SAD = vad_snr_log_fx( L_snr_sum_HE_SAD, LG10 );
1299 :
1300 3100 : *snr_sum_he = snr_sum_HE_SAD;
1301 3100 : move16(); /* *snr_sum_he=snr_sum_HE_SAD; */
1302 :
1303 :
1304 : /*---------------------------------------------------------------------*
1305 : * compute thr1 for SAD decision
1306 : *---------------------------------------------------------------------*/
1307 3100 : lp_snr = sub( lp_speech_fx, lp_noise_fx ); /*Q8*/
1308 :
1309 3100 : sub( 0, 0 );
1310 3100 : IF( LT_16( lp_snr, hNoiseEst->sign_dyn_lp_fx ) )
1311 : {
1312 85 : lp_snr = add( lp_snr, 1 << 8 ); /* lp_snr += 1; */
1313 :
1314 85 : if ( GT_16( lp_snr, hNoiseEst->sign_dyn_lp_fx ) )
1315 : {
1316 3 : lp_snr = hNoiseEst->sign_dyn_lp_fx;
1317 3 : move16();
1318 : }
1319 : }
1320 :
1321 : /*thr1 = nk * lp_snr + nc*1.0 + nv * ( st->Etot_v_h2 - nv_ofs); */ /* Linear function for noisy speech */
1322 :
1323 3100 : L_tmp = L_shl( L_mult( sub( hNoiseEst->Etot_v_h2_fx, nv_ofs ), nv ), 7 ); /* Q8+Q8+1 +7 --> Q24 */
1324 3100 : L_tmp = L_mac( L_tmp, nc, (Word16) 32767 ); /* Q8+Q15+1 = Q24 */
1325 3100 : thr1 = mac_r( L_tmp, lp_snr, nk ); /* Q8+Q15+1 - 16 --> Q8 */
1326 :
1327 3100 : IF( GT_16( lp_snr, (Word16) 20 * ( 1 << 8 ) ) ) /* if (lp_snr > 20.0f )*/
1328 : {
1329 : {
1330 : /* thr1 = thr1 + 0.3f * (lp_snr - 20.0f); */
1331 3100 : thr1 = add( thr1, mult( 9830, sub( lp_snr, (Word16) 20 * ( 1 << 8 ) ) ) ); /* Q15*Q8+1 -16 --> Q8 */
1332 :
1333 3100 : test();
1334 3100 : test();
1335 3100 : test();
1336 3100 : if ( EQ_16( st_fx->max_band, 16 ) && GT_16( lp_snr, 40 * 256 ) && GT_16( thr1, 6600 ) && LT_16( lp_speech_fx, 11520 ) )
1337 : {
1338 0 : thr1 = 6600;
1339 0 : move16();
1340 : }
1341 : }
1342 : }
1343 :
1344 :
1345 : /*---------------------------------------------------------------------*
1346 : * WB input
1347 : * SNR threshold computing
1348 : * Hangover control & final VAD decision
1349 : *---------------------------------------------------------------------*/
1350 :
1351 3100 : IF( NE_16( vad_bwidth_fx, NB ) )
1352 : {
1353 :
1354 : /* Outlier Detection first calculates thr1_ol and snr_sum_ol instead of
1355 : modyfying thr1 and snr_sum */
1356 :
1357 3100 : thr1_ol = thr1;
1358 3100 : move16();
1359 3100 : hangover_short = 3;
1360 3100 : move16();
1361 :
1362 3100 : IF( LT_16( lp_snr, th_clean ) )
1363 : {
1364 0 : hangover_short = 4;
1365 0 : move16();
1366 :
1367 : /* In this section the modified nk, and nc are used */
1368 0 : test();
1369 0 : test();
1370 0 : test();
1371 0 : test();
1372 0 : test();
1373 0 : test();
1374 0 : test();
1375 0 : test();
1376 0 : test(); /*_DIFF_FLOAT_FIX_ -> the conditions around Opt_SC_VBR_fx are invertered compared to float
1377 : ### st_fx->Opt_SC_VBR!=0 vs !st_fx->Opt_SC_VBR #####*/
1378 : // test();
1379 0 : IF( LE_16( snr_outlier_index, 4 ) && ( ( GT_16( st_fx->last_coder_type, UNVOICED ) && ( st_fx->Opt_SC_VBR != 0 ) ) ||
1380 : ( GT_16( last_7k2_coder_type, UNVOICED ) && ( st_fx->Opt_SC_VBR == 0 ) ) ) )
1381 :
1382 :
1383 : {
1384 0 : thr1_ol = sub( thr1_ol, (Word16) ( 1 << 8 ) ); /*thr1_ol = thr1 - 1.0f ; */
1385 : /*snr_sum_ol = 10.0f * (float)log10( hVAD->L_snr_sum_vad_fx );*/
1386 0 : snr_sum_ol = vad_snr_log_fx( hVAD->L_snr_sum_vad_fx, LG10 ); /* snr in Q8 */
1387 : }
1388 0 : ELSE IF( ( ( LE_16( st_fx->last_coder_type, UNVOICED ) ) && ( LT_32( L_snr_outlier, MAX_SNR_OUTLIER_2_FX ) ) && ( st_fx->Opt_SC_VBR != 0 ) ) ||
1389 : ( ( LE_16( last_7k2_coder_type, UNVOICED ) ) && ( LT_32( L_snr_outlier, MAX_SNR_OUTLIER_2_FX ) ) && ( st_fx->Opt_SC_VBR == 0 ) ) )
1390 :
1391 : {
1392 : /* thr1_ol = thr1 + (float)(1.0f - 0.04f * snr_outlier); */
1393 0 : L_tmp2 = Msub_32_16( (Word32) ( 1 << ( 24 - 16 ) ), L_snr_outlier, 20972 ); /* (1.0)Q24(Q8 in high 32bit word) - Q4*Q19+1 */
1394 0 : tmp2 = round_fx( L_shl( L_tmp2, 16 ) ); /* high word is in Q8 */
1395 0 : thr1_ol = add( thr1_ol, tmp2 ); /* (Q8 , Q8) */
1396 : }
1397 : ELSE
1398 : {
1399 : /*thr1_ol = thr1 + max(0, (float)(0.6f - 0.01f * L_snr_outlier)); */
1400 0 : thr1_ol = thr1;
1401 0 : move16();
1402 0 : L_tmp2 = Msub_32_16( (Word32) 614, L_snr_outlier, 20972 ); /* .6*1024= */ /* 0.6 Q26(Q10 in high word) - Q4*Q21+1 */
1403 : #ifdef ISSUE_1867_replace_overflow_libenc
1404 0 : tmp2 = round_fx( L_shl_sat( L_tmp2, 14 ) ); /* Q10(high word)+ 14 -16 --> Q8*/
1405 : #else
1406 : tmp2 = round_fx( L_shl_o( L_tmp2, 14, &Overflow ) ); /* Q10(high word)+ 14 -16 --> Q8*/
1407 : #endif
1408 0 : IF( L_tmp2 > 0 )
1409 : {
1410 0 : thr1_ol = add( thr1_ol, tmp2 ); /* Q24 >>16 + Q8 */
1411 : }
1412 : }
1413 : }
1414 :
1415 : /* apply outlier modification */
1416 3100 : snr_sum = snr_sum_ol;
1417 3100 : move16(); /*NB s*/
1418 3100 : thr1 = thr1_ol;
1419 3100 : move16();
1420 :
1421 : /* DTX HANGOVER is in pre_proc_fx() */
1422 3100 : flag_he1 = 0;
1423 3100 : move16();
1424 :
1425 3100 : IF( GT_32( L_mssnr, L_vad_thr ) )
1426 : {
1427 3032 : flag_he1 = 1;
1428 3032 : move16(); /* he1 primary decision */
1429 3032 : hVAD->nb_active_frames_he1 = add( hVAD->nb_active_frames_he1, 1 ); /* Counter of consecutive active speech frames */
1430 3032 : move16();
1431 3032 : IF( GE_16( hVAD->nb_active_frames_he1, ACTIVE_FRAMES_FX ) )
1432 : {
1433 3000 : hVAD->nb_active_frames_he1 = ACTIVE_FRAMES_FX;
1434 3000 : move16();
1435 3000 : hVAD->hangover_cnt_he1 = 0;
1436 3000 : move16(); /* Reset the counter of hangover frames after at least "active_frames" speech frames */
1437 : }
1438 :
1439 : /* inside HO period */
1440 3032 : test();
1441 3032 : IF( sub( hVAD->hangover_cnt_he1, HANGOVER_LONG_HE_FX ) < 0 && hVAD->hangover_cnt_he1 != 0 )
1442 : {
1443 28 : hVAD->hangover_cnt_he1 = add( hVAD->hangover_cnt_he1, 1 );
1444 28 : move16();
1445 : }
1446 :
1447 3032 : IF( hVAD->soft_hangover > 0 )
1448 : {
1449 1289 : hVAD->soft_hangover = sub( hVAD->soft_hangover, 1 );
1450 1289 : move16();
1451 : }
1452 : }
1453 : ELSE
1454 : {
1455 : /* Reset the counter of speech frames necessary to start hangover algorithm */
1456 68 : hVAD->nb_active_frames_he1 = 0;
1457 68 : move16();
1458 : }
1459 :
1460 :
1461 3100 : IF( GT_16( hVAD->voiced_burst, 3 ) )
1462 : {
1463 1315 : IF( LT_16( hVAD->bcg_flux_fx, 640 ) ) /* Q4 */
1464 : {
1465 0 : hVAD->soft_hangover = hangover_sf_tbl[add( snr_idx, 3 )];
1466 0 : move16();
1467 : }
1468 : ELSE
1469 : {
1470 1315 : hVAD->soft_hangover = hangover_sf_tbl[snr_idx];
1471 1315 : move16();
1472 : }
1473 : }
1474 :
1475 :
1476 3100 : hangover_hd = hangover_hd_tbl[snr_idx];
1477 3100 : move16();
1478 :
1479 3100 : IF( LT_16( hVAD->bcg_flux_fx, 640 ) )
1480 : {
1481 0 : hangover_hd = add( shr( hangover_hd, 1 ), 1 );
1482 : // move16();
1483 : }
1484 :
1485 : /* VAD hangover for he1 */
1486 3100 : test();
1487 3100 : IF( flag_he1 == 0 && hVAD->soft_hangover > 0 )
1488 : {
1489 23 : IF( GT_32( L_mssnr_hov, L_vad_thr ) )
1490 : {
1491 10 : flag_he1 = 1;
1492 10 : move16();
1493 10 : hVAD->soft_hangover = sub( hVAD->soft_hangover, 1 );
1494 10 : move16();
1495 : }
1496 : ELSE
1497 : {
1498 13 : hVAD->soft_hangover = 0;
1499 13 : move16();
1500 : }
1501 :
1502 23 : if ( hVAD->soft_hangover < 0 )
1503 : {
1504 0 : hVAD->soft_hangover = 0;
1505 0 : move16();
1506 : }
1507 : }
1508 :
1509 3100 : test();
1510 3100 : test();
1511 3100 : IF( ( flag_he1 == 0 ) && ( LT_16( hVAD->hangover_cnt_he1, hangover_hd ) ) && ( hVAD->soft_hangover == 0 ) )
1512 : {
1513 15 : flag_he1 = 1;
1514 15 : move16();
1515 15 : hVAD->hangover_cnt_he1 = add( hVAD->hangover_cnt_he1, 1 );
1516 15 : move16();
1517 : }
1518 :
1519 :
1520 : /* Calculate background stationarity */
1521 3100 : test();
1522 3100 : IF( flag_he1 == 0 && hNoiseEst->first_noise_updt > 0 )
1523 : {
1524 0 : IF( GT_16( snr_sumt, hVAD->bcg_flux_fx ) )
1525 : {
1526 0 : IF( hVAD->bcg_flux_init-- > 0 )
1527 : {
1528 0 : IF( GT_16( snr_sumt, add( hVAD->bcg_flux_fx, 800 ) ) )
1529 : {
1530 : /*st->bcg_flux = 0.9f * st->bcg_flux + (1-0.9f)*(st->bcg_flux+50);*/
1531 0 : hVAD->bcg_flux_fx = mac_r( L_mult( hVAD->bcg_flux_fx, 29491 ), add( hVAD->bcg_flux_fx, 800 ), 3277 ); /*Q4 */
1532 0 : move16();
1533 : }
1534 : ELSE
1535 : {
1536 : /*st->bcg_flux = 0.9f * st->bcg_flux + (1-0.9f)*snr_sumt*/
1537 0 : hVAD->bcg_flux_fx = mac_r( L_mult( hVAD->bcg_flux_fx, 29491 ), snr_sumt, 3277 ); /*Q4 */
1538 0 : move16();
1539 : }
1540 : }
1541 : ELSE
1542 : {
1543 0 : IF( GT_16( snr_sumt, add( hVAD->bcg_flux_fx, 160 ) ) )
1544 : {
1545 : /*st->bcg_flux = 0.99f * st->bcg_flux + (1-0.99f)*(st->bcg_flux+10);*/
1546 0 : hVAD->bcg_flux_fx = mac_r( L_mult( hVAD->bcg_flux_fx, 32440 ), add( hVAD->bcg_flux_fx, 160 ), 328 ); /*Q4 */
1547 0 : move16();
1548 : }
1549 : ELSE
1550 : {
1551 : /*st->bcg_flux = 0.99f * st->bcg_flux + (1-0.99f)*snr_sumt;*/
1552 0 : hVAD->bcg_flux_fx = mac_r( L_mult( hVAD->bcg_flux_fx, 32440 ), snr_sumt, 328 ); /*Q4 */
1553 0 : move16();
1554 : }
1555 : }
1556 : }
1557 : ELSE
1558 : {
1559 0 : IF( hVAD->bcg_flux_init-- > 0 )
1560 : {
1561 0 : IF( LT_16( snr_sumt, sub( hVAD->bcg_flux_fx, 480 ) ) )
1562 : {
1563 : /*st->bcg_flux = 0.95f * st->bcg_flux + (1-0.95f)*(st->bcg_flux-30);*/
1564 0 : hVAD->bcg_flux_fx = mac_r( L_mult( hVAD->bcg_flux_fx, 31130 ), sub( hVAD->bcg_flux_fx, 480 ), 1638 ); /*Q4 */
1565 0 : move16();
1566 : }
1567 : ELSE
1568 : {
1569 : /*st->bcg_flux = 0.95f * st->bcg_flux + (1-0.95f)*snr_sumt;*/
1570 0 : hVAD->bcg_flux_fx = mac_r( L_mult( hVAD->bcg_flux_fx, 31130 ), snr_sumt, 1638 ); /*Q4 */
1571 0 : move16();
1572 : }
1573 : }
1574 : ELSE
1575 : {
1576 0 : IF( LT_16( snr_sumt, sub( hVAD->bcg_flux_fx, 160 ) ) )
1577 : {
1578 : /*st->bcg_flux = 0.9992f * st->bcg_flux + (1-0.9992f)*(st->bcg_flux-10);*/
1579 0 : hVAD->bcg_flux_fx = mac_r( L_mult( hVAD->bcg_flux_fx, 32742 ), sub( hVAD->bcg_flux_fx, 160 ), 26 ); /*Q4 */
1580 0 : move16();
1581 : }
1582 : ELSE
1583 : {
1584 : /*st->bcg_flux = 0.9992f * st->bcg_flux + (1-0.9992f)*snr_sumt;*/
1585 0 : hVAD->bcg_flux_fx = mac_r( L_mult( hVAD->bcg_flux_fx, 32742 ), snr_sumt, 26 ); /*Q4 */
1586 0 : move16();
1587 : }
1588 : }
1589 : }
1590 :
1591 0 : hVAD->bcg_flux_init = s_max( hVAD->bcg_flux_init, 0 ); /*Q0*/
1592 0 : move16();
1593 : }
1594 :
1595 3100 : flag = 0;
1596 3100 : move16();
1597 3100 : st_fx->localVAD = 0;
1598 3100 : move16();
1599 : /* if ( snr_sum > thr1 && flag_he1 == 1 ) */ /* Speech present */
1600 3100 : test();
1601 :
1602 3100 : IF( ( GT_16( snr_sum, thr1 ) ) && ( EQ_16( flag_he1, 1 ) ) ) /* Speech present */
1603 : {
1604 2992 : flag = 1;
1605 2992 : move16();
1606 2992 : st_fx->localVAD = 1;
1607 2992 : move16();
1608 :
1609 2992 : hVAD->nb_active_frames = add( hVAD->nb_active_frames, 1 ); /* Counter of consecutive active speech frames */
1610 2992 : move16();
1611 :
1612 2992 : IF( GE_16( hVAD->nb_active_frames, ACTIVE_FRAMES_FX ) )
1613 : {
1614 2942 : hVAD->nb_active_frames = ACTIVE_FRAMES_FX;
1615 2942 : move16();
1616 2942 : hVAD->hangover_cnt = 0;
1617 2942 : move16(); /* Reset the counter of hangover frames after at least "active_frames" speech frames */
1618 : }
1619 :
1620 : /* inside HO period */
1621 2992 : test();
1622 2992 : IF( LT_16( hVAD->hangover_cnt, HANGOVER_LONG_FX ) && hVAD->hangover_cnt != 0 )
1623 : {
1624 42 : hVAD->hangover_cnt = add( hVAD->hangover_cnt, 1 );
1625 42 : move16();
1626 : }
1627 : }
1628 : ELSE
1629 : {
1630 : /* Reset the counter of speech frames necessary to start hangover algorithm */
1631 108 : hVAD->nb_active_frames = 0;
1632 108 : move16();
1633 :
1634 108 : IF( LT_16( hVAD->hangover_cnt, HANGOVER_LONG_FX ) ) /* inside HO period */
1635 : {
1636 98 : hVAD->hangover_cnt = add( hVAD->hangover_cnt, 1 );
1637 98 : move16();
1638 : }
1639 :
1640 :
1641 108 : IF( LE_16( hVAD->hangover_cnt, hangover_short ) ) /* "hard" hangover */
1642 : {
1643 57 : test();
1644 57 : test();
1645 57 : test();
1646 57 : if ( st_fx->element_mode == EVS_MONO && ( LT_16( lp_snr, th_clean ) ) && ( st_fx->Opt_SC_VBR != 0 ) && ( GE_16( hVAD->hangover_cnt, 2 ) ) )
1647 : {
1648 0 : *noisy_speech_HO = 1;
1649 0 : move16();
1650 : }
1651 57 : test();
1652 57 : test();
1653 57 : test();
1654 57 : if ( st_fx->element_mode == EVS_MONO && ( GE_16( lp_snr, th_clean ) ) && ( st_fx->Opt_SC_VBR != 0 ) && ( GE_16( hVAD->hangover_cnt, 2 ) ) )
1655 : {
1656 0 : *clean_speech_HO = 1;
1657 0 : move16();
1658 : }
1659 57 : flag = 1;
1660 57 : move16(); /*HO*/
1661 : }
1662 : }
1663 :
1664 :
1665 : /* localVAD and vad_flag for HE-SAD - in parallel with normal localVAD and vad_flag */
1666 :
1667 3100 : *localVAD_HE_SAD = 0;
1668 3100 : move16();
1669 :
1670 3100 : test();
1671 3100 : IF( ( GT_16( snr_sum_HE_SAD, thr1 ) ) && ( EQ_16( flag_he1, 1 ) ) ) /* Speech present */
1672 : {
1673 :
1674 2992 : *localVAD_HE_SAD = 1;
1675 2992 : move16();
1676 : }
1677 : } /* end of WB SWB */
1678 :
1679 : /*---------------------------------------------------------------------*
1680 : * NB input
1681 : * SNR threshold computing
1682 : * Hangover control & final VAD decision
1683 : *---------------------------------------------------------------------*/
1684 :
1685 : ELSE /* NB input */
1686 : {
1687 : /* Add localVAD_HE_SAD also for NB operation for use with speech music classifier */
1688 0 : *localVAD_HE_SAD = 0;
1689 0 : move16();
1690 0 : if ( GT_16( snr_sum_HE_SAD, thr1 ) )
1691 : {
1692 0 : *localVAD_HE_SAD = 1;
1693 0 : move16();
1694 : }
1695 :
1696 0 : st_fx->localVAD = 0;
1697 0 : move16(); /* safety inits for fx */
1698 0 : IF( GT_16( snr_sum, thr1 ) ) /* Speech present, possibly in hangover */
1699 : {
1700 0 : hVAD->nb_active_frames = add( hVAD->nb_active_frames, 1 ); /* Counter of consecutive active speech frames */
1701 0 : move16();
1702 0 : IF( GE_16( hVAD->nb_active_frames, ACTIVE_FRAMES_FX ) )
1703 : {
1704 0 : hVAD->nb_active_frames = ACTIVE_FRAMES_FX;
1705 0 : move16();
1706 0 : hVAD->hangover_cnt = 0;
1707 0 : move16(); /* Reset the counter of hangover frames after at least "active_frames" speech frames */
1708 : }
1709 :
1710 0 : st_fx->localVAD = 1;
1711 0 : move16();
1712 : }
1713 : ELSE
1714 : {
1715 0 : hVAD->nb_active_frames = 0;
1716 0 : move16(); /* Reset the counter of speech frames necessary to start hangover algorithm */
1717 : /* st_fx->localVAD = 0; move16(); */ /* set above */
1718 : }
1719 :
1720 0 : thr1_nb_mod = thr1;
1721 0 : move16(); /* thr1 may be adjusted after this point */
1722 0 : IF( LT_16( hVAD->hangover_cnt, HANGOVER_LONG_NB_FX ) )
1723 : {
1724 0 : hVAD->hangover_cnt = add( hVAD->hangover_cnt, 1 );
1725 0 : move16();
1726 0 : IF( LT_16( lp_snr, 4864 ) )
1727 : /*19.0f Q8*/ /* very low SNR */
1728 : {
1729 0 : thr1_nb_mod = sub( thr1_nb_mod, 1331 ); /*thr1 -= 5.2f;*/
1730 : }
1731 0 : ELSE IF( LT_16( lp_snr, 8960 ) ) /*35 in Q8 */ /* low SNR */
1732 : {
1733 0 : thr1_nb_mod = sub( thr1_nb_mod, 512 ); /*thr1 -= 2.0f;*/
1734 : }
1735 : }
1736 :
1737 :
1738 0 : thr2 = sub( thr1_nb_mod, 384 ); /*thr2 = thr1 - 1.5f; , clean speech */
1739 :
1740 : /* -dtx condition dependency in noisy speech */
1741 0 : tmp = 333;
1742 0 : move16(); /* 1.3f; */
1743 0 : if ( st_fx->Opt_DTX_ON == 0 )
1744 : {
1745 0 : tmp = 282;
1746 0 : move16(); /* 1.10f; */
1747 : }
1748 0 : IF( LT_16( lp_snr, th_clean ) )
1749 : {
1750 0 : thr2 = sub( thr1_nb_mod, tmp ); /*thr2 = thr1 - [ 1.10 || 1.3 ];*/
1751 : }
1752 :
1753 :
1754 0 : flag = 0;
1755 0 : move16();
1756 0 : if ( GT_16( snr_sum, thr1_nb_mod ) ) /* Speech assumed present, even though lowered thr1 */
1757 : {
1758 0 : flag = 1;
1759 0 : move16();
1760 : }
1761 :
1762 :
1763 0 : test();
1764 0 : IF( ( LT_16( snr_sum, thr1_nb_mod ) ) && ( GT_16( snr_sum, thr2 ) ) ) /* Speech present */
1765 : {
1766 0 : flag = 1;
1767 0 : move16();
1768 0 : st_fx->localVAD = 0;
1769 0 : move16();
1770 :
1771 0 : if ( EQ_16( st_fx->element_mode, EVS_MONO ) )
1772 : {
1773 0 : *NB_speech_HO = 1;
1774 0 : move16();
1775 : }
1776 : }
1777 0 : thr1 = thr1_nb_mod;
1778 0 : move16(); /* needed for st_fx->vadnoise_fx update below */
1779 : } /* end of NB */
1780 :
1781 :
1782 : /* *flag_noisy_speech_snr is a Word8 parameter */
1783 3100 : *flag_noisy_speech_snr = 0; /*_DIFF_FLOAT_FIX_ -> this initialisation is not done here in float */
1784 3100 : move16();
1785 3100 : IF( vad_bwidth_fx != NB )
1786 : {
1787 3100 : if ( LT_16( lp_snr, TH16_2_NFLAG_FX ) ) /*now 27, original threshold: 35dB*/
1788 : {
1789 0 : *flag_noisy_speech_snr = 1;
1790 0 : move16();
1791 : }
1792 : }
1793 : ELSE
1794 : {
1795 0 : if ( LT_16( lp_snr, TH8_1_NFLAG_FX ) ) /* now 20.0 */
1796 : {
1797 0 : *flag_noisy_speech_snr = 1;
1798 0 : move16();
1799 : }
1800 : }
1801 :
1802 3100 : IF( st_fx->hSC_VBR != NULL )
1803 : {
1804 : /* SC-VBR */
1805 3100 : st_fx->hSC_VBR->vadsnr_fx = snr_sum;
1806 3100 : move16(); /* for ppp, voiced_enc */
1807 3100 : st_fx->hSC_VBR->vadnoise_fx = thr1;
1808 3100 : move16(); /* used in nb for find_uv */
1809 : }
1810 :
1811 : /* Updates */
1812 3100 : hVAD->prim_act_quick_fx = mult_r( 26214, hVAD->prim_act_quick_fx ); /*Q15 */
1813 3100 : move16();
1814 3100 : IF( st_fx->localVAD != 0 )
1815 : {
1816 2992 : hVAD->prim_act_quick_fx = add( 6554, hVAD->prim_act_quick_fx ); /*Q15 */
1817 2992 : move16();
1818 : }
1819 :
1820 3100 : hVAD->prim_act_slow_fx = mult_r( 32440, hVAD->prim_act_slow_fx ); /*Q15 */
1821 3100 : move16();
1822 :
1823 3100 : IF( st_fx->localVAD != 0 )
1824 : {
1825 2992 : hVAD->prim_act_slow_fx = add( 328, hVAD->prim_act_slow_fx ); /*Q15 */
1826 2992 : move16();
1827 : }
1828 :
1829 3100 : tmp = hVAD->prim_act_slow_fx; /*Q15*/
1830 3100 : move16();
1831 3100 : if ( LE_16( hVAD->prim_act_quick_fx, hVAD->prim_act_slow_fx ) )
1832 : {
1833 259 : tmp = hVAD->prim_act_quick_fx;
1834 259 : move16();
1835 : }
1836 : /*st->prim_act = 0.1f * tmp + (1.0f-0.1f)* st->prim_act;*/
1837 3100 : hVAD->prim_act_fx = mac_r( L_mult( 3277, tmp ), 29491, hVAD->prim_act_fx ); /*Q15 */
1838 3100 : move16();
1839 :
1840 3100 : hVAD->prim_act_quick_he_fx = mult_r( 26214, hVAD->prim_act_quick_he_fx ); /*Q15 */
1841 3100 : move16();
1842 3100 : IF( *localVAD_HE_SAD != 0 )
1843 : {
1844 2992 : hVAD->prim_act_quick_he_fx = add( 6554, hVAD->prim_act_quick_he_fx ); /*Q15 */
1845 2992 : move16();
1846 : }
1847 :
1848 3100 : hVAD->prim_act_slow_he_fx = mult_r( 32440, hVAD->prim_act_slow_he_fx ); /*Q15 */
1849 3100 : move16();
1850 3100 : IF( *localVAD_HE_SAD != 0 )
1851 : {
1852 2992 : hVAD->prim_act_slow_he_fx = add( 328, hVAD->prim_act_slow_he_fx ); /*Q15 */
1853 2992 : move16();
1854 : }
1855 :
1856 3100 : tmp = hVAD->prim_act_slow_he_fx;
1857 3100 : move16();
1858 3100 : if ( LE_16( hVAD->prim_act_quick_he_fx, hVAD->prim_act_slow_he_fx ) )
1859 : {
1860 259 : tmp = hVAD->prim_act_quick_he_fx;
1861 259 : move16();
1862 : }
1863 3100 : hVAD->prim_act_he_fx = mac_r( L_mult( 3277, tmp ), 29491, hVAD->prim_act_he_fx );
1864 3100 : move16();
1865 :
1866 3100 : IF( L_and( hVAD->vad_flag_reg_H, (Word32) 0x40000L ) != 0 ) /* 0x4000L = 0x01L << 18 */
1867 : {
1868 2945 : hVAD->vad_flag_cnt_50 = sub( hVAD->vad_flag_cnt_50, 1 );
1869 2945 : move16();
1870 : }
1871 :
1872 3100 : hVAD->vad_flag_reg_H = L_shl( L_and( hVAD->vad_flag_reg_H, (Word32) 0x3fffffffL ), 1 );
1873 3100 : move32();
1874 :
1875 3100 : IF( L_and( hVAD->vad_flag_reg_L, (Word32) 0x40000000L ) != 0 )
1876 : {
1877 2984 : hVAD->vad_flag_reg_H = L_or( hVAD->vad_flag_reg_H, 0x01L );
1878 2984 : move32();
1879 : }
1880 :
1881 3100 : hVAD->vad_flag_reg_L = L_shl( L_and( hVAD->vad_flag_reg_L, (Word32) 0x3fffffffL ), 1 );
1882 3100 : move32();
1883 :
1884 3100 : IF( flag != 0 ) /* should not include the extra DTX hangover */
1885 : {
1886 3049 : hVAD->vad_flag_reg_L = L_or( hVAD->vad_flag_reg_L, 0x01L );
1887 3049 : move32();
1888 3049 : hVAD->vad_flag_cnt_50 = add( hVAD->vad_flag_cnt_50, 1 );
1889 3049 : move16();
1890 : }
1891 :
1892 :
1893 3100 : IF( L_and( hVAD->vad_prim_reg, (Word32) 0x8000L ) != 0 ) /* 0x8000L = 1L << 15 */
1894 : {
1895 2963 : hVAD->vad_prim_cnt_16 = sub( hVAD->vad_prim_cnt_16, 1 );
1896 2963 : move16();
1897 : }
1898 :
1899 3100 : hVAD->vad_prim_reg = L_shl( L_and( hVAD->vad_prim_reg, (Word32) 0x3fffffffL ), 1 );
1900 3100 : move32();
1901 3100 : IF( st_fx->localVAD != 0 )
1902 : {
1903 2992 : hVAD->vad_prim_reg = L_or( hVAD->vad_prim_reg, 0x01L );
1904 2992 : move32();
1905 2992 : hVAD->vad_prim_cnt_16 = add( hVAD->vad_prim_cnt_16, 1 );
1906 2992 : move16();
1907 : }
1908 :
1909 3100 : return flag;
1910 : }
1911 :
1912 1214690 : Word16 wb_vad_ivas_fx(
1913 : Encoder_State *st_fx, /* i/o: encoder state structure */
1914 : const Word32 fr_bands[], /* i : per band i energy (contains 2 vectors) Qx + QSCALE */
1915 : const Word16 q_fr_bands, /* i : Q of fr_bands */
1916 : Word16 *noisy_speech_HO, /* o : SC-VBR noisy speech HO flag */
1917 : Word16 *clean_speech_HO, /* o : SC-VBR clean speech HO flag */
1918 : Word16 *NB_speech_HO, /* o : SC-VBR NB speech HO flag */
1919 : Word16 *snr_sum_he, /* o : Output snr_sum as weighted spectral measure*/
1920 : Word16 *localVAD_HE_SAD,
1921 : Word16 *flag_noisy_speech_snr, /* o : */
1922 : VAD_HANDLE hVAD, /* i/o: VAD data handle */
1923 : NOISE_EST_HANDLE hNoiseEst, /* i : Noise estimation handle */
1924 : Word16 lp_speech_fx, /* i : long term active speech energy average Q8 */
1925 : Word16 lp_noise_fx /* i : long term noise energy Q8 */
1926 : )
1927 : {
1928 1214690 : Word16 i, flag = 0, hangover_short;
1929 1214690 : Word16 snr_sum, thr1 = 0, thr1_nb_mod, thr2 = 0, nk = 0, th_clean = 0;
1930 : Word32 nc;
1931 : Word16 lp_snr; /* Q8 */
1932 : const Word32 *pt1;
1933 : const Word32 *pt2;
1934 : const Word32 *pt3;
1935 :
1936 : Word16 min_snr, sign_thr;
1937 :
1938 : Word32 L_snr, L_snr_sum;
1939 : Word32 ener, fr_enr, ftmp, ftmp1;
1940 : Word16 m_noise_local, e_noise, e_num, m_num, q_snr_tmp, q_snr;
1941 : Word32 L_snr_tmp;
1942 : Word16 snr_sumt;
1943 : Word32 L_vad_thr;
1944 : Word16 hangover_hd;
1945 : Word16 snr_idx;
1946 : Word32 delta1, delta2, delta3, delta4;
1947 :
1948 : Word16 flag_he1;
1949 : Word16 stmp;
1950 1214690 : Word32 L_msnr, L_mssnr = 0, L_mssnr_hov;
1951 : Word16 j, tmp, tmp2;
1952 : Word32 L_tmp, L_tmp1, L_tmp2;
1953 :
1954 : Word32 L_snr18, L_snr19; /* Q4 */
1955 : Word32 L_msnr18, L_msnr19; /* Q13 */
1956 : Word16 nb_sig_snr; /* Q0 */
1957 :
1958 : Word16 nv;
1959 : Word32 nv_ofs; /* Q24 */
1960 : Word32 L_snr_sum_HE_SAD; /* Q4 */
1961 : Word16 snr_sum_HE_SAD; /*Q8 log */
1962 : Word16 sign_thr_HE_SAD, min_snr_HE_SAD;
1963 : Word32 L_snr_sumt;
1964 :
1965 : Word16 thr1_ol;
1966 : Word32 L_snr_sum_ol;
1967 : Word16 snr_sum_ol; /* Q8 log */
1968 :
1969 : Word32 L_snr_outlier, L_snr_outlier_Q4;
1970 : Word16 snr_outlier_index;
1971 : Word32 L_accum_ener_L;
1972 : Word32 L_accum_ener_H;
1973 : Word16 vad_bwidth_fx;
1974 : Word16 last_7k2_coder_type;
1975 : Word16 q_shift, q_ener, q_diff1, q_diff2;
1976 : Word16 q_L_snr_sum_ol, e_snr, f_snr;
1977 : #ifndef ISSUE_1867_replace_overflow_libenc
1978 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
1979 : Flag Overflow = 0;
1980 : move32();
1981 : #endif
1982 : #endif
1983 1214690 : Word16 L_msnr_e = 0, L_mssnr_e = 0, L_mssnr_hov_e = 0, L_msnr18_e = 0, L_msnr19_e = 0;
1984 1214690 : move16(); /*L_msnr_e*/
1985 1214690 : move16(); /*L_mssnr_e*/
1986 1214690 : move16(); /*L_mssnr_hov_e*/
1987 1214690 : move16(); /*L_msnr18_e*/
1988 1214690 : move16(); /*L_msnr19_e*/
1989 1214690 : move32(); /*L_mssnr*/
1990 1214690 : move16(); /*thr1*/
1991 1214690 : move16(); /*thr2*/
1992 1214690 : move16(); /*nk*/
1993 1214690 : move32(); /*nc*/
1994 1214690 : move16(); /*th_clean*/
1995 1214690 : move16(); /*flag*/
1996 :
1997 1214690 : if ( hNoiseEst == NULL )
1998 : {
1999 1132964 : hNoiseEst = st_fx->hNoiseEst;
2000 : }
2001 :
2002 1214690 : if ( hVAD == NULL )
2003 : {
2004 1132964 : hVAD = st_fx->hVAD;
2005 : }
2006 1214690 : if ( LT_16( lp_speech_fx, -100 * 256 ) )
2007 : {
2008 1132964 : lp_speech_fx = extract_h( st_fx->lp_speech_32fx ); /*Q8*/
2009 1132964 : move16();
2010 : }
2011 :
2012 1214690 : if ( LT_16( lp_noise_fx, -100 * 256 ) )
2013 : {
2014 1132964 : lp_noise_fx = extract_h( st_fx->lp_noise_32fx ); /*Q8*/
2015 1132964 : move16();
2016 : }
2017 :
2018 1214690 : vad_bwidth_fx = st_fx->input_bwidth;
2019 1214690 : move16();
2020 :
2021 1214690 : L_snr_outlier = L_deposit_l( 0 );
2022 1214690 : snr_outlier_index = 0;
2023 1214690 : move16();
2024 1214690 : L_accum_ener_L = L_deposit_l( 0 );
2025 1214690 : L_accum_ener_H = L_deposit_l( 0 );
2026 :
2027 1214690 : L_snr18 = L_deposit_l( 0 ); /* Q4*/
2028 1214690 : L_snr19 = L_deposit_l( 0 ); /* Q4 */
2029 1214690 : L_msnr18 = L_deposit_l( 8192 ); /* 1.0 Q13*/
2030 1214690 : L_msnr19 = L_deposit_l( 8192 ); /* 1.0 Q13 */
2031 :
2032 :
2033 1214690 : IF( EQ_16( vad_bwidth_fx, NB ) )
2034 : {
2035 4264 : st_fx->min_band = 1;
2036 4264 : move16();
2037 4264 : st_fx->max_band = 16;
2038 4264 : move16();
2039 : }
2040 : ELSE
2041 : {
2042 1210426 : st_fx->min_band = 0;
2043 1210426 : move16();
2044 1210426 : st_fx->max_band = 19;
2045 1210426 : move16();
2046 : }
2047 :
2048 1214690 : IF( st_fx->Opt_SC_VBR )
2049 : {
2050 0 : last_7k2_coder_type = st_fx->hSC_VBR->last_7k2_coder_type;
2051 0 : move16();
2052 : }
2053 : ELSE
2054 : {
2055 1214690 : last_7k2_coder_type = -1;
2056 1214690 : move16();
2057 : }
2058 : /*---------------------------------------------------------------------*
2059 : * set SNR thresholds depending on the input bandwitdh
2060 : *---------------------------------------------------------------------*/
2061 1214690 : IF( EQ_16( st_fx->max_band, 19 ) )
2062 : /* WB input */ /* or SWB input */
2063 : {
2064 1210426 : nk = 3277;
2065 1210426 : move16(); /*0.1 Q15 */
2066 1210426 : nc = 270113178;
2067 1210426 : move32(); /*16.1 Q24 */
2068 1210426 : nv = 8397;
2069 1210426 : move16(); /* 2.05 Q12*/
2070 1210426 : nv_ofs = 27682406;
2071 1210426 : move32(); /* 1.65 Q24*/
2072 1210426 : th_clean = TH16_2_FX;
2073 1210426 : move16(); /* 35 Q8 */
2074 1210426 : sign_thr = 21;
2075 1210426 : move16(); /*1.3 Q4 */
2076 1210426 : tmp = sub( vad_bwidth_fx, WB );
2077 1210426 : if ( tmp != 0 )
2078 : {
2079 1094684 : sign_thr = 28;
2080 1094684 : move16(); /*1.75f; Q4 SWB */
2081 : }
2082 1210426 : min_snr = 13;
2083 1210426 : move16(); /*0.8 Q4 WB */
2084 1210426 : if ( tmp != 0 )
2085 : {
2086 1094684 : min_snr = 4;
2087 1094684 : move16(); /*0.25f; Q4 SWB */
2088 : }
2089 :
2090 1210426 : sign_thr_HE_SAD = 40;
2091 1210426 : move16(); /* 2.5f Q4 */
2092 1210426 : min_snr_HE_SAD = 3;
2093 1210426 : move16(); /* 0.2f Q4 */
2094 : }
2095 : ELSE /* NB input */
2096 : {
2097 : // move16();
2098 4264 : nk = 3277;
2099 4264 : move16(); /* 0.1 Q15 */
2100 4264 : nc = 268435456;
2101 4264 : move32(); /* 16.0 Q24 */
2102 4264 : nv = 16384;
2103 4264 : move16(); /* 4.0 Q12 */
2104 4264 : nv_ofs = 19293798;
2105 4264 : move32(); /*1.15 Q24*/
2106 4264 : th_clean = TH8_1_FX;
2107 4264 : move16(); /*20 Q8 */
2108 4264 : sign_thr = 28;
2109 4264 : move16(); /* 1.75 * Q4 SIGN_THR */
2110 4264 : min_snr = 4;
2111 4264 : move16(); /* .25 *Q4 MIN_SNR */
2112 4264 : sign_thr_HE_SAD = 42;
2113 4264 : move16(); /* 2.65f Q4 */
2114 4264 : min_snr_HE_SAD = 1;
2115 4264 : move16(); /* 0.05f Q4 */
2116 : }
2117 :
2118 1214690 : hangover_short = 0;
2119 1214690 : move16();
2120 :
2121 1214690 : IF( st_fx->Opt_SC_VBR != 0 )
2122 : {
2123 0 : *noisy_speech_HO = 0;
2124 0 : move16();
2125 0 : *clean_speech_HO = 0;
2126 0 : move16();
2127 0 : *NB_speech_HO = 0;
2128 0 : move16();
2129 : }
2130 :
2131 : /*---------------------------------------------------------------------*
2132 : * compute SNR for each band & total
2133 : *---------------------------------------------------------------------*/
2134 :
2135 1214690 : lp_snr = sub( lp_speech_fx, lp_noise_fx ); /*Q8 */
2136 :
2137 1214690 : snr_idx = 2;
2138 1214690 : move16();
2139 1214690 : if ( GT_16( lp_snr, 4608 ) ) /*18.0 Q8*/
2140 : {
2141 1082048 : snr_idx = 1;
2142 1082048 : move16();
2143 : }
2144 1214690 : if ( GT_16( lp_snr, 6144 ) ) /*24.0 Q8*/
2145 : {
2146 1060987 : snr_idx = 0;
2147 1060987 : move16();
2148 : }
2149 :
2150 :
2151 1214690 : IF( snr_idx == 0 )
2152 : {
2153 1060987 : stmp = 6;
2154 1060987 : move32();
2155 1060987 : delta1 = 0;
2156 1060987 : move32(); /*0.0f in Q16 */
2157 1060987 : delta2 = 0;
2158 1060987 : move32(); /*0.0f in Q16 */
2159 1060987 : delta3 = 0;
2160 1060987 : move32(); /*0.0f in Q16 */
2161 1060987 : delta4 = 0;
2162 1060987 : move32(); /*0.0f in Q16 */
2163 :
2164 :
2165 : /*vad_thr = 2.4f*lp_snr - 42.2f;
2166 : vad_thr = min(vad_thr, 80 ); */
2167 :
2168 1060987 : L_vad_thr = -345702;
2169 1060987 : move32(); /* -42.2 Q13*/
2170 1060987 : L_vad_thr = L_mac0( L_vad_thr, 77, lp_snr ); /* (2.4)Q5*(lp_snr)Q8 */
2171 1060987 : L_vad_thr = L_min( L_vad_thr, 80 * ( 1 << 13 ) );
2172 : }
2173 153703 : ELSE IF( EQ_16( snr_idx, 1 ) )
2174 : {
2175 21061 : stmp = 6;
2176 21061 : move32();
2177 21061 : delta1 = 6554;
2178 21061 : move32(); /*0.1f in Q16 */
2179 21061 : delta2 = 13107;
2180 21061 : move32(); /*0.2f in Q16 */
2181 21061 : delta3 = 13107;
2182 21061 : move32(); /*0.2f in Q16 */
2183 21061 : delta4 = 13107;
2184 21061 : move32(); /*0.2f in Q16 */
2185 :
2186 : /* vad_thr = 2.4f*lp_snr - 40.2f;
2187 : vad_thr = min(vad_thr, 80);
2188 : */
2189 21061 : L_vad_thr = -329318;
2190 21061 : move32(); /* -40.2 Q13*/
2191 21061 : L_vad_thr = L_mac0( L_vad_thr, 77, lp_snr ); /* (2.4)Q5*(lp_snr)Q8 */
2192 21061 : L_vad_thr = L_min( L_vad_thr, 80 * ( 1 << 13 ) );
2193 : }
2194 : ELSE
2195 : {
2196 132642 : stmp = 9;
2197 132642 : move32();
2198 132642 : delta1 = 13107;
2199 132642 : move32(); /*0.2f in Q16 */
2200 132642 : delta2 = 26214;
2201 132642 : move32(); /*0.4f in Q16 */
2202 132642 : delta3 = 19661;
2203 132642 : move32(); /*0.3f in Q16 */
2204 132642 : delta4 = 26214;
2205 132642 : move32(); /*0.4f in Q16 */
2206 : /* vad_thr = 2.5f*lp_snr - 10.0f;
2207 : vad_thr = max(vad_thr, 1);
2208 : */
2209 132642 : L_vad_thr = -81920;
2210 132642 : move32(); /* -10 Q13*/
2211 132642 : L_vad_thr = L_mac0( L_vad_thr, 80, lp_snr ); /* (2.5)Q5*(lp_snr)Q8 */
2212 132642 : L_vad_thr = L_max( L_vad_thr, 1 * ( 1 << 13 ) );
2213 : }
2214 :
2215 1214690 : nb_sig_snr = 20;
2216 1214690 : move16();
2217 :
2218 1214690 : L_snr_sum = L_deposit_l( 0 );
2219 1214690 : L_snr_sum_HE_SAD = L_deposit_l( 0 );
2220 1214690 : Word16 q_snr_sum = 0;
2221 1214690 : Word16 q_snr_sum_HE_SAD = 0;
2222 1214690 : move16();
2223 1214690 : move16();
2224 1214690 : snr_sumt = 0;
2225 1214690 : move16();
2226 1214690 : L_mssnr_hov = L_deposit_l( 0 );
2227 1214690 : *snr_sum_he = 0;
2228 1214690 : move16();
2229 1214690 : snr_sum_HE_SAD = 0;
2230 1214690 : move16();
2231 :
2232 1214690 : L_snr_sumt = 0;
2233 1214690 : move32();
2234 1214690 : q_snr = 0;
2235 1214690 : move16();
2236 1214690 : move16();
2237 :
2238 1214690 : pt1 = fr_bands;
2239 1214690 : pt2 = fr_bands + NB_BANDS;
2240 1214690 : pt3 = hNoiseEst->bckr_fx;
2241 :
2242 1214690 : q_ener = s_min( q_fr_bands, hNoiseEst->q_enrO );
2243 1214690 : q_diff1 = sub( q_ener, hNoiseEst->q_enrO );
2244 1214690 : q_diff2 = sub( q_ener, q_fr_bands );
2245 1214690 : q_shift = add( Q31 + Q1, sub( q_ener, hNoiseEst->q_bckr ) );
2246 :
2247 25491434 : FOR( i = st_fx->min_band; i <= st_fx->max_band; i++ )
2248 : {
2249 24276744 : ener = L_shl( hNoiseEst->enrO_fx[i], q_diff1 ); // q_ener
2250 24276744 : ftmp = L_shl( *pt1++, q_diff2 ); // q_ener
2251 24276744 : ftmp1 = L_shl( *pt2++, q_diff2 ); // q_ener
2252 :
2253 : /*fr_enr = ( 0.2f * st->enrO[i] + 0.4f * ftmp + 0.4f * ftmp1 );*/
2254 24276744 : L_tmp = Mpy_32_16_1( ener, 13107 /* 0.2 in Q16 */ ); // q_ener+1
2255 24276744 : fr_enr = Madd_32_16( Madd_32_16( L_tmp, ftmp, 26214 /* 0.4 in Q16 */ ), ftmp1, 26214 /* 0.4 in Q16 */ ); // q_ener+1
2256 :
2257 24276744 : IF( GT_32( ftmp, ftmp1 ) )
2258 : {
2259 : /* snr[i] = ( 0.2f * hNoiseEst->enrO[i] + 0.4f * ftmp + 0.4f * ftmp1 ) / *pt3++; */
2260 10764057 : IF( *pt3 != 0 )
2261 : {
2262 : /* Since fr_enr = 0.2f * hNoiseEst->enrO[i] + 0.4f * ftmp + 0.4f * ftmp1 */
2263 10764057 : e_num = sub( norm_l( fr_enr ), 1 );
2264 10764057 : m_num = extract_h( L_shl( fr_enr, e_num ) ); // q_ener+1+e_num-16
2265 :
2266 10764057 : e_noise = norm_l( *pt3 );
2267 10764057 : m_noise_local = extract_h( L_shl( *pt3++, e_noise ) ); // hNoiseEst->q_bckr+e_noise-16
2268 :
2269 10764057 : L_snr = L_deposit_h( div_s( m_num, m_noise_local ) ); // 31+(q_ener+1+e_num-16)-(hNoiseEst->q_bckr+e_noise-16)
2270 10764057 : q_snr_tmp = add( q_shift, sub( e_num, e_noise ) );
2271 : }
2272 : ELSE
2273 : {
2274 0 : L_snr = Mpy_32_16_1( fr_enr, 18286 /* (1/E_MIN) in Q6 */ ); // q_ener+1+6-15
2275 0 : q_snr_tmp = sub( q_ener, 8 );
2276 : }
2277 : }
2278 : ELSE
2279 : {
2280 : /* snr[i] = ( 0.2f * hNoiseEst->enrO[i] + 0.3f * ftmp + 0.5f * ftmp1 ) / *pt3++; */
2281 : /* Since, L_tmp = 0.2f * hNoiseEst->enrO[i] */
2282 13512687 : L_tmp = Msub_32_16( Madd_32_16( L_tmp, ftmp, 19661 /* 0.3 in Q16 */ ), ftmp1, -32768 /* -0.5 in Q16 */ ); // q_ener+1
2283 :
2284 13512687 : IF( *pt3 != 0 )
2285 : {
2286 13512687 : e_num = sub( norm_l( L_tmp ), 1 );
2287 13512687 : m_num = extract_h( L_shl( L_tmp, e_num ) ); // q_ener+1+e_num-16
2288 :
2289 13512687 : e_noise = norm_l( *pt3 );
2290 13512687 : m_noise_local = extract_h( L_shl( *pt3++, e_noise ) ); // hNoiseEst->q_bckr+e_noise-16
2291 :
2292 13512687 : L_snr = L_deposit_h( div_s( m_num, m_noise_local ) ); // 31+(q_ener+1+e_num-16)-(hNoiseEst->q_bckr+e_noise-16)
2293 13512687 : q_snr_tmp = add( q_shift, sub( e_num, e_noise ) );
2294 : }
2295 : ELSE
2296 : {
2297 0 : L_snr = Mpy_32_16_1( L_tmp, 18286 /* (1/E_MIN) in Q6 */ ); // q_ener+1+6-15
2298 0 : q_snr_tmp = sub( q_ener, 8 );
2299 : }
2300 : }
2301 :
2302 24276744 : if ( LT_32( L_snr, L_shl_sat( 2, q_snr_tmp ) ) )
2303 : {
2304 4720675 : nb_sig_snr = sub( nb_sig_snr, 1 ); /* nb_sig_snr--; */
2305 : }
2306 24276744 : IF( LT_32( L_snr, L_shl_sat( 1, q_snr_tmp ) ) )
2307 : {
2308 1605326 : L_snr = ONE_IN_Q30;
2309 1605326 : q_snr_tmp = Q30;
2310 1605326 : move32();
2311 1605326 : move16();
2312 : }
2313 :
2314 : /* snr[i] = (float)log10(snr[i]); */
2315 24276744 : Word16 exp = norm_l( L_snr );
2316 24276744 : Word16 val = Log2_norm_lc( L_shl( L_snr, exp ) );
2317 24276744 : exp = sub( sub( 30, exp ), q_snr_tmp );
2318 24276744 : L_snr = L_mac( val, exp, ONE_IN_Q14 ); // Q15
2319 24276744 : L_snr = Mpy_32_16_1( L_snr, 19728 /* log2 in Q16 */ ); // Q16
2320 :
2321 : /* snr_sumt += snr[i];*/
2322 24276744 : L_snr_sumt = L_add( L_snr_sumt, L_snr ); // Q16
2323 :
2324 24276744 : IF( LT_16( i, 2 ) )
2325 : {
2326 2425116 : ftmp = L_add( L_snr, delta1 ); // Q16
2327 : }
2328 21851628 : ELSE IF( LT_16( i, 7 ) )
2329 : {
2330 6073450 : ftmp = L_add( L_snr, delta2 ); // Q16
2331 : }
2332 15778178 : ELSE IF( LT_16( i, 18 ) )
2333 : {
2334 13357326 : ftmp = L_add( L_snr, delta3 ); // Q16
2335 : }
2336 : ELSE
2337 : {
2338 2420852 : ftmp = L_add( L_snr, delta4 ); // Q16
2339 : }
2340 :
2341 24276744 : ftmp1 = ftmp; // Q16
2342 24276744 : move32();
2343 :
2344 24276744 : if ( LT_16( i, 7 ) )
2345 : {
2346 8498566 : ftmp1 = L_add( ftmp, 26214 /*0.4 in Q16*/ ); // Q16
2347 : }
2348 :
2349 24276744 : ftmp = L_min( ftmp, 2 << 16 ); // Q16
2350 24276744 : ftmp1 = L_min( ftmp1, 2 << 16 ); // Q16
2351 :
2352 24276744 : Word16 norm_tmp = norm_l( ftmp );
2353 24276744 : Word32 scaled_tmp = L_shl( ftmp, norm_tmp ); /*16+norm_tmp*/
2354 24276744 : L_msnr = scaled_tmp;
2355 24276744 : move32();
2356 24276744 : L_msnr_e = sub( 15, norm_tmp );
2357 153618984 : FOR( j = 1; j < stmp; j++ )
2358 : {
2359 : /* Q13*Q13 +1 -16 +2 = Q13 */
2360 129342240 : L_msnr = Mult_32_32( L_msnr, scaled_tmp ); /*L_msnr_e , msnr *= ftmp;*/
2361 : }
2362 24276744 : L_msnr_e = imult1616( L_msnr_e, stmp );
2363 24276744 : L_mssnr = BASOP_Util_Add_Mant32Exp( L_mssnr, L_mssnr_e, L_msnr, L_msnr_e, &L_mssnr_e ); /*L_mssnr_e mssnr += msnr;*/
2364 :
2365 24276744 : IF( EQ_16( i, 18 ) )
2366 : {
2367 1210426 : L_msnr18 = L_add( L_msnr, 0 ); /*L_msnr_e msnr18 = msnr; */
2368 1210426 : L_msnr18_e = L_msnr_e;
2369 1210426 : move16();
2370 : }
2371 :
2372 24276744 : IF( EQ_16( i, 19 ) )
2373 : {
2374 1210426 : L_msnr19 = L_add( L_msnr, 0 ); /* L_msnr_e , msnr19 = msnr; */
2375 1210426 : L_msnr19_e = L_msnr_e;
2376 1210426 : move16();
2377 : }
2378 :
2379 24276744 : norm_tmp = norm_l( ftmp1 );
2380 24276744 : scaled_tmp = L_shl( ftmp1, norm_tmp ); /*16+norm_tmp*/
2381 24276744 : L_msnr = scaled_tmp;
2382 24276744 : move32();
2383 24276744 : L_msnr_e = sub( 15, norm_tmp );
2384 153618984 : FOR( j = 1; j < stmp; j++ )
2385 : {
2386 129342240 : L_msnr = Mult_32_32( L_msnr, scaled_tmp ); /*L_msnr_e msnr *= ftmp1;*/
2387 : }
2388 24276744 : L_msnr_e = imult1616( L_msnr_e, stmp );
2389 24276744 : L_mssnr_hov = BASOP_Util_Add_Mant32Exp( L_mssnr_hov, L_mssnr_hov_e, L_msnr, L_msnr_e, &L_mssnr_hov_e ); /*L_mssnr_hov_e mssnr_hov += msnr; */
2390 :
2391 : /* recompute after he1 modifications */
2392 : /* snr[i] = fr_enr / st->bckr[i] ;*/
2393 24276744 : IF( hNoiseEst->bckr_fx[i] != 0 )
2394 : {
2395 24276744 : e_num = sub( norm_l( fr_enr ), 1 );
2396 24276744 : m_num = extract_h( L_shl( fr_enr, e_num ) ); // q_ener+1+e_num-16
2397 :
2398 24276744 : e_noise = norm_l( hNoiseEst->bckr_fx[i] );
2399 24276744 : m_noise_local = extract_h( L_shl( hNoiseEst->bckr_fx[i], e_noise ) ); // hNoiseEst->q_bckr+e_noise-16
2400 :
2401 24276744 : L_snr_tmp = L_deposit_h( div_s( m_num, m_noise_local ) ); // 31+q_ener+1+e_num-hNoiseEst->q_bckr-e_noise
2402 24276744 : q_snr_tmp = add( 32, sub( add( q_ener, e_num ), add( hNoiseEst->q_bckr, e_noise ) ) );
2403 : }
2404 : ELSE
2405 : {
2406 0 : L_snr_tmp = Mpy_32_16_1( fr_enr, 18286 /* 1/E_MIN in Q6 */ ); // q_ener+1+6-15
2407 0 : q_snr_tmp = sub( q_ener, 8 );
2408 : }
2409 :
2410 : /* conditional snrsum, snr_sum = snr_sum + snr[i];*/
2411 24276744 : IF( GT_16( q_snr_tmp, 28 ) ) // added to avoid overflow while scaling sign_thr_HE_SAD,min_snr_HE_SAD,sign_thr and min_snr while scaling to q_snr_tmp
2412 : {
2413 5033375 : L_snr_tmp = L_shl( L_snr_tmp, sub( 28, q_snr_tmp ) );
2414 5033375 : q_snr_tmp = 28;
2415 5033375 : move16();
2416 : }
2417 24276744 : exp = sub( Q4, q_snr_tmp );
2418 24276744 : L_snr = L_shl_sat( L_snr_tmp, exp ); // Q4
2419 24276744 : sign_thr_snr_acc_ivas_fx( &L_snr_sum_HE_SAD, &q_snr_sum_HE_SAD, L_snr_tmp, q_snr_tmp, L_shl( sign_thr_HE_SAD, sub( q_snr_tmp, 4 ) ), L_shl( min_snr_HE_SAD, sub( q_snr_tmp, 4 ) ) );
2420 24276744 : sign_thr_snr_acc_ivas_fx( &L_snr_sum, &q_snr_sum, L_snr_tmp, q_snr_tmp, L_shl( sign_thr, sub( q_snr_tmp, 4 ) ), L_shl( min_snr, sub( q_snr_tmp, 4 ) ) );
2421 :
2422 : /* if( snr[i] < 1.0f ) { snr[i] = 1.0f;} */
2423 24276744 : IF( LT_32( L_snr, 16 /* 1.0 in Q4 */ ) )
2424 : {
2425 3426042 : L_snr_tmp = 16;
2426 3426042 : q_snr_tmp = Q4;
2427 3426042 : move32();
2428 3426042 : move16();
2429 3426042 : exp = 0;
2430 3426042 : move16();
2431 : }
2432 :
2433 : /* float saves all snrs in an snr[] vector ,
2434 : in fix we only save two bands */
2435 24276744 : if ( EQ_16( i, 18 ) )
2436 : {
2437 1210426 : L_snr18 = L_shl_sat( L_snr_tmp, exp ); /*Q4 */
2438 : }
2439 24276744 : if ( EQ_16( i, 19 ) )
2440 : {
2441 1210426 : L_snr19 = L_shl_sat( L_snr_tmp, exp ); /* Q4 */
2442 : }
2443 :
2444 : /* accumulate background noise energy in bands [0-2] and in bands [3-19]*/
2445 24276744 : IF( LT_16( i, 3 ) )
2446 : {
2447 : #ifdef ISSUE_1867_replace_overflow_libenc
2448 3639806 : L_accum_ener_L = L_add_sat( L_accum_ener_L, hNoiseEst->bckr_fx[i] ); /* hNoiseEst->q_bckr */
2449 : #else
2450 : L_accum_ener_L = L_add_o( L_accum_ener_L, hNoiseEst->bckr_fx[i], &Overflow ); /* hNoiseEst->q_bckr */
2451 : #endif
2452 : }
2453 : ELSE
2454 : {
2455 : #ifdef ISSUE_1867_replace_overflow_libenc
2456 20636938 : L_accum_ener_H = L_add_sat( L_accum_ener_H, hNoiseEst->bckr_fx[i] ); /*hNoiseEst->q_bckr */
2457 : #else
2458 : L_accum_ener_H = L_add_o( L_accum_ener_H, hNoiseEst->bckr_fx[i], &Overflow ); /*hNoiseEst->q_bckr */
2459 : #endif
2460 : }
2461 :
2462 : /* Identify the outlier band */
2463 24276744 : IF( GT_32( L_snr_tmp, L_shl_sat( L_snr_outlier, sub( q_snr_tmp, q_snr ) ) ) )
2464 : {
2465 3424503 : L_snr_outlier = L_snr_tmp;
2466 3424503 : q_snr = q_snr_tmp;
2467 3424503 : snr_outlier_index = i;
2468 3424503 : move32();
2469 3424503 : move16();
2470 3424503 : move16();
2471 : }
2472 : } /* end of band loop */
2473 : #ifdef ISSUE_1867_replace_overflow_libenc
2474 1214690 : L_snr_sum_HE_SAD = L_shl_sat( L_snr_sum_HE_SAD, sub( 4, q_snr_sum_HE_SAD ) ); // q_snr_sum_HE_SAD->q4
2475 : #else
2476 : L_snr_sum_HE_SAD = L_shl_o( L_snr_sum_HE_SAD, sub( 4, q_snr_sum_HE_SAD ), &Overflow ); // q_snr_sum_HE_SAD->q4
2477 : #endif
2478 :
2479 1214690 : snr_sumt = extract_h( L_shl( L_snr_sumt, Q4 ) ); // Q16 -> Q4
2480 :
2481 1214690 : test();
2482 1214690 : test();
2483 1214690 : test(); /* one additional test for ELSE IF */
2484 1214690 : IF( ( EQ_16( st_fx->max_band, 19 ) ) && ( GT_32( L_snr18, 5 * ( 1 << 4 ) ) ) && ( GT_32( L_snr19, 5 * ( 1 << 4 ) ) ) )
2485 899048 : {
2486 : /* mssnr = (mssnr + 3*(msnr18 + msnr19)) * 0.77f; */
2487 : /* mssnr = (mssnr*.77f + 2.31f*(msnr18 + msnr19)); */
2488 : Word16 L_tmp_e;
2489 899048 : L_tmp1 = Mult_32_16( L_mssnr, 25231 ); /* Q13+Q15+1-16 --> L_mssnr_e */
2490 899048 : L_tmp = Mult_32_16( BASOP_Util_Add_Mant32Exp( L_msnr18, L_msnr18_e, L_msnr19, L_msnr19_e, &L_tmp_e ), 18924 ); /* Q(31-L_tmp1_e)+Q(15-2)+1-16 -->exp= L_msnr_e +2*/
2491 899048 : L_tmp = BASOP_Util_Add_Mant32Exp( L_tmp1, L_mssnr_e, L_tmp, add( L_tmp_e, 2 ), &L_tmp_e );
2492 899048 : IF( EQ_16( BASOP_Util_Cmp_Mant32Exp( L_tmp, L_tmp_e, L_mssnr, L_mssnr_e ), 1 ) )
2493 : {
2494 771114 : L_mssnr = L_tmp;
2495 771114 : L_mssnr_e = L_tmp_e;
2496 771114 : move32();
2497 771114 : move16();
2498 : }
2499 : }
2500 315642 : ELSE IF( ( snr_idx != 0 ) && GT_16( nb_sig_snr, 13 ) )
2501 : {
2502 21580 : L_tmp = -126976;
2503 21580 : move32(); /* -15.5 Q13 */
2504 21580 : L_tmp = L_mac0( L_tmp, 80, lp_snr ); /* 2.5f(Q5)*lp_snr(Q8) - 15.5f */
2505 21580 : IF( L_tmp > 0 ) /* 2.5f*lp_snr - 15.5f > 0 */
2506 : {
2507 20691 : L_mssnr = BASOP_Util_Add_Mant32Exp( L_mssnr, L_mssnr_e, L_tmp, 18, &L_mssnr_e ); /* mssnr += 2.5f*lp_snr - 15.5f; */
2508 : }
2509 : }
2510 :
2511 1214690 : L_snr_outlier_Q4 = L_shl_sat( L_snr_outlier, sub( Q4, q_snr ) ); // Q4
2512 :
2513 : /* Separated SNR_SUM outlier modification */
2514 : /* snr_sum_ol = snr_sum; */
2515 1214690 : L_snr_sum_ol = L_snr_sum; // q_snr_sum
2516 1214690 : q_L_snr_sum_ol = q_snr_sum;
2517 1214690 : move32();
2518 1214690 : move16();
2519 :
2520 1214690 : test();
2521 1214690 : test();
2522 1214690 : test();
2523 1214690 : IF( ( EQ_16( st_fx->max_band, 19 ) ) && LT_32( L_snr_outlier_Q4, MAX_SNR_OUTLIER_3_FX ) && GT_16( snr_outlier_index, 3 ) && LT_16( snr_outlier_index, MAX_SNR_OUTLIER_IND_FX ) )
2524 : {
2525 55480 : q_L_snr_sum_ol = s_min( add( norm_l( L_snr_sum_ol ), q_snr_sum ), add( norm_l( L_snr_outlier ), q_snr ) );
2526 55480 : L_tmp1 = L_shl( L_snr_sum_ol, sub( q_L_snr_sum_ol, q_snr_sum ) ); // q_L_snr_sum_ol
2527 55480 : L_tmp2 = L_shl( L_snr_outlier, sub( q_L_snr_sum_ol, q_snr ) ); // q_L_snr_sum_ol
2528 :
2529 55480 : test();
2530 55480 : test();
2531 55480 : IF( LT_32( L_accum_ener_H, Mult_32_16( L_accum_ener_L, INV_OUTLIER_THR_1_FX ) ) /* float:: (accum_ener_L*INV_OUTLIER_THR_1 > accum_ener_H ) !!! */
2532 : || LT_32( L_snr_outlier_Q4, MAX_SNR_OUTLIER_1_FX ) )
2533 :
2534 : {
2535 : /* snr_sum_ol = SNR_OUTLIER_WGHT_1 * ( snr_sum_ol - snr_outlier );
2536 : As SNR_OUTLIER_WGHT_1 is 1.0f we do not need to multiply here , i.e. no need to loose any precisison */
2537 48525 : L_snr_sum_ol = L_sub( L_tmp1, L_tmp2 ); // q_L_snr_sum_ol
2538 : }
2539 6955 : ELSE IF( LT_32( L_accum_ener_H, Mult_32_16( L_accum_ener_L, INV_OUTLIER_THR_2_FX ) ) /* float:: (accum_ener_L *INV_OUTLIER_THR_2 > accum_ener_H ) !!! */
2540 : || LT_32( L_snr_outlier_Q4, MAX_SNR_OUTLIER_2_FX ) )
2541 : {
2542 : /* snr_sum_ol = SNR_OUTLIER_WGHT_2 * (snr_sum_ol - snr_outlier); */
2543 3856 : L_snr_sum_ol = Mpy_32_32( 1084479242 /* 1.01f in Q30 */, L_sub( L_tmp1, L_tmp2 ) ); // q_L_snr_sum_ol+30-31
2544 3856 : q_L_snr_sum_ol = sub( q_L_snr_sum_ol, 1 );
2545 : }
2546 : ELSE
2547 : {
2548 : /* snr_sum_ol = SNR_OUTLIER_WGHT_2 * (snr_sum_ol - snr_outlier); */
2549 3099 : L_snr_sum_ol = Mpy_32_32( 1095216660 /* 1.02f in Q30 */, L_sub( L_tmp1, L_tmp2 ) ); // q_L_snr_sum_ol+30-31
2550 3099 : q_L_snr_sum_ol = sub( q_L_snr_sum_ol, 1 );
2551 : }
2552 : }
2553 : /*st_fx->snr_sum_vad_fx = 0.5f * st->snr_sum_vad + 0.5f * snr_sum_ol;*/
2554 1214690 : q_snr_tmp = s_min( add( hVAD->q_L_snr_sum_vad, norm_l( hVAD->L_snr_sum_vad_fx ) ), add( norm_l( L_snr_sum_ol ), q_L_snr_sum_ol ) );
2555 : /* 0.5f * st->snr_sum_vad */
2556 1214690 : L_tmp1 = L_shl( hVAD->L_snr_sum_vad_fx, sub( sub( q_snr_tmp, 1 ), hVAD->q_L_snr_sum_vad ) ); // q_snr_tmp
2557 : /* 0.5f * snr_sum_ol */
2558 1214690 : L_tmp2 = L_shl( L_snr_sum_ol, sub( sub( q_snr_tmp, 1 ), q_L_snr_sum_ol ) ); // q_snr_tmp
2559 1214690 : hVAD->L_snr_sum_vad_fx = L_add( L_tmp1, L_tmp2 ); // q_snr_tmp
2560 1214690 : hVAD->q_L_snr_sum_vad = q_snr_tmp;
2561 1214690 : move32();
2562 1214690 : move16();
2563 :
2564 : /* snr_sum_ol = 10.0f * (float)log10( snr_sum_ol ); */
2565 1214690 : e_snr = norm_l( L_snr_sum_ol );
2566 1214690 : f_snr = Log2_norm_lc( L_shl( L_snr_sum_ol, e_snr ) ); // Q15
2567 1214690 : e_snr = sub( sub( 30, e_snr ), q_L_snr_sum_ol );
2568 1214690 : L_tmp = L_mac( f_snr, e_snr, ONE_IN_Q14 ); // Q15
2569 1214690 : L_snr_sum_ol = Mpy_32_16_1( L_tmp, 24660 /* 10*log(2) in Q13 */ ); // Q13
2570 1214690 : snr_sum_ol = extract_h( L_shl( L_snr_sum_ol, Q24 - Q13 ) ); // Q8
2571 1214690 : snr_sum = snr_sum_ol;
2572 1214690 : move16(); /* note for NB no outlier modification */
2573 :
2574 : /* snr_sum_HE_SAD = 10.0f * (float)log10( snr_sum_HE_SAD ); */
2575 1214690 : snr_sum_HE_SAD = vad_snr_log_fx( L_snr_sum_HE_SAD, LG10 );
2576 :
2577 1214690 : *snr_sum_he = snr_sum_HE_SAD;
2578 1214690 : move16(); /* *snr_sum_he=snr_sum_HE_SAD; */
2579 :
2580 :
2581 : /*---------------------------------------------------------------------*
2582 : * compute thr1 for SAD decision
2583 : *---------------------------------------------------------------------*/
2584 1214690 : lp_snr = sub( lp_speech_fx, lp_noise_fx ); /*Q8*/
2585 :
2586 1214690 : IF( LT_16( lp_snr, hNoiseEst->sign_dyn_lp_fx ) )
2587 : {
2588 242384 : lp_snr = add( lp_snr, 1 << 8 ); /* lp_snr += 1; */
2589 :
2590 242384 : if ( GT_16( lp_snr, hNoiseEst->sign_dyn_lp_fx ) )
2591 : {
2592 11174 : lp_snr = hNoiseEst->sign_dyn_lp_fx;
2593 11174 : move16();
2594 : }
2595 : }
2596 :
2597 : /*thr1 = nk * lp_snr + nc*1.0 + nv * ( st->Etot_v_h2 - nv_ofs); */ /* Linear function for noisy speech */
2598 :
2599 1214690 : L_tmp = L_shl( Mpy_32_16_1( L_sub( hNoiseEst->Etot_v_h2_32fx, nv_ofs ), nv ), 3 ); // Q24 (24+12-15+3)
2600 1214690 : L_tmp = L_add( L_tmp, nc ); // Q24
2601 1214690 : thr1 = mac_r( L_tmp, lp_snr, nk ); // Q24
2602 :
2603 1214690 : test();
2604 1214690 : IF( st_fx->element_mode > EVS_MONO && LT_16( hNoiseEst->first_noise_updt_cnt, 100 ) )
2605 : {
2606 : /* lower threshold during warmup time */
2607 871456 : thr1 = sub( thr1, 2560 );
2608 871456 : L_vad_thr = 0;
2609 871456 : move32();
2610 : }
2611 :
2612 1214690 : IF( GT_16( lp_snr, (Word16) 20 * ( 1 << 8 ) ) ) /* if (lp_snr > 20.0f )*/
2613 : {
2614 1071924 : test();
2615 1071924 : IF( st_fx->element_mode == EVS_MONO || GE_16( hNoiseEst->first_noise_updt_cnt, 100 ) )
2616 : {
2617 : /* thr1 = thr1 + 0.3f * (lp_snr - 20.0f); */
2618 212856 : thr1 = add( thr1, mult( 9830, sub( lp_snr, (Word16) 20 * ( 1 << 8 ) ) ) ); /* Q15*Q8+1 -16 --> Q8 */
2619 :
2620 212856 : test();
2621 212856 : test();
2622 212856 : test();
2623 212856 : if ( EQ_16( st_fx->max_band, 16 ) && GT_16( lp_snr, 40 * 256 ) && GT_16( thr1, 6600 ) && LT_16( lp_speech_fx, 11520 ) )
2624 : {
2625 1939 : thr1 = 6600;
2626 1939 : move16();
2627 : }
2628 : }
2629 : }
2630 :
2631 :
2632 : /*---------------------------------------------------------------------*
2633 : * WB input
2634 : * SNR threshold computing
2635 : * Hangover control & final VAD decision
2636 : *---------------------------------------------------------------------*/
2637 :
2638 1214690 : IF( vad_bwidth_fx != NB )
2639 : {
2640 :
2641 : /* Outlier Detection first calculates thr1_ol and snr_sum_ol instead of
2642 : modyfying thr1 and snr_sum */
2643 :
2644 1210426 : thr1_ol = thr1;
2645 1210426 : move16();
2646 1210426 : hangover_short = 3;
2647 1210426 : move16();
2648 :
2649 1210426 : IF( LT_16( lp_snr, th_clean ) )
2650 : {
2651 212493 : hangover_short = 4;
2652 212493 : move16();
2653 :
2654 : /* In this section the modified nk, and nc are used */
2655 212493 : test();
2656 212493 : test();
2657 212493 : test();
2658 212493 : test();
2659 212493 : test();
2660 212493 : test();
2661 212493 : test();
2662 212493 : test();
2663 212493 : test(); /*_DIFF_FLOAT_FIX_ -> the conditions around Opt_SC_VBR_fx are invertered compared to float
2664 : ### st_fx->Opt_SC_VBR!=0 vs !st_fx->Opt_SC_VBR #####*/
2665 212493 : test();
2666 212493 : IF( ( LE_16( snr_outlier_index, 4 ) && ( st_fx->last_coder_type > UNVOICED ) && !st_fx->Opt_SC_VBR ) ||
2667 : ( LE_16( snr_outlier_index, 4 ) && ( last_7k2_coder_type > UNVOICED ) && st_fx->Opt_SC_VBR ) )
2668 : {
2669 : /*thr1_ol = thr1 - 1.0f ; */
2670 88935 : thr1_ol = sub( thr1, ONE_IN_Q8 ); // Q8
2671 :
2672 : /*snr_sum_ol = 10.0f * (float)log10( hVAD->L_snr_sum_vad_fx );*/
2673 88935 : e_snr = norm_l( hVAD->L_snr_sum_vad_fx );
2674 88935 : f_snr = Log2_norm_lc( L_shl( hVAD->L_snr_sum_vad_fx, e_snr ) ); // Q15
2675 88935 : e_snr = sub( sub( 30, e_snr ), hVAD->q_L_snr_sum_vad );
2676 88935 : L_tmp = L_mac( f_snr, e_snr, ONE_IN_Q14 ); // Q15
2677 88935 : L_snr_sum_ol = Mpy_32_16_1( L_tmp, 24660 /* 10*log(2) in Q13 */ ); // Q13
2678 88935 : snr_sum_ol = round_fx( L_shl( L_snr_sum_ol, Q24 - Q13 ) ); // Q8
2679 : }
2680 123558 : ELSE IF( ( ( LE_16( st_fx->last_coder_type, UNVOICED ) ) && ( LT_32( L_snr_outlier_Q4, MAX_SNR_OUTLIER_2_FX ) ) && ( st_fx->Opt_SC_VBR == 0 ) ) ||
2681 : ( ( LE_16( last_7k2_coder_type, UNVOICED ) ) && ( LT_32( L_snr_outlier_Q4, MAX_SNR_OUTLIER_2_FX ) ) && ( st_fx->Opt_SC_VBR != 0 ) ) )
2682 : {
2683 : /* thr1_ol = thr1 + (float)(1.0f - 0.04f * snr_outlier); */
2684 15409 : L_tmp = Mpy_32_16_1( L_snr_outlier, 20972 /*0.04f in Q19*/ ); // q_snr+19-15
2685 15409 : L_tmp = L_shl( L_tmp, sub( Q24 - 4, q_snr ) ); // Q24 (24-(q_nsr+4))
2686 15409 : tmp2 = round_fx( L_sub( ONE_IN_Q24, L_tmp ) ); // Q8
2687 15409 : thr1_ol = add( thr1, tmp2 ); // Q8
2688 : }
2689 : ELSE
2690 : {
2691 : /*thr1_ol = thr1 + max(0, (float)(0.6f - 0.01f * snr_outlier)); */
2692 : /* Saturation is added in the below step for 0.04f * snr_outlier in Q24.
2693 : In case of saturation, 0.04f * snr_outlier will be much greater than 0.6f and (0.6f - 0.01f * snr_outlier) becomes negative.
2694 : max(0, (float)(0.6f - 0.01f * snr_outlier)) gives zero. Hence addition of saturation has no impact */
2695 108149 : L_tmp = Mpy_32_16_1( L_snr_outlier, 20972 /*0.04f in Q21*/ ); // q_snr+21-15
2696 108149 : L_tmp = L_shl_sat( L_tmp, sub( Q24 - 6, q_snr ) ); // Q24 (24-(q_nsr+6))
2697 108149 : tmp2 = round_fx( L_sub( 10066330 /* 0.6 in Q24*/, L_tmp ) ); // Q8
2698 108149 : tmp2 = s_max( 0, tmp2 ); // Q8
2699 108149 : thr1_ol = add( thr1, tmp2 ); // Q8
2700 : }
2701 : }
2702 :
2703 : /* apply outlier modification */
2704 1210426 : snr_sum = snr_sum_ol;
2705 1210426 : move16(); /*NB s*/
2706 1210426 : thr1 = thr1_ol;
2707 1210426 : move16();
2708 :
2709 : /* DTX HANGOVER is in pre_proc_fx() */
2710 1210426 : flag_he1 = 0;
2711 1210426 : move16();
2712 1210426 : st_fx->localVAD = 0;
2713 1210426 : move16();
2714 1210426 : IF( EQ_16( BASOP_Util_Cmp_Mant32Exp( L_mssnr, L_mssnr_e, L_vad_thr, 18 ), 1 ) )
2715 : {
2716 1037082 : flag_he1 = 1;
2717 1037082 : move16();
2718 1037082 : st_fx->localVAD = 1;
2719 1037082 : move16();
2720 : /* he1 primary decision */
2721 1037082 : hVAD->nb_active_frames_he1 = add( hVAD->nb_active_frames_he1, 1 ); /* Counter of consecutive active speech frames */
2722 1037082 : move16();
2723 :
2724 1037082 : IF( GE_16( hVAD->nb_active_frames_he1, ACTIVE_FRAMES_FX ) )
2725 : {
2726 1025979 : hVAD->nb_active_frames_he1 = ACTIVE_FRAMES_FX;
2727 1025979 : move16();
2728 1025979 : hVAD->hangover_cnt_he1 = 0;
2729 1025979 : move16(); /* Reset the counter of hangover frames after at least "active_frames" speech frames */
2730 : }
2731 :
2732 : /* inside HO period */
2733 1037082 : test();
2734 1037082 : IF( sub( hVAD->hangover_cnt_he1, HANGOVER_LONG_HE_FX ) < 0 && hVAD->hangover_cnt_he1 != 0 )
2735 : {
2736 10607 : hVAD->hangover_cnt_he1 = add( hVAD->hangover_cnt_he1, 1 );
2737 10607 : move16();
2738 : }
2739 :
2740 1037082 : IF( hVAD->soft_hangover > 0 )
2741 : {
2742 314882 : hVAD->soft_hangover = sub( hVAD->soft_hangover, 1 );
2743 314882 : move16();
2744 : }
2745 : }
2746 : ELSE
2747 : {
2748 : /* Reset the counter of speech frames necessary to start hangover algorithm */
2749 173344 : hVAD->nb_active_frames_he1 = 0;
2750 173344 : move16();
2751 : }
2752 :
2753 :
2754 1210426 : IF( GT_16( hVAD->voiced_burst, 3 ) )
2755 : {
2756 315732 : IF( LT_16( hVAD->bcg_flux_fx, 640 ) ) /* Q4 */
2757 : {
2758 28395 : hVAD->soft_hangover = hangover_sf_tbl[add( snr_idx, 3 )];
2759 28395 : move16();
2760 : }
2761 : ELSE
2762 : {
2763 287337 : hVAD->soft_hangover = hangover_sf_tbl[snr_idx];
2764 287337 : move16();
2765 : }
2766 : }
2767 :
2768 :
2769 1210426 : hangover_hd = hangover_hd_tbl[snr_idx];
2770 1210426 : move16();
2771 :
2772 1210426 : IF( LT_16( hVAD->bcg_flux_fx, 640 ) )
2773 : {
2774 262833 : hangover_hd = add( shr( hangover_hd, 1 ), 1 );
2775 : }
2776 :
2777 : /* VAD hangover for he1 */
2778 1210426 : test();
2779 1210426 : IF( flag_he1 == 0 && hVAD->soft_hangover > 0 )
2780 : {
2781 1875 : IF( EQ_16( BASOP_Util_Cmp_Mant32Exp( L_mssnr_hov, L_mssnr_hov_e, L_vad_thr, 18 ), 1 ) )
2782 : {
2783 930 : flag_he1 = 1;
2784 930 : move16();
2785 930 : hVAD->soft_hangover = sub( hVAD->soft_hangover, 1 );
2786 930 : move16();
2787 : }
2788 : ELSE
2789 : {
2790 945 : hVAD->soft_hangover = 0;
2791 945 : move16();
2792 : }
2793 :
2794 1875 : if ( hVAD->soft_hangover < 0 )
2795 : {
2796 0 : hVAD->soft_hangover = 0;
2797 0 : move16();
2798 : }
2799 : }
2800 :
2801 1210426 : test();
2802 1210426 : test();
2803 1210426 : IF( ( flag_he1 == 0 ) && ( LT_16( hVAD->hangover_cnt_he1, hangover_hd ) ) && ( hVAD->soft_hangover == 0 ) )
2804 : {
2805 7491 : flag_he1 = 1;
2806 7491 : move16();
2807 7491 : hVAD->hangover_cnt_he1 = add( hVAD->hangover_cnt_he1, 1 );
2808 7491 : move16();
2809 : }
2810 :
2811 :
2812 : /* Calculate background stationarity */
2813 1210426 : test();
2814 1210426 : IF( flag_he1 == 0 && hNoiseEst->first_noise_updt > 0 )
2815 : {
2816 157408 : IF( GT_16( snr_sumt, hVAD->bcg_flux_fx ) )
2817 : {
2818 53 : IF( hVAD->bcg_flux_init-- > 0 )
2819 : {
2820 0 : IF( GT_16( snr_sumt, add( hVAD->bcg_flux_fx, 800 ) ) )
2821 : {
2822 : /*st->bcg_flux = 0.9f * st->bcg_flux + (1-0.9f)*(st->bcg_flux+50);*/
2823 0 : hVAD->bcg_flux_fx = mac_r( L_mult( hVAD->bcg_flux_fx, 29491 ), add( hVAD->bcg_flux_fx, 800 ), 3277 ); /*Q4 */
2824 0 : move16();
2825 : }
2826 : ELSE
2827 : {
2828 : /*st->bcg_flux = 0.9f * st->bcg_flux + (1-0.9f)*snr_sumt*/
2829 0 : hVAD->bcg_flux_fx = mac_r( L_mult( hVAD->bcg_flux_fx, 29491 ), snr_sumt, 3277 ); /*Q4 */
2830 0 : move16();
2831 : }
2832 : }
2833 : ELSE
2834 : {
2835 53 : IF( GT_16( snr_sumt, add( hVAD->bcg_flux_fx, 160 ) ) )
2836 : {
2837 : /*st->bcg_flux = 0.99f * st->bcg_flux + (1-0.99f)*(st->bcg_flux+10);*/
2838 0 : hVAD->bcg_flux_fx = mac_r( L_mult( hVAD->bcg_flux_fx, 32440 ), add( hVAD->bcg_flux_fx, 160 ), 328 ); /*Q4 */
2839 0 : move16();
2840 : }
2841 : ELSE
2842 : {
2843 : /*st->bcg_flux = 0.99f * st->bcg_flux + (1-0.99f)*snr_sumt;*/
2844 53 : hVAD->bcg_flux_fx = mac_r( L_mult( hVAD->bcg_flux_fx, 32440 ), snr_sumt, 328 ); /*Q4 */
2845 53 : move16();
2846 : }
2847 : }
2848 : }
2849 : ELSE
2850 : {
2851 157355 : IF( hVAD->bcg_flux_init-- > 0 )
2852 : {
2853 26102 : IF( LT_16( snr_sumt, sub( hVAD->bcg_flux_fx, 480 ) ) )
2854 : {
2855 : /*st->bcg_flux = 0.95f * st->bcg_flux + (1-0.95f)*(st->bcg_flux-30);*/
2856 16961 : hVAD->bcg_flux_fx = mac_r( L_mult( hVAD->bcg_flux_fx, 31131 ), sub( hVAD->bcg_flux_fx, 480 ), 1638 ); /*Q4 */
2857 16961 : move16();
2858 : }
2859 : ELSE
2860 : {
2861 : /*st->bcg_flux = 0.95f * st->bcg_flux + (1-0.95f)*snr_sumt;*/
2862 9141 : hVAD->bcg_flux_fx = mac_r( L_mult( hVAD->bcg_flux_fx, 31131 ), snr_sumt, 1638 ); /*Q4 */
2863 9141 : move16();
2864 : }
2865 : }
2866 : ELSE
2867 : {
2868 131253 : IF( LT_16( snr_sumt, sub( hVAD->bcg_flux_fx, 160 ) ) )
2869 : {
2870 : /*st->bcg_flux = 0.9992f * st->bcg_flux + (1-0.9992f)*(st->bcg_flux-10);*/
2871 12661 : hVAD->bcg_flux_fx = mac_r( L_mult( hVAD->bcg_flux_fx, 32742 ), sub( hVAD->bcg_flux_fx, 160 ), 26 ); /*Q4 */
2872 12661 : move16();
2873 : }
2874 : ELSE
2875 : {
2876 : /*st->bcg_flux = 0.9992f * st->bcg_flux + (1-0.9992f)*snr_sumt;*/
2877 118592 : hVAD->bcg_flux_fx = mac_r( L_mult( hVAD->bcg_flux_fx, 32742 ), snr_sumt, 26 ); /*Q4 */
2878 118592 : move16();
2879 : }
2880 : }
2881 : }
2882 :
2883 157408 : hVAD->bcg_flux_init = s_max( hVAD->bcg_flux_init, 0 );
2884 157408 : move16();
2885 : }
2886 :
2887 1210426 : flag = 0;
2888 1210426 : move16();
2889 1210426 : st_fx->localVAD = 0;
2890 1210426 : move16();
2891 : /* if ( snr_sum > thr1 && flag_he1 == 1 ) */ /* Speech present */
2892 1210426 : test();
2893 :
2894 1210426 : IF( ( GT_16( snr_sum, thr1 ) ) && ( EQ_16( flag_he1, 1 ) ) ) /* Speech present */
2895 : {
2896 1019191 : flag = 1;
2897 1019191 : move16();
2898 1019191 : st_fx->localVAD = 1;
2899 1019191 : move16();
2900 :
2901 1019191 : hVAD->nb_active_frames = add( hVAD->nb_active_frames, 1 ); /* Counter of consecutive active speech frames */
2902 1019191 : move16();
2903 :
2904 1019191 : IF( GE_16( hVAD->nb_active_frames, ACTIVE_FRAMES_FX ) )
2905 : {
2906 1004730 : hVAD->nb_active_frames = ACTIVE_FRAMES_FX;
2907 1004730 : move16();
2908 1004730 : hVAD->hangover_cnt = 0;
2909 1004730 : move16(); /* Reset the counter of hangover frames after at least "active_frames" speech frames */
2910 : }
2911 :
2912 : /* inside HO period */
2913 1019191 : test();
2914 1019191 : IF( LT_16( hVAD->hangover_cnt, HANGOVER_LONG_FX ) && hVAD->hangover_cnt != 0 )
2915 : {
2916 9085 : hVAD->hangover_cnt = add( hVAD->hangover_cnt, 1 );
2917 9085 : move16();
2918 : }
2919 : }
2920 : ELSE
2921 : {
2922 : /* Reset the counter of speech frames necessary to start hangover algorithm */
2923 191235 : hVAD->nb_active_frames = 0;
2924 191235 : move16();
2925 :
2926 191235 : IF( LT_16( hVAD->hangover_cnt, HANGOVER_LONG_FX ) ) /* inside HO period */
2927 : {
2928 38950 : hVAD->hangover_cnt = add( hVAD->hangover_cnt, 1 );
2929 38950 : move16();
2930 : }
2931 :
2932 :
2933 191235 : IF( LE_16( hVAD->hangover_cnt, hangover_short ) ) /* "hard" hangover */
2934 : {
2935 17919 : test();
2936 17919 : test();
2937 17919 : test();
2938 17919 : if ( ( st_fx->element_mode == EVS_MONO ) && ( LT_16( lp_snr, th_clean ) ) && ( st_fx->Opt_SC_VBR != 0 ) && ( GE_16( hVAD->hangover_cnt, 2 ) ) )
2939 : {
2940 0 : *noisy_speech_HO = 1;
2941 0 : move16();
2942 : }
2943 17919 : test();
2944 17919 : test();
2945 17919 : test();
2946 17919 : if ( ( st_fx->element_mode == EVS_MONO ) && ( GE_16( lp_snr, th_clean ) ) && ( st_fx->Opt_SC_VBR != 0 ) && ( GE_16( hVAD->hangover_cnt, 2 ) ) )
2947 : {
2948 0 : *clean_speech_HO = 1;
2949 0 : move16();
2950 : }
2951 17919 : flag = 1;
2952 17919 : move16(); /*HO*/
2953 : }
2954 : }
2955 :
2956 :
2957 : /* localVAD and vad_flag for HE-SAD - in parallel with normal localVAD and vad_flag */
2958 :
2959 1210426 : *localVAD_HE_SAD = 0;
2960 1210426 : move16();
2961 :
2962 1210426 : test();
2963 1210426 : IF( ( GT_16( snr_sum_HE_SAD, thr1 ) ) && ( EQ_16( flag_he1, 1 ) ) ) /* Speech present */
2964 : {
2965 :
2966 1008834 : *localVAD_HE_SAD = 1;
2967 1008834 : move16();
2968 : }
2969 : } /* end of WB SWB */
2970 :
2971 : /*---------------------------------------------------------------------*
2972 : * NB input
2973 : * SNR threshold computing
2974 : * Hangover control & final VAD decision
2975 : *---------------------------------------------------------------------*/
2976 :
2977 : ELSE /* NB input */
2978 : {
2979 : /* Add localVAD_HE_SAD also for NB operation for use with speech music classifier */
2980 4264 : *localVAD_HE_SAD = 0;
2981 4264 : move16();
2982 4264 : if ( GT_16( snr_sum_HE_SAD, thr1 ) )
2983 : {
2984 1756 : *localVAD_HE_SAD = 1;
2985 1756 : move16();
2986 : }
2987 :
2988 4264 : st_fx->localVAD = 0;
2989 4264 : move16(); /* safety inits for fx */
2990 4264 : IF( GT_16( snr_sum, thr1 ) ) /* Speech present, possibly in hangover */
2991 : {
2992 1789 : hVAD->nb_active_frames = add( hVAD->nb_active_frames, 1 ); /* Counter of consecutive active speech frames */
2993 1789 : move16();
2994 1789 : IF( GE_16( hVAD->nb_active_frames, ACTIVE_FRAMES_FX ) )
2995 : {
2996 1438 : hVAD->nb_active_frames = ACTIVE_FRAMES_FX;
2997 1438 : move16();
2998 1438 : hVAD->hangover_cnt = 0;
2999 1438 : move16(); /* Reset the counter of hangover frames after at least "active_frames" speech frames */
3000 : }
3001 :
3002 1789 : st_fx->localVAD = 1;
3003 1789 : move16();
3004 : }
3005 : ELSE
3006 : {
3007 2475 : hVAD->nb_active_frames = 0;
3008 2475 : move16(); /* Reset the counter of speech frames necessary to start hangover algorithm */
3009 : /* st_fx->localVAD = 0; move16(); */ /* set above */
3010 : }
3011 :
3012 4264 : thr1_nb_mod = thr1;
3013 4264 : move16(); /* thr1 may be adjusted after this point */
3014 4264 : IF( LT_16( hVAD->hangover_cnt, HANGOVER_LONG_NB_FX ) )
3015 : {
3016 2466 : hVAD->hangover_cnt = add( hVAD->hangover_cnt, 1 );
3017 2466 : move16();
3018 :
3019 2466 : IF( LT_16( lp_snr, 4864 ) )
3020 : /*19.0f Q8*/ /* very low SNR */
3021 : {
3022 0 : thr1_nb_mod = sub( thr1_nb_mod, 1331 ); /*thr1 -= 5.2f;*/
3023 : }
3024 2466 : ELSE IF( LT_16( lp_snr, 8960 ) ) /*35 in Q8 */ /* low SNR */
3025 : {
3026 0 : thr1_nb_mod = sub( thr1_nb_mod, 512 ); /*thr1 -= 2.0f;*/
3027 : }
3028 : }
3029 :
3030 :
3031 4264 : thr2 = sub( thr1_nb_mod, 384 ); /*thr2 = thr1 - 1.5f; , clean speech */
3032 :
3033 : /* -dtx condition dependency in noisy speech */
3034 4264 : tmp = 333;
3035 4264 : move16(); /* 1.3f; */
3036 4264 : if ( st_fx->Opt_DTX_ON == 0 )
3037 : {
3038 0 : tmp = 282;
3039 0 : move16(); /* 1.10f; */
3040 : }
3041 4264 : IF( LT_16( lp_snr, th_clean ) )
3042 : {
3043 0 : thr2 = sub( thr1_nb_mod, tmp ); /*thr2 = thr1 - [ 1.10 || 1.3 ];*/
3044 : }
3045 :
3046 :
3047 4264 : flag = 0;
3048 4264 : move16();
3049 4264 : IF( GT_16( snr_sum, thr1_nb_mod ) ) /* Speech assumed present, even though lowered thr1 */
3050 : {
3051 1789 : flag = 1;
3052 1789 : move16();
3053 : }
3054 :
3055 :
3056 4264 : test();
3057 4264 : IF( ( LT_16( snr_sum, thr1_nb_mod ) ) && ( GT_16( snr_sum, thr2 ) ) ) /* Speech present */
3058 : {
3059 220 : flag = 1;
3060 220 : move16();
3061 220 : st_fx->localVAD = 0;
3062 220 : move16();
3063 :
3064 220 : if ( st_fx->element_mode == EVS_MONO )
3065 : {
3066 0 : *NB_speech_HO = 1;
3067 0 : move16();
3068 : }
3069 : }
3070 4264 : thr1 = thr1_nb_mod;
3071 4264 : move16(); /* needed for st_fx->vadnoise_fx update below */
3072 : } /* end of NB */
3073 :
3074 :
3075 : /* *flag_noisy_speech_snr is a Word8 parameter */
3076 1214690 : *flag_noisy_speech_snr = 0; /*_DIFF_FLOAT_FIX_ -> this initialisation is not done here in float */
3077 1214690 : move16();
3078 1214690 : IF( vad_bwidth_fx != NB )
3079 : {
3080 1210426 : if ( LT_16( lp_snr, TH16_2_NFLAG_FX ) ) /*now 27, original threshold: 35dB*/
3081 : {
3082 212493 : *flag_noisy_speech_snr = 1;
3083 212493 : move16();
3084 : }
3085 : }
3086 : ELSE
3087 : {
3088 4264 : if ( LT_16( lp_snr, TH8_1_NFLAG_FX ) ) /* now 20.0 */
3089 : {
3090 0 : *flag_noisy_speech_snr = 1;
3091 0 : move16();
3092 : }
3093 : }
3094 :
3095 1214690 : IF( st_fx->hSC_VBR != NULL )
3096 : {
3097 : /* SC-VBR */
3098 0 : st_fx->hSC_VBR->vadsnr_fx = snr_sum;
3099 0 : move16(); /* for ppp, voiced_enc */
3100 0 : st_fx->hSC_VBR->vadnoise_fx = thr1;
3101 0 : move16(); /* used in nb for find_uv */
3102 : }
3103 :
3104 : /* Updates */
3105 1214690 : hVAD->prim_act_quick_fx = mult_r( 26214, hVAD->prim_act_quick_fx ); /*Q15 */
3106 1214690 : move16();
3107 :
3108 1214690 : IF( st_fx->localVAD != 0 )
3109 : {
3110 1020980 : hVAD->prim_act_quick_fx = add( 6554, hVAD->prim_act_quick_fx ); /*Q15 */
3111 1020980 : move16();
3112 : }
3113 :
3114 1214690 : hVAD->prim_act_slow_fx = mult_r( 32440, hVAD->prim_act_slow_fx ); /*Q15 */
3115 1214690 : move16();
3116 :
3117 1214690 : IF( st_fx->localVAD != 0 )
3118 : {
3119 1020980 : hVAD->prim_act_slow_fx = add( 328, hVAD->prim_act_slow_fx ); /*Q15 */
3120 1020980 : move16();
3121 : }
3122 :
3123 1214690 : tmp = hVAD->prim_act_slow_fx; /*Q15*/
3124 1214690 : move16();
3125 1214690 : if ( LE_16( hVAD->prim_act_quick_fx, hVAD->prim_act_slow_fx ) )
3126 : {
3127 197899 : tmp = hVAD->prim_act_quick_fx;
3128 197899 : move16();
3129 : }
3130 : /*st->prim_act = 0.1f * tmp + (1.0f-0.1f)* st->prim_act;*/
3131 1214690 : hVAD->prim_act_fx = mac_r( L_mult( 3277, tmp ), 29491, hVAD->prim_act_fx );
3132 1214690 : move16();
3133 :
3134 1214690 : hVAD->prim_act_quick_he_fx = mult_r( 26214, hVAD->prim_act_quick_he_fx ); /*Q15 */
3135 1214690 : move16();
3136 1214690 : IF( *localVAD_HE_SAD != 0 )
3137 : {
3138 1010590 : hVAD->prim_act_quick_he_fx = add( 6554, hVAD->prim_act_quick_he_fx ); /*Q15 */
3139 1010590 : move16();
3140 : }
3141 :
3142 1214690 : hVAD->prim_act_slow_he_fx = mult_r( 32440, hVAD->prim_act_slow_he_fx ); /*Q15 */
3143 1214690 : move16();
3144 1214690 : IF( *localVAD_HE_SAD != 0 )
3145 : {
3146 1010590 : hVAD->prim_act_slow_he_fx = add( 328, hVAD->prim_act_slow_he_fx ); /*Q15 */
3147 1010590 : move16();
3148 : }
3149 :
3150 1214690 : tmp = hVAD->prim_act_slow_he_fx;
3151 1214690 : move16();
3152 1214690 : if ( LE_16( hVAD->prim_act_quick_he_fx, hVAD->prim_act_slow_he_fx ) )
3153 : {
3154 206305 : tmp = hVAD->prim_act_quick_he_fx;
3155 206305 : move16();
3156 : }
3157 1214690 : hVAD->prim_act_he_fx = mac_r( L_mult( 3277, tmp ), 29491, hVAD->prim_act_he_fx );
3158 1214690 : move16();
3159 :
3160 1214690 : IF( L_and( hVAD->vad_flag_reg_H, (Word32) 0x40000L ) != 0 ) /* 0x4000L = 0x01L << 18 */
3161 : {
3162 869523 : hVAD->vad_flag_cnt_50 = sub( hVAD->vad_flag_cnt_50, 1 );
3163 869523 : move16();
3164 : }
3165 :
3166 1214690 : hVAD->vad_flag_reg_H = L_shl( L_and( hVAD->vad_flag_reg_H, (Word32) 0x3fffffffL ), 1 );
3167 1214690 : move32();
3168 :
3169 1214690 : IF( L_and( hVAD->vad_flag_reg_L, (Word32) 0x40000000L ) != 0 )
3170 : {
3171 907742 : hVAD->vad_flag_reg_H = L_or( hVAD->vad_flag_reg_H, 0x01L );
3172 907742 : move32();
3173 : }
3174 :
3175 1214690 : hVAD->vad_flag_reg_L = L_shl( L_and( hVAD->vad_flag_reg_L, (Word32) 0x3fffffffL ), 1 );
3176 1214690 : move32();
3177 :
3178 1214690 : IF( flag != 0 ) /* should not include the extra DTX hangover */
3179 : {
3180 1039119 : hVAD->vad_flag_reg_L = L_or( hVAD->vad_flag_reg_L, 0x01L );
3181 1039119 : move32();
3182 1039119 : hVAD->vad_flag_cnt_50 = add( hVAD->vad_flag_cnt_50, 1 );
3183 1039119 : move16();
3184 : }
3185 :
3186 :
3187 1214690 : IF( L_and( hVAD->vad_prim_reg, (Word32) 0x8000L ) != 0 ) /* 0x8000L = 1L << 15 */
3188 : {
3189 933763 : hVAD->vad_prim_cnt_16 = sub( hVAD->vad_prim_cnt_16, 1 ); /*Q0*/
3190 933763 : move16();
3191 : }
3192 :
3193 1214690 : hVAD->vad_prim_reg = L_shl( L_and( hVAD->vad_prim_reg, (Word32) 0x3fffffffL ), 1 );
3194 1214690 : move32();
3195 :
3196 1214690 : IF( st_fx->localVAD != 0 )
3197 : {
3198 1020980 : hVAD->vad_prim_reg = L_or( hVAD->vad_prim_reg, 0x01L ); /*Q0*/
3199 1020980 : move32();
3200 1020980 : hVAD->vad_prim_cnt_16 = add( hVAD->vad_prim_cnt_16, 1 ); /*Q0*/
3201 1020980 : move16();
3202 : }
3203 :
3204 1214690 : return flag;
3205 : }
|