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