LCOV - code coverage report
Current view: top level - lib_enc - hq_classifier_enc_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main @ 43b7b28dcb1471ff5d355252c4b8f37ee7ecc268 Lines: 651 724 89.9 %
Date: 2025-11-02 02:02:47 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             : 
       5             : #include <stdint.h>
       6             : #include "options.h"     /* Compilation switches                   */
       7             : #include "cnst.h"        /* Common constants                       */
       8             : #include "rom_com.h"     /* Static table prototypes                */
       9             : #include "prot_fx.h"     /* Function prototypes                    */
      10             : #include "prot_fx_enc.h" /* Function prototypes                    */
      11             : 
      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( Encoder_State *st, const Word32 *coefs_fx );
      32             : 
      33             : 
      34             : /*--------------------------------------------------------------------------*
      35             :  * hf_spectrum_sparseness()
      36             :  *
      37             :  * Detection of sparse spectrum in high band for activation of harmonic
      38             :  * modes HQ_HARMONIC and HQ_HVQ
      39             :  *--------------------------------------------------------------------------*/
      40             : 
      41             : /*! r: Harmonic decision for high band */
      42        6696 : 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        6696 :     Word16 inv_rms32_e = 0;
      64        6696 :     move16();
      65             : 
      66        6696 :     crest_lp_fx = &st->hHQ_core->crest_lp_fx;         /* &st->hHQ_core->crest_lp_q */
      67        6696 :     crest_mod_lp_fx = &st->hHQ_core->crest_mod_lp_fx; /* &st->hHQ_core->crest_mod_lp_q */
      68             : 
      69        6696 :     result = TRUE;
      70        6696 :     move16();
      71        6696 :     IF( st->element_mode != EVS_MONO )
      72             :     {
      73             : 
      74     2149416 :         FOR( i = 0; i < L_SPEC_HB; i++ )
      75             :         {
      76     2142720 :             A_fx[i] = L_abs( coefs_fx[i + L_SPEC_HB] ); /* Q12 */
      77     2142720 :             move32();
      78             :         }
      79        6696 :         low_count_fx = 0;
      80        6696 :         move16();
      81        6696 :         inv_rms_fx = 0;
      82        6696 :         move64();
      83        6696 :         crest_mod_fx = 0;
      84        6696 :         move32();
      85        6696 :         maximum_l( A_fx, L_SPEC_HB, &Amax_fx );
      86        6696 :         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        6696 :             thr_fx = Mpy_32_32( Amax_fx, PEAK_THRESHOLD_FX ); /* Q12 */
      97        6696 :             movmean_fx = 0;                                   /* avoid uninitialized warning */
      98        6696 :             move32();
      99             :             // p_num = &inv_tbl[HALF_WIN_LENGTH + 1];       /* Table for division 1./(11:21) */
     100        6696 :             p_num_fx = &inv_tbl_fx[HALF_WIN_LENGTH + 1]; /* Table for division 1./(11:21) Q15*/
     101     2149416 :             FOR( i = 0; i < L_SPEC_HB; i++ )
     102             :             {
     103             :                 // inv_rms += A[i] * A[i];
     104     2142720 :                 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     2142720 :                 IF( LT_32( A_fx[i], thr_fx ) )
     107             :                 {
     108     1361061 :                     low_count_fx = add( low_count_fx, 1 );
     109             :                 }
     110     2142720 :                 IF( LE_16( i, HALF_WIN_LENGTH ) )
     111             :                 {
     112       73656 :                     IF( i == 0 )
     113             :                     {
     114        6696 :                         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       66960 :                         p_num_fx++;
     120       66960 :                         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     2069064 :                     IF( LE_16( L_SPEC_HB, i + HALF_WIN_LENGTH ) )
     126             :                     {
     127             : 
     128       66960 :                         p_num_fx--;
     129       66960 :                         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     2002104 :                         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     2142720 :                 IF( LT_32( crest_mod_fx, movmean_fx ) )
     138             :                 {
     139       89145 :                     crest_mod_fx = movmean_fx; // Q12
     140       89145 :                     move32();
     141             :                 }
     142             :             }
     143        6696 :             Word16 l_shift = W_norm( inv_rms_fx );
     144        6696 :             inv_rms32_fx = W_extract_h( W_shl( inv_rms_fx, l_shift ) );                                     // Q15+l_shift-32
     145        6696 :             Word16 q_rms = sub( add( Q15, l_shift ), 32 );                                                  // q_rms
     146        6696 :             inv_rms32_div_fx = BASOP_Util_Divide3232_Scale_newton( inv_rms32_fx, L_SPEC_HB, &inv_rms32_e ); /* Q31-inv_rms32_e */
     147        6696 :             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        6696 :             inv_rms32_fx = ISqrt32( inv_rms32_div_fx, &inv_rms32_e ); /* Q31-inv_rms32_e */
     150             : 
     151        6696 :             crest_fx = Mpy_32_32( Amax_fx, inv_rms32_fx );                                                  // Q12 + (Q31-inv_rms32_e) -Q31 = Q12 - inv_rms32_e
     152        6696 :             crest_mod_fx = Mpy_32_32( crest_mod_fx, inv_rms32_fx );                                         // Q12 + (Q31-inv_rms32_e) -Q31 = Q12 - inv_rms32_e
     153        6696 :             *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        6696 :             move32();
     155        6696 :             st->hHQ_core->crest_lp_q = sub( Q12, inv_rms32_e );
     156        6696 :             move16();
     157        6696 :             *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        6696 :             move32();
     159        6696 :             st->hHQ_core->crest_mod_lp_q = sub( Q12, inv_rms32_e );
     160        6696 :             move16();
     161             :         }
     162        6696 :         *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        6696 :         move32();
     164        6696 :         *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        6696 :         move32();
     166             : 
     167        6696 :         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        6696 :         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        6696 :         test();
     170        6696 :         test();
     171        6696 :         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        6696 :     return result; /* Q0 */
     179             : }
     180             : /*--------------------------------------------------------------------------*
     181             :  * hq_classifier_enc_fx()
     182             :  *
     183             :  * HQ mode selector (decision_matrix)
     184             :  *--------------------------------------------------------------------------*/
     185         392 : 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         392 :     HQ_ENC_HANDLE hHQ_core = st_fx->hHQ_core;
     199             : 
     200         392 :     *hqswb_clas = HQ_NORMAL;
     201         392 :     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         392 :     test();
     209         392 :     test();
     210         392 :     test();
     211         392 :     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          66 :         *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          66 :         move16();
     216             : 
     217             :         /* Detect harmonic VQ mode HQ_HVQ */
     218          66 :         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         392 :     test();
     223         392 :     test();
     224         392 :     test();
     225         392 :     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         392 :     test();
     236         392 :     test();
     237         392 :     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         392 :     test();
     244         392 :     IF( GE_16( length, L_FRAME32k ) && LE_32( st_fx->core_brate, HQ_32k ) )
     245             :     {
     246          66 :         bits = 2;
     247          66 :         move16();
     248             :     }
     249             :     ELSE
     250             :     {
     251         326 :         bits = 1;
     252         326 :         move16();
     253             :     }
     254             : 
     255         392 :     test();
     256         392 :     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         392 :         push_indice( st_fx->hBstr, IND_HQ_SWB_CLAS, *hqswb_clas, bits );
     270             :     }
     271             : 
     272         392 :     test();
     273         392 :     test();
     274         392 :     IF( EQ_16( *hqswb_clas, HQ_NORMAL ) && EQ_16( length, L_FRAME32k ) && LE_32( st_fx->core_brate, HQ_32k ) )
     275             :     {
     276          46 :         *hqswb_clas = HQ_GEN_SWB; /* Q0 */
     277          46 :         move16();
     278             :     }
     279             : 
     280         392 :     return bits;
     281             : }
     282        7801 : 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        7801 :     HQ_ENC_HANDLE hHQ_core = st_fx->hHQ_core;
     298             :     Word32 max_brate;
     299             :     Word16 harmonic_decision;
     300             : 
     301             : 
     302        7801 :     max_brate = HQ_32k;
     303        7801 :     move32();
     304             : 
     305        7801 :     if ( st_fx->element_mode > EVS_MONO )
     306             :     {
     307        7801 :         max_brate = HQ_48k;
     308        7801 :         move32();
     309             :     }
     310             : 
     311        7801 :     *hqswb_clas = HQ_NORMAL; /* Q0 */
     312        7801 :     bits = 1;
     313        7801 :     move16();
     314        7801 :     IF( EQ_16( is_transient, 1 ) )
     315             :     {
     316         460 :         *hqswb_clas = HQ_TRANSIENT; /* Q0 */
     317         460 :         move16();
     318             :     }
     319             : 
     320             :     /* classification and limit bandwidth for bit allocation */
     321        7801 :     test();
     322        7801 :     IF( EQ_16( length, L_SPEC32k ) || EQ_16( length, L_SPEC48k ) )
     323             :     {
     324        7156 :         IF( LE_32( st_fx->core_brate, max_brate ) )
     325             :         {
     326        7156 :             test();
     327        7156 :             IF( !is_transient && EQ_16( st_fx->bwidth, st_fx->last_bwidth ) )
     328             :             {
     329             :                 /* Detect HQ_HARMONIC mode */
     330        6696 :                 *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        6696 :                 harmonic_decision = hf_spectrum_sparseness_fx( st_fx, coefs );
     333             : 
     334             : 
     335        6696 :                 test();
     336        6696 :                 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        6696 :                     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        7156 :             bits = 2;
     348        7156 :             move16();
     349             :         }
     350             :     }
     351         645 :     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        7801 :     push_indice( st_fx->hBstr, IND_HQ_SWB_CLAS, *hqswb_clas, bits );
     358             : 
     359        7801 :     IF( LE_32( st_fx->core_brate, HQ_32k ) && EQ_16( *hqswb_clas, HQ_NORMAL ) )
     360             :     {
     361        3285 :         IF( EQ_16( length, L_SPEC32k ) )
     362             :         {
     363         605 :             *hqswb_clas = HQ_GEN_SWB; /* Q0 */
     364         605 :             move16();
     365             :         }
     366        2680 :         ELSE IF( EQ_16( length, L_SPEC48k ) )
     367             :         {
     368        2210 :             *hqswb_clas = HQ_GEN_FB; /* Q0 */
     369        2210 :             move16();
     370             :         }
     371             :     }
     372             : 
     373        7801 :     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        6696 : 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     3649320 :     FOR( i = 96; i < length; i++ )
     394             :     {
     395     3642624 :         input_abs_fx[i] = L_abs( input_hi_fx[i] );
     396     3642624 :         move32();
     397             :     }
     398             : 
     399        6696 :     hqswb_clas = HQ_NORMAL;
     400        6696 :     move16();
     401        6696 :     peak_th_fx = L_shl( 10L, sub( Q_coeff, 5 ) ); /* 5 is safe shift */
     402             : 
     403        6696 :     k = 0;
     404        6696 :     move16();
     405        6696 :     k1 = 0;
     406        6696 :     move16();
     407        6696 :     q = 96; /* q used for indexing */
     408        6696 :     move16();
     409             : 
     410      100440 :     FOR( i = 3; i < 17; i++ )
     411             :     {
     412       93744 :         peak_fx = L_deposit_l( 0 );
     413       93744 :         mean_fx = L_deposit_l( 1 );
     414             : 
     415             :         /*for(j = 0; j < 32; j ++, q ++) */
     416     3093552 :         FOR( j = 0; j < 32; j++ )
     417             :         {
     418     2999808 :             input_abs_fx[q] = L_shr( input_abs_fx[q], 5 ); /*Q_coeff-5 */
     419     2999808 :             move32();
     420     2999808 :             mean_fx = L_add( mean_fx, input_abs_fx[q] ); /*Q_coeff-5 */
     421     2999808 :             if ( GT_32( input_abs_fx[q], peak_fx ) )
     422             :             {
     423      414179 :                 peak_fx = input_abs_fx[q]; /*Q_coeff-5 */
     424      414179 :                 move32();
     425             :             }
     426     2999808 :             q += 1;
     427             :         }
     428             : 
     429       93744 :         IF( LT_16( i, 8 ) )
     430             :         {
     431       33480 :             if ( GT_32( peak_fx, Mult_32_16( mean_fx, 4608 ) ) ) /* Q15 0.140625 */
     432             :             {
     433       22413 :                 k = add( k, 1 );
     434             :             }
     435             :         }
     436             :         ELSE
     437             :         {
     438       60264 :             test();
     439       60264 :             if ( GT_32( peak_fx, Mult_32_16( mean_fx, 3686 ) ) /*Q15 0.1125 */
     440       25829 :                  && GT_32( peak_fx, peak_th_fx ) )             /*Q27 10 */
     441             :             {
     442       22366 :                 k1 = add( k1, 1 );
     443             :             }
     444             :         }
     445             :     }
     446             : 
     447        6696 :     test();
     448        6696 :     IF( GE_16( add( k, k1 ), 10 ) && GT_16( k1, 5 ) )
     449             :     {
     450        1699 :         IF( LT_16( *mode_count, 8 ) )
     451             :         {
     452        1699 :             *mode_count = add( *mode_count, 1 );
     453        1699 :             move16();
     454             :         }
     455             : 
     456        1699 :         IF( *mode_count1 > 0 )
     457             :         {
     458           0 :             *mode_count1 = sub( *mode_count1, 1 );
     459           0 :             move16();
     460             :         }
     461             :     }
     462             :     ELSE
     463             :     {
     464        4997 :         IF( LT_16( *mode_count1, 8 ) )
     465             :         {
     466        4997 :             *mode_count1 = add( *mode_count1, 1 );
     467        4997 :             move16();
     468             :         }
     469             : 
     470        4997 :         IF( *mode_count > 0 )
     471             :         {
     472           0 :             *mode_count = sub( *mode_count, 1 );
     473           0 :             move16();
     474             :         }
     475             :     }
     476             : 
     477        6696 :     test();
     478        6696 :     test();
     479        6696 :     test();
     480        6696 :     test();
     481        6696 :     test();
     482        6696 :     test();
     483             : 
     484        6696 :     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        2258 :         hqswb_clas = HQ_HARMONIC;
     487        2258 :         move16();
     488             :     }
     489        6696 :     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         104 : 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       53032 :     FOR( i = 96; i < length; i++ )
     510             :     {
     511       52928 :         input_abs_fx[i] = L_abs( input_hi_fx[i] ); /* Q_coeff */
     512             :     }
     513             : 
     514         104 :     hqswb_clas = HQ_NORMAL;
     515         104 :     move16();
     516         104 :     peak_th_fx = L_shl( 10L, sub( Q_coeff, 5 ) ); /* 5 is safe shift */
     517             : 
     518         104 :     k = 0;
     519         104 :     move16();
     520         104 :     k1 = 0;
     521         104 :     move16();
     522         104 :     q = 96; /* q used for indexing */
     523         104 :     move16();
     524             : 
     525        1560 :     FOR( i = 3; i < 17; i++ )
     526             :     {
     527        1456 :         peak_fx = L_deposit_l( 0 );
     528        1456 :         mean_fx = L_deposit_l( 1 );
     529             : 
     530             :         /*for(j = 0; j < 32; j ++, q ++) */
     531       48048 :         FOR( j = 0; j < 32; j++ )
     532             :         {
     533       46592 :             input_abs_fx[q] = L_shr( input_abs_fx[q], 5 ); /*Q_coeff-5 */
     534       46592 :             move32();
     535       46592 :             mean_fx = L_add( mean_fx, input_abs_fx[q] ); /*Q_coeff-5 */
     536       46592 :             if ( GT_32( input_abs_fx[q], peak_fx ) )
     537             :             {
     538        6130 :                 peak_fx = input_abs_fx[q]; /*Q_coeff-5 */
     539        6130 :                 move32();
     540             :             }
     541       46592 :             q += 1;
     542             :         }
     543             : 
     544        1456 :         IF( LT_16( i, 8 ) )
     545             :         {
     546         520 :             if ( GT_32( peak_fx, Mult_32_16( mean_fx, 4608 ) ) ) /* Q15 0.140625 */
     547             :             {
     548          96 :                 k = add( k, 1 );
     549             :             }
     550             :         }
     551             :         ELSE
     552             :         {
     553         936 :             test();
     554         936 :             if ( GT_32( peak_fx, Mult_32_16( mean_fx, 3686 ) ) /*Q15 0.1125 */
     555         234 :                  && GT_32( peak_fx, peak_th_fx ) )             /*Q27 10 */
     556             :             {
     557         216 :                 k1 = add( k1, 1 );
     558             :             }
     559             :         }
     560             :     }
     561             : 
     562         104 :     test();
     563         104 :     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         104 :         IF( LT_16( *mode_count1, 8 ) )
     580             :         {
     581          91 :             *mode_count1 = add( *mode_count1, 1 );
     582          91 :             move16();
     583             :         }
     584             : 
     585         104 :         IF( *mode_count > 0 )
     586             :         {
     587           0 :             *mode_count = sub( *mode_count, 1 );
     588           0 :             move16();
     589             :         }
     590             :     }
     591             : 
     592         104 :     test();
     593         104 :     test();
     594         104 :     test();
     595         104 :     test();
     596         104 :     test();
     597         104 :     test();
     598             : 
     599         104 :     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          20 :         hqswb_clas = HQ_HARMONIC;
     602          20 :         move16();
     603             :     }
     604             : 
     605         104 :     return hqswb_clas; /* Q0 */
     606             : }
     607             : 
     608             : /*--------------------------------------------------------------------------*
     609             :  * hvq_classifier()
     610             :  *
     611             :  * Classification of harmonic low band content for Harmonic VQ
     612             :  *--------------------------------------------------------------------------*/
     613        6696 : 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        6696 :     Word16 temp_e = 0;
     656        6696 :     move16();
     657             : 
     658        6696 :     L_input_max = L_deposit_l( 0 );
     659        6696 :     set32_fx( L_thr, 0, L_FRAME16k );
     660             : 
     661        6696 :     IF( LT_32( L_core_brate, HQ_BWE_CROSSOVER_BRATE ) )
     662             :     {
     663        2654 :         nsub = HVQ_NSUB_24k;
     664        2654 :         move16();
     665        2654 :         inv_nsub = 4681; /* 1/7 in Q15 */
     666        2654 :         move16();
     667        2654 :         inv_gains_nsub = 10923; /* 1/3 in Q15 */
     668        2654 :         move16();
     669             :     }
     670             :     ELSE
     671             :     {
     672        4042 :         nsub = HVQ_NSUB_32k;
     673        4042 :         move16();
     674        4042 :         inv_nsub = 3277; /* 1/10 in Q15 */
     675        4042 :         move16();
     676        4042 :         inv_gains_nsub = 6554; /* 1/5 in Q15 */
     677        4042 :         move16();
     678             :     }
     679             : 
     680        6696 :     N = shl( nsub, 5 ); /* Mult by 32 (HVQ_BW) */
     681             : 
     682        6696 :     test();
     683        6696 :     test();
     684        6696 :     IF( EQ_16( *hqswb_clas, HQ_HARMONIC ) && last_core != ACELP_CORE && NE_16( last_core, AMR_WB_CORE ) )
     685        2228 :     {
     686      597300 :         FOR( i = 0; i < N; i++ )
     687             :         {
     688      595072 :             L_input_abs[i] = L_abs( input[i] ); /* Q12 */
     689      595072 :             move16();
     690      595072 :             IF( GT_32( L_input_abs[i], L_input_max ) )
     691             :             {
     692       13556 :                 L_input_max = L_input_abs[i]; /* Q12 */
     693       13556 :                 move16();
     694             :             }
     695             :         }
     696             : 
     697        2228 :         exp1 = norm_l( L_input_max );
     698             : 
     699        2228 :         *Npeaks = 0;
     700        2228 :         move16();
     701        2228 :         L_nf = 3276800; /* 800 in Q12 */
     702        2228 :         move32();
     703        2228 :         L_pe = 3276800; /* 800 in Q12    */
     704        2228 :         move32();
     705        2228 :         num_sharp_bands = 0;
     706        2228 :         move16();
     707        2228 :         k = 0;
     708        2228 :         move16();
     709        2228 :         q = 0;
     710        2228 :         move16();
     711        2228 :         sharp_dist = 0;
     712        2228 :         move16();
     713             : 
     714             :         /* Find peak threshold */
     715       20824 :         FOR( i = 0; i < nsub; i++ )
     716             :         {
     717       18596 :             L_peak = 0;
     718       18596 :             L_nf_mean[i] = 0;
     719       18596 :             L_pe_mean[i] = 0;
     720       18596 :             move32();
     721       18596 :             move32();
     722       18596 :             move32();
     723             : 
     724      613668 :             FOR( j = 0; j < HVQ_BW; j++ )
     725             :             {
     726      595072 :                 L_d = L_input_abs[q]; /* Q12 */
     727      595072 :                 IF( GT_32( L_d, L_nf ) )
     728             :                 {
     729             :                     /*nf = HVQ_NF_WEIGHT1 * nf + (1 - HVQ_NF_WEIGHT1) * d; */
     730      317930 :                     Mpy_32_16_ss( L_d, HVQ_NF_WEIGHT1B, &L_tmp, &lsb );   /* 12+15-15=12 */
     731      317930 :                     Mpy_32_16_ss( L_nf, HVQ_NF_WEIGHT1_FX, &L_nf, &lsb ); /* 12+15-15=12 */
     732      317930 :                     L_nf = L_add( L_nf, L_tmp );                          /*Q12 */
     733             :                 }
     734             :                 ELSE
     735             :                 {
     736             :                     /*nf = HVQ_NF_WEIGHT2 * nf + (1 - HVQ_NF_WEIGHT2) * d; */
     737      277142 :                     Mpy_32_16_ss( L_d, HVQ_NF_WEIGHT2B, &L_tmp, &lsb );   /* 12+15-15=12 */
     738      277142 :                     Mpy_32_16_ss( L_nf, HVQ_NF_WEIGHT2_FX, &L_nf, &lsb ); /* 12+15-15=12 */
     739      277142 :                     L_nf = L_add( L_nf, L_tmp );                          /*Q12 */
     740             :                 }
     741             : 
     742      595072 :                 IF( GT_32( L_d, L_pe ) )
     743             :                 {
     744             :                     /*pe = HVQ_PE_WEIGHT1 * pe + (1 - HVQ_PE_WEIGHT1) * d; */
     745      118938 :                     Mpy_32_16_ss( L_d, HVQ_PE_WEIGHT1B, &L_tmp, &lsb );   /* 12+15-15=12 */
     746      118938 :                     Mpy_32_16_ss( L_pe, HVQ_PE_WEIGHT1_FX, &L_pe, &lsb ); /* 12+15-15=12 */
     747      118938 :                     L_pe = L_add( L_pe, L_tmp );                          /*Q12 */
     748             :                 }
     749             :                 ELSE
     750             :                 {
     751             :                     /*pe = HVQ_PE_WEIGHT2 * pe + (1 - HVQ_PE_WEIGHT2) * d; */
     752      476134 :                     Mpy_32_16_ss( L_d, HVQ_PE_WEIGHT2B, &L_tmp, &lsb );   /* 12+15-15=12 */
     753      476134 :                     Mpy_32_16_ss( L_pe, HVQ_PE_WEIGHT2_FX, &L_pe, &lsb ); /* 12+15-15=12 */
     754      476134 :                     L_pe = L_add( L_pe, L_tmp );                          /*Q12 */
     755             :                 }
     756             : 
     757      595072 :                 L_nf_mean[i] = L_add_sat( L_nf_mean[i], L_nf ); /*Q12 */
     758      595072 :                 L_pe_mean[i] = L_add_sat( L_pe_mean[i], L_pe ); /*Q12 */
     759      595072 :                 move32();
     760      595072 :                 move32();
     761      595072 :                 IF( GT_32( L_d, L_peak ) )
     762             :                 {
     763       89235 :                     L_peak = L_add( L_d, 0 );
     764             :                 }
     765             : 
     766      595072 :                 q += 1;
     767             :             }
     768       18596 :             L_nf_mean[i] = L_shr( L_nf_mean[i], 5 ); /* Divide by 5 (HVQ_BW) */
     769       18596 :             L_pe_mean[i] = L_shr( L_pe_mean[i], 5 ); /* Divide by 5 (HVQ_BW) */
     770       18596 :             move32();
     771       18596 :             move32();
     772             :             /*thr_tmp = (float)pow( pe_mean[i]/nf_mean[i], HVQ_THR_POW ) * nf_mean[i]; */
     773       18596 :             exp1 = norm_l( L_nf_mean[i] );
     774       18596 :             nf_mean_norm = extract_h( L_shl( L_nf_mean[i], exp1 ) ); /* 12+s-16=s-4 */
     775       18596 :             IF( nf_mean_norm == 0 )
     776             :             {
     777           0 :                 inv_nf_mean = 0;
     778             :             }
     779             :             ELSE
     780             :             {
     781       18596 :                 inv_nf_mean = div_s( 1 << 14, nf_mean_norm ); /* 15+14-s+4=33-s */
     782             :             }
     783       18596 :             Mpy_32_16_ss( L_pe_mean[i], inv_nf_mean, &L_tmp, &lsb ); /*12+33-s-15=30-s */
     784             : 
     785       18596 :             exp2 = norm_l( L_tmp );
     786       18596 :             tmp = Log2_norm_lc( L_shl( L_tmp, exp2 ) ); /* Q15 */
     787       18596 :             exp2 = sub( exp1, exp2 );                   /* Q0 */
     788       18596 :             L_tmp = Mpy_32_16( exp2, tmp, 32767 );      /* 1 in Q15. Q16 */
     789       18596 :             Mpy_32_16_ss( L_tmp, 28836, &L_tmp, &lsb ); /* 16+15-15=16 */
     790       18596 :             frac = L_Extract_lc( L_tmp, &tmp );         /* Q15 and Q0 */
     791       18596 :             L_tmp = Pow2( 14, frac );                   /* Q14 */
     792       18596 :             L_tmp = L_shl( L_tmp, tmp );                /* Q14 */
     793             : 
     794       18596 :             Mpy_32_16_ss( L_tmp, nf_mean_norm, &L_tmp, &lsb );             /*14+s-4-15=s-5 */
     795       18596 :             shift = sub( 17, exp1 );                                       /* 16-(s-5)=17-s */
     796       18596 :             L_thr_tmp = L_shl( L_tmp, shift );                             /* Q16 */
     797       18596 :             L_thr_tmp = L_add( L_thr_tmp, lshr( lsb, sub( 16, shift ) ) ); /*Q16 */
     798             : 
     799       18596 :             set32_fx( &L_thr[k], L_thr_tmp, HVQ_BW );
     800       18596 :             k = add( k, HVQ_BW );
     801             : 
     802             :             /*sharp[i] = peak/nf_mean[i]; */
     803       18596 :             Mpy_32_16_ss( L_peak, inv_nf_mean, &L_tmp, &lsb ); /* 12+33-s-15=30-s */
     804       18596 :             shift = sub( exp1, 8 );
     805       18596 :             sharp[i] = extract_h( L_shl( L_tmp, shift ) ); /* 30-s+s-8-16 -> Q6 */
     806       18596 :             move16();
     807             :             /*sharp_dist += (sharp[i]-HVQ_SHARP_THRES); */
     808       18596 :             sharp_dist = add_sat( sharp_dist, sub( sharp[i], HVQ_SHARP_THRES_FX ) ); /* Q6 */
     809       18596 :             if ( GT_16( sharp[i], HVQ_SHARP_THRES_FX ) )
     810             :             {
     811       16013 :                 num_sharp_bands = add( num_sharp_bands, 1 );
     812             :             }
     813             :         }
     814             : 
     815             :         /* Estimate noise floor gains */
     816        2228 :         offset = s_and( nsub, 1 );
     817       19596 :         FOR( i = 0; i < ( nsub & (Word16) 0xFFFE ); i++ )
     818             :         {
     819             :             /*(2*i+1)/nsub */
     820       17368 :             idx = mult( add( shl( i, 1 ), 1 ), add( inv_nsub, 1 ) );           /*0+15-15 = 0 */
     821       17368 :             L_nf_gains[idx] = L_add( L_nf_gains[idx], L_nf_mean[i + offset] ); /* Q12 */
     822       17368 :             L_pe_gains[idx] = L_add( L_pe_gains[idx], L_pe_mean[i + offset] ); /* Q12 */
     823       17368 :             move32();
     824       17368 :             move32();
     825             :         }
     826             : 
     827        6684 :         FOR( i = 0; i < HVQ_NF_GROUPS; i++ )
     828             :         {
     829        4456 :             Mpy_32_16_ss( L_nf_gains[i], inv_gains_nsub, &L_nf_gains[i], &lsb ); /*12+15-15=12 */
     830        4456 :             Mpy_32_16_ss( L_pe_gains[i], inv_gains_nsub, &L_pe_gains[i], &lsb ); /*12+15-15=12 */
     831             :         }
     832             : 
     833             :         /* Allocate available peaks */
     834       20824 :         FOR( i = 0; i < nsub; i++ )
     835             :         {
     836       18596 :             avail_peaks[i] = HVQ_PA_PEAKS_SHARP1; /* Q0 */
     837       18596 :             move16();
     838       18596 :             idx = mult( add( shl( i, 1 ), 1 ), add( inv_nsub, 1 ) );      /*0+15-15 = 0 */
     839       18596 :             Mpy_32_16_ss( L_nf_gains[idx], HVQ_PA_FAC_FX, &L_tmp, &lsb ); /* 12+15-15 -> Q12 */
     840       18596 :             IF( LT_32( L_nf_mean[i], L_tmp ) )
     841             :             {
     842        6684 :                 IF( LT_16( sharp[i], HVQ_PA_SHARP_THRES3_FX ) )
     843             :                 {
     844        1487 :                     avail_peaks[i] = HVQ_PA_PEAKS_SHARP3; /* Q0 */
     845        1487 :                     move16();
     846             :                 }
     847        5197 :                 ELSE IF( LT_16( sharp[i], HVQ_PA_SHARP_THRES2_FX ) )
     848             :                 {
     849         673 :                     avail_peaks[i] = HVQ_PA_PEAKS_SHARP2; /* Q0 */
     850         673 :                     move16();
     851             :                 }
     852             :             }
     853             :         }
     854             : 
     855             : 
     856             :         /* Adjust threshold around previous peaks */
     857       27058 :         FOR( i = 0; i < *prev_Npeaks; i++ )
     858             :         {
     859       24830 :             j = sub( prev_peaks[i], 2 ); /* Q0 */
     860       24830 :             k = add( prev_peaks[i], 2 ); /* Q0 */
     861       24830 :             p_adj = hvq_thr_adj_fx;      /* Q15 */
     862             : 
     863      124150 :             FOR( q = j; q < k; q++ )
     864             :             {
     865       99320 :                 Mpy_32_16_ss( L_thr[q], *p_adj++, &L_thr[q], &lsb ); /* 12+15-15=12 */
     866       99320 :                 move32();
     867             :             }
     868             :         }
     869             : 
     870        2228 :         num_peak_cands = 0;
     871        2228 :         move16();
     872             : 
     873             :         /* Remove everything below threshold for peak search */
     874        2228 :         L_input_abs[0] = L_deposit_l( 0 );
     875        2228 :         L_input_abs[1] = L_deposit_l( 0 );
     876        2228 :         L_input_abs[N - 2] = L_deposit_l( 0 );
     877        2228 :         L_input_abs[N - 1] = L_deposit_l( 0 );
     878        2228 :         move32();
     879        2228 :         move32();
     880        2228 :         move32();
     881        2228 :         move32();
     882      592844 :         FOR( i = 0; i < N - 2; i++ )
     883             :         {
     884      590616 :             IF( LT_32( L_input_abs[i], L_thr[i] ) )
     885             :             {
     886      481953 :                 L_input_abs[i] = L_deposit_l( 0 );
     887             : 
     888      481953 :                 move32();
     889             :             }
     890             :             ELSE
     891             :             {
     892      108663 :                 L_input_abs[num_peak_cands] = L_input_abs[i]; /* Q12 */
     893      108663 :                 move32();
     894      108663 :                 peak_cand_idx[num_peak_cands] = i; /* Q0 */
     895      108663 :                 move16();
     896      108663 :                 num_peak_cands = add( num_peak_cands, 1 );
     897             :             }
     898             :         }
     899             : 
     900             : 
     901        2228 :         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 ) );
     902        2228 :         peak_th = shr( peak_th, sub( 15, temp_e ) );
     903             :         /* Find peaks */
     904        2228 :         pindx = maximum_32_fx( L_input_abs, num_peak_cands, &L_m );
     905        2228 :         i = 0;
     906        2228 :         move16();
     907             : 
     908       46676 :         WHILE( L_m > 0 && LT_16( i, peak_th + 1 ) )
     909             :         {
     910       44448 :             idx = mult( peak_cand_idx[pindx], INV_HVQ_BW ); /* 0+15-15=0 */
     911       44448 :             IF( avail_peaks[idx] > 0 )
     912             :             {
     913       43425 :                 peaks[i++] = peak_cand_idx[pindx]; /* Q0 */
     914       43425 :                 avail_peaks[idx]--;
     915             :             }
     916             : 
     917       44448 :             j = sub( pindx, 2 );
     918       44448 :             k = add( pindx, 2 );
     919             : 
     920       44448 :             if ( j < 0 )
     921             :             {
     922        2165 :                 j = 0;
     923        2165 :                 move16();
     924             :             }
     925             : 
     926       44448 :             tmp = sub( num_peak_cands, 1 );
     927       44448 :             if ( GT_16( k, tmp ) )
     928             :             {
     929        1559 :                 k = tmp;
     930        1559 :                 move16();
     931             :             }
     932             : 
     933       44448 :             low = sub( peak_cand_idx[pindx], 2 );
     934       44448 :             high = add( peak_cand_idx[pindx], 2 );
     935             : 
     936       44448 :             if ( low < 0 )
     937             :             {
     938           0 :                 low = 0;
     939           0 :                 move16();
     940             :             }
     941             : 
     942       44448 :             tmp = sub( N, 1 );
     943       44448 :             if ( GT_16( high, tmp ) )
     944             :             {
     945           0 :                 high = tmp;
     946           0 :                 move16();
     947             :             }
     948             : 
     949      174331 :             FOR( q = j; q <= pindx; q++ )
     950             :             {
     951      129883 :                 IF( GE_16( peak_cand_idx[q], low ) )
     952             :                 {
     953       73442 :                     peak_cand_idx[q] = 0;
     954       73442 :                     move16();
     955       73442 :                     L_input_abs[q] = 0;
     956       73442 :                     move16();
     957             :                 }
     958             :             }
     959             : 
     960      130973 :             FOR( q = pindx + 1; q <= k; q++ )
     961             :             {
     962       86525 :                 IF( LE_16( peak_cand_idx[q], high ) )
     963             :                 {
     964       59481 :                     peak_cand_idx[q] = 0;
     965       59481 :                     move16();
     966       59481 :                     L_input_abs[q] = 0;
     967       59481 :                     move16();
     968             :                 }
     969             :             }
     970             : 
     971       44448 :             pindx = maximum_32_fx( L_input_abs, num_peak_cands, &L_m );
     972             :         }
     973             : 
     974        2228 :         *Npeaks = i; /* Q0 */
     975        2228 :         move16();
     976        2228 :         IF( GT_16( *Npeaks, HVQ_MIN_PEAKS ) )
     977             :         {
     978        2228 :             test();
     979        2228 :             IF( GT_16( num_sharp_bands, sub( nsub, 3 ) ) && LE_16( *Npeaks, peak_th ) )
     980             :             {
     981        1231 :                 sharp_dist = mult( sharp_dist, inv_nsub ); /*x+15-15=x */
     982        1231 :                 test();
     983        1231 :                 IF( LE_16( sharp_dist, SHARP_DIST_THRES_FX ) && *hvq_hangover < 0 )
     984             :                 {
     985          39 :                     *hvq_hangover = add( *hvq_hangover, 1 ); /* Q0 */
     986             :                 }
     987             :                 ELSE
     988             :                 {
     989        1192 :                     *hqswb_clas = HQ_HVQ; /* Q0 */
     990        1192 :                     move16();
     991        1192 :                     *hvq_hangover = 2; /* Q0 */
     992        1192 :                     move16();
     993             :                 }
     994             : 
     995             :                 /* update memory */
     996        1231 :                 *prev_Npeaks = *Npeaks; /* Q0 */
     997        1231 :                 move16();
     998        1231 :                 Copy( peaks, prev_peaks, *Npeaks ); /* Q0 */
     999             :             }
    1000             :             ELSE
    1001             :             {
    1002         997 :                 IF( *hvq_hangover > 0 )
    1003             :                 {
    1004         275 :                     *hqswb_clas = HQ_HVQ; /* Q0 */
    1005         275 :                     move16();
    1006         275 :                     *hvq_hangover = sub( *hvq_hangover, 1 ); /* Q0 */
    1007         275 :                     move16();
    1008             :                 }
    1009             :                 ELSE
    1010             :                 {
    1011         722 :                     *hvq_hangover = -1;
    1012         722 :                     move16();
    1013             :                 }
    1014             :             }
    1015             :         }
    1016             :         ELSE
    1017             :         {
    1018             :             /* Zero peaks, likely silence input. */
    1019           0 :             *hvq_hangover = -1;
    1020           0 :             move16();
    1021             :         }
    1022             : 
    1023             :         //*Npeaks = (int16_t) ( s_min( ( L_core_brate * HVQ_PEAKS_PER_DELTA + HVQ_PEAKS_PER_DELTA_OFFS ) / HVQ_PEAKS_BPS_DELTA, *Npeaks ) );
    1024        2228 :         temp_e = 0;
    1025        2228 :         move16();
    1026        2228 :         Word16 Npeaks_temp = *Npeaks;
    1027        2228 :         *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 );
    1028        2228 :         *Npeaks = s_min( shr( *Npeaks, sub( 15, temp_e ) ), Npeaks_temp );
    1029        2228 :         move16();
    1030             :     }
    1031             :     ELSE
    1032             :     {
    1033        4468 :         *prev_Npeaks = 0;
    1034        4468 :         move16();
    1035        4468 :         *hvq_hangover = 0;
    1036        4468 :         move16();
    1037             :     }
    1038             : 
    1039             : 
    1040        6696 :     return;
    1041             : }
    1042             : 
    1043          66 : void hvq_classifier_fx(
    1044             :     const Word32 *input,       /* i  : input signal                Q12 */
    1045             :     Word16 *prev_Npeaks,       /* i/o: Peak number memory          Q0  */
    1046             :     Word16 *prev_peaks,        /* i/o: Peak indices memory         Q0  */
    1047             :     Word16 *hqswb_clas,        /* i/o: HQ class                    Q0  */
    1048             :     Word16 *Npeaks,            /* o  : Number of peaks             Q0  */
    1049             :     Word16 *peaks,             /* o  : Peak indices                Q0  */
    1050             :     const Word32 L_core_brate, /* i  : Core bit-rate               Q0  */
    1051             :     const Word16 last_core,    /* i  : Last core used              Q0  */
    1052             :     Word32 *L_nf_gains,        /* o  : Noisefloor gains            Q12 */
    1053             :     Word16 *hvq_hangover,      /* i/o: Mode-switch hangover        Q0  */
    1054             :     Word32 *L_pe_gains         /* o  : peak gains                  Q12 */
    1055             : )
    1056             : {
    1057             :     const Word16 *p_adj;
    1058             :     UWord16 lsb;
    1059             : 
    1060             :     Word32 L_input_abs[L_FRAME32k];
    1061             :     Word32 L_input_max;
    1062             :     Word32 L_thr[L_FRAME16k];
    1063             :     Word32 L_thr_tmp;
    1064             :     Word32 L_m;
    1065             :     Word32 L_tmp;
    1066             :     Word32 L_d;
    1067             :     Word32 L_peak;
    1068             :     Word32 L_nf, L_pe;
    1069             :     Word32 L_pe_mean[HVQ_NSUB_32k], L_nf_mean[HVQ_NSUB_32k];
    1070             : 
    1071             :     Word16 inv_nsub;
    1072             :     Word16 sharp_dist;
    1073             :     Word16 exp1, exp2;
    1074             :     Word16 tmp;
    1075             :     Word16 shift;
    1076             :     Word16 idx;
    1077             :     Word16 frac;
    1078             :     Word16 inv_nf_mean;
    1079             :     Word16 inv_gains_nsub;
    1080             :     Word16 nf_mean_norm;
    1081             :     Word16 num_sharp_bands, i, j, k, q, peak_th, nsub, pindx, N, offset;
    1082             :     Word16 num_peak_cands, high, low;
    1083             :     Word16 sharp[HVQ_NSUB_32k];
    1084             :     Word16 peak_cand_idx[HVQ_THRES_BIN_32k], avail_peaks[HVQ_NSUB_32k];
    1085             : 
    1086          66 :     L_input_max = L_deposit_l( 0 );
    1087          66 :     set32_fx( L_thr, 0, L_FRAME16k );
    1088             : 
    1089          66 :     IF( EQ_32( L_core_brate, HQ_24k40 ) )
    1090             :     {
    1091          66 :         nsub = HVQ_NSUB_24k;
    1092          66 :         move16();
    1093          66 :         inv_nsub = 4681; /* 1/7 in Q15 */
    1094          66 :         move16();
    1095          66 :         inv_gains_nsub = 10923; /* 1/3 in Q15 */
    1096          66 :         move16();
    1097             :     }
    1098             :     ELSE
    1099             :     {
    1100           0 :         nsub = HVQ_NSUB_32k;
    1101           0 :         move16();
    1102           0 :         inv_nsub = 3277; /* 1/10 in Q15 */
    1103           0 :         move16();
    1104           0 :         inv_gains_nsub = 6554; /* 1/5 in Q15 */
    1105           0 :         move16();
    1106             :     }
    1107             : 
    1108          66 :     N = shl( nsub, 5 ); /* Mult by 32 (HVQ_BW) */
    1109             : 
    1110          66 :     test();
    1111          66 :     test();
    1112          66 :     IF( EQ_16( *hqswb_clas, HQ_HARMONIC ) && last_core != ACELP_CORE && NE_16( last_core, AMR_WB_CORE ) )
    1113             :     {
    1114        4275 :         FOR( i = 0; i < N; i++ )
    1115             :         {
    1116        4256 :             L_input_abs[i] = L_abs( input[i] ); /* Q12 */
    1117        4256 :             IF( GT_32( L_input_abs[i], L_input_max ) )
    1118             :             {
    1119         104 :                 L_input_max = L_input_abs[i]; /* Q12 */
    1120         104 :                 move16();
    1121             :             }
    1122             :         }
    1123             : 
    1124          19 :         exp1 = norm_l( L_input_max );
    1125             : 
    1126          19 :         *Npeaks = 0;
    1127          19 :         move16();
    1128          19 :         L_nf = 3276800; /* 800 in Q12 */
    1129          19 :         move32();
    1130          19 :         L_pe = 3276800; /* 800 in Q12    */
    1131          19 :         move32();
    1132          19 :         num_sharp_bands = 0;
    1133          19 :         move16();
    1134          19 :         k = 0;
    1135          19 :         move16();
    1136          19 :         q = 0;
    1137          19 :         move16();
    1138          19 :         sharp_dist = 0;
    1139          19 :         move16();
    1140             : 
    1141             :         /* Find peak threshold */
    1142         152 :         FOR( i = 0; i < nsub; i++ )
    1143             :         {
    1144         133 :             L_peak = 0;
    1145         133 :             L_nf_mean[i] = 0;
    1146         133 :             L_pe_mean[i] = 0;
    1147         133 :             move32();
    1148         133 :             move32();
    1149         133 :             move32();
    1150        4389 :             FOR( j = 0; j < HVQ_BW; j++ )
    1151             :             {
    1152        4256 :                 L_d = L_input_abs[q]; /* Q12 */
    1153        4256 :                 move32();
    1154        4256 :                 IF( GT_32( L_d, L_nf ) )
    1155             :                 {
    1156             :                     /*nf = HVQ_NF_WEIGHT1 * nf + (1 - HVQ_NF_WEIGHT1) * d; */
    1157        2763 :                     Mpy_32_16_ss( L_d, HVQ_NF_WEIGHT1B, &L_tmp, &lsb );   /* 12+15-15=12 */
    1158        2763 :                     Mpy_32_16_ss( L_nf, HVQ_NF_WEIGHT1_FX, &L_nf, &lsb ); /* 12+15-15=12 */
    1159        2763 :                     L_nf = L_add( L_nf, L_tmp );                          /*Q12 */
    1160             :                 }
    1161             :                 ELSE
    1162             :                 {
    1163             :                     /*nf = HVQ_NF_WEIGHT2 * nf + (1 - HVQ_NF_WEIGHT2) * d; */
    1164        1493 :                     Mpy_32_16_ss( L_d, HVQ_NF_WEIGHT2B, &L_tmp, &lsb );   /* 12+15-15=12 */
    1165        1493 :                     Mpy_32_16_ss( L_nf, HVQ_NF_WEIGHT2_FX, &L_nf, &lsb ); /* 12+15-15=12 */
    1166        1493 :                     L_nf = L_add( L_nf, L_tmp );                          /*Q12 */
    1167             :                 }
    1168             : 
    1169        4256 :                 IF( GT_32( L_d, L_pe ) )
    1170             :                 {
    1171             :                     /*pe = HVQ_PE_WEIGHT1 * pe + (1 - HVQ_PE_WEIGHT1) * d; */
    1172        1110 :                     Mpy_32_16_ss( L_d, HVQ_PE_WEIGHT1B, &L_tmp, &lsb );   /* 12+15-15=12 */
    1173        1110 :                     Mpy_32_16_ss( L_pe, HVQ_PE_WEIGHT1_FX, &L_pe, &lsb ); /* 12+15-15=12 */
    1174        1110 :                     L_pe = L_add( L_pe, L_tmp );                          /*Q12 */
    1175             :                 }
    1176             :                 ELSE
    1177             :                 {
    1178             :                     /*pe = HVQ_PE_WEIGHT2 * pe + (1 - HVQ_PE_WEIGHT2) * d; */
    1179        3146 :                     Mpy_32_16_ss( L_d, HVQ_PE_WEIGHT2B, &L_tmp, &lsb );   /* 12+15-15=12 */
    1180        3146 :                     Mpy_32_16_ss( L_pe, HVQ_PE_WEIGHT2_FX, &L_pe, &lsb ); /* 12+15-15=12 */
    1181        3146 :                     L_pe = L_add( L_pe, L_tmp );                          /*Q12 */
    1182             :                 }
    1183             : 
    1184        4256 :                 L_nf_mean[i] = L_add_sat( L_nf_mean[i], L_nf ); /*Q12 */
    1185        4256 :                 L_pe_mean[i] = L_add_sat( L_pe_mean[i], L_pe ); /*Q12 */
    1186        4256 :                 move32();
    1187        4256 :                 move32();
    1188        4256 :                 IF( GT_32( L_d, L_peak ) )
    1189             :                 {
    1190         599 :                     L_peak = L_add( L_d, 0 );
    1191             :                 }
    1192             : 
    1193        4256 :                 q += 1;
    1194             :             }
    1195         133 :             L_nf_mean[i] = L_shr( L_nf_mean[i], 5 ); /* Divide by 5 (HVQ_BW) */
    1196         133 :             L_pe_mean[i] = L_shr( L_pe_mean[i], 5 ); /* Divide by 5 (HVQ_BW) */
    1197         133 :             move32();
    1198         133 :             move32();
    1199             : 
    1200             :             /*thr_tmp = (float)pow( pe_mean[i]/nf_mean[i], HVQ_THR_POW ) * nf_mean[i]; */
    1201         133 :             exp1 = norm_l( L_nf_mean[i] );
    1202         133 :             nf_mean_norm = extract_h( L_shl( L_nf_mean[i], exp1 ) ); /* 12+s-16=s-4 */
    1203         133 :             IF( nf_mean_norm == 0 )
    1204             :             {
    1205           0 :                 inv_nf_mean = 0;
    1206             :             }
    1207             :             ELSE
    1208             :             {
    1209         133 :                 inv_nf_mean = div_s( 1 << 14, nf_mean_norm ); /* 15+14-s+4=33-s */
    1210             :             }
    1211         133 :             Mpy_32_16_ss( L_pe_mean[i], inv_nf_mean, &L_tmp, &lsb ); /*12+33-s-15=30-s */
    1212             : 
    1213         133 :             exp2 = norm_l( L_tmp );
    1214         133 :             tmp = Log2_norm_lc( L_shl( L_tmp, exp2 ) ); /* Q15 */
    1215         133 :             exp2 = exp1 - exp2;                         /* Q0 */
    1216         133 :             L_tmp = Mpy_32_16( exp2, tmp, 32767 );      /* 1 in Q15. Q16 */
    1217         133 :             Mpy_32_16_ss( L_tmp, 28836, &L_tmp, &lsb ); /* 16+15-15=16 */
    1218         133 :             frac = L_Extract_lc( L_tmp, &tmp );         /* Q15 and Q0 */
    1219         133 :             L_tmp = Pow2( 14, frac );                   /* Q14 */
    1220         133 :             L_tmp = L_shl( L_tmp, tmp );                /* Q14 */
    1221             : 
    1222         133 :             Mpy_32_16_ss( L_tmp, nf_mean_norm, &L_tmp, &lsb );             /*14+s-4-15=s-5 */
    1223         133 :             shift = sub( 17, exp1 );                                       /* 16-(s-5)=17-s */
    1224         133 :             L_thr_tmp = L_shl( L_tmp, shift );                             /* Q16 */
    1225         133 :             L_thr_tmp = L_add( L_thr_tmp, lshr( lsb, sub( 16, shift ) ) ); /*Q16 */
    1226             : 
    1227         133 :             set32_fx( &L_thr[k], L_thr_tmp, HVQ_BW );
    1228         133 :             k = add( k, HVQ_BW );
    1229             : 
    1230             :             /*sharp[i] = peak/nf_mean[i]; */
    1231         133 :             Mpy_32_16_ss( L_peak, inv_nf_mean, &L_tmp, &lsb ); /* 12+33-s-15=30-s */
    1232         133 :             shift = sub( exp1, 8 );
    1233         133 :             sharp[i] = extract_h( L_shl( L_tmp, shift ) ); /* 30-s+s-8-16 -> Q6 */
    1234         133 :             move16();
    1235             : 
    1236             :             /*sharp_dist += (sharp[i]-HVQ_SHARP_THRES); */
    1237         133 :             sharp_dist = add_sat( sharp_dist, sub( sharp[i], HVQ_SHARP_THRES_FX ) );
    1238         133 :             IF( GT_16( sharp[i], HVQ_SHARP_THRES_FX ) )
    1239             :             {
    1240          67 :                 num_sharp_bands = add( num_sharp_bands, 1 );
    1241             :             }
    1242             :         }
    1243             : 
    1244             :         /* Estimate noise floor gains */
    1245          19 :         offset = s_and( nsub, 1 );
    1246         133 :         FOR( i = 0; i < ( nsub & (Word16) 0xFFFE ); i++ )
    1247             :         {
    1248             :             /*(2*i+1)/nsub */
    1249         114 :             idx = mult( add( shl( i, 1 ), 1 ), add( inv_nsub, 1 ) ); /*0+15-15 = 0 */
    1250         114 :             L_nf_gains[idx] = L_add( L_nf_gains[idx], L_nf_mean[i + offset] );
    1251         114 :             L_pe_gains[idx] = L_add( L_pe_gains[idx], L_pe_mean[i + offset] );
    1252         114 :             move32();
    1253         114 :             move32();
    1254             :         }
    1255             : 
    1256          57 :         FOR( i = 0; i < HVQ_NF_GROUPS; i++ )
    1257             :         {
    1258          38 :             Mpy_32_16_ss( L_nf_gains[i], inv_gains_nsub, &L_nf_gains[i], &lsb ); /*12+15-15=12 */
    1259          38 :             Mpy_32_16_ss( L_pe_gains[i], inv_gains_nsub, &L_pe_gains[i], &lsb ); /*12+15-15=12 */
    1260             :         }
    1261             : 
    1262             :         /* Allocate available peaks */
    1263         152 :         FOR( i = 0; i < nsub; i++ )
    1264             :         {
    1265         133 :             avail_peaks[i] = HVQ_PA_PEAKS_SHARP1;
    1266         133 :             move16();
    1267         133 :             idx = mult( add( shl( i, 1 ), 1 ), add( inv_nsub, 1 ) );      /*0+15-15 = 0 */
    1268         133 :             Mpy_32_16_ss( L_nf_gains[idx], HVQ_PA_FAC_FX, &L_tmp, &lsb ); /* 12+15-15 -> Q12 */
    1269         133 :             IF( LT_32( L_nf_mean[i], L_tmp ) )
    1270             :             {
    1271          39 :                 IF( LT_16( sharp[i], HVQ_PA_SHARP_THRES3_FX ) )
    1272             :                 {
    1273          34 :                     avail_peaks[i] = HVQ_PA_PEAKS_SHARP3;
    1274          34 :                     move16();
    1275             :                 }
    1276           5 :                 ELSE IF( LT_16( sharp[i], HVQ_PA_SHARP_THRES2_FX ) )
    1277             :                 {
    1278           4 :                     avail_peaks[i] = HVQ_PA_PEAKS_SHARP2;
    1279           4 :                     move16();
    1280             :                 }
    1281             :             }
    1282             :         }
    1283             : 
    1284             : 
    1285             :         /* Adjust threshold around previous peaks */
    1286          19 :         FOR( i = 0; i < *prev_Npeaks; i++ )
    1287             :         {
    1288           0 :             j = sub( prev_peaks[i], 2 ); /* Q0 */
    1289           0 :             k = add( prev_peaks[i], 2 ); /* Q0 */
    1290           0 :             p_adj = hvq_thr_adj_fx;      /* Q15 */
    1291           0 :             move16();
    1292             : 
    1293           0 :             FOR( q = j; q < k; q++ )
    1294             :             {
    1295           0 :                 Mpy_32_16_ss( L_thr[q], *p_adj++, &L_thr[q], &lsb ); /* 12+15-15=12 */
    1296           0 :                 move32();
    1297             :             }
    1298             :         }
    1299             : 
    1300          19 :         num_peak_cands = 0;
    1301          19 :         move16();
    1302             : 
    1303             :         /* Remove everything below threshold for peak search */
    1304          19 :         L_input_abs[0] = L_deposit_l( 0 );
    1305          19 :         L_input_abs[1] = L_deposit_l( 0 );
    1306          19 :         L_input_abs[N - 2] = L_deposit_l( 0 );
    1307          19 :         L_input_abs[N - 1] = L_deposit_l( 0 );
    1308          19 :         move32();
    1309          19 :         move32();
    1310          19 :         move32();
    1311          19 :         move32();
    1312        4237 :         FOR( i = 0; i < N - 2; i++ )
    1313             :         {
    1314        4218 :             IF( LT_32( L_input_abs[i], L_thr[i] ) )
    1315             :             {
    1316        3120 :                 L_input_abs[i] = L_deposit_l( 0 );
    1317        3120 :                 move32();
    1318             :             }
    1319             :             ELSE
    1320             :             {
    1321        1098 :                 L_input_abs[num_peak_cands] = L_input_abs[i]; /* Q12 */
    1322        1098 :                 move32();
    1323        1098 :                 peak_cand_idx[num_peak_cands] = i; /* Q0 */
    1324        1098 :                 move16();
    1325        1098 :                 num_peak_cands = add( num_peak_cands, 1 );
    1326             :             }
    1327             :         }
    1328          19 :         IF( EQ_32( L_core_brate, HQ_24k40 ) )
    1329             :         {
    1330          19 :             peak_th = HVQ_MAX_PEAKS_24k_CLAS;
    1331          19 :             move16();
    1332             :         }
    1333             :         ELSE
    1334             :         {
    1335           0 :             peak_th = HVQ_MAX_PEAKS_32k;
    1336           0 :             move16();
    1337             :         }
    1338             :         /* Find peaks */
    1339          19 :         pindx = maximum_32_fx( L_input_abs, num_peak_cands, &L_m );
    1340          19 :         i = 0;
    1341          19 :         move16();
    1342             : 
    1343         461 :         WHILE( L_m > 0 && LT_16( i, peak_th + 1 ) )
    1344             :         {
    1345         442 :             idx = mult( peak_cand_idx[pindx], INV_HVQ_BW ); /* 0+15-15=0 */
    1346         442 :             IF( avail_peaks[idx] > 0 )
    1347             :             {
    1348         398 :                 peaks[i++] = peak_cand_idx[pindx]; /* Q0 */
    1349         398 :                 move16();
    1350         398 :                 avail_peaks[idx]--;
    1351             :             }
    1352             : 
    1353         442 :             j = sub( pindx, 2 );
    1354         442 :             k = add( pindx, 2 );
    1355             : 
    1356         442 :             if ( j < 0 )
    1357             :             {
    1358          19 :                 j = 0;
    1359          19 :                 move16();
    1360             :             }
    1361             : 
    1362         442 :             tmp = sub( num_peak_cands, 1 );
    1363         442 :             if ( GT_16( k, tmp ) )
    1364             :             {
    1365          17 :                 k = tmp;
    1366          17 :                 move16();
    1367             :             }
    1368             : 
    1369         442 :             low = sub( peak_cand_idx[pindx], 2 );
    1370         442 :             high = add( peak_cand_idx[pindx], 2 );
    1371             : 
    1372         442 :             if ( low < 0 )
    1373             :             {
    1374           0 :                 low = 0;
    1375           0 :                 move16();
    1376             :             }
    1377             : 
    1378         442 :             tmp = sub( N, 1 );
    1379         442 :             IF( GT_16( high, tmp ) )
    1380             :             {
    1381           0 :                 high = tmp;
    1382           0 :                 move16();
    1383             :             }
    1384             : 
    1385        1738 :             FOR( q = j; q <= pindx; q++ )
    1386             :             {
    1387        1296 :                 IF( GE_16( peak_cand_idx[q], low ) )
    1388             :                 {
    1389         649 :                     peak_cand_idx[q] = 0;
    1390         649 :                     move16();
    1391         649 :                     L_input_abs[q] = 0;
    1392         649 :                     move16();
    1393             :                 }
    1394             :             }
    1395             : 
    1396        1299 :             FOR( q = pindx + 1; q <= k; q++ )
    1397             :             {
    1398         857 :                 IF( LE_16( peak_cand_idx[q], high ) )
    1399             :                 {
    1400         529 :                     peak_cand_idx[q] = 0;
    1401         529 :                     move16();
    1402         529 :                     L_input_abs[q] = 0;
    1403         529 :                     move16();
    1404             :                 }
    1405             :             }
    1406             : 
    1407         442 :             pindx = maximum_32_fx( L_input_abs, num_peak_cands, &L_m ); /* Q0 */
    1408             :         }
    1409             : 
    1410          19 :         *Npeaks = i;
    1411          19 :         move16();
    1412          19 :         IF( GT_16( *Npeaks, HVQ_MIN_PEAKS ) )
    1413             :         {
    1414          19 :             test();
    1415          19 :             IF( GT_16( num_sharp_bands, sub( nsub, 3 ) ) && LE_16( *Npeaks, peak_th ) )
    1416             :             {
    1417           0 :                 sharp_dist = mult( sharp_dist, inv_nsub ); /*x+15-15=x */
    1418           0 :                 test();
    1419           0 :                 IF( LE_16( sharp_dist, SHARP_DIST_THRES_FX ) && *hvq_hangover < 0 )
    1420             :                 {
    1421           0 :                     *hvq_hangover = add( *hvq_hangover, 1 );
    1422             :                 }
    1423             :                 ELSE
    1424             :                 {
    1425           0 :                     *hqswb_clas = HQ_HVQ; /* Q0 */
    1426           0 :                     move16();
    1427           0 :                     *hvq_hangover = 2; /* Q0 */
    1428           0 :                     move16();
    1429             :                 }
    1430             : 
    1431             :                 /* update memory */
    1432           0 :                 *prev_Npeaks = *Npeaks; /* Q0 */
    1433           0 :                 move16();
    1434           0 :                 Copy( peaks, prev_peaks, *Npeaks ); /* Q0 */
    1435             :             }
    1436             :             ELSE
    1437             :             {
    1438          19 :                 IF( *hvq_hangover > 0 )
    1439             :                 {
    1440           0 :                     *hqswb_clas = HQ_HVQ; /* Q0 */
    1441           0 :                     move16();
    1442           0 :                     *hvq_hangover = sub( *hvq_hangover, 1 ); /* Q0 */
    1443           0 :                     move16();
    1444             :                 }
    1445             :                 ELSE
    1446             :                 {
    1447          19 :                     *hvq_hangover = -1;
    1448          19 :                     move16();
    1449             :                 }
    1450             :             }
    1451             :         }
    1452             :         ELSE
    1453             :         {
    1454             :             /* Zero peaks, likely silence input. */
    1455           0 :             *hvq_hangover = -1;
    1456           0 :             move16();
    1457             :         }
    1458             : 
    1459          19 :         IF( EQ_32( L_core_brate, HQ_24k40 ) )
    1460             :         {
    1461          19 :             *Npeaks = s_min( HVQ_MAX_PEAKS_24k, *Npeaks ); /* Q0 */
    1462          19 :             move16();
    1463             :         }
    1464             :         ELSE
    1465             :         {
    1466           0 :             *Npeaks = s_min( HVQ_MAX_PEAKS_32k, *Npeaks ); /* Q0 */
    1467           0 :             move16();
    1468             :         }
    1469             :     }
    1470             :     ELSE
    1471             :     {
    1472          47 :         *prev_Npeaks = 0;
    1473          47 :         move16();
    1474          47 :         *hvq_hangover = 0;
    1475          47 :         move16();
    1476             :     }
    1477             : 
    1478             : 
    1479          66 :     return;
    1480             : }

Generated by: LCOV version 1.14