LCOV - code coverage report
Current view: top level - lib_enc - hq_classifier_enc_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main enc/dec/rend @ 3ea8505de0a48ae0f5675c28be980f7a28fcc88e Lines: 655 728 90.0 %
Date: 2025-05-31 01:58:07 Functions: 7 7 100.0 %

          Line data    Source code
       1             : /*====================================================================================
       2             :     EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0
       3             :   ====================================================================================*/
       4             : #include <stdint.h>
       5             : #include "options.h" /* Compilation switches                   */
       6             : #include "cnst.h"    /* Common constants                       */
       7             : //#include "prot_fx.h"        /* Function prototypes                    */
       8             : #include "rom_com_fx.h"  /* Static table prototypes                */
       9             : #include "rom_com.h"     /* Static table prototypes                */
      10             : #include "prot_fx.h"     /* Function prototypes                    */
      11             : #include "prot_fx_enc.h" /* Function prototypes                    */
      12             : 
      13             : /*-----------------------------------------------------------------*
      14             :  * Local constants
      15             :  *-----------------------------------------------------------------*/
      16             : 
      17             : #define SHARP_DIST_THRES_FX 1420 /* Q6, 22.2 */
      18             : 
      19             : #define HALF_WIN_LENGTH     10
      20             : #define L_SPEC_HB           320
      21             : #define PEAK_THRESHOLD      3277      /*Q15 0.1f*/
      22             : #define PEAK_THRESHOLD_FX   214748364 // 0.1f in Q31
      23             : #define LOW_COUNT_THRESHOLD 220
      24             : 
      25             : 
      26             : /*-----------------------------------------------------------------*
      27             :  * Local functions
      28             :  *-----------------------------------------------------------------*/
      29             : 
      30             : void hvq_classifier_fx( const Word32 *input /*Q12*/, Word16 *prev_Npeaks, Word16 *prev_peaks, Word16 *hqswb_clas, Word16 *Npeaks, Word16 *peaks, const Word32 L_core_brate, const Word16 last_core, Word32 *L_nf_gains /*Q12*/, Word16 *hvq_hangover, Word32 *L_pe_gains /*Q12*/ );
      31             : static Word16 hf_spectrum_sparseness_fx(
      32             :     Encoder_State *st,     /* i/o: encoder state structure         */
      33             :     const Word32 *coefs_fx /* i  : MDCT spectrum                   Q12*/
      34             : );
      35             : /*--------------------------------------------------------------------------*
      36             :  * hf_spectrum_sparseness()
      37             :  *
      38             :  * Detection of sparse spectrum in high band for activation of harmonic
      39             :  * modes HQ_HARMONIC and HQ_HVQ
      40             :  *--------------------------------------------------------------------------*/
      41             : /*! r: Harmonic decision for high band */
      42        6674 : static Word16 hf_spectrum_sparseness_fx(
      43             :     Encoder_State *st,     /* i/o: encoder state structure         */
      44             :     const Word32 *coefs_fx /* i  : MDCT spectrum (Q12)                  */
      45             : )
      46             : {
      47             :     Word16 i;
      48             :     Word32 thr_fx;
      49             :     Word16 low_count_fx;
      50             :     Word32 Amax_fx;
      51             :     Word32 movmean_fx;
      52             :     Word64 inv_rms_fx;
      53             :     Word32 inv_rms32_fx;
      54             :     Word32 inv_rms32_div_fx;
      55             :     Word32 crest_fx;
      56             :     Word32 crest_mod_fx;
      57             :     const Word16 *p_num_fx;
      58             :     Word32 A_fx[960];
      59             :     Word16 result;
      60             :     Word32 *crest_lp_fx;
      61             :     Word32 *crest_mod_lp_fx;
      62             :     Word32 hq_crest_threshold, hq_crest_mod_threshold;
      63        6674 :     Word16 inv_rms32_e = 0;
      64        6674 :     move16();
      65             : 
      66        6674 :     crest_lp_fx = &st->hHQ_core->crest_lp_fx;         /* &st->hHQ_core->crest_lp_q */
      67        6674 :     crest_mod_lp_fx = &st->hHQ_core->crest_mod_lp_fx; /* &st->hHQ_core->crest_mod_lp_q */
      68             : 
      69        6674 :     result = TRUE;
      70        6674 :     move16();
      71        6674 :     IF( st->element_mode != EVS_MONO )
      72             :     {
      73             : 
      74     2142354 :         FOR( i = 0; i < L_SPEC_HB; i++ )
      75             :         {
      76     2135680 :             A_fx[i] = L_abs( coefs_fx[i + L_SPEC_HB] ); /* Q12 */
      77     2135680 :             move32();
      78             :         }
      79        6674 :         low_count_fx = 0;
      80        6674 :         move16();
      81        6674 :         inv_rms_fx = 0;
      82        6674 :         move64();
      83        6674 :         crest_mod_fx = 0;
      84        6674 :         move32();
      85        6674 :         maximum_l( A_fx, L_SPEC_HB, &Amax_fx );
      86        6674 :         IF( Amax_fx == 0 )
      87             :         {
      88             :             /* For all-zero input the crest is 1.0 */
      89           0 :             crest_fx = L_shl( 1, st->hHQ_core->crest_lp_q );         /* &st->hHQ_core->crest_lp_q */
      90           0 :             crest_mod_fx = L_shl( 1, st->hHQ_core->crest_mod_lp_q ); /* &st->hHQ_core->crest_mod_lp_q */
      91           0 :             low_count_fx = 0;
      92           0 :             move16();
      93             :         }
      94             :         ELSE
      95             :         {
      96        6674 :             thr_fx = Mpy_32_32( Amax_fx, PEAK_THRESHOLD_FX ); /* Q12 */
      97        6674 :             movmean_fx = 0;                                   /* avoid uninitialized warning */
      98        6674 :             move32();
      99             :             // p_num = &inv_tbl[HALF_WIN_LENGTH + 1];       /* Table for division 1./(11:21) */
     100        6674 :             p_num_fx = &inv_tbl_fx[HALF_WIN_LENGTH + 1]; /* Table for division 1./(11:21) Q15*/
     101     2142354 :             FOR( i = 0; i < L_SPEC_HB; i++ )
     102             :             {
     103             :                 // inv_rms += A[i] * A[i];
     104     2135680 :                 inv_rms_fx = W_add( inv_rms_fx, W_shr( W_mult0_32_32( A_fx[i], A_fx[i] ), Q9 ) ); // 2*Q12 -Q9 (Q9 for guard bits) Q15
     105             : 
     106     2135680 :                 IF( LT_32( A_fx[i], thr_fx ) )
     107             :                 {
     108     1355915 :                     low_count_fx = add( low_count_fx, 1 );
     109             :                 }
     110     2135680 :                 IF( LE_16( i, HALF_WIN_LENGTH ) )
     111             :                 {
     112       73414 :                     IF( i == 0 )
     113             :                     {
     114        6674 :                         movmean_fx = Mpy_32_16_1( sum_l_fx( &A_fx[0], i + HALF_WIN_LENGTH + 1 ), ( *p_num_fx ) ); // Q12
     115             :                     }
     116             :                     ELSE
     117             :                     {
     118             : 
     119       66740 :                         p_num_fx++;
     120       66740 :                         movmean_fx = L_add( movmean_fx, Mpy_32_16_1( L_sub( A_fx[i + HALF_WIN_LENGTH], movmean_fx ), ( *p_num_fx ) ) ); // Q12
     121             :                     }
     122             :                 }
     123             :                 ELSE
     124             :                 {
     125     2062266 :                     IF( LE_16( L_SPEC_HB, i + HALF_WIN_LENGTH ) )
     126             :                     {
     127             : 
     128       66740 :                         p_num_fx--;
     129       66740 :                         movmean_fx = L_add( movmean_fx, Mpy_32_16_1( L_sub( movmean_fx, A_fx[i - HALF_WIN_LENGTH - 1] ), ( *p_num_fx ) ) ); // Q12
     130             :                     }
     131             :                     ELSE
     132             :                     {
     133     1995526 :                         movmean_fx = L_add( movmean_fx, Mpy_32_16_1( L_sub( A_fx[i + HALF_WIN_LENGTH], A_fx[i - HALF_WIN_LENGTH - 1] ), ( *p_num_fx ) ) ); // Q12
     134             :                     }
     135             :                 }
     136             : 
     137     2135680 :                 IF( LT_32( crest_mod_fx, movmean_fx ) )
     138             :                 {
     139       88797 :                     crest_mod_fx = movmean_fx; // Q12
     140       88797 :                     move32();
     141             :                 }
     142             :             }
     143        6674 :             Word16 l_shift = W_norm( inv_rms_fx );
     144        6674 :             inv_rms32_fx = W_extract_h( W_shl( inv_rms_fx, l_shift ) );                                     // Q15+l_shift-32
     145        6674 :             Word16 q_rms = sub( add( Q15, l_shift ), 32 );                                                  // q_rms
     146        6674 :             inv_rms32_div_fx = BASOP_Util_Divide3232_Scale_newton( inv_rms32_fx, L_SPEC_HB, &inv_rms32_e ); /* Q31-inv_rms32_e */
     147        6674 :             inv_rms32_e = sub( 31, add( sub( Q31, inv_rms32_e ), q_rms ) );
     148             :             // inv_rms = 1.0f / (float) sqrtf( inv_rms / L_SPEC_HB );
     149        6674 :             inv_rms32_fx = ISqrt32( inv_rms32_div_fx, &inv_rms32_e ); /* Q31-inv_rms32_e */
     150             : 
     151        6674 :             crest_fx = Mpy_32_32( Amax_fx, inv_rms32_fx );                                                  // Q12 + (Q31-inv_rms32_e) -Q31 = Q12 - inv_rms32_e
     152        6674 :             crest_mod_fx = Mpy_32_32( crest_mod_fx, inv_rms32_fx );                                         // Q12 + (Q31-inv_rms32_e) -Q31 = Q12 - inv_rms32_e
     153        6674 :             *crest_lp_fx = L_shr( *crest_lp_fx, sub( st->hHQ_core->crest_lp_q, sub( Q12, inv_rms32_e ) ) ); /* Q12-inv_rms32_e */
     154        6674 :             move32();
     155        6674 :             st->hHQ_core->crest_lp_q = sub( Q12, inv_rms32_e );
     156        6674 :             move16();
     157        6674 :             *crest_mod_lp_fx = L_shr( *crest_mod_lp_fx, sub( st->hHQ_core->crest_mod_lp_q, sub( Q12, inv_rms32_e ) ) ); /* Q12-inv_rms32_e */
     158        6674 :             move32();
     159        6674 :             st->hHQ_core->crest_mod_lp_q = sub( Q12, inv_rms32_e );
     160        6674 :             move16();
     161             :         }
     162        6674 :         *crest_lp_fx = L_add( Mpy_32_32( HQ_CREST_FAC_SM_FX, ( *crest_lp_fx ) ), Mpy_32_32( ONE_IN_Q31 - HQ_CREST_FAC_SM_FX, crest_fx ) ); /* Q(st->hHQ_core->crest_lp_q) */
     163        6674 :         move32();
     164        6674 :         *crest_mod_lp_fx = L_add( Mpy_32_32( HQ_CREST_FAC_SM_FX, ( *crest_mod_lp_fx ) ), Mpy_32_32( L_sub( ONE_IN_Q31, HQ_CREST_FAC_SM_FX ), crest_mod_fx ) ); /* Q(st->hHQ_core->crest_mod_lp_q) */
     165        6674 :         move32();
     166             : 
     167        6674 :         hq_crest_threshold = L_shr( HQ_CREST_THRESHOLD_FX, sub( Q28, st->hHQ_core->crest_lp_q ) );             /* Q(st->hHQ_core->crest_lp_q) */
     168        6674 :         hq_crest_mod_threshold = L_shr( HQ_CREST_MOD_THRESHOLD_FX, sub( Q29, st->hHQ_core->crest_mod_lp_q ) ); /* Q(st->hHQ_core->crest_mod_lp_q) */
     169        6674 :         test();
     170        6674 :         test();
     171        6674 :         if ( GT_32( ( *crest_lp_fx ), hq_crest_threshold ) && GT_32( ( *crest_mod_lp_fx ), hq_crest_mod_threshold ) && GT_16( low_count_fx, LOW_COUNT_THRESHOLD ) )
     172             :         {
     173          14 :             result = FALSE;
     174          14 :             move16();
     175             :         }
     176             :     }
     177             : 
     178        6674 :     return result; /* Q0 */
     179             : }
     180             : /*--------------------------------------------------------------------------*
     181             :  * hq_classifier_enc_fx()
     182             :  *
     183             :  * HQ mode selector (decision_matrix)
     184             :  *--------------------------------------------------------------------------*/
     185         370 : Word16 hq_classifier_enc_fx(                            /* o  : Consumed bits                   Q0  */
     186             :                              Encoder_State *st_fx,      /* i/o: encoder state structure             */
     187             :                              const Word16 length,       /* i  : Frame length                    Q0  */
     188             :                              const Word32 *coefs,       /* i  : Spectral coefficients           Q12 */
     189             :                              const Word16 is_transient, /* i  : Transient flag                  Q0  */
     190             :                              Word16 *Npeaks,            /* o  : Number of identified peaks      Q0  */
     191             :                              Word16 *peaks,             /* o  : Peak indices                    Q0  */
     192             :                              Word32 *pe_gains,          /* o  : Peak gains                      Q12 */
     193             :                              Word32 *nf_gains,          /* o  : Noise-fill gains                Q12 */
     194             :                              Word16 *hqswb_clas         /* o  : HQ class                        Q0  */
     195             : )
     196             : {
     197             :     Word16 bits;
     198         370 :     HQ_ENC_HANDLE hHQ_core = st_fx->hHQ_core;
     199             : 
     200         370 :     *hqswb_clas = HQ_NORMAL;
     201         370 :     IF( EQ_16( is_transient, 1 ) )
     202             :     {
     203          35 :         *hqswb_clas = HQ_TRANSIENT;
     204          35 :         move16();
     205             :     }
     206             : 
     207             :     /* classification and limit bandwidth for bit allocation */
     208         370 :     test();
     209         370 :     test();
     210         370 :     test();
     211         370 :     IF( EQ_16( length, L_FRAME32k ) && NE_16( is_transient, 1 ) && LE_32( st_fx->core_brate, HQ_32k ) && EQ_16( st_fx->bwidth, st_fx->last_bwidth ) )
     212             :     {
     213             :         /* Detect HQ_HARMONIC mode */
     214          44 :         *hqswb_clas = peak_avrg_ratio_fx( st_fx->total_brate, coefs, NUMC_N + 96, &hHQ_core->mode_count, &hHQ_core->mode_count1, 12 ); /* Q0 */
     215          44 :         move16();
     216             : 
     217             :         /* Detect harmonic VQ mode HQ_HVQ */
     218          44 :         hvq_classifier_fx( coefs, &hHQ_core->prev_Npeaks, hHQ_core->prev_peaks, hqswb_clas, Npeaks, peaks, st_fx->core_brate, st_fx->last_core,
     219             :                            nf_gains, &hHQ_core->hvq_hangover, pe_gains );
     220             :     }
     221             : 
     222         370 :     test();
     223         370 :     test();
     224         370 :     test();
     225         370 :     IF( EQ_16( length, L_FRAME48k ) && NE_16( is_transient, 1 ) && LE_32( st_fx->core_brate, HQ_32k ) && EQ_16( st_fx->bwidth, st_fx->last_bwidth ) )
     226             :     {
     227             :         /* Detect HQ_HARMONIC mode */
     228           0 :         *hqswb_clas = peak_avrg_ratio_fx( st_fx->total_brate, coefs, NUMC_N + 96, &hHQ_core->mode_count, &hHQ_core->mode_count1, 12 ); /* Q0 */
     229           0 :         move16();
     230             :         /* Detect harmonic VQ mode HQ_HVQ */
     231           0 :         hvq_classifier_fx( coefs, &hHQ_core->prev_Npeaks, hHQ_core->prev_peaks, hqswb_clas, Npeaks, peaks,
     232           0 :                            st_fx->core_brate, st_fx->last_core, nf_gains, &hHQ_core->hvq_hangover, pe_gains );
     233             :     }
     234             : 
     235         370 :     test();
     236         370 :     test();
     237         370 :     IF( EQ_16( length, L_FRAME48k ) && LE_32( st_fx->core_brate, HQ_32k ) && EQ_16( *hqswb_clas, HQ_NORMAL ) )
     238             :     {
     239           0 :         *hqswb_clas = HQ_GEN_FB; /* Q0 */
     240           0 :         move16();
     241             :     }
     242             : 
     243         370 :     test();
     244         370 :     IF( GE_16( length, L_FRAME32k ) && LE_32( st_fx->core_brate, HQ_32k ) )
     245             :     {
     246          44 :         bits = 2;
     247          44 :         move16();
     248             :     }
     249             :     ELSE
     250             :     {
     251         326 :         bits = 1;
     252         326 :         move16();
     253             :     }
     254             : 
     255         370 :     test();
     256         370 :     IF( EQ_16( length, L_FRAME48k ) && LE_32( st_fx->core_brate, HQ_32k ) )
     257             :     {
     258           0 :         IF( GE_16( *hqswb_clas, HQ_GEN_SWB ) )
     259             :         {
     260           0 :             push_indice( st_fx->hBstr, IND_HQ_SWB_CLAS, *hqswb_clas - 5, bits );
     261             :         }
     262             :         ELSE
     263             :         {
     264           0 :             push_indice( st_fx->hBstr, IND_HQ_SWB_CLAS, *hqswb_clas, bits );
     265             :         }
     266             :     }
     267             :     ELSE
     268             :     {
     269         370 :         push_indice( st_fx->hBstr, IND_HQ_SWB_CLAS, *hqswb_clas, bits );
     270             :     }
     271             : 
     272         370 :     test();
     273         370 :     test();
     274         370 :     IF( EQ_16( *hqswb_clas, HQ_NORMAL ) && EQ_16( length, L_FRAME32k ) && LE_32( st_fx->core_brate, HQ_32k ) )
     275             :     {
     276          32 :         *hqswb_clas = HQ_GEN_SWB; /* Q0 */
     277          32 :         move16();
     278             :     }
     279             : 
     280         370 :     return bits;
     281             : }
     282        7772 : Word16 hq_classifier_enc_ivas_fx(                            /* o  : Consumed bits                   Q0  */
     283             :                                   Encoder_State *st_fx,      /* i/o: encoder state structure             */
     284             :                                   const Word16 length,       /* i  : Frame length                    Q0  */
     285             :                                   const Word32 *coefs,       /* i  : Spectral coefficients           Q12 */
     286             :                                   const Word16 is_transient, /* i  : Transient flag                  Q0  */
     287             :                                   Word16 *Npeaks,            /* o  : Number of identified peaks      Q0  */
     288             :                                   Word16 *peaks,             /* o  : Peak indices                    Q0  */
     289             :                                   Word32 *pe_gains,          /* o  : Peak gains                      Q12 */
     290             :                                   Word32 *nf_gains,          /* o  : Noise-fill gains                Q12 */
     291             :                                   Word16 *hqswb_clas         /* o  : HQ class                        Q0  */
     292             : )
     293             : {
     294             : 
     295             : 
     296             :     Word16 bits;
     297        7772 :     HQ_ENC_HANDLE hHQ_core = st_fx->hHQ_core;
     298             :     Word32 max_brate;
     299             :     Word16 harmonic_decision;
     300             : 
     301             : 
     302        7772 :     max_brate = HQ_32k;
     303        7772 :     move32();
     304             : 
     305        7772 :     if ( st_fx->element_mode > EVS_MONO )
     306             :     {
     307        7772 :         max_brate = HQ_48k;
     308        7772 :         move32();
     309             :     }
     310             : 
     311        7772 :     *hqswb_clas = HQ_NORMAL; /* Q0 */
     312        7772 :     bits = 1;
     313        7772 :     move16();
     314        7772 :     IF( EQ_16( is_transient, 1 ) )
     315             :     {
     316         458 :         *hqswb_clas = HQ_TRANSIENT; /* Q0 */
     317         458 :         move16();
     318             :     }
     319             : 
     320             :     /* classification and limit bandwidth for bit allocation */
     321        7772 :     test();
     322        7772 :     IF( EQ_16( length, L_SPEC32k ) || EQ_16( length, L_SPEC48k ) )
     323             :     {
     324        7132 :         IF( LE_32( st_fx->core_brate, max_brate ) )
     325             :         {
     326        7132 :             test();
     327        7132 :             IF( !is_transient && EQ_16( st_fx->bwidth, st_fx->last_bwidth ) )
     328             :             {
     329             :                 /* Detect HQ_HARMONIC mode */
     330        6674 :                 *hqswb_clas = peak_avrg_ratio_ivas_fx( st_fx->total_brate, coefs, NUMC_N + 96, &hHQ_core->mode_count, &hHQ_core->mode_count1, 12 ); /* Q0 */
     331             : 
     332        6674 :                 harmonic_decision = hf_spectrum_sparseness_fx( st_fx, coefs );
     333             : 
     334             : 
     335        6674 :                 test();
     336        6674 :                 IF( EQ_16( *hqswb_clas, HQ_HARMONIC ) && !harmonic_decision )
     337             :                 {
     338           0 :                     *hqswb_clas = HQ_NORMAL; /* Q0 */
     339           0 :                     move16();
     340             :                 }
     341             :                 ELSE
     342             :                 {
     343             :                     /* Detect harmonic VQ mode HQ_HVQ */
     344        6674 :                     hvq_classifier_ivas_fx( coefs, &hHQ_core->prev_Npeaks, hHQ_core->prev_peaks, hqswb_clas, Npeaks, peaks, st_fx->core_brate, st_fx->last_core, nf_gains, &hHQ_core->hvq_hangover, pe_gains );
     345             :                 }
     346             :             }
     347        7132 :             bits = 2;
     348        7132 :             move16();
     349             :         }
     350             :     }
     351         640 :     ELSE IF( EQ_16( length, L_SPEC16k_EXT ) || EQ_16( length, L_SPEC48k_EXT ) )
     352             :     {
     353         145 :         bits = 0; /* HQ_NORMAL only -- no signalling needed */
     354         145 :         move16();
     355             :     }
     356             :     /* write signalling info to the bitstream */
     357        7772 :     push_indice( st_fx->hBstr, IND_HQ_SWB_CLAS, *hqswb_clas, bits );
     358             : 
     359        7772 :     IF( LE_32( st_fx->core_brate, HQ_32k ) && EQ_16( *hqswb_clas, HQ_NORMAL ) )
     360             :     {
     361        3272 :         IF( EQ_16( length, L_SPEC32k ) )
     362             :         {
     363         597 :             *hqswb_clas = HQ_GEN_SWB; /* Q0 */
     364         597 :             move16();
     365             :         }
     366        2675 :         ELSE IF( EQ_16( length, L_SPEC48k ) )
     367             :         {
     368        2210 :             *hqswb_clas = HQ_GEN_FB; /* Q0 */
     369        2210 :             move16();
     370             :         }
     371             :     }
     372             : 
     373        7772 :     return bits; /* Q0 */
     374             : }
     375             : /*--------------------------------------------------------------------------*
     376             :  * peak_avrg_ratio()
     377             :  *
     378             :  * Classify the input signal and decide if it has a harmonic structure
     379             :  *--------------------------------------------------------------------------*/
     380        6674 : Word16 peak_avrg_ratio_ivas_fx(
     381             :     const Word32 total_brate,  /* i  : total bitrate          Q0*/
     382             :     const Word32 *input_hi_fx, /* i  : input signal     Q_coeff      */
     383             :     const Word16 length,       /* i  : number of coefficients Q0*/
     384             :     Word16 *mode_count,        /* i/o: HQ_HARMONIC mode count Q0*/
     385             :     Word16 *mode_count1,       /* i/o: HQ_NORMAL mode count   Q0*/
     386             :     Word16 Q_coeff )
     387             : {
     388             :     Word16 i, j, q, k, k1, hqswb_clas;
     389             :     Word32 mean_fx, peak_fx;
     390             :     Word32 input_abs_fx[L_FRAME32k];
     391             :     Word32 peak_th_fx;
     392             : 
     393     3637330 :     FOR( i = 96; i < length; i++ )
     394             :     {
     395     3630656 :         input_abs_fx[i] = L_abs( input_hi_fx[i] );
     396     3630656 :         move32();
     397             :     }
     398             : 
     399        6674 :     hqswb_clas = HQ_NORMAL;
     400        6674 :     move16();
     401        6674 :     peak_th_fx = L_shl( 10L, sub( Q_coeff, 5 ) ); /* 5 is safe shift */
     402             : 
     403        6674 :     k = 0;
     404        6674 :     move16();
     405        6674 :     k1 = 0;
     406        6674 :     move16();
     407        6674 :     q = 96; /* q used for indexing */
     408        6674 :     move16();
     409             : 
     410      100110 :     FOR( i = 3; i < 17; i++ )
     411             :     {
     412       93436 :         peak_fx = L_deposit_l( 0 );
     413       93436 :         mean_fx = L_deposit_l( 1 );
     414             : 
     415             :         /*for(j = 0; j < 32; j ++, q ++) */
     416     3083388 :         FOR( j = 0; j < 32; j++ )
     417             :         {
     418     2989952 :             input_abs_fx[q] = L_shr( input_abs_fx[q], 5 ); /*Q_coeff-5 */
     419     2989952 :             move32();
     420     2989952 :             mean_fx = L_add( mean_fx, input_abs_fx[q] ); /*Q_coeff-5 */
     421     2989952 :             if ( GT_32( input_abs_fx[q], peak_fx ) )
     422             :             {
     423      412875 :                 peak_fx = input_abs_fx[q]; /*Q_coeff-5 */
     424      412875 :                 move32();
     425             :             }
     426     2989952 :             q += 1;
     427             :         }
     428             : 
     429       93436 :         IF( LT_16( i, 8 ) )
     430             :         {
     431       33370 :             if ( GT_32( peak_fx, Mult_32_16( mean_fx, 4608 ) ) ) /* Q15 0.140625 */
     432             :             {
     433       22340 :                 k = add( k, 1 );
     434             :             }
     435             :         }
     436             :         ELSE
     437             :         {
     438       60066 :             test();
     439       60066 :             if ( GT_32( peak_fx, Mult_32_16( mean_fx, 3686 ) ) /*Q15 0.1125 */
     440       25720 :                  && GT_32( peak_fx, peak_th_fx ) )             /*Q27 10 */
     441             :             {
     442       22257 :                 k1 = add( k1, 1 );
     443             :             }
     444             :         }
     445             :     }
     446             : 
     447        6674 :     test();
     448        6674 :     IF( GE_16( add( k, k1 ), 10 ) && GT_16( k1, 5 ) )
     449             :     {
     450        1690 :         IF( LT_16( *mode_count, 8 ) )
     451             :         {
     452        1690 :             *mode_count = add( *mode_count, 1 );
     453        1690 :             move16();
     454             :         }
     455             : 
     456        1690 :         IF( *mode_count1 > 0 )
     457             :         {
     458           0 :             *mode_count1 = sub( *mode_count1, 1 );
     459           0 :             move16();
     460             :         }
     461             :     }
     462             :     ELSE
     463             :     {
     464        4984 :         IF( LT_16( *mode_count1, 8 ) )
     465             :         {
     466        4984 :             *mode_count1 = add( *mode_count1, 1 );
     467        4984 :             move16();
     468             :         }
     469             : 
     470        4984 :         IF( *mode_count > 0 )
     471             :         {
     472           0 :             *mode_count = sub( *mode_count, 1 );
     473           0 :             move16();
     474             :         }
     475             :     }
     476             : 
     477        6674 :     test();
     478        6674 :     test();
     479        6674 :     test();
     480        6674 :     test();
     481        6674 :     test();
     482        6674 :     test();
     483             : 
     484        6674 :     IF( ( GE_16( add( k, k1 ), 5 ) && GT_16( k1, 2 ) && LT_32( total_brate, HQ_BWE_CROSSOVER_BRATE ) ) || ( ( ( GE_16( add( k, k1 ), 10 ) && GT_16( k1, 5 ) ) || GE_16( *mode_count, 5 ) ) && LT_16( *mode_count1, 5 ) ) )
     485             :     {
     486        2245 :         hqswb_clas = HQ_HARMONIC;
     487        2245 :         move16();
     488             :     }
     489        6674 :     return hqswb_clas; /* Q0 */
     490             : }
     491             : /*--------------------------------------------------------------------------*
     492             :  * peak_avrg_ratio()
     493             :  *
     494             :  * Classify the input signal and decide if it has a harmonic structure
     495             :  *--------------------------------------------------------------------------*/
     496          80 : Word16 peak_avrg_ratio_fx(
     497             :     const Word32 total_brate,  /* i  : total bitrate          Q0*/
     498             :     const Word32 *input_hi_fx, /* i  : input signal           Q_coeff*/
     499             :     const Word16 length,       /* i  : number of coefficients Q0*/
     500             :     Word16 *mode_count,        /* i/o: HQ_HARMONIC mode count Q0*/
     501             :     Word16 *mode_count1,       /* i/o: HQ_NORMAL mode count   Q0*/
     502             :     Word16 Q_coeff )
     503             : {
     504             :     Word16 i, j, q, k, k1, hqswb_clas;
     505             :     Word32 mean_fx, peak_fx;
     506             :     Word32 input_abs_fx[L_FRAME32k];
     507             :     Word32 peak_th_fx;
     508             : 
     509       40144 :     FOR( i = 96; i < length; i++ )
     510             :     {
     511       40064 :         input_abs_fx[i] = L_abs( input_hi_fx[i] ); /* Q_coeff */
     512             :     }
     513             : 
     514          80 :     hqswb_clas = HQ_NORMAL;
     515          80 :     move16();
     516          80 :     peak_th_fx = L_shl( 10L, sub( Q_coeff, 5 ) ); /* 5 is safe shift */
     517             : 
     518          80 :     k = 0;
     519          80 :     move16();
     520          80 :     k1 = 0;
     521          80 :     move16();
     522          80 :     q = 96; /* q used for indexing */
     523          80 :     move16();
     524             : 
     525        1200 :     FOR( i = 3; i < 17; i++ )
     526             :     {
     527        1120 :         peak_fx = L_deposit_l( 0 );
     528        1120 :         mean_fx = L_deposit_l( 1 );
     529             : 
     530             :         /*for(j = 0; j < 32; j ++, q ++) */
     531       36960 :         FOR( j = 0; j < 32; j++ )
     532             :         {
     533       35840 :             input_abs_fx[q] = L_shr( input_abs_fx[q], 5 ); /*Q_coeff-5 */
     534       35840 :             move32();
     535       35840 :             mean_fx = L_add( mean_fx, input_abs_fx[q] ); /*Q_coeff-5 */
     536       35840 :             if ( GT_32( input_abs_fx[q], peak_fx ) )
     537             :             {
     538        4648 :                 peak_fx = input_abs_fx[q]; /*Q_coeff-5 */
     539        4648 :                 move32();
     540             :             }
     541       35840 :             q += 1;
     542             :         }
     543             : 
     544        1120 :         IF( LT_16( i, 8 ) )
     545             :         {
     546         400 :             if ( GT_32( peak_fx, Mult_32_16( mean_fx, 4608 ) ) ) /* Q15 0.140625 */
     547             :             {
     548          82 :                 k = add( k, 1 );
     549             :             }
     550             :         }
     551             :         ELSE
     552             :         {
     553         720 :             test();
     554         720 :             if ( GT_32( peak_fx, Mult_32_16( mean_fx, 3686 ) ) /*Q15 0.1125 */
     555         186 :                  && GT_32( peak_fx, peak_th_fx ) )             /*Q27 10 */
     556             :             {
     557         170 :                 k1 = add( k1, 1 );
     558             :             }
     559             :         }
     560             :     }
     561             : 
     562          80 :     test();
     563          80 :     IF( GE_16( add( k, k1 ), 10 ) && GT_16( k1, 5 ) )
     564             :     {
     565           0 :         IF( LT_16( *mode_count, 8 ) )
     566             :         {
     567           0 :             *mode_count = add( *mode_count, 1 );
     568           0 :             move16();
     569             :         }
     570             : 
     571           0 :         IF( *mode_count1 > 0 )
     572             :         {
     573           0 :             *mode_count1 = sub( *mode_count1, 1 );
     574           0 :             move16();
     575             :         }
     576             :     }
     577             :     ELSE
     578             :     {
     579          80 :         IF( LT_16( *mode_count1, 8 ) )
     580             :         {
     581          66 :             *mode_count1 = add( *mode_count1, 1 );
     582          66 :             move16();
     583             :         }
     584             : 
     585          80 :         IF( *mode_count > 0 )
     586             :         {
     587           0 :             *mode_count = sub( *mode_count, 1 );
     588           0 :             move16();
     589             :         }
     590             :     }
     591             : 
     592          80 :     test();
     593          80 :     test();
     594          80 :     test();
     595          80 :     test();
     596          80 :     test();
     597          80 :     test();
     598             : 
     599          80 :     IF( ( GE_16( add( k, k1 ), 5 ) && GT_16( k1, 2 ) && EQ_32( total_brate, HQ_24k40 ) ) || ( ( ( GE_16( add( k, k1 ), 10 ) && GT_16( k1, 5 ) ) || GE_16( *mode_count, 5 ) ) && LT_16( *mode_count1, 5 ) ) )
     600             :     {
     601          12 :         hqswb_clas = HQ_HARMONIC;
     602          12 :         move16();
     603             :     }
     604             : 
     605          80 :     return hqswb_clas; /* Q0 */
     606             : }
     607             : 
     608             : /*--------------------------------------------------------------------------*
     609             :  * hvq_classifier()
     610             :  *
     611             :  * Classification of harmonic low band content for Harmonic VQ
     612             :  *--------------------------------------------------------------------------*/
     613        6674 : void hvq_classifier_ivas_fx(
     614             :     const Word32 *input,       /* i  : input signal                Q12 */
     615             :     Word16 *prev_Npeaks,       /* i/o: Peak number memory          Q0  */
     616             :     Word16 *prev_peaks,        /* i/o: Peak indices memory         Q0  */
     617             :     Word16 *hqswb_clas,        /* i/o: HQ class                    Q0  */
     618             :     Word16 *Npeaks,            /* o  : Number of peaks             Q0  */
     619             :     Word16 *peaks,             /* o  : Peak indices                Q0  */
     620             :     const Word32 L_core_brate, /* i  : Core bit-rate               Q0  */
     621             :     const Word16 last_core,    /* i  : Last core used              Q0  */
     622             :     Word32 *L_nf_gains,        /* o  : Noisefloor gains            Q12 */
     623             :     Word16 *hvq_hangover,      /* i/o: Mode-switch hangover        Q0  */
     624             :     Word32 *L_pe_gains         /* o  : peak gains                  Q12 */
     625             : )
     626             : {
     627             :     const Word16 *p_adj;
     628             :     UWord16 lsb;
     629             : 
     630             :     Word32 L_input_abs[L_FRAME32k];
     631             :     Word32 L_input_max;
     632             :     Word32 L_thr[L_FRAME16k];
     633             :     Word32 L_thr_tmp;
     634             :     Word32 L_m;
     635             :     Word32 L_tmp;
     636             :     Word32 L_d;
     637             :     Word32 L_peak;
     638             :     Word32 L_nf, L_pe;
     639             :     Word32 L_pe_mean[HVQ_NSUB_32k], L_nf_mean[HVQ_NSUB_32k];
     640             : 
     641             :     Word16 inv_nsub;
     642             :     Word16 sharp_dist;
     643             :     Word16 exp1, exp2;
     644             :     Word16 tmp;
     645             :     Word16 shift;
     646             :     Word16 idx;
     647             :     Word16 frac;
     648             :     Word16 inv_nf_mean;
     649             :     Word16 inv_gains_nsub;
     650             :     Word16 nf_mean_norm;
     651             :     Word16 num_sharp_bands, i, j, k, q, peak_th, nsub, pindx, N, offset;
     652             :     Word16 num_peak_cands, high, low;
     653             :     Word16 sharp[HVQ_NSUB_32k];
     654             :     Word16 peak_cand_idx[HVQ_THRES_BIN_32k], avail_peaks[HVQ_NSUB_32k];
     655             : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
     656        6674 :     Flag Overflow = 0;
     657        6674 :     move16();
     658             : #endif
     659        6674 :     Word16 temp_e = 0;
     660        6674 :     move16();
     661        6674 :     L_input_max = L_deposit_l( 0 );
     662        6674 :     set32_fx( L_thr, 0, L_FRAME16k );
     663             : 
     664        6674 :     IF( LT_32( L_core_brate, HQ_BWE_CROSSOVER_BRATE ) )
     665             :     {
     666        2641 :         nsub = HVQ_NSUB_24k;
     667        2641 :         move16();
     668        2641 :         inv_nsub = 4681; /* 1/7 in Q15 */
     669        2641 :         move16();
     670        2641 :         inv_gains_nsub = 10923; /* 1/3 in Q15 */
     671        2641 :         move16();
     672             :     }
     673             :     ELSE
     674             :     {
     675        4033 :         nsub = HVQ_NSUB_32k;
     676        4033 :         move16();
     677        4033 :         inv_nsub = 3277; /* 1/10 in Q15 */
     678        4033 :         move16();
     679        4033 :         inv_gains_nsub = 6554; /* 1/5 in Q15 */
     680        4033 :         move16();
     681             :     }
     682             : 
     683        6674 :     N = shl( nsub, 5 ); /* Mult by 32 (HVQ_BW) */
     684             : 
     685        6674 :     test();
     686        6674 :     test();
     687        6674 :     IF( EQ_16( *hqswb_clas, HQ_HARMONIC ) && last_core != ACELP_CORE && NE_16( last_core, AMR_WB_CORE ) )
     688        2215 :     {
     689      594375 :         FOR( i = 0; i < N; i++ )
     690             :         {
     691      592160 :             L_input_abs[i] = L_abs( input[i] ); /* Q12 */
     692      592160 :             move16();
     693      592160 :             IF( GT_32( L_input_abs[i], L_input_max ) )
     694             :             {
     695       13497 :                 L_input_max = L_input_abs[i]; /* Q12 */
     696       13497 :                 move16();
     697             :             }
     698             :         }
     699             : 
     700        2215 :         exp1 = norm_l( L_input_max );
     701             : 
     702        2215 :         *Npeaks = 0;
     703        2215 :         move16();
     704        2215 :         L_nf = 3276800; /* 800 in Q12 */
     705        2215 :         move32();
     706        2215 :         L_pe = 3276800; /* 800 in Q12    */
     707        2215 :         move32();
     708        2215 :         num_sharp_bands = 0;
     709        2215 :         move16();
     710        2215 :         k = 0;
     711        2215 :         move16();
     712        2215 :         q = 0;
     713        2215 :         move16();
     714        2215 :         sharp_dist = 0;
     715        2215 :         move16();
     716             : 
     717             :         /* Find peak threshold */
     718       20720 :         FOR( i = 0; i < nsub; i++ )
     719             :         {
     720       18505 :             L_peak = 0;
     721       18505 :             L_nf_mean[i] = 0;
     722       18505 :             L_pe_mean[i] = 0;
     723       18505 :             move32();
     724       18505 :             move32();
     725       18505 :             move32();
     726             : 
     727      610665 :             FOR( j = 0; j < HVQ_BW; j++ )
     728             :             {
     729      592160 :                 L_d = L_input_abs[q]; /* Q12 */
     730      592160 :                 IF( GT_32( L_d, L_nf ) )
     731             :                 {
     732             :                     /*nf = HVQ_NF_WEIGHT1 * nf + (1 - HVQ_NF_WEIGHT1) * d; */
     733      316205 :                     Mpy_32_16_ss( L_d, HVQ_NF_WEIGHT1B, &L_tmp, &lsb );   /* 12+15-15=12 */
     734      316205 :                     Mpy_32_16_ss( L_nf, HVQ_NF_WEIGHT1_FX, &L_nf, &lsb ); /* 12+15-15=12 */
     735      316205 :                     L_nf = L_add( L_nf, L_tmp );                          /*Q12 */
     736             :                 }
     737             :                 ELSE
     738             :                 {
     739             :                     /*nf = HVQ_NF_WEIGHT2 * nf + (1 - HVQ_NF_WEIGHT2) * d; */
     740      275955 :                     Mpy_32_16_ss( L_d, HVQ_NF_WEIGHT2B, &L_tmp, &lsb );   /* 12+15-15=12 */
     741      275955 :                     Mpy_32_16_ss( L_nf, HVQ_NF_WEIGHT2_FX, &L_nf, &lsb ); /* 12+15-15=12 */
     742      275955 :                     L_nf = L_add( L_nf, L_tmp );                          /*Q12 */
     743             :                 }
     744             : 
     745      592160 :                 IF( GT_32( L_d, L_pe ) )
     746             :                 {
     747             :                     /*pe = HVQ_PE_WEIGHT1 * pe + (1 - HVQ_PE_WEIGHT1) * d; */
     748      118293 :                     Mpy_32_16_ss( L_d, HVQ_PE_WEIGHT1B, &L_tmp, &lsb );   /* 12+15-15=12 */
     749      118293 :                     Mpy_32_16_ss( L_pe, HVQ_PE_WEIGHT1_FX, &L_pe, &lsb ); /* 12+15-15=12 */
     750      118293 :                     L_pe = L_add( L_pe, L_tmp );                          /*Q12 */
     751             :                 }
     752             :                 ELSE
     753             :                 {
     754             :                     /*pe = HVQ_PE_WEIGHT2 * pe + (1 - HVQ_PE_WEIGHT2) * d; */
     755      473867 :                     Mpy_32_16_ss( L_d, HVQ_PE_WEIGHT2B, &L_tmp, &lsb );   /* 12+15-15=12 */
     756      473867 :                     Mpy_32_16_ss( L_pe, HVQ_PE_WEIGHT2_FX, &L_pe, &lsb ); /* 12+15-15=12 */
     757      473867 :                     L_pe = L_add( L_pe, L_tmp );                          /*Q12 */
     758             :                 }
     759             : 
     760      592160 :                 L_nf_mean[i] = L_add_sat( L_nf_mean[i], L_nf ); /*Q12 */
     761      592160 :                 L_pe_mean[i] = L_add_sat( L_pe_mean[i], L_pe ); /*Q12 */
     762      592160 :                 move32();
     763      592160 :                 move32();
     764      592160 :                 IF( GT_32( L_d, L_peak ) )
     765             :                 {
     766       88825 :                     L_peak = L_add( L_d, 0 );
     767             :                 }
     768             : 
     769      592160 :                 q += 1;
     770             :             }
     771       18505 :             L_nf_mean[i] = L_shr( L_nf_mean[i], 5 ); /* Divide by 5 (HVQ_BW) */
     772       18505 :             L_pe_mean[i] = L_shr( L_pe_mean[i], 5 ); /* Divide by 5 (HVQ_BW) */
     773       18505 :             move32();
     774       18505 :             move32();
     775             :             /*thr_tmp = (float)pow( pe_mean[i]/nf_mean[i], HVQ_THR_POW ) * nf_mean[i]; */
     776       18505 :             exp1 = norm_l( L_nf_mean[i] );
     777       18505 :             nf_mean_norm = extract_h( L_shl( L_nf_mean[i], exp1 ) ); /* 12+s-16=s-4 */
     778       18505 :             IF( nf_mean_norm == 0 )
     779             :             {
     780           0 :                 inv_nf_mean = 0;
     781             :             }
     782             :             ELSE
     783             :             {
     784       18505 :                 inv_nf_mean = div_s( 1 << 14, nf_mean_norm ); /* 15+14-s+4=33-s */
     785             :             }
     786       18505 :             Mpy_32_16_ss( L_pe_mean[i], inv_nf_mean, &L_tmp, &lsb ); /*12+33-s-15=30-s */
     787             : 
     788       18505 :             exp2 = norm_l( L_tmp );
     789       18505 :             tmp = Log2_norm_lc( L_shl( L_tmp, exp2 ) ); /* Q15 */
     790       18505 :             exp2 = sub( exp1, exp2 );                   /* Q0 */
     791       18505 :             L_tmp = Mpy_32_16( exp2, tmp, 32767 );      /* 1 in Q15. Q16 */
     792       18505 :             Mpy_32_16_ss( L_tmp, 28836, &L_tmp, &lsb ); /* 16+15-15=16 */
     793       18505 :             frac = L_Extract_lc( L_tmp, &tmp );         /* Q15 and Q0 */
     794       18505 :             L_tmp = Pow2( 14, frac );                   /* Q14 */
     795       18505 :             L_tmp = L_shl( L_tmp, tmp );                /* Q14 */
     796             : 
     797       18505 :             Mpy_32_16_ss( L_tmp, nf_mean_norm, &L_tmp, &lsb );             /*14+s-4-15=s-5 */
     798       18505 :             shift = sub( 17, exp1 );                                       /* 16-(s-5)=17-s */
     799       18505 :             L_thr_tmp = L_shl( L_tmp, shift );                             /* Q16 */
     800       18505 :             L_thr_tmp = L_add( L_thr_tmp, lshr( lsb, sub( 16, shift ) ) ); /*Q16 */
     801             : 
     802       18505 :             set32_fx( &L_thr[k], L_thr_tmp, HVQ_BW );
     803       18505 :             k = add( k, HVQ_BW );
     804             : 
     805             :             /*sharp[i] = peak/nf_mean[i]; */
     806       18505 :             Mpy_32_16_ss( L_peak, inv_nf_mean, &L_tmp, &lsb ); /* 12+33-s-15=30-s */
     807       18505 :             shift = sub( exp1, 8 );
     808       18505 :             sharp[i] = extract_h( L_shl( L_tmp, shift ) ); /* 30-s+s-8-16 -> Q6 */
     809       18505 :             move16();
     810             :             /*sharp_dist += (sharp[i]-HVQ_SHARP_THRES); */
     811       18505 :             sharp_dist = add_o( sharp_dist, sub( sharp[i], HVQ_SHARP_THRES_FX ), &Overflow ); /* Q6 */
     812       18505 :             if ( GT_16( sharp[i], HVQ_SHARP_THRES_FX ) )
     813             :             {
     814       15934 :                 num_sharp_bands = add( num_sharp_bands, 1 );
     815             :             }
     816             :         }
     817             : 
     818             :         /* Estimate noise floor gains */
     819        2215 :         offset = s_and( nsub, 1 );
     820       19505 :         FOR( i = 0; i < ( nsub & (Word16) 0xFFFE ); i++ )
     821             :         {
     822             :             /*(2*i+1)/nsub */
     823       17290 :             idx = mult( add( shl( i, 1 ), 1 ), add( inv_nsub, 1 ) );           /*0+15-15 = 0 */
     824       17290 :             L_nf_gains[idx] = L_add( L_nf_gains[idx], L_nf_mean[i + offset] ); /* Q12 */
     825       17290 :             L_pe_gains[idx] = L_add( L_pe_gains[idx], L_pe_mean[i + offset] ); /* Q12 */
     826       17290 :             move32();
     827       17290 :             move32();
     828             :         }
     829             : 
     830        6645 :         FOR( i = 0; i < HVQ_NF_GROUPS; i++ )
     831             :         {
     832        4430 :             Mpy_32_16_ss( L_nf_gains[i], inv_gains_nsub, &L_nf_gains[i], &lsb ); /*12+15-15=12 */
     833        4430 :             Mpy_32_16_ss( L_pe_gains[i], inv_gains_nsub, &L_pe_gains[i], &lsb ); /*12+15-15=12 */
     834             :         }
     835             : 
     836             :         /* Allocate available peaks */
     837       20720 :         FOR( i = 0; i < nsub; i++ )
     838             :         {
     839       18505 :             avail_peaks[i] = HVQ_PA_PEAKS_SHARP1; /* Q0 */
     840       18505 :             move16();
     841       18505 :             idx = mult( add( shl( i, 1 ), 1 ), add( inv_nsub, 1 ) );      /*0+15-15 = 0 */
     842       18505 :             Mpy_32_16_ss( L_nf_gains[idx], HVQ_PA_FAC_FX, &L_tmp, &lsb ); /* 12+15-15 -> Q12 */
     843       18505 :             IF( LT_32( L_nf_mean[i], L_tmp ) )
     844             :             {
     845        6678 :                 IF( LT_16( sharp[i], HVQ_PA_SHARP_THRES3_FX ) )
     846             :                 {
     847        1487 :                     avail_peaks[i] = HVQ_PA_PEAKS_SHARP3; /* Q0 */
     848        1487 :                     move16();
     849             :                 }
     850        5191 :                 ELSE IF( LT_16( sharp[i], HVQ_PA_SHARP_THRES2_FX ) )
     851             :                 {
     852         673 :                     avail_peaks[i] = HVQ_PA_PEAKS_SHARP2; /* Q0 */
     853         673 :                     move16();
     854             :                 }
     855             :             }
     856             :         }
     857             : 
     858             : 
     859             :         /* Adjust threshold around previous peaks */
     860       27033 :         FOR( i = 0; i < *prev_Npeaks; i++ )
     861             :         {
     862       24818 :             j = sub( prev_peaks[i], 2 ); /* Q0 */
     863       24818 :             k = add( prev_peaks[i], 2 ); /* Q0 */
     864       24818 :             p_adj = hvq_thr_adj_fx;      /* Q15 */
     865             : 
     866      124090 :             FOR( q = j; q < k; q++ )
     867             :             {
     868       99272 :                 Mpy_32_16_ss( L_thr[q], *p_adj++, &L_thr[q], &lsb ); /* 12+15-15=12 */
     869       99272 :                 move32();
     870             :             }
     871             :         }
     872             : 
     873        2215 :         num_peak_cands = 0;
     874        2215 :         move16();
     875             : 
     876             :         /* Remove everything below threshold for peak search */
     877        2215 :         L_input_abs[0] = L_deposit_l( 0 );
     878        2215 :         L_input_abs[1] = L_deposit_l( 0 );
     879        2215 :         L_input_abs[N - 2] = L_deposit_l( 0 );
     880        2215 :         L_input_abs[N - 1] = L_deposit_l( 0 );
     881        2215 :         move32();
     882        2215 :         move32();
     883        2215 :         move32();
     884        2215 :         move32();
     885      589945 :         FOR( i = 0; i < N - 2; i++ )
     886             :         {
     887      587730 :             IF( LT_32( L_input_abs[i], L_thr[i] ) )
     888             :             {
     889      479653 :                 L_input_abs[i] = L_deposit_l( 0 );
     890             : 
     891      479653 :                 move32();
     892             :             }
     893             :             ELSE
     894             :             {
     895      108077 :                 L_input_abs[num_peak_cands] = L_input_abs[i]; /* Q12 */
     896      108077 :                 move32();
     897      108077 :                 peak_cand_idx[num_peak_cands] = i; /* Q0 */
     898      108077 :                 move16();
     899      108077 :                 num_peak_cands = add( num_peak_cands, 1 );
     900             :             }
     901             :         }
     902             : 
     903             : 
     904        2215 :         peak_th = extract_l( BASOP_Util_Divide3232_Scale( L_add( W_extract_l( W_mult0_32_32( L_core_brate, HVQ_PEAKS_PER_DELTA_THR ) ), HVQ_PEAKS_PER_DELTA_THR_OFFS ), HVQ_PEAKS_BPS_DELTA, &temp_e ) );
     905        2215 :         peak_th = shr( peak_th, sub( 15, temp_e ) );
     906             :         /* Find peaks */
     907        2215 :         pindx = maximum_32_fx( L_input_abs, num_peak_cands, &L_m );
     908        2215 :         i = 0;
     909        2215 :         move16();
     910             : 
     911       46418 :         WHILE( L_m > 0 && LT_16( i, peak_th + 1 ) )
     912             :         {
     913       44203 :             idx = mult( peak_cand_idx[pindx], INV_HVQ_BW ); /* 0+15-15=0 */
     914       44203 :             IF( avail_peaks[idx] > 0 )
     915             :             {
     916       43189 :                 peaks[i++] = peak_cand_idx[pindx]; /* Q0 */
     917       43189 :                 avail_peaks[idx]--;
     918             :             }
     919             : 
     920       44203 :             j = sub( pindx, 2 );
     921       44203 :             k = add( pindx, 2 );
     922             : 
     923       44203 :             if ( j < 0 )
     924             :             {
     925        2149 :                 j = 0;
     926        2149 :                 move16();
     927             :             }
     928             : 
     929       44203 :             tmp = sub( num_peak_cands, 1 );
     930       44203 :             if ( GT_16( k, tmp ) )
     931             :             {
     932        1553 :                 k = tmp;
     933        1553 :                 move16();
     934             :             }
     935             : 
     936       44203 :             low = sub( peak_cand_idx[pindx], 2 );
     937       44203 :             high = add( peak_cand_idx[pindx], 2 );
     938             : 
     939       44203 :             if ( low < 0 )
     940             :             {
     941           0 :                 low = 0;
     942           0 :                 move16();
     943             :             }
     944             : 
     945       44203 :             tmp = sub( N, 1 );
     946       44203 :             if ( GT_16( high, tmp ) )
     947             :             {
     948           0 :                 high = tmp;
     949           0 :                 move16();
     950             :             }
     951             : 
     952      173373 :             FOR( q = j; q <= pindx; q++ )
     953             :             {
     954      129170 :                 IF( GE_16( peak_cand_idx[q], low ) )
     955             :                 {
     956       73041 :                     peak_cand_idx[q] = 0;
     957       73041 :                     move16();
     958       73041 :                     L_input_abs[q] = 0;
     959       73041 :                     move16();
     960             :                 }
     961             :             }
     962             : 
     963      130247 :             FOR( q = pindx + 1; q <= k; q++ )
     964             :             {
     965       86044 :                 IF( LE_16( peak_cand_idx[q], high ) )
     966             :                 {
     967       59182 :                     peak_cand_idx[q] = 0;
     968       59182 :                     move16();
     969       59182 :                     L_input_abs[q] = 0;
     970       59182 :                     move16();
     971             :                 }
     972             :             }
     973             : 
     974       44203 :             pindx = maximum_32_fx( L_input_abs, num_peak_cands, &L_m );
     975             :         }
     976             : 
     977        2215 :         *Npeaks = i; /* Q0 */
     978        2215 :         move16();
     979        2215 :         IF( GT_16( *Npeaks, HVQ_MIN_PEAKS ) )
     980             :         {
     981        2215 :             test();
     982        2215 :             IF( GT_16( num_sharp_bands, sub( nsub, 3 ) ) && LE_16( *Npeaks, peak_th ) )
     983             :             {
     984        1231 :                 sharp_dist = mult( sharp_dist, inv_nsub ); /*x+15-15=x */
     985        1231 :                 test();
     986        1231 :                 IF( LE_16( sharp_dist, SHARP_DIST_THRES_FX ) && *hvq_hangover < 0 )
     987             :                 {
     988          39 :                     *hvq_hangover = add( *hvq_hangover, 1 ); /* Q0 */
     989             :                 }
     990             :                 ELSE
     991             :                 {
     992        1192 :                     *hqswb_clas = HQ_HVQ; /* Q0 */
     993        1192 :                     move16();
     994        1192 :                     *hvq_hangover = 2; /* Q0 */
     995        1192 :                     move16();
     996             :                 }
     997             : 
     998             :                 /* update memory */
     999        1231 :                 *prev_Npeaks = *Npeaks; /* Q0 */
    1000        1231 :                 move16();
    1001        1231 :                 Copy( peaks, prev_peaks, *Npeaks ); /* Q0 */
    1002             :             }
    1003             :             ELSE
    1004             :             {
    1005         984 :                 IF( *hvq_hangover > 0 )
    1006             :                 {
    1007         274 :                     *hqswb_clas = HQ_HVQ; /* Q0 */
    1008         274 :                     move16();
    1009         274 :                     *hvq_hangover = sub( *hvq_hangover, 1 ); /* Q0 */
    1010         274 :                     move16();
    1011             :                 }
    1012             :                 ELSE
    1013             :                 {
    1014         710 :                     *hvq_hangover = -1;
    1015         710 :                     move16();
    1016             :                 }
    1017             :             }
    1018             :         }
    1019             :         ELSE
    1020             :         {
    1021             :             /* Zero peaks, likely silence input. */
    1022           0 :             *hvq_hangover = -1;
    1023           0 :             move16();
    1024             :         }
    1025             : 
    1026             :         //*Npeaks = (int16_t) ( s_min( ( L_core_brate * HVQ_PEAKS_PER_DELTA + HVQ_PEAKS_PER_DELTA_OFFS ) / HVQ_PEAKS_BPS_DELTA, *Npeaks ) );
    1027        2215 :         temp_e = 0;
    1028        2215 :         move16();
    1029        2215 :         Word16 Npeaks_temp = *Npeaks;
    1030        2215 :         *Npeaks = BASOP_Util_Divide3232_Scale( L_add( W_extract_l( W_mult0_32_32( L_core_brate, HVQ_PEAKS_PER_DELTA ) ), HVQ_PEAKS_PER_DELTA_OFFS ), HVQ_PEAKS_BPS_DELTA, &temp_e );
    1031        2215 :         *Npeaks = s_min( shr( *Npeaks, sub( 15, temp_e ) ), Npeaks_temp );
    1032        2215 :         move16();
    1033             :     }
    1034             :     ELSE
    1035             :     {
    1036        4459 :         *prev_Npeaks = 0;
    1037        4459 :         move16();
    1038        4459 :         *hvq_hangover = 0;
    1039        4459 :         move16();
    1040             :     }
    1041             : 
    1042             : 
    1043        6674 :     return;
    1044             : }
    1045             : 
    1046          44 : void hvq_classifier_fx(
    1047             :     const Word32 *input,       /* i  : input signal                Q12 */
    1048             :     Word16 *prev_Npeaks,       /* i/o: Peak number memory          Q0  */
    1049             :     Word16 *prev_peaks,        /* i/o: Peak indices memory         Q0  */
    1050             :     Word16 *hqswb_clas,        /* i/o: HQ class                    Q0  */
    1051             :     Word16 *Npeaks,            /* o  : Number of peaks             Q0  */
    1052             :     Word16 *peaks,             /* o  : Peak indices                Q0  */
    1053             :     const Word32 L_core_brate, /* i  : Core bit-rate               Q0  */
    1054             :     const Word16 last_core,    /* i  : Last core used              Q0  */
    1055             :     Word32 *L_nf_gains,        /* o  : Noisefloor gains            Q12 */
    1056             :     Word16 *hvq_hangover,      /* i/o: Mode-switch hangover        Q0  */
    1057             :     Word32 *L_pe_gains         /* o  : peak gains                  Q12 */
    1058             : )
    1059             : {
    1060             :     const Word16 *p_adj;
    1061             :     UWord16 lsb;
    1062             : 
    1063             :     Word32 L_input_abs[L_FRAME32k];
    1064             :     Word32 L_input_max;
    1065             :     Word32 L_thr[L_FRAME16k];
    1066             :     Word32 L_thr_tmp;
    1067             :     Word32 L_m;
    1068             :     Word32 L_tmp;
    1069             :     Word32 L_d;
    1070             :     Word32 L_peak;
    1071             :     Word32 L_nf, L_pe;
    1072             :     Word32 L_pe_mean[HVQ_NSUB_32k], L_nf_mean[HVQ_NSUB_32k];
    1073             : 
    1074             :     Word16 inv_nsub;
    1075             :     Word16 sharp_dist;
    1076             :     Word16 exp1, exp2;
    1077             :     Word16 tmp;
    1078             :     Word16 shift;
    1079             :     Word16 idx;
    1080             :     Word16 frac;
    1081             :     Word16 inv_nf_mean;
    1082             :     Word16 inv_gains_nsub;
    1083             :     Word16 nf_mean_norm;
    1084             :     Word16 num_sharp_bands, i, j, k, q, peak_th, nsub, pindx, N, offset;
    1085             :     Word16 num_peak_cands, high, low;
    1086             :     Word16 sharp[HVQ_NSUB_32k];
    1087             :     Word16 peak_cand_idx[HVQ_THRES_BIN_32k], avail_peaks[HVQ_NSUB_32k];
    1088             : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
    1089          44 :     Flag Overflow = 0;
    1090          44 :     move32();
    1091             : #endif
    1092          44 :     L_input_max = L_deposit_l( 0 );
    1093          44 :     set32_fx( L_thr, 0, L_FRAME16k );
    1094             : 
    1095          44 :     IF( EQ_32( L_core_brate, HQ_24k40 ) )
    1096             :     {
    1097          44 :         nsub = HVQ_NSUB_24k;
    1098          44 :         move16();
    1099          44 :         inv_nsub = 4681; /* 1/7 in Q15 */
    1100          44 :         move16();
    1101          44 :         inv_gains_nsub = 10923; /* 1/3 in Q15 */
    1102          44 :         move16();
    1103             :     }
    1104             :     ELSE
    1105             :     {
    1106           0 :         nsub = HVQ_NSUB_32k;
    1107           0 :         move16();
    1108           0 :         inv_nsub = 3277; /* 1/10 in Q15 */
    1109           0 :         move16();
    1110           0 :         inv_gains_nsub = 6554; /* 1/5 in Q15 */
    1111           0 :         move16();
    1112             :     }
    1113             : 
    1114          44 :     N = shl( nsub, 5 ); /* Mult by 32 (HVQ_BW) */
    1115             : 
    1116          44 :     test();
    1117          44 :     test();
    1118          44 :     IF( EQ_16( *hqswb_clas, HQ_HARMONIC ) && last_core != ACELP_CORE && NE_16( last_core, AMR_WB_CORE ) )
    1119             :     {
    1120        2700 :         FOR( i = 0; i < N; i++ )
    1121             :         {
    1122        2688 :             L_input_abs[i] = L_abs( input[i] ); /* Q12 */
    1123        2688 :             IF( GT_32( L_input_abs[i], L_input_max ) )
    1124             :             {
    1125          62 :                 L_input_max = L_input_abs[i]; /* Q12 */
    1126          62 :                 move16();
    1127             :             }
    1128             :         }
    1129             : 
    1130          12 :         exp1 = norm_l( L_input_max );
    1131             : 
    1132          12 :         *Npeaks = 0;
    1133          12 :         move16();
    1134          12 :         L_nf = 3276800; /* 800 in Q12 */
    1135          12 :         move32();
    1136          12 :         L_pe = 3276800; /* 800 in Q12    */
    1137          12 :         move32();
    1138          12 :         num_sharp_bands = 0;
    1139          12 :         move16();
    1140          12 :         k = 0;
    1141          12 :         move16();
    1142          12 :         q = 0;
    1143          12 :         move16();
    1144          12 :         sharp_dist = 0;
    1145          12 :         move16();
    1146             : 
    1147             :         /* Find peak threshold */
    1148          96 :         FOR( i = 0; i < nsub; i++ )
    1149             :         {
    1150          84 :             L_peak = 0;
    1151          84 :             L_nf_mean[i] = 0;
    1152          84 :             L_pe_mean[i] = 0;
    1153          84 :             move32();
    1154          84 :             move32();
    1155          84 :             move32();
    1156        2772 :             FOR( j = 0; j < HVQ_BW; j++ )
    1157             :             {
    1158        2688 :                 L_d = L_input_abs[q]; /* Q12 */
    1159        2688 :                 move32();
    1160        2688 :                 IF( GT_32( L_d, L_nf ) )
    1161             :                 {
    1162             :                     /*nf = HVQ_NF_WEIGHT1 * nf + (1 - HVQ_NF_WEIGHT1) * d; */
    1163        1768 :                     Mpy_32_16_ss( L_d, HVQ_NF_WEIGHT1B, &L_tmp, &lsb );   /* 12+15-15=12 */
    1164        1768 :                     Mpy_32_16_ss( L_nf, HVQ_NF_WEIGHT1_FX, &L_nf, &lsb ); /* 12+15-15=12 */
    1165        1768 :                     L_nf = L_add( L_nf, L_tmp );                          /*Q12 */
    1166             :                 }
    1167             :                 ELSE
    1168             :                 {
    1169             :                     /*nf = HVQ_NF_WEIGHT2 * nf + (1 - HVQ_NF_WEIGHT2) * d; */
    1170         920 :                     Mpy_32_16_ss( L_d, HVQ_NF_WEIGHT2B, &L_tmp, &lsb );   /* 12+15-15=12 */
    1171         920 :                     Mpy_32_16_ss( L_nf, HVQ_NF_WEIGHT2_FX, &L_nf, &lsb ); /* 12+15-15=12 */
    1172         920 :                     L_nf = L_add( L_nf, L_tmp );                          /*Q12 */
    1173             :                 }
    1174             : 
    1175        2688 :                 IF( GT_32( L_d, L_pe ) )
    1176             :                 {
    1177             :                     /*pe = HVQ_PE_WEIGHT1 * pe + (1 - HVQ_PE_WEIGHT1) * d; */
    1178         704 :                     Mpy_32_16_ss( L_d, HVQ_PE_WEIGHT1B, &L_tmp, &lsb );   /* 12+15-15=12 */
    1179         704 :                     Mpy_32_16_ss( L_pe, HVQ_PE_WEIGHT1_FX, &L_pe, &lsb ); /* 12+15-15=12 */
    1180         704 :                     L_pe = L_add( L_pe, L_tmp );                          /*Q12 */
    1181             :                 }
    1182             :                 ELSE
    1183             :                 {
    1184             :                     /*pe = HVQ_PE_WEIGHT2 * pe + (1 - HVQ_PE_WEIGHT2) * d; */
    1185        1984 :                     Mpy_32_16_ss( L_d, HVQ_PE_WEIGHT2B, &L_tmp, &lsb );   /* 12+15-15=12 */
    1186        1984 :                     Mpy_32_16_ss( L_pe, HVQ_PE_WEIGHT2_FX, &L_pe, &lsb ); /* 12+15-15=12 */
    1187        1984 :                     L_pe = L_add( L_pe, L_tmp );                          /*Q12 */
    1188             :                 }
    1189             : 
    1190        2688 :                 L_nf_mean[i] = L_add_sat( L_nf_mean[i], L_nf ); /*Q12 */
    1191        2688 :                 L_pe_mean[i] = L_add_sat( L_pe_mean[i], L_pe ); /*Q12 */
    1192        2688 :                 move32();
    1193        2688 :                 move32();
    1194        2688 :                 IF( GT_32( L_d, L_peak ) )
    1195             :                 {
    1196         367 :                     L_peak = L_add( L_d, 0 );
    1197             :                 }
    1198             : 
    1199        2688 :                 q += 1;
    1200             :             }
    1201          84 :             L_nf_mean[i] = L_shr( L_nf_mean[i], 5 ); /* Divide by 5 (HVQ_BW) */
    1202          84 :             L_pe_mean[i] = L_shr( L_pe_mean[i], 5 ); /* Divide by 5 (HVQ_BW) */
    1203          84 :             move32();
    1204          84 :             move32();
    1205             : 
    1206             :             /*thr_tmp = (float)pow( pe_mean[i]/nf_mean[i], HVQ_THR_POW ) * nf_mean[i]; */
    1207          84 :             exp1 = norm_l( L_nf_mean[i] );
    1208          84 :             nf_mean_norm = extract_h( L_shl( L_nf_mean[i], exp1 ) ); /* 12+s-16=s-4 */
    1209          84 :             IF( nf_mean_norm == 0 )
    1210             :             {
    1211           0 :                 inv_nf_mean = 0;
    1212             :             }
    1213             :             ELSE
    1214             :             {
    1215          84 :                 inv_nf_mean = div_s( 1 << 14, nf_mean_norm ); /* 15+14-s+4=33-s */
    1216             :             }
    1217          84 :             Mpy_32_16_ss( L_pe_mean[i], inv_nf_mean, &L_tmp, &lsb ); /*12+33-s-15=30-s */
    1218             : 
    1219          84 :             exp2 = norm_l( L_tmp );
    1220          84 :             tmp = Log2_norm_lc( L_shl( L_tmp, exp2 ) ); /* Q15 */
    1221          84 :             exp2 = exp1 - exp2;                         /* Q0 */
    1222          84 :             L_tmp = Mpy_32_16( exp2, tmp, 32767 );      /* 1 in Q15. Q16 */
    1223          84 :             Mpy_32_16_ss( L_tmp, 28836, &L_tmp, &lsb ); /* 16+15-15=16 */
    1224          84 :             frac = L_Extract_lc( L_tmp, &tmp );         /* Q15 and Q0 */
    1225          84 :             L_tmp = Pow2( 14, frac );                   /* Q14 */
    1226          84 :             L_tmp = L_shl( L_tmp, tmp );                /* Q14 */
    1227             : 
    1228          84 :             Mpy_32_16_ss( L_tmp, nf_mean_norm, &L_tmp, &lsb );             /*14+s-4-15=s-5 */
    1229          84 :             shift = sub( 17, exp1 );                                       /* 16-(s-5)=17-s */
    1230          84 :             L_thr_tmp = L_shl( L_tmp, shift );                             /* Q16 */
    1231          84 :             L_thr_tmp = L_add( L_thr_tmp, lshr( lsb, sub( 16, shift ) ) ); /*Q16 */
    1232             : 
    1233          84 :             set32_fx( &L_thr[k], L_thr_tmp, HVQ_BW );
    1234          84 :             k = add( k, HVQ_BW );
    1235             : 
    1236             :             /*sharp[i] = peak/nf_mean[i]; */
    1237          84 :             Mpy_32_16_ss( L_peak, inv_nf_mean, &L_tmp, &lsb ); /* 12+33-s-15=30-s */
    1238          84 :             shift = sub( exp1, 8 );
    1239          84 :             sharp[i] = extract_h( L_shl( L_tmp, shift ) ); /* 30-s+s-8-16 -> Q6 */
    1240          84 :             move16();
    1241             : 
    1242             :             /*sharp_dist += (sharp[i]-HVQ_SHARP_THRES); */
    1243          84 :             sharp_dist = add_o( sharp_dist, sub( sharp[i], HVQ_SHARP_THRES_FX ), &Overflow );
    1244          84 :             IF( GT_16( sharp[i], HVQ_SHARP_THRES_FX ) )
    1245             :             {
    1246          47 :                 num_sharp_bands = add( num_sharp_bands, 1 );
    1247             :             }
    1248             :         }
    1249             : 
    1250             :         /* Estimate noise floor gains */
    1251          12 :         offset = s_and( nsub, 1 );
    1252          84 :         FOR( i = 0; i < ( nsub & (Word16) 0xFFFE ); i++ )
    1253             :         {
    1254             :             /*(2*i+1)/nsub */
    1255          72 :             idx = mult( add( shl( i, 1 ), 1 ), add( inv_nsub, 1 ) ); /*0+15-15 = 0 */
    1256          72 :             L_nf_gains[idx] = L_add( L_nf_gains[idx], L_nf_mean[i + offset] );
    1257          72 :             L_pe_gains[idx] = L_add( L_pe_gains[idx], L_pe_mean[i + offset] );
    1258          72 :             move32();
    1259          72 :             move32();
    1260             :         }
    1261             : 
    1262          36 :         FOR( i = 0; i < HVQ_NF_GROUPS; i++ )
    1263             :         {
    1264          24 :             Mpy_32_16_ss( L_nf_gains[i], inv_gains_nsub, &L_nf_gains[i], &lsb ); /*12+15-15=12 */
    1265          24 :             Mpy_32_16_ss( L_pe_gains[i], inv_gains_nsub, &L_pe_gains[i], &lsb ); /*12+15-15=12 */
    1266             :         }
    1267             : 
    1268             :         /* Allocate available peaks */
    1269          96 :         FOR( i = 0; i < nsub; i++ )
    1270             :         {
    1271          84 :             avail_peaks[i] = HVQ_PA_PEAKS_SHARP1;
    1272          84 :             move16();
    1273          84 :             idx = mult( add( shl( i, 1 ), 1 ), add( inv_nsub, 1 ) );      /*0+15-15 = 0 */
    1274          84 :             Mpy_32_16_ss( L_nf_gains[idx], HVQ_PA_FAC_FX, &L_tmp, &lsb ); /* 12+15-15 -> Q12 */
    1275          84 :             IF( LT_32( L_nf_mean[i], L_tmp ) )
    1276             :             {
    1277          24 :                 IF( LT_16( sharp[i], HVQ_PA_SHARP_THRES3_FX ) )
    1278             :                 {
    1279          20 :                     avail_peaks[i] = HVQ_PA_PEAKS_SHARP3;
    1280          20 :                     move16();
    1281             :                 }
    1282           4 :                 ELSE IF( LT_16( sharp[i], HVQ_PA_SHARP_THRES2_FX ) )
    1283             :                 {
    1284           2 :                     avail_peaks[i] = HVQ_PA_PEAKS_SHARP2;
    1285           2 :                     move16();
    1286             :                 }
    1287             :             }
    1288             :         }
    1289             : 
    1290             : 
    1291             :         /* Adjust threshold around previous peaks */
    1292          12 :         FOR( i = 0; i < *prev_Npeaks; i++ )
    1293             :         {
    1294           0 :             j = sub( prev_peaks[i], 2 ); /* Q0 */
    1295           0 :             k = add( prev_peaks[i], 2 ); /* Q0 */
    1296           0 :             p_adj = hvq_thr_adj_fx;      /* Q15 */
    1297           0 :             move16();
    1298             : 
    1299           0 :             FOR( q = j; q < k; q++ )
    1300             :             {
    1301           0 :                 Mpy_32_16_ss( L_thr[q], *p_adj++, &L_thr[q], &lsb ); /* 12+15-15=12 */
    1302           0 :                 move32();
    1303             :             }
    1304             :         }
    1305             : 
    1306          12 :         num_peak_cands = 0;
    1307          12 :         move16();
    1308             : 
    1309             :         /* Remove everything below threshold for peak search */
    1310          12 :         L_input_abs[0] = L_deposit_l( 0 );
    1311          12 :         L_input_abs[1] = L_deposit_l( 0 );
    1312          12 :         L_input_abs[N - 2] = L_deposit_l( 0 );
    1313          12 :         L_input_abs[N - 1] = L_deposit_l( 0 );
    1314          12 :         move32();
    1315          12 :         move32();
    1316          12 :         move32();
    1317          12 :         move32();
    1318        2676 :         FOR( i = 0; i < N - 2; i++ )
    1319             :         {
    1320        2664 :             IF( LT_32( L_input_abs[i], L_thr[i] ) )
    1321             :             {
    1322        1960 :                 L_input_abs[i] = L_deposit_l( 0 );
    1323        1960 :                 move32();
    1324             :             }
    1325             :             ELSE
    1326             :             {
    1327         704 :                 L_input_abs[num_peak_cands] = L_input_abs[i]; /* Q12 */
    1328         704 :                 move32();
    1329         704 :                 peak_cand_idx[num_peak_cands] = i; /* Q0 */
    1330         704 :                 move16();
    1331         704 :                 num_peak_cands = add( num_peak_cands, 1 );
    1332             :             }
    1333             :         }
    1334          12 :         IF( EQ_32( L_core_brate, HQ_24k40 ) )
    1335             :         {
    1336          12 :             peak_th = HVQ_MAX_PEAKS_24k_CLAS;
    1337          12 :             move16();
    1338             :         }
    1339             :         ELSE
    1340             :         {
    1341           0 :             peak_th = HVQ_MAX_PEAKS_32k;
    1342           0 :             move16();
    1343             :         }
    1344             :         /* Find peaks */
    1345          12 :         pindx = maximum_32_fx( L_input_abs, num_peak_cands, &L_m );
    1346          12 :         i = 0;
    1347          12 :         move16();
    1348             : 
    1349         300 :         WHILE( L_m > 0 && LT_16( i, peak_th + 1 ) )
    1350             :         {
    1351         288 :             idx = mult( peak_cand_idx[pindx], INV_HVQ_BW ); /* 0+15-15=0 */
    1352         288 :             IF( avail_peaks[idx] > 0 )
    1353             :             {
    1354         252 :                 peaks[i++] = peak_cand_idx[pindx]; /* Q0 */
    1355         252 :                 move16();
    1356         252 :                 avail_peaks[idx]--;
    1357             :             }
    1358             : 
    1359         288 :             j = sub( pindx, 2 );
    1360         288 :             k = add( pindx, 2 );
    1361             : 
    1362         288 :             if ( j < 0 )
    1363             :             {
    1364          14 :                 j = 0;
    1365          14 :                 move16();
    1366             :             }
    1367             : 
    1368         288 :             tmp = sub( num_peak_cands, 1 );
    1369         288 :             if ( GT_16( k, tmp ) )
    1370             :             {
    1371          14 :                 k = tmp;
    1372          14 :                 move16();
    1373             :             }
    1374             : 
    1375         288 :             low = sub( peak_cand_idx[pindx], 2 );
    1376         288 :             high = add( peak_cand_idx[pindx], 2 );
    1377             : 
    1378         288 :             if ( low < 0 )
    1379             :             {
    1380           0 :                 low = 0;
    1381           0 :                 move16();
    1382             :             }
    1383             : 
    1384         288 :             tmp = sub( N, 1 );
    1385         288 :             IF( GT_16( high, tmp ) )
    1386             :             {
    1387           0 :                 high = tmp;
    1388           0 :                 move16();
    1389             :             }
    1390             : 
    1391        1129 :             FOR( q = j; q <= pindx; q++ )
    1392             :             {
    1393         841 :                 IF( GE_16( peak_cand_idx[q], low ) )
    1394             :                 {
    1395         440 :                     peak_cand_idx[q] = 0;
    1396         440 :                     move16();
    1397         440 :                     L_input_abs[q] = 0;
    1398         440 :                     move16();
    1399             :                 }
    1400             :             }
    1401             : 
    1402         840 :             FOR( q = pindx + 1; q <= k; q++ )
    1403             :             {
    1404         552 :                 IF( LE_16( peak_cand_idx[q], high ) )
    1405             :                 {
    1406         355 :                     peak_cand_idx[q] = 0;
    1407         355 :                     move16();
    1408         355 :                     L_input_abs[q] = 0;
    1409         355 :                     move16();
    1410             :                 }
    1411             :             }
    1412             : 
    1413         288 :             pindx = maximum_32_fx( L_input_abs, num_peak_cands, &L_m ); /* Q0 */
    1414             :         }
    1415             : 
    1416          12 :         *Npeaks = i;
    1417          12 :         move16();
    1418          12 :         IF( GT_16( *Npeaks, HVQ_MIN_PEAKS ) )
    1419             :         {
    1420          12 :             test();
    1421          12 :             IF( GT_16( num_sharp_bands, sub( nsub, 3 ) ) && LE_16( *Npeaks, peak_th ) )
    1422             :             {
    1423           0 :                 sharp_dist = mult( sharp_dist, inv_nsub ); /*x+15-15=x */
    1424           0 :                 test();
    1425           0 :                 IF( LE_16( sharp_dist, SHARP_DIST_THRES_FX ) && *hvq_hangover < 0 )
    1426             :                 {
    1427           0 :                     *hvq_hangover = add( *hvq_hangover, 1 );
    1428             :                 }
    1429             :                 ELSE
    1430             :                 {
    1431           0 :                     *hqswb_clas = HQ_HVQ; /* Q0 */
    1432           0 :                     move16();
    1433           0 :                     *hvq_hangover = 2; /* Q0 */
    1434           0 :                     move16();
    1435             :                 }
    1436             : 
    1437             :                 /* update memory */
    1438           0 :                 *prev_Npeaks = *Npeaks; /* Q0 */
    1439           0 :                 move16();
    1440           0 :                 Copy( peaks, prev_peaks, *Npeaks ); /* Q0 */
    1441             :             }
    1442             :             ELSE
    1443             :             {
    1444          12 :                 IF( *hvq_hangover > 0 )
    1445             :                 {
    1446           0 :                     *hqswb_clas = HQ_HVQ; /* Q0 */
    1447           0 :                     move16();
    1448           0 :                     *hvq_hangover = sub( *hvq_hangover, 1 ); /* Q0 */
    1449           0 :                     move16();
    1450             :                 }
    1451             :                 ELSE
    1452             :                 {
    1453          12 :                     *hvq_hangover = -1;
    1454          12 :                     move16();
    1455             :                 }
    1456             :             }
    1457             :         }
    1458             :         ELSE
    1459             :         {
    1460             :             /* Zero peaks, likely silence input. */
    1461           0 :             *hvq_hangover = -1;
    1462           0 :             move16();
    1463             :         }
    1464             : 
    1465          12 :         IF( EQ_32( L_core_brate, HQ_24k40 ) )
    1466             :         {
    1467          12 :             *Npeaks = s_min( HVQ_MAX_PEAKS_24k, *Npeaks ); /* Q0 */
    1468          12 :             move16();
    1469             :         }
    1470             :         ELSE
    1471             :         {
    1472           0 :             *Npeaks = s_min( HVQ_MAX_PEAKS_32k, *Npeaks ); /* Q0 */
    1473           0 :             move16();
    1474             :         }
    1475             :     }
    1476             :     ELSE
    1477             :     {
    1478          32 :         *prev_Npeaks = 0;
    1479          32 :         move16();
    1480          32 :         *hvq_hangover = 0;
    1481          32 :         move16();
    1482             :     }
    1483             : 
    1484             : 
    1485          44 :     return;
    1486             : }

Generated by: LCOV version 1.14