LCOV - code coverage report
Current view: top level - lib_enc - speech_music_classif_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main @ e95243e9e67ddeb69dddf129509de1b3d95b402e Lines: 2302 2525 91.2 %
Date: 2025-09-14 03:13:15 Functions: 20 20 100.0 %

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

Generated by: LCOV version 1.14