xref: /aosp_15_r20/external/libxaac/encoder/ixheaace_signal_classifier.c (revision 15dc779a375ca8b5125643b829a8aa4b70d7f451)
1 /******************************************************************************
2  *                                                                            *
3  * Copyright (C) 2023 The Android Open Source Project
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at:
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  *****************************************************************************
18  * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
19  */
20 #include <string.h>
21 #include <math.h>
22 #include "iusace_type_def.h"
23 #include "iusace_cnst.h"
24 
25 #include "iusace_fd_quant.h"
26 #include "iusace_bitbuffer.h"
27 #include "impd_drc_common_enc.h"
28 #include "impd_drc_uni_drc.h"
29 #include "impd_drc_api.h"
30 #include "impd_drc_uni_drc_eq.h"
31 #include "impd_drc_uni_drc_filter_bank.h"
32 #include "impd_drc_gain_enc.h"
33 #include "impd_drc_struct_def.h"
34 
35 #include "ixheaace_memory_standards.h"
36 #include "iusace_tns_usac.h"
37 #include "iusace_psy_mod.h"
38 #include "iusace_config.h"
39 #include "iusace_signal_classifier.h"
40 #include "iusace_fft.h"
41 #include "iusace_block_switch_const.h"
42 #include "iusace_block_switch_struct_def.h"
43 #include "iusace_cnst.h"
44 #include "iusace_ms.h"
45 #include "ixheaace_adjust_threshold_data.h"
46 #include "iusace_fd_qc_util.h"
47 #include "ixheaace_sbr_header.h"
48 #include "ixheaace_config.h"
49 #include "ixheaace_asc_write.h"
50 #include "iusace_main.h"
51 
iusace_calc_pds(FLOAT32 * ptr_input,WORD32 ccfl)52 static VOID iusace_calc_pds(FLOAT32 *ptr_input, WORD32 ccfl) {
53   WORD32 i;
54   FLOAT64 max_pow, delta;
55   FLOAT64 log_ccfl_base_10 = (ccfl == 1024) ? LOG_1024_BASE_10 : LOG_768_BASE_10;
56 
57   max_pow = MAX(
58       10 * (log10(ptr_input[0] * ptr_input[0] + ptr_input[1] * ptr_input[1]) - log_ccfl_base_10) +
59           10e-15,
60       MIN_POW);
61 
62   for (i = 1; i<ccfl>> 1; i++) {
63     /* removed the sqrt along with clubbing the for loops */
64     ptr_input[2 * i] = (FLOAT32)MAX(10 * (log10(ptr_input[2 * i] * ptr_input[2 * i] +
65                                                 ptr_input[2 * i + 1] * ptr_input[2 * i + 1]) -
66                                           log_ccfl_base_10) +
67                                         10e-15,
68                                     MIN_POW);
69 
70     max_pow = MAX(max_pow, ptr_input[2 * i]);
71   }
72 
73   /* Normalized to reference sound pressure level 96 dB */
74   delta = 96 - max_pow;
75 
76   for (i = 0; i<ccfl>> 1; i++) {
77     ptr_input[2 * i] = ptr_input[2 * i] + (FLOAT32)delta;
78   }
79   return;
80 }
81 
iusace_find_tonal(FLOAT32 * ptr_input,WORD32 * ptr_tonal_flag,FLOAT32 * ptr_scratch,WORD32 ccfl)82 static VOID iusace_find_tonal(FLOAT32 *ptr_input, WORD32 *ptr_tonal_flag, FLOAT32 *ptr_scratch,
83                               WORD32 ccfl) {
84   WORD32 i, j;
85   WORD32 is_tonal;
86   FLOAT64 tonal_spl;
87   FLOAT64 absolute_threshold_xm;
88 
89   for (i = 0; i<ccfl>> 1; i++) {
90     ptr_scratch[i] = ptr_input[2 * i];
91   }
92 
93   if (ccfl == FRAME_LEN_LONG) {
94     for (i = 0; i <= 511; i++) {
95       ptr_tonal_flag[i] = 0;
96     }
97 
98     for (i = 2; i < 500; i++) {
99       if (ptr_scratch[i] > ptr_scratch[i - 1] && ptr_scratch[i] >= ptr_scratch[i + 1]) {
100         is_tonal = 1;
101 
102         /* Verify it meets the condition: ptr_scratch[i]-ptr_scratch[i+j]>=7 */
103 
104         if (1 < i && i < 62) {
105           for (j = -2; j <= -2; j++) {
106             is_tonal = is_tonal && ptr_scratch[i] - ptr_scratch[i + j] >= 7;
107             if (is_tonal == 0) break;
108           }
109           if (is_tonal == 1) {
110             for (j = 2; j <= 2; j++) {
111               is_tonal = is_tonal && ptr_scratch[i] - ptr_scratch[i + j] >= 7;
112               if (is_tonal == 0) break;
113             }
114           }
115 
116           if (is_tonal == 1) {
117             ptr_tonal_flag[i] = 1;
118           }
119         }
120 
121         else if (62 <= i && i < 126) {
122           for (j = -3; j <= -2; j++) {
123             is_tonal = is_tonal && ptr_scratch[i] - ptr_scratch[i + j] >= 7;
124             if (is_tonal == 0) break;
125           }
126           if (is_tonal == 1) {
127             for (j = 2; j <= 3; j++) {
128               is_tonal = is_tonal && ptr_scratch[i] - ptr_scratch[i + j] >= 7;
129               if (is_tonal == 0) break;
130             }
131           }
132 
133           if (is_tonal == 1) {
134             ptr_tonal_flag[i] = 1;
135           }
136         }
137 
138         else if (126 <= i && i < 254) {
139           for (j = -6; j <= -2; j++) {
140             is_tonal = is_tonal && ptr_scratch[i] - ptr_scratch[i + j] >= 7;
141             if (is_tonal == 0) break;
142           }
143           if (is_tonal == 1) {
144             for (j = 2; j <= 6; j++) {
145               is_tonal = is_tonal && ptr_scratch[i] - ptr_scratch[i + j] >= 7;
146               if (is_tonal == 0) break;
147             }
148           }
149 
150           if (is_tonal == 1) {
151             ptr_tonal_flag[i] = 1;
152           }
153         }
154 
155         else if (254 <= i && i < 500) {
156           for (j = -12; j <= -2; j++) {
157             is_tonal = is_tonal && ptr_scratch[i] - ptr_scratch[i + j] >= 7;
158             if (is_tonal == 0) break;
159           }
160           if (is_tonal == 1) {
161             for (j = 2; j <= 12; j++) {
162               is_tonal = is_tonal && ptr_scratch[i] - ptr_scratch[i + j] >= 7;
163               if (is_tonal == 0) break;
164             }
165           }
166 
167           if (is_tonal == 1) {
168             ptr_tonal_flag[i] = 1;
169           }
170         }
171       }
172     }
173 
174     for (i = 0; i <= 511; i++) {
175       if (ptr_tonal_flag[i] == 1) {
176         /* compute the SPL of tonal */
177         tonal_spl =
178             10 * log10(pow(10, (ptr_scratch[i - 1] / 10)) + pow(10, (ptr_scratch[i] / 10)) +
179                        pow(10, (ptr_scratch[i + 1] / 10)));
180 
181         if (i >= 324) {
182           absolute_threshold_xm = iusace_classify_arrays.absolute_threshold_1024[i] + 20;
183         } else {
184           absolute_threshold_xm = iusace_classify_arrays.absolute_threshold_1024[i];
185         }
186         if (tonal_spl < absolute_threshold_xm) {
187           ptr_tonal_flag[i] = 0;
188         }
189       }
190     }
191   } else  // (ccfl == 768)
192   {
193     for (i = 0; i <= 383; i++) {
194       ptr_tonal_flag[i] = 0;
195     }
196 
197     for (i = 2; i < 375; i++) {
198       if (ptr_scratch[i] > ptr_scratch[i - 1] && ptr_scratch[i] >= ptr_scratch[i + 1]) {
199         is_tonal = 1;
200 
201         /* Verify it meets the condition: ptr_scratch[i]-ptr_scratch[i+j]>=7 */
202 
203         if (1 < i && i < 47) {
204           for (j = -2; j <= -2; j++) {
205             is_tonal = is_tonal && ptr_scratch[i] - ptr_scratch[i + j] >= 7;
206             if (is_tonal == 0) break;
207           }
208           if (is_tonal == 1) {
209             for (j = 2; j <= 2; j++) {
210               is_tonal = is_tonal && ptr_scratch[i] - ptr_scratch[i + j] >= 7;
211               if (is_tonal == 0) break;
212             }
213           }
214 
215           if (is_tonal == 1) {
216             ptr_tonal_flag[i] = 1;
217           }
218         }
219 
220         else if (47 <= i && i < 95) {
221           for (j = -3; j <= -2; j++) {
222             is_tonal = is_tonal && ptr_scratch[i] - ptr_scratch[i + j] >= 7;
223             if (is_tonal == 0) break;
224           }
225           if (is_tonal == 1) {
226             for (j = 2; j <= 3; j++) {
227               is_tonal = is_tonal && ptr_scratch[i] - ptr_scratch[i + j] >= 7;
228               if (is_tonal == 0) break;
229             }
230           }
231 
232           if (is_tonal == 1) {
233             ptr_tonal_flag[i] = 1;
234           }
235         }
236 
237         else if (95 <= i && i < 194) {
238           for (j = -5; j <= -2; j++) {
239             is_tonal = is_tonal && ptr_scratch[i] - ptr_scratch[i + j] >= 7;
240             if (is_tonal == 0) break;
241           }
242           if (is_tonal == 1) {
243             for (j = 2; j <= 5; j++) {
244               is_tonal = is_tonal && ptr_scratch[i] - ptr_scratch[i + j] >= 7;
245               if (is_tonal == 0) break;
246             }
247           }
248 
249           if (is_tonal == 1) {
250             ptr_tonal_flag[i] = 1;
251           }
252         }
253 
254         else if (191 <= i && i < 375) {
255           for (j = -9; j <= -2; j++) {
256             is_tonal = is_tonal && ptr_scratch[i] - ptr_scratch[i + j] >= 7;
257             if (is_tonal == 0) break;
258           }
259           if (is_tonal == 1) {
260             for (j = 2; j <= 9; j++) {
261               is_tonal = is_tonal && ptr_scratch[i] - ptr_scratch[i + j] >= 7;
262               if (is_tonal == 0) break;
263             }
264           }
265 
266           if (is_tonal == 1) {
267             ptr_tonal_flag[i] = 1;
268           }
269         }
270       }
271     }
272 
273     for (i = 0; i <= 383; i++) {
274       if (ptr_tonal_flag[i] == 1) {
275         /* compute the SPL of tonal */
276         tonal_spl =
277             10 * log10(pow(10, (ptr_scratch[i - 1] / 10)) + pow(10, (ptr_scratch[i] / 10)) +
278                        pow(10, (ptr_scratch[i + 1] / 10)));
279 
280         if (i >= 243) {
281           absolute_threshold_xm = iusace_classify_arrays.absolute_threshold_768[i] + 20;
282         } else {
283           absolute_threshold_xm = iusace_classify_arrays.absolute_threshold_768[i];
284         }
285         if (tonal_spl < absolute_threshold_xm) {
286           ptr_tonal_flag[i] = 0;
287         }
288       }
289     }
290   }
291   return;
292 }
293 
iusace_tonal_analysis(ia_tonal_params_struct * pstr_ton_params,iusace_scratch_mem * pstr_scratch,WORD32 ccfl)294 static VOID iusace_tonal_analysis(ia_tonal_params_struct *pstr_ton_params,
295                                   iusace_scratch_mem *pstr_scratch, WORD32 ccfl) {
296   FLOAT32 *ptr_complex_fft = pstr_scratch->p_complex_fft;
297   WORD32 *ptr_tonal_flag = pstr_scratch->p_tonal_flag;
298   FLOAT32 *ptr_time_sig = pstr_ton_params->time_signal;
299   WORD32 framecnt_xm = pstr_ton_params->framecnt_xm;
300   WORD32 *ptr_n_tonal = pstr_ton_params->n_tonal;
301   WORD32 *ptr_n_tonal_low_frequency = pstr_ton_params->n_tonal_low_frequency;
302   FLOAT32 *ptr_n_tonal_low_frequency_ratio = pstr_ton_params->n_tonal_low_frequency_ratio;
303   FLOAT32 *ave_n_tonal = pstr_ton_params->ave_n_tonal;
304   FLOAT32 *ave_n_tonal_short = pstr_ton_params->ave_n_tonal_short;
305   WORD32 i;
306   WORD32 fft_size = ccfl;
307 
308   WORD32 frame_length;
309   WORD32 n_tonal_total, n_tonal_low_frequency_total;
310 
311   for (i = 0; i < ccfl; i++) {
312     ptr_complex_fft[2 * i] = (FLOAT32)(
313         ptr_time_sig[i] * ((ccfl == 1024) ? iusace_classify_arrays.hanning_window_1024[i]
314                                           : iusace_classify_arrays.hanning_window_768[i]));
315     ptr_complex_fft[2 * i + 1] = 0;
316   }
317 
318   iusace_complex_fft(ptr_complex_fft, fft_size, pstr_scratch);
319 
320   /* compute power density spectrum */
321   /* re_fft contains the resulting pds */
322   iusace_calc_pds(ptr_complex_fft, ccfl);
323 
324   /* detect tonal */
325   iusace_find_tonal(ptr_complex_fft, ptr_tonal_flag, pstr_scratch->p_pow_spec, ccfl);
326 
327   /* update n_tonal, n_tonal_low_frequency */
328   for (i = 0; i < 99; i++) {
329     ptr_n_tonal[i] = ptr_n_tonal[i + 1];
330     ptr_n_tonal_low_frequency[i] = ptr_n_tonal_low_frequency[i + 1];
331   }
332   ptr_n_tonal[99] = 0;
333   for (i = 0; i<ccfl>> 1; i++) {
334     ptr_n_tonal[99] += ptr_tonal_flag[i];
335   }
336   ptr_n_tonal_low_frequency[99] = 0;
337   for (i = 0; i < INDEXOFLOWFREQUENCY; i++) {
338     ptr_n_tonal_low_frequency[99] += ptr_tonal_flag[i];
339   }
340 
341   /* compute long-term AVE and the ratio of distribution in low-frequency domain */
342   if (framecnt_xm < AVE_TONAL_LENGTH) {
343     frame_length = framecnt_xm;
344   } else {
345     frame_length = AVE_TONAL_LENGTH;
346   }
347 
348   n_tonal_total = 0;
349   n_tonal_low_frequency_total = 0;
350   for (i = 0; i < frame_length; i++) {
351     n_tonal_total += ptr_n_tonal[99 - i];
352     n_tonal_low_frequency_total += ptr_n_tonal_low_frequency[99 - i];
353   }
354 
355   *ave_n_tonal = (FLOAT32)n_tonal_total / frame_length;
356 
357   if (n_tonal_total == 0) {
358     *ptr_n_tonal_low_frequency_ratio = 1;
359   } else {
360     *ptr_n_tonal_low_frequency_ratio = (FLOAT32)n_tonal_low_frequency_total / n_tonal_total;
361   }
362 
363   /* compute the short-term AVE */
364   if (framecnt_xm < AVE_TONAL_LENGTH_SHORT) {
365     frame_length = framecnt_xm;
366   } else {
367     frame_length = AVE_TONAL_LENGTH_SHORT;
368   }
369 
370   n_tonal_total = 0;
371   for (i = 0; i < frame_length; i++) {
372     n_tonal_total += ptr_n_tonal[99 - i];
373   }
374 
375   *ave_n_tonal_short = (FLOAT32)n_tonal_total / frame_length;
376   return;
377 }
378 
iusace_spectral_tilt_analysis(ia_spec_tilt_params_struct * ptr_spec_params,WORD32 ccfl)379 static VOID iusace_spectral_tilt_analysis(ia_spec_tilt_params_struct *ptr_spec_params,
380                                           WORD32 ccfl) {
381   FLOAT32 *ptr_time_signal = ptr_spec_params->time_signal;
382   WORD32 framecnt_xm = ptr_spec_params->framecnt_xm;
383   FLOAT32 *ptr_spec_tilt_buf = ptr_spec_params->spec_tilt_buf;
384   FLOAT32 *ptr_msd_spec_tilt = ptr_spec_params->msd_spec_tilt;
385   FLOAT32 *ptr_msd_spec_tilt_short = ptr_spec_params->msd_spec_tilt_short;
386   WORD32 i;
387   WORD32 frame_length;
388 
389   FLOAT32 r0, r1;
390   FLOAT32 spec_tilt;
391   FLOAT32 ave_spec_tilt;
392 
393   /* compute spectral tilt */
394   r0 = 0;
395   r1 = 0;
396   for (i = 0; i < ccfl - 1; i++) {
397     r0 += ptr_time_signal[i] * ptr_time_signal[i];
398     r1 += ptr_time_signal[i] * ptr_time_signal[i + 1];
399   }
400   r0 += ptr_time_signal[i] * ptr_time_signal[i];
401 
402   if (r0 == 0) {
403     spec_tilt = 1.0f;
404   } else {
405     spec_tilt = r1 / r0;
406   }
407 
408   /* update spec_tilt_buf */
409   for (i = 0; i < 100 - 1; i++) {
410     ptr_spec_tilt_buf[i] = ptr_spec_tilt_buf[i + 1];
411   }
412   ptr_spec_tilt_buf[99] = spec_tilt;
413 
414   /* compute the long-term mean square deviation of the spectral tilt */
415   if (framecnt_xm < SPECTRAL_TILT_LENGTH) {
416     frame_length = framecnt_xm;
417   } else {
418     frame_length = SPECTRAL_TILT_LENGTH;
419   }
420 
421   ave_spec_tilt = 0;
422   for (i = 0; i < frame_length; i++) {
423     ave_spec_tilt += ptr_spec_tilt_buf[99 - i];
424   }
425   ave_spec_tilt /= frame_length;
426 
427   *ptr_msd_spec_tilt = 0;
428   for (i = 0; i < frame_length; i++) {
429     *ptr_msd_spec_tilt +=
430         (ptr_spec_tilt_buf[99 - i] - ave_spec_tilt) * (ptr_spec_tilt_buf[99 - i] - ave_spec_tilt);
431   }
432   *ptr_msd_spec_tilt /= frame_length;
433 
434   /* compute the short-term mean square deviation of the spectral tilt */
435   if (framecnt_xm < SPECTRAL_TILT_LENGTH_SHORT) {
436     frame_length = framecnt_xm;
437   } else {
438     frame_length = SPECTRAL_TILT_LENGTH_SHORT;
439   }
440 
441   ave_spec_tilt = 0;
442   for (i = 0; i < frame_length; i++) {
443     ave_spec_tilt += ptr_spec_tilt_buf[99 - i];
444   }
445   ave_spec_tilt /= frame_length;
446 
447   *ptr_msd_spec_tilt_short = 0;
448   for (i = 0; i < frame_length; i++) {
449     *ptr_msd_spec_tilt_short +=
450         (ptr_spec_tilt_buf[99 - i] - ave_spec_tilt) * (ptr_spec_tilt_buf[99 - i] - ave_spec_tilt);
451   }
452   *ptr_msd_spec_tilt_short /= frame_length;
453 
454   /* compute the energy of current frame */
455   if (r0 <= 1) {
456     ptr_spec_params->frame_energy = 0;
457   } else {
458     ptr_spec_params->frame_energy = (FLOAT32)(10 * log(r0) / log(10));
459   }
460   return;
461 }
462 
iusace_init_mode_decision(ia_mode_params_struct * pstr_mode_params)463 static WORD32 iusace_init_mode_decision(ia_mode_params_struct *pstr_mode_params) {
464   WORD32 i;
465   WORD32 framecnt = pstr_mode_params->framecnt;
466   WORD32 *framecnt_xm = pstr_mode_params->framecnt_xm;
467   WORD32 *flag_border = pstr_mode_params->flag_border;
468   FLOAT32 ave_n_tonal_short = pstr_mode_params->ave_n_tonal_short;
469   FLOAT32 ave_n_tonal = pstr_mode_params->ave_n_tonal;
470   FLOAT32 *ave_n_tonal_short_buf = pstr_mode_params->ave_n_tonal_short_buf;
471   FLOAT32 *ave_n_tonal_buf = pstr_mode_params->ave_n_tonal_buf;
472   FLOAT32 msd_spec_tilt = pstr_mode_params->msd_spec_tilt;
473   FLOAT32 msd_spec_tilt_short = pstr_mode_params->msd_spec_tilt_short;
474   FLOAT32 *msd_spec_tilt_buf = pstr_mode_params->msd_spec_tilt_buf;
475   FLOAT32 *msd_spec_tilt_short_buf = pstr_mode_params->msd_spec_tilt_short_buf;
476   FLOAT32 n_tonal_low_frequency_ratio = pstr_mode_params->n_tonal_low_frequency_ratio;
477   FLOAT32 frame_energy = pstr_mode_params->frame_energy;
478   WORD32 init_mode_decision_result = TBD;
479   WORD32 count_msd_st_monchhichi = 0;
480   WORD32 count_msd_st_speech_music = 0, count_msd_st_music_speech = 0;
481   WORD32 flag_ave_music_speech = 0;
482   WORD32 count_msd_st_music = 0;
483   WORD32 border_state = 0;
484   WORD32 count_quiet_mode = 0;
485 
486   *flag_border = NO_BORDER;
487 
488   /* border decision according to spectral tilt */
489 
490   /* update msd_spec_tilt_buf, msd_spec_tilt_short_buf */
491   for (i = 0; i < 5 - 1; i++) {
492     msd_spec_tilt_buf[i] = msd_spec_tilt_buf[i + 1];
493     msd_spec_tilt_short_buf[i] = msd_spec_tilt_short_buf[i + 1];
494   }
495   msd_spec_tilt_buf[4] = msd_spec_tilt;
496   msd_spec_tilt_short_buf[4] = msd_spec_tilt_short;
497 
498   /* speech->music find strict border of speech->music */
499   if ((msd_spec_tilt >= 0.014) && (msd_spec_tilt_short <= 0.000005)) {
500     count_msd_st_monchhichi++;
501   } else {
502     count_msd_st_monchhichi = 0;
503   }
504   if (((*flag_border != BORDER_SPEECH_MUSIC_DEFINITE) &&
505        (*flag_border != BORDER_MUSIC_SPEECH_DEFINITE)) &&
506       (border_state != BORDER_SPEECH_MUSIC_DEFINITE) && (count_msd_st_monchhichi >= 15) &&
507       (*framecnt_xm >= 300)) {
508     *framecnt_xm = 10;
509     *flag_border = BORDER_SPEECH_MUSIC;
510   }
511 
512   /* find the relative loose border of speech->music */
513   if ((msd_spec_tilt >= 0.0025) && (msd_spec_tilt_short <= 0.000003)) {
514     count_msd_st_speech_music++;
515   } else {
516     count_msd_st_speech_music = 0;
517   }
518   if (((*flag_border != BORDER_SPEECH_MUSIC_DEFINITE) &&
519        (*flag_border != BORDER_MUSIC_SPEECH_DEFINITE)) &&
520       (border_state != BORDER_SPEECH_MUSIC_DEFINITE) && (count_msd_st_speech_music >= 15) &&
521       (*framecnt_xm >= 300)) {
522     *framecnt_xm = 10;
523     *flag_border = BORDER_SPEECH_MUSIC;
524   }
525 
526   /* music->speech */
527   if ((msd_spec_tilt_buf[0] <= 0.0003) && (msd_spec_tilt_short_buf[0] <= 0.0002)) {
528     count_msd_st_music_speech++;
529   }
530   if (((*flag_border != BORDER_SPEECH_MUSIC_DEFINITE) &&
531        (*flag_border != BORDER_MUSIC_SPEECH_DEFINITE)) &&
532       (border_state != BORDER_MUSIC_SPEECH_DEFINITE) && (count_msd_st_music_speech >= 100) &&
533       (msd_spec_tilt >= 0.0008) && (msd_spec_tilt_short >= 0.0025) && (*framecnt_xm >= 20)) {
534     *framecnt_xm = 10;
535     *flag_border = BORDER_MUSIC_SPEECH;
536   }
537 
538   /* border decision according to tonal
539    *  update ave_n_tonal_short_buf, ave_n_tonal_buf */
540   for (i = 0; i < 5 - 1; i++) {
541     ave_n_tonal_short_buf[i] = ave_n_tonal_short_buf[i + 1];
542     ave_n_tonal_buf[i] = ave_n_tonal_buf[i + 1];
543   }
544   ave_n_tonal_short_buf[4] = ave_n_tonal_short;
545   ave_n_tonal_buf[4] = ave_n_tonal;
546 
547   /* music->speech */
548   if ((ave_n_tonal_buf[0] >= 12) && (ave_n_tonal_buf[0] < 15) &&
549       (ave_n_tonal_buf[0] - ave_n_tonal_short_buf[0] >= 5) && (*framecnt_xm >= 20) &&
550       (ave_n_tonal_short - ave_n_tonal_short_buf[0] < 5)) {
551     *framecnt_xm = 10;
552     flag_ave_music_speech = 1;
553     *flag_border = BORDER_MUSIC_SPEECH_DEFINITE;
554   }
555 
556   /* update border decision according to energy */
557   if (frame_energy <= 60) {
558     count_quiet_mode = 0;
559   } else {
560     count_quiet_mode++;
561   }
562 
563   if ((*flag_border == BORDER_MUSIC_SPEECH) && (count_quiet_mode <= 5)) {
564     *flag_border = BORDER_MUSIC_SPEECH_DEFINITE;
565     *framecnt_xm = 10;
566   }
567 
568   /* MUSIC_DEFINITE and SPEECH_DEFINITE mode decision according to short-term characters */
569 
570   /* ave_n_tonal_short */
571   if ((init_mode_decision_result == TBD) && (ave_n_tonal_short >= 19)) {
572     init_mode_decision_result = MUSIC_DEFINITE;
573   }
574   if ((init_mode_decision_result == TBD) && (ave_n_tonal_short <= 1.5)) {
575     init_mode_decision_result = SPEECH_DEFINITE;
576   }
577 
578   /* msd_spec_tilt_short */
579   if (msd_spec_tilt_short >= 0.02) {
580     init_mode_decision_result = SPEECH_DEFINITE;
581   }
582   if ((init_mode_decision_result == TBD) && (msd_spec_tilt_short <= 0.00000025) &&
583       (framecnt >= 10)) {
584     init_mode_decision_result = MUSIC_DEFINITE;
585   }
586 
587   /* SPEECH mode decision */
588 
589   /* flag_ave_music_speech??ave_n_tonal_short */
590   if ((init_mode_decision_result == TBD) && (flag_ave_music_speech == 1)) {
591     if ((ave_n_tonal_short <= 12) && (*framecnt_xm <= 150)) {
592       init_mode_decision_result = SPEECH;
593     }
594   }
595 
596   /* MUSIC_DEFINITE and SPEECH_DEFINITE mode decision */
597 
598   /* ave_n_tonal */
599   if ((init_mode_decision_result == TBD) && (ave_n_tonal <= 3)) {
600     init_mode_decision_result = SPEECH_DEFINITE;
601   }
602   if ((init_mode_decision_result == TBD) && (ave_n_tonal >= 15)) {
603     init_mode_decision_result = MUSIC_DEFINITE;
604   }
605 
606   /** ave_n_tonal_short
607    */
608   if ((init_mode_decision_result == TBD) && (ave_n_tonal_short >= 17)) {
609     init_mode_decision_result = MUSIC_DEFINITE;
610   }
611 
612   /** msd_spec_tilt
613    */
614   if ((init_mode_decision_result == TBD) && (msd_spec_tilt >= 0.01)) {
615     init_mode_decision_result = SPEECH_DEFINITE;
616   }
617   if ((init_mode_decision_result == TBD) && (framecnt >= 10) && (msd_spec_tilt <= 0.00004)) {
618     init_mode_decision_result = MUSIC_DEFINITE;
619   }
620 
621   /** n_tonal_low_frequency_ratio
622    */
623   if ((init_mode_decision_result == TBD) && (n_tonal_low_frequency_ratio <= 0.91)) {
624     init_mode_decision_result = MUSIC_DEFINITE;
625   }
626 
627   /** MUSIC and SPEECH mode decision
628    */
629 
630   /** msd_spec_tilt
631    */
632   if ((init_mode_decision_result == TBD) && (msd_spec_tilt <= 0.0002) && (*framecnt_xm >= 15)) {
633     init_mode_decision_result = MUSIC;
634   }
635 
636   /** n_tonal_low_frequency_ratio
637    */
638   if ((init_mode_decision_result == TBD) && (n_tonal_low_frequency_ratio >= 0.95)) {
639     init_mode_decision_result = SPEECH;
640   }
641   if ((init_mode_decision_result == TBD) && (n_tonal_low_frequency_ratio <= 0.935)) {
642     init_mode_decision_result = MUSIC;
643   }
644 
645   /** the rest of the frame to SPEECH
646    */
647   if (init_mode_decision_result == TBD) {
648     init_mode_decision_result = SPEECH;
649   }
650 
651   /** MUSIC mode decision according to changes of the MSD of the spectral tilt
652    */
653 
654   /** compute the changes of the MSD of the spectral tilt
655    */
656   if ((msd_spec_tilt <= 0.007) && (init_mode_decision_result != SPEECH_DEFINITE)) {
657     if (init_mode_decision_result != SPEECH) {
658       count_msd_st_music++;
659     }
660   } else {
661     count_msd_st_music = 0;
662   }
663 
664   if ((init_mode_decision_result != SPEECH_DEFINITE) && (count_msd_st_music >= 400) &&
665       (border_state != BORDER_MUSIC_SPEECH_DEFINITE)) {
666     init_mode_decision_result = MUSIC;
667   }
668 
669   /** update border flag
670    */
671 
672   if (*flag_border != NO_BORDER) {
673     border_state = *flag_border;
674   }
675 
676   /** update BORDER_SPEECH_MUSIC_DEFINITE
677    */
678   if (((border_state == BORDER_MUSIC_SPEECH) || (border_state == BORDER_MUSIC_SPEECH_DEFINITE)) &&
679       (init_mode_decision_result == MUSIC_DEFINITE) && (*framecnt_xm >= 20)) {
680     *flag_border = BORDER_SPEECH_MUSIC_DEFINITE;
681     *framecnt_xm = 10;
682     border_state = *flag_border;
683   }
684 
685   /** update BORDER_MUSIC_SPEECH_DEFINITE
686    */
687   if (((border_state == BORDER_SPEECH_MUSIC) || (border_state == BORDER_SPEECH_MUSIC_DEFINITE)) &&
688       (init_mode_decision_result == SPEECH_DEFINITE) && (*framecnt_xm >= 20)) {
689     *flag_border = BORDER_MUSIC_SPEECH_DEFINITE;
690     *framecnt_xm = 10;
691   }
692 
693   return init_mode_decision_result;
694 }
695 
iusace_smoothing_mode_decision(ia_smooth_params_struct * pstr_smooth_param)696 static WORD32 iusace_smoothing_mode_decision(ia_smooth_params_struct *pstr_smooth_param) {
697   WORD32 *ptr_init_result_ahead = pstr_smooth_param->init_result_ahead;
698   WORD32 flag_border = pstr_smooth_param->flag_border;
699   WORD32 *ptr_flag_border_buf_behind = pstr_smooth_param->flag_border_buf_behind;
700   WORD32 *ptr_flag_border_buf_ahead = pstr_smooth_param->flag_border_buf_ahead;
701   FLOAT32 frame_energy = pstr_smooth_param->frame_energy;
702   FLOAT32 *ptr_frame_energy_buf_behind = pstr_smooth_param->frame_energy_buf_behind;
703   FLOAT32 *ptr_frame_energy_buf_ahead = pstr_smooth_param->frame_energy_buf_ahead;
704   WORD32 *ptr_smoothing_result_buf = pstr_smooth_param->smoothing_result_buf;
705   WORD32 *ptr_init_result_behind = pstr_smooth_param->init_result_behind;
706   WORD32 init_mode_decision_result = pstr_smooth_param->init_mode_decision_result;
707   WORD32 i;
708 
709   WORD32 mode_decision_result;
710 
711   WORD32 num_music, num_speech;
712 
713   /** update data array
714    */
715 
716   /** update init_result_behind, init_result_ahead
717    */
718   for (i = 0; i < 99; i++) {
719     ptr_init_result_behind[i] = ptr_init_result_behind[i + 1];
720   }
721   ptr_init_result_behind[99] = ptr_init_result_ahead[0];
722 
723   ptr_init_result_ahead[NFRAMEAHEAD - 1] = init_mode_decision_result;
724 
725   /** update flag_border_buf_behind, flag_border_buf_ahead
726    * update frame_energy_buf_behind, frame_energy_buf_ahead
727    */
728 
729   for (i = 0; i < 9; i++) {
730     ptr_flag_border_buf_behind[i] = ptr_flag_border_buf_behind[i + 1];
731     ptr_frame_energy_buf_behind[i] = ptr_frame_energy_buf_behind[i + 1];
732   }
733   ptr_flag_border_buf_behind[9] = ptr_flag_border_buf_ahead[0];
734   ptr_frame_energy_buf_behind[9] = ptr_frame_energy_buf_ahead[0];
735 
736   ptr_flag_border_buf_ahead[NFRAMEAHEAD - 1] = flag_border;
737 
738   ptr_frame_energy_buf_ahead[NFRAMEAHEAD - 1] = frame_energy;
739 
740   /** smoothing according to past results
741    */
742 
743   mode_decision_result = ptr_init_result_behind[99];
744 
745   /** update smoothing_result_buf
746    */
747   if (ptr_flag_border_buf_behind[9] == NO_BORDER) {
748     for (i = 0; i < 99; i++) {
749       ptr_smoothing_result_buf[i] = ptr_smoothing_result_buf[i + 1];
750     }
751     pstr_smooth_param->num_smoothing++;
752   } else {
753     for (i = 0; i < 99; i++) {
754       ptr_smoothing_result_buf[i] = TBD;
755     }
756     pstr_smooth_param->num_smoothing = 1;
757   }
758   ptr_smoothing_result_buf[99] = ptr_init_result_behind[99];
759 
760   if (pstr_smooth_param->num_smoothing >= SMOOTHING_LENGTH) {
761     num_music = 0;
762     num_speech = 0;
763 
764     /** smoothed result count
765      */
766     for (i = 0; i < SMOOTHING_LENGTH; i++) {
767       if ((ptr_smoothing_result_buf[100 - i] == SPEECH) ||
768           (ptr_smoothing_result_buf[100 - i] == SPEECH_DEFINITE)) {
769         num_speech++;
770       } else {
771         num_music++;
772       }
773     }
774 
775     /** smoothing
776      */
777     if ((num_speech > num_music) && (init_mode_decision_result != MUSIC_DEFINITE)) {
778       mode_decision_result = SPEECH;
779     }
780     if ((num_music > num_speech) && (init_mode_decision_result != SPEECH_DEFINITE)) {
781       mode_decision_result = MUSIC;
782     }
783   }
784 
785   /** correct according to energies and ahead mode decision results
786    */
787 
788   if ((mode_decision_result == MUSIC) && (ptr_frame_energy_buf_behind[9] <= 60)) {
789     for (i = 0; i < NFRAMEAHEAD; i++) {
790       if ((ptr_init_result_ahead[i] == SPEECH_DEFINITE) || (ptr_init_result_ahead[i] == SPEECH)) {
791         pstr_smooth_param->flag_speech_definite = 1;
792       }
793     }
794   }
795   if ((pstr_smooth_param->flag_speech_definite == 1) && (mode_decision_result == MUSIC)) {
796     mode_decision_result = SPEECH;
797   } else {
798     pstr_smooth_param->flag_speech_definite = 0;
799   }
800 
801   /** correct MUSIC mode
802    */
803 
804   if (ptr_frame_energy_buf_behind[9] <= 65) {
805     pstr_smooth_param->count_small_energy = 0;
806   } else {
807     pstr_smooth_param->count_small_energy++;
808   }
809   if (((ptr_flag_border_buf_ahead[NFRAMEAHEAD - 1] == BORDER_SPEECH_MUSIC) ||
810        (ptr_flag_border_buf_ahead[NFRAMEAHEAD - 1] == BORDER_SPEECH_MUSIC_DEFINITE)) &&
811       (pstr_smooth_param->count_small_energy <= 30)) {
812     pstr_smooth_param->flag_music_definite = 1;
813   }
814   if ((pstr_smooth_param->flag_music_definite == 1) &&
815       ((mode_decision_result == SPEECH) || (mode_decision_result == SPEECH_DEFINITE))) {
816     mode_decision_result = MUSIC;
817   } else {
818     pstr_smooth_param->flag_music_definite = 0;
819   }
820 
821   return mode_decision_result;
822 }
823 
iusace_classification_ccfl(ia_classification_struct * pstr_sig_class,FLOAT32 * ptr_time_signal,iusace_scratch_mem * pstr_scratch,WORD32 ccfl)824 static WORD32 iusace_classification_ccfl(ia_classification_struct *pstr_sig_class,
825                                          FLOAT32 *ptr_time_signal,
826                                          iusace_scratch_mem *pstr_scratch, WORD32 ccfl) {
827   WORD32 i;
828   ia_tonal_params_struct pstr_ton_params;
829   ia_smooth_params_struct smooth_param;
830   ia_mode_params_struct pstr_mode_params;
831   ia_spec_tilt_params_struct ptr_spec_params;
832 
833   ia_classification_buf_struct *pstr_buffers = &(pstr_sig_class->buffers);
834   pFLOAT32 spec_tilt_buf = pstr_sig_class->spec_tilt_buf;
835   pWORD32 n_tonal = pstr_sig_class->n_tonal;
836   pWORD32 n_tonal_low_frequency = pstr_sig_class->n_tonal_low_frequency;
837   pWORD32 framecnt_xm = &(pstr_sig_class->framecnt_xm);
838   pWORD32 framecnt = &(pstr_sig_class->framecnt);
839   pFLOAT32 ave_n_tonal_short_buf = pstr_sig_class->ave_n_tonal_short_buf;
840   pFLOAT32 ave_n_tonal_buf = pstr_sig_class->ave_n_tonal_buf;
841   pFLOAT32 msd_spec_tilt_buf = pstr_sig_class->msd_spec_tilt_buf;
842   pFLOAT32 msd_spec_tilt_short_buf = pstr_sig_class->msd_spec_tilt_short_buf;
843 
844   FLOAT32 n_tonal_low_frequency_ratio;    /* the ratio of distribution of the numbers */
845                                           /* of tonal in the low frequency domain     */
846   FLOAT32 ave_n_tonal, ave_n_tonal_short; /**< the number of tonal */
847   FLOAT32 msd_spec_tilt;                  /* the long-term MSD of spectral tilt */
848   FLOAT32 msd_spec_tilt_short;            /* the short-term MSD of spectral tilt */
849 
850   WORD32 init_mode_decision_result; /* the initial mode decision */
851   WORD32 flag_border = NO_BORDER;   /* flag of current border */
852 
853   WORD32 mode_decision_result; /* final mode decision result */
854 
855   if (pstr_sig_class->init_flag == 0) {
856     /* initialize */
857     pstr_sig_class->init_flag = 1;
858 
859     for (i = 0; i < 5; i++) {
860       n_tonal[i] = 0;
861       n_tonal_low_frequency[i] = 0;
862       spec_tilt_buf[i] = 0;
863       pstr_buffers->init_result_behind[i] = TBD;
864       pstr_buffers->smoothing_result_buf[i] = TBD;
865 
866       ave_n_tonal_short_buf[i] = 0;
867       ave_n_tonal_buf[i] = 0;
868       msd_spec_tilt_buf[i] = 0;
869       msd_spec_tilt_short_buf[i] = 0;
870 
871       pstr_buffers->frame_energy_buf_behind[i] = 0;
872       pstr_buffers->flag_border_buf_behind[i] = NO_BORDER;
873     }
874     for (; i < 10; i++) {
875       n_tonal[i] = 0;
876       n_tonal_low_frequency[i] = 0;
877       spec_tilt_buf[i] = 0;
878       pstr_buffers->init_result_behind[i] = TBD;
879       pstr_buffers->smoothing_result_buf[i] = TBD;
880 
881       pstr_buffers->frame_energy_buf_behind[i] = 0;
882       pstr_buffers->flag_border_buf_behind[i] = NO_BORDER;
883     }
884 
885     for (; i < 100; i++) {
886       n_tonal[i] = 0;
887       n_tonal_low_frequency[i] = 0;
888       spec_tilt_buf[i] = 0;
889       pstr_buffers->init_result_behind[i] = TBD;
890       pstr_buffers->smoothing_result_buf[i] = TBD;
891     }
892     for (i = 0; i < NFRAMEAHEAD; i++) {
893       pstr_buffers->frame_energy_buf_ahead[i] = 0;
894       pstr_buffers->flag_border_buf_ahead[i] = NO_BORDER;
895       pstr_buffers->init_result_ahead[i] = TBD;
896     }
897   }
898 
899   *framecnt += 1;
900   *framecnt_xm += 1;
901 
902   pstr_ton_params.time_signal = (FLOAT32 *)ptr_time_signal;
903   pstr_ton_params.framecnt_xm = *framecnt_xm;
904   pstr_ton_params.n_tonal = n_tonal;
905   pstr_ton_params.n_tonal_low_frequency = n_tonal_low_frequency;
906   pstr_ton_params.n_tonal_low_frequency_ratio = &n_tonal_low_frequency_ratio;
907   pstr_ton_params.ave_n_tonal = &ave_n_tonal;
908   pstr_ton_params.ave_n_tonal_short = &ave_n_tonal_short;
909   /** analysis tonal
910    */
911   iusace_tonal_analysis(&pstr_ton_params, pstr_scratch, ccfl);
912 
913   ptr_spec_params.time_signal = ptr_time_signal;
914   ptr_spec_params.framecnt_xm = *framecnt_xm;
915   ptr_spec_params.spec_tilt_buf = spec_tilt_buf;
916   ptr_spec_params.msd_spec_tilt = &msd_spec_tilt;
917   ptr_spec_params.msd_spec_tilt_short = &msd_spec_tilt_short;
918   /** analysis spectral tilt
919    */
920   iusace_spectral_tilt_analysis(&ptr_spec_params, ccfl);
921 
922   pstr_mode_params.framecnt = *framecnt;
923   pstr_mode_params.framecnt_xm = framecnt_xm;
924   pstr_mode_params.flag_border = &flag_border;
925   pstr_mode_params.ave_n_tonal_short = ave_n_tonal_short;
926   pstr_mode_params.ave_n_tonal = ave_n_tonal;
927   pstr_mode_params.ave_n_tonal_short_buf = ave_n_tonal_short_buf;
928   pstr_mode_params.ave_n_tonal_buf = ave_n_tonal_buf;
929   pstr_mode_params.msd_spec_tilt = msd_spec_tilt;
930   pstr_mode_params.msd_spec_tilt_short = msd_spec_tilt_short;
931   pstr_mode_params.msd_spec_tilt_buf = msd_spec_tilt_buf;
932   pstr_mode_params.msd_spec_tilt_short_buf = msd_spec_tilt_short_buf;
933   pstr_mode_params.n_tonal_low_frequency_ratio = n_tonal_low_frequency_ratio;
934   pstr_mode_params.frame_energy = ptr_spec_params.frame_energy;
935   /** initial mode decision and boundary decisions
936    */
937   init_mode_decision_result = iusace_init_mode_decision(&pstr_mode_params);
938 
939   smooth_param.flag_border_buf_behind = pstr_buffers->flag_border_buf_behind;
940   smooth_param.flag_border_buf_ahead = pstr_buffers->flag_border_buf_ahead;
941   smooth_param.frame_energy = ptr_spec_params.frame_energy;
942   smooth_param.frame_energy_buf_behind = pstr_buffers->frame_energy_buf_behind;
943   smooth_param.frame_energy_buf_ahead = pstr_buffers->frame_energy_buf_ahead;
944   smooth_param.smoothing_result_buf = pstr_buffers->smoothing_result_buf;
945   smooth_param.init_result_ahead = pstr_buffers->init_result_ahead;
946   smooth_param.flag_border = flag_border;
947   smooth_param.init_result_behind = pstr_buffers->init_result_behind;
948   smooth_param.init_mode_decision_result = init_mode_decision_result;
949   smooth_param.flag_speech_definite = 0;
950   smooth_param.count_small_energy = 0;
951   smooth_param.flag_music_definite = 0;
952   smooth_param.num_smoothing = 0;
953   /* smoothing */
954   mode_decision_result = iusace_smoothing_mode_decision(&smooth_param);
955 
956   return mode_decision_result;
957 }
958 
iusace_classification(ia_classification_struct * pstr_sig_class,iusace_scratch_mem * pstr_scratch,WORD32 ccfl)959 VOID iusace_classification(ia_classification_struct *pstr_sig_class,
960                            iusace_scratch_mem *pstr_scratch, WORD32 ccfl) {
961   WORD32 n_frames, n_class, avg_cls, nf;
962   WORD32 i;
963   FLOAT32 *ptr_time_signal = pstr_scratch->p_time_signal;
964   WORD32 mode_decision_result;
965 
966   n_frames = pstr_sig_class->n_buffer_samples / ccfl;
967 
968   for (nf = 0; nf < n_frames; nf++) {
969     for (i = 0; i < ccfl; i++) {
970       ptr_time_signal[i] = pstr_sig_class->input_samples[ccfl * nf + i];
971     }
972 
973     /* classification of ccfl-frame */
974     mode_decision_result =
975         iusace_classification_ccfl(pstr_sig_class, ptr_time_signal, pstr_scratch, ccfl);
976 
977     /* coding mode decision of 1024-frame */
978     if ((mode_decision_result == MUSIC) || (mode_decision_result == MUSIC_DEFINITE)) {
979       pstr_sig_class->coding_mode = FD_MODE;
980     } else if ((mode_decision_result == SPEECH) || (mode_decision_result == SPEECH_DEFINITE)) {
981       pstr_sig_class->coding_mode = TD_MODE;
982     }
983 
984     pstr_sig_class->class_buf[pstr_sig_class->n_buf_class + nf] = pstr_sig_class->coding_mode;
985     pstr_sig_class->pre_mode = pstr_sig_class->coding_mode;
986   }
987 
988   /* merge ccfl-frame results */
989   pstr_sig_class->n_buf_class += n_frames;
990   n_class = (pstr_sig_class->n_class_frames > pstr_sig_class->n_buf_class)
991                 ? pstr_sig_class->n_buf_class
992                 : pstr_sig_class->n_class_frames;
993   {
994     WORD32 min_cls, max_cls;
995 
996     min_cls = max_cls = pstr_sig_class->class_buf[0];
997     for (i = 1; i < n_class; i++) {
998       if (pstr_sig_class->class_buf[i] > max_cls) {
999         max_cls = pstr_sig_class->class_buf[i];
1000       } else if (pstr_sig_class->class_buf[i] < min_cls) {
1001         min_cls = pstr_sig_class->class_buf[i];
1002       }
1003     }
1004 
1005     avg_cls = 0;
1006     for (i = 0; i < n_class; i++) {
1007       if (pstr_sig_class->class_buf[i] == max_cls) {
1008         avg_cls += 1;
1009       }
1010       if (pstr_sig_class->class_buf[i] == min_cls) {
1011         avg_cls += -1;
1012       }
1013     }
1014 
1015     if (avg_cls > 0) {
1016       pstr_sig_class->coding_mode = max_cls;
1017     } else {
1018       pstr_sig_class->coding_mode = min_cls;
1019     }
1020   }
1021 
1022   /* shift, save pre_mode and unused class */
1023   if (n_class > 0) {
1024     pstr_sig_class->pre_mode = pstr_sig_class->class_buf[n_class - 1];
1025   }
1026   pstr_sig_class->n_buf_class -= n_class;
1027   pstr_sig_class->n_buffer_samples -= ccfl * n_frames;
1028 
1029   WORD32 minimum = MIN(pstr_sig_class->n_buf_class, pstr_sig_class->n_buffer_samples);
1030   if (minimum == pstr_sig_class->n_buf_class) {
1031     for (i = 0; i < minimum; i++) {
1032       pstr_sig_class->class_buf[i] = pstr_sig_class->class_buf[i + n_class];
1033       pstr_sig_class->input_samples[i] = pstr_sig_class->input_samples[i + ccfl * n_frames];
1034     }
1035 
1036     /* shift, save unused samples */
1037     for (; i < pstr_sig_class->n_buffer_samples; i++) {
1038       pstr_sig_class->input_samples[i] = pstr_sig_class->input_samples[i + ccfl * n_frames];
1039     }
1040   } else {
1041     for (i = 0; i < minimum; i++) {
1042       pstr_sig_class->class_buf[i] = pstr_sig_class->class_buf[i + n_class];
1043       pstr_sig_class->input_samples[i] = pstr_sig_class->input_samples[i + ccfl * n_frames];
1044     }
1045 
1046     /* shift, save unused samples */
1047     for (; i < pstr_sig_class->n_buf_class; i++) {
1048       pstr_sig_class->class_buf[i] = pstr_sig_class->class_buf[i + n_class];
1049     }
1050   }
1051 }
1052 
iusace_init_classification(ia_classification_struct * pstr_sig_class)1053 VOID iusace_init_classification(ia_classification_struct *pstr_sig_class) {
1054   pstr_sig_class->pre_mode = FD_MODE;
1055 
1056   pstr_sig_class->n_buffer_samples = 0;
1057   memset(pstr_sig_class->input_samples, 0, 3840 * 2 * sizeof(FLOAT32));
1058   pstr_sig_class->n_class_frames = 2;
1059   pstr_sig_class->n_buf_class = 0;
1060 
1061   pstr_sig_class->is_switch_mode = 1;
1062 
1063   pstr_sig_class->framecnt = 0;
1064   pstr_sig_class->init_flag = 0;
1065   pstr_sig_class->framecnt_xm = 0;
1066 
1067   memset(&pstr_sig_class->buffers, 0, sizeof(ia_classification_buf_struct));
1068   memset(pstr_sig_class->spec_tilt_buf, 0, sizeof(FLOAT32) * 100);
1069   memset(pstr_sig_class->n_tonal, 0, sizeof(WORD32) * 100);
1070   memset(pstr_sig_class->n_tonal_low_frequency, 0, sizeof(WORD32) * 100);
1071   memset(pstr_sig_class->msd_spec_tilt_buf, 0, sizeof(FLOAT32) * 5);
1072   memset(pstr_sig_class->msd_spec_tilt_short_buf, 0, sizeof(FLOAT32) * 5);
1073   memset(pstr_sig_class->ave_n_tonal_short_buf, 0, sizeof(FLOAT32) * 5);
1074   memset(pstr_sig_class->ave_n_tonal_buf, 0, sizeof(FLOAT32) * 5);
1075   return;
1076 }
1077