Line data Source code
1 : /*====================================================================================
2 : EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0
3 : ====================================================================================*/
4 :
5 : #include <stdlib.h>
6 : #include <assert.h>
7 : #include "options.h"
8 : #include "cnst.h"
9 : // #include "prot_fx.h"
10 : #include "rom_enc.h"
11 : #include "rom_com_fx.h"
12 : #include "rom_com.h"
13 : #include "stl.h"
14 : #include "prot_fx.h" /* Function prototypes */
15 : #include "prot_fx_enc.h" /* Function prototypes */
16 : #ifdef DEBUGGING
17 : #include "debug.h"
18 : #endif
19 : #include <math.h>
20 : #include "ivas_prot_fx.h"
21 :
22 :
23 : /*---------------------------------------------------------------------*
24 : * Local constants
25 : *---------------------------------------------------------------------*/
26 : #define ATT_NSEG 32
27 : #define ATT_SEG_LEN ( L_FRAME / ATT_NSEG )
28 : #define ATT_3LSUB_POS ( 3 * ATT_NSEG / NB_SUBFR )
29 : #define ATT_3LSUB_POS_16k 26 /* (short)((4.0f * ATT_NSEG / (float)NB_SUBFR16k) + 0.5f) */
30 :
31 : #define LOG_PROB_CONST 11292 /*0.5f * N_FEATURES * LOG_PI2 in Q10 */
32 : #define DLP_BIAS 0.138121f
33 : #define DLP_BIAS_FX 36208 /*Q18*/
34 :
35 : #define TON_ALPHA_FX 31130 /* 0.95f in Q15 */
36 : #define THR_MASS_MAX_FX 3565158 /* 0.85f in Q22 */
37 : #define THR_MASS_MIN_FX 3145728 /* 0.75f in Q22 */
38 : #define THR_MASS_STEP_UP_FX 41943 /* 0.01f in Q22 */
39 : #define THR_MASS_STEP_DN_FX 83886 /* 0.02f in Q22 */
40 :
41 : /*---------------------------------------------------------------------*
42 : * Local functions
43 : *---------------------------------------------------------------------*/
44 :
45 : static Word16 sp_mus_classif_gmm_fx( Encoder_State *st_fx, const Word16 localVAD_HE_SAD, const Word16 lsp_new[M], const Word16 cor_map_sum, const Word32 epsP[M + 1], const Word32 PS[], Word16 non_sta, Word16 relE, Word16 *voi_fv, Word16 *cor_map_sum_fv, Word16 *LPCErr, Word16 Q_esp, Word16 *high_lpn_flag_ptr );
46 :
47 :
48 : static void sp_mus_classif_2nd_fx( Encoder_State *st, const Word16 Etot, Word16 *attack_flag, const Word16 *inp, const Word16 Qx );
49 :
50 : static void music_mixed_classif_improv_fx( Encoder_State *st, const Word16 *new_inp, const Word32 *epsP, Word16 Q_epsP, Word16 etot, Word16 old_cor, Word16 cor_map_sum );
51 :
52 : static void tonal_context_improv_fx( Encoder_State *st_fx, const Word32 PS[], const Word16 voi_fv, const Word16 cor_map_sum_fv, const Word16 LPCErr, const Word16 Qx );
53 :
54 : static void var_cor_calc_fx( const Word16 old_corr, Word16 *mold_corr, Word16 var_cor_t[], Word16 *high_stable_cor );
55 :
56 : static Word16 attack_det_fx( const Word16 *inp, const Word16 Qx, const Word16 last_clas, const Word16 localVAD, const Word16 coder_type, const Word32 total_brate );
57 :
58 : static void order_spectrum_fx( Word16 *vec, Word16 len );
59 :
60 : static void detect_sparseness_fx( Encoder_State *st_fx, const Word16 localVAD_HE_SAD, const Word16 voi_fv );
61 : // Q18
62 : Word32 log_weights_speech_compute[N_SMC_MIXTURES] = {
63 : -578045, -483403, -473370, -468152, -379470, -473234
64 : };
65 : Word32 log_weights_music_compute[N_SMC_MIXTURES] = {
66 : -486797, -522830, -315523, -429999, -775981, -477255
67 : };
68 : Word32 log_weights_noise_compute[N_SMC_MIXTURES] = {
69 : -439941, -576743, -269243, -645452, -529228, -542196
70 : };
71 : /*---------------------------------------------------------------------*
72 : * speech_music_clas_init_fx()
73 : *
74 : * Initialization of speech/music classifier
75 : *---------------------------------------------------------------------*/
76 :
77 3 : void speech_music_clas_init_fx(
78 : SP_MUS_CLAS_HANDLE hSpMusClas /* i/o: speech/music classifier handle */
79 : )
80 : {
81 : Word16 i;
82 :
83 :
84 3 : hSpMusClas->inact_cnt = 0;
85 3 : move16();
86 3 : set16_fx( hSpMusClas->past_dec, 0, HANG_LEN - 1 );
87 3 : set16_fx( hSpMusClas->past_dlp_fx, 0, HANG_LEN - 1 );
88 3 : set16_fx( hSpMusClas->past_log_enr_fx, -1448, NB_BANDS_SPMUS ); /* log(E_MIN) in Q8 */
89 :
90 3 : hSpMusClas->sp_mus_state = -8;
91 3 : move16();
92 3 : hSpMusClas->wdrop_fx = 0;
93 3 : move16();
94 3 : hSpMusClas->wdlp_0_95_sp_fx = 0;
95 3 : move16();
96 3 : set16_fx( hSpMusClas->last_lsp_fx, 0, M_LSP_SPMUS );
97 3 : hSpMusClas->last_cor_map_sum_fx = 0;
98 3 : move16();
99 3 : hSpMusClas->last_non_sta_fx = 0;
100 3 : move16();
101 3 : set32_fx( hSpMusClas->past_PS_fx, 0, HIGHEST_FBIN - LOWEST_FBIN );
102 3 : hSpMusClas->past_ps_diff_fx = 0;
103 3 : move16();
104 3 : hSpMusClas->past_epsP2_fx = 1024;
105 3 : move16();
106 :
107 :
108 3 : hSpMusClas->gsc_thres_fx[0] = TH_0_MIN_FX;
109 3 : move16();
110 3 : hSpMusClas->gsc_thres_fx[1] = TH_1_MIN_FX;
111 3 : move16();
112 3 : hSpMusClas->gsc_thres_fx[2] = TH_2_MIN_FX;
113 3 : move16();
114 3 : hSpMusClas->gsc_thres_fx[3] = TH_3_MIN_FX;
115 3 : move16();
116 3 : set16_fx( hSpMusClas->gsc_lt_diff_etot_fx, 0, 40 );
117 3 : hSpMusClas->gsc_mem_etot_fx = 0;
118 3 : move16();
119 3 : hSpMusClas->gsc_last_music_flag = 0;
120 3 : move16();
121 3 : hSpMusClas->gsc_nb_thr_1 = 0;
122 3 : move16();
123 3 : hSpMusClas->gsc_nb_thr_3 = 0;
124 3 : move16();
125 3 : hSpMusClas->mold_corr_fx = 29491;
126 3 : move16();
127 3 : hSpMusClas->mean_avr_dyn_fx = 64;
128 3 : move16(); /*Q7 */
129 3 : hSpMusClas->last_sw_dyn_fx = 2560;
130 3 : move16();
131 : /* speech/music classifier improvement */
132 183 : FOR( i = 0; i < BUF_LEN; i++ )
133 : {
134 180 : hSpMusClas->buf_flux_fx[i] = -12800;
135 180 : move16(); /*-100.0 in Q7 */
136 180 : hSpMusClas->buf_pkh_fx[i] = 0;
137 180 : move16();
138 180 : hSpMusClas->buf_epsP_tilt_fx[i] = 0;
139 180 : move16();
140 180 : hSpMusClas->buf_cor_map_sum_fx[i] = 0;
141 180 : move16();
142 180 : hSpMusClas->buf_Ntonal_fx[i] = 0;
143 180 : move16();
144 180 : hSpMusClas->buf_Ntonal2_fx[i] = 0;
145 180 : move16();
146 180 : hSpMusClas->buf_Ntonal_lf_fx[i] = 0;
147 180 : move16();
148 : }
149 :
150 3 : set16_fx( hSpMusClas->lpe_buf_fx, 0, HANG_LEN_INIT );
151 3 : set16_fx( hSpMusClas->voicing_buf_fx, 0, HANG_LEN_INIT );
152 3 : hSpMusClas->gsc_hangover = 0;
153 3 : move16();
154 3 : set16_fx( hSpMusClas->sparse_buf_fx, 0, HANG_LEN_INIT );
155 3 : set16_fx( hSpMusClas->hf_spar_buf_fx, 0, HANG_LEN_INIT );
156 3 : hSpMusClas->LT_sparse_fx = 0;
157 3 : move16();
158 3 : hSpMusClas->gsc_cnt = 0;
159 3 : move16();
160 3 : set16_fx( hSpMusClas->old_Bin_E_fx, 0, 3 * N_OLD_BIN_E );
161 3 : set16_fx( hSpMusClas->buf_etot_fx, 0, 4 );
162 3 : set16_fx( hSpMusClas->buf_dlp_fx, 0, 10 );
163 :
164 3 : hSpMusClas->UV_cnt1 = 300;
165 3 : move16();
166 3 : hSpMusClas->LT_UV_cnt1_fx = 16000;
167 3 : move16(); /*250.0f in Q6 */
168 3 : hSpMusClas->onset_cnt = 0;
169 3 : move16();
170 3 : hSpMusClas->attack_hangover = 0;
171 3 : move16();
172 3 : hSpMusClas->dec_mov_fx = 0;
173 3 : move16();
174 3 : hSpMusClas->dec_mov1_fx = 0;
175 3 : move16();
176 3 : hSpMusClas->mov_log_max_spl_fx = 25600;
177 3 : move16(); /*200.0 in Q7 */
178 3 : hSpMusClas->old_lt_diff_fx[0] = 0;
179 3 : move16();
180 3 : hSpMusClas->old_lt_diff_fx[1] = 0;
181 3 : move16();
182 :
183 : /* GSC - pitch excitation parameters */
184 3 : hSpMusClas->high_stable_cor = 0;
185 3 : move16();
186 3 : set16_fx( hSpMusClas->var_cor_t_fx, 0, VAR_COR_LEN );
187 :
188 3 : hSpMusClas->lps_fx = 0;
189 3 : move16();
190 3 : hSpMusClas->lpm_fx = 0;
191 3 : move16();
192 3 : hSpMusClas->lt_dec_thres_fx = 5120;
193 3 : move16(); /*10 in Q9 */
194 3 : hSpMusClas->ener_RAT_fx = 0;
195 3 : move16();
196 :
197 : /* speech/music classification */
198 3 : set16_fx( hSpMusClas->lt_old_mode, 1, 3 );
199 3 : hSpMusClas->lt_voicing = 16384 /*0.5f Q15*/;
200 3 : move16();
201 3 : hSpMusClas->lt_corr = 16384 /*0.5f Q15*/;
202 3 : move16();
203 3 : hSpMusClas->lt_tonality = 0;
204 3 : move32();
205 3 : set16_fx( hSpMusClas->lt_corr_pitch, 0, 3 );
206 3 : hSpMusClas->lt_hangover = 0;
207 3 : move16();
208 3 : hSpMusClas->lowrate_pitchGain = 0;
209 3 : move16();
210 :
211 :
212 3 : hSpMusClas->lt_music_hangover = 0;
213 3 : move16();
214 3 : set16_fx( hSpMusClas->tonality2_buf_fx, 0, HANG_LEN_INIT );
215 3 : set16_fx( hSpMusClas->tonality3_buf_fx, 0, HANG_LEN_INIT );
216 3 : set16_fx( hSpMusClas->LPCErr_buf_fx, 0, HANG_LEN_INIT );
217 3 : hSpMusClas->lt_music_state = 0;
218 3 : move16();
219 3 : hSpMusClas->lt_speech_state = 0;
220 3 : move16();
221 3 : hSpMusClas->lt_speech_hangover = 0;
222 3 : move16();
223 :
224 :
225 3 : return;
226 : }
227 :
228 9532 : void speech_music_clas_init_ivas_fx(
229 : SP_MUS_CLAS_HANDLE hSpMusClas /* i/o: speech/music classifier handle */
230 : )
231 : {
232 : Word16 i;
233 :
234 9532 : set32_fx( hSpMusClas->FV_st_fx, 0, N_SMC_FEATURES );
235 :
236 9532 : hSpMusClas->inact_cnt = 0;
237 9532 : move16();
238 9532 : set16_fx( hSpMusClas->past_dec, 0, HANG_LEN - 1 );
239 9532 : set16_fx( hSpMusClas->past_dlp_fx, 0, HANG_LEN - 1 );
240 :
241 9532 : set32_fx( hSpMusClas->past_dlp_mean_ST_fx, 0, HANG_LEN - 1 );
242 9532 : hSpMusClas->dlp_mean_ST_fx = 0;
243 9532 : move32();
244 9532 : hSpMusClas->dlp_mean_LT_fx = 0;
245 9532 : move32();
246 9532 : hSpMusClas->dlp_var_LT_fx = 0;
247 9532 : move32();
248 :
249 152512 : FOR( i = 0; i < N_SMC_FEATURES; i++ )
250 : {
251 142980 : hSpMusClas->prev_FV_fx[i] = L_add( L_shr( hout_intervals_fx[2 * i], 1 ), L_shr( hout_intervals_fx[2 * i + 1], 1 ) );
252 142980 : move32();
253 : }
254 :
255 152512 : FOR( i = 0; i < NB_BANDS_SPMUS; i++ )
256 : {
257 142980 : hSpMusClas->past_log_enr_fx[i] = -1448; /* log(E_MIN) in Q8 */
258 142980 : move16();
259 : }
260 :
261 9532 : hSpMusClas->sp_mus_state = -8;
262 9532 : move16();
263 9532 : hSpMusClas->wdrop_32fx = 0;
264 9532 : move32();
265 9532 : hSpMusClas->wrise_fx = 0;
266 9532 : move16();
267 9532 : hSpMusClas->wdlp_0_95_sp_fx = 0;
268 9532 : move16();
269 9532 : hSpMusClas->wdlp_0_95_sp_32fx = 0;
270 9532 : move32();
271 9532 : hSpMusClas->wdlp_xtalk_fx = 0;
272 9532 : move16();
273 9532 : set16_fx( hSpMusClas->last_lsp_fx, 0, M_LSP_SPMUS );
274 9532 : hSpMusClas->last_cor_map_sum_fx = 0;
275 9532 : move16();
276 9532 : hSpMusClas->last_non_sta_fx = 0;
277 9532 : move16();
278 9532 : set32_fx( hSpMusClas->past_PS_fx, 0, HIGHEST_FBIN - LOWEST_FBIN );
279 9532 : hSpMusClas->past_PS_Q = Q31;
280 9532 : move16();
281 9532 : hSpMusClas->past_ps_diff_fx = 0;
282 9532 : move16();
283 9532 : hSpMusClas->past_epsP2_fx = 1024; /* 1.0f in Q10 */
284 9532 : move16();
285 9532 : hSpMusClas->past_epsP_fx = 0;
286 9532 : move16();
287 9532 : hSpMusClas->flag_spitch_cnt = 0;
288 9532 : move16();
289 :
290 :
291 9532 : hSpMusClas->gsc_thres_fx[0] = TH_0_MIN_FX;
292 9532 : move16();
293 9532 : hSpMusClas->gsc_thres_fx[1] = TH_1_MIN_FX;
294 9532 : move16();
295 9532 : hSpMusClas->gsc_thres_fx[2] = TH_2_MIN_FX;
296 9532 : move16();
297 9532 : hSpMusClas->gsc_thres_fx[3] = TH_3_MIN_FX;
298 9532 : move16();
299 9532 : set16_fx( hSpMusClas->gsc_lt_diff_etot_fx, 0, 40 );
300 9532 : hSpMusClas->gsc_mem_etot_fx = 0;
301 9532 : move16();
302 9532 : hSpMusClas->gsc_last_music_flag = 0;
303 9532 : move16();
304 9532 : hSpMusClas->gsc_nb_thr_1 = 0;
305 9532 : move16();
306 9532 : hSpMusClas->gsc_nb_thr_3 = 0;
307 9532 : move16();
308 9532 : hSpMusClas->mold_corr_fx = 29491; /* 0.9f in Q15 */
309 9532 : move16();
310 9532 : hSpMusClas->mean_avr_dyn_fx = 64; /* 0.5f in Q7 */
311 9532 : move16();
312 9532 : hSpMusClas->last_sw_dyn_fx = 2560; /* 10.0f in Q7 */
313 9532 : move16();
314 :
315 9532 : hSpMusClas->relE_attack_cnt = 0;
316 9532 : move16();
317 9532 : hSpMusClas->prev_relE_fx = 0;
318 9532 : move16();
319 9532 : hSpMusClas->prev_Etot_fx = 0;
320 9532 : move16();
321 9532 : hSpMusClas->prev_vad = 0;
322 9532 : move16();
323 9532 : hSpMusClas->vad_0_1_cnt = 0;
324 9532 : move16();
325 9532 : hSpMusClas->relE_attack_sum_fx = 0;
326 9532 : move16();
327 :
328 : /* speech/music classifier improvement */
329 581452 : FOR( i = 0; i < BUF_LEN; i++ )
330 : {
331 571920 : hSpMusClas->buf_flux_fx[i] = -12800; /*-100.0f in Q7 */
332 571920 : move16();
333 571920 : hSpMusClas->buf_pkh_fx[i] = 0;
334 571920 : move16();
335 571920 : hSpMusClas->buf_epsP_tilt_fx[i] = 0;
336 571920 : move16();
337 571920 : hSpMusClas->buf_cor_map_sum_fx[i] = 0;
338 571920 : move16();
339 571920 : hSpMusClas->buf_Ntonal_fx[i] = 0;
340 571920 : move16();
341 571920 : hSpMusClas->buf_Ntonal2_fx[i] = 0;
342 571920 : move16();
343 571920 : hSpMusClas->buf_Ntonal_lf_fx[i] = 0;
344 571920 : move16();
345 : }
346 :
347 9532 : set16_fx( hSpMusClas->lpe_buf_fx, 0, HANG_LEN_INIT );
348 9532 : set16_fx( hSpMusClas->voicing_buf_fx, 0, HANG_LEN_INIT );
349 9532 : hSpMusClas->gsc_hangover = 0;
350 9532 : move16();
351 9532 : set16_fx( hSpMusClas->sparse_buf_fx, 0, HANG_LEN_INIT );
352 9532 : set16_fx( hSpMusClas->hf_spar_buf_fx, 0, HANG_LEN_INIT );
353 9532 : hSpMusClas->LT_sparse_fx = 0;
354 9532 : move16();
355 9532 : hSpMusClas->gsc_cnt = 0;
356 9532 : move16();
357 9532 : hSpMusClas->last_vad_spa = 0;
358 9532 : move16();
359 :
360 9532 : set16_fx( hSpMusClas->old_Bin_E_fx, 0, 3 * N_OLD_BIN_E );
361 9532 : set16_fx( hSpMusClas->buf_etot_fx, 0, 4 );
362 9532 : set16_fx( hSpMusClas->buf_dlp_fx, 0, 10 );
363 :
364 9532 : hSpMusClas->UV_cnt1 = 300;
365 9532 : move16();
366 9532 : hSpMusClas->LT_UV_cnt1_fx = 16000; /* 250.0f in Q6 */
367 9532 : move16();
368 9532 : hSpMusClas->onset_cnt = 0;
369 9532 : move16();
370 9532 : hSpMusClas->attack_hangover = 0;
371 9532 : move16();
372 9532 : hSpMusClas->dec_mov_fx = 0;
373 9532 : move16();
374 9532 : hSpMusClas->dec_mov1_fx = 0;
375 9532 : move16();
376 9532 : hSpMusClas->mov_log_max_spl_fx = 25600; /* 200.0 in Q7 */
377 9532 : move16();
378 9532 : hSpMusClas->old_lt_diff_fx[0] = 0;
379 9532 : move16();
380 9532 : hSpMusClas->old_lt_diff_fx[1] = 0;
381 9532 : move16();
382 :
383 9532 : set32_fx( hSpMusClas->finc_prev_fx, 0, ATT_NSEG );
384 9532 : hSpMusClas->q_finc_prev = Q31;
385 9532 : move16();
386 9532 : hSpMusClas->lt_finc_fx = 0;
387 9532 : move32();
388 9532 : hSpMusClas->Q_lt_finc = Q31;
389 9532 : move16();
390 :
391 9532 : hSpMusClas->last_strong_attack = 0;
392 9532 : move16();
393 9532 : hSpMusClas->tdm_lt_Etot_fx = 3; /* 0.01f in Q8 */
394 9532 : move16();
395 9532 : set32_fx( hSpMusClas->tod_lt_Bin_E_fx, 0, TOD_NSPEC );
396 9532 : hSpMusClas->Q_tod_lt_Bin_E = Q31;
397 9532 : move16();
398 9532 : set32_fx( hSpMusClas->tod_S_map_lt_fx, 0, TOD_NSPEC );
399 9532 : hSpMusClas->tod_thr_lt_fx = TOD_THR_MASS_FX_Q22;
400 9532 : move32();
401 9532 : hSpMusClas->tod_weight_fx = 0;
402 9532 : move16();
403 9532 : hSpMusClas->tod_S_mass_prev_fx = 0;
404 9532 : move32();
405 9532 : hSpMusClas->tod_S_mass_lt_fx = 0;
406 9532 : move32();
407 :
408 : /* speech/music classification */
409 9532 : set16_fx( hSpMusClas->lt_old_mode, 1, 3 );
410 9532 : hSpMusClas->lt_voicing = 16384; /* 0.5f in Q15 */
411 9532 : move16();
412 9532 : hSpMusClas->lt_corr = 16384; /* 0.5f in Q15 */
413 9532 : move16();
414 9532 : hSpMusClas->lt_tonality = 0;
415 9532 : move32();
416 9532 : set16_fx( hSpMusClas->lt_corr_pitch, 0, 3 );
417 9532 : hSpMusClas->lt_hangover = 0;
418 9532 : move16();
419 9532 : hSpMusClas->lowrate_pitchGain = 0;
420 9532 : move16();
421 :
422 9532 : hSpMusClas->lt_music_hangover = 0;
423 9532 : move16();
424 9532 : set16_fx( hSpMusClas->tonality2_buf_fx, 0, HANG_LEN_INIT );
425 9532 : set16_fx( hSpMusClas->tonality3_buf_fx, 0, HANG_LEN_INIT );
426 9532 : set16_fx( hSpMusClas->LPCErr_buf_fx, 0, HANG_LEN_INIT );
427 9532 : hSpMusClas->lt_music_state = 0;
428 9532 : move16();
429 9532 : hSpMusClas->lt_speech_state = 0;
430 9532 : move16();
431 9532 : hSpMusClas->lt_speech_hangover = 0;
432 9532 : move16();
433 :
434 9532 : hSpMusClas->lt_dec_thres_fx = 5120; /* 10.0f in Q9 */
435 9532 : move16();
436 9532 : hSpMusClas->ener_RAT_fx = 0;
437 9532 : move16();
438 :
439 9532 : hSpMusClas->high_stable_cor = 0;
440 9532 : move16();
441 9532 : set16_fx( hSpMusClas->var_cor_t_fx, 0, VAR_COR_LEN );
442 :
443 9532 : hSpMusClas->lps_fx = 0;
444 9532 : move16();
445 9532 : hSpMusClas->lpm_fx = 0;
446 9532 : move16();
447 9532 : hSpMusClas->lpn_fx = 0;
448 9532 : move16();
449 :
450 9532 : return;
451 : }
452 :
453 : /*---------------------------------------------------------------------*
454 : * speech_music_classif()
455 : *
456 : * Speech/music classification
457 : *
458 : * The following technologies are used based on the outcome of the sp/mus classifier
459 : * sp_aud_decision1 sp_aud_decision2
460 : * 0 0 use ACELP (+TD BWE)
461 : * 1 0 use ACELP (+FD BWE) or HQ/LR-MDCT depending on bitrate
462 : * 1 1 use GSC (+FD BWE) or HQ/LR-MDCT depending on bitrate
463 : *
464 : * 0 1 exceptionally use GSC (+FD BWE) instead of LR-MDCT at 13.2 kbps (WB/SWB) for sparse spectra
465 : *---------------------------------------------------------------------*/
466 :
467 3100 : void speech_music_classif_fx(
468 : Encoder_State *st, /* i/o: state structure */
469 : const Word16 *new_inp, /* i : new input signal */
470 : const Word16 *inp, /* i : input signal to locate attach position */
471 : const Word16 localVAD_HE_SAD, /* i : HE-SAD flag without hangover */
472 : const Word16 lsp_new[M], /* i : LSPs in current frame Q15 */
473 : const Word16 cor_map_sum, /* i : correlation map sum (from multi-harmonic anal.)Q8*/
474 : const Word32 epsP[M + 1], /* i : LP prediciton error Q_esp*/
475 : const Word32 PS[], /* i : energy spectrum Q_new+QSCALE*/
476 : const Word16 Etot, /* i : total frame energy Q8 */
477 : const Word16 old_cor, /* i : max correlation from previous frame Q15 */
478 : Word16 *attack_flag, /* o : flag to indicate if attack is to be treated by TC or GSC */
479 : Word16 non_sta, /* i : unbound non-stationarity for sp/mus classifier */
480 : Word16 relE, /* i : relative frame energy */
481 : Word16 Q_esp, /* i : scaling of esP */
482 : Word16 Q_inp, /* i : scaling of input */
483 : Word16 *high_lpn_flag_ptr, /* o : noise log prob flag for NOISE_EST */
484 : Word16 flag_spitch /* i : flag to indicate very short stable pitch */
485 : )
486 : {
487 : Word16 voi_fv, cor_map_sum_fv, LPCErr;
488 3100 : GSC_ENC_HANDLE hGSCEnc = st->hGSCEnc;
489 :
490 : /* 1st stage speech/music classifier based on the GMM model */
491 3100 : st->sp_aud_decision1 = sp_mus_classif_gmm_fx( st, localVAD_HE_SAD, lsp_new, cor_map_sum,
492 : epsP, PS, non_sta, relE, &voi_fv, &cor_map_sum_fv, &LPCErr, Q_esp, high_lpn_flag_ptr );
493 :
494 3100 : test();
495 3100 : IF( EQ_16( st->codec_mode, MODE1 ) || EQ_32( st->sr_core, INT_FS_12k8 ) )
496 : {
497 :
498 :
499 : /* Improvement of the 1st stage decision on mixed/music content */
500 2050 : test();
501 2050 : IF( st->Opt_SC_VBR == 0 && NE_32( st->total_brate, ACELP_24k40 ) )
502 : {
503 2050 : music_mixed_classif_improv_fx( st, new_inp, epsP, Q_esp, Etot, old_cor, cor_map_sum );
504 : }
505 :
506 2050 : st->sp_aud_decision0 = st->sp_aud_decision1;
507 2050 : move16();
508 :
509 : /* 2nd stage speech/music classifier (rewrite music to speech in onsets) */
510 2050 : st->sp_aud_decision2 = st->sp_aud_decision1;
511 2050 : move16();
512 :
513 2050 : IF( st->bwidth > NB )
514 : {
515 2050 : sp_mus_classif_2nd_fx( st, Etot, attack_flag, inp, Q_inp - 1 );
516 :
517 : /* avoid switch to AUDIO/MUSIC class for very short stable high st->pitch
518 : and/or stable pitch with high correlation at low bitrates*/
519 2050 : test();
520 2050 : test();
521 2050 : IF( flag_spitch && EQ_16( st->bwidth, WB ) && LT_32( st->total_brate, ACELP_13k20 ) )
522 : {
523 0 : st->sp_aud_decision2 = 0;
524 0 : move16();
525 : }
526 : }
527 :
528 :
529 : /* Context-based improvement of 1st and 2nd stage decision on stable tonal signals */
530 2050 : test();
531 2050 : IF( st->Opt_SC_VBR == 0 && NE_32( st->total_brate, ACELP_24k40 ) )
532 : {
533 2050 : tonal_context_improv_fx( st, PS, voi_fv, cor_map_sum_fv, LPCErr, Q_inp + QSCALE - 2 );
534 : }
535 :
536 : /* Avoid using LR-MDCT on sparse spectra, use GSC instead at 13.2 kbps (WB/SWB) */
537 2050 : test();
538 2050 : test();
539 2050 : test();
540 2050 : test();
541 2050 : IF( !st->Opt_SC_VBR && EQ_32( st->total_brate, ACELP_13k20 ) && EQ_16( st->vad_flag, 1 ) &&
542 : ( EQ_16( st->bwidth, WB ) || EQ_16( st->bwidth, SWB ) ) )
543 : {
544 1041 : detect_sparseness_fx( st, localVAD_HE_SAD, voi_fv );
545 : }
546 :
547 : /* override speech/music classification to ACELP when background noise level reaches certain level */
548 : /* this is a patch against mis-classifications during active noisy speech segments */
549 2050 : IF( GT_16( st->lp_noise_fx, 3072 ) )
550 : {
551 0 : st->sp_aud_decision1 = 0;
552 0 : move16();
553 0 : st->sp_aud_decision2 = 0;
554 0 : move16();
555 : }
556 :
557 :
558 : /* select GSC on SWB noisy speech (only on active unvoiced SWB noisy speech segments) */
559 2050 : st->GSC_noisy_speech = 0;
560 2050 : move16();
561 :
562 2050 : test();
563 2050 : test();
564 2050 : test();
565 2050 : test();
566 2050 : test();
567 2050 : test();
568 2050 : IF( EQ_16( st->vad_flag, 1 ) && GE_32( st->total_brate, ACELP_13k20 ) && LT_32( st->total_brate, ACELP_24k40 ) &&
569 : GT_16( st->lp_noise_fx, 3072 ) && st->sp_aud_decision1 == 0 && GE_16( st->bwidth, SWB ) &&
570 : EQ_16( st->coder_type_raw, UNVOICED ) )
571 : {
572 0 : st->GSC_noisy_speech = 1;
573 0 : move16();
574 : }
575 :
576 : /* Select AUDIO frames */
577 2050 : test();
578 2050 : test();
579 : #ifdef DEBUGGING
580 : if ( st->codec_mode == MODE1 && ( st->force == 1 || ( st->force == -1 && ( st->sp_aud_decision2 || st->GSC_noisy_speech ) ) ) )
581 : #else
582 2050 : IF( EQ_16( st->codec_mode, MODE1 ) && ( st->sp_aud_decision2 || st->GSC_noisy_speech ) )
583 : #endif
584 : {
585 622 : st->coder_type = AUDIO;
586 622 : move16();
587 622 : hGSCEnc->noise_lev = NOISE_LEVEL_SP0;
588 622 : move16();
589 : }
590 : }
591 : ELSE
592 : {
593 1050 : st->sp_aud_decision0 = st->sp_aud_decision1;
594 1050 : move16();
595 : }
596 :
597 :
598 3100 : return;
599 : }
600 :
601 : /*---------------------------------------------------------------------*
602 : * sp_mus_classif_gmm_fx()
603 : *
604 : * Speech/music classification based on GMM model
605 : *---------------------------------------------------------------------*/
606 :
607 3100 : static Word16 sp_mus_classif_gmm_fx( /* o : decision flag (1-music, 0-speech or noise) */
608 : Encoder_State *st_fx, /* i/o: state structure */
609 : const Word16 localVAD_HE_SAD, /* i : local VAD HE flag */
610 : const Word16 lsp_new[M], /* i : LSPs in current frame Q15 */
611 : const Word16 cor_map_sum, /* i : correlation map sum (from multi-harmonic anal.)Q8 */
612 : const Word32 epsP[M + 1], /* i : LP prediciton error Q_esp */
613 : const Word32 PS[], /* i : energy spectrum Q_new+Qscale-2 */
614 : Word16 non_sta, /* i : unbound non-stationarity for sp/mus classifier */
615 : Word16 relE, /* i : relative frame energy */
616 : Word16 *voi_fv, /* o : scaled voicing feature */
617 : Word16 *cor_map_sum_fv, /* o : scaled correlation map feature */
618 : Word16 *LPCErr, /* o : scaled LP prediction error feature */
619 : Word16 Q_esp, /* i : scaling of epsP */
620 : Word16 *high_lpn_flag_ptr /* o : noise log prob flag for NOISE_EST */
621 : )
622 : {
623 : Word16 i, k, p, dec, vad;
624 :
625 3100 : Word16 lsp[M], FV[N_FEATURES], *pFV = FV;
626 : const Word32 *pSF_a;
627 : const Word16 *pSF_m;
628 : Word16 lsf2acos_fact, wrelE, dlp, wdrop, wght;
629 :
630 : Word32 mx;
631 : Word32 sum_PS;
632 : Word16 ftmp, tmp16;
633 : Word16 xm[N_FEATURES];
634 : Word16 lps, lpm;
635 : Word16 lpn;
636 : Word16 e_tmp, f_tmp;
637 : Word32 L_tmp;
638 : Word16 exp1;
639 : Word32 ps_sta;
640 : Word32 ps_diff;
641 : Word16 ps_diff_16;
642 : Word32 dPS[128], PS_norm[128];
643 : Word32 lepsP1;
644 3100 : Word32 max_s = 0, max_m = 0, py_s, py_m;
645 3100 : move32();
646 3100 : move32();
647 : Word32 max_n, py_n; /* pyn */
648 3100 : Word16 ishift[12] = { 8, 0, 2, 2, 2, 2, 2, 1, 0, 2, 2, 1 };
649 3100 : move16();
650 3100 : move16();
651 3100 : move16();
652 3100 : move16();
653 3100 : move16();
654 3100 : move16();
655 3100 : move16();
656 3100 : move16();
657 3100 : move16();
658 3100 : move16();
659 3100 : move16();
660 3100 : move16();
661 : Word16 tmp;
662 : Word16 tmp1, tmp2, exp2, scale, exp3;
663 3100 : SP_MUS_CLAS_HANDLE hSpMusClas = st_fx->hSpMusClas;
664 3100 : HQ_ENC_HANDLE hHQ_core = st_fx->hHQ_core;
665 : #ifndef ISSUE_1867_replace_overflow_libenc
666 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
667 : Flag Overflow = 0;
668 : move16();
669 : #endif
670 : #endif
671 :
672 : /*------------------------------------------------------------------*
673 : * Initialization
674 : *------------------------------------------------------------------*/
675 :
676 3100 : vad = localVAD_HE_SAD;
677 3100 : move16();
678 :
679 : /*------------------------------------------------------------------*
680 : * Preparation of the feature vector
681 : *------------------------------------------------------------------*/
682 :
683 : /* [0] OL pitch Q0 */
684 : /*(float)(pitch[0] + pitch[1] + pitch[2]) / 3.0f;*/
685 3100 : L_tmp = L_mult( st_fx->pitch[0], 10923 );
686 3100 : L_tmp = L_mac( L_tmp, st_fx->pitch[1], 10923 );
687 3100 : L_tmp = L_mac( L_tmp, st_fx->pitch[2], 10923 );
688 :
689 3100 : test();
690 3100 : IF( EQ_16( st_fx->tc_cnt, 1 ) || EQ_16( st_fx->tc_cnt, 2 ) )
691 : {
692 260 : *pFV++ = st_fx->pitch[2];
693 260 : move16();
694 : }
695 : ELSE
696 : {
697 2840 : *pFV++ = round_fx( L_tmp );
698 2840 : move16();
699 : }
700 :
701 : /* [1] voicing Q15 */
702 : /*(float)(voicing[0] + voicing[1] + voicing[2]) / 3.0f*/
703 3100 : test();
704 3100 : IF( EQ_16( st_fx->tc_cnt, 1 ) || EQ_16( st_fx->tc_cnt, 2 ) )
705 : {
706 260 : *pFV++ = st_fx->voicing_fx[2];
707 260 : move16();
708 : }
709 : ELSE
710 : {
711 2840 : L_tmp = L_mult( st_fx->voicing_fx[0], 10923 );
712 2840 : L_tmp = L_mac( L_tmp, st_fx->voicing_fx[1], 10923 );
713 2840 : L_tmp = L_mac( L_tmp, st_fx->voicing_fx[2], 10923 );
714 2840 : *pFV++ = round_fx_sat( L_tmp );
715 2840 : move16();
716 : }
717 :
718 : /* [2,3,4,5,6] LSFs Q15*/
719 3100 : Copy( lsp_new, lsp, M );
720 3100 : lsf2acos_fact = 25735;
721 3100 : move16(); /* PI/6400 -> Q27 */
722 :
723 : /*ftmp = (float)acos(lsp[1...5]);*/
724 : /**pFV++ = ftmp + st->last_lsp[1...5];*/
725 : /*st->last_lsp[1...5] = ftmp;*/
726 18600 : FOR( i = 1; i < M_LSP_SPMUS; i++ )
727 : {
728 15500 : L_tmp = sub_lsp2lsf_fx( lsp[i] );
729 15500 : tmp16 = round_fx( L_shl( L_mult0( extract_l( L_tmp ), lsf2acos_fact ), 2 ) );
730 15500 : *pFV++ = add( tmp16, hSpMusClas->last_lsp_fx[i] );
731 15500 : move16(); /*Q13*/
732 15500 : hSpMusClas->last_lsp_fx[i] = tmp16;
733 15500 : move16();
734 : }
735 :
736 : /* [7] cor_map_sum Q8 */
737 3100 : *pFV++ = round_fx( L_mac( L_mult( cor_map_sum, 16384 ), hSpMusClas->last_cor_map_sum_fx, 16384 ) ); /* Q8 ->Q7*/
738 3100 : move16();
739 3100 : hSpMusClas->last_cor_map_sum_fx = cor_map_sum;
740 3100 : move16();
741 :
742 : /* [8] non_sta Q8*/
743 3100 : *pFV++ = round_fx( L_mac( L_mult( non_sta, 16384 ), hSpMusClas->last_non_sta_fx, 16384 ) ); /* Q8 -> Q7 */
744 3100 : move16();
745 3100 : hSpMusClas->last_non_sta_fx = non_sta;
746 3100 : move16();
747 :
748 : /* [9] epsP Q10 */
749 3100 : IF( EQ_16( st_fx->bwidth, NB ) )
750 : {
751 0 : *pFV++ = -1687;
752 0 : move16(); /*Q10*/
753 : }
754 : ELSE
755 : {
756 : /*lepsP1 = (float)log(epsP[1] + 1e-5f);*/
757 3100 : IF( epsP[1] != 0 )
758 : {
759 3100 : e_tmp = norm_l( epsP[1] );
760 3100 : f_tmp = Log2_norm_lc( L_shl( epsP[1], e_tmp ) );
761 3100 : e_tmp = sub( 30, add( e_tmp, Q_esp ) );
762 3100 : lepsP1 = Mpy_32_16( e_tmp, f_tmp, 22713 ); /* Q16 */ /* 22713 = ln(2) in Q15 */
763 : }
764 : ELSE
765 : {
766 0 : lepsP1 = L_deposit_l( 0 );
767 : }
768 :
769 : /*ftmp = (float)log(epsP[13]);*/
770 3100 : IF( epsP[13] != 0 )
771 : {
772 3100 : e_tmp = norm_l( epsP[13] );
773 3100 : f_tmp = Log2_norm_lc( L_shl( epsP[13], e_tmp ) );
774 3100 : e_tmp = sub( 30, add( e_tmp, Q_esp ) );
775 3100 : L_tmp = Mpy_32_16( e_tmp, f_tmp, 22713 ); /* Q16 */ /* 22713 = ln(2) in Q15 */
776 : }
777 : ELSE
778 : {
779 0 : L_tmp = L_deposit_l( 0 );
780 : }
781 :
782 : /*ftmp = (float)log(epsP[13]) - lepsP1;*/
783 3100 : L_tmp = L_sub( L_tmp, lepsP1 ); /*Q16 */
784 3100 : ftmp = round_fx( L_shl( L_tmp, 10 ) ); /*Q10 */
785 :
786 : /**pFV++ = ftmp + st->past_epsP2;*/
787 3100 : *pFV++ = add( ftmp, hSpMusClas->past_epsP2_fx );
788 3100 : move16(); /*Q10 */
789 :
790 : /*st->past_epsP2 = ftmp;*/
791 3100 : hSpMusClas->past_epsP2_fx = ftmp;
792 3100 : move16(); /*Q10 */
793 : }
794 :
795 : /* calculation of differential normalized power spectrum */
796 3100 : sum_PS = L_deposit_l( 0 );
797 210800 : FOR( i = LOWEST_FBIN; i < HIGHEST_FBIN; i++ )
798 : {
799 : #ifdef ISSUE_1867_replace_overflow_libenc
800 207700 : sum_PS = L_add_sat( sum_PS, PS[i] );
801 : #else
802 : sum_PS = L_add_o( sum_PS, PS[i], &Overflow );
803 : #endif
804 : }
805 3100 : exp1 = norm_l( sum_PS );
806 : #ifdef ISSUE_1867_replace_overflow_libenc
807 3100 : tmp1 = round_fx_sat( L_shl( sum_PS, exp1 ) );
808 : #else
809 : tmp1 = round_fx_o( L_shl( sum_PS, exp1 ), &Overflow );
810 : #endif
811 3100 : exp1 = sub( 30, exp1 );
812 :
813 210800 : FOR( i = LOWEST_FBIN; i < HIGHEST_FBIN; i++ )
814 : {
815 : /*PS_norm[i] = PS[i] / sum_PS;*/
816 : /*dPS[i] = (float)fabs(PS_norm[i] - st->past_PS[i]);*/
817 207700 : exp2 = norm_l( PS[i] );
818 : #ifdef ISSUE_1867_replace_overflow_libenc
819 207700 : tmp2 = round_fx_sat( L_shl( PS[i], exp2 ) );
820 : #else
821 : tmp2 = round_fx_o( L_shl( PS[i], exp2 ), &Overflow );
822 : #endif
823 207700 : exp2 = sub( 30, exp2 );
824 :
825 207700 : scale = shr( sub( tmp1, tmp2 ), 15 );
826 207700 : tmp2 = shl( tmp2, scale );
827 207700 : exp2 = sub( exp2, scale );
828 :
829 207700 : exp3 = sub( exp1, exp2 );
830 :
831 207700 : tmp = div_s( tmp2, tmp1 ); /*Q(15+exp3) */
832 207700 : PS_norm[i] = L_shl( tmp, sub( 10, exp3 ) );
833 207700 : move32(); /*Q25 */
834 207700 : dPS[i] = L_abs( L_sub( PS_norm[i], hSpMusClas->past_PS_fx[i - LOWEST_FBIN] ) );
835 207700 : move32(); /*Q25 */
836 : }
837 :
838 : /* [10] ps_diff (spectral difference) Q10*/
839 3100 : ps_diff = 0;
840 3100 : move16();
841 210800 : FOR( i = LOWEST_FBIN; i < HIGHEST_FBIN; i++ )
842 : {
843 : /*ps_diff += dPS[i];*/
844 207700 : ps_diff = L_add( ps_diff, dPS[i] ); /*Q25*/
845 : }
846 :
847 : /*ps_diff = (float)log(ps_diff + 1e-5f);*/
848 3100 : IF( ps_diff != 0 )
849 : {
850 3100 : e_tmp = norm_l( ps_diff );
851 3100 : f_tmp = Log2_norm_lc( L_shl( ps_diff, e_tmp ) );
852 3100 : e_tmp = sub( 30 - 25, e_tmp );
853 3100 : ps_diff = Mpy_32_16( e_tmp, f_tmp, 22713 ); /* Q16 */ /* 22713 = ln(2) in Q15 */
854 3100 : ps_diff_16 = round_fx( L_shl( ps_diff, 10 ) ); /*Q10 */
855 : }
856 : ELSE
857 : {
858 0 : ps_diff_16 = -11789;
859 0 : move16(); /*Q10 */
860 : }
861 :
862 3100 : *pFV++ = add( ps_diff_16, hSpMusClas->past_ps_diff_fx );
863 3100 : move16(); /*Q10 */
864 3100 : hSpMusClas->past_ps_diff_fx = ps_diff_16;
865 3100 : move16(); /*Q10 */
866 :
867 : /* [11] ps_sta (spectral stationarity) Q11 */
868 3100 : ps_sta = 0;
869 3100 : move16();
870 210800 : FOR( i = LOWEST_FBIN; i < HIGHEST_FBIN; i++ )
871 : {
872 : /*mx = PS_norm[i] > st->past_PS[i] ? PS_norm[i] : st->past_PS[i];*/
873 207700 : mx = L_max( PS_norm[i], hSpMusClas->past_PS_fx[i - LOWEST_FBIN] ); /*Q25 */
874 :
875 : /*ps_sta += mx / (dPS[i] + 1e-5f);*/
876 207700 : IF( !dPS[i] )
877 : {
878 95 : ps_sta = L_add( ps_sta, L_shr( mx, 9 ) ); /*Q16 */
879 : }
880 : ELSE
881 : {
882 207605 : exp1 = norm_l( L_add( dPS[i], 336 ) );
883 : #ifdef ISSUE_1867_replace_overflow_libenc
884 207605 : tmp1 = round_fx_sat( L_shl_sat( L_add( dPS[i], 336 ), exp1 ) );
885 : #else
886 : tmp1 = round_fx_o( L_shl_o( L_add( dPS[i], 336 ), exp1, &Overflow ), &Overflow );
887 : #endif
888 207605 : exp1 = sub( 30, exp1 );
889 :
890 207605 : exp2 = norm_l( mx );
891 207605 : tmp2 = round_fx( L_shl( mx, exp2 ) );
892 207605 : exp2 = sub( 30, exp2 );
893 :
894 207605 : scale = shr( sub( tmp1, tmp2 ), 15 );
895 207605 : tmp2 = shl( tmp2, scale );
896 207605 : exp2 = sub( exp2, scale );
897 :
898 207605 : exp3 = sub( exp1, exp2 );
899 :
900 207605 : tmp = div_s( tmp2, tmp1 ); /*Q(15+exp3) */
901 207605 : L_tmp = L_shl( tmp, sub( 1, exp3 ) ); /*Q16 */
902 207605 : ps_sta = L_add_sat( ps_sta, L_tmp ); /*Q16 */
903 : }
904 : }
905 :
906 : /**pFV++ = (float)log(ps_sta + 1e-5f);*/
907 3100 : ps_sta = L_add_sat( ps_sta, 336 );
908 3100 : e_tmp = norm_l( ps_sta );
909 3100 : f_tmp = Log2_norm_lc( L_shl( ps_sta, e_tmp ) );
910 3100 : e_tmp = sub( 30 - 16, e_tmp );
911 3100 : L_tmp = Mpy_32_16( e_tmp, f_tmp, 22713 ); /* Q16 */ /* 22713 = ln(2) in Q15 */
912 3100 : *pFV++ = round_fx( L_shl( L_tmp, 11 ) ); /*Q11 */
913 3100 : move16();
914 :
915 : /* update PS vector */
916 3100 : Copy32( &PS_norm[LOWEST_FBIN], hSpMusClas->past_PS_fx, HIGHEST_FBIN - LOWEST_FBIN );
917 :
918 : /*------------------------------------------------------------------*
919 : * Scaling of the feature vector
920 : *------------------------------------------------------------------*/
921 :
922 : /* FV[0] -> Q0 */
923 : /* FV[1...6] -> Q13*/
924 : /* FV[7,8] -> Q7 */
925 : /* FV[9,10] -> Q10 */
926 : /* FV[11] -> Q11 */
927 :
928 :
929 3100 : pFV = FV;
930 3100 : IF( EQ_16( st_fx->bwidth, NB ) )
931 : {
932 0 : pSF_m = SF_8k_mult_fx;
933 0 : pSF_a = SF_8k_add_fx;
934 : }
935 : ELSE
936 : {
937 3100 : pSF_m = SF_mult_fx;
938 3100 : pSF_a = SF_add_fx;
939 : }
940 :
941 40300 : FOR( i = 0; i < N_FEATURES; i++ )
942 : {
943 : /**pFV = pSF[0] * *pFV + pSF[1];*/
944 : #ifdef ISSUE_1867_replace_overflow_libenc
945 37200 : *pFV = round_fx_sat( L_shl_sat( L_mac( pSF_a[i], *pFV, pSF_m[i] ), ishift[i] ) );
946 : #else
947 : *pFV = round_fx_o( L_shl_o( L_mac( pSF_a[i], *pFV, pSF_m[i] ), ishift[i], &Overflow ), &Overflow );
948 : #endif
949 37200 : move16();
950 37200 : pFV++;
951 : }
952 :
953 3100 : *voi_fv = FV[1];
954 3100 : move16();
955 3100 : *cor_map_sum_fv = FV[7];
956 3100 : move16();
957 3100 : *LPCErr = FV[9];
958 3100 : move16();
959 :
960 :
961 : /*------------------------------------------------------------------*
962 : * Calculation of posterior probability
963 : * Log-probability
964 : *------------------------------------------------------------------*/
965 :
966 3100 : max_s = L_add( MIN_32, 0 );
967 3100 : max_m = L_add( MIN_32, 0 );
968 : /* pyn = 1e-5f;*/
969 3100 : max_n = L_add( MIN_32, 0 );
970 :
971 :
972 21700 : FOR( k = 0; k < N_MIXTURES; k++ )
973 : {
974 : /* for each mixture, calculate the probability of speech or noise and the probability of music */
975 : /* active frames - calculate the probability of speech */
976 241800 : FOR( p = 0; p < N_FEATURES; p++ )
977 : {
978 : /* xm[p] = FV[p] - m_speech[k*N_FEATURES+p];*/
979 : #ifdef ISSUE_1867_replace_overflow_libenc
980 223200 : xm[p] = sub_sat( FV[p], m_speech_fx[k * N_FEATURES + p] );
981 : #else
982 : xm[p] = sub_o( FV[p], m_speech_fx[k * N_FEATURES + p], &Overflow );
983 : #endif
984 223200 : move16(); /*Q15 */
985 : }
986 :
987 : /*py = lvm_speech[k] + dot_product_mat(xm, &invV_speech[k*N_FEATURES*N_FEATURES], N_FEATURES );*/
988 18600 : L_tmp = dot_product_mat_fx( xm, &invV_speech_fx[k * N_FEATURES * N_FEATURES], N_FEATURES ); /*Q10 */
989 18600 : py_s = L_add( lvm_speech_fx[k], L_tmp ); /*Q10 */
990 18600 : max_s = L_max( py_s, max_s );
991 :
992 :
993 : /* pys += (float)exp(py); */
994 :
995 : /* inactive frames - calculate the probability of noise */
996 241800 : FOR( p = 0; p < N_FEATURES; p++ )
997 : {
998 : /*xm[p] = FV[p] - m_noise[k*N_FEATURES+p];*/
999 : #ifdef ISSUE_1867_replace_overflow_libenc
1000 223200 : xm[p] = sub_sat( FV[p], m_noise_fx[k * N_FEATURES + p] );
1001 : #else
1002 : xm[p] = sub_o( FV[p], m_noise_fx[k * N_FEATURES + p], &Overflow );
1003 : #endif
1004 223200 : move16(); /*Q15 */
1005 : }
1006 :
1007 : /*py = lvm_noise[k] + dot_product_mat(xm, &invV_noise[k*N_FEATURES*N_FEATURES], N_FEATURES );*/
1008 18600 : L_tmp = dot_product_mat_fx( xm, &invV_noise_fx[k * N_FEATURES * N_FEATURES], N_FEATURES ); /*Q10 */
1009 : /* pyn += (float)exp(py); */
1010 18600 : py_n = L_add( lvm_noise_fx[k], L_tmp ); /*Q10 */
1011 18600 : max_n = L_max( py_n, max_n );
1012 :
1013 :
1014 : /* either active or inactive frames - calculate the probability of music */
1015 241800 : FOR( p = 0; p < N_FEATURES; p++ )
1016 : {
1017 : /*xm[p] = FV[p] - m_music[k*N_FEATURES+p];*/
1018 : #ifdef ISSUE_1867_replace_overflow_libenc
1019 223200 : xm[p] = sub_sat( FV[p], m_music_fx[k * N_FEATURES + p] );
1020 : #else
1021 : xm[p] = sub_o( FV[p], m_music_fx[k * N_FEATURES + p], &Overflow );
1022 : #endif
1023 223200 : move16(); /*Q15 */
1024 : }
1025 :
1026 : /*py = lvm_music[k] + dot_product_mat(xm, &invV_music[k*N_FEATURES*N_FEATURES], N_FEATURES );*/
1027 18600 : L_tmp = dot_product_mat_fx( xm, &invV_music_fx[k * N_FEATURES * N_FEATURES], N_FEATURES ); /*Q10 */
1028 18600 : py_m = L_add( lvm_music_fx[k], L_tmp ); /*Q10 */
1029 18600 : max_m = L_max( py_m, max_m );
1030 :
1031 : /*pym += (float)exp(py);#######*/
1032 : }
1033 :
1034 : /* calculate log-probability */
1035 : /*log(0.0001)-0.5f * N_FEATURES * LOG_PI2 in Q9 */
1036 : #ifdef ISSUE_1867_replace_overflow_libenc
1037 3100 : lps = extract_h( L_shl_sat( L_sub( max_s, LOG_PROB_CONST ), 16 - 1 ) ); /*Q9 */
1038 : #else
1039 : lps = extract_h( L_shl_o( L_sub( max_s, LOG_PROB_CONST ), 16 - 1, &Overflow ) ); /*Q9 */
1040 : #endif
1041 3100 : lps = s_max( lps, -10832 );
1042 :
1043 3100 : lpm = extract_h( L_shl( L_sub( max_m, LOG_PROB_CONST ), 16 - 1 ) ); /*Q9 */
1044 3100 : lpm = s_max( lpm, -10832 );
1045 : /*
1046 : lpn = (float)log(pyn) - 0.5f * N_FEATURES * (float)log(2*PI);
1047 : */
1048 : #ifdef ISSUE_1867_replace_overflow_libenc
1049 3100 : lpn = extract_h( L_shl_sat( L_sub( max_n, LOG_PROB_CONST ), 16 - 1 ) ); /*Q9 */
1050 : #else
1051 : lpn = extract_h( L_shl_o( L_sub( max_n, LOG_PROB_CONST ), 16 - 1, &Overflow ) ); /*Q9 */
1052 : #endif
1053 3100 : lpn = s_max( lpn, -10832 );
1054 :
1055 3100 : *high_lpn_flag_ptr = 0;
1056 3100 : move16();
1057 3100 : test();
1058 3100 : if ( GT_16( lpn, lps ) && GT_16( lpn, lpm ) )
1059 : {
1060 53 : *high_lpn_flag_ptr = 1;
1061 53 : move16();
1062 : }
1063 :
1064 :
1065 3100 : IF( !vad )
1066 : {
1067 : /* increase log-probability of noise */
1068 : /* lps = lpn * 1.2f; */
1069 108 : lps = add( lpn, mult_r( 6554, lpn ) ); /* Q9 */
1070 : }
1071 :
1072 3100 : hSpMusClas->lpm_fx = lpm;
1073 3100 : move16();
1074 3100 : hSpMusClas->lps_fx = lps;
1075 3100 : move16();
1076 :
1077 : /* determine HQ GENERIC speech class */
1078 3100 : IF( hHQ_core != NULL )
1079 : {
1080 3100 : hHQ_core->hq_generic_speech_class = 0;
1081 3100 : move16();
1082 3100 : if ( GT_16( lps, add( lpm, 256 ) ) )
1083 : {
1084 1433 : hHQ_core->hq_generic_speech_class = 1;
1085 1433 : move16();
1086 : }
1087 : }
1088 :
1089 : /*------------------------------------------------------------------*
1090 : * State machine (sp_mus_state < 0 .. inactive, > 0 .. entry, = 0 .. active )
1091 : *------------------------------------------------------------------*/
1092 :
1093 3100 : IF( vad )
1094 : {
1095 2992 : test();
1096 2992 : test();
1097 2992 : test();
1098 2992 : IF( LT_16( relE, -20 * 256 ) || ( LE_16( lps, -5 * 512 ) && LE_16( lpm, -5 * 512 ) ) )
1099 : {
1100 370 : IF( hSpMusClas->sp_mus_state > 0 )
1101 : {
1102 70 : if ( LT_16( hSpMusClas->sp_mus_state, HANG_LEN ) )
1103 : {
1104 : /* energy is too low but we are in entry period -> reset the inactive counter to allow new entry later */
1105 9 : hSpMusClas->inact_cnt = 0;
1106 9 : move16();
1107 : }
1108 :
1109 : /* energy is too low -> we are going to instable state */
1110 70 : hSpMusClas->sp_mus_state = 0;
1111 70 : move16();
1112 : }
1113 300 : ELSE IF( GT_16( hSpMusClas->sp_mus_state, -HANG_LEN ) )
1114 : {
1115 : /* energy is still too low -> we are still in instable state */
1116 136 : hSpMusClas->sp_mus_state = sub( hSpMusClas->sp_mus_state, 1 );
1117 : }
1118 : }
1119 2622 : ELSE IF( hSpMusClas->sp_mus_state <= 0 )
1120 : {
1121 70 : IF( hSpMusClas->inact_cnt == 0 )
1122 : {
1123 :
1124 24 : hSpMusClas->sp_mus_state = 1;
1125 24 : move16();
1126 : }
1127 : ELSE
1128 : {
1129 :
1130 46 : hSpMusClas->sp_mus_state = HANG_LEN;
1131 46 : move16();
1132 : }
1133 :
1134 70 : hSpMusClas->inact_cnt = 12;
1135 70 : move16();
1136 : }
1137 2552 : ELSE IF( hSpMusClas->sp_mus_state > 0 && LT_16( hSpMusClas->sp_mus_state, HANG_LEN ) )
1138 : {
1139 : /* we are inside an entry period -> increment the counter of entry frames */
1140 129 : hSpMusClas->sp_mus_state = add( hSpMusClas->sp_mus_state, 1 );
1141 : }
1142 :
1143 2992 : test();
1144 2992 : if ( hSpMusClas->sp_mus_state < 0 && hSpMusClas->inact_cnt > 0 )
1145 : {
1146 182 : hSpMusClas->inact_cnt = sub( hSpMusClas->inact_cnt, 1 );
1147 : }
1148 : }
1149 : ELSE
1150 : {
1151 108 : test();
1152 108 : IF( hSpMusClas->sp_mus_state > 0 && LT_16( hSpMusClas->sp_mus_state, HANG_LEN ) )
1153 : {
1154 0 : hSpMusClas->inact_cnt = 0;
1155 0 : move16();
1156 : }
1157 108 : ELSE IF( hSpMusClas->inact_cnt > 0 )
1158 : {
1159 40 : hSpMusClas->inact_cnt = sub( hSpMusClas->inact_cnt, 1 );
1160 : }
1161 :
1162 108 : test();
1163 108 : IF( hSpMusClas->sp_mus_state > 0 && LT_16( hSpMusClas->sp_mus_state, HANG_LEN ) )
1164 : {
1165 :
1166 0 : hSpMusClas->sp_mus_state = -HANG_LEN;
1167 0 : move16();
1168 : }
1169 108 : ELSE IF( hSpMusClas->sp_mus_state > 0 )
1170 : {
1171 :
1172 0 : hSpMusClas->sp_mus_state = -1;
1173 0 : move16();
1174 : }
1175 108 : ELSE IF( GT_16( hSpMusClas->sp_mus_state, -HANG_LEN ) )
1176 : {
1177 : /* we are in inactive state */
1178 63 : hSpMusClas->sp_mus_state = sub( hSpMusClas->sp_mus_state, 1 );
1179 : }
1180 : }
1181 :
1182 : /*------------------------------------------------------------------*
1183 : * Decision without hangover
1184 : * Weighted decision
1185 : *------------------------------------------------------------------*/
1186 :
1187 : /* decision without hangover (0 - speech/noise, 1 - music) */
1188 3100 : logic16();
1189 3100 : dec = sub( lpm, lps ) > 0;
1190 3100 : move16();
1191 3100 : dlp = sub( lpm, lps ); /*Q9*/
1192 :
1193 3100 : IF( !vad )
1194 : {
1195 108 : dec = 0;
1196 108 : move16();
1197 108 : dlp = 0;
1198 108 : move16();
1199 : }
1200 :
1201 : /* calculate weight based on relE (close to 0.01 in low-E regions, close to 1 in high-E regions) */
1202 : /*wrelE = 1.0f + relE/15;*/
1203 3100 : wrelE = add( 2048, mult_r( relE, 17476 ) ); /* 1/15 in Q18 -> 17476 result in Q11 */
1204 :
1205 :
1206 3100 : wrelE = s_min( wrelE, 2048 );
1207 3100 : wrelE = s_max( wrelE, 20 );
1208 :
1209 : /* calculate weight based on drops of dlp (close to 1 during sudden drops of dlp, close to 0 otherwise) */
1210 3100 : test();
1211 3100 : IF( dlp < 0 && LT_16( dlp, hSpMusClas->past_dlp_fx[0] ) )
1212 : {
1213 899 : IF( hSpMusClas->past_dlp_fx[0] > 0 )
1214 : {
1215 279 : hSpMusClas->wdrop_fx = negate( dlp ); /*Q9*/
1216 : }
1217 : ELSE
1218 : {
1219 620 : hSpMusClas->wdrop_fx = add( hSpMusClas->wdrop_fx, sub( hSpMusClas->past_dlp_fx[0], dlp ) ); /*Q9*/
1220 : }
1221 : }
1222 : ELSE
1223 : {
1224 2201 : hSpMusClas->wdrop_fx = 0;
1225 2201 : move16();
1226 : }
1227 :
1228 : /*wdrop = st->wdrop/20;*/
1229 3100 : wdrop = mult_r( hSpMusClas->wdrop_fx, 26214 ); /*Q9*Q19->Q13*/
1230 3100 : wdrop = s_min( wdrop, 8192 ); /* limitation [0.1,1] Q13 */
1231 3100 : wdrop = s_max( wdrop, 819 );
1232 :
1233 : /* combine weights into one */
1234 : /*wght = wrelE * wdrop;*/
1235 3100 : wght = mult_r( wrelE, wdrop ); /* Q11*Q13 -> Q9*/
1236 3100 : wght = s_max( wght, 5 );
1237 :
1238 : /* calculate weighted decision */
1239 : /*st->wdlp_0_95_sp = wght * dlp + (1 - wght) * st->wdlp_0_95_sp;*/
1240 : /* = Q9 * Q9 + (Q9-Q9)*Q9 */
1241 3100 : L_tmp = L_mac( L_mult( wght, dlp ), sub( 512, wght ), hSpMusClas->wdlp_0_95_sp_fx );
1242 3100 : hSpMusClas->wdlp_0_95_sp_fx = round_fx( L_shl( L_tmp, 6 ) );
1243 :
1244 3100 : if ( EQ_16( hSpMusClas->sp_mus_state, -HANG_LEN ) )
1245 : {
1246 228 : hSpMusClas->wdlp_0_95_sp_fx = 0;
1247 228 : move16();
1248 : }
1249 :
1250 : /*------------------------------------------------------------------*
1251 : * Final speech/music decision
1252 : *------------------------------------------------------------------*/
1253 :
1254 3100 : test();
1255 3100 : test();
1256 3100 : IF( !vad && EQ_16( hSpMusClas->sp_mus_state, -HANG_LEN ) )
1257 : {
1258 : /* inactive state */
1259 49 : dec = 0;
1260 49 : move16();
1261 : }
1262 3051 : ELSE IF( hSpMusClas->sp_mus_state <= 0 )
1263 : {
1264 : /* transition from active to inactive state or instable state */
1265 429 : dec = hSpMusClas->past_dec[0];
1266 429 : move16();
1267 : }
1268 2622 : ELSE IF( hSpMusClas->sp_mus_state > 0 && LT_16( hSpMusClas->sp_mus_state, HANG_LEN ) )
1269 : {
1270 : /* entry state -> final decision is calculated based on weighted average of past non-binary decisions */
1271 138 : L_tmp = L_mult( w_spmus_fx[hSpMusClas->sp_mus_state - 1][0], dlp ); /*Q15*Q9 */
1272 :
1273 : /*ftmp += dotp( &w[st_fx->sp_mus_state-1][1], st_fx->past_dlp_fx, HANG_LEN-1 );*/
1274 138 : L_tmp = L_add( L_tmp, Dot_product( &w_spmus_fx[hSpMusClas->sp_mus_state - 1][1], hSpMusClas->past_dlp_fx, HANG_LEN - 1 ) );
1275 138 : logic16();
1276 138 : move16();
1277 :
1278 : /*dec = ftmp > 2.0f;*/
1279 138 : dec = L_sub( L_tmp, 2 * ( 1 << 25 ) ) > 0;
1280 : }
1281 : ELSE
1282 : {
1283 : /* stable active state */
1284 2484 : test();
1285 2484 : test();
1286 2484 : test();
1287 2484 : test();
1288 2484 : IF( hSpMusClas->wdlp_0_95_sp_fx > 0 && hSpMusClas->past_dec[0] == 0 && hSpMusClas->past_dec[1] == 0 && hSpMusClas->past_dec[2] == 0 )
1289 : {
1290 : /* switching from speech to music */
1291 18 : dec = 1;
1292 18 : move16();
1293 : }
1294 2466 : ELSE IF( hSpMusClas->past_dec[0] == 1 && hSpMusClas->wdlp_0_95_sp_fx < 0 )
1295 : {
1296 : /* switching from music to speech */
1297 18 : dec = 0;
1298 18 : move16();
1299 : }
1300 : ELSE
1301 : {
1302 2448 : dec = hSpMusClas->past_dec[0];
1303 2448 : move16();
1304 : }
1305 : }
1306 :
1307 :
1308 : /*------------------------------------------------------------------*
1309 : * Updates
1310 : *------------------------------------------------------------------*/
1311 :
1312 : /* update the buffer of past non-binary decisions */
1313 3100 : Copy( &hSpMusClas->past_dlp_fx[0], &hSpMusClas->past_dlp_fx[1], HANG_LEN - 2 );
1314 3100 : hSpMusClas->past_dlp_fx[0] = dlp;
1315 3100 : move16();
1316 :
1317 : /* update the buffer of past binary decisions */
1318 3100 : Copy( &hSpMusClas->past_dec[0], &hSpMusClas->past_dec[1], HANG_LEN - 2 );
1319 3100 : hSpMusClas->past_dec[0] = dec;
1320 3100 : move16();
1321 :
1322 3100 : return dec;
1323 : }
1324 :
1325 :
1326 : /*---------------------------------------------------------------------*
1327 : * sp_mus_classif_2nd_fx()
1328 : *
1329 : * 2nd stage speech/music classifier (convert music to speech for onsets)
1330 : *---------------------------------------------------------------------*/
1331 :
1332 2050 : static void sp_mus_classif_2nd_fx(
1333 : Encoder_State *st, /* i/o: Encoder state structure */
1334 : const Word16 Etot, /* i : total frame energy */
1335 : Word16 *attack_flag, /* i/o: attack flag (GSC or TC) */
1336 : const Word16 *inp, /* i : input signal */
1337 : const Word16 Qx )
1338 : {
1339 : Word16 attack;
1340 2050 : SP_MUS_CLAS_HANDLE hSpMusClas = st->hSpMusClas;
1341 :
1342 : /* initialization */
1343 2050 : *attack_flag = 0;
1344 2050 : move16();
1345 :
1346 : /* signal stability estimation */
1347 2050 : stab_est_fx( Etot, hSpMusClas->gsc_lt_diff_etot_fx, &hSpMusClas->gsc_mem_etot_fx, &hSpMusClas->gsc_nb_thr_3, &hSpMusClas->gsc_nb_thr_1, hSpMusClas->gsc_thres_fx, &hSpMusClas->gsc_last_music_flag, st->vad_flag );
1348 :
1349 : /* calculate variance of correlation */
1350 2050 : var_cor_calc_fx( st->old_corr_fx, &hSpMusClas->mold_corr_fx, hSpMusClas->var_cor_t_fx, &hSpMusClas->high_stable_cor );
1351 :
1352 : /* attack detection */
1353 2050 : attack = attack_det_fx( inp, Qx, st->clas, st->localVAD, st->coder_type, st->total_brate );
1354 :
1355 2050 : test();
1356 2050 : test();
1357 2050 : test();
1358 2050 : test();
1359 2050 : test();
1360 2050 : test();
1361 2050 : IF( EQ_16( st->sp_aud_decision1, 1 ) )
1362 : {
1363 665 : test();
1364 665 : test();
1365 665 : test();
1366 665 : IF( LT_16( hSpMusClas->ener_RAT_fx, 5898 ) && GT_16( hSpMusClas->lt_dec_thres_fx, 7680 ) )
1367 : {
1368 0 : st->sp_aud_decision2 = 0;
1369 0 : move16();
1370 : }
1371 665 : ELSE IF( EQ_16( hSpMusClas->high_stable_cor, 1 ) && GE_16( st->pitch[0], 130 ) )
1372 : {
1373 : /* prevent GSC in highly correlated signal with low energy variation */
1374 : /* this is basically a patch against bassoon-type of music */
1375 0 : st->sp_aud_decision2 = 0;
1376 0 : move16();
1377 :
1378 0 : test();
1379 0 : if ( EQ_16( st->codec_mode, MODE1 ) && EQ_16( st->coder_type, TRANSITION ) )
1380 : {
1381 0 : st->coder_type = GENERIC;
1382 0 : move16();
1383 : }
1384 : }
1385 665 : ELSE IF( GT_16( hSpMusClas->gsc_lt_diff_etot_fx[MAX_LT - 1], 1152 ) &&
1386 : GT_16( sub( hSpMusClas->gsc_lt_diff_etot_fx[MAX_LT - 1], hSpMusClas->gsc_lt_diff_etot_fx[MAX_LT - 2] ), 2560 ) ) /* 10.0f in Q8 */
1387 : {
1388 23 : IF( EQ_16( st->tc_cnt, 1 ) )
1389 : {
1390 0 : st->sp_aud_decision2 = 0;
1391 0 : move16();
1392 :
1393 0 : if ( EQ_16( st->codec_mode, MODE1 ) )
1394 : {
1395 0 : st->coder_type = TRANSITION;
1396 0 : move16();
1397 : }
1398 : }
1399 : ELSE
1400 : {
1401 23 : IF( GE_16( attack, ATT_3LSUB_POS ) )
1402 : {
1403 : /* do TC coding if attack is located in the last subframe */
1404 6 : st->sp_aud_decision2 = 0;
1405 6 : move16();
1406 6 : *attack_flag = add( attack, 1 );
1407 6 : move16();
1408 6 : if ( EQ_16( st->codec_mode, MODE1 ) )
1409 : {
1410 6 : st->coder_type = TRANSITION;
1411 6 : move16();
1412 : }
1413 : }
1414 17 : ELSE IF( GE_16( attack, ATT_SEG_LEN >> 1 ) )
1415 : {
1416 : /* do GSC coding if attack is located after the first quarter of the first subframe */
1417 : /* (pre-echo will be treated at the decoder side) */
1418 0 : st->sp_aud_decision2 = 1;
1419 0 : move16();
1420 0 : *attack_flag = 31;
1421 0 : move16();
1422 : }
1423 : }
1424 : }
1425 : }
1426 1385 : ELSE IF( EQ_16( st->localVAD, 1 ) && EQ_16( st->coder_type, GENERIC ) &&
1427 : ( ( GE_16( attack, ATT_3LSUB_POS ) && LT_32( st->total_brate, ACELP_24k40 ) ) ||
1428 : ( GE_16( attack, ATT_3LSUB_POS_16k ) && GE_32( st->total_brate, ACELP_24k40 ) && LT_32( st->total_brate, ACELP_48k ) ) ) )
1429 : {
1430 : /* do TC coding if attack is located in the last subframe */
1431 19 : *attack_flag = add( attack, 1 );
1432 19 : move16();
1433 19 : if ( EQ_16( st->codec_mode, MODE1 ) )
1434 : {
1435 19 : st->coder_type = TRANSITION;
1436 19 : move16();
1437 : }
1438 : }
1439 :
1440 2050 : return;
1441 : }
1442 :
1443 :
1444 : /*---------------------------------------------------------------------*
1445 : * var_cor_calc_fx()
1446 : *
1447 : * Calculate variance of correlation
1448 : *---------------------------------------------------------------------*/
1449 :
1450 2050 : static void var_cor_calc_fx(
1451 : const Word16 old_corr,
1452 : Word16 *mold_corr,
1453 : Word16 var_cor_t[],
1454 : Word16 *high_stable_cor )
1455 : {
1456 : Word16 i, var_cor;
1457 :
1458 : /* update buffer of old correlation values */
1459 20500 : FOR( i = VAR_COR_LEN - 1; i > 0; i-- )
1460 : {
1461 18450 : var_cor_t[i] = var_cor_t[i - 1]; /*Q11*/
1462 18450 : move16();
1463 : }
1464 2050 : var_cor_t[i] = old_corr;
1465 2050 : move16();
1466 :
1467 : /* calculate variance of correlation */
1468 2050 : var_cor = var_fx( var_cor_t, 11, VAR_COR_LEN );
1469 :
1470 2050 : *high_stable_cor = 0;
1471 2050 : move16();
1472 2050 : test();
1473 2050 : if ( GT_16( *mold_corr, 26214 ) && LT_16( var_cor, 2 ) )
1474 : {
1475 0 : *high_stable_cor = 1;
1476 0 : move16();
1477 : }
1478 :
1479 : /* update average correlation */
1480 : /*st->mold_corr = 0.1f * st->old_corr + 0.9f * st->mold_corr;*/
1481 2050 : *mold_corr = mac_r( L_mult( 3277, old_corr ), 29491, *mold_corr ); /*Q15 */
1482 :
1483 2050 : return;
1484 : }
1485 :
1486 : /*---------------------------------------------------------------------*
1487 : * attack_det_fx()
1488 : *
1489 : * Attack detection
1490 : *---------------------------------------------------------------------*/
1491 :
1492 2050 : static Word16 attack_det_fx( /* o : attack flag */
1493 : const Word16 *inp, /* i : input signal */
1494 : const Word16 Qx,
1495 : const Word16 last_clas, /* i : last signal clas */
1496 : const Word16 localVAD, /* i : local VAD flag */
1497 : const Word16 coder_type, /* i : coder type */
1498 : const Word32 total_brate /* i : total bitrate */
1499 : )
1500 : {
1501 : Word16 i, j, tmp, tmp1, attack, exp1;
1502 : Word32 L_tmp, etmp, etmp2, finc[ATT_NSEG];
1503 : Word16 att_3lsub_pos;
1504 : #ifndef ISSUE_1867_replace_overflow_libenc
1505 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
1506 : Flag Overflow = 0;
1507 : move16();
1508 : #endif
1509 : #endif
1510 :
1511 2050 : att_3lsub_pos = ATT_3LSUB_POS;
1512 2050 : move16();
1513 2050 : if ( GE_32( total_brate, ACELP_24k40 ) )
1514 : {
1515 1000 : att_3lsub_pos = ATT_3LSUB_POS_16k;
1516 1000 : move16();
1517 : }
1518 :
1519 : /* compute energy per section */
1520 67650 : FOR( i = 0; i < ATT_NSEG; i++ )
1521 : {
1522 65600 : L_tmp = L_mult0( inp[i * ATT_SEG_LEN], inp[i * ATT_SEG_LEN] ); /*2*Qx */
1523 :
1524 524800 : FOR( j = 1; j < ATT_SEG_LEN; j++ )
1525 : {
1526 : #ifdef ISSUE_1867_replace_overflow_libenc
1527 459200 : L_tmp = L_mac0_sat( L_tmp, inp[i * ATT_SEG_LEN + j], inp[i * ATT_SEG_LEN + j] ); /*2*Qx */
1528 : #else
1529 : L_tmp = L_mac0_o( L_tmp, inp[i * ATT_SEG_LEN + j], inp[i * ATT_SEG_LEN + j], &Overflow ); /*2*Qx */
1530 : #endif
1531 : }
1532 :
1533 65600 : finc[i] = L_tmp;
1534 65600 : move32();
1535 : }
1536 :
1537 2050 : attack = maximum_32_fx( finc, ATT_NSEG, &etmp );
1538 2050 : move16();
1539 2050 : test();
1540 2050 : IF( EQ_16( localVAD, 1 ) && EQ_16( coder_type, GENERIC ) )
1541 : {
1542 : /*----------------------------------------------------------------------*
1543 : * Detect if there is a strong onset in the last subframe
1544 : * - if detected, TC is used to better code the onset
1545 : *----------------------------------------------------------------------*/
1546 :
1547 : /* compute mean energy in the first three subframes */
1548 1548 : exp1 = norm_s( att_3lsub_pos );
1549 1548 : tmp = div_s( shl( 1, sub( 14, exp1 ) ), att_3lsub_pos ); /*Q(29-exp1) */
1550 :
1551 1548 : L_tmp = L_shr_sat( finc[0], Qx ); /*Qx */
1552 :
1553 39046 : FOR( i = 1; i < att_3lsub_pos; i++ )
1554 : {
1555 : #ifdef ISSUE_1867_replace_overflow_libenc
1556 37498 : L_tmp = L_add_sat( L_tmp, L_shr_sat( finc[i], Qx ) ); /*Qx */
1557 : #else
1558 : L_tmp = L_add_o( L_tmp, L_shr_sat( finc[i], Qx ), &Overflow ); /*Qx */
1559 : #endif
1560 : }
1561 1548 : L_tmp = Mult_32_16( L_tmp, tmp ); /*Q(14-exp1+Qx) */
1562 1548 : etmp = L_shl( L_tmp, sub( exp1, 14 ) ); /*Qx */
1563 :
1564 1548 : tmp1 = sub( ATT_NSEG, attack );
1565 1548 : exp1 = norm_s( tmp1 );
1566 1548 : tmp = div_s( shl( 1, sub( 14, exp1 ) ), tmp1 ); /*Q(29-exp1) */
1567 :
1568 1548 : L_tmp = L_shr_sat( finc[attack], Qx ); /*Qx */
1569 27151 : FOR( i = 1; i < tmp1; i++ )
1570 : {
1571 : #ifdef ISSUE_1867_replace_overflow_libenc
1572 25603 : L_tmp = L_add_sat( L_tmp, L_shr_sat( finc[i + attack], Qx ) ); /*Qx */
1573 : #else
1574 : L_tmp = L_add_o( L_tmp, L_shr_sat( finc[i + attack], Qx ), &Overflow ); /*Qx */
1575 : #endif
1576 : }
1577 1548 : L_tmp = Mult_32_16( L_tmp, tmp ); /*Q(14-exp1+Qx) */
1578 1548 : etmp2 = L_shl( L_tmp, sub( exp1, 14 ) ); /*Qx */
1579 :
1580 : /* and compare them */
1581 1548 : if ( GT_32( etmp, L_shr( etmp2, 3 ) ) )
1582 : {
1583 : /* stop, if the attack is not sufficiently strong */
1584 1496 : attack = 0;
1585 1496 : move16();
1586 : }
1587 :
1588 1548 : test();
1589 1548 : if ( EQ_16( last_clas, VOICED_CLAS ) && GT_32( L_add( L_shl( etmp, 4 ), L_shl( etmp, 2 ) ), etmp2 ) )
1590 : {
1591 : /* stop, if the signal was voiced and the attack is not sufficiently strong */
1592 553 : attack = 0;
1593 553 : move16();
1594 : }
1595 :
1596 : /* compare also wrt. other sections (reduces a misclassification) */
1597 1548 : IF( attack > 0 )
1598 : {
1599 50 : etmp2 = L_add( finc[attack], 0 );
1600 50 : etmp = Mult_32_16( etmp2, 16384 ); /* etmp2 / 2.0 = (etmp2*0.5) */
1601 1045 : FOR( i = 2; i < ATT_3LSUB_POS - 2; i++ )
1602 : {
1603 998 : IF( GT_32( finc[i], etmp ) )
1604 : {
1605 3 : attack = 0;
1606 3 : move16();
1607 3 : BREAK;
1608 : }
1609 : }
1610 : }
1611 : }
1612 502 : ELSE IF( attack > 0 )
1613 : {
1614 477 : etmp2 = L_add( finc[attack], 0 );
1615 477 : etmp = Mult_32_16( etmp2, 25206 ); /* etmp2 / 1.3 = (etmp2*0.76923) */
1616 5688 : FOR( i = 2; i < att_3lsub_pos - 2; i++ )
1617 : {
1618 : /*if( i != attack && finc[i] * 1.3f > etmp2 ) -> finc[i] > (etmp2*0.76923) */
1619 5539 : test();
1620 5539 : IF( NE_16( i, attack ) && GT_32( finc[i], etmp ) )
1621 : {
1622 328 : attack = 0;
1623 328 : move16();
1624 328 : BREAK;
1625 : }
1626 : }
1627 : }
1628 :
1629 2050 : return attack;
1630 : }
1631 :
1632 : /* -------------------------------------------------------------------- - *
1633 : *ivas_smc_gmm()
1634 : *
1635 : *1st stage of the speech / music classification(based on the GMM model)
1636 : * -------------------------------------------------------------------- - */
1637 : /*! r: S/M decision (0=speech or noise,1=unclear,2=music) */
1638 1150754 : Word16 ivas_smc_gmm_fx(
1639 : Encoder_State *st, /* i/o: state structure */
1640 : STEREO_CLASSIF_HANDLE hStereoClassif, /* i/o: stereo classifier structure */
1641 : const Word16 localVAD_HE_SAD, /* i : HE-SAD flag without hangover */
1642 : const Word16 Etot_fx, /* i : total frame energy */
1643 : const Word16 lsp_new_fx[M], /* i : LSPs in current frame Q15 */
1644 : const Word16 cor_map_sum_fx, /* i : correlation map sum (from multi-harmonic anal.) Q8 */
1645 : const Word32 epsP_fx[M + 1], /* i : LP prediciton error */
1646 : const Word32 PS_fx[], /* i : energy spectrum */
1647 : const Word32 non_sta_fx, /* i : unbound non-stationarity Q20 */
1648 : const Word16 relE_fx, /* i : relative frame energy Q8 */
1649 : Word16 *high_lpn_flag, /* i/o: sp/mus LPN flag */
1650 : const Word16 flag_spitch, /* i : flag to indicate very short stable pitch */
1651 : Word16 Qfact_PS,
1652 : Word16 Q_esp,
1653 : Word16 Qfact_PS_past )
1654 : {
1655 : Word16 i, m, dec;
1656 : Word16 flag_odv;
1657 : Word32 lps_fx, lpm_fx, lpn_fx;
1658 : Word32 ps_fx[N_SMC_MIXTURES], pm_fx[N_SMC_MIXTURES], pn_fx[N_SMC_MIXTURES];
1659 : Word64 wprob_fx;
1660 : Word32 fvm_fx[N_PCA_COEF];
1661 : Word32 sum_PS_fx, ps_diff_fx;
1662 : Word32 dlp_fx, wrelE_fx, wdrop_fx, wght_fx;
1663 : Word32 wrise_fx;
1664 : Word16 dlp_mean2var_fx;
1665 : Word16 dlp_mean2var_q;
1666 : Word32 FV_fx[N_SMC_FEATURES], *pFV_fx;
1667 : Word32 dPS_fx[128];
1668 : Word32 PS_norm_fx[128];
1669 : const Word32 *pODV_fx;
1670 : Word32 *pFV_st_fx;
1671 : Word16 relE_attack_flag, smc_st_mean_fact_fx;
1672 : Word16 j, len;
1673 : const Word32 *pt_mel_fb_fx;
1674 : Word32 melS_fx[NB_MEL_BANDS], mfcc_fx[NB_MEL_BANDS];
1675 : Word16 odv_cnt;
1676 : Word16 i_out[N_SMC_FEATURES], *p_out;
1677 : Word16 temp_exp;
1678 : Word16 Qfact_FV;
1679 : Word32 temp32, temp32_log;
1680 : Word32 temp32_log1, temp32_log2;
1681 : Word16 temp16;
1682 1150754 : Word16 dotp_exp = 0;
1683 1150754 : move16();
1684 : /*------------------------------------------------------------------*
1685 : * Initialization
1686 : *------------------------------------------------------------------*/
1687 :
1688 1150754 : SP_MUS_CLAS_HANDLE hSpMusClas = st->hSpMusClas;
1689 : Word32 temp_sqrt, temp_acos;
1690 : /*------------------------------------------------------------------*
1691 : * State machine (sp_mus_state: -8 = INACTIVE, -7:-1 = UNSTABLE, 0:7 = ENTRY, 8 = STABLE )
1692 : *------------------------------------------------------------------*/
1693 :
1694 1150754 : IF( localVAD_HE_SAD )
1695 : {
1696 975852 : test();
1697 975852 : IF( LT_16( relE_fx, -5120 /*20 q8*/ ) )
1698 : {
1699 101441 : IF( hSpMusClas->sp_mus_state > 0 )
1700 : {
1701 10643 : if ( LT_16( hSpMusClas->sp_mus_state, HANG_LEN ) )
1702 : {
1703 : /* energy is too low but we are in entry period -> reset the inactive counter to allow new entry later */
1704 2333 : hSpMusClas->inact_cnt = 0;
1705 2333 : move16();
1706 : }
1707 :
1708 : /* energy is too low -> we are going to instable state */
1709 10643 : hSpMusClas->sp_mus_state = 0;
1710 10643 : move16();
1711 : }
1712 90798 : ELSE IF( GT_16( hSpMusClas->sp_mus_state, -HANG_LEN ) )
1713 : {
1714 : /* energy is still too low -> we are still in instable state */
1715 29506 : hSpMusClas->sp_mus_state = sub( hSpMusClas->sp_mus_state, 1 );
1716 : }
1717 : }
1718 874411 : ELSE IF( hSpMusClas->sp_mus_state <= 0 )
1719 : {
1720 21910 : IF( hSpMusClas->inact_cnt == 0 )
1721 : {
1722 :
1723 13710 : hSpMusClas->sp_mus_state = 1;
1724 13710 : move16();
1725 : }
1726 : ELSE
1727 : {
1728 :
1729 8200 : hSpMusClas->sp_mus_state = HANG_LEN;
1730 8200 : move16();
1731 : }
1732 :
1733 21910 : hSpMusClas->inact_cnt = 12;
1734 21910 : move16();
1735 : }
1736 852501 : ELSE IF( hSpMusClas->sp_mus_state > 0 && hSpMusClas->sp_mus_state < HANG_LEN )
1737 : {
1738 : /* we are inside an entry period -> increment the counter of entry frames */
1739 65439 : hSpMusClas->sp_mus_state = add( hSpMusClas->sp_mus_state, 1 );
1740 : }
1741 :
1742 975852 : test();
1743 975852 : IF( hSpMusClas->sp_mus_state < 0 && hSpMusClas->inact_cnt > 0 )
1744 : {
1745 30427 : hSpMusClas->inact_cnt = sub( hSpMusClas->inact_cnt, 1 );
1746 30427 : move16();
1747 : }
1748 : }
1749 : ELSE
1750 : {
1751 174902 : test();
1752 174902 : IF( hSpMusClas->sp_mus_state > 0 && LT_16( hSpMusClas->sp_mus_state, HANG_LEN ) )
1753 : {
1754 962 : hSpMusClas->inact_cnt = 0;
1755 962 : move16();
1756 : }
1757 173940 : ELSE IF( hSpMusClas->inact_cnt > 0 )
1758 : {
1759 23527 : hSpMusClas->inact_cnt = sub( hSpMusClas->inact_cnt, 1 );
1760 : }
1761 :
1762 174902 : test();
1763 174902 : IF( hSpMusClas->sp_mus_state > 0 && LT_16( hSpMusClas->sp_mus_state, HANG_LEN ) )
1764 : {
1765 962 : hSpMusClas->sp_mus_state = -HANG_LEN;
1766 962 : move16();
1767 : }
1768 173940 : ELSE IF( hSpMusClas->sp_mus_state > 0 )
1769 : {
1770 3423 : hSpMusClas->sp_mus_state = -1;
1771 3423 : move16();
1772 : }
1773 170517 : ELSE IF( GT_16( hSpMusClas->sp_mus_state, -HANG_LEN ) )
1774 : {
1775 : /* we are in inactive state */
1776 15646 : hSpMusClas->sp_mus_state = sub( hSpMusClas->sp_mus_state, 1 );
1777 : }
1778 : }
1779 :
1780 : /* detect attacks based on relE */
1781 1150754 : IF( GT_16( relE_fx, hSpMusClas->prev_relE_fx ) )
1782 : {
1783 487667 : hSpMusClas->relE_attack_sum_fx = add_sat( sub_sat( relE_fx, hSpMusClas->prev_relE_fx ), hSpMusClas->relE_attack_sum_fx ); /*q8*/
1784 487667 : move16();
1785 : }
1786 : ELSE
1787 : {
1788 663087 : hSpMusClas->relE_attack_sum_fx = 0; /*q8*/
1789 663087 : move16();
1790 : }
1791 1150754 : hSpMusClas->prev_relE_fx = relE_fx;
1792 1150754 : move16();
1793 1150754 : test();
1794 1150754 : test();
1795 1150754 : test();
1796 : /* update counter from last VAD 0->1 change */
1797 1150754 : IF( hSpMusClas->prev_vad == 0 && EQ_16( localVAD_HE_SAD, 1 ) )
1798 : {
1799 15626 : hSpMusClas->vad_0_1_cnt = 1;
1800 15626 : move16();
1801 : }
1802 1135128 : ELSE IF( EQ_16( localVAD_HE_SAD, 1 ) && hSpMusClas->vad_0_1_cnt > 0 && LT_16( hSpMusClas->vad_0_1_cnt, 50 ) )
1803 : {
1804 248523 : hSpMusClas->vad_0_1_cnt = add( hSpMusClas->vad_0_1_cnt, 1 );
1805 : }
1806 : ELSE
1807 : {
1808 886605 : hSpMusClas->vad_0_1_cnt = 0;
1809 886605 : move16();
1810 : }
1811 1150754 : hSpMusClas->prev_vad = localVAD_HE_SAD;
1812 1150754 : move16();
1813 1150754 : test();
1814 1150754 : test();
1815 1150754 : IF( hSpMusClas->sp_mus_state > 0 && LT_16( hSpMusClas->sp_mus_state, HANG_LEN ) && GT_16( hSpMusClas->relE_attack_sum_fx, 1280 /*q8*/ ) )
1816 : {
1817 23140 : hSpMusClas->relE_attack_cnt = add( hSpMusClas->relE_attack_cnt, 1 );
1818 :
1819 : /* set flag only in the first X frames in a series */
1820 23140 : IF( hSpMusClas->relE_attack_cnt > 0 && LT_16( hSpMusClas->relE_attack_cnt, 3 ) )
1821 : {
1822 16618 : relE_attack_flag = 1;
1823 : }
1824 : ELSE
1825 : {
1826 6522 : relE_attack_flag = 0;
1827 : }
1828 23140 : move16();
1829 : }
1830 : ELSE
1831 : {
1832 1127614 : hSpMusClas->relE_attack_cnt = 0;
1833 1127614 : move16();
1834 1127614 : relE_attack_flag = 0;
1835 1127614 : move16();
1836 : }
1837 :
1838 1150754 : hSpMusClas->prev_Etot_fx = Etot_fx;
1839 1150754 : move16();
1840 :
1841 : /*------------------------------------------------------------------*
1842 : * Preparation of the feature vector
1843 : *------------------------------------------------------------------*/
1844 :
1845 1150754 : pFV_fx = FV_fx;
1846 1150754 : test();
1847 1150754 : test();
1848 : /* [0] OL pitch */
1849 1150754 : IF( relE_attack_flag || EQ_16( st->tc_cnt, 1 ) || EQ_16( st->tc_cnt, 2 ) )
1850 : {
1851 115608 : *pFV_fx++ = L_shl( st->pitch[2], Q20 );
1852 : }
1853 : ELSE
1854 : {
1855 : // *pFV_fx++ = (float) ( st->pitch[0] + st->pitch[1] + st->pitch[2] ) / 3.0f;
1856 1035146 : *pFV_fx++ = Mpy_32_32( L_shl( add( add( st->pitch[0], st->pitch[1] ), st->pitch[2] ), Q20 ), 715827883 );
1857 : }
1858 1150754 : move32();
1859 :
1860 1150754 : test();
1861 1150754 : test();
1862 : /* [1] voicing */
1863 1150754 : IF( relE_attack_flag || EQ_16( st->tc_cnt, 1 ) || EQ_16( st->tc_cnt, 2 ) )
1864 : {
1865 115608 : *pFV_fx++ = L_shl( st->voicing_fx[2], 5 ); /*q20*/
1866 : }
1867 : ELSE
1868 : {
1869 : // *pFV++ = ( st->voicing[0] + st->voicing[1] + st->voicing[2] ) / 3.0f;
1870 1035146 : *pFV_fx++ = Mpy_32_32( L_shl( L_add( L_add( st->voicing_fx[0], st->voicing_fx[1] ), st->voicing_fx[2] ), Q5 ), 715827883 ); /*q20*/
1871 : }
1872 1150754 : move32();
1873 :
1874 1150754 : temp_exp = 1;
1875 1150754 : move16();
1876 1150754 : temp16 = lsp_new_fx[2];
1877 1150754 : move16();
1878 :
1879 1150754 : temp32 = L_sub( ONE_IN_Q30, L_mult0( temp16, temp16 ) ); // Q30
1880 1150754 : temp_sqrt = Sqrt32( temp32, &temp_exp );
1881 1150754 : temp_acos = BASOP_util_atan2( temp_sqrt, L_deposit_h( temp16 ), temp_exp );
1882 1150754 : *pFV_fx++ = L_shl( temp_acos, Q7 ); // Q20
1883 1150754 : move32();
1884 1150754 : temp_exp = 1;
1885 1150754 : move16();
1886 1150754 : temp16 = lsp_new_fx[3];
1887 1150754 : move16();
1888 :
1889 1150754 : temp32 = L_sub( ONE_IN_Q30, L_mult0( temp16, temp16 ) ); // Q30
1890 1150754 : temp_sqrt = Sqrt32( temp32, &temp_exp );
1891 1150754 : temp_acos = BASOP_util_atan2( temp_sqrt, L_deposit_h( temp16 ), temp_exp );
1892 1150754 : *pFV_fx++ = L_shl( temp_acos, Q7 ); // Q20
1893 1150754 : move32();
1894 1150754 : temp_exp = 1;
1895 1150754 : move16();
1896 1150754 : temp16 = lsp_new_fx[4];
1897 1150754 : move16();
1898 :
1899 1150754 : temp32 = L_sub( ONE_IN_Q30, L_mult0( temp16, temp16 ) ); // Q30
1900 1150754 : temp_sqrt = Sqrt32( temp32, &temp_exp );
1901 1150754 : temp_acos = BASOP_util_atan2( temp_sqrt, L_deposit_h( temp16 ), temp_exp );
1902 1150754 : *pFV_fx++ = L_shl( temp_acos, Q7 ); // Q20
1903 1150754 : move32();
1904 1150754 : temp_exp = 1;
1905 1150754 : move16();
1906 1150754 : temp16 = lsp_new_fx[5];
1907 1150754 : move16();
1908 :
1909 1150754 : temp32 = L_sub( ONE_IN_Q30, L_mult0( temp16, temp16 ) ); // Q30
1910 1150754 : temp_sqrt = Sqrt32( temp32, &temp_exp );
1911 1150754 : temp_acos = BASOP_util_atan2( temp_sqrt, L_deposit_h( temp16 ), temp_exp );
1912 1150754 : *pFV_fx++ = L_shl( temp_acos, Q7 ); // Q20
1913 1150754 : move32();
1914 1150754 : temp_exp = 1;
1915 1150754 : move16();
1916 1150754 : temp16 = lsp_new_fx[6];
1917 1150754 : move16();
1918 :
1919 :
1920 1150754 : temp32 = L_sub( ONE_IN_Q30, L_mult0( temp16, temp16 ) ); // Q30
1921 1150754 : temp_sqrt = Sqrt32( temp32, &temp_exp );
1922 1150754 : temp_acos = BASOP_util_atan2( temp_sqrt, L_deposit_h( temp16 ), temp_exp );
1923 1150754 : *pFV_fx++ = L_shl( temp_acos, Q7 ); // Q20
1924 1150754 : move32();
1925 : // temf = acosf( lsp_new[2] );
1926 : /* [2,3,4,5,6] LSFs */
1927 : /* *pFV++ = acosf( lsp_new[2] );
1928 : *pFV++ = acosf( lsp_new[3] );
1929 : *pFV++ = acosf( lsp_new[4] );
1930 : *pFV++ = acosf( lsp_new[5] );
1931 : *pFV++ = acosf( lsp_new[6] );*/
1932 :
1933 : /* [7] cor_map_sum */
1934 1150754 : *pFV_fx++ = L_shl( cor_map_sum_fx, Q12 ); /*scaling from Q8 to Q20*/
1935 1150754 : move32();
1936 :
1937 : /* [8] non_sta */
1938 1150754 : *pFV_fx++ = non_sta_fx; /*Q20*/
1939 1150754 : move32();
1940 :
1941 : /* [9] epsP */
1942 1150754 : temp32 = L_add( epsP_fx[14], L_shr( 21475, sub( 31, Q_esp ) ) );
1943 1150754 : temp32_log = L_add( BASOP_Util_Log2( temp32 ), L_shl( sub( Q31, Q_esp ), Q25 ) );
1944 1150754 : temp32_log1 = Mpy_32_32( temp32_log, 1488522239 ); /*logf(x) = log2(x)*logf(2)*/
1945 :
1946 1150754 : temp32 = L_add( epsP_fx[0], L_shr( 21475, sub( 31, Q_esp ) ) );
1947 1150754 : temp32_log = L_add( BASOP_Util_Log2( temp32 ), L_shl( sub( Q31, Q_esp ), Q25 ) );
1948 1150754 : temp32_log2 = Mpy_32_32( temp32_log, 1488522239 ); /*logf(x) = log2(x)*logf(2)*/
1949 :
1950 1150754 : *pFV_fx++ = L_shr( L_sub( temp32_log1, temp32_log2 ), Q5 );
1951 1150754 : move32();
1952 : //*pFV++ = logf( epsP[14] + 1e-5f ) - logf( epsP[0] + 1e-5f );
1953 :
1954 : /* [10,11,12] MFCCs */
1955 1150754 : set_zero_fx( melS_fx, NB_MEL_BANDS );
1956 :
1957 1150754 : pt_mel_fb_fx = mel_fb_fx;
1958 :
1959 47180914 : FOR( i = 0; i < NB_MEL_BANDS; i++ )
1960 : {
1961 46030160 : j = mel_fb_start[i];
1962 46030160 : move16();
1963 46030160 : len = mel_fb_len[i];
1964 46030160 : move16();
1965 46030160 : temp32 = dotp_me_fx( &PS_fx[j], pt_mel_fb_fx, len, 31 - Qfact_PS, Q1, &dotp_exp );
1966 46030160 : IF( LT_16( dotp_exp, -17 ) ) /*-18 is exponent of 10737:to avoid overflow when left shifting 10737*/
1967 : {
1968 2382 : temp32 = L_shr( temp32, sub( -17, dotp_exp ) );
1969 2382 : dotp_exp = -17;
1970 2382 : move16();
1971 : }
1972 46030160 : temp32_log = L_add_sat( BASOP_Util_Log2( L_add_sat( L_shr( temp32, 1 ), L_shr( 10737 /*1e-5f q30*/, dotp_exp ) ) ), L_shl( add( dotp_exp, 1 ), Q25 ) );
1973 46030160 : temp32_log = Mpy_32_32( temp32_log, 1488522239 ); /*logf(x) = log2(x)*logf(2)*/
1974 46030160 : melS_fx[i] = temp32_log;
1975 46030160 : move32();
1976 : // melS[i] = logf( dotp( &PS[j], pt_mel_fb, len ) + 1e-5f );
1977 46030160 : pt_mel_fb_fx += len;
1978 : }
1979 :
1980 1150754 : Word16 guard_bits = find_guarded_bits_fx( NB_MEL_BANDS );
1981 1150754 : move16();
1982 1150754 : v_mult_mat_fixed( mfcc_fx, melS_fx, dct_mtx_fx, NB_MEL_BANDS, NB_MEL_COEF, guard_bits ); // Q19
1983 1150754 : *pFV_fx++ = L_shl( mfcc_fx[2], 1 ); // Q20
1984 1150754 : move32();
1985 1150754 : *pFV_fx++ = L_shl( mfcc_fx[6], 1 );
1986 1150754 : move32();
1987 1150754 : *pFV_fx++ = L_shl( mfcc_fx[12], 1 );
1988 1150754 : move32();
1989 : /* *pFV++ = mfcc[2];
1990 : *pFV++ = mfcc[6];
1991 : *pFV++ = mfcc[12];*/
1992 :
1993 : /* calculation of differential normalized power spectrum */
1994 1150754 : sum_PS_fx = 0;
1995 1150754 : move32();
1996 : Word16 q_temp32;
1997 1150754 : Word16 sum_PS_e = 0;
1998 1150754 : move16();
1999 1150754 : Word64 sum = W_shl( 21475 /* 1e-5 in Q31 */, sub( Qfact_PS, 30 ) ); // Qfact_PS+1
2000 1150754 : move64();
2001 78251272 : FOR( i = LOWEST_FBIN; i < HIGHEST_FBIN; i++ )
2002 : {
2003 77100518 : sum = W_mac_32_32( sum, PS_fx[i], 1 ); // Qfact_PS+1
2004 : }
2005 1150754 : IF( sum == 0 )
2006 : {
2007 0 : sum_PS_fx = 1407374884; // 1e-5 in Q47
2008 0 : move32();
2009 0 : sum_PS_e = -16;
2010 0 : move16();
2011 : }
2012 : ELSE
2013 : {
2014 1150754 : sum_PS_e = W_norm( sum );
2015 1150754 : sum_PS_fx = W_extract_h( W_shl( sum, sum_PS_e ) ); // Qfact_PS+1+sum_PS_e-32
2016 1150754 : sum_PS_e = sub( 62, add( Qfact_PS, sum_PS_e ) ); // 31-(Qfact_PS+1+sum_PS_e-32)
2017 : }
2018 :
2019 78251272 : FOR( i = LOWEST_FBIN; i < HIGHEST_FBIN; i++ )
2020 : {
2021 77100518 : temp32 = BASOP_Util_Divide3232_Scale_newton( PS_fx[i], sum_PS_fx, &temp_exp ); // 31-temp_exp
2022 77100518 : q_temp32 = add( sub( 31, temp_exp ), sub( Qfact_PS, sub( 31, sum_PS_e ) ) );
2023 77100518 : test();
2024 77100518 : if ( temp32 == 0 )
2025 : {
2026 281 : q_temp32 = 31;
2027 281 : move16();
2028 : }
2029 77100518 : IF( LT_16( q_temp32, 31 ) && EQ_32( temp32, L_shl( 1, q_temp32 ) ) )
2030 : {
2031 0 : temp32 = ONE_IN_Q31;
2032 0 : move32();
2033 0 : q_temp32 = Q31;
2034 0 : move16();
2035 : }
2036 77100518 : PS_norm_fx[i] = L_shl( temp32, sub( Qfact_PS_past, q_temp32 ) ); // Qfact_PS_past
2037 77100518 : move32();
2038 77100518 : dPS_fx[i] = L_abs( L_sub( PS_norm_fx[i], hSpMusClas->past_PS_fx[i - LOWEST_FBIN] ) );
2039 77100518 : move32();
2040 : }
2041 :
2042 : /* [13] ps_diff (spectral difference) */
2043 1150754 : ps_diff_fx = 0;
2044 1150754 : move32();
2045 78251272 : FOR( i = LOWEST_FBIN; i < HIGHEST_FBIN; i++ )
2046 : {
2047 77100518 : ps_diff_fx = L_add( L_shr( dPS_fx[i], Q7 ), ps_diff_fx ); // Qfact_PS_past-7
2048 : }
2049 :
2050 1150754 : *pFV_fx++ = L_shr( ps_diff_fx, sub( sub( Qfact_PS_past, Q7 ), Q20 ) ); /// ps_diff;
2051 1150754 : move32();
2052 :
2053 : /* [14] ps_sta (spectral stationarity) */
2054 1150754 : Word32 ps_sta_fx = 0;
2055 1150754 : move32();
2056 1150754 : Word16 ps_sta_exp = 0;
2057 1150754 : move16();
2058 : Word32 avoid_divide_by_zero;
2059 1150754 : avoid_divide_by_zero = L_shr( 21475, sub( 31, Qfact_PS_past ) ); // 21475 = 1e-5 in Q31
2060 :
2061 78251272 : FOR( i = LOWEST_FBIN; i < HIGHEST_FBIN; i++ )
2062 : {
2063 : Word32 tmp_max;
2064 77100518 : tmp_max = L_max( PS_norm_fx[i], hSpMusClas->past_PS_fx[i - LOWEST_FBIN] );
2065 : /* Saturation doesn't have a significant impact here, as a value of 1e-5 in Q31 format is added to prevent division by zero */
2066 77100518 : temp32 = BASOP_Util_Divide3232_Scale_newton( tmp_max, L_add_sat( dPS_fx[i], avoid_divide_by_zero ), &temp_exp ); // 31-temp_exp
2067 77100518 : ps_sta_fx = BASOP_Util_Add_Mant32Exp( temp32, temp_exp, ps_sta_fx, ps_sta_exp, &ps_sta_exp );
2068 : }
2069 1150754 : temp32_log = L_add( BASOP_Util_Log2( L_add_sat( ps_sta_fx, L_shr( 21475, ps_sta_exp ) ) ), L_shl( ps_sta_exp, Q25 ) );
2070 1150754 : temp32_log = Mpy_32_32( temp32_log, 1488522239 ); /*logf(x) = log2(x)*logf(2)*/
2071 1150754 : *pFV_fx++ = L_shr( temp32_log, Q5 ); // logf( ps_sta + 1e-5f );
2072 1150754 : move32();
2073 1150754 : MVR2R_WORD32( &PS_norm_fx[LOWEST_FBIN], hSpMusClas->past_PS_fx, HIGHEST_FBIN - LOWEST_FBIN );
2074 :
2075 : /* save ps_diff and ps_sta features for XTALK and UNCLR classifier */
2076 1150754 : IF( hStereoClassif != NULL )
2077 : {
2078 782051 : IF( st->idchan == 0 )
2079 : {
2080 420855 : hStereoClassif->ps_diff_ch1_fx = ps_diff_fx; // Qfact_PS_past - 7
2081 420855 : hStereoClassif->ps_diff_ch1_e = sub( 38, Qfact_PS_past ); // Qfact_PS_past - 7
2082 420855 : hStereoClassif->ps_sta_ch1_fx = temp32_log; // logf( ps_sta + 1e-5f );Q25
2083 420855 : hStereoClassif->ps_sta_ch1_e = 6; // logf( ps_sta + 1e-5f );Q25
2084 : }
2085 : ELSE
2086 : {
2087 361196 : hStereoClassif->ps_diff_ch2_fx = ps_diff_fx;
2088 361196 : hStereoClassif->ps_diff_ch2_e = sub( 38, Qfact_PS_past );
2089 361196 : hStereoClassif->ps_sta_ch2_fx = temp32_log; // logf( ps_sta + 1e-5f );Q25
2090 361196 : hStereoClassif->ps_sta_ch2_e = 6; // logf( ps_sta + 1e-5f );Q25
2091 : }
2092 782051 : move32();
2093 782051 : move16();
2094 782051 : move32();
2095 782051 : move16();
2096 : }
2097 :
2098 : /*------------------------------------------------------------------*
2099 : * Outlier detection based on feature histograms
2100 : *------------------------------------------------------------------*/
2101 1150754 : flag_odv = 0;
2102 1150754 : move16();
2103 1150754 : IF( localVAD_HE_SAD )
2104 : {
2105 975852 : pFV_fx = FV_fx;
2106 975852 : pODV_fx = hout_intervals_fx;
2107 975852 : p_out = i_out;
2108 975852 : odv_cnt = 0;
2109 975852 : move16();
2110 15613632 : FOR( i = 0; i < N_SMC_FEATURES; i++ )
2111 : {
2112 14637780 : test();
2113 14637780 : IF( LT_32( *pFV_fx, pODV_fx[0] ) || GT_32( *pFV_fx, pODV_fx[1] ) )
2114 : {
2115 2510 : *p_out++ = i;
2116 2510 : odv_cnt = add( odv_cnt, 1 );
2117 : }
2118 :
2119 14637780 : pFV_fx++;
2120 14637780 : pODV_fx += 2;
2121 : }
2122 :
2123 : /* set outlier flag */
2124 975852 : IF( GE_16( odv_cnt, 2 ) )
2125 : {
2126 549 : flag_odv = 1;
2127 549 : move16();
2128 : /* replace outlying features with values from the previous frame */
2129 1954 : FOR( i = 0; i < odv_cnt; i++ )
2130 : {
2131 1405 : FV_fx[i_out[i]] = hSpMusClas->prev_FV_fx[i_out[i]];
2132 1405 : move32();
2133 : }
2134 : }
2135 : }
2136 :
2137 : /*------------------------------------------------------------------*
2138 : * Adaptive short-term mean filter on feature vector
2139 : *------------------------------------------------------------------*/
2140 1150754 : Qfact_FV = 20;
2141 1150754 : move16();
2142 1150754 : pFV_fx = FV_fx;
2143 1150754 : pFV_st_fx = hSpMusClas->FV_st_fx;
2144 1150754 : smc_st_mean_fact_fx = SMC_ST_MEAN_RSHIFT_FACT_FX;
2145 1150754 : move16();
2146 18412064 : FOR( i = 0; i < N_SMC_FEATURES; i++ )
2147 : {
2148 : //*pFV_st = smc_st_mean_fact * ( *pFV_st ) + ( 1 - smc_st_mean_fact ) * ( *pFV );
2149 17261310 : *pFV_st_fx = L_add( L_shr( *pFV_st_fx, smc_st_mean_fact_fx ), L_shr( *pFV_fx, 1 ) );
2150 17261310 : move32();
2151 :
2152 17261310 : test();
2153 17261310 : test();
2154 17261310 : test();
2155 17261310 : test();
2156 17261310 : test();
2157 17261310 : IF( hSpMusClas->sp_mus_state > 0 && LT_16( hSpMusClas->sp_mus_state, HANG_LEN ) && ( relE_attack_flag || flag_odv ) )
2158 : {
2159 : /* strong attack or outlier frame during entry state -> features cannot be trusted but there is also no useful past info -> */
2160 : /* -> do whatever you want because dlp will be reset to 0 anyway */
2161 249270 : pFV_fx++;
2162 249270 : pFV_st_fx++;
2163 : }
2164 17012040 : ELSE IF( hSpMusClas->sp_mus_state == HANG_LEN && ( EQ_16( st->tc_cnt, 1 ) || EQ_16( st->tc_cnt, 2 ) ) )
2165 : {
2166 : /* energy attack in stable state -> use current features intead of the long-term average */
2167 1355010 : pFV_fx++;
2168 1355010 : pFV_st_fx++;
2169 : }
2170 : ELSE
2171 : {
2172 15657030 : *pFV_fx++ = *pFV_st_fx++;
2173 15657030 : move32();
2174 : }
2175 : }
2176 :
2177 : /* update */
2178 1150754 : MVR2R_WORD32( FV_fx, hSpMusClas->prev_FV_fx, N_SMC_FEATURES );
2179 : /*------------------------------------------------------------------*
2180 : * Non-linear power transformation (boxcox) on certain features
2181 : *------------------------------------------------------------------*/
2182 1150754 : pFV_fx = FV_fx;
2183 18412064 : FOR( i = 0; i < N_SMC_FEATURES; i++ )
2184 : {
2185 17261310 : IF( bcox_lmbd_fx[i] != 0 )
2186 : {
2187 3452262 : *pFV_fx = L_sub( *pFV_fx, L_shr( bcox_add_cnst_fx[i], sub( 31, Qfact_FV ) ) );
2188 3452262 : move32();
2189 3452262 : IF( LT_32( *pFV_fx, L_shl( 1, Qfact_FV ) ) )
2190 : {
2191 112189 : *pFV_fx = L_shl( 1, Qfact_FV );
2192 112189 : move32();
2193 : }
2194 3452262 : Word16 pow_e = 0;
2195 3452262 : move32();
2196 3452262 : temp32_log = L_add( BASOP_Util_Log2( *pFV_fx ), L_shl( sub( 31, Qfact_FV ), Q25 ) ); // Q25
2197 3452262 : temp32 = Mpy_32_32( temp32_log, bcox_lmbd_fx[i] ); // Q25
2198 3452262 : Word32 pow_temp = BASOP_util_Pow2( temp32, 31 - Q25, &pow_e );
2199 3452262 : IF( pow_e <= 0 )
2200 : {
2201 1035347 : pow_temp = L_shr( pow_temp, sub( 1, pow_e ) );
2202 1035347 : pow_e = add( pow_e, sub( 1, pow_e ) );
2203 : }
2204 3452262 : temp32 = L_sub( pow_temp, L_shl( 1, 31 - pow_e ) );
2205 3452262 : temp_exp = 0;
2206 3452262 : move32();
2207 3452262 : temp32 = L_deposit_h( BASOP_Util_Divide3232_Scale( temp32, bcox_lmbd_fx[i], &temp_exp ) );
2208 3452262 : *pFV_fx = L_shl( temp32, sub( Qfact_FV, sub( 31, add( temp_exp, pow_e ) ) ) );
2209 3452262 : move32();
2210 : // float temp = powf( *pFV, bcox_lmbd[i] );
2211 : // *pFV = ( powf( *pFV, bcox_lmbd[i] ) - 1 ) / bcox_lmbd[i];
2212 : }
2213 :
2214 17261310 : pFV_fx++;
2215 : }
2216 :
2217 : /*------------------------------------------------------------------*
2218 : * Scaling of the feature vector
2219 : * PCA
2220 : *------------------------------------------------------------------*/
2221 :
2222 1150754 : pFV_fx = FV_fx;
2223 18412064 : FOR( i = 0; i < N_SMC_FEATURES; i++ )
2224 : {
2225 : /* Standard scaler - mean and variance normalization */
2226 : // *pFV = ( *pFV - sm_means[i] ) / sm_scale[i];
2227 17261310 : temp32 = L_sub( *pFV_fx, sm_means_fx[i] );
2228 17261310 : temp_exp = 0;
2229 17261310 : move16();
2230 17261310 : temp32 = L_deposit_h( BASOP_Util_Divide3232_Scale( temp32, sm_scale_fx[i], &temp_exp ) );
2231 : // *pFV_fx = L_shl( temp32, Qfact_FV - ( 31 - temp_exp ) );
2232 17261310 : *pFV_fx = L_shl( temp32, sub( Qfact_FV, sub( 31, temp_exp ) ) );
2233 17261310 : move32();
2234 17261310 : pFV_fx++;
2235 : /* MinMax sclaer - mean and variance normalization */
2236 : /**pFV = *pFV * sm_scale[i] + sm_min[i];*/
2237 : }
2238 :
2239 : /* PCA */
2240 1150754 : v_sub_fixed_no_hdrm( FV_fx, pca_mean_fx, FV_fx, N_SMC_FEATURES );
2241 1150754 : v_mult_mat_fixed( FV_fx, FV_fx, pca_components_fx, N_SMC_FEATURES, N_PCA_COEF, 0 );
2242 : /*------------------------------------------------------------------*
2243 : * Calculation of posterior probability
2244 : * Log-probability
2245 : *------------------------------------------------------------------*/
2246 :
2247 : /* run loop for all mixtures (for each mixture, calculate the probability of speech, music and noise) */
2248 1150754 : lps_fx = lpm_fx = lpn_fx = 0;
2249 1150754 : move32();
2250 1150754 : move32();
2251 1150754 : move32();
2252 :
2253 8055278 : FOR( m = 0; m < N_SMC_MIXTURES; m++ )
2254 : {
2255 6904524 : v_sub32_fx( FV_fx, &means_speech_fx[m * N_PCA_COEF], fvm_fx, N_PCA_COEF );
2256 6904524 : wprob_fx = dot_product_cholesky_fixed( fvm_fx, &prec_chol_speech_fx[m * ( N_PCA_COEF * N_PCA_COEF + N_PCA_COEF ) / 2], N_PCA_COEF ); // Q10
2257 6904524 : ps_fx[m] = L_sub( L_sub( L_add( log_weights_speech_compute[m], log_det_chol_speech_fx[m] ), W_extract_l( W_shr( wprob_fx, Q10 ) ) ), HALF_N_PCA_COEF_LOG_P12_Q18 ); // Q18
2258 6904524 : move32();
2259 6904524 : v_sub32_fx( FV_fx, &means_music_fx[m * N_PCA_COEF], fvm_fx, N_PCA_COEF );
2260 6904524 : wprob_fx = dot_product_cholesky_fixed( fvm_fx, &prec_chol_music_fx[m * ( N_PCA_COEF * N_PCA_COEF + N_PCA_COEF ) / 2], N_PCA_COEF ); // Q10
2261 6904524 : pm_fx[m] = L_sub( L_sub( L_add( log_weights_music_compute[m], log_det_chol_music_fx[m] ), W_extract_l( W_shr( wprob_fx, Q10 ) ) ), HALF_N_PCA_COEF_LOG_P12_Q18 ); // Q18
2262 6904524 : move32();
2263 6904524 : v_sub32_fx( FV_fx, &means_noise_fx[m * N_PCA_COEF], fvm_fx, N_PCA_COEF );
2264 6904524 : wprob_fx = dot_product_cholesky_fixed( fvm_fx, &prec_chol_noise_fx[m * ( N_PCA_COEF * N_PCA_COEF + N_PCA_COEF ) / 2], N_PCA_COEF ); // Q10
2265 6904524 : pn_fx[m] = L_sub( L_sub( L_add( log_weights_noise_compute[m], log_det_chol_noise_fx[m] ), W_extract_l( W_shr( wprob_fx, Q10 ) ) ), HALF_N_PCA_COEF_LOG_P12_Q18 ); // Q18
2266 6904524 : move32();
2267 : }
2268 :
2269 1150754 : lps_fx = logsumexp_fx( ps_fx, 31 - Q18, N_SMC_MIXTURES );
2270 1150754 : lpm_fx = logsumexp_fx( pm_fx, 31 - Q18, N_SMC_MIXTURES );
2271 1150754 : lpn_fx = logsumexp_fx( pn_fx, 31 - Q18, N_SMC_MIXTURES );
2272 1150754 : *high_lpn_flag = 0;
2273 1150754 : move16();
2274 1150754 : if ( GT_32( lpn_fx, lps_fx ) && GT_32( lpn_fx, lpm_fx ) )
2275 : {
2276 143347 : *high_lpn_flag = 1;
2277 143347 : move32();
2278 : }
2279 1150754 : hSpMusClas->lpm_fx = extract_h( L_shl_sat( lpm_fx, 16 - 11 ) ); // Q7
2280 1150754 : move16();
2281 1150754 : hSpMusClas->lps_fx = extract_h( L_shl_sat( lps_fx, 16 - 11 ) ); // Q7
2282 1150754 : move16();
2283 1150754 : hSpMusClas->lpn_fx = extract_h( L_shl_sat( lpn_fx, 16 - 11 ) ); // Q7
2284 1150754 : move16();
2285 : /* determine HQ Generic speech class */
2286 1150754 : IF( st->hHQ_core != NULL )
2287 : {
2288 421725 : IF( GT_32( lps_fx, L_add( lpm_fx, ONE_IN_Q17 ) ) )
2289 : {
2290 160017 : st->hHQ_core->hq_generic_speech_class = 1;
2291 : }
2292 : ELSE
2293 : {
2294 261708 : st->hHQ_core->hq_generic_speech_class = 0;
2295 : }
2296 421725 : move16();
2297 : }
2298 :
2299 : /*------------------------------------------------------------------*
2300 : * Decision without hangover
2301 : * Weighted decision
2302 : *------------------------------------------------------------------*/
2303 1150754 : test();
2304 1150754 : test();
2305 1150754 : test();
2306 1150754 : test();
2307 1150754 : test();
2308 : /* decision without hangover (0 - speech/noise, 1 - music) */
2309 1150754 : IF( !localVAD_HE_SAD || LT_16( Etot_fx, 2560 ) || ( hSpMusClas->sp_mus_state > 0 && LT_16( hSpMusClas->sp_mus_state, HANG_LEN ) && ( relE_attack_flag || flag_odv ) ) )
2310 : {
2311 215659 : dlp_fx = 0;
2312 215659 : move32();
2313 : }
2314 : ELSE
2315 : {
2316 935095 : dlp_fx = L_add( L_sub( lpm_fx, lps_fx ), DLP_BIAS_FX );
2317 935095 : dlp_fx = L_shl( dlp_fx, 1 ); // Q19
2318 :
2319 935095 : IF( GT_32( dlp_fx, 15728640 ) ) /*30.0f in Q19*/
2320 : {
2321 33252 : dlp_fx = 15728640;
2322 : }
2323 901843 : ELSE IF( LT_32( dlp_fx, -15728640 ) )
2324 : {
2325 0 : dlp_fx = -15728640;
2326 : }
2327 935095 : move32();
2328 : }
2329 :
2330 1150754 : dec = (Word16) GT_32( dlp_fx, 0 );
2331 1150754 : move16();
2332 : /* calculate weight based on relE (higher relE -> lower weight, lower relE -> higher weight) */
2333 :
2334 1150754 : wrelE_fx = lin_interp32_fx( L_deposit_h( relE_fx ), 15 << 24, 1932735283 /*0.9 in Q31*/, -( 15 << 24 ), 2126008812 /*0.99 in Q31*/, 1 ); // Q31
2335 : /* calculate weight based on drops of dlp (close to 1 during sudden drops of dlp, close to 0 otherwise) */
2336 : // hSpMusClas->dlp_mean_ST = 0.8f * hSpMusClas->dlp_mean_ST + 0.2f * dlp;
2337 1150754 : hSpMusClas->dlp_mean_ST_fx = L_add( Mpy_32_32( 1717986918, hSpMusClas->dlp_mean_ST_fx ), Mpy_32_32( 429496729, dlp_fx ) );
2338 1150754 : hSpMusClas->lt_dec_thres_fx = extract_l( L_shr( hSpMusClas->dlp_mean_ST_fx, 10 ) );
2339 1150754 : test();
2340 1150754 : IF( dlp_fx < 0 && LT_32( dlp_fx, hSpMusClas->dlp_mean_ST_fx ) )
2341 : {
2342 259528 : IF( hSpMusClas->dlp_mean_ST_fx > 0 )
2343 : {
2344 77462 : hSpMusClas->wdrop_32fx = L_negate( dlp_fx ); // Q19
2345 77462 : move32();
2346 : }
2347 182066 : ELSE IF( hSpMusClas->wdrop_32fx > 0 )
2348 : {
2349 42255 : hSpMusClas->wdrop_32fx = L_add( hSpMusClas->wdrop_32fx, L_sub( hSpMusClas->dlp_mean_ST_fx, dlp_fx ) );
2350 42255 : move32();
2351 : }
2352 259528 : move16();
2353 : }
2354 : ELSE
2355 : {
2356 891226 : hSpMusClas->wdrop_32fx = 0;
2357 891226 : move32();
2358 : }
2359 1150754 : wdrop_fx = lin_interp32_fx( hSpMusClas->wdrop_32fx, 7864320, 1503238554 /* 0.7 in Q31 */, 0, ONE_IN_Q31 /* 1.0f in Q31 */, 1 ); /* Q31 */
2360 :
2361 1150754 : test();
2362 1150754 : test();
2363 : /* calculate weight based on rises of dlp (close to 1 during sudden rise of dlp, close to 0 otherwise) */
2364 1150754 : IF( EQ_16( hSpMusClas->sp_mus_state, HANG_LEN ) && hSpMusClas->dlp_mean_ST_fx > 0 && GT_32( hSpMusClas->dlp_mean_ST_fx, hSpMusClas->past_dlp_mean_ST_fx[0] ) )
2365 : {
2366 251909 : IF( hSpMusClas->past_dlp_mean_ST_fx[0] < 0 )
2367 : {
2368 14052 : hSpMusClas->wrise_fx = extract_l( L_shr( hSpMusClas->dlp_mean_ST_fx, 10 ) );
2369 : }
2370 237857 : ELSE IF( hSpMusClas->wrise_fx > 0 )
2371 : {
2372 34982 : hSpMusClas->wrise_fx = add( hSpMusClas->wrise_fx, extract_l( L_shr( L_sub( hSpMusClas->dlp_mean_ST_fx, hSpMusClas->past_dlp_mean_ST_fx[0] ), 10 ) ) );
2373 : }
2374 251909 : move16();
2375 : }
2376 : ELSE
2377 : {
2378 898845 : hSpMusClas->wrise_fx = 0;
2379 898845 : move16();
2380 : }
2381 :
2382 :
2383 1150754 : wrise_fx = lin_interp32_fx( L_deposit_h( hSpMusClas->wrise_fx ), 167772160, 2040109466 /* 0.95 in Q31 */, 0, ONE_IN_Q31 /* 1.0f in Q31 */, 1 ); /* Q31 */
2384 : /* combine weights into one */
2385 : // wght = wrelE * wdrop * wrise;
2386 1150754 : wght_fx = Mpy_32_32( Mpy_32_32( wrelE_fx, wdrop_fx ), wrise_fx ); /* Q31 */
2387 1150754 : test();
2388 : /* ratio of delta means vs. delta variances */
2389 1150754 : IF( hSpMusClas->sp_mus_state > 0 && LT_16( hSpMusClas->sp_mus_state, HANG_LEN ) )
2390 : {
2391 :
2392 71311 : hSpMusClas->dlp_mean_LT_fx = dlp_fx;
2393 71311 : move32();
2394 71311 : hSpMusClas->dlp_var_LT_fx = 0;
2395 71311 : move32();
2396 : }
2397 :
2398 1150754 : hSpMusClas->dlp_mean_LT_fx = L_add( Mpy_32_32( 1932735283, hSpMusClas->dlp_mean_LT_fx ), Mpy_32_32( 214748365, dlp_fx ) ); // Q19
2399 :
2400 1150754 : temp32 = L_sub( dlp_fx, hSpMusClas->dlp_mean_LT_fx );
2401 1150754 : temp32 = W_extract_l( W_shr( W_mult0_32_32( temp32, temp32 ), 19 ) ); /*q19*/
2402 1150754 : hSpMusClas->dlp_var_LT_fx = L_add( Mpy_32_32( 1932735283, hSpMusClas->dlp_var_LT_fx ), Mpy_32_32( 214748365, temp32 ) );
2403 :
2404 1150754 : test();
2405 1150754 : IF( hSpMusClas->sp_mus_state > 0 && LT_16( hSpMusClas->sp_mus_state, HANG_LEN ) )
2406 : {
2407 71311 : dlp_mean2var_fx = 0;
2408 71311 : move16();
2409 71311 : dlp_mean2var_q = 0;
2410 71311 : move16();
2411 : }
2412 : ELSE
2413 : {
2414 1079443 : temp_exp = sub( Q31, Q19 );
2415 1079443 : Word16 div_e = 0;
2416 1079443 : move16();
2417 1079443 : temp_sqrt = Sqrt32( L_abs( hSpMusClas->dlp_var_LT_fx ), &temp_exp );
2418 1079443 : IF( temp_exp < 0 )
2419 : {
2420 61815 : temp_sqrt = L_shl( temp_sqrt, temp_exp );
2421 61815 : temp_exp = 0;
2422 61815 : move16();
2423 : }
2424 1079443 : temp_sqrt = L_shr( temp_sqrt, 1 ); /*adding 1 as guard bit to avoid overflow in addition*/
2425 1079443 : temp_exp = add( temp_exp, 1 );
2426 1079443 : temp_sqrt = L_add( temp_sqrt, L_shl( 1, sub( 31, temp_exp ) ) );
2427 1079443 : dlp_mean2var_fx = BASOP_Util_Divide3232_Scale( L_abs( hSpMusClas->dlp_mean_LT_fx ), temp_sqrt, &div_e );
2428 1079443 : dlp_mean2var_q = sub( add( Q3, temp_exp ), div_e ); // 15-div_e+Q19 -(31-temp_exp)
2429 1079443 : IF( GT_16( dlp_mean2var_q, 26 ) )
2430 : {
2431 17230 : dlp_mean2var_fx = shl( dlp_mean2var_fx, sub( 26, dlp_mean2var_q ) );
2432 17230 : dlp_mean2var_q = 26;
2433 17230 : move16();
2434 : }
2435 : }
2436 :
2437 1150754 : IF( GT_32( L_deposit_l( dlp_mean2var_fx ), L_shl( 15, dlp_mean2var_q ) ) )
2438 : {
2439 : /* decrease the weight little bit when the classifier indicates "strong speech" or "strong music" */
2440 3145 : wght_fx = Mpy_32_32( wght_fx, 1932735283 /* 0.9f in Q31 */ ); /* Q31 */
2441 : }
2442 :
2443 1150754 : IF( GT_32( wght_fx, ONE_IN_Q31 ) )
2444 : {
2445 0 : wght_fx = ONE_IN_Q31; /* 1.0f in Q31 */
2446 : }
2447 1150754 : ELSE IF( LT_32( wght_fx, 21474836 /* 0.01f in Q31 */ ) )
2448 : {
2449 0 : wght_fx = 21474836; /* 0.01f in Q31 */
2450 : }
2451 1150754 : move32();
2452 1150754 : if ( LT_16( Etot_fx, 2560 /* 10f in Q8 */ ) )
2453 : {
2454 : /* silence */
2455 135238 : wght_fx = 1975684956; /* 0.92f in Q31 */
2456 135238 : move32();
2457 : }
2458 :
2459 : /* calculate weighted decision */
2460 : // hSpMusClas->wdlp_0_95_sp = wght * hSpMusClas->wdlp_0_95_sp + ( 1 - wght ) * dlp;
2461 1150754 : hSpMusClas->wdlp_0_95_sp_32fx = L_add( Mpy_32_32( wght_fx, hSpMusClas->wdlp_0_95_sp_32fx /*q24*/ ), Mpy_32_32( L_sub( ONE_IN_Q31, wght_fx ), L_shl( dlp_fx /*q19*/, 5 ) ) ); // Q24
2462 1150754 : move32();
2463 :
2464 : /* xtalk classifier: apply long hysteresis to prevent LRTD on music */
2465 :
2466 1150754 : hSpMusClas->wdlp_xtalk_fx = Madd_32_32( Mpy_32_32( 2136746230 /* 0.995f in Q31*/, hSpMusClas->wdlp_xtalk_fx /* Q25*/ ), 687194767 /* 0.005f in Q37 */, dlp_fx /* Q19*/ ); // Q25
2467 1150754 : move32();
2468 :
2469 : /*------------------------------------------------------------------*
2470 : * Final speech/music decision
2471 : *------------------------------------------------------------------*/
2472 :
2473 1150754 : IF( flag_spitch )
2474 : {
2475 39733 : hSpMusClas->flag_spitch_cnt = 5;
2476 39733 : move16();
2477 : }
2478 1111021 : ELSE IF( hSpMusClas->flag_spitch_cnt > 0 )
2479 : {
2480 5830 : hSpMusClas->flag_spitch_cnt = sub( hSpMusClas->flag_spitch_cnt, 1 );
2481 5830 : move16();
2482 : }
2483 1150754 : test();
2484 1150754 : IF( Etot_fx < 2560 )
2485 : {
2486 : /* silence */
2487 135238 : dec = 0;
2488 135238 : move16();
2489 : }
2490 1015516 : ELSE IF( hSpMusClas->sp_mus_state > 0 && LT_16( hSpMusClas->sp_mus_state, HANG_LEN ) )
2491 : {
2492 71311 : temp32 = L_mult( w_spmus_fx[hSpMusClas->sp_mus_state - 1][0], (Word16) L_shr( dlp_fx, 10 ) ); /*Q25 */
2493 71311 : temp32 = L_add( temp32, Dot_product( &w_spmus_fx[hSpMusClas->sp_mus_state - 1][1], hSpMusClas->past_dlp_fx, sub( HANG_LEN, 1 ) ) );
2494 : /* entry state -> final decision is calculated based on weighted average of past non-binary decisions */
2495 71311 : IF( GT_32( temp32, 2 << 25 ) )
2496 : {
2497 35198 : IF( GT_32( dlp_fx, 2 << 19 ) )
2498 : {
2499 24346 : dec = 2;
2500 : }
2501 : ELSE
2502 : {
2503 10852 : dec = 1;
2504 : }
2505 : }
2506 : ELSE
2507 : {
2508 36113 : dec = 0;
2509 : }
2510 71311 : move16();
2511 : }
2512 : ELSE
2513 : {
2514 944205 : test();
2515 944205 : test();
2516 944205 : test();
2517 944205 : test();
2518 944205 : test();
2519 944205 : test();
2520 944205 : test();
2521 944205 : test();
2522 944205 : test();
2523 944205 : test();
2524 944205 : test();
2525 944205 : test();
2526 944205 : test();
2527 944205 : test();
2528 : /* stable active state */
2529 944205 : IF( hSpMusClas->past_dec[0] == 0 && hSpMusClas->past_dec[1] == 0 && hSpMusClas->past_dec[2] == 0 &&
2530 : ( ( hSpMusClas->flag_spitch_cnt > 0 && GT_32( hSpMusClas->wdlp_0_95_sp_32fx, 57042534 /*3.4*(2^24)*/ ) ) || ( hSpMusClas->flag_spitch_cnt == 0 && GT_32( hSpMusClas->wdlp_0_95_sp_32fx, 35232154 /*2.1*(2^24)*/ ) ) ) )
2531 : {
2532 : /* switching from speech to unclear */
2533 1935 : dec = 1;
2534 : }
2535 942270 : ELSE IF( hSpMusClas->past_dec[0] == 0 && LT_16( hSpMusClas->vad_0_1_cnt, 50 ) && hSpMusClas->relE_attack_sum_fx == 0 && GT_32( hSpMusClas->wdlp_0_95_sp_32fx, 1 << 24 ) )
2536 : {
2537 : /* switch from speech to unclear also during slowly rising weak music onsets */
2538 3365 : dec = 1;
2539 : }
2540 938905 : ELSE IF( EQ_16( hSpMusClas->past_dec[0], 1 ) && GT_32( hSpMusClas->wdlp_0_95_sp_32fx, 41943040 /*2.5*2^24*/ ) )
2541 : {
2542 : /* switching from unclear to music */
2543 4212 : dec = 2;
2544 : }
2545 934693 : ELSE IF( EQ_16( hSpMusClas->past_dec[0], 2 ) && EQ_16( hSpMusClas->past_dec[1], 2 ) && EQ_16( hSpMusClas->past_dec[2], 2 ) && LT_32( hSpMusClas->wdlp_0_95_sp_32fx, -( 1 << 24 ) ) )
2546 : {
2547 : /* switching from music to unclear */
2548 2441 : dec = 1;
2549 : }
2550 932252 : ELSE IF( EQ_16( hSpMusClas->past_dec[0], 1 ) && LT_32( hSpMusClas->wdlp_0_95_sp_32fx, -( 41943040 /*2.5*2^24*/ ) ) )
2551 : {
2552 : /* switching from unclear to speech */
2553 2526 : dec = 0;
2554 : }
2555 : ELSE
2556 : {
2557 929726 : dec = hSpMusClas->past_dec[0];
2558 : }
2559 944205 : move16();
2560 : }
2561 :
2562 : /*------------------------------------------------------------------*
2563 : * raw S/M decision based on smoothed GMM score
2564 : *------------------------------------------------------------------*/
2565 1150754 : test();
2566 1150754 : IF( dec == 0 || st->hSpMusClas->wdlp_0_95_sp_32fx <= 0 )
2567 : {
2568 698739 : st->sp_aud_decision0 = 0;
2569 698739 : st->sp_aud_decision1 = 0;
2570 : }
2571 : ELSE
2572 : {
2573 452015 : st->sp_aud_decision0 = 1;
2574 452015 : st->sp_aud_decision1 = 1;
2575 : }
2576 1150754 : move16();
2577 1150754 : move16();
2578 : /*------------------------------------------------------------------*
2579 : * Updates
2580 : *------------------------------------------------------------------*/
2581 :
2582 : /* update buffer of past non-binary decisions */
2583 1150754 : Copy( &hSpMusClas->past_dlp_fx[0], &hSpMusClas->past_dlp_fx[1], HANG_LEN - 2 );
2584 1150754 : hSpMusClas->past_dlp_fx[0] = extract_l( L_shr( dlp_fx, 10 ) );
2585 1150754 : move16();
2586 :
2587 1150754 : Copy32( &hSpMusClas->past_dlp_mean_ST_fx[0], &hSpMusClas->past_dlp_mean_ST_fx[1], HANG_LEN - 2 );
2588 1150754 : hSpMusClas->past_dlp_mean_ST_fx[0] = hSpMusClas->dlp_mean_ST_fx;
2589 1150754 : move32();
2590 :
2591 : /* update buffer of past binary decisions */
2592 1150754 : mvs2s( &hSpMusClas->past_dec[0], &hSpMusClas->past_dec[1], HANG_LEN - 2 );
2593 1150754 : hSpMusClas->past_dec[0] = dec;
2594 1150754 : move16();
2595 : #ifdef DEBUG_MODE_INFO
2596 : dbgwrite( &st->hSpMusClas->wdlp_0_95_sp_32fx, sizeof( Word32 ), 1, 1, "res/wdlp_0_95_sp.x" );
2597 : #endif
2598 :
2599 1150754 : return dec;
2600 : }
2601 :
2602 : /*---------------------------------------------------------------------*
2603 : * var_cor_calc_ivas_fx()
2604 : *
2605 : * Calculate variance of correlation
2606 : *---------------------------------------------------------------------*/
2607 :
2608 414383 : static void var_cor_calc_ivas_fx(
2609 : const Word16 old_corr, /* Q15 */
2610 : Word16 *mold_corr, /* Q15 */
2611 : Word16 var_cor_t[], /* Q11 */
2612 : Word16 *high_stable_cor )
2613 : {
2614 : Word16 i, var_cor;
2615 :
2616 : /* update buffer of old correlation values */
2617 4143830 : FOR( i = VAR_COR_LEN - 1; i > 0; i-- )
2618 : {
2619 3729447 : var_cor_t[i] = var_cor_t[i - 1]; /*Q11*/
2620 3729447 : move16();
2621 : }
2622 414383 : var_cor_t[i] = shr( old_corr, 4 ); /* Q11 */
2623 414383 : move16();
2624 :
2625 : /* calculate variance of correlation */
2626 414383 : var_cor = var_fx( var_cor_t, 11, VAR_COR_LEN );
2627 :
2628 414383 : *high_stable_cor = 0;
2629 414383 : move16();
2630 414383 : test();
2631 414383 : if ( GT_16( *mold_corr, 26214 ) && LT_16( var_cor, 1 ) )
2632 : {
2633 5610 : *high_stable_cor = 1;
2634 5610 : move16();
2635 : }
2636 :
2637 : /* update average correlation */
2638 : /*st->mold_corr = 0.1f * st->old_corr + 0.9f * st->mold_corr;*/
2639 414383 : *mold_corr = mac_r( L_mult( 3277, old_corr ), 29491, *mold_corr ); /*Q15 */
2640 414383 : move16();
2641 :
2642 414383 : return;
2643 : }
2644 :
2645 : /*---------------------------------------------------------------------*
2646 : * attack_det_fx()
2647 : *
2648 : * Attack detection
2649 : *---------------------------------------------------------------------*/
2650 :
2651 414383 : static Word16 attack_det_ivas_fx( /* o : attack flag */
2652 : const Word16 *inp, /* i : input signal */
2653 : const Word16 Qx,
2654 : const Word16 last_clas, /* i : last signal clas */
2655 : const Word16 localVAD, /* i : local VAD flag */
2656 : const Word16 coder_type, /* i : coder type */
2657 : const Word32 total_brate, /* i : total bitrate */
2658 : const Word16 element_mode, /* i : IVAS element mode */
2659 : const Word16 clas, /* i : signal class */
2660 : Word32 finc_prev[], /* i/o: previous finc, (q_finc_prev) */
2661 : Word16 *q_finc_prev, /* i/o: Q of previous finc */
2662 : Word32 *lt_finc, /* i/o: long-term mean finc, (q_lt_finc) */
2663 : Word16 *q_lt_finc, /* i/o: Q of lt_finc */
2664 : Word16 *last_strong_attack /* i/o: last strong attack flag */
2665 : )
2666 : {
2667 : Word16 i, j, tmp, tmp1, attack, exp1, etmp_e, etmp2_e, s;
2668 : Word32 L_tmp, etmp, etmp2, finc[ATT_NSEG], mean_finc;
2669 : Word16 att_3lsub_pos;
2670 : Word16 attack1;
2671 : Word64 W_tmp;
2672 : Word16 q_diff;
2673 :
2674 : #ifndef ISSUE_1867_replace_overflow_libenc
2675 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
2676 : Flag Overflow = 0;
2677 : move32();
2678 : #endif
2679 : #endif
2680 :
2681 414383 : att_3lsub_pos = ATT_3LSUB_POS;
2682 414383 : move16();
2683 414383 : if ( GE_32( total_brate, ACELP_24k40 ) )
2684 : {
2685 0 : att_3lsub_pos = ATT_3LSUB_POS_16k;
2686 0 : move16();
2687 : }
2688 :
2689 : /* compute energy per section */
2690 13674639 : FOR( i = 0; i < ATT_NSEG; i++ )
2691 : {
2692 13260256 : L_tmp = L_mult0( inp[i * ATT_SEG_LEN], inp[i * ATT_SEG_LEN] ); /*2*Qx */
2693 :
2694 106082048 : FOR( j = 1; j < ATT_SEG_LEN; j++ )
2695 : {
2696 : #ifdef ISSUE_1867_replace_overflow_libenc
2697 92821792 : L_tmp = L_mac0_sat( L_tmp, inp[i * ATT_SEG_LEN + j], inp[i * ATT_SEG_LEN + j] ); /*2*Qx */
2698 : #else
2699 : L_tmp = L_mac0_o( L_tmp, inp[i * ATT_SEG_LEN + j], inp[i * ATT_SEG_LEN + j], &Overflow ); /*2*Qx */
2700 : #endif
2701 : }
2702 :
2703 13260256 : finc[i] = L_tmp;
2704 13260256 : move32();
2705 : }
2706 :
2707 414383 : attack = maximum_32_fx( finc, ATT_NSEG, &etmp );
2708 414383 : attack1 = attack;
2709 414383 : move16();
2710 :
2711 414383 : *q_finc_prev = shl( Qx, 1 ); // Q of finc
2712 414383 : move16();
2713 414383 : q_diff = sub( *q_finc_prev, *q_lt_finc );
2714 414383 : test();
2715 414383 : IF( EQ_16( localVAD, 1 ) && EQ_16( coder_type, GENERIC ) )
2716 : {
2717 : /*----------------------------------------------------------------------*
2718 : * Detect if there is a strong onset in the last subframe
2719 : * - if detected, TC is used to better code the onset
2720 : *----------------------------------------------------------------------*/
2721 :
2722 : /* compute mean energy in the first three subframes */
2723 209150 : exp1 = norm_s( att_3lsub_pos );
2724 209150 : tmp = div_s( shl( 1, sub( 14, exp1 ) ), att_3lsub_pos ); /*Q(29-exp1) */
2725 :
2726 209150 : W_tmp = 0;
2727 209150 : move64();
2728 5228750 : FOR( i = 0; i < att_3lsub_pos; i++ )
2729 : {
2730 5019600 : W_tmp = W_add( W_tmp, finc[i] ); /* *q_ finc_prev */
2731 : }
2732 209150 : s = W_norm( W_tmp );
2733 209150 : L_tmp = W_extract_h( W_shl( W_tmp, s ) ); // *q_finc_prev + s - 32
2734 :
2735 209150 : L_tmp = Mpy_32_16_1( L_tmp, tmp ); /* *q_finc_prev + s - 32 + Q29 - exp1 - 15 => *q_finc_prev + s - exp1 - 18 */
2736 209150 : etmp = L_tmp;
2737 209150 : move32();
2738 209150 : etmp_e = sub( 31, add( *q_finc_prev, sub( s, add( exp1, 18 ) ) ) );
2739 :
2740 :
2741 209150 : tmp1 = sub( ATT_NSEG, attack );
2742 209150 : exp1 = norm_s( tmp1 );
2743 209150 : tmp = div_s( shl( 1, sub( 14, exp1 ) ), tmp1 ); /*Q(29-exp1) */
2744 :
2745 209150 : W_tmp = 0;
2746 209150 : move64();
2747 3636039 : FOR( i = 0; i < tmp1; i++ )
2748 : {
2749 3426889 : W_tmp = W_add( W_tmp, finc[i + attack] ); /* *q_finc_prev */
2750 : }
2751 209150 : s = W_norm( W_tmp );
2752 209150 : L_tmp = W_extract_h( W_shl( W_tmp, s ) ); // *q_finc_prev + s - 32
2753 :
2754 209150 : L_tmp = Mpy_32_16_1( L_tmp, tmp ); /* *q_finc_prev + s - 32 + Q29 - exp1 - 15 => *q_finc_prev + s - exp1 - 18 */
2755 209150 : etmp2 = L_tmp;
2756 209150 : move32();
2757 209150 : etmp2_e = sub( 31, add( *q_finc_prev, sub( s, add( exp1, 18 ) ) ) );
2758 :
2759 : /* and compare them */
2760 : /* if ( etmp * 8 > etmp2 ) */
2761 209150 : if ( BASOP_Util_Cmp_Mant32Exp( etmp, add( etmp_e, 3 ), etmp2, etmp2_e ) > 0 )
2762 : {
2763 : /* stop, if the attack is not sufficiently strong */
2764 202788 : attack = 0;
2765 202788 : move16();
2766 : }
2767 :
2768 209150 : test();
2769 : /* if ( last_clas == VOICED_CLAS && etmp * 20 > etmp2 ) */
2770 209150 : if ( EQ_16( last_clas, VOICED_CLAS ) && BASOP_Util_Cmp_Mant32Exp( etmp, etmp_e, Mpy_32_16_1( etmp2, 1638 /* 1/20 in Q15 */ ), etmp2_e ) > 0 )
2771 : {
2772 : /* stop, if the signal was voiced and the attack is not sufficiently strong */
2773 49287 : attack = 0;
2774 49287 : move16();
2775 : }
2776 :
2777 : /* compare also wrt. other sections (reduces a misclassification) */
2778 209150 : IF( attack > 0 )
2779 : {
2780 5756 : etmp2 = L_add( finc[attack], 0 );
2781 5756 : etmp = Mult_32_16( etmp2, 16384 ); /* etmp2 / 2.0 = (etmp2*0.5) */
2782 117936 : FOR( i = 2; i < ATT_3LSUB_POS - 2; i++ )
2783 : {
2784 112616 : IF( GT_32( finc[i], etmp ) )
2785 : {
2786 436 : attack = 0;
2787 436 : move16();
2788 436 : BREAK;
2789 : }
2790 : }
2791 : }
2792 :
2793 209150 : test();
2794 209150 : test();
2795 209150 : test();
2796 209150 : IF( attack == 0 && GT_16( element_mode, EVS_MONO ) && ( LT_16( clas, VOICED_TRANSITION ) || EQ_16( clas, ONSET ) ) )
2797 : {
2798 136994 : Copy32( finc, finc_prev, attack1 );
2799 :
2800 : /* compute mean energy before the attack */
2801 136994 : Word64 W_etmp = W_deposit32_l( finc_prev[0] );
2802 4383808 : FOR( Word16 idx = 1; idx < ATT_NSEG; idx++ )
2803 : {
2804 4246814 : W_etmp = W_add( W_etmp, W_deposit32_l( finc_prev[idx] ) );
2805 : }
2806 136994 : W_etmp = W_shr( W_etmp, 5 ); /*ATT_NSEG == 32*/
2807 :
2808 136994 : etmp2 = finc[attack1];
2809 136994 : move32();
2810 136994 : test();
2811 136994 : test();
2812 136994 : if ( ( LT_64( W_shl( W_etmp, 4 ), W_deposit32_l( etmp2 ) ) ) || ( LT_64( W_add( W_shl( W_etmp, 3 ), W_shl( W_etmp, 2 ) ), W_deposit32_l( etmp2 ) ) && EQ_16( last_clas, UNVOICED_CLAS ) ) )
2813 : {
2814 5018 : attack = attack1;
2815 5018 : move16();
2816 : }
2817 136994 : test();
2818 136994 : if ( GT_32( L_shl_sat( *lt_finc, q_diff ), Mpy_32_32( etmp2, 107374182 /* 1.f/20 in Q31 */ ) ) || *last_strong_attack )
2819 : {
2820 129115 : attack = 0;
2821 129115 : move16();
2822 : }
2823 : }
2824 209150 : *last_strong_attack = attack;
2825 209150 : move16();
2826 : }
2827 205233 : ELSE IF( attack > 0 )
2828 : {
2829 194569 : etmp2 = L_add( finc[attack], 0 );
2830 194569 : etmp = Mult_32_16( etmp2, 25206 ); /* etmp2 / 1.3 = (etmp2*0.76923) */
2831 2521637 : FOR( i = 2; i < att_3lsub_pos - 2; i++ )
2832 : {
2833 : /*if( i != attack && finc[i] * 1.3f > etmp2 ) -> finc[i] > (etmp2*0.76923) */
2834 2447378 : test();
2835 2447378 : IF( NE_16( i, attack ) && GT_32( finc[i], etmp ) )
2836 : {
2837 120310 : attack = 0;
2838 120310 : move16();
2839 120310 : BREAK;
2840 : }
2841 : }
2842 194569 : *last_strong_attack = 0;
2843 194569 : move16();
2844 : }
2845 :
2846 : /* updates */
2847 414383 : Copy32( finc, finc_prev, ATT_NSEG );
2848 :
2849 : /* Calculating mean of finc */
2850 414383 : W_tmp = W_mult_32_16( finc[0], 1 ); // q_finc_prev+1
2851 13260256 : FOR( i = 1; i < ATT_NSEG; i++ )
2852 : {
2853 12845873 : W_tmp = W_mac_32_16( W_tmp, finc[i], 1 ); // q_finc_prev+1
2854 : }
2855 : /* mean = W_tmp / 32 and change the Q from q_finc_prev+1 to q_finc_prev
2856 : Mean value doesn't saturate, W_shl_sat_l is used only considering complexity */
2857 414383 : mean_finc = W_shl_sat_l( W_tmp, -Q6 ); // q_finc_prev+1 -> q_finc_prev
2858 :
2859 : //*lt_finc = 0.95f * *lt_finc + 0.05f * mean( finc, ATT_NSEG );
2860 414383 : IF( q_diff > 0 ) /* q_finc_prev > q_lt_finc */
2861 : {
2862 289833 : mean_finc = L_shr( mean_finc, q_diff ); // q_lt_finc
2863 289833 : *lt_finc = Madd_32_32( Mpy_32_32( *lt_finc, 2040109466 /* 0.95 in Q31 */ ), mean_finc, 107374182 /* 0.05f in Q31 */ ); // q_lt_finc
2864 289833 : move32();
2865 : }
2866 : ELSE
2867 : {
2868 124550 : *lt_finc = Madd_32_32( Mpy_32_32( L_shl( *lt_finc, q_diff ), 2040109466 /* 0.95 in Q31 */ ), mean_finc, 107374182 /* 0.05f in Q31 */ ); // q_finc_prev
2869 124550 : move32();
2870 124550 : *q_lt_finc = *q_finc_prev;
2871 124550 : move16();
2872 : }
2873 :
2874 414383 : return attack;
2875 : }
2876 :
2877 : /*---------------------------------------------------------------------*
2878 : * tonal_det()
2879 : *
2880 : * Tonal detector based on spectral stability and harmonicity
2881 : *---------------------------------------------------------------------*/
2882 :
2883 414383 : static Word32 tonal_det_fx(
2884 : const Word16 S[], // Q7
2885 : Word16 vad_flag,
2886 : Word32 tod_S_map_lt[], // Q22
2887 : Word32 *tod_thr_lt, // Q22
2888 : Word16 *tod_weight, // Q15
2889 : Word32 *tod_S_mass_prev, // Q22
2890 : Word32 *tod_S_mass_lt // Q22
2891 : )
2892 : {
2893 : Word16 i;
2894 : Word32 S_mass, alpha;
2895 : Word32 L_tmp;
2896 : Word64 W_tmp;
2897 :
2898 : /* update the adaptive weight */
2899 414383 : *tod_weight = add( mult( TON_ALPHA_FX, *tod_weight ), imult1616( ( 32767 - TON_ALPHA_FX ), vad_flag ) );
2900 414383 : move16();
2901 414383 : IF( GT_16( *tod_weight, TON_ALPHA_FX ) )
2902 : {
2903 269204 : *tod_weight = TON_ALPHA_FX;
2904 269204 : move16();
2905 : }
2906 145179 : ELSE IF( LT_16( *tod_weight, ( 32767 - TON_ALPHA_FX ) ) )
2907 : {
2908 28982 : *tod_weight = 32767 - TON_ALPHA_FX;
2909 28982 : move16();
2910 : }
2911 :
2912 : /* calculate LT spectral correlation in each band up to 4KHz */
2913 414383 : W_tmp = 0;
2914 414383 : move64();
2915 33565023 : FOR( i = 0; i < TOD_NSPEC; i++ )
2916 : {
2917 33150640 : tod_S_map_lt[i] = L_add( Mpy_32_16_1( tod_S_map_lt[i], *tod_weight ), L_mult0( sub( 32767, *tod_weight ), S[i] ) ); // Q22
2918 33150640 : move16();
2919 :
2920 33150640 : W_tmp = W_add( W_tmp, (Word64) ( tod_S_map_lt[i] ) ); // Q22
2921 : }
2922 : // S_mass /= TOD_NSPEC;
2923 414383 : L_tmp = W_extract_l( W_tmp ); // Q22
2924 414383 : S_mass = ( Mpy_32_32( L_tmp, TOD_NSPEC_INV_Q31 ) ); // Q22
2925 :
2926 414383 : IF( GT_32( S_mass, *tod_S_mass_prev ) )
2927 : {
2928 201076 : alpha = 1503238554; /* 0.7f in Q31 */
2929 : }
2930 : ELSE
2931 : {
2932 213307 : alpha = 644245094; /* 0.3f in Q31 */
2933 : }
2934 414383 : move16();
2935 :
2936 414383 : *tod_S_mass_prev = S_mass;
2937 414383 : move32();
2938 414383 : *tod_S_mass_lt = L_add( Mpy_32_32( alpha, *tod_S_mass_lt ), Mpy_32_32( L_sub( ONE_IN_Q31, alpha ), S_mass ) ); // Q22
2939 414383 : move32();
2940 414383 : S_mass = *tod_S_mass_lt;
2941 414383 : move32();
2942 :
2943 : /* updating adaptive decision threshold */
2944 414383 : IF( GT_32( S_mass, *tod_thr_lt ) )
2945 : {
2946 2001 : *tod_thr_lt = L_sub( *tod_thr_lt, THR_MASS_STEP_DN_FX );
2947 : }
2948 : ELSE
2949 : {
2950 412382 : *tod_thr_lt = L_add( *tod_thr_lt, THR_MASS_STEP_UP_FX );
2951 : }
2952 414383 : move16();
2953 :
2954 414383 : if ( GT_32( *tod_thr_lt, THR_MASS_MAX_FX ) )
2955 : {
2956 411811 : *tod_thr_lt = THR_MASS_MAX_FX;
2957 : }
2958 :
2959 414383 : if ( LT_32( *tod_thr_lt, THR_MASS_MIN_FX ) )
2960 : {
2961 1663 : *tod_thr_lt = THR_MASS_MIN_FX;
2962 : }
2963 414383 : move16();
2964 :
2965 414383 : return S_mass; /* Q22 */
2966 : }
2967 :
2968 :
2969 : /*---------------------------------------------------------------------*
2970 : * ivas_smc_mode_selection()
2971 : *
2972 : * 2nd stage speech/music classifier (select coding mode (ACELP, GSC and TCX) based on S/M classification)
2973 : * output (sp_aud_decision1 - sp_aud_decision2 -> coding mode):
2974 : * 0 - 0 -> ACELP
2975 : * 1 - 0 -> GSC
2976 : * 1 - 1 -> TCX
2977 : *---------------------------------------------------------------------*/
2978 :
2979 414383 : void ivas_smc_mode_selection_fx(
2980 : Encoder_State *st, /* i/o: encoder state structure */
2981 : const Word32 element_brate, /* i : element bitrate */
2982 : Word16 smc_dec, /* i : raw decision of the 1st stage classifier*/
2983 : const Word16 relE, /* i : relative frame energy, Q8 */
2984 : const Word16 Etot, /* i : total frame energy, Q8 */
2985 : Word16 *attack_flag, /* i/o: attack flag (GSC or TC) */
2986 : const Word16 *inp, /* i : input signal */
2987 : const Word16 Q_new, /* i : Q of input signal */
2988 : const Word16 S_map[], /* i : short-term correlation map, Q7 */
2989 : const Word16 flag_spitch /* i : flag to indicate very short stable pitch*/
2990 : )
2991 : {
2992 : Word16 attack;
2993 : Word32 ton;
2994 : Word16 i;
2995 414383 : Word32 S_p2a, S_max, S_ave = 0;
2996 414383 : move32();
2997 : Word32 thr_sp2a;
2998 :
2999 414383 : SP_MUS_CLAS_HANDLE hSpMusClas = st->hSpMusClas;
3000 :
3001 : /* initialization */
3002 414383 : *attack_flag = 0;
3003 414383 : move16();
3004 414383 : st->sp_aud_decision2 = 0;
3005 414383 : move16();
3006 :
3007 : /* signal stability estimation */
3008 414383 : stab_est_fx( Etot, hSpMusClas->gsc_lt_diff_etot_fx, &hSpMusClas->gsc_mem_etot_fx, &hSpMusClas->gsc_nb_thr_3, &hSpMusClas->gsc_nb_thr_1, hSpMusClas->gsc_thres_fx, &hSpMusClas->gsc_last_music_flag, st->vad_flag );
3009 :
3010 : /* calculate variance of correlation */
3011 414383 : var_cor_calc_ivas_fx( st->old_corr_fx, &hSpMusClas->mold_corr_fx, hSpMusClas->var_cor_t_fx, &hSpMusClas->high_stable_cor );
3012 :
3013 : /* attack detection */
3014 414383 : IF( NE_16( shl( Q_new, 1 ), hSpMusClas->q_finc_prev ) )
3015 : {
3016 54391 : Scale_sig32( hSpMusClas->finc_prev_fx, ATT_NSEG, sub( shl( Q_new, 1 ), hSpMusClas->q_finc_prev ) );
3017 54391 : hSpMusClas->q_finc_prev = shl( Q_new, 1 );
3018 54391 : move16();
3019 : }
3020 414383 : attack = attack_det_ivas_fx( inp, Q_new, st->clas, st->localVAD, st->coder_type, 0, st->element_mode, st->clas, hSpMusClas->finc_prev_fx,
3021 : &hSpMusClas->q_finc_prev, &hSpMusClas->lt_finc_fx, &hSpMusClas->Q_lt_finc, &hSpMusClas->last_strong_attack );
3022 :
3023 : /* tonal detector */
3024 414383 : ton = tonal_det_fx( S_map, st->vad_flag, hSpMusClas->tod_S_map_lt_fx, &hSpMusClas->tod_thr_lt_fx, &hSpMusClas->tod_weight_fx, &hSpMusClas->tod_S_mass_prev_fx, &hSpMusClas->tod_S_mass_lt_fx ); // Q22
3025 :
3026 : /* calculate spectral peak-to-average ratio */
3027 414383 : Word16 shift = sub( st->q_Bin_E, st->hSpMusClas->Q_tod_lt_Bin_E );
3028 33565023 : FOR( i = 0; i < TOD_NSPEC; i++ )
3029 : {
3030 : // st->hSpMusClas->tod_lt_Bin_E[i] = P2A_FACT * st->hSpMusClas->tod_lt_Bin_E[i] + ( 1 - P2A_FACT ) * st->Bin_E[i];
3031 33150640 : st->hSpMusClas->tod_lt_Bin_E_fx[i] = Madd_32_16( L_shl( Mpy_32_16_1( st->hSpMusClas->tod_lt_Bin_E_fx[i], P2A_FACT_FX_Q15 ), shift ), st->Bin_E_fx[i], ( 32767 - P2A_FACT_FX_Q15 ) ); // Q = st->q_Bin_E + Q_SCALE - 2
3032 33150640 : move32();
3033 : }
3034 414383 : st->hSpMusClas->Q_tod_lt_Bin_E = add( st->hSpMusClas->Q_tod_lt_Bin_E, shift );
3035 414383 : move16();
3036 414383 : maximum_32_fx( st->hSpMusClas->tod_lt_Bin_E_fx, TOD_NSPEC, &S_max );
3037 : // S_ave = sum_f( st->hSpMusClas->tod_lt_Bin_E_fx, TOD_NSPEC ) / TOD_NSPEC;
3038 33565023 : FOR( i = 0; i < TOD_NSPEC; i++ )
3039 : {
3040 33150640 : S_ave = L_add( S_ave, st->hSpMusClas->tod_lt_Bin_E_fx[i] );
3041 : }
3042 414383 : S_ave = Mpy_32_32( S_ave, TOD_NSPEC_INV_Q31 );
3043 :
3044 414383 : S_p2a = L_sub( S_max, S_ave );
3045 :
3046 414383 : IF( LE_32( element_brate, IVAS_16k4 ) )
3047 : {
3048 135734 : thr_sp2a = L_shl( THR_P2A_HIGH_FX, st->q_Bin_E ); // Q = st->q_Bin_E
3049 : }
3050 : ELSE
3051 : {
3052 278649 : thr_sp2a = L_shl( THR_P2A_FX, st->q_Bin_E ); // Q = st->q_Bin_E
3053 : }
3054 :
3055 : /* initial 3-way selection of coding modes (ACELP/GSC/TCX) */
3056 414383 : test();
3057 414383 : test();
3058 414383 : IF( GT_16( relE, -2560 /* -10.0f in Q8 */ ) && ( GT_32( S_p2a, thr_sp2a ) || GT_32( ton, hSpMusClas->tod_thr_lt_fx ) ) )
3059 : {
3060 : /* select TCX to encode extremely peaky signals or strongly tonal signals */
3061 18224 : st->sp_aud_decision1 = 1;
3062 18224 : st->sp_aud_decision2 = 1;
3063 : }
3064 396159 : ELSE IF( smc_dec == SPEECH )
3065 : {
3066 : /* select ACELP to encode speech */
3067 153422 : st->sp_aud_decision1 = 0;
3068 153422 : st->sp_aud_decision2 = 0;
3069 : }
3070 242737 : ELSE IF( EQ_16( smc_dec, SPEECH_OR_MUSIC ) )
3071 : {
3072 : /* select GSC to encode "unclear" segments (classifier's score on the borderline) */
3073 6308 : st->sp_aud_decision1 = 1;
3074 6308 : st->sp_aud_decision2 = 0;
3075 : }
3076 : ELSE
3077 : {
3078 : /* select TCX to encode music */
3079 236429 : st->sp_aud_decision1 = 1;
3080 236429 : st->sp_aud_decision2 = 1;
3081 : }
3082 414383 : move16();
3083 414383 : move16();
3084 :
3085 : /* change decision from GSC to ACELP/TCX in some special cases */
3086 414383 : test();
3087 414383 : IF( EQ_16( st->sp_aud_decision1, 1 ) && st->sp_aud_decision2 == 0 )
3088 : {
3089 6308 : test();
3090 6308 : test();
3091 6308 : IF( LT_16( hSpMusClas->ener_RAT_fx, 5898 /* 0.18f in Q15 */ ) && GT_16( hSpMusClas->lt_dec_thres_fx, 7680 /* 15.0f in Q9 */ ) )
3092 : {
3093 : /* prevent GSC on strong music with almost no content below 1kHz */
3094 4 : st->sp_aud_decision2 = 1;
3095 4 : move16();
3096 : }
3097 6304 : ELSE IF( flag_spitch )
3098 : {
3099 : /* prevent GSC on signals with very short and stable high pitch period */
3100 114 : IF( LT_32( hSpMusClas->wdlp_0_95_sp_32fx, 41943040 /* 2.5f in Q24 */ ) )
3101 : {
3102 : /* select ACELP instead */
3103 110 : st->sp_aud_decision1 = 0;
3104 110 : move16();
3105 : }
3106 : ELSE
3107 : {
3108 : /* select TCX instead */
3109 4 : st->sp_aud_decision2 = 1;
3110 4 : move16();
3111 : }
3112 : }
3113 6190 : ELSE IF( hSpMusClas->high_stable_cor && GE_16( st->pitch[0], 130 ) )
3114 : {
3115 : /* prevent GSC in highly correlated signal with low energy variation */
3116 : /* this is basically a patch against bassoon-type of music */
3117 0 : st->sp_aud_decision2 = 1;
3118 0 : move16();
3119 : }
3120 : }
3121 :
3122 : /* change decision from GSC to ACELP TC during attacks/onsets */
3123 414383 : test();
3124 414383 : IF( EQ_16( st->sp_aud_decision1, 1 ) && st->sp_aud_decision2 == 0 )
3125 : {
3126 6190 : test();
3127 6190 : IF( GT_16( hSpMusClas->gsc_lt_diff_etot_fx[MAX_LT - 1], 1152 /*4.5f in Q8*/ ) &&
3128 : ( GT_16( hSpMusClas->gsc_lt_diff_etot_fx[MAX_LT - 1], add( hSpMusClas->gsc_lt_diff_etot_fx[MAX_LT - 2], 2560 /* 10.0f in Q8 */ ) ) ) )
3129 : {
3130 107 : IF( EQ_16( st->tc_cnt, 1 ) )
3131 : {
3132 : /* do ACELP TC coding instead of GC/VC if onset has been already declared before */
3133 45 : st->sp_aud_decision1 = 0;
3134 45 : move16();
3135 45 : st->coder_type = TRANSITION;
3136 45 : move16();
3137 : }
3138 : ELSE
3139 : {
3140 62 : IF( GE_16( attack, ATT_3LSUB_POS ) )
3141 : {
3142 : /* do ACELP TC coding also if attack is located in the last subframe */
3143 16 : st->sp_aud_decision1 = 0;
3144 16 : move16();
3145 16 : *attack_flag = add( attack, 1 );
3146 16 : move16();
3147 16 : st->coder_type = TRANSITION;
3148 16 : move16();
3149 : }
3150 46 : ELSE IF( GE_16( attack, ATT_SEG_LEN / 2 ) )
3151 : {
3152 : /* do GSC coding if attack is located after the first quarter of the first subframe */
3153 : /* (pre-echo will be treated at the decoder side) */
3154 1 : *attack_flag = 31;
3155 1 : move16();
3156 1 : *attack_flag = add( attack, 1 );
3157 1 : move16();
3158 : }
3159 : }
3160 : }
3161 : }
3162 :
3163 414383 : test();
3164 414383 : test();
3165 414383 : test();
3166 414383 : test();
3167 414383 : IF( EQ_16( st->localVAD, 1 ) && EQ_16( st->coder_type, GENERIC ) && attack > 0 /*&& *attack_flag < 32*/ /*&& st->tc_cnt != 2*/ && !( EQ_16( st->sp_aud_decision2, 1 ) && GT_32( ton, 2726298 /* 0.65f in Q22 */ ) ) )
3168 : {
3169 : /* change ACELP coder_type to TC if attack has been detected */
3170 6788 : st->sp_aud_decision1 = 0;
3171 6788 : move16();
3172 6788 : st->sp_aud_decision2 = 0;
3173 6788 : move16();
3174 :
3175 6788 : st->coder_type = TRANSITION;
3176 6788 : move16();
3177 6788 : *attack_flag = add( attack, 1 );
3178 6788 : move16();
3179 : }
3180 :
3181 : #ifdef DEBUGGING
3182 : if ( st->idchan == 0 && st->coder_type != INACTIVE )
3183 : {
3184 : if ( st->force == FORCE_GSC && element_brate < IVAS_24k4 )
3185 : {
3186 : /* enforce GSC */
3187 : st->sp_aud_decision1 = 1;
3188 : st->sp_aud_decision2 = 0;
3189 : }
3190 : else if ( st->force == FORCE_SPEECH && ( st->sp_aud_decision1 == 1 || st->sp_aud_decision2 == 1 ) )
3191 : {
3192 : if ( element_brate < IVAS_24k4 )
3193 : {
3194 : /* convert TCX to GSC */
3195 : st->sp_aud_decision1 = 1;
3196 : st->sp_aud_decision2 = 0;
3197 : }
3198 : else
3199 : {
3200 : /* convert TCX to ACELP */
3201 : st->sp_aud_decision1 = 0;
3202 : st->sp_aud_decision2 = 0;
3203 : }
3204 : }
3205 : else if ( st->force == FORCE_MUSIC )
3206 : {
3207 : /* enforce TCX */
3208 : st->sp_aud_decision1 = 1;
3209 : st->sp_aud_decision2 = 1;
3210 : }
3211 : }
3212 : #endif
3213 :
3214 : /* set GSC noisy speech flag on unvoiced SWB segments */
3215 414383 : st->GSC_noisy_speech = 0;
3216 414383 : move16();
3217 414383 : test();
3218 414383 : test();
3219 414383 : test();
3220 414383 : test();
3221 414383 : test();
3222 414383 : if ( EQ_16( st->vad_flag, 1 ) && LE_32( element_brate, IVAS_16k4 ) && GT_32( st->lp_noise_32fx, 503316480 /* 30.0f in Q24 */ ) && st->sp_aud_decision1 == 0 && GE_16( st->bwidth, SWB ) && EQ_16( st->coder_type_raw, UNVOICED ) )
3223 : {
3224 1244 : st->GSC_noisy_speech = 1;
3225 1244 : move16();
3226 : }
3227 :
3228 : /* set GSC submode */
3229 414383 : test();
3230 414383 : test();
3231 414383 : test();
3232 414383 : IF( st->element_mode > EVS_MONO && ( EQ_16( st->sp_aud_decision1, 1 ) && st->sp_aud_decision2 == 0 ) && GT_32( st->total_brate, STEREO_GSC_BIT_RATE_ALLOC ) ) /* below STEREO_GSC_BIT_RATE_ALLOC, fall back on normal GSC */
3233 : {
3234 5120 : st->GSC_IVAS_mode = 1;
3235 5120 : move16();
3236 5120 : IF( st->hSpMusClas->wdlp_0_95_sp_32fx > 0 )
3237 : {
3238 : /* music-like content */
3239 2979 : st->GSC_IVAS_mode = 3;
3240 : }
3241 2141 : ELSE IF( st->tc_cnt > 0 )
3242 : {
3243 : /* likely presence of an onset, GSC bit allocation will be more focused on LF */
3244 233 : st->GSC_IVAS_mode = 2;
3245 : }
3246 5120 : move16();
3247 :
3248 5120 : test();
3249 5120 : IF( EQ_16( st->coder_type_raw, UNVOICED ) && st->sp_aud_decision0 == 0 /*&& st->GSC_IVAS_mode < 3*/ )
3250 : {
3251 128 : st->GSC_noisy_speech = 1;
3252 : }
3253 : ELSE
3254 : {
3255 4992 : st->GSC_noisy_speech = 0;
3256 : }
3257 5120 : move16();
3258 : }
3259 :
3260 : /* set coder_type to AUDIO when GSC is selected (st->core will be set later in the decision matrix) */
3261 414383 : test();
3262 414383 : test();
3263 414383 : IF( ( EQ_16( st->sp_aud_decision1, 1 ) && st->sp_aud_decision2 == 0 ) || st->GSC_noisy_speech )
3264 : {
3265 7285 : st->coder_type = AUDIO;
3266 7285 : move16();
3267 7285 : test();
3268 7285 : if ( st->hGSCEnc != NULL && st->GSC_noisy_speech == 0 ) /* In case of GSC_noisy_speech, NOISE_LEVEL should remain at NOISE_LEVEL_SP3 */
3269 : {
3270 5913 : st->hGSCEnc->noise_lev = NOISE_LEVEL_SP0;
3271 5913 : move16();
3272 : }
3273 : }
3274 :
3275 414383 : return;
3276 : }
3277 :
3278 : /*---------------------------------------------------------------------*
3279 : * mode_decision_fx()
3280 : *
3281 : *
3282 : *---------------------------------------------------------------------*/
3283 :
3284 2041 : static Word16 mode_decision_fx(
3285 : Encoder_State *st, /* i : endoer state structure */
3286 : Word16 len, /* i : buffering status */
3287 : Word16 *dec_mov, /* i/o: moving average of classifier decision Q15*/
3288 : Word16 *buf_flux, /* i : buffer storing spectral energy fluctuation Q7*/
3289 : Word16 *buf_epsP_tilt, /* i : buffer storing LP prediciton error tilt Q15*/
3290 : Word16 *buf_pkh, /* i : buffer storing highband spectral peakiness Q1*/
3291 : Word16 *buf_cor_map_sum, /* i : buffer storing correlation map sum Q8*/
3292 : Word16 *buf_Ntonal, /* i : buffer storing No.of 1st spectral tone Q0*/
3293 : Word16 *buf_Ntonal2, /* i : buffer storing No.of 2nd spectral tone Q0*/
3294 : Word16 *buf_Ntonal_lf, /* i : buffer storing low band spectral tone ratio Q0*/
3295 : Word16 *buf_dlp /* i : buffer storing log probability diff between speech and music Q9*/
3296 : )
3297 : {
3298 : Word16 mode;
3299 : Word16 i;
3300 : Word16 voiced_cnt;
3301 : Word16 M_pkh;
3302 : Word16 M_cor_map_sum;
3303 : Word16 M_Ntonal;
3304 : Word16 M_flux;
3305 : Word32 V_epsP_tilt;
3306 : Word16 lf_Ntonal_ratio;
3307 : Word16 tmp, tmp1;
3308 : Word32 L_tmp;
3309 : Word16 inv_len;
3310 : Word16 j;
3311 : Word16 M_flux10;
3312 2041 : SP_MUS_CLAS_HANDLE hSpMusClas = st->hSpMusClas;
3313 :
3314 :
3315 2041 : mode = *dec_mov > 16384;
3316 2041 : logic16();
3317 2041 : move16();
3318 :
3319 2041 : IF( LE_16( len, 5 ) )
3320 : {
3321 25 : return ( mode );
3322 : }
3323 : ELSE
3324 : {
3325 2016 : IF( LT_16( len, 10 ) )
3326 : {
3327 20 : inv_len = div_s( 1, len ); /*Q15 */
3328 :
3329 20 : L_tmp = L_deposit_l( 0 );
3330 170 : FOR( i = 0; i < len; i++ )
3331 : {
3332 150 : L_tmp = L_add( L_tmp, buf_pkh[BUF_LEN - len + i] ); /*Q1 */
3333 : }
3334 20 : L_tmp = Mult_32_16( L_tmp, inv_len ); /*Q1 */
3335 20 : M_pkh = extract_l( L_tmp ); /*Q1 */
3336 :
3337 20 : L_tmp = L_deposit_l( 0 );
3338 170 : FOR( i = 0; i < len; i++ )
3339 : {
3340 150 : L_tmp = L_add( L_tmp, buf_cor_map_sum[BUF_LEN - len + i] ); /*Q8 */
3341 : }
3342 20 : L_tmp = Mult_32_16( L_tmp, inv_len ); /*Q8 */
3343 20 : M_cor_map_sum = extract_l( L_tmp ); /*Q8 */
3344 :
3345 20 : tmp = 0;
3346 20 : move16();
3347 170 : FOR( i = 0; i < len; i++ )
3348 : {
3349 150 : tmp = add( tmp, shl( buf_Ntonal[BUF_LEN - len + i], 2 ) ); /*Q2 */
3350 : }
3351 20 : M_Ntonal = mult_r( tmp, inv_len ); /*Q2 */
3352 :
3353 20 : V_epsP_tilt = var_fx_32( buf_epsP_tilt + BUF_LEN - len, 15, len ); /*Q31 */
3354 :
3355 20 : voiced_cnt = 0;
3356 20 : move16();
3357 140 : FOR( i = 9; i > 3; i-- )
3358 : {
3359 120 : if ( buf_dlp[i] > 0 )
3360 : {
3361 10 : voiced_cnt = add( voiced_cnt, 1 );
3362 : }
3363 : }
3364 :
3365 20 : test();
3366 20 : test();
3367 20 : test();
3368 20 : test();
3369 20 : IF( ( GT_16( M_pkh, 2200 ) || LT_32( V_epsP_tilt, 171799 ) || GT_16( M_cor_map_sum, 25600 ) ) && LT_16( voiced_cnt, 4 ) )
3370 : {
3371 4 : mode = 1;
3372 4 : move16();
3373 : }
3374 16 : ELSE IF( GT_16( M_Ntonal, 108 ) && LT_16( voiced_cnt, 4 ) ) /*27 in Q2 */
3375 : {
3376 0 : mode = 1;
3377 0 : move16();
3378 : }
3379 : }
3380 : ELSE
3381 : {
3382 1996 : voiced_cnt = 0;
3383 1996 : move16();
3384 21956 : FOR( i = 0; i < 10; i++ )
3385 : {
3386 19960 : if ( buf_dlp[i] > 0 )
3387 : {
3388 10234 : voiced_cnt = add( voiced_cnt, 1 );
3389 : }
3390 : }
3391 :
3392 1996 : inv_len = 3277; /*Q15 */
3393 1996 : move16();
3394 :
3395 1996 : L_tmp = L_deposit_l( 0 );
3396 21956 : FOR( i = 0; i < 10; i++ )
3397 : {
3398 19960 : L_tmp = L_add( L_tmp, L_shl( buf_flux[BUF_LEN - 10 + i], 2 ) ); /*Q9 */
3399 : }
3400 1996 : L_tmp = Mult_32_16( L_tmp, inv_len ); /*Q9 */
3401 1996 : M_flux10 = extract_l( L_tmp ); /*Q9 */
3402 :
3403 1996 : L_tmp = L_deposit_l( 0 );
3404 21956 : FOR( i = 0; i < 10; i++ )
3405 : {
3406 19960 : L_tmp = L_add( L_tmp, buf_pkh[BUF_LEN - 10 + i] ); /*Q1 */
3407 : }
3408 1996 : L_tmp = Mult_32_16( L_tmp, inv_len ); /*Q1 */
3409 1996 : M_pkh = extract_l( L_tmp ); /*Q1 */
3410 :
3411 1996 : L_tmp = L_deposit_l( 0 );
3412 21956 : FOR( i = 0; i < 10; i++ )
3413 : {
3414 19960 : L_tmp = L_add( L_tmp, buf_cor_map_sum[BUF_LEN - 10 + i] ); /*Q8 */
3415 : }
3416 1996 : L_tmp = Mult_32_16( L_tmp, inv_len ); /*Q8 */
3417 1996 : M_cor_map_sum = extract_l( L_tmp ); /*Q8 */
3418 :
3419 1996 : V_epsP_tilt = var_fx_32( buf_epsP_tilt + BUF_LEN - 10, 15, 10 ); /*Q31 */
3420 :
3421 1996 : L_tmp = L_deposit_l( 0 );
3422 11976 : FOR( i = 0; i < 5; i++ )
3423 : {
3424 9980 : L_tmp = L_add( L_tmp, L_shl( buf_flux[BUF_LEN - 5 + i], 2 ) ); /*Q9 */
3425 : }
3426 1996 : L_tmp = Mult_32_16( L_tmp, 6554 ); /*Q9 */
3427 1996 : tmp = extract_l( L_tmp ); /*Q9 */
3428 :
3429 1996 : test();
3430 1996 : test();
3431 1996 : test();
3432 1996 : test();
3433 1996 : test();
3434 1996 : test();
3435 1996 : IF( ( LT_16( M_flux10, 4352 ) || ( LT_32( V_epsP_tilt, 2147484 ) && LT_16( M_flux10, 6144 ) ) || GT_16( M_pkh, 2100 ) ||
3436 : GT_16( M_cor_map_sum, 25600 ) ) &&
3437 : LT_16( voiced_cnt, 3 ) && LT_16( tmp, 7680 ) )
3438 : {
3439 238 : mode = 1;
3440 238 : move16();
3441 238 : *dec_mov = 32767;
3442 238 : move16();
3443 238 : return ( mode );
3444 : }
3445 :
3446 1758 : test();
3447 1758 : test();
3448 1758 : test();
3449 1758 : test();
3450 1758 : test();
3451 1758 : IF( GT_16( M_flux10, 8192 ) || ( GT_16( M_flux10, 7680 ) && GT_16( voiced_cnt, 2 ) ) || GT_16( tmp, 9728 ) ||
3452 : ( GE_16( buf_flux[59], 2560 ) && GT_16( hSpMusClas->lps_fx, hSpMusClas->lpm_fx ) ) )
3453 : {
3454 1520 : mode = 0;
3455 1520 : move16();
3456 1520 : *dec_mov = 0;
3457 1520 : move16();
3458 1520 : return ( mode );
3459 : }
3460 :
3461 5442 : FOR( i = 10; i < len; i++ )
3462 : {
3463 5335 : inv_len = div_s( 1, i ); /*Q15 */
3464 :
3465 5335 : L_tmp = L_deposit_l( 0 );
3466 185500 : FOR( j = 0; j < i; j++ )
3467 : {
3468 180165 : L_tmp = L_add( L_tmp, L_shl( buf_flux[BUF_LEN - i + j], 2 ) ); /*Q9 */
3469 : }
3470 5335 : L_tmp = Mult_32_16( L_tmp, inv_len ); /*Q9 */
3471 5335 : M_flux = extract_l( L_tmp ); /*Q9 */
3472 :
3473 5335 : L_tmp = L_deposit_l( 0 );
3474 185500 : FOR( j = 0; j < i; j++ )
3475 : {
3476 180165 : L_tmp = L_add( L_tmp, buf_pkh[BUF_LEN - i + j] ); /*Q1 */
3477 : }
3478 5335 : L_tmp = Mult_32_16( L_tmp, inv_len ); /*Q1 */
3479 5335 : M_pkh = extract_l( L_tmp ); /*Q1 */
3480 :
3481 5335 : L_tmp = L_deposit_l( 0 );
3482 185500 : FOR( j = 0; j < i; j++ )
3483 : {
3484 180165 : L_tmp = L_add( L_tmp, buf_cor_map_sum[BUF_LEN - i + j] ); /*Q8 */
3485 : }
3486 5335 : L_tmp = Mult_32_16( L_tmp, inv_len ); /*Q8 */
3487 5335 : M_cor_map_sum = extract_l( L_tmp ); /*Q8 */
3488 :
3489 5335 : V_epsP_tilt = var_fx_32( buf_epsP_tilt + BUF_LEN - i, 15, i ); /*Q31 */
3490 :
3491 5335 : test();
3492 5335 : test();
3493 5335 : test();
3494 5335 : test();
3495 5335 : test();
3496 5335 : IF( ( ( LT_16( M_flux, add( 6144, mult_r( 1638, shl( sub( len, 10 ), 9 ) ) ) ) && LT_16( M_flux10, 7680 ) ) ||
3497 : LT_32( V_epsP_tilt, L_add( 214748, L_shl( L_mult0( 19327, ( len - 10 ) ), 1 ) ) ) ||
3498 : GT_16( M_pkh, sub( 2100, extract_l( L_mult0( 10, sub( len, 10 ) ) ) ) ) ||
3499 : GT_16( M_cor_map_sum, sub( 24320, extract_l( L_mult0( 77, sub( len, 10 ) ) ) ) ) ) &&
3500 : LT_16( voiced_cnt, 3 ) )
3501 : {
3502 131 : mode = 1;
3503 131 : move16();
3504 131 : return ( mode );
3505 : }
3506 : }
3507 :
3508 107 : IF( EQ_16( len, BUF_LEN ) )
3509 : {
3510 103 : tmp = 0;
3511 103 : move16();
3512 6283 : FOR( i = 0; i < len; i++ )
3513 : {
3514 6180 : tmp = add( tmp, shl( buf_Ntonal[i], 2 ) ); /*Q2 */
3515 : }
3516 103 : M_Ntonal = mult_r( tmp, 546 ); /*Q2 */
3517 :
3518 103 : tmp = 0;
3519 103 : move16();
3520 6283 : FOR( i = 0; i < len; i++ )
3521 : {
3522 6180 : tmp = add( tmp, buf_Ntonal_lf[i] ); /*Q0 */
3523 : }
3524 103 : tmp1 = 0;
3525 103 : move16();
3526 6283 : FOR( i = 0; i < len; i++ )
3527 : {
3528 6180 : tmp1 = add( tmp1, buf_Ntonal2[i] ); /*Q0 */
3529 : }
3530 103 : lf_Ntonal_ratio = 0;
3531 103 : move16(); /*Q15 */
3532 103 : if ( tmp1 != 0 )
3533 : {
3534 103 : lf_Ntonal_ratio = div_s( tmp, tmp1 ); /*Q15 */
3535 : }
3536 :
3537 103 : test();
3538 103 : IF( GT_16( M_Ntonal, 72 ) || LT_16( lf_Ntonal_ratio, 6554 ) )
3539 : {
3540 0 : mode = 1;
3541 0 : move16();
3542 : }
3543 103 : ELSE IF( LT_16( M_Ntonal, 4 ) )
3544 : {
3545 0 : mode = 0;
3546 0 : move16();
3547 : }
3548 : }
3549 : }
3550 : }
3551 :
3552 127 : return ( mode );
3553 : }
3554 :
3555 : /*---------------------------------------------------------------------*
3556 : * tonal_dist_fx()
3557 : *
3558 : *
3559 : *---------------------------------------------------------------------*/
3560 :
3561 2041 : static void tonal_dist_fx(
3562 : Word16 *p2v_map, /* i : spectral peakiness map Q7*/
3563 : Word16 *buf_pkh, /* i/o: buffer storing highband spectral peakiness Q1*/
3564 : Word16 *buf_Ntonal, /* i/o: buffer storing No.of 1st spectral tone Q0*/
3565 : Word16 *buf_Ntonal2, /* i/o: buffer storing No.of 2nd spectral tone Q0*/
3566 : Word16 *buf_Ntonal_lf /* i/o: buffer storing low band spectral tone ratio Q0*/
3567 : )
3568 : {
3569 : Word16 i;
3570 : Word32 pk;
3571 : Word16 Ntonal;
3572 : Word16 Ntonal2;
3573 : Word16 Ntonal_lf;
3574 :
3575 :
3576 : /* find number of tonals, number of tonals at low-band,
3577 : spectral peakiness at high-band */
3578 2041 : pk = L_deposit_l( 0 );
3579 2041 : Ntonal = 0;
3580 2041 : move16();
3581 2041 : Ntonal2 = 0;
3582 2041 : move16();
3583 2041 : Ntonal_lf = 0;
3584 2041 : move16();
3585 132665 : FOR( i = 0; i < 64; i++ )
3586 : {
3587 130624 : if ( GT_16( p2v_map[i], 7040 ) )
3588 : {
3589 9820 : Ntonal = add( Ntonal, 1 );
3590 : }
3591 :
3592 130624 : IF( GT_16( p2v_map[i], 10240 ) )
3593 : {
3594 5699 : Ntonal2 = add( Ntonal2, 1 );
3595 5699 : Ntonal_lf = add( Ntonal_lf, 1 );
3596 : }
3597 : }
3598 :
3599 130624 : FOR( i = 64; i < 127; i++ )
3600 : {
3601 128583 : if ( p2v_map[i] != 0 )
3602 : {
3603 33844 : pk = L_add( pk, p2v_map[i] ); /*Q7 */
3604 : }
3605 128583 : if ( GT_16( p2v_map[i], 7040 ) )
3606 : {
3607 4215 : Ntonal = add( Ntonal, 1 );
3608 : }
3609 128583 : if ( GT_16( p2v_map[i], 10240 ) )
3610 : {
3611 1519 : Ntonal2 = add( Ntonal2, 1 );
3612 : }
3613 : }
3614 :
3615 : /* update buffers */
3616 122460 : FOR( i = 0; i < BUF_LEN - 1; i++ )
3617 : {
3618 120419 : buf_pkh[i] = buf_pkh[i + 1];
3619 120419 : move16();
3620 120419 : buf_Ntonal[i] = buf_Ntonal[i + 1];
3621 120419 : move16();
3622 120419 : buf_Ntonal2[i] = buf_Ntonal2[i + 1];
3623 120419 : move16();
3624 120419 : buf_Ntonal_lf[i] = buf_Ntonal_lf[i + 1];
3625 120419 : move16();
3626 : }
3627 :
3628 2041 : buf_pkh[i] = extract_l( L_shr_r( pk, 6 ) ); /*Q1 */
3629 2041 : buf_Ntonal[i] = Ntonal;
3630 2041 : move16(); /*Q0 */
3631 2041 : buf_Ntonal2[i] = Ntonal2;
3632 2041 : move16(); /*Q0 */
3633 2041 : buf_Ntonal_lf[i] = Ntonal_lf;
3634 2041 : move16(); /*Q0 */
3635 :
3636 2041 : return;
3637 : }
3638 :
3639 : /*---------------------------------------------------------------------*
3640 : * flux_fx()
3641 : *
3642 : *
3643 : *---------------------------------------------------------------------*/
3644 :
3645 2041 : static void flux_fx(
3646 : Word16 *Bin_E, /* i : log energy spectrum of the current frame Q7*/
3647 : Word16 *p2v_map, /* i : spectral peakiness map Q7*/
3648 : Word16 *old_Bin_E, /* i/o: log energy spectrum of the frame 60ms ago Q7*/
3649 : Word16 *buf_flux, /* i/o: buffer storing spectral energy fluctuation Q7*/
3650 : Word16 attack_hangover, /* i/o: hangover preventing flux buffering Q0*/
3651 : Word16 dec_mov /* i/o: moving average of classifier decision Q15*/
3652 : )
3653 : {
3654 : Word16 i;
3655 : Word16 *pt1, *pt2, *pt3, *pt4, *pt5, *pt6;
3656 : Word16 flux;
3657 : Word32 L_flux;
3658 : Word16 cnt;
3659 : Word16 tmp;
3660 :
3661 : /* calculate flux */
3662 2041 : L_flux = L_deposit_l( 0 );
3663 2041 : cnt = 0;
3664 2041 : move16();
3665 87763 : FOR( i = 0; i < N_OLD_BIN_E; i++ )
3666 : {
3667 85722 : IF( p2v_map[i] != 0 )
3668 : {
3669 20995 : L_flux = L_add_sat( L_flux, abs_s( sub_sat( Bin_E[i], old_Bin_E[i] ) ) ); /*Q7 */
3670 : }
3671 85722 : if ( p2v_map[i] != 0 )
3672 : {
3673 20995 : cnt = add( cnt, 1 );
3674 : }
3675 : }
3676 :
3677 2041 : flux = 640;
3678 2041 : move16(); /*5 in Q7 */
3679 2041 : IF( cnt != 0 )
3680 : {
3681 2035 : tmp = div_s( 1, cnt ); /*Q15 */
3682 2035 : flux = extract_l( Mult_32_16( L_flux, tmp ) ); /*Q7 */
3683 : }
3684 :
3685 2041 : test();
3686 2041 : if ( GT_16( flux, 2560 ) && GT_16( dec_mov, 26214 ) )
3687 : {
3688 54 : flux = 2560;
3689 54 : move16(); /*20 in Q7 */
3690 : }
3691 :
3692 : /* update old Bin_E buffer */
3693 2041 : pt1 = old_Bin_E;
3694 2041 : pt2 = old_Bin_E + N_OLD_BIN_E;
3695 2041 : pt3 = Bin_E;
3696 2041 : pt4 = old_Bin_E + N_OLD_BIN_E;
3697 2041 : pt5 = old_Bin_E + 2 * N_OLD_BIN_E;
3698 2041 : pt6 = old_Bin_E + 2 * N_OLD_BIN_E;
3699 :
3700 87763 : FOR( i = 0; i < N_OLD_BIN_E; i++ )
3701 : {
3702 85722 : *pt1++ = *pt2++;
3703 85722 : move16();
3704 85722 : *pt4++ = *pt5++;
3705 85722 : move16();
3706 85722 : *pt6++ = *pt3++;
3707 85722 : move16();
3708 : }
3709 : /* update flux buffer */
3710 2041 : IF( attack_hangover <= 0 )
3711 : {
3712 122460 : FOR( i = 0; i < BUF_LEN - 1; i++ )
3713 : {
3714 120419 : buf_flux[i] = buf_flux[i + 1];
3715 120419 : move16();
3716 : }
3717 2041 : buf_flux[i] = flux;
3718 2041 : move16();
3719 : }
3720 :
3721 2041 : return;
3722 : }
3723 :
3724 : /*---------------------------------------------------------------------*
3725 : * spec_analysis_fx()
3726 : *
3727 : *
3728 : *---------------------------------------------------------------------*/
3729 :
3730 2041 : static void spec_analysis_fx(
3731 : Word16 *Bin_E, /* i : log energy spectrum of the current frame Q7*/
3732 : Word16 *p2v_map /* o : spectral peakiness map Q7*/
3733 : )
3734 : {
3735 : Word16 i, k, m;
3736 : Word16 peak[65];
3737 : Word16 valley[65];
3738 : Word16 peak_idx[65];
3739 : Word16 valey_idx[65];
3740 : Word16 p2v[65];
3741 : #ifndef ISSUE_1867_replace_overflow_libenc
3742 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
3743 : Flag Overflow = 0;
3744 : move32();
3745 : #endif
3746 : #endif
3747 :
3748 : /* find spectral peaks */
3749 2041 : k = 0;
3750 2041 : move16();
3751 257166 : FOR( i = 1; i < L_FFT / 2 - 2; i++ )
3752 : {
3753 255125 : test();
3754 255125 : IF( GT_16( Bin_E[i], Bin_E[i - 1] ) && GT_16( Bin_E[i], Bin_E[i + 1] ) )
3755 : {
3756 68073 : peak[k] = Bin_E[i];
3757 68073 : move16();
3758 68073 : peak_idx[k] = i;
3759 68073 : move16();
3760 68073 : k = add( k, 1 );
3761 : }
3762 : }
3763 2041 : assert( k + 1 < 65 );
3764 2041 : peak_idx[k] = -1;
3765 2041 : move16();
3766 2041 : peak_idx[k + 1] = -1;
3767 2041 : move16();
3768 2041 : IF( k == 0 )
3769 : {
3770 0 : FOR( i = 0; i < 127; i++ )
3771 : {
3772 0 : p2v_map[i] = 0;
3773 0 : move16();
3774 : }
3775 :
3776 0 : return;
3777 : }
3778 :
3779 : /* find spectral valleys */
3780 2041 : m = 0;
3781 2041 : move16();
3782 :
3783 2041 : IF( LT_16( Bin_E[0], Bin_E[1] ) )
3784 : {
3785 1107 : valley[0] = Bin_E[0];
3786 1107 : move16();
3787 1107 : valey_idx[0] = 0;
3788 1107 : move16();
3789 1107 : m = add( m, 1 );
3790 : }
3791 :
3792 2041 : k = 126;
3793 2041 : move16();
3794 3611 : FOR( i = 125; i >= 0; i-- )
3795 : {
3796 3611 : IF( LE_16( Bin_E[i + 1], Bin_E[i] ) )
3797 : {
3798 2041 : BREAK;
3799 : }
3800 1570 : k = i;
3801 1570 : move16();
3802 : }
3803 :
3804 255596 : FOR( i = 1; i < k; i++ )
3805 : {
3806 253555 : test();
3807 253555 : IF( LT_16( Bin_E[i], Bin_E[i - 1] ) && LT_16( Bin_E[i], Bin_E[i + 1] ) )
3808 : {
3809 66856 : valley[m] = Bin_E[i];
3810 66856 : move16();
3811 66856 : valey_idx[m] = i;
3812 66856 : move16();
3813 66856 : m = add( m, 1 );
3814 : }
3815 : }
3816 2041 : valley[m] = Bin_E[k];
3817 2041 : move16();
3818 2041 : valey_idx[m] = k;
3819 2041 : move16();
3820 :
3821 : /* find spectral peak to valley distances */
3822 2041 : k = 0;
3823 2041 : move16();
3824 70004 : FOR( i = 0; i < m; i++ )
3825 : {
3826 67963 : test();
3827 67963 : IF( GT_16( peak_idx[k], valey_idx[i] ) && LT_16( peak_idx[k], valey_idx[i + 1] ) )
3828 : {
3829 : #ifdef ISSUE_1867_replace_overflow_libenc
3830 66509 : p2v[k] = sub_sat( shl_sat( peak[k], 1 ), add_sat( valley[i], valley[i + 1] ) );
3831 : #else
3832 : #ifdef ISSUE_1796_replace_shl_o
3833 : p2v[k] = sub_o( shl_sat( peak[k], 1 ), add_o( valley[i], valley[i + 1], &Overflow ), &Overflow );
3834 : #else
3835 : p2v[k] = sub_o( shl_o( peak[k], 1, &Overflow ), add_o( valley[i], valley[i + 1], &Overflow ), &Overflow );
3836 : #endif
3837 : #endif
3838 66509 : move16();
3839 66509 : k = add( k, 1 );
3840 : }
3841 : }
3842 :
3843 261248 : FOR( i = 0; i < 127; i++ )
3844 : {
3845 259207 : p2v_map[i] = 0;
3846 259207 : move16();
3847 : }
3848 :
3849 68550 : FOR( i = 0; i < k; i++ )
3850 : {
3851 66509 : p2v_map[peak_idx[i]] = p2v[i];
3852 66509 : move16();
3853 : }
3854 : }
3855 :
3856 2050 : static void music_mixed_classif_improv_fx(
3857 : Encoder_State *st, /* i : encoder state structure */
3858 : const Word16 *new_inp, /* i : new input signal */
3859 : const Word32 *epsP, /* i : LP prediciton error Q_epsP*/
3860 : Word16 Q_epsP,
3861 : Word16 etot, /* i : total frame energy Q8*/
3862 : Word16 old_cor, /* i : normalized correlation Q15*/
3863 : Word16 cor_map_sum /* i : correlation map sum Q8*/
3864 : )
3865 : {
3866 : Word16 i, max_spl, dec, len, percus_flag, lt_diff, log_max_spl, epsP_tilt, p2v_map[128];
3867 : Word16 exp, frac, expn, fracn, expd, fracd, scale;
3868 : Word16 tmp;
3869 2050 : Word32 L_tmp, ftmp, ftmp1, epsP_max = MIN_32;
3870 2050 : move32();
3871 2050 : SP_MUS_CLAS_HANDLE hSpMusClas = st->hSpMusClas;
3872 :
3873 : /* find sample with maximum absolute amplitude */
3874 2050 : max_spl = 0;
3875 2050 : move16();
3876 526850 : FOR( i = 0; i < L_FRAME; i++ )
3877 : {
3878 524800 : max_spl = s_max( abs_s( new_inp[i] ), max_spl );
3879 : }
3880 :
3881 : /* music is considered only appearing in high SNR condition and active signal */
3882 2050 : test();
3883 2050 : IF( st->vad_flag == 0 || LT_16( sub( st->lp_speech_fx, st->lp_noise_fx ), 6400 ) ) /* 25 in Q8 */
3884 : {
3885 : /* st->dec_mov = 0.5f; */
3886 : /* st->dec_mov1 = 0.5f; */
3887 9 : hSpMusClas->dec_mov_fx = 16384;
3888 9 : move16();
3889 9 : hSpMusClas->dec_mov1_fx = 16384;
3890 9 : move16();
3891 :
3892 9 : if ( st->vad_flag == 0 )
3893 : {
3894 9 : hSpMusClas->onset_cnt = 0;
3895 9 : move16();
3896 : }
3897 :
3898 9 : return;
3899 : }
3900 :
3901 2041 : hSpMusClas->onset_cnt = add( hSpMusClas->onset_cnt, 1 );
3902 2041 : hSpMusClas->onset_cnt = s_min( hSpMusClas->onset_cnt, 9 );
3903 :
3904 2041 : IF( EQ_16( hSpMusClas->onset_cnt, 1 ) )
3905 : {
3906 5 : set16_fx( hSpMusClas->buf_flux_fx, -12800, BUF_LEN ); /*-100.0 in Q7 */
3907 : }
3908 :
3909 : /* spectral analysis */
3910 2041 : spec_analysis_fx( st->lgBin_E_fx, p2v_map );
3911 :
3912 : /* percussive music detection */
3913 2041 : log_max_spl = 0;
3914 2041 : move16();
3915 2041 : IF( max_spl )
3916 : {
3917 2041 : L_tmp = L_deposit_h( max_spl ); /*Q16 */
3918 2041 : exp = norm_l( L_tmp );
3919 2041 : frac = Log2_norm_lc( L_shl( L_tmp, exp ) );
3920 2041 : exp = sub( sub( 30, exp ), 16 );
3921 2041 : L_tmp = Mpy_32_16( exp, frac, 28391 ); /*Q12 */
3922 2041 : log_max_spl = round_fx( L_shl( L_tmp, 11 ) ); /*Q7 */
3923 : }
3924 :
3925 2041 : lt_diff = sub( log_max_spl, hSpMusClas->mov_log_max_spl_fx ); /*Q7 */
3926 :
3927 8164 : FOR( i = 0; i < 3; i++ )
3928 : {
3929 6123 : hSpMusClas->buf_etot_fx[i] = hSpMusClas->buf_etot_fx[i + 1];
3930 6123 : move16(); /*Q8 */
3931 : }
3932 2041 : hSpMusClas->buf_etot_fx[i] = etot;
3933 2041 : move16(); /*Q8 */
3934 :
3935 2041 : percus_flag = 0;
3936 2041 : move16();
3937 2041 : test();
3938 2041 : test();
3939 2041 : IF( GT_16( sub( hSpMusClas->buf_etot_fx[1], hSpMusClas->buf_etot_fx[0] ), 1536 ) &&
3940 : LT_16( hSpMusClas->buf_etot_fx[2], hSpMusClas->buf_etot_fx[1] ) &&
3941 : GT_16( sub( hSpMusClas->buf_etot_fx[1], st->lp_speech_fx ), 768 ) ) /* 3 in Q8 */
3942 : {
3943 : /*tmp = add(shr(voicing[0],2),shr(voicing[1],2)); //Q15 */
3944 : /*tmp = add(tmp,shr(old_cor,1)); //Q15 */
3945 15 : tmp = mac_r( L_mac( L_mult( st->voicing_fx[0], 8192 ), st->voicing_fx[1], 8192 ), old_cor, 16384 );
3946 15 : test();
3947 15 : test();
3948 15 : IF( GT_16( sub( hSpMusClas->buf_etot_fx[1], hSpMusClas->buf_etot_fx[3] ), 768 ) &&
3949 : LT_16( hSpMusClas->buf_etot_fx[3], hSpMusClas->buf_etot_fx[2] ) &&
3950 : LT_16( tmp, 24576 ) ) /* 0.75 in Q15 */
3951 : {
3952 4 : IF( GT_16( hSpMusClas->dec_mov_fx, 26214 ) ) /* 0.8 in Q15 */
3953 : {
3954 2 : percus_flag = 1;
3955 2 : move16();
3956 : }
3957 : ELSE
3958 : {
3959 2 : test();
3960 2 : test();
3961 2 : test();
3962 2 : if ( LT_16( old_cor, 24576 ) && LT_16( st->voicing_fx[0], 24576 ) && LT_16( st->voicing_fx[1], 24576 ) && GT_16( hSpMusClas->old_lt_diff_fx[0], 1280 ) )
3963 : {
3964 0 : percus_flag = 1;
3965 0 : move16();
3966 : }
3967 : }
3968 : }
3969 : }
3970 :
3971 : /* sound attack detection */
3972 2041 : test();
3973 2041 : test();
3974 2041 : test();
3975 2041 : if ( GT_16( sub( hSpMusClas->buf_etot_fx[3], hSpMusClas->buf_etot_fx[2] ), 1536 ) && GT_16( hSpMusClas->dec_mov_fx, 29491 ) && GT_16( sub( etot, st->lp_speech_fx ), 1280 ) && GT_16( hSpMusClas->old_lt_diff_fx[0], 640 ) )
3976 : {
3977 0 : hSpMusClas->attack_hangover = 3;
3978 0 : move16();
3979 : }
3980 :
3981 2041 : test();
3982 2041 : IF( GT_16( st->voicing_fx[0], 29491 ) && GT_16( st->voicing_fx[1], 29491 ) )
3983 : {
3984 555 : IF( GT_16( log_max_spl, hSpMusClas->mov_log_max_spl_fx ) )
3985 : {
3986 : /**mov_log_max_spl = add(mult_r(31130,(*mov_log_max_spl)),mult_r(1638,log_max_spl)); //Q7 */
3987 28 : hSpMusClas->mov_log_max_spl_fx = round_fx( L_mac( L_mult( 31130, hSpMusClas->mov_log_max_spl_fx ), 1638, log_max_spl ) ); /*Q7 */
3988 : }
3989 : ELSE
3990 : {
3991 : /**mov_log_max_spl = add(mult_r(32604,(*mov_log_max_spl)),mult_r(164,log_max_spl)); //Q7 */
3992 527 : hSpMusClas->mov_log_max_spl_fx = round_fx( L_mac( L_mult( 32604, hSpMusClas->mov_log_max_spl_fx ), 164, log_max_spl ) ); /*Q7 */
3993 : }
3994 : }
3995 :
3996 2041 : hSpMusClas->old_lt_diff_fx[0] = hSpMusClas->old_lt_diff_fx[1];
3997 2041 : move16(); /*Q7 */
3998 2041 : hSpMusClas->old_lt_diff_fx[1] = lt_diff;
3999 2041 : move16(); /*Q7 */
4000 :
4001 : /* calculate and buffer spectral energy fluctuation */
4002 2041 : flux_fx( st->lgBin_E_fx, p2v_map, hSpMusClas->old_Bin_E_fx, hSpMusClas->buf_flux_fx, hSpMusClas->attack_hangover, hSpMusClas->dec_mov_fx );
4003 :
4004 2041 : hSpMusClas->attack_hangover = sub( hSpMusClas->attack_hangover, 1 );
4005 2041 : move16();
4006 2041 : hSpMusClas->attack_hangover = s_max( hSpMusClas->attack_hangover, 0 );
4007 2041 : move16();
4008 :
4009 : /* identify flux buffer buffering status */
4010 2041 : len = 0;
4011 2041 : move16();
4012 115822 : FOR( i = BUF_LEN - 1; i >= 0; i-- )
4013 : {
4014 114058 : IF( hSpMusClas->buf_flux_fx[i] < 0 )
4015 : {
4016 277 : BREAK;
4017 : }
4018 :
4019 113781 : len = add( len, 1 );
4020 : }
4021 :
4022 : /* reset flux buffer if percussive music is detected */
4023 2041 : IF( EQ_16( percus_flag, 1 ) )
4024 : {
4025 2 : set16_fx( &hSpMusClas->buf_flux_fx[BUF_LEN - len], 640, len ); /* 5 in Q7 */
4026 : }
4027 :
4028 : /* calculate and buffer the tilt of residual LP energies */
4029 2041 : ftmp = 0;
4030 2041 : move16();
4031 2041 : ftmp1 = 0;
4032 2041 : move16();
4033 34697 : FOR( i = 1; i <= 16; i++ )
4034 : {
4035 32656 : epsP_max = L_max( epsP_max, epsP[i] );
4036 : }
4037 :
4038 32656 : FOR( i = 1; i < 16; i++ )
4039 : {
4040 30615 : IF( EQ_32( epsP[i], epsP_max ) )
4041 : {
4042 2041 : tmp = -32768;
4043 2041 : move16();
4044 2041 : L_tmp = Mult_32_16( epsP[i], tmp ); /* Q_epsP */
4045 2041 : ftmp = L_sub( ftmp, L_shr( L_tmp, 4 ) ); /* Q(Q_epsP-4) */
4046 : }
4047 : ELSE
4048 : {
4049 28574 : expn = norm_l( epsP[i] );
4050 28574 : fracn = extract_h( L_shl( epsP[i], expn ) );
4051 28574 : expn = sub( sub( 30, expn ), Q_epsP );
4052 :
4053 28574 : expd = norm_l( epsP_max );
4054 28574 : fracd = extract_h( L_shl( epsP_max, expd ) );
4055 28574 : expd = sub( sub( 30, expd ), Q_epsP );
4056 :
4057 28574 : scale = shr( sub( fracd, fracn ), 15 );
4058 28574 : fracn = shl( fracn, scale );
4059 28574 : expn = sub( expn, scale );
4060 :
4061 28574 : tmp = div_s( fracn, fracd ); /*Q(15+expd-expn) */
4062 28574 : tmp = shl( tmp, sub( expn, expd ) ); /*Q15 */
4063 :
4064 28574 : L_tmp = Mult_32_16( epsP[i], tmp ); /*Q_epsP */
4065 28574 : ftmp = L_add( ftmp, L_shr( L_tmp, 4 ) ); /*Q(Q_epsP-4) */
4066 : }
4067 : }
4068 :
4069 32656 : FOR( i = 1; i < 16; i++ )
4070 : {
4071 30615 : IF( EQ_32( epsP[i], epsP_max ) )
4072 : {
4073 2041 : tmp = -32768;
4074 2041 : move16();
4075 2041 : L_tmp = Mult_32_16( epsP[i + 1], tmp ); /*Q_epsP */
4076 2041 : ftmp1 = L_sub( ftmp1, L_shr( L_tmp, 4 ) ); /*Q(Q_epsP-4) */
4077 : }
4078 28574 : ELSE IF( EQ_32( epsP[i + 1], epsP_max ) )
4079 : {
4080 0 : tmp = -32768;
4081 0 : move16();
4082 0 : L_tmp = Mult_32_16( epsP[i], tmp ); /*Q_epsP */
4083 0 : ftmp1 = L_sub( ftmp1, L_shr( L_tmp, 4 ) ); /*Q(Q_epsP-4) */
4084 : }
4085 : ELSE
4086 : {
4087 28574 : expn = norm_l( epsP[i] );
4088 28574 : fracn = extract_h( L_shl( epsP[i], expn ) );
4089 28574 : expn = sub( sub( 30, expn ), Q_epsP );
4090 :
4091 28574 : expd = norm_l( epsP_max );
4092 28574 : fracd = extract_h( L_shl( epsP_max, expd ) );
4093 28574 : expd = sub( sub( 30, expd ), Q_epsP );
4094 :
4095 28574 : scale = shr( sub( fracd, fracn ), 15 );
4096 28574 : fracn = shl( fracn, scale );
4097 28574 : expn = sub( expn, scale );
4098 :
4099 28574 : tmp = div_s( fracn, fracd ); /*Q(15+expd-expn) */
4100 28574 : tmp = shl( tmp, sub( expn, expd ) ); /*Q15 */
4101 :
4102 28574 : L_tmp = Mult_32_16( epsP[i + 1], tmp ); /*Q_epsP */
4103 28574 : ftmp1 = L_add( ftmp1, L_shr( L_tmp, 4 ) ); /*Q(Q_epsP-4) */
4104 : }
4105 : }
4106 :
4107 : /* epsP_tilt = ftmp1/ftmp; */
4108 2041 : expn = norm_l( ftmp1 );
4109 2041 : fracn = extract_h( L_shl( ftmp1, expn ) );
4110 2041 : expn = sub( sub( 30, expn ), Q_epsP - 4 );
4111 :
4112 2041 : expd = norm_l( ftmp );
4113 2041 : fracd = round_fx_sat( L_shl( ftmp, expd ) );
4114 2041 : expd = sub( sub( 30, expd ), sub( Q_epsP, 4 ) );
4115 :
4116 2041 : scale = shr( sub( fracd, fracn ), 15 );
4117 2041 : fracn = shl( fracn, scale );
4118 2041 : expn = sub( expn, scale );
4119 :
4120 2041 : tmp = div_s( fracn, fracd ); /*Q(15+expd-expn) */
4121 :
4122 2041 : epsP_tilt = shl( tmp, sub( expn, expd ) ); /*Q15 */
4123 :
4124 122460 : FOR( i = 0; i < BUF_LEN - 1; i++ )
4125 : {
4126 120419 : hSpMusClas->buf_epsP_tilt_fx[i] = hSpMusClas->buf_epsP_tilt_fx[i + 1];
4127 120419 : move16(); /*Q15 */
4128 : }
4129 2041 : hSpMusClas->buf_epsP_tilt_fx[i] = epsP_tilt;
4130 2041 : move16(); /*Q15 */
4131 :
4132 : /* calculate and buffer highband spectral peakness */
4133 2041 : tonal_dist_fx( p2v_map, hSpMusClas->buf_pkh_fx, hSpMusClas->buf_Ntonal_fx, hSpMusClas->buf_Ntonal2_fx, hSpMusClas->buf_Ntonal_lf_fx );
4134 :
4135 : /* buffer sum of correlation map */
4136 122460 : FOR( i = 0; i < BUF_LEN - 1; i++ )
4137 : {
4138 120419 : hSpMusClas->buf_cor_map_sum_fx[i] = hSpMusClas->buf_cor_map_sum_fx[i + 1];
4139 120419 : move16(); /*Q8 */
4140 : }
4141 2041 : hSpMusClas->buf_cor_map_sum_fx[i] = cor_map_sum;
4142 2041 : move16(); /*Q8 */
4143 :
4144 : /* buffer voicing metric */
4145 20410 : FOR( i = 0; i < 9; i++ )
4146 : {
4147 18369 : hSpMusClas->buf_dlp_fx[i] = hSpMusClas->buf_dlp_fx[i + 1];
4148 18369 : move16();
4149 : }
4150 2041 : hSpMusClas->buf_dlp_fx[i] = sub( hSpMusClas->lps_fx, hSpMusClas->lpm_fx );
4151 2041 : move16(); /*Q9 */
4152 :
4153 : /* classification */
4154 2041 : dec = mode_decision_fx( st, len, &hSpMusClas->dec_mov_fx, hSpMusClas->buf_flux_fx, hSpMusClas->buf_epsP_tilt_fx, hSpMusClas->buf_pkh_fx,
4155 2041 : hSpMusClas->buf_cor_map_sum_fx, hSpMusClas->buf_Ntonal_fx, hSpMusClas->buf_Ntonal2_fx, hSpMusClas->buf_Ntonal_lf_fx,
4156 2041 : hSpMusClas->buf_dlp_fx );
4157 2041 : move16();
4158 :
4159 : /* update long term moving average of the classification decisions */
4160 2041 : IF( GT_16( len, 30 ) )
4161 : {
4162 1891 : IF( dec == 0 )
4163 : {
4164 1501 : hSpMusClas->dec_mov_fx = mult_r( 31785, hSpMusClas->dec_mov_fx ); /*Q15 */
4165 1501 : hSpMusClas->dec_mov1_fx = mult_r( 31785, hSpMusClas->dec_mov1_fx ); /*Q15 */
4166 : }
4167 : ELSE
4168 : {
4169 390 : hSpMusClas->dec_mov_fx = add( mult_r( 31785, hSpMusClas->dec_mov_fx ), 983 ); /*Q15 */
4170 390 : hSpMusClas->dec_mov1_fx = add( mult_r( 31785, hSpMusClas->dec_mov1_fx ), 983 ); /*Q15 */
4171 : }
4172 1891 : move16();
4173 1891 : move16();
4174 : }
4175 :
4176 : /* update long term unvoiced counter */
4177 2041 : test();
4178 2041 : test();
4179 2041 : test();
4180 2041 : IF( ( EQ_16( st->coder_type_raw, UNVOICED ) || EQ_16( st->coder_type_raw, INACTIVE ) ) &&
4181 : GT_16( etot, 384 ) && LT_16( hSpMusClas->buf_Ntonal2_fx[59], 2 ) )
4182 : {
4183 73 : hSpMusClas->UV_cnt1 = sub( hSpMusClas->UV_cnt1, 8 );
4184 : }
4185 : ELSE
4186 : {
4187 1968 : hSpMusClas->UV_cnt1 = add( hSpMusClas->UV_cnt1, 1 );
4188 : }
4189 2041 : move16();
4190 :
4191 2041 : hSpMusClas->UV_cnt1 = s_min( hSpMusClas->UV_cnt1, 300 );
4192 2041 : move16();
4193 2041 : hSpMusClas->UV_cnt1 = s_max( hSpMusClas->UV_cnt1, 0 );
4194 2041 : move16();
4195 :
4196 : /**LT_UV_cnt1 = add(mult_r(29491,*LT_UV_cnt1),mult_r(3277,shl(*UV_cnt1,6)));*/ /* Q6 */
4197 2041 : hSpMusClas->LT_UV_cnt1_fx = round_fx( L_mac( L_mult( 29491, hSpMusClas->LT_UV_cnt1_fx ), 3277, shl( hSpMusClas->UV_cnt1, 6 ) ) ); /*Q6 */
4198 2041 : move16();
4199 : /* revert classification decision due to long-term unvoiced counter */
4200 2041 : test();
4201 2041 : test();
4202 2041 : if ( EQ_16( dec, 1 ) && LT_16( hSpMusClas->dec_mov1_fx, 6554 ) && LT_16( hSpMusClas->LT_UV_cnt1_fx, 12800 ) )
4203 : {
4204 0 : dec = 0;
4205 0 : move16();
4206 : }
4207 :
4208 : /* overwrite 1st stage speech/music decision to music */
4209 2041 : if ( EQ_16( dec, 1 ) )
4210 : {
4211 420 : st->sp_aud_decision1 = 1;
4212 420 : move16();
4213 : }
4214 :
4215 2041 : return;
4216 : }
4217 :
4218 :
4219 : /*----------------------------------------------------------------------------------*
4220 : * tonal_context_improv_fx()
4221 : *
4222 : * Context-based improvement of 1st/2nd stage speech/music decision on stable tonal signals
4223 : *----------------------------------------------------------------------------------*/
4224 :
4225 2050 : static void tonal_context_improv_fx(
4226 : Encoder_State *st_fx, /* i/o: Encoder state structure */
4227 : const Word32 PS[], /* i : energy spectrum */
4228 : const Word16 voi_fv, /* i : scaled voicing feature */
4229 : const Word16 cor_map_sum_fv, /* i : scaled correlation map feature */
4230 : const Word16 LPCErr, /* i : scaled LP prediction error feature */
4231 : const Word16 Qx )
4232 : {
4233 : Word16 t2_fx, t3_fx, tL_fx, err_fx, cor_fx, dft_fx;
4234 : Word16 exp, expa, expb, fraca, fracb, scale, exp1, exp2, exp3, tmp;
4235 : Word16 voi_mean, lt_pitch_diff;
4236 : Word32 L_tmp, tonality, tonality1, tonality2, tonality3, sort_max, sort_avg, sort_val[80];
4237 2050 : VAD_HANDLE hVAD = st_fx->hVAD;
4238 2050 : SP_MUS_CLAS_HANDLE hSpMusClas = st_fx->hSpMusClas;
4239 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
4240 2050 : Flag Overflow = 0;
4241 2050 : move16();
4242 : #endif
4243 :
4244 2050 : IF( EQ_16( st_fx->last_codec_mode, MODE2 ) )
4245 : {
4246 262 : set16_fx( hSpMusClas->tonality2_buf_fx, 0, HANG_LEN_INIT );
4247 262 : set16_fx( hSpMusClas->tonality3_buf_fx, 0, HANG_LEN_INIT );
4248 262 : set16_fx( hSpMusClas->LPCErr_buf_fx, 0, HANG_LEN_INIT );
4249 262 : hSpMusClas->lt_music_hangover = 0;
4250 262 : move16();
4251 262 : hSpMusClas->lt_music_state = 0;
4252 262 : move16();
4253 262 : hSpMusClas->lt_speech_state = 0;
4254 262 : move16();
4255 262 : hSpMusClas->lt_speech_hangover = 0;
4256 262 : move16();
4257 : }
4258 :
4259 : /* estimate maximum tonality in bands [0-1 kHz], [1-2kHz] and [2-4kHz] */
4260 2050 : Copy32( PS, sort_val, 80 );
4261 :
4262 : /* tonality in band [0-1 kHz] */
4263 2050 : sort_32_fx( sort_val, 0, 19 );
4264 2050 : sort_max = L_add( sort_val[19], 0 );
4265 2050 : sort_avg = sum32_fx( &sort_val[0], 10 );
4266 :
4267 : /* tonality1 = sort_max / sort_avg; */
4268 2050 : IF( sort_avg )
4269 : {
4270 2050 : expa = norm_l( sort_max );
4271 2050 : fraca = extract_h( L_shl( sort_max, expa ) );
4272 2050 : expa = sub( 30, add( expa, Qx ) );
4273 :
4274 2050 : expb = norm_l( sort_avg );
4275 2050 : fracb = extract_h( L_shl( sort_avg, expb ) );
4276 2050 : expb = sub( 30, add( expb, Qx ) );
4277 :
4278 2050 : scale = shr( sub( fracb, fraca ), 15 );
4279 2050 : fraca = shl( fraca, scale );
4280 2050 : expa = sub( expa, scale );
4281 :
4282 2050 : tmp = div_s( fraca, fracb );
4283 2050 : exp1 = sub( expa, expb );
4284 :
4285 2050 : tonality1 = L_shl_o( tmp, exp1, &Overflow );
4286 : }
4287 : ELSE
4288 : {
4289 0 : tonality1 = L_shl( sort_max, sub( 15, Qx ) ); /*Q15 */
4290 : }
4291 :
4292 : /* tonality in band [1-2 kHz] */
4293 2050 : sort_32_fx( sort_val, 20, 39 );
4294 2050 : sort_max = sort_val[39];
4295 2050 : sort_avg = sum32_fx( &sort_val[20], 10 );
4296 :
4297 2050 : IF( sort_avg )
4298 : {
4299 : /* tonality2 = sort_max / sort_avg; */
4300 2050 : expa = norm_l( sort_max );
4301 2050 : fraca = extract_h( L_shl( sort_max, expa ) );
4302 2050 : expa = sub( 30, add( expa, Qx ) );
4303 :
4304 :
4305 2050 : expb = norm_l( sort_avg );
4306 2050 : fracb = extract_h( L_shl( sort_avg, expb ) );
4307 2050 : expb = sub( 30, add( expb, Qx ) );
4308 :
4309 2050 : scale = shr( sub( fracb, fraca ), 15 );
4310 2050 : fraca = shl( fraca, scale );
4311 2050 : expa = sub( expa, scale );
4312 :
4313 2050 : tmp = div_s( fraca, fracb );
4314 2050 : exp2 = sub( expa, expb );
4315 :
4316 2050 : tonality2 = L_shl_o( tmp, exp2, &Overflow );
4317 : }
4318 : ELSE
4319 : {
4320 0 : tonality2 = L_shl( sort_max, sub( 15, Qx ) ); /*Q15 */
4321 : }
4322 :
4323 : /* tonality in band [2-4 kHz] */
4324 2050 : sort_32_fx( sort_val, 40, 79 );
4325 2050 : sort_max = sort_val[79];
4326 2050 : sort_avg = sum32_fx( &sort_val[40], 20 );
4327 :
4328 2050 : IF( sort_avg )
4329 : {
4330 : /* tonality3 = sort_max / sort_avg; */
4331 2050 : expa = norm_l( sort_max );
4332 2050 : fraca = extract_h( L_shl( sort_max, expa ) );
4333 2050 : expa = sub( 30, add( expa, Qx ) );
4334 :
4335 2050 : expb = norm_l( sort_avg );
4336 2050 : fracb = extract_h( L_shl( sort_avg, expb ) );
4337 2050 : expb = sub( 30, add( expb, Qx ) );
4338 :
4339 2050 : scale = shr( sub( fracb, fraca ), 15 );
4340 2050 : fraca = shl( fraca, scale );
4341 2050 : expa = sub( expa, scale );
4342 :
4343 2050 : tmp = div_s( fraca, fracb );
4344 2050 : exp3 = sub( expa, expb );
4345 :
4346 2050 : tonality3 = L_shl_o( tmp, exp3, &Overflow );
4347 : }
4348 : ELSE
4349 : {
4350 0 : tonality3 = L_shl( sort_max, sub( 15, Qx ) ); /*Q15 */
4351 : }
4352 :
4353 2050 : tonality = L_max( L_max( tonality1, tonality2 ), tonality3 );
4354 :
4355 : /* voi_mean = 0.33f * (st->voicing_fx[0] + voicing[1] + voicing[2]); */
4356 2050 : L_tmp = L_mult( st_fx->voicing_fx[0], 10923 );
4357 2050 : L_tmp = L_mac( L_tmp, st_fx->voicing_fx[1], 10923 );
4358 2050 : voi_mean = mac_r_sat( L_tmp, st_fx->voicing_fx[2], 10923 ); /* Q15 */
4359 2050 : test();
4360 2050 : IF( EQ_16( hVAD->hangover_cnt, 10 ) && EQ_16( st_fx->vad_flag, 1 ) )
4361 : {
4362 : /* long-term voicing parameter */
4363 10 : hSpMusClas->lt_voicing = round_fx( L_mac( L_mult( 3277, hSpMusClas->lt_voicing ), 29491, voi_mean ) );
4364 :
4365 : /* long-term correlation value */
4366 10 : hSpMusClas->lt_corr = round_fx( L_mac( L_mult( 3277, hSpMusClas->lt_corr ), 29491, st_fx->old_corr_fx ) );
4367 :
4368 : /* long-term tonality measure */
4369 10 : hSpMusClas->lt_tonality = L_add( Mult_32_16( hSpMusClas->lt_tonality, 3277 ), Mult_32_16( tonality, 29491 ) );
4370 : }
4371 : ELSE
4372 : {
4373 : /* long-term voicing parameter */
4374 2040 : hSpMusClas->lt_voicing = round_fx( L_mac( L_mult( 22938, hSpMusClas->lt_voicing ), 9830, voi_mean ) );
4375 :
4376 : /* long-term correlation value */
4377 2040 : hSpMusClas->lt_corr = round_fx( L_mac( L_mult( 22938, hSpMusClas->lt_corr ), 9830, st_fx->old_corr_fx ) );
4378 :
4379 : /* long-term tonality measure */
4380 2040 : hSpMusClas->lt_tonality = L_add( Mult_32_16( hSpMusClas->lt_tonality, 16384 ), Mult_32_16( tonality, 16384 ) );
4381 : }
4382 2050 : move16();
4383 2050 : move16();
4384 2050 : move16();
4385 :
4386 : /* Pitch difference w.r.t to past 3 frames */
4387 2050 : lt_pitch_diff = abs_s( sub( hSpMusClas->lt_corr_pitch[0], st_fx->pitch[0] ) );
4388 2050 : lt_pitch_diff = add( lt_pitch_diff, abs_s( sub( hSpMusClas->lt_corr_pitch[1], st_fx->pitch[0] ) ) );
4389 2050 : lt_pitch_diff = add( lt_pitch_diff, abs_s( sub( hSpMusClas->lt_corr_pitch[2], st_fx->pitch[0] ) ) );
4390 :
4391 2050 : hSpMusClas->lt_corr_pitch[0] = hSpMusClas->lt_corr_pitch[1];
4392 2050 : move16();
4393 2050 : hSpMusClas->lt_corr_pitch[1] = hSpMusClas->lt_corr_pitch[2];
4394 2050 : move16();
4395 2050 : hSpMusClas->lt_corr_pitch[2] = st_fx->pitch[0];
4396 2050 : move16();
4397 :
4398 2050 : hSpMusClas->lt_old_mode[0] = hSpMusClas->lt_old_mode[1];
4399 2050 : move16();
4400 2050 : hSpMusClas->lt_old_mode[1] = hSpMusClas->lt_old_mode[2];
4401 2050 : move16();
4402 :
4403 2050 : test();
4404 2050 : test();
4405 2050 : test();
4406 2050 : test();
4407 2050 : test();
4408 2050 : test();
4409 2050 : test();
4410 2050 : test();
4411 2050 : test();
4412 2050 : test();
4413 2050 : test();
4414 2050 : test();
4415 2050 : test();
4416 2050 : IF( st_fx->sp_aud_decision1 == 1 &&
4417 : ( GT_32( L_min( L_min( tonality1, tonality2 ), tonality3 ), 1638400 ) ) &&
4418 : ( GT_32( L_add_sat( tonality1, tonality2 ), 6553600 ) && GT_32( L_add_sat( tonality2, tonality3 ), 6553600 ) && GT_32( L_add_sat( tonality1, tonality3 ), 6553600 ) ) &&
4419 : ( LT_32( hSpMusClas->lt_tonality, 655360000 ) ) &&
4420 : ( ( GT_32( hSpMusClas->lt_tonality, 32768000 ) && GT_16( s_max( hSpMusClas->lt_voicing, voi_mean ), 32440 ) ) ||
4421 : ( GT_32( hSpMusClas->lt_tonality, 49152000 ) && GT_16( hSpMusClas->lt_corr, 32440 ) ) ||
4422 : ( GT_32( hSpMusClas->lt_tonality, 98304000 ) && GT_16( hSpMusClas->lowrate_pitchGain, 15729 ) ) ||
4423 : ( lt_pitch_diff == 0 && GT_16( hSpMusClas->lowrate_pitchGain, 14582 ) ) ) )
4424 : {
4425 19 : IF( LT_16( sum16_fx( hSpMusClas->lt_old_mode, 2 ), 2 ) )
4426 : {
4427 : /* probably speech - change the decision to speech */
4428 0 : st_fx->sp_aud_decision1 = 0;
4429 0 : move16();
4430 0 : st_fx->sp_aud_decision2 = 0;
4431 0 : move16();
4432 :
4433 0 : if ( hSpMusClas->lt_hangover == 0 )
4434 : {
4435 0 : hSpMusClas->lt_hangover = 6;
4436 0 : move16();
4437 : }
4438 : }
4439 : }
4440 : ELSE
4441 : {
4442 : /* not speech, but still in the hangover period - change the decision to speech */
4443 2031 : IF( hSpMusClas->lt_hangover > 0 )
4444 : {
4445 0 : st_fx->sp_aud_decision1 = 0;
4446 0 : move16();
4447 0 : st_fx->sp_aud_decision2 = 0;
4448 0 : move16();
4449 :
4450 0 : hSpMusClas->lt_hangover = sub( hSpMusClas->lt_hangover, 1 );
4451 : }
4452 : }
4453 :
4454 : /* calculate standard deviation of log-tonality */
4455 2050 : Copy( hSpMusClas->tonality2_buf_fx + 1, hSpMusClas->tonality2_buf_fx, HANG_LEN_INIT - 1 );
4456 : /* st->tonality2_buf[HANG_LEN_INIT - 1] = 0.2f*(float)log10(tonality2); */
4457 2050 : exp = norm_l( tonality2 );
4458 2050 : tmp = Log2_norm_lc( L_shl( tonality2, exp ) ); /*15 */
4459 2050 : exp = sub( 30, add( exp, 16 ) );
4460 2050 : L_tmp = Mpy_32_16( exp, tmp, 15783 ); /*19 //3945, 0.2*log10(2), Q18 */
4461 2050 : hSpMusClas->tonality2_buf_fx[HANG_LEN_INIT - 1] = round_fx( L_shl( L_tmp, 11 ) ); /*14 */
4462 2050 : move16();
4463 : /* t2 = std( st->tonality2_buf, HANG_LEN_INIT ); */
4464 2050 : t2_fx = std_fx( hSpMusClas->tonality2_buf_fx, HANG_LEN_INIT ); /*14 */
4465 :
4466 2050 : Copy( hSpMusClas->tonality3_buf_fx + 1, hSpMusClas->tonality3_buf_fx, HANG_LEN_INIT - 1 );
4467 : /* st->tonality3_buf[HANG_LEN_INIT - 1] = 0.2f*(float)log10(tonality3); */
4468 2050 : exp = norm_l( tonality3 );
4469 2050 : tmp = Log2_norm_lc( L_shl( tonality3, exp ) ); /*15 */
4470 2050 : exp = sub( 30, add( exp, 16 ) );
4471 2050 : L_tmp = Mpy_32_16( exp, tmp, 15783 ); /*19 //3945, 0.2*log10(2), Q18 */
4472 2050 : hSpMusClas->tonality3_buf_fx[HANG_LEN_INIT - 1] = round_fx( L_shl( L_tmp, 11 ) ); /*14 */
4473 2050 : t3_fx = std_fx( hSpMusClas->tonality3_buf_fx, HANG_LEN_INIT ); /*14 */
4474 2050 : move16();
4475 :
4476 : /* tL = 0.2f*(float)log10(st->lt_tonality); */
4477 2050 : exp = norm_l( hSpMusClas->lt_tonality );
4478 2050 : tmp = Log2_norm_lc( L_shl( hSpMusClas->lt_tonality, exp ) ); /*15 */
4479 2050 : exp = sub( 30, add( exp, 16 ) );
4480 2050 : L_tmp = Mpy_32_16( exp, tmp, 15783 ); /*19 //3945, 0.2*log10(2), Q18 */
4481 2050 : tL_fx = round_fx( L_shl( L_tmp, 11 ) ); /*14 */
4482 :
4483 : /* calculate standard deviation of residual LP energy */
4484 2050 : Copy( hSpMusClas->LPCErr_buf_fx + 1, hSpMusClas->LPCErr_buf_fx, HANG_LEN_INIT - 1 );
4485 2050 : hSpMusClas->LPCErr_buf_fx[HANG_LEN_INIT - 1] = LPCErr;
4486 2050 : move16();
4487 : /* err = std( st->LPCErr_buf, HANG_LEN_INIT ); */
4488 2050 : err_fx = std_fx( hSpMusClas->LPCErr_buf_fx, HANG_LEN_INIT );
4489 :
4490 2050 : cor_fx = s_max( sub( voi_fv, cor_map_sum_fv ), 0 ); /*15 */
4491 2050 : dft_fx = abs_s( sub( hSpMusClas->tonality2_buf_fx[HANG_LEN_INIT - 1], hSpMusClas->tonality3_buf_fx[HANG_LEN_INIT - 1] ) ); /*14 */
4492 :
4493 :
4494 : /* state machine for strong music */
4495 2050 : test();
4496 2050 : test();
4497 2050 : test();
4498 2050 : test();
4499 2050 : test();
4500 2050 : test();
4501 2050 : test();
4502 2050 : test();
4503 2050 : test();
4504 2050 : test();
4505 2050 : test();
4506 2050 : test();
4507 2050 : IF( ( EQ_16( st_fx->sp_aud_decision1, 1 ) ) && hSpMusClas->lt_music_state == 0 && hSpMusClas->lt_music_hangover == 0 &&
4508 : ( LT_16( t2_fx, 8847 ) ) && ( GT_16( t2_fx, 4260 ) ) && ( GT_16( t3_fx, 3604 ) ) && ( LT_16( tL_fx, 8847 ) ) && ( GT_16( tL_fx, 4260 ) ) && ( GT_16( err_fx, 8192 ) ) )
4509 : {
4510 7 : hSpMusClas->lt_music_state = 1;
4511 7 : move16();
4512 7 : hSpMusClas->lt_music_hangover = 6;
4513 7 : move16();
4514 : }
4515 2043 : ELSE IF( EQ_16( hSpMusClas->lt_music_state, 1 ) && hSpMusClas->lt_music_hangover == 0 &&
4516 : ( LT_16( t2_fx, 5571 ) ) && ( LT_16( t3_fx, 4260 ) ) && ( LT_16( tL_fx, 7373 ) ) )
4517 : {
4518 6 : hSpMusClas->lt_music_state = 0;
4519 6 : move16();
4520 6 : hSpMusClas->lt_music_hangover = 6;
4521 6 : move16();
4522 : }
4523 :
4524 2050 : IF( hSpMusClas->lt_music_hangover > 0 )
4525 : {
4526 73 : hSpMusClas->lt_music_hangover = sub( hSpMusClas->lt_music_hangover, 1 );
4527 73 : move16();
4528 : }
4529 :
4530 : /* state machine for strong speech */
4531 2050 : test();
4532 2050 : test();
4533 2050 : test();
4534 2050 : test();
4535 2050 : test();
4536 2050 : test();
4537 2050 : test();
4538 2050 : test();
4539 2050 : test();
4540 2050 : test();
4541 2050 : test();
4542 2050 : test();
4543 2050 : test();
4544 2050 : IF( ( EQ_16( st_fx->sp_aud_decision1, 1 ) ) && hSpMusClas->lt_speech_state == 0 && hSpMusClas->lt_speech_hangover == 0 &&
4545 : ( GT_16( cor_fx, 13107 ) ) && ( LT_16( dft_fx, 1638 ) ) && GT_16( shr( voi_fv, 1 ), add( cor_map_sum_fv, 1966 ) ) &&
4546 : ( LT_16( t2_fx, shr( cor_fx, 1 ) ) ) && ( LT_16( t3_fx, shr( cor_fx, 1 ) ) ) && ( LT_16( tL_fx, shr( cor_fx, 1 ) ) ) &&
4547 : ( LT_16( cor_map_sum_fv, cor_fx ) ) && ( GT_16( voi_fv, cor_fx ) ) && ( GT_16( voi_fv, 24903 ) ) )
4548 : {
4549 7 : hSpMusClas->lt_speech_state = 1;
4550 7 : move16();
4551 7 : hSpMusClas->lt_speech_hangover = 6;
4552 7 : move16();
4553 : }
4554 2043 : ELSE IF( ( EQ_16( hSpMusClas->lt_speech_state, 1 ) ) && hSpMusClas->lt_speech_hangover == 0 && ( LT_16( cor_fx, 13107 ) ) )
4555 : {
4556 7 : hSpMusClas->lt_speech_state = 0;
4557 7 : move16();
4558 7 : hSpMusClas->lt_speech_hangover = 6;
4559 7 : move16();
4560 : }
4561 :
4562 2050 : IF( hSpMusClas->lt_speech_hangover > 0 )
4563 : {
4564 70 : hSpMusClas->lt_speech_hangover = sub( hSpMusClas->lt_speech_hangover, 1 );
4565 70 : move16();
4566 : }
4567 :
4568 : /* final decision */
4569 2050 : test();
4570 2050 : test();
4571 2050 : IF( EQ_16( st_fx->sp_aud_decision1, 1 ) && EQ_16( hSpMusClas->lt_speech_state, 1 ) )
4572 : {
4573 : /* strong speech - probably error in speech/music classification */
4574 38 : st_fx->sp_aud_decision1 = 0;
4575 38 : move16();
4576 38 : st_fx->sp_aud_decision2 = 0;
4577 38 : move16();
4578 : }
4579 2012 : ELSE IF( st_fx->sp_aud_decision1 == 0 && EQ_16( hSpMusClas->lt_speech_state, 1 ) )
4580 : {
4581 : /* strong music - probably error in speech/music classification */
4582 8 : st_fx->sp_aud_decision1 = 0;
4583 8 : move16();
4584 8 : st_fx->sp_aud_decision2 = 0;
4585 8 : move16();
4586 : }
4587 :
4588 : /* update the buffer of past decisions */
4589 2050 : hSpMusClas->lt_old_mode[2] = st_fx->sp_aud_decision1;
4590 2050 : move16();
4591 :
4592 2050 : return;
4593 : }
4594 :
4595 : /*----------------------------------------------------------------------------------*
4596 : * detect_sparseness_fx()
4597 : *
4598 : *
4599 : *----------------------------------------------------------------------------------*/
4600 1041 : static void detect_sparseness_fx(
4601 : Encoder_State *st_fx, /* i/o: encoder state structure */
4602 : const Word16 localVAD_HE_SAD, /* i : HE-SAD flag without hangover */
4603 : const Word16 voi_fv /* i : scaled voicing feature */
4604 : )
4605 : {
4606 : Word16 sum, sumh;
4607 : Word32 L_tmp, L_tmp1;
4608 : Word16 tmp, tmp1;
4609 : Word16 S1[128];
4610 : Word16 i, j;
4611 1041 : Word16 hb_sp_high_flag = 0;
4612 1041 : move16();
4613 1041 : Word16 lb_sp_high_flag = 0;
4614 1041 : move16();
4615 : Word16 sparse;
4616 : Word16 tmp_buf[4];
4617 1041 : Word16 Mlpe = 0, Mv = 0, Msp;
4618 1041 : move16();
4619 1041 : move16();
4620 1041 : SP_MUS_CLAS_HANDLE hSpMusClas = st_fx->hSpMusClas;
4621 :
4622 1041 : Copy( st_fx->lgBin_E_fx, S1, 128 );
4623 :
4624 1041 : L_tmp = L_deposit_l( 0 );
4625 84321 : FOR( i = 0; i < 80; i++ )
4626 : {
4627 83280 : if ( S1[i] < 0 )
4628 : {
4629 17471 : S1[i] = 0;
4630 17471 : move16(); /* Q7 */
4631 : }
4632 83280 : L_tmp = L_add( L_tmp, L_deposit_l( S1[i] ) );
4633 : }
4634 :
4635 1041 : L_tmp1 = L_deposit_l( 0 );
4636 51009 : FOR( i = 80; i < 128; i++ )
4637 : {
4638 49968 : if ( S1[i] < 0 )
4639 : {
4640 13117 : S1[i] = 0;
4641 13117 : move16();
4642 : }
4643 49968 : L_tmp1 = L_add( L_tmp1, L_deposit_l( S1[i] ) );
4644 : }
4645 :
4646 1041 : sumh = extract_l( L_shr( L_tmp1, 7 ) ); /* Q0 */
4647 1041 : sum = add( extract_l( L_shr( L_tmp, 7 ) ), sumh ); /* Q0 */
4648 :
4649 : /* order spectral from max to min */
4650 1041 : order_spectrum_fx( S1, 128 );
4651 :
4652 : /* calculate spectral sparseness in the range 0 - 6.4 kHz */
4653 1041 : j = 0;
4654 1041 : move16();
4655 1041 : L_tmp = 0;
4656 1041 : move16();
4657 1041 : L_tmp1 = L_deposit_l( mult( sum, 24576 ) );
4658 55622 : FOR( i = 0; i < 128; i++ )
4659 : {
4660 55616 : L_tmp = L_add( L_tmp, L_deposit_l( S1[i] ) );
4661 55616 : IF( GT_32( L_shr( L_tmp, 7 ), L_tmp1 ) )
4662 : {
4663 1035 : j = i;
4664 1035 : move16();
4665 1035 : BREAK;
4666 : }
4667 : }
4668 :
4669 8328 : FOR( i = 0; i < HANG_LEN_INIT - 1; i++ )
4670 : {
4671 7287 : hSpMusClas->sparse_buf_fx[i] = hSpMusClas->sparse_buf_fx[i + 1];
4672 7287 : move16();
4673 : }
4674 :
4675 1041 : sparse = j;
4676 1041 : move16();
4677 1041 : hSpMusClas->sparse_buf_fx[i] = sparse;
4678 1041 : move16();
4679 :
4680 1041 : IF( EQ_16( st_fx->bwidth, WB ) )
4681 : {
4682 0 : Msp = 0;
4683 0 : move16();
4684 0 : FOR( i = 0; i < 8; i++ )
4685 : {
4686 0 : Msp = add( Msp, hSpMusClas->sparse_buf_fx[i] );
4687 : }
4688 0 : Msp = shl( Msp, 5 ); /* Q8 */
4689 :
4690 : /* find long-term smoothed sparseness */
4691 0 : IF( st_fx->last_vad_spa_fx == 0 )
4692 : {
4693 0 : set16_fx( &hSpMusClas->sparse_buf_fx[0], sparse, HANG_LEN_INIT - 1 );
4694 0 : hSpMusClas->LT_sparse_fx = sparse;
4695 0 : move16();
4696 : }
4697 : ELSE
4698 : {
4699 0 : set16_fx( tmp_buf, 0, 4 );
4700 :
4701 0 : FOR( i = 0; i < HANG_LEN_INIT; i++ )
4702 : {
4703 0 : FOR( j = 0; j < 4; j++ )
4704 : {
4705 0 : IF( GT_16( hSpMusClas->sparse_buf_fx[i], tmp_buf[j] ) )
4706 : {
4707 0 : Copy( &tmp_buf[j], &tmp_buf[j + 1], sub( 3, j ) );
4708 0 : tmp_buf[j] = hSpMusClas->sparse_buf_fx[i];
4709 0 : move16();
4710 0 : BREAK;
4711 : }
4712 : }
4713 : }
4714 :
4715 : /* ftmp = 0.25f*(HANG_LEN_INIT*Msp - sum_f(tmp_buf, 4)) - st->LT_sparse; */
4716 0 : tmp = shl( sum16_fx( tmp_buf, 4 ), 5 );
4717 0 : tmp = shl( sub( Msp, tmp ), 1 );
4718 0 : tmp = sub( tmp, hSpMusClas->LT_sparse_fx );
4719 :
4720 0 : hSpMusClas->LT_sparse_fx = add( hSpMusClas->LT_sparse_fx, shr( tmp, 2 ) ); /* Q8 */
4721 : }
4722 :
4723 : /* find high-band sparseness */
4724 0 : Copy( st_fx->lgBin_E_fx + 80, S1, 48 );
4725 :
4726 0 : order_spectrum_fx( S1, 48 );
4727 :
4728 0 : FOR( i = 0; i < HANG_LEN_INIT - 1; i++ )
4729 : {
4730 0 : hSpMusClas->hf_spar_buf_fx[i] = hSpMusClas->hf_spar_buf_fx[i + 1];
4731 0 : move16();
4732 : }
4733 :
4734 : /* st_fx->hf_spar_buf_fx[i] = sum_f(S1, 5)/sumh; */
4735 0 : L_tmp = L_deposit_l( 0 );
4736 0 : FOR( i = 0; i < 5; i++ )
4737 : {
4738 0 : if ( S1[i] < 0 )
4739 : {
4740 0 : S1[i] = 0;
4741 0 : move16();
4742 : }
4743 :
4744 0 : L_tmp = L_add( L_tmp, S1[i] );
4745 : }
4746 :
4747 0 : tmp = extract_l( L_shr( L_tmp, 7 ) );
4748 0 : IF( tmp == 0 )
4749 : {
4750 0 : hSpMusClas->hf_spar_buf_fx[HANG_LEN_INIT - 1] = 0;
4751 : }
4752 : ELSE
4753 : {
4754 0 : hSpMusClas->hf_spar_buf_fx[HANG_LEN_INIT - 1] = div_s( tmp, sumh );
4755 : }
4756 0 : move16();
4757 :
4758 0 : tmp = 0;
4759 0 : move16();
4760 0 : FOR( i = 0; i < 8; i++ )
4761 : {
4762 0 : tmp = add( tmp, shr( hSpMusClas->hf_spar_buf_fx[i], 3 ) );
4763 : }
4764 0 : IF( GT_16( tmp, 6554 ) )
4765 : {
4766 0 : hb_sp_high_flag = 1;
4767 0 : move16();
4768 : }
4769 :
4770 : /* find low-band sparseness */
4771 0 : Copy( st_fx->lgBin_E_fx, S1, 60 );
4772 :
4773 0 : order_spectrum_fx( S1, 60 );
4774 0 : L_tmp = L_deposit_l( 0 );
4775 0 : L_tmp1 = L_deposit_l( 0 );
4776 0 : FOR( i = 0; i < 5; i++ )
4777 : {
4778 0 : if ( S1[i] < 0 )
4779 : {
4780 0 : S1[i] = 0;
4781 0 : move16();
4782 : }
4783 :
4784 0 : L_tmp = L_add( L_tmp, S1[i] );
4785 : }
4786 :
4787 0 : FOR( ; i < 60; i++ )
4788 : {
4789 0 : if ( S1[i] < 0 )
4790 : {
4791 0 : S1[i] = 0;
4792 0 : move16();
4793 : }
4794 :
4795 0 : L_tmp1 = L_add( L_tmp1, S1[i] );
4796 : }
4797 :
4798 : /* if ( sum_f(S1, 5)/sum_f(S1,60) > 0.18f ) */
4799 0 : tmp = extract_l( L_shr( L_tmp, 7 ) );
4800 0 : IF( tmp != 0 )
4801 : {
4802 0 : tmp = div_s( tmp, add( tmp, extract_l( L_shr( L_tmp1, 7 ) ) ) );
4803 0 : if ( GT_16( tmp, 5898 ) )
4804 : {
4805 0 : lb_sp_high_flag = 1;
4806 0 : move16();
4807 : }
4808 : }
4809 :
4810 : /* find smoothed linear prediction efficiency */
4811 0 : FOR( i = 0; i < 7; i++ )
4812 : {
4813 0 : hSpMusClas->lpe_buf_fx[i] = hSpMusClas->lpe_buf_fx[i + 1];
4814 0 : move16();
4815 : }
4816 :
4817 0 : hSpMusClas->lpe_buf_fx[i] = hSpMusClas->past_epsP2_fx;
4818 0 : move16();
4819 0 : Mlpe = 0;
4820 0 : move16();
4821 0 : FOR( i = 0; i < 8; i++ )
4822 : {
4823 0 : Mlpe = add( Mlpe, shr( hSpMusClas->lpe_buf_fx[i], 3 ) );
4824 : }
4825 :
4826 : /* find smoothed voicing */
4827 0 : FOR( i = 0; i < HANG_LEN_INIT - 1; i++ )
4828 : {
4829 0 : hSpMusClas->voicing_buf_fx[i] = hSpMusClas->voicing_buf_fx[i + 1];
4830 0 : move16();
4831 : }
4832 :
4833 0 : hSpMusClas->voicing_buf_fx[i] = voi_fv;
4834 0 : move16();
4835 0 : Mv = 0;
4836 0 : move16();
4837 0 : FOR( i = 0; i < 8; i++ )
4838 : {
4839 0 : Mv = add( Mv, shr( hSpMusClas->voicing_buf_fx[i], 3 ) );
4840 : }
4841 : }
4842 :
4843 : /* avoid using LR-MDCT on sparse spectra */
4844 1041 : IF( EQ_16( st_fx->sp_aud_decision1, 1 ) )
4845 : {
4846 301 : tmp = 91;
4847 301 : move16();
4848 301 : if ( EQ_16( st_fx->bwidth, WB ) )
4849 : {
4850 0 : tmp = 90;
4851 0 : move16();
4852 : }
4853 :
4854 301 : IF( GT_16( sparse, tmp ) )
4855 : {
4856 0 : st_fx->sp_aud_decision1 = 0;
4857 0 : move16();
4858 0 : st_fx->sp_aud_decision2 = 1;
4859 0 : move16();
4860 0 : hSpMusClas->gsc_hangover = 1;
4861 0 : move16();
4862 : }
4863 301 : ELSE IF( EQ_16( hSpMusClas->gsc_hangover, 1 ) )
4864 : {
4865 0 : IF( GT_16( sparse, 85 ) )
4866 : {
4867 0 : st_fx->sp_aud_decision1 = 0;
4868 0 : move16();
4869 0 : st_fx->sp_aud_decision2 = 1;
4870 0 : move16();
4871 : }
4872 : ELSE
4873 : {
4874 0 : tmp = 0;
4875 0 : move16();
4876 0 : FOR( i = 0; i < hSpMusClas->gsc_cnt; i++ )
4877 : {
4878 0 : tmp = add( tmp, hSpMusClas->sparse_buf_fx[HANG_LEN_INIT - 1 - hSpMusClas->gsc_cnt + i] );
4879 : }
4880 0 : tmp1 = div_s( 1, hSpMusClas->gsc_cnt );
4881 0 : tmp = mult( tmp, tmp1 );
4882 :
4883 0 : IF( LT_16( abs_s( sub( sparse, tmp ) ), 7 ) )
4884 : {
4885 0 : st_fx->sp_aud_decision1 = 0;
4886 0 : move16();
4887 0 : st_fx->sp_aud_decision2 = 1;
4888 0 : move16();
4889 : }
4890 : }
4891 : }
4892 :
4893 301 : IF( EQ_16( st_fx->bwidth, WB ) )
4894 : {
4895 0 : test();
4896 0 : test();
4897 0 : test();
4898 0 : test();
4899 0 : test();
4900 0 : test();
4901 0 : test();
4902 0 : test();
4903 0 : test();
4904 0 : IF( GT_16( hSpMusClas->LT_sparse_fx, 15360 ) && GT_16( sparse, 50 ) && LT_16( Mlpe, -1331 ) && GT_16( Mv, 27853 ) &&
4905 : lb_sp_high_flag == 0 && ( ( hb_sp_high_flag == 0 && GT_16( sumh, mult_r( 4915, sum ) ) ) || LE_16( sumh, mult_r( 4915, sum ) ) ) )
4906 : {
4907 0 : st_fx->sp_aud_decision1 = 0;
4908 0 : move16();
4909 0 : st_fx->sp_aud_decision2 = 1;
4910 0 : move16();
4911 0 : hSpMusClas->gsc_hangover = 1;
4912 0 : move16();
4913 : }
4914 0 : ELSE IF( EQ_16( hSpMusClas->gsc_hangover, 1 ) && !( st_fx->sp_aud_decision1 == 0 && EQ_16( st_fx->sp_aud_decision2, 1 ) ) )
4915 : {
4916 0 : IF( LT_16( abs_s( sub( sparse, mean_fx( &hSpMusClas->sparse_buf_fx[HANG_LEN_INIT - 1 - hSpMusClas->gsc_cnt], hSpMusClas->gsc_cnt ) ) ), 7 ) )
4917 : {
4918 0 : st_fx->sp_aud_decision1 = 0;
4919 0 : move16();
4920 0 : st_fx->sp_aud_decision2 = 1;
4921 0 : move16();
4922 : }
4923 : }
4924 : }
4925 : }
4926 :
4927 : /* update the counter of consecutive GSC frames with sparse spectrum */
4928 1041 : test();
4929 1041 : IF( st_fx->sp_aud_decision1 == 0 && EQ_16( st_fx->sp_aud_decision2, 1 ) )
4930 : {
4931 0 : hSpMusClas->gsc_cnt = add( hSpMusClas->gsc_cnt, 1 );
4932 0 : IF( GT_16( hSpMusClas->gsc_cnt, 7 ) )
4933 : {
4934 0 : hSpMusClas->gsc_cnt = 7;
4935 0 : move16();
4936 : }
4937 : }
4938 : ELSE
4939 : {
4940 1041 : hSpMusClas->gsc_cnt = 0;
4941 1041 : move16();
4942 1041 : hSpMusClas->gsc_hangover = 0;
4943 1041 : move16();
4944 : }
4945 :
4946 1041 : st_fx->last_vad_spa_fx = localVAD_HE_SAD;
4947 1041 : move16();
4948 :
4949 1041 : return;
4950 : }
4951 :
4952 : /*---------------------------------------------------------------------*
4953 : * order_spectrum()
4954 : *
4955 : *
4956 : *---------------------------------------------------------------------*/
4957 1041 : static void order_spectrum_fx(
4958 : Word16 *vec,
4959 : Word16 len )
4960 : {
4961 : Word16 i, j, end, end_1, len_2, tmp;
4962 : Word16 smax, smin;
4963 : Word16 imax, imin;
4964 :
4965 1041 : len_2 = shr( len, 1 );
4966 67665 : FOR( i = 0; i < len_2; i++ )
4967 : {
4968 66624 : imax = i;
4969 66624 : move16();
4970 66624 : imin = i;
4971 66624 : move16();
4972 66624 : smax = vec[i];
4973 66624 : move16();
4974 66624 : smin = vec[i];
4975 66624 : move16();
4976 66624 : end = sub( len, i );
4977 4397184 : FOR( j = i; j < end; j++ )
4978 : {
4979 4330560 : IF( GT_16( vec[j], smax ) )
4980 : {
4981 178505 : smax = vec[j];
4982 178505 : move16();
4983 178505 : imax = j;
4984 178505 : move16();
4985 : }
4986 : ELSE
4987 : {
4988 4152055 : IF( LT_16( vec[j], smin ) )
4989 : {
4990 250056 : smin = vec[j];
4991 250056 : move16();
4992 250056 : imin = j;
4993 250056 : move16();
4994 : }
4995 : }
4996 : }
4997 :
4998 66624 : tmp = vec[i];
4999 66624 : move16();
5000 66624 : vec[i] = smax;
5001 66624 : move16();
5002 66624 : vec[imax] = tmp;
5003 66624 : move16();
5004 :
5005 66624 : IF( EQ_16( imin, i ) )
5006 : {
5007 11757 : imin = imax;
5008 11757 : move16();
5009 : }
5010 :
5011 66624 : end_1 = sub( end, 1 );
5012 66624 : tmp = vec[end_1];
5013 66624 : move16();
5014 66624 : vec[end_1] = smin;
5015 66624 : move16();
5016 66624 : vec[imin] = tmp;
5017 66624 : move16();
5018 : }
5019 1041 : }
|