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