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