LCOV - code coverage report
Current view: top level - lib_enc - hq_classifier_enc_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main @ e95243e9e67ddeb69dddf129509de1b3d95b402e Lines: 651 724 89.9 %
Date: 2025-09-14 03:13:15 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        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             : #ifndef ISSUE_1867_replace_overflow_libenc
     656             : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
     657             :     Flag Overflow = 0;
     658             :     move16();
     659             : #endif
     660             : #endif
     661        6696 :     Word16 temp_e = 0;
     662        6696 :     move16();
     663        6696 :     L_input_max = L_deposit_l( 0 );
     664        6696 :     set32_fx( L_thr, 0, L_FRAME16k );
     665             : 
     666        6696 :     IF( LT_32( L_core_brate, HQ_BWE_CROSSOVER_BRATE ) )
     667             :     {
     668        2654 :         nsub = HVQ_NSUB_24k;
     669        2654 :         move16();
     670        2654 :         inv_nsub = 4681; /* 1/7 in Q15 */
     671        2654 :         move16();
     672        2654 :         inv_gains_nsub = 10923; /* 1/3 in Q15 */
     673        2654 :         move16();
     674             :     }
     675             :     ELSE
     676             :     {
     677        4042 :         nsub = HVQ_NSUB_32k;
     678        4042 :         move16();
     679        4042 :         inv_nsub = 3277; /* 1/10 in Q15 */
     680        4042 :         move16();
     681        4042 :         inv_gains_nsub = 6554; /* 1/5 in Q15 */
     682        4042 :         move16();
     683             :     }
     684             : 
     685        6696 :     N = shl( nsub, 5 ); /* Mult by 32 (HVQ_BW) */
     686             : 
     687        6696 :     test();
     688        6696 :     test();
     689        6696 :     IF( EQ_16( *hqswb_clas, HQ_HARMONIC ) && last_core != ACELP_CORE && NE_16( last_core, AMR_WB_CORE ) )
     690        2228 :     {
     691      597300 :         FOR( i = 0; i < N; i++ )
     692             :         {
     693      595072 :             L_input_abs[i] = L_abs( input[i] ); /* Q12 */
     694      595072 :             move16();
     695      595072 :             IF( GT_32( L_input_abs[i], L_input_max ) )
     696             :             {
     697       13556 :                 L_input_max = L_input_abs[i]; /* Q12 */
     698       13556 :                 move16();
     699             :             }
     700             :         }
     701             : 
     702        2228 :         exp1 = norm_l( L_input_max );
     703             : 
     704        2228 :         *Npeaks = 0;
     705        2228 :         move16();
     706        2228 :         L_nf = 3276800; /* 800 in Q12 */
     707        2228 :         move32();
     708        2228 :         L_pe = 3276800; /* 800 in Q12    */
     709        2228 :         move32();
     710        2228 :         num_sharp_bands = 0;
     711        2228 :         move16();
     712        2228 :         k = 0;
     713        2228 :         move16();
     714        2228 :         q = 0;
     715        2228 :         move16();
     716        2228 :         sharp_dist = 0;
     717        2228 :         move16();
     718             : 
     719             :         /* Find peak threshold */
     720       20824 :         FOR( i = 0; i < nsub; i++ )
     721             :         {
     722       18596 :             L_peak = 0;
     723       18596 :             L_nf_mean[i] = 0;
     724       18596 :             L_pe_mean[i] = 0;
     725       18596 :             move32();
     726       18596 :             move32();
     727       18596 :             move32();
     728             : 
     729      613668 :             FOR( j = 0; j < HVQ_BW; j++ )
     730             :             {
     731      595072 :                 L_d = L_input_abs[q]; /* Q12 */
     732      595072 :                 IF( GT_32( L_d, L_nf ) )
     733             :                 {
     734             :                     /*nf = HVQ_NF_WEIGHT1 * nf + (1 - HVQ_NF_WEIGHT1) * d; */
     735      317930 :                     Mpy_32_16_ss( L_d, HVQ_NF_WEIGHT1B, &L_tmp, &lsb );   /* 12+15-15=12 */
     736      317930 :                     Mpy_32_16_ss( L_nf, HVQ_NF_WEIGHT1_FX, &L_nf, &lsb ); /* 12+15-15=12 */
     737      317930 :                     L_nf = L_add( L_nf, L_tmp );                          /*Q12 */
     738             :                 }
     739             :                 ELSE
     740             :                 {
     741             :                     /*nf = HVQ_NF_WEIGHT2 * nf + (1 - HVQ_NF_WEIGHT2) * d; */
     742      277142 :                     Mpy_32_16_ss( L_d, HVQ_NF_WEIGHT2B, &L_tmp, &lsb );   /* 12+15-15=12 */
     743      277142 :                     Mpy_32_16_ss( L_nf, HVQ_NF_WEIGHT2_FX, &L_nf, &lsb ); /* 12+15-15=12 */
     744      277142 :                     L_nf = L_add( L_nf, L_tmp );                          /*Q12 */
     745             :                 }
     746             : 
     747      595072 :                 IF( GT_32( L_d, L_pe ) )
     748             :                 {
     749             :                     /*pe = HVQ_PE_WEIGHT1 * pe + (1 - HVQ_PE_WEIGHT1) * d; */
     750      118938 :                     Mpy_32_16_ss( L_d, HVQ_PE_WEIGHT1B, &L_tmp, &lsb );   /* 12+15-15=12 */
     751      118938 :                     Mpy_32_16_ss( L_pe, HVQ_PE_WEIGHT1_FX, &L_pe, &lsb ); /* 12+15-15=12 */
     752      118938 :                     L_pe = L_add( L_pe, L_tmp );                          /*Q12 */
     753             :                 }
     754             :                 ELSE
     755             :                 {
     756             :                     /*pe = HVQ_PE_WEIGHT2 * pe + (1 - HVQ_PE_WEIGHT2) * d; */
     757      476134 :                     Mpy_32_16_ss( L_d, HVQ_PE_WEIGHT2B, &L_tmp, &lsb );   /* 12+15-15=12 */
     758      476134 :                     Mpy_32_16_ss( L_pe, HVQ_PE_WEIGHT2_FX, &L_pe, &lsb ); /* 12+15-15=12 */
     759      476134 :                     L_pe = L_add( L_pe, L_tmp );                          /*Q12 */
     760             :                 }
     761             : 
     762      595072 :                 L_nf_mean[i] = L_add_sat( L_nf_mean[i], L_nf ); /*Q12 */
     763      595072 :                 L_pe_mean[i] = L_add_sat( L_pe_mean[i], L_pe ); /*Q12 */
     764      595072 :                 move32();
     765      595072 :                 move32();
     766      595072 :                 IF( GT_32( L_d, L_peak ) )
     767             :                 {
     768       89235 :                     L_peak = L_add( L_d, 0 );
     769             :                 }
     770             : 
     771      595072 :                 q += 1;
     772             :             }
     773       18596 :             L_nf_mean[i] = L_shr( L_nf_mean[i], 5 ); /* Divide by 5 (HVQ_BW) */
     774       18596 :             L_pe_mean[i] = L_shr( L_pe_mean[i], 5 ); /* Divide by 5 (HVQ_BW) */
     775       18596 :             move32();
     776       18596 :             move32();
     777             :             /*thr_tmp = (float)pow( pe_mean[i]/nf_mean[i], HVQ_THR_POW ) * nf_mean[i]; */
     778       18596 :             exp1 = norm_l( L_nf_mean[i] );
     779       18596 :             nf_mean_norm = extract_h( L_shl( L_nf_mean[i], exp1 ) ); /* 12+s-16=s-4 */
     780       18596 :             IF( nf_mean_norm == 0 )
     781             :             {
     782           0 :                 inv_nf_mean = 0;
     783             :             }
     784             :             ELSE
     785             :             {
     786       18596 :                 inv_nf_mean = div_s( 1 << 14, nf_mean_norm ); /* 15+14-s+4=33-s */
     787             :             }
     788       18596 :             Mpy_32_16_ss( L_pe_mean[i], inv_nf_mean, &L_tmp, &lsb ); /*12+33-s-15=30-s */
     789             : 
     790       18596 :             exp2 = norm_l( L_tmp );
     791       18596 :             tmp = Log2_norm_lc( L_shl( L_tmp, exp2 ) ); /* Q15 */
     792       18596 :             exp2 = sub( exp1, exp2 );                   /* Q0 */
     793       18596 :             L_tmp = Mpy_32_16( exp2, tmp, 32767 );      /* 1 in Q15. Q16 */
     794       18596 :             Mpy_32_16_ss( L_tmp, 28836, &L_tmp, &lsb ); /* 16+15-15=16 */
     795       18596 :             frac = L_Extract_lc( L_tmp, &tmp );         /* Q15 and Q0 */
     796       18596 :             L_tmp = Pow2( 14, frac );                   /* Q14 */
     797       18596 :             L_tmp = L_shl( L_tmp, tmp );                /* Q14 */
     798             : 
     799       18596 :             Mpy_32_16_ss( L_tmp, nf_mean_norm, &L_tmp, &lsb );             /*14+s-4-15=s-5 */
     800       18596 :             shift = sub( 17, exp1 );                                       /* 16-(s-5)=17-s */
     801       18596 :             L_thr_tmp = L_shl( L_tmp, shift );                             /* Q16 */
     802       18596 :             L_thr_tmp = L_add( L_thr_tmp, lshr( lsb, sub( 16, shift ) ) ); /*Q16 */
     803             : 
     804       18596 :             set32_fx( &L_thr[k], L_thr_tmp, HVQ_BW );
     805       18596 :             k = add( k, HVQ_BW );
     806             : 
     807             :             /*sharp[i] = peak/nf_mean[i]; */
     808       18596 :             Mpy_32_16_ss( L_peak, inv_nf_mean, &L_tmp, &lsb ); /* 12+33-s-15=30-s */
     809       18596 :             shift = sub( exp1, 8 );
     810       18596 :             sharp[i] = extract_h( L_shl( L_tmp, shift ) ); /* 30-s+s-8-16 -> Q6 */
     811       18596 :             move16();
     812             :             /*sharp_dist += (sharp[i]-HVQ_SHARP_THRES); */
     813             : #ifdef ISSUE_1867_replace_overflow_libenc
     814       18596 :             sharp_dist = add_sat( sharp_dist, sub( sharp[i], HVQ_SHARP_THRES_FX ) ); /* Q6 */
     815             : #else
     816             :             sharp_dist = add_o( sharp_dist, sub( sharp[i], HVQ_SHARP_THRES_FX ), &Overflow ); /* Q6 */
     817             : #endif
     818       18596 :             if ( GT_16( sharp[i], HVQ_SHARP_THRES_FX ) )
     819             :             {
     820       16013 :                 num_sharp_bands = add( num_sharp_bands, 1 );
     821             :             }
     822             :         }
     823             : 
     824             :         /* Estimate noise floor gains */
     825        2228 :         offset = s_and( nsub, 1 );
     826       19596 :         FOR( i = 0; i < ( nsub & (Word16) 0xFFFE ); i++ )
     827             :         {
     828             :             /*(2*i+1)/nsub */
     829       17368 :             idx = mult( add( shl( i, 1 ), 1 ), add( inv_nsub, 1 ) );           /*0+15-15 = 0 */
     830       17368 :             L_nf_gains[idx] = L_add( L_nf_gains[idx], L_nf_mean[i + offset] ); /* Q12 */
     831       17368 :             L_pe_gains[idx] = L_add( L_pe_gains[idx], L_pe_mean[i + offset] ); /* Q12 */
     832       17368 :             move32();
     833       17368 :             move32();
     834             :         }
     835             : 
     836        6684 :         FOR( i = 0; i < HVQ_NF_GROUPS; i++ )
     837             :         {
     838        4456 :             Mpy_32_16_ss( L_nf_gains[i], inv_gains_nsub, &L_nf_gains[i], &lsb ); /*12+15-15=12 */
     839        4456 :             Mpy_32_16_ss( L_pe_gains[i], inv_gains_nsub, &L_pe_gains[i], &lsb ); /*12+15-15=12 */
     840             :         }
     841             : 
     842             :         /* Allocate available peaks */
     843       20824 :         FOR( i = 0; i < nsub; i++ )
     844             :         {
     845       18596 :             avail_peaks[i] = HVQ_PA_PEAKS_SHARP1; /* Q0 */
     846       18596 :             move16();
     847       18596 :             idx = mult( add( shl( i, 1 ), 1 ), add( inv_nsub, 1 ) );      /*0+15-15 = 0 */
     848       18596 :             Mpy_32_16_ss( L_nf_gains[idx], HVQ_PA_FAC_FX, &L_tmp, &lsb ); /* 12+15-15 -> Q12 */
     849       18596 :             IF( LT_32( L_nf_mean[i], L_tmp ) )
     850             :             {
     851        6684 :                 IF( LT_16( sharp[i], HVQ_PA_SHARP_THRES3_FX ) )
     852             :                 {
     853        1487 :                     avail_peaks[i] = HVQ_PA_PEAKS_SHARP3; /* Q0 */
     854        1487 :                     move16();
     855             :                 }
     856        5197 :                 ELSE IF( LT_16( sharp[i], HVQ_PA_SHARP_THRES2_FX ) )
     857             :                 {
     858         673 :                     avail_peaks[i] = HVQ_PA_PEAKS_SHARP2; /* Q0 */
     859         673 :                     move16();
     860             :                 }
     861             :             }
     862             :         }
     863             : 
     864             : 
     865             :         /* Adjust threshold around previous peaks */
     866       27058 :         FOR( i = 0; i < *prev_Npeaks; i++ )
     867             :         {
     868       24830 :             j = sub( prev_peaks[i], 2 ); /* Q0 */
     869       24830 :             k = add( prev_peaks[i], 2 ); /* Q0 */
     870       24830 :             p_adj = hvq_thr_adj_fx;      /* Q15 */
     871             : 
     872      124150 :             FOR( q = j; q < k; q++ )
     873             :             {
     874       99320 :                 Mpy_32_16_ss( L_thr[q], *p_adj++, &L_thr[q], &lsb ); /* 12+15-15=12 */
     875       99320 :                 move32();
     876             :             }
     877             :         }
     878             : 
     879        2228 :         num_peak_cands = 0;
     880        2228 :         move16();
     881             : 
     882             :         /* Remove everything below threshold for peak search */
     883        2228 :         L_input_abs[0] = L_deposit_l( 0 );
     884        2228 :         L_input_abs[1] = L_deposit_l( 0 );
     885        2228 :         L_input_abs[N - 2] = L_deposit_l( 0 );
     886        2228 :         L_input_abs[N - 1] = L_deposit_l( 0 );
     887        2228 :         move32();
     888        2228 :         move32();
     889        2228 :         move32();
     890        2228 :         move32();
     891      592844 :         FOR( i = 0; i < N - 2; i++ )
     892             :         {
     893      590616 :             IF( LT_32( L_input_abs[i], L_thr[i] ) )
     894             :             {
     895      481953 :                 L_input_abs[i] = L_deposit_l( 0 );
     896             : 
     897      481953 :                 move32();
     898             :             }
     899             :             ELSE
     900             :             {
     901      108663 :                 L_input_abs[num_peak_cands] = L_input_abs[i]; /* Q12 */
     902      108663 :                 move32();
     903      108663 :                 peak_cand_idx[num_peak_cands] = i; /* Q0 */
     904      108663 :                 move16();
     905      108663 :                 num_peak_cands = add( num_peak_cands, 1 );
     906             :             }
     907             :         }
     908             : 
     909             : 
     910        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 ) );
     911        2228 :         peak_th = shr( peak_th, sub( 15, temp_e ) );
     912             :         /* Find peaks */
     913        2228 :         pindx = maximum_32_fx( L_input_abs, num_peak_cands, &L_m );
     914        2228 :         i = 0;
     915        2228 :         move16();
     916             : 
     917       46676 :         WHILE( L_m > 0 && LT_16( i, peak_th + 1 ) )
     918             :         {
     919       44448 :             idx = mult( peak_cand_idx[pindx], INV_HVQ_BW ); /* 0+15-15=0 */
     920       44448 :             IF( avail_peaks[idx] > 0 )
     921             :             {
     922       43425 :                 peaks[i++] = peak_cand_idx[pindx]; /* Q0 */
     923       43425 :                 avail_peaks[idx]--;
     924             :             }
     925             : 
     926       44448 :             j = sub( pindx, 2 );
     927       44448 :             k = add( pindx, 2 );
     928             : 
     929       44448 :             if ( j < 0 )
     930             :             {
     931        2165 :                 j = 0;
     932        2165 :                 move16();
     933             :             }
     934             : 
     935       44448 :             tmp = sub( num_peak_cands, 1 );
     936       44448 :             if ( GT_16( k, tmp ) )
     937             :             {
     938        1559 :                 k = tmp;
     939        1559 :                 move16();
     940             :             }
     941             : 
     942       44448 :             low = sub( peak_cand_idx[pindx], 2 );
     943       44448 :             high = add( peak_cand_idx[pindx], 2 );
     944             : 
     945       44448 :             if ( low < 0 )
     946             :             {
     947           0 :                 low = 0;
     948           0 :                 move16();
     949             :             }
     950             : 
     951       44448 :             tmp = sub( N, 1 );
     952       44448 :             if ( GT_16( high, tmp ) )
     953             :             {
     954           0 :                 high = tmp;
     955           0 :                 move16();
     956             :             }
     957             : 
     958      174331 :             FOR( q = j; q <= pindx; q++ )
     959             :             {
     960      129883 :                 IF( GE_16( peak_cand_idx[q], low ) )
     961             :                 {
     962       73442 :                     peak_cand_idx[q] = 0;
     963       73442 :                     move16();
     964       73442 :                     L_input_abs[q] = 0;
     965       73442 :                     move16();
     966             :                 }
     967             :             }
     968             : 
     969      130973 :             FOR( q = pindx + 1; q <= k; q++ )
     970             :             {
     971       86525 :                 IF( LE_16( peak_cand_idx[q], high ) )
     972             :                 {
     973       59481 :                     peak_cand_idx[q] = 0;
     974       59481 :                     move16();
     975       59481 :                     L_input_abs[q] = 0;
     976       59481 :                     move16();
     977             :                 }
     978             :             }
     979             : 
     980       44448 :             pindx = maximum_32_fx( L_input_abs, num_peak_cands, &L_m );
     981             :         }
     982             : 
     983        2228 :         *Npeaks = i; /* Q0 */
     984        2228 :         move16();
     985        2228 :         IF( GT_16( *Npeaks, HVQ_MIN_PEAKS ) )
     986             :         {
     987        2228 :             test();
     988        2228 :             IF( GT_16( num_sharp_bands, sub( nsub, 3 ) ) && LE_16( *Npeaks, peak_th ) )
     989             :             {
     990        1231 :                 sharp_dist = mult( sharp_dist, inv_nsub ); /*x+15-15=x */
     991        1231 :                 test();
     992        1231 :                 IF( LE_16( sharp_dist, SHARP_DIST_THRES_FX ) && *hvq_hangover < 0 )
     993             :                 {
     994          39 :                     *hvq_hangover = add( *hvq_hangover, 1 ); /* Q0 */
     995             :                 }
     996             :                 ELSE
     997             :                 {
     998        1192 :                     *hqswb_clas = HQ_HVQ; /* Q0 */
     999        1192 :                     move16();
    1000        1192 :                     *hvq_hangover = 2; /* Q0 */
    1001        1192 :                     move16();
    1002             :                 }
    1003             : 
    1004             :                 /* update memory */
    1005        1231 :                 *prev_Npeaks = *Npeaks; /* Q0 */
    1006        1231 :                 move16();
    1007        1231 :                 Copy( peaks, prev_peaks, *Npeaks ); /* Q0 */
    1008             :             }
    1009             :             ELSE
    1010             :             {
    1011         997 :                 IF( *hvq_hangover > 0 )
    1012             :                 {
    1013         275 :                     *hqswb_clas = HQ_HVQ; /* Q0 */
    1014         275 :                     move16();
    1015         275 :                     *hvq_hangover = sub( *hvq_hangover, 1 ); /* Q0 */
    1016         275 :                     move16();
    1017             :                 }
    1018             :                 ELSE
    1019             :                 {
    1020         722 :                     *hvq_hangover = -1;
    1021         722 :                     move16();
    1022             :                 }
    1023             :             }
    1024             :         }
    1025             :         ELSE
    1026             :         {
    1027             :             /* Zero peaks, likely silence input. */
    1028           0 :             *hvq_hangover = -1;
    1029           0 :             move16();
    1030             :         }
    1031             : 
    1032             :         //*Npeaks = (int16_t) ( s_min( ( L_core_brate * HVQ_PEAKS_PER_DELTA + HVQ_PEAKS_PER_DELTA_OFFS ) / HVQ_PEAKS_BPS_DELTA, *Npeaks ) );
    1033        2228 :         temp_e = 0;
    1034        2228 :         move16();
    1035        2228 :         Word16 Npeaks_temp = *Npeaks;
    1036        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 );
    1037        2228 :         *Npeaks = s_min( shr( *Npeaks, sub( 15, temp_e ) ), Npeaks_temp );
    1038        2228 :         move16();
    1039             :     }
    1040             :     ELSE
    1041             :     {
    1042        4468 :         *prev_Npeaks = 0;
    1043        4468 :         move16();
    1044        4468 :         *hvq_hangover = 0;
    1045        4468 :         move16();
    1046             :     }
    1047             : 
    1048             : 
    1049        6696 :     return;
    1050             : }
    1051             : 
    1052          66 : void hvq_classifier_fx(
    1053             :     const Word32 *input,       /* i  : input signal                Q12 */
    1054             :     Word16 *prev_Npeaks,       /* i/o: Peak number memory          Q0  */
    1055             :     Word16 *prev_peaks,        /* i/o: Peak indices memory         Q0  */
    1056             :     Word16 *hqswb_clas,        /* i/o: HQ class                    Q0  */
    1057             :     Word16 *Npeaks,            /* o  : Number of peaks             Q0  */
    1058             :     Word16 *peaks,             /* o  : Peak indices                Q0  */
    1059             :     const Word32 L_core_brate, /* i  : Core bit-rate               Q0  */
    1060             :     const Word16 last_core,    /* i  : Last core used              Q0  */
    1061             :     Word32 *L_nf_gains,        /* o  : Noisefloor gains            Q12 */
    1062             :     Word16 *hvq_hangover,      /* i/o: Mode-switch hangover        Q0  */
    1063             :     Word32 *L_pe_gains         /* o  : peak gains                  Q12 */
    1064             : )
    1065             : {
    1066             :     const Word16 *p_adj;
    1067             :     UWord16 lsb;
    1068             : 
    1069             :     Word32 L_input_abs[L_FRAME32k];
    1070             :     Word32 L_input_max;
    1071             :     Word32 L_thr[L_FRAME16k];
    1072             :     Word32 L_thr_tmp;
    1073             :     Word32 L_m;
    1074             :     Word32 L_tmp;
    1075             :     Word32 L_d;
    1076             :     Word32 L_peak;
    1077             :     Word32 L_nf, L_pe;
    1078             :     Word32 L_pe_mean[HVQ_NSUB_32k], L_nf_mean[HVQ_NSUB_32k];
    1079             : 
    1080             :     Word16 inv_nsub;
    1081             :     Word16 sharp_dist;
    1082             :     Word16 exp1, exp2;
    1083             :     Word16 tmp;
    1084             :     Word16 shift;
    1085             :     Word16 idx;
    1086             :     Word16 frac;
    1087             :     Word16 inv_nf_mean;
    1088             :     Word16 inv_gains_nsub;
    1089             :     Word16 nf_mean_norm;
    1090             :     Word16 num_sharp_bands, i, j, k, q, peak_th, nsub, pindx, N, offset;
    1091             :     Word16 num_peak_cands, high, low;
    1092             :     Word16 sharp[HVQ_NSUB_32k];
    1093             :     Word16 peak_cand_idx[HVQ_THRES_BIN_32k], avail_peaks[HVQ_NSUB_32k];
    1094             : #ifndef ISSUE_1867_replace_overflow_libenc
    1095             : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
    1096             :     Flag Overflow = 0;
    1097             :     move32();
    1098             : #endif
    1099             : #endif
    1100          66 :     L_input_max = L_deposit_l( 0 );
    1101          66 :     set32_fx( L_thr, 0, L_FRAME16k );
    1102             : 
    1103          66 :     IF( EQ_32( L_core_brate, HQ_24k40 ) )
    1104             :     {
    1105          66 :         nsub = HVQ_NSUB_24k;
    1106          66 :         move16();
    1107          66 :         inv_nsub = 4681; /* 1/7 in Q15 */
    1108          66 :         move16();
    1109          66 :         inv_gains_nsub = 10923; /* 1/3 in Q15 */
    1110          66 :         move16();
    1111             :     }
    1112             :     ELSE
    1113             :     {
    1114           0 :         nsub = HVQ_NSUB_32k;
    1115           0 :         move16();
    1116           0 :         inv_nsub = 3277; /* 1/10 in Q15 */
    1117           0 :         move16();
    1118           0 :         inv_gains_nsub = 6554; /* 1/5 in Q15 */
    1119           0 :         move16();
    1120             :     }
    1121             : 
    1122          66 :     N = shl( nsub, 5 ); /* Mult by 32 (HVQ_BW) */
    1123             : 
    1124          66 :     test();
    1125          66 :     test();
    1126          66 :     IF( EQ_16( *hqswb_clas, HQ_HARMONIC ) && last_core != ACELP_CORE && NE_16( last_core, AMR_WB_CORE ) )
    1127             :     {
    1128        4275 :         FOR( i = 0; i < N; i++ )
    1129             :         {
    1130        4256 :             L_input_abs[i] = L_abs( input[i] ); /* Q12 */
    1131        4256 :             IF( GT_32( L_input_abs[i], L_input_max ) )
    1132             :             {
    1133         104 :                 L_input_max = L_input_abs[i]; /* Q12 */
    1134         104 :                 move16();
    1135             :             }
    1136             :         }
    1137             : 
    1138          19 :         exp1 = norm_l( L_input_max );
    1139             : 
    1140          19 :         *Npeaks = 0;
    1141          19 :         move16();
    1142          19 :         L_nf = 3276800; /* 800 in Q12 */
    1143          19 :         move32();
    1144          19 :         L_pe = 3276800; /* 800 in Q12    */
    1145          19 :         move32();
    1146          19 :         num_sharp_bands = 0;
    1147          19 :         move16();
    1148          19 :         k = 0;
    1149          19 :         move16();
    1150          19 :         q = 0;
    1151          19 :         move16();
    1152          19 :         sharp_dist = 0;
    1153          19 :         move16();
    1154             : 
    1155             :         /* Find peak threshold */
    1156         152 :         FOR( i = 0; i < nsub; i++ )
    1157             :         {
    1158         133 :             L_peak = 0;
    1159         133 :             L_nf_mean[i] = 0;
    1160         133 :             L_pe_mean[i] = 0;
    1161         133 :             move32();
    1162         133 :             move32();
    1163         133 :             move32();
    1164        4389 :             FOR( j = 0; j < HVQ_BW; j++ )
    1165             :             {
    1166        4256 :                 L_d = L_input_abs[q]; /* Q12 */
    1167        4256 :                 move32();
    1168        4256 :                 IF( GT_32( L_d, L_nf ) )
    1169             :                 {
    1170             :                     /*nf = HVQ_NF_WEIGHT1 * nf + (1 - HVQ_NF_WEIGHT1) * d; */
    1171        2763 :                     Mpy_32_16_ss( L_d, HVQ_NF_WEIGHT1B, &L_tmp, &lsb );   /* 12+15-15=12 */
    1172        2763 :                     Mpy_32_16_ss( L_nf, HVQ_NF_WEIGHT1_FX, &L_nf, &lsb ); /* 12+15-15=12 */
    1173        2763 :                     L_nf = L_add( L_nf, L_tmp );                          /*Q12 */
    1174             :                 }
    1175             :                 ELSE
    1176             :                 {
    1177             :                     /*nf = HVQ_NF_WEIGHT2 * nf + (1 - HVQ_NF_WEIGHT2) * d; */
    1178        1493 :                     Mpy_32_16_ss( L_d, HVQ_NF_WEIGHT2B, &L_tmp, &lsb );   /* 12+15-15=12 */
    1179        1493 :                     Mpy_32_16_ss( L_nf, HVQ_NF_WEIGHT2_FX, &L_nf, &lsb ); /* 12+15-15=12 */
    1180        1493 :                     L_nf = L_add( L_nf, L_tmp );                          /*Q12 */
    1181             :                 }
    1182             : 
    1183        4256 :                 IF( GT_32( L_d, L_pe ) )
    1184             :                 {
    1185             :                     /*pe = HVQ_PE_WEIGHT1 * pe + (1 - HVQ_PE_WEIGHT1) * d; */
    1186        1110 :                     Mpy_32_16_ss( L_d, HVQ_PE_WEIGHT1B, &L_tmp, &lsb );   /* 12+15-15=12 */
    1187        1110 :                     Mpy_32_16_ss( L_pe, HVQ_PE_WEIGHT1_FX, &L_pe, &lsb ); /* 12+15-15=12 */
    1188        1110 :                     L_pe = L_add( L_pe, L_tmp );                          /*Q12 */
    1189             :                 }
    1190             :                 ELSE
    1191             :                 {
    1192             :                     /*pe = HVQ_PE_WEIGHT2 * pe + (1 - HVQ_PE_WEIGHT2) * d; */
    1193        3146 :                     Mpy_32_16_ss( L_d, HVQ_PE_WEIGHT2B, &L_tmp, &lsb );   /* 12+15-15=12 */
    1194        3146 :                     Mpy_32_16_ss( L_pe, HVQ_PE_WEIGHT2_FX, &L_pe, &lsb ); /* 12+15-15=12 */
    1195        3146 :                     L_pe = L_add( L_pe, L_tmp );                          /*Q12 */
    1196             :                 }
    1197             : 
    1198        4256 :                 L_nf_mean[i] = L_add_sat( L_nf_mean[i], L_nf ); /*Q12 */
    1199        4256 :                 L_pe_mean[i] = L_add_sat( L_pe_mean[i], L_pe ); /*Q12 */
    1200        4256 :                 move32();
    1201        4256 :                 move32();
    1202        4256 :                 IF( GT_32( L_d, L_peak ) )
    1203             :                 {
    1204         599 :                     L_peak = L_add( L_d, 0 );
    1205             :                 }
    1206             : 
    1207        4256 :                 q += 1;
    1208             :             }
    1209         133 :             L_nf_mean[i] = L_shr( L_nf_mean[i], 5 ); /* Divide by 5 (HVQ_BW) */
    1210         133 :             L_pe_mean[i] = L_shr( L_pe_mean[i], 5 ); /* Divide by 5 (HVQ_BW) */
    1211         133 :             move32();
    1212         133 :             move32();
    1213             : 
    1214             :             /*thr_tmp = (float)pow( pe_mean[i]/nf_mean[i], HVQ_THR_POW ) * nf_mean[i]; */
    1215         133 :             exp1 = norm_l( L_nf_mean[i] );
    1216         133 :             nf_mean_norm = extract_h( L_shl( L_nf_mean[i], exp1 ) ); /* 12+s-16=s-4 */
    1217         133 :             IF( nf_mean_norm == 0 )
    1218             :             {
    1219           0 :                 inv_nf_mean = 0;
    1220             :             }
    1221             :             ELSE
    1222             :             {
    1223         133 :                 inv_nf_mean = div_s( 1 << 14, nf_mean_norm ); /* 15+14-s+4=33-s */
    1224             :             }
    1225         133 :             Mpy_32_16_ss( L_pe_mean[i], inv_nf_mean, &L_tmp, &lsb ); /*12+33-s-15=30-s */
    1226             : 
    1227         133 :             exp2 = norm_l( L_tmp );
    1228         133 :             tmp = Log2_norm_lc( L_shl( L_tmp, exp2 ) ); /* Q15 */
    1229         133 :             exp2 = exp1 - exp2;                         /* Q0 */
    1230         133 :             L_tmp = Mpy_32_16( exp2, tmp, 32767 );      /* 1 in Q15. Q16 */
    1231         133 :             Mpy_32_16_ss( L_tmp, 28836, &L_tmp, &lsb ); /* 16+15-15=16 */
    1232         133 :             frac = L_Extract_lc( L_tmp, &tmp );         /* Q15 and Q0 */
    1233         133 :             L_tmp = Pow2( 14, frac );                   /* Q14 */
    1234         133 :             L_tmp = L_shl( L_tmp, tmp );                /* Q14 */
    1235             : 
    1236         133 :             Mpy_32_16_ss( L_tmp, nf_mean_norm, &L_tmp, &lsb );             /*14+s-4-15=s-5 */
    1237         133 :             shift = sub( 17, exp1 );                                       /* 16-(s-5)=17-s */
    1238         133 :             L_thr_tmp = L_shl( L_tmp, shift );                             /* Q16 */
    1239         133 :             L_thr_tmp = L_add( L_thr_tmp, lshr( lsb, sub( 16, shift ) ) ); /*Q16 */
    1240             : 
    1241         133 :             set32_fx( &L_thr[k], L_thr_tmp, HVQ_BW );
    1242         133 :             k = add( k, HVQ_BW );
    1243             : 
    1244             :             /*sharp[i] = peak/nf_mean[i]; */
    1245         133 :             Mpy_32_16_ss( L_peak, inv_nf_mean, &L_tmp, &lsb ); /* 12+33-s-15=30-s */
    1246         133 :             shift = sub( exp1, 8 );
    1247         133 :             sharp[i] = extract_h( L_shl( L_tmp, shift ) ); /* 30-s+s-8-16 -> Q6 */
    1248         133 :             move16();
    1249             : 
    1250             :             /*sharp_dist += (sharp[i]-HVQ_SHARP_THRES); */
    1251             : #ifdef ISSUE_1867_replace_overflow_libenc
    1252         133 :             sharp_dist = add_sat( sharp_dist, sub( sharp[i], HVQ_SHARP_THRES_FX ) );
    1253             : #else
    1254             :             sharp_dist = add_o( sharp_dist, sub( sharp[i], HVQ_SHARP_THRES_FX ), &Overflow );
    1255             : #endif
    1256         133 :             IF( GT_16( sharp[i], HVQ_SHARP_THRES_FX ) )
    1257             :             {
    1258          67 :                 num_sharp_bands = add( num_sharp_bands, 1 );
    1259             :             }
    1260             :         }
    1261             : 
    1262             :         /* Estimate noise floor gains */
    1263          19 :         offset = s_and( nsub, 1 );
    1264         133 :         FOR( i = 0; i < ( nsub & (Word16) 0xFFFE ); i++ )
    1265             :         {
    1266             :             /*(2*i+1)/nsub */
    1267         114 :             idx = mult( add( shl( i, 1 ), 1 ), add( inv_nsub, 1 ) ); /*0+15-15 = 0 */
    1268         114 :             L_nf_gains[idx] = L_add( L_nf_gains[idx], L_nf_mean[i + offset] );
    1269         114 :             L_pe_gains[idx] = L_add( L_pe_gains[idx], L_pe_mean[i + offset] );
    1270         114 :             move32();
    1271         114 :             move32();
    1272             :         }
    1273             : 
    1274          57 :         FOR( i = 0; i < HVQ_NF_GROUPS; i++ )
    1275             :         {
    1276          38 :             Mpy_32_16_ss( L_nf_gains[i], inv_gains_nsub, &L_nf_gains[i], &lsb ); /*12+15-15=12 */
    1277          38 :             Mpy_32_16_ss( L_pe_gains[i], inv_gains_nsub, &L_pe_gains[i], &lsb ); /*12+15-15=12 */
    1278             :         }
    1279             : 
    1280             :         /* Allocate available peaks */
    1281         152 :         FOR( i = 0; i < nsub; i++ )
    1282             :         {
    1283         133 :             avail_peaks[i] = HVQ_PA_PEAKS_SHARP1;
    1284         133 :             move16();
    1285         133 :             idx = mult( add( shl( i, 1 ), 1 ), add( inv_nsub, 1 ) );      /*0+15-15 = 0 */
    1286         133 :             Mpy_32_16_ss( L_nf_gains[idx], HVQ_PA_FAC_FX, &L_tmp, &lsb ); /* 12+15-15 -> Q12 */
    1287         133 :             IF( LT_32( L_nf_mean[i], L_tmp ) )
    1288             :             {
    1289          39 :                 IF( LT_16( sharp[i], HVQ_PA_SHARP_THRES3_FX ) )
    1290             :                 {
    1291          34 :                     avail_peaks[i] = HVQ_PA_PEAKS_SHARP3;
    1292          34 :                     move16();
    1293             :                 }
    1294           5 :                 ELSE IF( LT_16( sharp[i], HVQ_PA_SHARP_THRES2_FX ) )
    1295             :                 {
    1296           4 :                     avail_peaks[i] = HVQ_PA_PEAKS_SHARP2;
    1297           4 :                     move16();
    1298             :                 }
    1299             :             }
    1300             :         }
    1301             : 
    1302             : 
    1303             :         /* Adjust threshold around previous peaks */
    1304          19 :         FOR( i = 0; i < *prev_Npeaks; i++ )
    1305             :         {
    1306           0 :             j = sub( prev_peaks[i], 2 ); /* Q0 */
    1307           0 :             k = add( prev_peaks[i], 2 ); /* Q0 */
    1308           0 :             p_adj = hvq_thr_adj_fx;      /* Q15 */
    1309           0 :             move16();
    1310             : 
    1311           0 :             FOR( q = j; q < k; q++ )
    1312             :             {
    1313           0 :                 Mpy_32_16_ss( L_thr[q], *p_adj++, &L_thr[q], &lsb ); /* 12+15-15=12 */
    1314           0 :                 move32();
    1315             :             }
    1316             :         }
    1317             : 
    1318          19 :         num_peak_cands = 0;
    1319          19 :         move16();
    1320             : 
    1321             :         /* Remove everything below threshold for peak search */
    1322          19 :         L_input_abs[0] = L_deposit_l( 0 );
    1323          19 :         L_input_abs[1] = L_deposit_l( 0 );
    1324          19 :         L_input_abs[N - 2] = L_deposit_l( 0 );
    1325          19 :         L_input_abs[N - 1] = L_deposit_l( 0 );
    1326          19 :         move32();
    1327          19 :         move32();
    1328          19 :         move32();
    1329          19 :         move32();
    1330        4237 :         FOR( i = 0; i < N - 2; i++ )
    1331             :         {
    1332        4218 :             IF( LT_32( L_input_abs[i], L_thr[i] ) )
    1333             :             {
    1334        3120 :                 L_input_abs[i] = L_deposit_l( 0 );
    1335        3120 :                 move32();
    1336             :             }
    1337             :             ELSE
    1338             :             {
    1339        1098 :                 L_input_abs[num_peak_cands] = L_input_abs[i]; /* Q12 */
    1340        1098 :                 move32();
    1341        1098 :                 peak_cand_idx[num_peak_cands] = i; /* Q0 */
    1342        1098 :                 move16();
    1343        1098 :                 num_peak_cands = add( num_peak_cands, 1 );
    1344             :             }
    1345             :         }
    1346          19 :         IF( EQ_32( L_core_brate, HQ_24k40 ) )
    1347             :         {
    1348          19 :             peak_th = HVQ_MAX_PEAKS_24k_CLAS;
    1349          19 :             move16();
    1350             :         }
    1351             :         ELSE
    1352             :         {
    1353           0 :             peak_th = HVQ_MAX_PEAKS_32k;
    1354           0 :             move16();
    1355             :         }
    1356             :         /* Find peaks */
    1357          19 :         pindx = maximum_32_fx( L_input_abs, num_peak_cands, &L_m );
    1358          19 :         i = 0;
    1359          19 :         move16();
    1360             : 
    1361         461 :         WHILE( L_m > 0 && LT_16( i, peak_th + 1 ) )
    1362             :         {
    1363         442 :             idx = mult( peak_cand_idx[pindx], INV_HVQ_BW ); /* 0+15-15=0 */
    1364         442 :             IF( avail_peaks[idx] > 0 )
    1365             :             {
    1366         398 :                 peaks[i++] = peak_cand_idx[pindx]; /* Q0 */
    1367         398 :                 move16();
    1368         398 :                 avail_peaks[idx]--;
    1369             :             }
    1370             : 
    1371         442 :             j = sub( pindx, 2 );
    1372         442 :             k = add( pindx, 2 );
    1373             : 
    1374         442 :             if ( j < 0 )
    1375             :             {
    1376          19 :                 j = 0;
    1377          19 :                 move16();
    1378             :             }
    1379             : 
    1380         442 :             tmp = sub( num_peak_cands, 1 );
    1381         442 :             if ( GT_16( k, tmp ) )
    1382             :             {
    1383          17 :                 k = tmp;
    1384          17 :                 move16();
    1385             :             }
    1386             : 
    1387         442 :             low = sub( peak_cand_idx[pindx], 2 );
    1388         442 :             high = add( peak_cand_idx[pindx], 2 );
    1389             : 
    1390         442 :             if ( low < 0 )
    1391             :             {
    1392           0 :                 low = 0;
    1393           0 :                 move16();
    1394             :             }
    1395             : 
    1396         442 :             tmp = sub( N, 1 );
    1397         442 :             IF( GT_16( high, tmp ) )
    1398             :             {
    1399           0 :                 high = tmp;
    1400           0 :                 move16();
    1401             :             }
    1402             : 
    1403        1738 :             FOR( q = j; q <= pindx; q++ )
    1404             :             {
    1405        1296 :                 IF( GE_16( peak_cand_idx[q], low ) )
    1406             :                 {
    1407         649 :                     peak_cand_idx[q] = 0;
    1408         649 :                     move16();
    1409         649 :                     L_input_abs[q] = 0;
    1410         649 :                     move16();
    1411             :                 }
    1412             :             }
    1413             : 
    1414        1299 :             FOR( q = pindx + 1; q <= k; q++ )
    1415             :             {
    1416         857 :                 IF( LE_16( peak_cand_idx[q], high ) )
    1417             :                 {
    1418         529 :                     peak_cand_idx[q] = 0;
    1419         529 :                     move16();
    1420         529 :                     L_input_abs[q] = 0;
    1421         529 :                     move16();
    1422             :                 }
    1423             :             }
    1424             : 
    1425         442 :             pindx = maximum_32_fx( L_input_abs, num_peak_cands, &L_m ); /* Q0 */
    1426             :         }
    1427             : 
    1428          19 :         *Npeaks = i;
    1429          19 :         move16();
    1430          19 :         IF( GT_16( *Npeaks, HVQ_MIN_PEAKS ) )
    1431             :         {
    1432          19 :             test();
    1433          19 :             IF( GT_16( num_sharp_bands, sub( nsub, 3 ) ) && LE_16( *Npeaks, peak_th ) )
    1434             :             {
    1435           0 :                 sharp_dist = mult( sharp_dist, inv_nsub ); /*x+15-15=x */
    1436           0 :                 test();
    1437           0 :                 IF( LE_16( sharp_dist, SHARP_DIST_THRES_FX ) && *hvq_hangover < 0 )
    1438             :                 {
    1439           0 :                     *hvq_hangover = add( *hvq_hangover, 1 );
    1440             :                 }
    1441             :                 ELSE
    1442             :                 {
    1443           0 :                     *hqswb_clas = HQ_HVQ; /* Q0 */
    1444           0 :                     move16();
    1445           0 :                     *hvq_hangover = 2; /* Q0 */
    1446           0 :                     move16();
    1447             :                 }
    1448             : 
    1449             :                 /* update memory */
    1450           0 :                 *prev_Npeaks = *Npeaks; /* Q0 */
    1451           0 :                 move16();
    1452           0 :                 Copy( peaks, prev_peaks, *Npeaks ); /* Q0 */
    1453             :             }
    1454             :             ELSE
    1455             :             {
    1456          19 :                 IF( *hvq_hangover > 0 )
    1457             :                 {
    1458           0 :                     *hqswb_clas = HQ_HVQ; /* Q0 */
    1459           0 :                     move16();
    1460           0 :                     *hvq_hangover = sub( *hvq_hangover, 1 ); /* Q0 */
    1461           0 :                     move16();
    1462             :                 }
    1463             :                 ELSE
    1464             :                 {
    1465          19 :                     *hvq_hangover = -1;
    1466          19 :                     move16();
    1467             :                 }
    1468             :             }
    1469             :         }
    1470             :         ELSE
    1471             :         {
    1472             :             /* Zero peaks, likely silence input. */
    1473           0 :             *hvq_hangover = -1;
    1474           0 :             move16();
    1475             :         }
    1476             : 
    1477          19 :         IF( EQ_32( L_core_brate, HQ_24k40 ) )
    1478             :         {
    1479          19 :             *Npeaks = s_min( HVQ_MAX_PEAKS_24k, *Npeaks ); /* Q0 */
    1480          19 :             move16();
    1481             :         }
    1482             :         ELSE
    1483             :         {
    1484           0 :             *Npeaks = s_min( HVQ_MAX_PEAKS_32k, *Npeaks ); /* Q0 */
    1485           0 :             move16();
    1486             :         }
    1487             :     }
    1488             :     ELSE
    1489             :     {
    1490          47 :         *prev_Npeaks = 0;
    1491          47 :         move16();
    1492          47 :         *hvq_hangover = 0;
    1493          47 :         move16();
    1494             :     }
    1495             : 
    1496             : 
    1497          66 :     return;
    1498             : }

Generated by: LCOV version 1.14