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