LCOV - code coverage report
Current view: top level - lib_dec - cng_dec_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main enc/dec/rend @ 3b2f07138c61dcf997bbf4165d0882f794b2995f Lines: 541 745 72.6 %
Date: 2025-05-03 01:55:50 Functions: 5 6 83.3 %

          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"
       8             : #include "rom_com.h"
       9             : #include "prot_fx.h"
      10             : #include "ivas_cnst.h"
      11             : 
      12             : /*Temporary location to be move in prot* when merge is done*/
      13             : void E_LPC_f_isp_a_conversion( const Word16 *isp, Word16 *a, const Word16 m );
      14             : void E_LPC_f_lsp_a_conversion( const Word16 *isp, Word16 *a, const Word16 m );
      15             : 
      16             : /*-----------------------------------------------------------------*
      17             :  * Local function prototypes
      18             :  *-----------------------------------------------------------------*/
      19             : 
      20             : static void shb_CNG_decod_fx( Decoder_State *st_fx, const Word16 *synth_fx, Word16 *shb_synth_fx, const Word16 sid_bw, const Word16 Qsyn );
      21             : 
      22             : static void shb_CNG_decod_ivas_fx( Decoder_State *st_fx, const Word16 *synth_fx, Word16 *shb_synth_fx, const Word16 sid_bw, const Word16 Qsyn );
      23             : 
      24             : /*-----------------------------------------------------------------*
      25             :  * Decode residual signal energy
      26             :  *-----------------------------------------------------------------*/
      27             : 
      28             : #ifndef REMOVE_EVS_DUPLICATES
      29             : void CNG_dec_fx(
      30             :     Decoder_State *st_fx,           /* i/o: State structure                          */
      31             :     const Word16 last_element_mode, /* i  : last element mode                    Q0   */
      32             :     Word16 Aq[],                    /* o  : LP coefficients                     Q12  */
      33             :     Word16 *lsp_new,                /* i/o: current frame LSPs                  Q15  */
      34             :     Word16 *lsf_new,                /* i/o: current frame LSFs                  Qlog2(2.56) */
      35             :     Word16 *allow_cn_step,          /* o  : allow CN step                       Q0   */
      36             :     Word16 *sid_bw                  /* i  : 0-NB/WB, 1-SWB SID                  Q0   */
      37             :     ,
      38             :     Word32 *q_env )
      39             : {
      40             :     Word16 istep;
      41             :     Word16 i, L_enr_index;
      42             :     Word32 L_ener;
      43             :     Word16 ener_fra, ener_int;
      44             :     Word16 num_bits;
      45             :     Word16 weights, ptr, j, k;
      46             :     Word16 m1;
      47             :     Word16 m = 0;
      48             :     move16();
      49             :     Word16 tmp[HO_HIST_SIZE * M];
      50             :     Word16 burst_ho_cnt = 0;
      51             :     move16();
      52             :     Word16 ll, s_ptr;
      53             :     Word32 L_enr, L_tmp1;
      54             :     Word16 tmp1, exp;
      55             :     Word16 lsf_tmp[M];
      56             :     Word32 C[M];
      57             :     Word32 max_val[2];
      58             :     Word16 max_idx[2];
      59             :     Word16 ftmp_fx;
      60             :     Word16 lsp_tmp[M];
      61             :     Word16 dev;
      62             :     Word16 max_dev;
      63             :     Word16 dist;
      64             :     Word16 tmpv;
      65             :     Word16 env_idx[2];
      66             :     Word32 enr1;
      67             :     Word32 env[NUM_ENV_CNG];
      68             :     Word32 tmp_env[HO_HIST_SIZE * NUM_ENV_CNG];
      69             :     Word32 L_tmp;
      70             :     Word16 fra;
      71             :     Word16 temp_lo_fx, temp_hi_fx;
      72             :     Word16 exp_pow;
      73             :     Word16 tmp_loop;
      74             :     Word16 enr_new, Aq_tmp[M + 1];
      75             : 
      76             :     Word16 LSF_Q_prediction; /* o  : LSF prediction mode - just temporary variable in CNG                */
      77             :     TD_CNG_DEC_HANDLE hTdCngDec;
      78             : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
      79             :     Flag Overflow = 0;
      80             :     move32();
      81             : #endif
      82             :     hTdCngDec = st_fx->hTdCngDec;
      83             : 
      84             :     m = 0;
      85             :     move16();
      86             :     /*-----------------------------------------------------------------*
      87             :      * Decode CNG spectral envelope (only in SID frame)
      88             :      *-----------------------------------------------------------------*/
      89             :     test();
      90             :     IF( EQ_32( st_fx->core_brate, SID_1k75 ) || EQ_32( st_fx->core_brate, SID_2k40 ) )
      91             :     {
      92             :         /* de-quantize the LSF vector */
      93             :         IF( st_fx->Opt_AMR_WB != 0 )
      94             :         {
      95             :             /* Flt function */
      96             :             isf_dec_amr_wb_fx( st_fx, Aq, lsf_new, lsp_new );
      97             :             /* check IF ISPs  may trigger too much synthesis energy */
      98             : 
      99             :             E_LPC_f_isp_a_conversion( lsp_new, Aq_tmp, M );
     100             :             enr_new = Enr_1_Az_fx( Aq_tmp, 2 * L_SUBFR );
     101             : 
     102             :             IF( ( shr( enr_new, 14 ) > 0 ) )
     103             :             {
     104             :                 /* Use old LSP vector */
     105             :                 Copy( st_fx->lsp_old_fx, lsp_new, M ); /* Q15 */
     106             :                 Copy( st_fx->lsf_old_fx, lsf_new, M ); /* Q2.56 */
     107             :             }
     108             :         }
     109             :         ELSE
     110             :         {
     111             :             lsf_dec_fx( st_fx, 0, Aq, &LSF_Q_prediction, lsf_new, lsp_new, 0, 0,
     112             :                         NULL );
     113             :             /* check IF LSPs  may trigger too much synthesis energy */
     114             : 
     115             :             E_LPC_f_lsp_a_conversion( lsp_new, Aq_tmp, M );
     116             :             enr_new = Enr_1_Az_fx( Aq_tmp, 2 * L_SUBFR );
     117             : 
     118             :             IF( shr( enr_new, 14 ) > 0 )
     119             :             {
     120             :                 /* Use old LSP vector */
     121             :                 Copy( st_fx->lsp_old_fx, lsp_new, M ); /* Q15 */
     122             :                 Copy( st_fx->lsf_old_fx, lsf_new, M ); /* Q2.56 */
     123             :             }
     124             :         }
     125             :     }
     126             :     ELSE
     127             :     {
     128             :         /* Use old LSP vector */
     129             :         Copy( st_fx->lsp_old_fx, lsp_new, M ); /* Q15 */
     130             :         Copy( st_fx->lsf_old_fx, lsf_new, M ); /* Q2.56 */
     131             :     }
     132             : 
     133             :     /* Initialize the CNG spectral envelope in case of the very first CNG frame */
     134             :     IF( st_fx->first_CNG == 0 )
     135             :     {
     136             :         Copy( st_fx->lsp_old_fx, st_fx->lspCNG_fx, M ); /* Q15 */
     137             :     }
     138             : 
     139             :     /*-----------------------------------------------------------------*
     140             :      * Decode residual signal energy
     141             :      *-----------------------------------------------------------------*/
     142             : 
     143             :     *allow_cn_step = 0;
     144             :     move16();
     145             :     test();
     146             :     IF( EQ_32( st_fx->core_brate, SID_1k75 ) || EQ_32( st_fx->core_brate, SID_2k40 ) )
     147             :     {
     148             :         istep = ISTEP_AMR_WB_SID_FX; /* Q15 */
     149             :         move16();
     150             :         if ( EQ_32( st_fx->core_brate, SID_2k40 ) )
     151             :         {
     152             :             istep = ISTEP_SID_FX; /* Q15 */
     153             :             move16();
     154             :         }
     155             : 
     156             :         /* initialize the energy quantization parameters */
     157             :         num_bits = 6;
     158             :         move16();
     159             :         if ( st_fx->Opt_AMR_WB == 0 )
     160             :         {
     161             :             num_bits = 7;
     162             :             move16();
     163             :         }
     164             : 
     165             :         /* decode the energy index */
     166             :         L_enr_index = get_next_indice_fx( st_fx, num_bits );
     167             : 
     168             :         IF( LE_32( st_fx->last_core_brate, SID_2k40 ) || EQ_16( st_fx->prev_bfi, 1 ) )
     169             :         {
     170             :             tmp1 = add( hTdCngDec->old_enr_index, 20 );
     171             :         }
     172             :         ELSE
     173             :         {
     174             :             tmp1 = add( hTdCngDec->old_enr_index, 40 );
     175             :         }
     176             :         IF( GT_16( L_enr_index, tmp1 ) && hTdCngDec->old_enr_index >= 0 ) /* Likely bit error and not startup */
     177             :         {
     178             :             L_enr_index = tmp1;
     179             :             move16();
     180             :             L_enr_index = s_min( L_enr_index, 127 ); /* Q0 */
     181             :             IF( st_fx->Opt_AMR_WB )
     182             :             {
     183             :                 L_enr_index = s_min( L_enr_index, 63 ); /* Q0 */
     184             :             }
     185             :         }
     186             : 
     187             :         test();
     188             :         test();
     189             :         test();
     190             :         IF( GT_32( st_fx->last_core_brate, SID_1k75 ) &&
     191             :             NE_16( st_fx->first_CNG, 0 ) &&
     192             :             GE_16( hTdCngDec->old_enr_index, 0 ) &&
     193             :             GT_16( L_enr_index, add( hTdCngDec->old_enr_index, 1 ) ) )
     194             :         {
     195             :             *allow_cn_step = 1;
     196             :             move16();
     197             :         }
     198             : 
     199             :         hTdCngDec->old_enr_index = L_enr_index;
     200             :         move16();
     201             :         if ( !L_enr_index )
     202             :         {
     203             :             L_enr_index = -5;
     204             :             move16();
     205             :         }
     206             :         /* st_fx->Enew = L_enr_index / step - 2.0f;*/
     207             :         L_ener = L_mult( L_enr_index, istep ); /* Q16 (0+15) */
     208             :         /* subtract by 2 not done to leave Energy in Q2 */
     209             : 
     210             :         /* extract integral and fractional parts */
     211             :         ener_fra = L_Extract_lc( L_ener, &ener_int );
     212             :         ener_int = add( ener_int, 4 ); /* Q2 to Q6 */
     213             : 
     214             :         /* find the new energy value */
     215             :         hTdCngDec->Enew_fx = Pow2( ener_int, ener_fra );
     216             :         move32();
     217             : 
     218             :         IF( EQ_32( st_fx->core_brate, SID_2k40 ) )
     219             :         {
     220             :             burst_ho_cnt = get_next_indice_fx( st_fx, 3 ); /* 3bit */
     221             : 
     222             :             *sid_bw = get_next_indice_fx( st_fx, 1 );
     223             :             move16();
     224             :             IF( *sid_bw == 0 )
     225             :             {
     226             :                 env_idx[0] = get_next_indice_fx( st_fx, 6 );
     227             :                 move16();
     228             : 
     229             :                 /* get quantized res_env_details */
     230             :                 FOR( i = 0; i < NUM_ENV_CNG; i++ )
     231             :                 {
     232             :                     q_env[i] = L_deposit_l( CNG_details_codebook_fx[env_idx[0]][i] );
     233             :                     move32();
     234             :                 }
     235             :             }
     236             :         }
     237             :         /* Reset CNG history IF CNG frame length is changed */
     238             :         test();
     239             :         test();
     240             :         IF( EQ_16( st_fx->bwidth, WB ) && NE_16( st_fx->first_CNG, 0 ) && NE_16( st_fx->L_frame, st_fx->last_CNG_L_frame ) )
     241             :         {
     242             :             hTdCngDec->ho_hist_size = 0;
     243             :             move16();
     244             :         }
     245             :     }
     246             : 
     247             :     /*---------------------------------------------------------------------*
     248             :      * CNG spectral envelope update
     249             :      * Find A(z) coefficients
     250             :      *---------------------------------------------------------------------*/
     251             :     test();
     252             :     test();
     253             :     test();
     254             :     IF( LE_32( st_fx->last_core_brate, SID_2k40 ) )
     255             :     {
     256             :         /* Reset hangover counter if not first SID period */
     257             :         if ( GT_32( st_fx->core_brate, FRAME_NO_DATA ) )
     258             :         {
     259             :             hTdCngDec->num_ho = 0;
     260             :             move16();
     261             :         }
     262             :         /* Update LSPs IF last SID energy not outliers or insufficient number of hangover frames */
     263             :         test();
     264             :         IF( LT_16( hTdCngDec->num_ho, 3 ) || LT_32( Mult_32_16( hTdCngDec->Enew_fx, 21845 /*1/1.5f, Q15*/ ), st_fx->lp_ener_fx ) )
     265             :         {
     266             :             FOR( i = 0; i < M; i++ )
     267             :             {
     268             :                 /* AR low-pass filter  */
     269             :                 st_fx->lspCNG_fx[i] = mac_r( L_mult( CNG_ISF_FACT_FX, st_fx->lspCNG_fx[i] ), 32768 - CNG_ISF_FACT_FX, lsp_new[i] );
     270             :                 move16(); /* Q15 (15+15+1-16) */
     271             :             }
     272             :         }
     273             :     }
     274             :     ELSE
     275             :     {
     276             :         /* Update CNG_mode IF allowed */
     277             :         test();
     278             :         test();
     279             :         test();
     280             :         IF( ( st_fx->Opt_AMR_WB || EQ_16( st_fx->bwidth, WB ) ) && ( !st_fx->first_CNG || GE_16( hTdCngDec->act_cnt2, MIN_ACT_CNG_UPD ) ) )
     281             :         {
     282             :             IF( GT_32( st_fx->last_active_brate, ACELP_16k40 ) )
     283             :             {
     284             :                 st_fx->CNG_mode = -1;
     285             :                 move16();
     286             :             }
     287             :             ELSE
     288             :             {
     289             :                 st_fx->CNG_mode = get_cng_mode( st_fx->last_active_brate );
     290             :                 move16();
     291             :             }
     292             :         }
     293             : 
     294             :         /* If first sid after active burst update LSF history from circ buffer */
     295             :         burst_ho_cnt = s_min( burst_ho_cnt, hTdCngDec->ho_circ_size ); /* MODE1_DTX_IN_CODEC_B_FIX   Q0*/
     296             :         hTdCngDec->act_cnt = 0;
     297             :         move16();
     298             :         s_ptr = add( sub( hTdCngDec->ho_circ_ptr, burst_ho_cnt ), 1 );
     299             :         IF( s_ptr < 0 )
     300             :         {
     301             :             s_ptr = add( s_ptr, hTdCngDec->ho_circ_size );
     302             :         }
     303             : 
     304             :         FOR( ll = burst_ho_cnt; ll > 0; ll-- )
     305             :         {
     306             :             hTdCngDec->ho_hist_ptr = add( hTdCngDec->ho_hist_ptr, 1 ); /* Q0 */
     307             :             move16();
     308             :             if ( EQ_16( hTdCngDec->ho_hist_ptr, HO_HIST_SIZE ) )
     309             :             {
     310             :                 hTdCngDec->ho_hist_ptr = 0;
     311             :                 move16();
     312             :             }
     313             : 
     314             :             /* Conversion between 12.8k and 16k LSPs */
     315             :             test();
     316             :             test();
     317             :             test();
     318             :             IF( ( EQ_16( st_fx->L_frame, L_FRAME16k ) && hTdCngDec->ho_16k_lsp[s_ptr] == 0 ) || ( EQ_16( st_fx->L_frame, L_FRAME ) && EQ_16( hTdCngDec->ho_16k_lsp[s_ptr], 1 ) ) )
     319             :             {
     320             :                 /* Conversion from 16k LPSs to 12k8 */
     321             :                 lsp_convert_poly_fx( &( hTdCngDec->ho_lsp_circ_fx[s_ptr * M] ), st_fx->L_frame, 0 );
     322             :             }
     323             :             /* update the circular buffers */
     324             :             Copy( &( hTdCngDec->ho_lsp_circ_fx[s_ptr * M] ), &( hTdCngDec->ho_lsp_hist_fx[hTdCngDec->ho_hist_ptr * M] ), M ); /* Qx */
     325             :             Copy32( &( hTdCngDec->ho_ener_circ_fx[s_ptr] ), &( hTdCngDec->ho_ener_hist_fx[hTdCngDec->ho_hist_ptr] ), 1 );     /* Q6 */
     326             :             hTdCngDec->ho_sid_bw = L_shl( L_and( hTdCngDec->ho_sid_bw, (Word32) 0x3fffffffL ), 1 );
     327             :             move32();
     328             :             Copy32( &( hTdCngDec->ho_env_circ_fx[s_ptr * NUM_ENV_CNG] ), &( hTdCngDec->ho_env_hist_fx[hTdCngDec->ho_hist_ptr * NUM_ENV_CNG] ), NUM_ENV_CNG ); /* Qx */
     329             : 
     330             :             hTdCngDec->ho_hist_size = add( hTdCngDec->ho_hist_size, 1 );
     331             :             move16();
     332             : 
     333             :             if ( GT_16( hTdCngDec->ho_hist_size, HO_HIST_SIZE ) )
     334             :             {
     335             :                 hTdCngDec->ho_hist_size = HO_HIST_SIZE;
     336             :                 move16();
     337             :             }
     338             : 
     339             :             s_ptr = add( s_ptr, 1 );
     340             :             if ( EQ_16( s_ptr, hTdCngDec->ho_circ_size ) )
     341             :             {
     342             :                 s_ptr = 0;
     343             :                 move16();
     344             :             }
     345             :         }
     346             : 
     347             :         IF( hTdCngDec->ho_hist_size > 0 ) /* can be -1 at init    MODE1_DTX_IN_CODEC_B_FIX    */
     348             :         {
     349             :             /* *allow_cn_step |= ( st_fx->ho_ener_hist[st_fx->ho_hist_ptr] > 4.0f * st_fx->lp_ener );*/
     350             :             L_tmp1 = L_shr( hTdCngDec->ho_ener_hist_fx[hTdCngDec->ho_hist_ptr], 2 );
     351             :             L_tmp1 = L_sub( L_tmp1, st_fx->lp_ener_fx );
     352             : 
     353             :             test();
     354             :             test();
     355             :             IF( ( L_tmp1 > 0 && ( st_fx->first_CNG || st_fx->element_mode == EVS_MONO ) ) )
     356             :             {
     357             :                 *allow_cn_step = s_or( *allow_cn_step, 1 );
     358             :                 move16();
     359             :             }
     360             :         }
     361             :         IF( EQ_16( last_element_mode, IVAS_CPE_TD ) )
     362             :         {
     363             :             *allow_cn_step = 1;
     364             :             move16();
     365             :         }
     366             :         test();
     367             :         IF( EQ_16( *allow_cn_step, 0 ) && GT_16( hTdCngDec->ho_hist_size, 0 ) )
     368             :         {
     369             :             /* Use average of energies below last energy */
     370             :             ptr = hTdCngDec->ho_hist_ptr;
     371             :             move16();
     372             :             Copy( &( hTdCngDec->ho_lsp_hist_fx[ptr * M] ), tmp, M ); /* Qx */
     373             :             m1 = 0;
     374             :             move16();
     375             :             IF( L_and( hTdCngDec->ho_sid_bw, (Word32) 0x1 ) == 0 )
     376             :             {
     377             :                 Copy32( &hTdCngDec->ho_env_hist_fx[ptr * NUM_ENV_CNG], tmp_env, NUM_ENV_CNG );
     378             :                 m1 = 1;
     379             :                 move16();
     380             :             }
     381             :             L_enr = Mult_32_16( hTdCngDec->ho_ener_hist_fx[ptr], W_DTX_HO_FX[0] ); /* Q6+15-15->Q6 */
     382             : 
     383             :             weights = W_DTX_HO_FX[0]; /* Q15 */
     384             :             move16();
     385             : 
     386             :             m = 1;
     387             :             move16();
     388             :             FOR( k = 1; k < hTdCngDec->ho_hist_size; k++ )
     389             :             {
     390             :                 ptr--;
     391             :                 if ( ptr < 0 )
     392             :                 {
     393             :                     ptr = HO_HIST_SIZE - 1;
     394             :                     move16();
     395             :                 }
     396             : 
     397             :                 test();
     398             :                 IF( LT_32( Mult_32_16( hTdCngDec->ho_ener_hist_fx[ptr], ONE_OVER_BUF_H_NRG_FX ), hTdCngDec->ho_ener_hist_fx[hTdCngDec->ho_hist_ptr] ) &&
     399             :                     GT_32( hTdCngDec->ho_ener_hist_fx[ptr], Mult_32_16( hTdCngDec->ho_ener_hist_fx[hTdCngDec->ho_hist_ptr], BUF_L_NRG_FX ) ) )
     400             :                 {
     401             :                     /*enr += W_DTX_HO[k] * st_fx->ho_ener_hist[ptr];*/
     402             :                     L_tmp1 = Mult_32_16( hTdCngDec->ho_ener_hist_fx[ptr], W_DTX_HO_FX[k] ); /* Q6+15-15->Q6 */
     403             :                     L_enr = L_add( L_enr, L_tmp1 );                                         /* Q6 */
     404             : 
     405             :                     /*weights += W_DTX_HO[k];*/
     406             :                     weights = add( weights, W_DTX_HO_FX[k] ); /* Q15 */
     407             : 
     408             :                     Copy( &hTdCngDec->ho_lsp_hist_fx[ptr * M], &tmp[m * M], M ); /* Qx */
     409             :                     IF( EQ_32( L_and( hTdCngDec->ho_sid_bw, L_shl( (Word32) 0x1, k ) ), 0 ) )
     410             :                     {
     411             :                         Copy32( &hTdCngDec->ho_env_hist_fx[ptr * NUM_ENV_CNG], &tmp_env[m1 * NUM_ENV_CNG], NUM_ENV_CNG ); /* Qx */
     412             :                         m1++;
     413             :                     }
     414             :                     m++;
     415             :                 }
     416             :             }
     417             : 
     418             :             /*enr /= weights;*/
     419             :             exp = norm_s( weights );
     420             :             tmp1 = div_s( shl( 1, sub( 14, exp ) ), weights ); /* Q(15+14-exp-15) */
     421             :             L_tmp1 = Mult_32_16( L_enr, tmp1 );                /* Q(14-exp+6-15)->Q(5-exp) */
     422             :             L_enr = L_shl( L_tmp1, add( exp, 1 ) );            /* Q6 */
     423             : 
     424             :             st_fx->lp_ener_fx = L_enr; /* Q6 */
     425             :             move32();
     426             :             set32_fx( max_val, 0, 2 );
     427             :             set16_fx( max_idx, 0, 2 );
     428             : 
     429             :             FOR( i = 0; i < m; i++ )
     430             :             {
     431             :                 IF( EQ_16( st_fx->L_frame, L_FRAME ) )
     432             :                 {
     433             :                     lsp2lsf_fx( &tmp[i * M], lsf_tmp, M, INT_FS_FX );
     434             :                     ftmp_fx = 964;
     435             :                     move16();                                            /*X2.56 */
     436             :                     tmpv = sub( 16384, add( lsf_tmp[M - 1], ftmp_fx ) ); /*QX2.56*/
     437             :                     L_tmp = L_mult0( tmpv, tmpv );                       /*QX6.5536*/
     438             :                 }
     439             :                 ELSE
     440             :                 {
     441             :                     lsp2lsf_fx( &tmp[i * M], lsf_tmp, M, INT_FS_16k_FX );
     442             :                     ftmp_fx = 1205;
     443             :                     move16();                                            /*QX2.56*/
     444             :                     tmpv = sub( 20480, add( lsf_tmp[M - 1], ftmp_fx ) ); /*QX2.56*/
     445             :                     L_tmp = L_mult0( tmpv, tmpv );                       /*QX6.5536*/
     446             :                 }
     447             : 
     448             :                 tmpv = sub( lsf_tmp[0], ftmp_fx );   /*QX2.56*/
     449             :                 L_tmp = L_mac0( L_tmp, tmpv, tmpv ); /*QX6.5536*/
     450             :                 FOR( j = 0; j < M - 1; j++ )
     451             :                 {
     452             :                     tmpv = sub( sub( lsf_tmp[j + 1], lsf_tmp[j] ), ftmp_fx ); /*QX2.56*/
     453             :                     L_tmp = L_mac0( L_tmp, tmpv, tmpv );                      /*QX6.5536*/
     454             :                 }
     455             : 
     456             :                 C[i] = Mpy_32_16_1( L_tmp, 1928 ); /*QX6.5536*/
     457             :                 move32();
     458             : 
     459             :                 IF( GT_32( C[i], max_val[0] ) )
     460             :                 {
     461             :                     max_val[1] = max_val[0];
     462             :                     move32();
     463             :                     max_idx[1] = max_idx[0];
     464             :                     move16();
     465             :                     max_val[0] = C[i];
     466             :                     move32();
     467             :                     max_idx[0] = i;
     468             :                     move16();
     469             :                 }
     470             :                 ELSE IF( GT_32( C[i], max_val[1] ) )
     471             :                 {
     472             :                     max_val[1] = C[i];
     473             :                     move32();
     474             :                     max_idx[1] = i;
     475             :                     move16();
     476             :                 }
     477             :             }
     478             : 
     479             :             IF( EQ_16( m, 1 ) )
     480             :             {
     481             :                 Copy( tmp, lsp_tmp, M ); /* Qx */
     482             :             }
     483             :             ELSE IF( LT_16( m, 4 ) )
     484             :             {
     485             :                 FOR( i = 0; i < M; i++ )
     486             :                 {
     487             :                     L_tmp1 = 0;
     488             :                     move32();
     489             :                     FOR( j = 0; j < m; j++ )
     490             :                     {
     491             :                         L_tmp1 = L_add( L_tmp1, L_deposit_l( tmp[j * M + i] ) );
     492             :                     }
     493             : 
     494             :                     L_tmp1 = L_sub( L_tmp1, L_deposit_l( tmp[max_idx[0] * M + i] ) );
     495             :                     tmpv = div_s( 1, sub( m, 1 ) );       /*Q15*/
     496             :                     L_tmp1 = Mpy_32_16_1( L_tmp1, tmpv ); /*Q15*/
     497             :                     lsp_tmp[i] = extract_l( L_tmp1 );     /*Q15*/
     498             :                     move16();
     499             :                 }
     500             :             }
     501             :             ELSE
     502             :             {
     503             :                 FOR( i = 0; i < M; i++ )
     504             :                 {
     505             :                     L_tmp1 = 0;
     506             :                     move32();
     507             :                     FOR( j = 0; j < m; j++ )
     508             :                     {
     509             :                         L_tmp1 = L_add( L_tmp1, L_deposit_l( tmp[j * M + i] ) );
     510             :                     }
     511             : 
     512             :                     L_tmp1 = L_sub( L_tmp1, L_add( L_deposit_l( tmp[max_idx[0] * M + i] ), L_deposit_l( tmp[max_idx[1] * M + i] ) ) ); /*Q15*/
     513             :                     tmpv = div_s( 1, sub( m, 2 ) );                                                                                    /*Q15*/
     514             :                     L_tmp1 = Mpy_32_16_1( L_tmp1, tmpv );                                                                              /*Q15*/
     515             :                     lsp_tmp[i] = extract_l( L_tmp1 );                                                                                  /*Q15*/
     516             :                     move16();
     517             :                 }
     518             :             }
     519             : 
     520             :             dist = 0;
     521             :             move16(); /*Q15*/
     522             :             max_dev = 0;
     523             :             move16(); /*Q15*/
     524             :             FOR( i = 0; i < M; i++ )
     525             :             {
     526             :                 dev = abs_s( sub( lsp_tmp[i], lsp_new[i] ) ); /*Q15*/
     527             :                 dist = add_o( dist, dev, &Overflow );         /*Q15*/
     528             :                 if ( GT_16( dev, max_dev ) )
     529             :                 {
     530             :                     max_dev = dev;
     531             :                     move16();
     532             :                 }
     533             :             }
     534             : 
     535             :             test();
     536             :             IF( GT_16( dist, 13107 ) || GT_16( max_dev, 3277 ) ) /* 0.4 and 0.1 in Q15 */
     537             :             {
     538             :                 FOR( i = 0; i < M; i++ )
     539             :                 {
     540             :                     st_fx->lspCNG_fx[i] = lsp_tmp[i];
     541             :                     move16(); /*Q15*/
     542             :                 }
     543             :             }
     544             :             ELSE
     545             :             {
     546             :                 FOR( i = 0; i < M; i++ )
     547             :                 {
     548             :                     /* AR low-pass filter  */
     549             :                     st_fx->lspCNG_fx[i] = add( mult_r( 26214, lsp_tmp[i] ), mult_r( 6554, lsp_new[i] ) ); /* Q15 */
     550             :                     move16();
     551             :                 }
     552             :             }
     553             :             IF( m1 > 0 )
     554             :             {
     555             :                 FOR( i = 0; i < NUM_ENV_CNG; i++ )
     556             :                 {
     557             :                     L_tmp = L_deposit_l( 0 );
     558             :                     FOR( j = 0; j < m1; j++ )
     559             :                     {
     560             :                         /* env[i] += tmp_env[j*NUM_ENV_CNG+i];*/
     561             :                         L_tmp = L_add_sat( L_tmp, tmp_env[j * NUM_ENV_CNG + i] );
     562             :                     }
     563             :                     /*    env[i] /= (float)m1;  */
     564             :                     /*    env[i] = env[i] - 2*st_fx->lp_ener_fx; */
     565             :                     IF( EQ_16( m1, 1 ) )
     566             :                     {
     567             :                         L_tmp = L_sub_sat( L_tmp, L_add_sat( st_fx->lp_ener_fx, st_fx->lp_ener_fx ) ); /* Q6 */
     568             :                     }
     569             :                     ELSE
     570             :                     {
     571             :                         tmp1 = div_s( 1, m1 );
     572             :                         L_tmp = Mult_32_16( L_tmp, tmp1 );                                             /* Q6 */
     573             :                         L_tmp = L_sub_sat( L_tmp, L_add_sat( st_fx->lp_ener_fx, st_fx->lp_ener_fx ) ); /* Q6 */
     574             :                     }
     575             :                     env[i] = L_tmp; /* Q6 */
     576             :                     move32();
     577             :                 }
     578             : 
     579             :                 Copy32( env, hTdCngDec->lp_env_fx, NUM_ENV_CNG ); /* Q6 */
     580             :             }
     581             :         }
     582             :         ELSE
     583             :         {
     584             :             Copy( lsp_new, st_fx->lspCNG_fx, M ); /* use newly analyzed ISFs */ /* Q15 */
     585             :         }
     586             :     }
     587             : 
     588             :     test();
     589             :     IF( EQ_32( st_fx->core_brate, SID_1k75 ) || EQ_32( st_fx->core_brate, SID_2k40 ) )
     590             :     {
     591             :         /* Update hangover memory during CNG */
     592             :         test();
     593             :         IF( ( *allow_cn_step == 0 ) && LT_32( hTdCngDec->Enew_fx, L_add_sat( st_fx->lp_ener_fx, L_shr( st_fx->lp_ener_fx, 1 ) ) ) )
     594             :         {
     595             :             /* update the pointer to circular buffer of old LSP vectors */
     596             :             hTdCngDec->ho_hist_ptr++;
     597             :             move16();
     598             :             if ( EQ_16( hTdCngDec->ho_hist_ptr, HO_HIST_SIZE ) )
     599             :             {
     600             :                 hTdCngDec->ho_hist_ptr = 0;
     601             :                 move16();
     602             :             }
     603             : 
     604             :             /* update the circular buffer of old LSP vectors with the new LSP vector */
     605             :             Copy( lsp_new, &( hTdCngDec->ho_lsp_hist_fx[( hTdCngDec->ho_hist_ptr ) * M] ), M ); /* Q15 */
     606             : 
     607             :             /* update the hangover energy buffer */
     608             :             hTdCngDec->ho_ener_hist_fx[hTdCngDec->ho_hist_ptr] = hTdCngDec->Enew_fx; /* Q6 */
     609             :             move32();
     610             :             test();
     611             :             IF( EQ_32( st_fx->core_brate, SID_2k40 ) && ( *sid_bw == 0 ) )
     612             :             {
     613             :                 /*  enr1 = (float)log10( st->Enew*L_frame + 0.1f ) / (float)log10( 2.0f );*/
     614             :                 exp = norm_l( hTdCngDec->Enew_fx );
     615             :                 L_tmp = L_shl( hTdCngDec->Enew_fx, exp );              /*Q(exp+6)*/
     616             :                 L_tmp = Mult_32_16( L_tmp, shl( st_fx->L_frame, 5 ) ); /*Q(exp+6+5-15=exp-4)*/
     617             :                 L_tmp = L_shr_sat( L_tmp, sub( exp, 10 ) );            /*Q6*/
     618             :                 exp = norm_l( L_tmp );
     619             :                 fra = Log2_norm_lc( L_shl( L_tmp, exp ) );
     620             :                 exp = sub( sub( 30, exp ), 6 );
     621             :                 L_tmp = L_Comp( exp, fra );
     622             :                 enr1 = L_shr( L_tmp, 10 ); /* Q6 */
     623             : 
     624             :                 FOR( i = 0; i < NUM_ENV_CNG; i++ )
     625             :                 {
     626             :                     /* get quantized envelope */
     627             :                     /*  env[i] = pow(2.0f,(enr1 - q_env[i])) + 2*st->Enew;*/
     628             :                     L_tmp = L_sub( enr1, q_env[i] ); /* Q6 */
     629             :                     L_tmp = L_shl( L_tmp, 10 );      /* 16 */
     630             :                     temp_lo_fx = L_Extract_lc( L_tmp, &temp_hi_fx );
     631             : 
     632             :                     exp_pow = sub( 14, temp_hi_fx );
     633             :                     L_tmp = Pow2( 14, temp_lo_fx );             /* Qexp_pow */
     634             :                     env[i] = L_shl( L_tmp, sub( 6, exp_pow ) ); /* Q6 */
     635             :                     move32();
     636             :                     L_tmp = L_add( hTdCngDec->Enew_fx, hTdCngDec->Enew_fx );
     637             :                     env[i] = L_add( env[i], L_tmp ); /* Q6 */
     638             :                     move32();
     639             :                 }
     640             :                 hTdCngDec->ho_sid_bw = L_shl( L_and( hTdCngDec->ho_sid_bw, (Word32) 0x3fffffffL ), 1 ); /* Q0 */
     641             :                 move32();
     642             :                 Copy32( env, &( hTdCngDec->ho_env_hist_fx[hTdCngDec->ho_hist_ptr * NUM_ENV_CNG] ), NUM_ENV_CNG ); /* Q6 */
     643             :             }
     644             :             ELSE IF( ( *sid_bw != 0 ) )
     645             :             {
     646             :                 hTdCngDec->ho_sid_bw = L_shl( L_and( hTdCngDec->ho_sid_bw, (Word32) 0x3fffffffL ), 1 ); /* Q0 */
     647             :                 move32();
     648             :                 hTdCngDec->ho_sid_bw = L_or( hTdCngDec->ho_sid_bw, 0x1L ); /* Q0 */
     649             :                 move32();
     650             :             }
     651             : 
     652             :             hTdCngDec->ho_hist_size = add( hTdCngDec->ho_hist_size, 1 );
     653             :             move16();
     654             :             if ( GT_16( hTdCngDec->ho_hist_size, HO_HIST_SIZE ) )
     655             :             {
     656             :                 hTdCngDec->ho_hist_size = HO_HIST_SIZE;
     657             :                 move16();
     658             :             }
     659             :         }
     660             :         /* Update the frame length memory */
     661             :         st_fx->last_CNG_L_frame = st_fx->L_frame;
     662             :         move16();
     663             : 
     664             :         if ( NE_32( st_fx->core_brate, SID_1k75 ) )
     665             :         {
     666             :             hTdCngDec->num_ho = m;
     667             :             move16();
     668             :         }
     669             :     }
     670             : 
     671             :     IF( st_fx->element_mode == EVS_MONO )
     672             :     {
     673             :         st_fx->last_CNG_L_frame = st_fx->L_frame;
     674             :         move16();
     675             : 
     676             :         IF( NE_32( st_fx->core_brate, SID_1k75 ) )
     677             :         {
     678             :             hTdCngDec->num_ho = m;
     679             :             move16();
     680             :         }
     681             :     }
     682             :     IF( st_fx->Opt_AMR_WB )
     683             :     {
     684             :         E_LPC_f_isp_a_conversion( st_fx->lspCNG_fx, Aq, M );
     685             :     }
     686             :     ELSE
     687             :     {
     688             :         E_LPC_f_lsp_a_conversion( st_fx->lspCNG_fx, Aq, M );
     689             :     }
     690             : 
     691             :     tmp_loop = shr( st_fx->L_frame, 6 );
     692             :     FOR( i = 1; i < tmp_loop; i++ ) /* L_frame/L_SUBFR */
     693             :     {
     694             :         Copy( Aq, &Aq[i * ( M + 1 )], add( M, 1 ) ); /* Q12 */
     695             :     }
     696             : 
     697             :     return;
     698             : }
     699             : #endif
     700        2378 : void CNG_dec_ivas_fx(
     701             :     Decoder_State *st_fx,           /* i/o: State structure                          */
     702             :     const Word16 last_element_mode, /* i  : last element mode                    Q0   */
     703             :     Word16 Aq[],                    /* o  : LP coefficients                     Q12  */
     704             :     Word16 *lsp_new,                /* i/o: current frame LSPs                  Q15  */
     705             :     Word16 *lsf_new,                /* i/o: current frame LSFs                  Qlog2(2.56) */
     706             :     Word16 *allow_cn_step,          /* o  : allow CN step                       Q0   */
     707             :     Word16 *sid_bw                  /* i  : 0-NB/WB, 1-SWB SID                  Q0   */
     708             :     ,
     709             :     Word32 *q_env )
     710             : {
     711             :     Word16 istep;
     712             :     Word16 i, L_enr_index;
     713             :     Word32 L_ener;
     714             :     Word16 ener_fra, ener_int;
     715             :     Word16 num_bits;
     716             :     Word16 weights, ptr, j, k;
     717             :     Word16 m1;
     718        2378 :     Word16 m = 0;
     719        2378 :     move16();
     720             :     Word16 tmp[HO_HIST_SIZE * M];
     721        2378 :     Word16 burst_ho_cnt = 0;
     722        2378 :     move16();
     723             :     Word16 ll, s_ptr;
     724             :     Word32 L_enr, L_tmp1;
     725             :     Word16 tmp1, exp;
     726             :     Word16 lsf_tmp[M];
     727             :     Word32 C[M];
     728             :     Word32 max_val[2];
     729             :     Word16 max_idx[2];
     730             :     Word16 ftmp_fx;
     731             :     Word16 lsp_tmp[M];
     732             :     Word16 dev;
     733             :     Word16 max_dev;
     734             :     Word16 dist;
     735             :     Word16 tmpv;
     736             :     Word16 env_idx[2];
     737             :     Word32 enr1;
     738             :     Word32 env[NUM_ENV_CNG];
     739             :     Word32 tmp_env[HO_HIST_SIZE * NUM_ENV_CNG];
     740             :     Word32 L_tmp;
     741             :     Word16 fra;
     742             :     Word16 temp_lo_fx, temp_hi_fx;
     743             :     Word16 exp_pow;
     744             :     Word16 tmp_loop;
     745             :     Word16 enr_new, Aq_tmp[M + 1];
     746             : 
     747             :     Word16 LSF_Q_prediction; /* o  : LSF prediction mode - just temporary variable in CNG                */
     748             :     TD_CNG_DEC_HANDLE hTdCngDec;
     749             : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
     750        2378 :     Flag Overflow = 0;
     751        2378 :     move32();
     752             : #endif
     753        2378 :     hTdCngDec = st_fx->hTdCngDec;
     754             : 
     755        2378 :     m = 0;
     756        2378 :     move16();
     757             :     /*-----------------------------------------------------------------*
     758             :      * Decode CNG spectral envelope (only in SID frame)
     759             :      *-----------------------------------------------------------------*/
     760        2378 :     test();
     761        2378 :     IF( EQ_32( st_fx->core_brate, SID_1k75 ) || EQ_32( st_fx->core_brate, SID_2k40 ) )
     762             :     {
     763             :         /* de-quantize the LSF vector */
     764         417 :         IF( st_fx->Opt_AMR_WB != 0 )
     765             :         {
     766             :             /* Flt function */
     767           0 :             isf_dec_amr_wb_fx( st_fx, Aq, lsf_new, lsp_new );
     768             :             /* check IF ISPs  may trigger too much synthesis energy */
     769             : 
     770           0 :             E_LPC_f_isp_a_conversion( lsp_new, Aq_tmp, M );
     771           0 :             enr_new = Enr_1_Az_fx( Aq_tmp, 2 * L_SUBFR );
     772             : 
     773           0 :             IF( ( shr( enr_new, 14 ) > 0 ) )
     774             :             {
     775             :                 /* Use old LSP vector */
     776           0 :                 Copy( st_fx->lsp_old_fx, lsp_new, M ); /* Q15 */
     777           0 :                 Copy( st_fx->lsf_old_fx, lsf_new, M ); /* Q2.56 */
     778             :             }
     779             :         }
     780             :         ELSE
     781             :         {
     782         417 :             lsf_dec_ivas_fx( st_fx, 0, Aq, &LSF_Q_prediction, lsf_new, lsp_new, 0, 0,
     783             :                              NULL );
     784             :             /* check IF LSPs  may trigger too much synthesis energy */
     785             : 
     786         417 :             E_LPC_f_lsp_a_conversion( lsp_new, Aq_tmp, M );
     787         417 :             enr_new = Enr_1_Az_fx( Aq_tmp, 2 * L_SUBFR );
     788             : 
     789         417 :             IF( shr( enr_new, 14 ) > 0 )
     790             :             {
     791             :                 /* Use old LSP vector */
     792           0 :                 Copy( st_fx->lsp_old_fx, lsp_new, M ); /* Q15 */
     793           0 :                 Copy( st_fx->lsf_old_fx, lsf_new, M ); /* Q2.56 */
     794             :             }
     795             :         }
     796             :     }
     797             :     ELSE
     798             :     {
     799             :         /* Use old LSP vector */
     800        1961 :         Copy( st_fx->lsp_old_fx, lsp_new, M ); /* Q15 */
     801        1961 :         Copy( st_fx->lsf_old_fx, lsf_new, M ); /* Q2.56 */
     802             :     }
     803             : 
     804             :     /* Initialize the CNG spectral envelope in case of the very first CNG frame */
     805        2378 :     IF( st_fx->first_CNG == 0 )
     806             :     {
     807          28 :         Copy( st_fx->lsp_old_fx, st_fx->lspCNG_fx, M ); /* Q15 */
     808             :     }
     809             : 
     810             :     /*-----------------------------------------------------------------*
     811             :      * Decode residual signal energy
     812             :      *-----------------------------------------------------------------*/
     813             : 
     814        2378 :     *allow_cn_step = 0;
     815        2378 :     move16();
     816        2378 :     test();
     817        2378 :     IF( EQ_32( st_fx->core_brate, SID_1k75 ) || EQ_32( st_fx->core_brate, SID_2k40 ) )
     818             :     {
     819         417 :         istep = ISTEP_AMR_WB_SID_FX; /* Q15 */
     820         417 :         move16();
     821         417 :         if ( EQ_32( st_fx->core_brate, SID_2k40 ) )
     822             :         {
     823         417 :             istep = ISTEP_SID_FX; /* Q15 */
     824         417 :             move16();
     825             :         }
     826             : 
     827             :         /* initialize the energy quantization parameters */
     828         417 :         num_bits = 6;
     829         417 :         move16();
     830         417 :         if ( st_fx->Opt_AMR_WB == 0 )
     831             :         {
     832         417 :             num_bits = 7;
     833         417 :             move16();
     834             :         }
     835             : 
     836             :         /* decode the energy index */
     837         417 :         L_enr_index = get_next_indice_fx( st_fx, num_bits );
     838             : 
     839         417 :         IF( LE_32( st_fx->last_core_brate, SID_2k40 ) || EQ_16( st_fx->prev_bfi, 1 ) )
     840             :         {
     841         228 :             tmp1 = add( hTdCngDec->old_enr_index, 20 );
     842             :         }
     843             :         ELSE
     844             :         {
     845         189 :             tmp1 = add( hTdCngDec->old_enr_index, 40 );
     846             :         }
     847         417 :         IF( GT_16( L_enr_index, tmp1 ) && hTdCngDec->old_enr_index >= 0 ) /* Likely bit error and not startup */
     848             :         {
     849           0 :             L_enr_index = tmp1;
     850           0 :             move16();
     851           0 :             L_enr_index = s_min( L_enr_index, 127 ); /* Q0 */
     852           0 :             IF( st_fx->Opt_AMR_WB )
     853             :             {
     854           0 :                 L_enr_index = s_min( L_enr_index, 63 ); /* Q0 */
     855             :             }
     856             :         }
     857             : 
     858         417 :         test();
     859         417 :         test();
     860         417 :         test();
     861         417 :         IF( GT_32( st_fx->last_core_brate, SID_1k75 ) &&
     862             :             NE_16( st_fx->first_CNG, 0 ) &&
     863             :             GE_16( hTdCngDec->old_enr_index, 0 ) &&
     864             :             GT_16( L_enr_index, add( hTdCngDec->old_enr_index, 1 ) ) )
     865             :         {
     866           0 :             *allow_cn_step = 1;
     867           0 :             move16();
     868             :         }
     869             : 
     870         417 :         hTdCngDec->old_enr_index = L_enr_index;
     871         417 :         move16();
     872         417 :         if ( !L_enr_index )
     873             :         {
     874          18 :             L_enr_index = -5;
     875          18 :             move16();
     876             :         }
     877             :         /* st_fx->Enew = L_enr_index / step - 2.0f;*/
     878         417 :         L_ener = L_mult( L_enr_index, istep ); /* Q16 (0+15) */
     879             :         /* subtract by 2 not done to leave Energy in Q2 */
     880             : 
     881             :         /* extract integral and fractional parts */
     882         417 :         ener_fra = L_Extract_lc( L_ener, &ener_int );
     883         417 :         ener_int = add( ener_int, 4 ); /* Q2 to Q6 */
     884             : 
     885             :         /* find the new energy value */
     886         417 :         hTdCngDec->Enew_fx = Pow2( ener_int, ener_fra );
     887         417 :         move32();
     888             : 
     889         417 :         IF( EQ_32( st_fx->core_brate, SID_2k40 ) )
     890             :         {
     891         417 :             burst_ho_cnt = get_next_indice_fx( st_fx, 3 ); /* 3bit */
     892             : 
     893         417 :             *sid_bw = get_next_indice_fx( st_fx, 1 );
     894         417 :             move16();
     895         417 :             IF( *sid_bw == 0 )
     896             :             {
     897           0 :                 env_idx[0] = get_next_indice_fx( st_fx, 6 );
     898           0 :                 move16();
     899             : 
     900             :                 /* get quantized res_env_details */
     901           0 :                 FOR( i = 0; i < NUM_ENV_CNG; i++ )
     902             :                 {
     903           0 :                     q_env[i] = L_deposit_l( CNG_details_codebook_fx[env_idx[0]][i] );
     904           0 :                     move32();
     905             :                 }
     906             :             }
     907             :         }
     908             :         /* Reset CNG history IF CNG frame length is changed */
     909         417 :         test();
     910         417 :         test();
     911         417 :         IF( EQ_16( st_fx->bwidth, WB ) && NE_16( st_fx->first_CNG, 0 ) && NE_16( st_fx->L_frame, st_fx->last_CNG_L_frame ) )
     912             :         {
     913           1 :             hTdCngDec->ho_hist_size = 0;
     914           1 :             move16();
     915             :         }
     916             :     }
     917             : 
     918             :     /*---------------------------------------------------------------------*
     919             :      * CNG spectral envelope update
     920             :      * Find A(z) coefficients
     921             :      *---------------------------------------------------------------------*/
     922        2378 :     test();
     923        2378 :     test();
     924        2378 :     test();
     925        2378 :     IF( LE_32( st_fx->last_core_brate, SID_2k40 ) )
     926             :     {
     927             :         /* Reset hangover counter if not first SID period */
     928        2189 :         if ( GT_32( st_fx->core_brate, FRAME_NO_DATA ) )
     929             :         {
     930         228 :             hTdCngDec->num_ho = 0;
     931         228 :             move16();
     932             :         }
     933             :         /* Update LSPs IF last SID energy not outliers or insufficient number of hangover frames */
     934        2189 :         test();
     935        2189 :         IF( LT_16( hTdCngDec->num_ho, 3 ) || LT_32( Mult_32_16( hTdCngDec->Enew_fx, 21845 /*1/1.5f, Q15*/ ), st_fx->lp_ener_fx ) )
     936             :         {
     937       36669 :             FOR( i = 0; i < M; i++ )
     938             :             {
     939             :                 /* AR low-pass filter  */
     940       34512 :                 st_fx->lspCNG_fx[i] = mac_r( L_mult( CNG_ISF_FACT_FX, st_fx->lspCNG_fx[i] ), 32768 - CNG_ISF_FACT_FX, lsp_new[i] );
     941       34512 :                 move16(); /* Q15 (15+15+1-16) */
     942             :             }
     943             :         }
     944             :     }
     945             :     ELSE
     946             :     {
     947             :         /* Update CNG_mode IF allowed */
     948         189 :         test();
     949         189 :         test();
     950         189 :         test();
     951         189 :         IF( ( st_fx->Opt_AMR_WB || EQ_16( st_fx->bwidth, WB ) ) && ( !st_fx->first_CNG || GE_16( hTdCngDec->act_cnt2, MIN_ACT_CNG_UPD ) ) )
     952             :         {
     953           6 :             IF( GT_32( st_fx->last_active_brate, ACELP_16k40 ) )
     954             :             {
     955           3 :                 st_fx->CNG_mode = -1;
     956           3 :                 move16();
     957             :             }
     958             :             ELSE
     959             :             {
     960           3 :                 st_fx->CNG_mode = get_cng_mode( st_fx->last_active_brate );
     961           3 :                 move16();
     962             :             }
     963             :         }
     964             : 
     965             :         /* If first sid after active burst update LSF history from circ buffer */
     966         189 :         burst_ho_cnt = s_min( burst_ho_cnt, hTdCngDec->ho_circ_size ); /* MODE1_DTX_IN_CODEC_B_FIX   Q0*/
     967         189 :         hTdCngDec->act_cnt = 0;
     968         189 :         move16();
     969         189 :         s_ptr = add( sub( hTdCngDec->ho_circ_ptr, burst_ho_cnt ), 1 );
     970         189 :         IF( s_ptr < 0 )
     971             :         {
     972          34 :             s_ptr = add( s_ptr, hTdCngDec->ho_circ_size );
     973             :         }
     974             : 
     975         478 :         FOR( ll = burst_ho_cnt; ll > 0; ll-- )
     976             :         {
     977         289 :             hTdCngDec->ho_hist_ptr = add( hTdCngDec->ho_hist_ptr, 1 ); /* Q0 */
     978         289 :             move16();
     979         289 :             if ( EQ_16( hTdCngDec->ho_hist_ptr, HO_HIST_SIZE ) )
     980             :             {
     981          25 :                 hTdCngDec->ho_hist_ptr = 0;
     982          25 :                 move16();
     983             :             }
     984             : 
     985             :             /* Conversion between 12.8k and 16k LSPs */
     986         289 :             test();
     987         289 :             test();
     988         289 :             test();
     989         289 :             IF( ( EQ_16( st_fx->L_frame, L_FRAME16k ) && hTdCngDec->ho_16k_lsp[s_ptr] == 0 ) || ( EQ_16( st_fx->L_frame, L_FRAME ) && EQ_16( hTdCngDec->ho_16k_lsp[s_ptr], 1 ) ) )
     990             :             {
     991             :                 /* Conversion from 16k LPSs to 12k8 */
     992          61 :                 lsp_convert_poly_fx( &( hTdCngDec->ho_lsp_circ_fx[s_ptr * M] ), st_fx->L_frame, 0 );
     993             :             }
     994             :             /* update the circular buffers */
     995         289 :             Copy( &( hTdCngDec->ho_lsp_circ_fx[s_ptr * M] ), &( hTdCngDec->ho_lsp_hist_fx[hTdCngDec->ho_hist_ptr * M] ), M ); /* Qx */
     996         289 :             Copy32( &( hTdCngDec->ho_ener_circ_fx[s_ptr] ), &( hTdCngDec->ho_ener_hist_fx[hTdCngDec->ho_hist_ptr] ), 1 );     /* Q6 */
     997         289 :             hTdCngDec->ho_sid_bw = L_shl( L_and( hTdCngDec->ho_sid_bw, (Word32) 0x3fffffffL ), 1 );
     998         289 :             move32();
     999         289 :             Copy32( &( hTdCngDec->ho_env_circ_fx[s_ptr * NUM_ENV_CNG] ), &( hTdCngDec->ho_env_hist_fx[hTdCngDec->ho_hist_ptr * NUM_ENV_CNG] ), NUM_ENV_CNG ); /* Qx */
    1000             : 
    1001         289 :             hTdCngDec->ho_hist_size = add( hTdCngDec->ho_hist_size, 1 );
    1002         289 :             move16();
    1003             : 
    1004         289 :             if ( GT_16( hTdCngDec->ho_hist_size, HO_HIST_SIZE ) )
    1005             :             {
    1006          32 :                 hTdCngDec->ho_hist_size = HO_HIST_SIZE;
    1007          32 :                 move16();
    1008             :             }
    1009             : 
    1010         289 :             s_ptr = add( s_ptr, 1 );
    1011         289 :             if ( EQ_16( s_ptr, hTdCngDec->ho_circ_size ) )
    1012             :             {
    1013          36 :                 s_ptr = 0;
    1014          36 :                 move16();
    1015             :             }
    1016             :         }
    1017             : 
    1018         189 :         IF( hTdCngDec->ho_hist_size > 0 ) /* can be -1 at init    MODE1_DTX_IN_CODEC_B_FIX    */
    1019             :         {
    1020             :             /* *allow_cn_step |= ( st_fx->ho_ener_hist[st_fx->ho_hist_ptr] > 4.0f * st_fx->lp_ener );*/
    1021         137 :             L_tmp1 = L_shr( hTdCngDec->ho_ener_hist_fx[hTdCngDec->ho_hist_ptr], 2 );
    1022         137 :             L_tmp1 = L_sub( L_tmp1, st_fx->lp_ener_fx );
    1023             : 
    1024         137 :             test();
    1025         137 :             test();
    1026         137 :             IF( ( L_tmp1 > 0 && ( st_fx->first_CNG || st_fx->element_mode == EVS_MONO ) ) )
    1027             :             {
    1028           8 :                 *allow_cn_step = s_or( *allow_cn_step, 1 );
    1029           8 :                 move16();
    1030             :             }
    1031             :         }
    1032         189 :         IF( EQ_16( last_element_mode, IVAS_CPE_TD ) )
    1033             :         {
    1034          15 :             *allow_cn_step = 1;
    1035          15 :             move16();
    1036             :         }
    1037         189 :         test();
    1038         189 :         IF( EQ_16( *allow_cn_step, 0 ) && GT_16( hTdCngDec->ho_hist_size, 0 ) )
    1039             :         {
    1040             :             /* Use average of energies below last energy */
    1041         122 :             ptr = hTdCngDec->ho_hist_ptr;
    1042         122 :             move16();
    1043         122 :             Copy( &( hTdCngDec->ho_lsp_hist_fx[ptr * M] ), tmp, M ); /* Qx */
    1044         122 :             m1 = 0;
    1045         122 :             move16();
    1046         122 :             IF( L_and( hTdCngDec->ho_sid_bw, (Word32) 0x1 ) == 0 )
    1047             :             {
    1048          77 :                 Copy32( &hTdCngDec->ho_env_hist_fx[ptr * NUM_ENV_CNG], tmp_env, NUM_ENV_CNG );
    1049          77 :                 m1 = 1;
    1050          77 :                 move16();
    1051             :             }
    1052         122 :             L_enr = Mult_32_16( hTdCngDec->ho_ener_hist_fx[ptr], W_DTX_HO_FX[0] ); /* Q6+15-15->Q6 */
    1053             : 
    1054         122 :             weights = W_DTX_HO_FX[0]; /* Q15 */
    1055         122 :             move16();
    1056             : 
    1057         122 :             m = 1;
    1058         122 :             move16();
    1059         531 :             FOR( k = 1; k < hTdCngDec->ho_hist_size; k++ )
    1060             :             {
    1061         409 :                 ptr--;
    1062         409 :                 if ( ptr < 0 )
    1063             :                 {
    1064          22 :                     ptr = HO_HIST_SIZE - 1;
    1065          22 :                     move16();
    1066             :                 }
    1067             : 
    1068         409 :                 test();
    1069         409 :                 IF( LT_32( Mult_32_16( hTdCngDec->ho_ener_hist_fx[ptr], ONE_OVER_BUF_H_NRG_FX ), hTdCngDec->ho_ener_hist_fx[hTdCngDec->ho_hist_ptr] ) &&
    1070             :                     GT_32( hTdCngDec->ho_ener_hist_fx[ptr], Mult_32_16( hTdCngDec->ho_ener_hist_fx[hTdCngDec->ho_hist_ptr], BUF_L_NRG_FX ) ) )
    1071             :                 {
    1072             :                     /*enr += W_DTX_HO[k] * st_fx->ho_ener_hist[ptr];*/
    1073         185 :                     L_tmp1 = Mult_32_16( hTdCngDec->ho_ener_hist_fx[ptr], W_DTX_HO_FX[k] ); /* Q6+15-15->Q6 */
    1074         185 :                     L_enr = L_add( L_enr, L_tmp1 );                                         /* Q6 */
    1075             : 
    1076             :                     /*weights += W_DTX_HO[k];*/
    1077         185 :                     weights = add( weights, W_DTX_HO_FX[k] ); /* Q15 */
    1078             : 
    1079         185 :                     Copy( &hTdCngDec->ho_lsp_hist_fx[ptr * M], &tmp[m * M], M ); /* Qx */
    1080         185 :                     IF( EQ_32( L_and( hTdCngDec->ho_sid_bw, L_shl( (Word32) 0x1, k ) ), 0 ) )
    1081             :                     {
    1082         122 :                         Copy32( &hTdCngDec->ho_env_hist_fx[ptr * NUM_ENV_CNG], &tmp_env[m1 * NUM_ENV_CNG], NUM_ENV_CNG ); /* Qx */
    1083         122 :                         m1++;
    1084             :                     }
    1085         185 :                     m++;
    1086             :                 }
    1087             :             }
    1088             : 
    1089             :             /*enr /= weights;*/
    1090         122 :             exp = norm_s( weights );
    1091         122 :             tmp1 = div_s( shl( 1, sub( 14, exp ) ), weights ); /* Q(15+14-exp-15) */
    1092         122 :             L_tmp1 = Mult_32_16( L_enr, tmp1 );                /* Q(14-exp+6-15)->Q(5-exp) */
    1093         122 :             L_enr = L_shl( L_tmp1, add( exp, 1 ) );            /* Q6 */
    1094             : 
    1095         122 :             st_fx->lp_ener_fx = L_enr; /* Q6 */
    1096         122 :             move32();
    1097         122 :             set32_fx( max_val, 0, 2 );
    1098         122 :             set16_fx( max_idx, 0, 2 );
    1099             : 
    1100         429 :             FOR( i = 0; i < m; i++ )
    1101             :             {
    1102         307 :                 IF( EQ_16( st_fx->L_frame, L_FRAME ) )
    1103             :                 {
    1104         201 :                     lsp2lsf_fx( &tmp[i * M], lsf_tmp, M, INT_FS_FX );
    1105         201 :                     ftmp_fx = 964;
    1106         201 :                     move16();                                            /*X2.56 */
    1107         201 :                     tmpv = sub( 16384, add( lsf_tmp[M - 1], ftmp_fx ) ); /*QX2.56*/
    1108         201 :                     L_tmp = L_mult0( tmpv, tmpv );                       /*QX6.5536*/
    1109             :                 }
    1110             :                 ELSE
    1111             :                 {
    1112         106 :                     lsp2lsf_fx( &tmp[i * M], lsf_tmp, M, INT_FS_16k_FX );
    1113         106 :                     ftmp_fx = 1205;
    1114         106 :                     move16();                                            /*QX2.56*/
    1115         106 :                     tmpv = sub( 20480, add( lsf_tmp[M - 1], ftmp_fx ) ); /*QX2.56*/
    1116         106 :                     L_tmp = L_mult0( tmpv, tmpv );                       /*QX6.5536*/
    1117             :                 }
    1118             : 
    1119         307 :                 tmpv = sub( lsf_tmp[0], ftmp_fx );   /*QX2.56*/
    1120         307 :                 L_tmp = L_mac0( L_tmp, tmpv, tmpv ); /*QX6.5536*/
    1121        4912 :                 FOR( j = 0; j < M - 1; j++ )
    1122             :                 {
    1123        4605 :                     tmpv = sub( sub( lsf_tmp[j + 1], lsf_tmp[j] ), ftmp_fx ); /*QX2.56*/
    1124        4605 :                     L_tmp = L_mac0( L_tmp, tmpv, tmpv );                      /*QX6.5536*/
    1125             :                 }
    1126             : 
    1127         307 :                 C[i] = Mpy_32_16_1( L_tmp, 1928 ); /*QX6.5536*/
    1128         307 :                 move32();
    1129             : 
    1130         307 :                 IF( GT_32( C[i], max_val[0] ) )
    1131             :                 {
    1132         220 :                     max_val[1] = max_val[0];
    1133         220 :                     move32();
    1134         220 :                     max_idx[1] = max_idx[0];
    1135         220 :                     move16();
    1136         220 :                     max_val[0] = C[i];
    1137         220 :                     move32();
    1138         220 :                     max_idx[0] = i;
    1139         220 :                     move16();
    1140             :                 }
    1141          87 :                 ELSE IF( GT_32( C[i], max_val[1] ) )
    1142             :                 {
    1143          49 :                     max_val[1] = C[i];
    1144          49 :                     move32();
    1145          49 :                     max_idx[1] = i;
    1146          49 :                     move16();
    1147             :                 }
    1148             :             }
    1149             : 
    1150         122 :             IF( EQ_16( m, 1 ) )
    1151             :             {
    1152          42 :                 Copy( tmp, lsp_tmp, M ); /* Qx */
    1153             :             }
    1154          80 :             ELSE IF( LT_16( m, 4 ) )
    1155             :             {
    1156        1020 :                 FOR( i = 0; i < M; i++ )
    1157             :                 {
    1158         960 :                     L_tmp1 = 0;
    1159         960 :                     move32();
    1160        3504 :                     FOR( j = 0; j < m; j++ )
    1161             :                     {
    1162        2544 :                         L_tmp1 = L_add( L_tmp1, L_deposit_l( tmp[j * M + i] ) );
    1163             :                     }
    1164             : 
    1165         960 :                     L_tmp1 = L_sub( L_tmp1, L_deposit_l( tmp[max_idx[0] * M + i] ) );
    1166         960 :                     tmpv = div_s( 1, sub( m, 1 ) );       /*Q15*/
    1167         960 :                     L_tmp1 = Mpy_32_16_1( L_tmp1, tmpv ); /*Q15*/
    1168         960 :                     lsp_tmp[i] = extract_l( L_tmp1 );     /*Q15*/
    1169         960 :                     move16();
    1170             :                 }
    1171             :             }
    1172             :             ELSE
    1173             :             {
    1174         340 :                 FOR( i = 0; i < M; i++ )
    1175             :                 {
    1176         320 :                     L_tmp1 = 0;
    1177         320 :                     move32();
    1178        2016 :                     FOR( j = 0; j < m; j++ )
    1179             :                     {
    1180        1696 :                         L_tmp1 = L_add( L_tmp1, L_deposit_l( tmp[j * M + i] ) );
    1181             :                     }
    1182             : 
    1183         320 :                     L_tmp1 = L_sub( L_tmp1, L_add( L_deposit_l( tmp[max_idx[0] * M + i] ), L_deposit_l( tmp[max_idx[1] * M + i] ) ) ); /*Q15*/
    1184         320 :                     tmpv = div_s( 1, sub( m, 2 ) );                                                                                    /*Q15*/
    1185         320 :                     L_tmp1 = Mpy_32_16_1( L_tmp1, tmpv );                                                                              /*Q15*/
    1186         320 :                     lsp_tmp[i] = extract_l( L_tmp1 );                                                                                  /*Q15*/
    1187         320 :                     move16();
    1188             :                 }
    1189             :             }
    1190             : 
    1191         122 :             dist = 0;
    1192         122 :             move16(); /*Q15*/
    1193         122 :             max_dev = 0;
    1194         122 :             move16(); /*Q15*/
    1195        2074 :             FOR( i = 0; i < M; i++ )
    1196             :             {
    1197        1952 :                 dev = abs_s( sub( lsp_tmp[i], lsp_new[i] ) ); /*Q15*/
    1198        1952 :                 dist = add_o( dist, dev, &Overflow );         /*Q15*/
    1199        1952 :                 if ( GT_16( dev, max_dev ) )
    1200             :                 {
    1201         610 :                     max_dev = dev;
    1202         610 :                     move16();
    1203             :                 }
    1204             :             }
    1205             : 
    1206         122 :             test();
    1207         122 :             IF( GT_16( dist, 13107 ) || GT_16( max_dev, 3277 ) ) /* 0.4 and 0.1 in Q15 */
    1208             :             {
    1209          34 :                 FOR( i = 0; i < M; i++ )
    1210             :                 {
    1211          32 :                     st_fx->lspCNG_fx[i] = lsp_tmp[i];
    1212          32 :                     move16(); /*Q15*/
    1213             :                 }
    1214             :             }
    1215             :             ELSE
    1216             :             {
    1217        2040 :                 FOR( i = 0; i < M; i++ )
    1218             :                 {
    1219             :                     /* AR low-pass filter  */
    1220        1920 :                     st_fx->lspCNG_fx[i] = add( mult_r( 26214, lsp_tmp[i] ), mult_r( 6554, lsp_new[i] ) ); /* Q15 */
    1221        1920 :                     move16();
    1222             :                 }
    1223             :             }
    1224         122 :             IF( m1 > 0 )
    1225             :             {
    1226        1953 :                 FOR( i = 0; i < NUM_ENV_CNG; i++ )
    1227             :                 {
    1228        1860 :                     L_tmp = L_deposit_l( 0 );
    1229        5840 :                     FOR( j = 0; j < m1; j++ )
    1230             :                     {
    1231             :                         /* env[i] += tmp_env[j*NUM_ENV_CNG+i];*/
    1232        3980 :                         L_tmp = L_add_sat( L_tmp, tmp_env[j * NUM_ENV_CNG + i] );
    1233             :                     }
    1234             :                     /*    env[i] /= (float)m1;  */
    1235             :                     /*    env[i] = env[i] - 2*st_fx->lp_ener_fx; */
    1236        1860 :                     IF( EQ_16( m1, 1 ) )
    1237             :                     {
    1238         680 :                         L_tmp = L_sub_sat( L_tmp, L_add_sat( st_fx->lp_ener_fx, st_fx->lp_ener_fx ) ); /* Q6 */
    1239             :                     }
    1240             :                     ELSE
    1241             :                     {
    1242        1180 :                         tmp1 = div_s( 1, m1 );
    1243        1180 :                         L_tmp = Mult_32_16( L_tmp, tmp1 );                                             /* Q6 */
    1244        1180 :                         L_tmp = L_sub_sat( L_tmp, L_add_sat( st_fx->lp_ener_fx, st_fx->lp_ener_fx ) ); /* Q6 */
    1245             :                     }
    1246        1860 :                     env[i] = L_tmp; /* Q6 */
    1247        1860 :                     move32();
    1248             :                 }
    1249             : 
    1250          93 :                 Copy32( env, hTdCngDec->lp_env_fx, NUM_ENV_CNG ); /* Q6 */
    1251             :             }
    1252             :         }
    1253             :         ELSE
    1254             :         {
    1255          67 :             Copy( lsp_new, st_fx->lspCNG_fx, M ); /* use newly analyzed ISFs */ /* Q15 */
    1256             :         }
    1257             :     }
    1258             : 
    1259        2378 :     test();
    1260        2378 :     IF( EQ_32( st_fx->core_brate, SID_1k75 ) || EQ_32( st_fx->core_brate, SID_2k40 ) )
    1261             :     {
    1262             :         /* Update hangover memory during CNG */
    1263         417 :         test();
    1264         417 :         IF( ( *allow_cn_step == 0 ) && LT_32( hTdCngDec->Enew_fx, L_add_sat( st_fx->lp_ener_fx, L_shr( st_fx->lp_ener_fx, 1 ) ) ) )
    1265             :         {
    1266             :             /* update the pointer to circular buffer of old LSP vectors */
    1267         285 :             hTdCngDec->ho_hist_ptr++;
    1268         285 :             move16();
    1269         285 :             if ( EQ_16( hTdCngDec->ho_hist_ptr, HO_HIST_SIZE ) )
    1270             :             {
    1271          34 :                 hTdCngDec->ho_hist_ptr = 0;
    1272          34 :                 move16();
    1273             :             }
    1274             : 
    1275             :             /* update the circular buffer of old LSP vectors with the new LSP vector */
    1276         285 :             Copy( lsp_new, &( hTdCngDec->ho_lsp_hist_fx[( hTdCngDec->ho_hist_ptr ) * M] ), M ); /* Q15 */
    1277             : 
    1278             :             /* update the hangover energy buffer */
    1279         285 :             hTdCngDec->ho_ener_hist_fx[hTdCngDec->ho_hist_ptr] = hTdCngDec->Enew_fx; /* Q6 */
    1280         285 :             move32();
    1281         285 :             test();
    1282         285 :             IF( EQ_32( st_fx->core_brate, SID_2k40 ) && ( *sid_bw == 0 ) )
    1283             :             {
    1284             :                 /*  enr1 = (float)log10( st->Enew*L_frame + 0.1f ) / (float)log10( 2.0f );*/
    1285           0 :                 exp = norm_l( hTdCngDec->Enew_fx );
    1286           0 :                 L_tmp = L_shl( hTdCngDec->Enew_fx, exp );              /*Q(exp+6)*/
    1287           0 :                 L_tmp = Mult_32_16( L_tmp, shl( st_fx->L_frame, 5 ) ); /*Q(exp+6+5-15=exp-4)*/
    1288           0 :                 L_tmp = L_shr_sat( L_tmp, sub( exp, 10 ) );            /*Q6*/
    1289           0 :                 exp = norm_l( L_tmp );
    1290           0 :                 fra = Log2_norm_lc( L_shl( L_tmp, exp ) );
    1291           0 :                 exp = sub( sub( 30, exp ), 6 );
    1292           0 :                 L_tmp = L_Comp( exp, fra );
    1293           0 :                 enr1 = L_shr( L_tmp, 10 ); /* Q6 */
    1294             : 
    1295           0 :                 FOR( i = 0; i < NUM_ENV_CNG; i++ )
    1296             :                 {
    1297             :                     /* get quantized envelope */
    1298             :                     /*  env[i] = pow(2.0f,(enr1 - q_env[i])) + 2*st->Enew;*/
    1299           0 :                     L_tmp = L_sub( enr1, q_env[i] ); /* Q6 */
    1300           0 :                     L_tmp = L_shl( L_tmp, 10 );      /* 16 */
    1301           0 :                     temp_lo_fx = L_Extract_lc( L_tmp, &temp_hi_fx );
    1302             : 
    1303           0 :                     exp_pow = sub( 14, temp_hi_fx );
    1304           0 :                     L_tmp = Pow2( 14, temp_lo_fx );             /* Qexp_pow */
    1305           0 :                     env[i] = L_shl( L_tmp, sub( 6, exp_pow ) ); /* Q6 */
    1306           0 :                     move32();
    1307           0 :                     L_tmp = L_add( hTdCngDec->Enew_fx, hTdCngDec->Enew_fx );
    1308           0 :                     env[i] = L_add( env[i], L_tmp ); /* Q6 */
    1309           0 :                     move32();
    1310             :                 }
    1311           0 :                 hTdCngDec->ho_sid_bw = L_shl( L_and( hTdCngDec->ho_sid_bw, (Word32) 0x3fffffffL ), 1 ); /* Q0 */
    1312           0 :                 move32();
    1313           0 :                 Copy32( env, &( hTdCngDec->ho_env_hist_fx[hTdCngDec->ho_hist_ptr * NUM_ENV_CNG] ), NUM_ENV_CNG ); /* Q6 */
    1314             :             }
    1315         285 :             ELSE IF( ( *sid_bw != 0 ) )
    1316             :             {
    1317         285 :                 hTdCngDec->ho_sid_bw = L_shl( L_and( hTdCngDec->ho_sid_bw, (Word32) 0x3fffffffL ), 1 ); /* Q0 */
    1318         285 :                 move32();
    1319         285 :                 hTdCngDec->ho_sid_bw = L_or( hTdCngDec->ho_sid_bw, 0x1L ); /* Q0 */
    1320         285 :                 move32();
    1321             :             }
    1322             : 
    1323         285 :             hTdCngDec->ho_hist_size = add( hTdCngDec->ho_hist_size, 1 );
    1324         285 :             move16();
    1325         285 :             if ( GT_16( hTdCngDec->ho_hist_size, HO_HIST_SIZE ) )
    1326             :             {
    1327         169 :                 hTdCngDec->ho_hist_size = HO_HIST_SIZE;
    1328         169 :                 move16();
    1329             :             }
    1330             :         }
    1331             :         /* Update the frame length memory */
    1332         417 :         st_fx->last_CNG_L_frame = st_fx->L_frame;
    1333         417 :         move16();
    1334             : 
    1335         417 :         if ( NE_32( st_fx->core_brate, SID_1k75 ) )
    1336             :         {
    1337         417 :             hTdCngDec->num_ho = m;
    1338         417 :             move16();
    1339             :         }
    1340             :     }
    1341             : 
    1342        2378 :     IF( st_fx->element_mode == EVS_MONO )
    1343             :     {
    1344           0 :         st_fx->last_CNG_L_frame = st_fx->L_frame;
    1345           0 :         move16();
    1346             : 
    1347           0 :         IF( NE_32( st_fx->core_brate, SID_1k75 ) )
    1348             :         {
    1349           0 :             hTdCngDec->num_ho = m;
    1350           0 :             move16();
    1351             :         }
    1352             :     }
    1353        2378 :     IF( st_fx->Opt_AMR_WB )
    1354             :     {
    1355           0 :         E_LPC_f_isp_a_conversion( st_fx->lspCNG_fx, Aq, M );
    1356             :     }
    1357             :     ELSE
    1358             :     {
    1359        2378 :         E_LPC_f_lsp_a_conversion( st_fx->lspCNG_fx, Aq, M );
    1360             :     }
    1361             : 
    1362        2378 :     tmp_loop = shr( st_fx->L_frame, 6 );
    1363       11044 :     FOR( i = 1; i < tmp_loop; i++ ) /* L_frame/L_SUBFR */
    1364             :     {
    1365        8666 :         Copy( Aq, &Aq[i * ( M + 1 )], add( M, 1 ) ); /* Q12 */
    1366             :     }
    1367             : 
    1368        2378 :     return;
    1369             : }
    1370             : 
    1371             : /*---------------------------------------------------------------------*
    1372             :  * swb_CNG_dec()
    1373             :  *
    1374             :  * Comfort noise generation for SHB signal
    1375             :  *---------------------------------------------------------------------*/
    1376             : 
    1377        1852 : void swb_CNG_dec_fx(
    1378             :     Decoder_State *st_fx,   /* i/o: State structure                          */
    1379             :     const Word16 *synth_fx, /* i  : ACELP core synthesis at 32kHz                Qsyn*/
    1380             :     Word16 *shb_synth_fx,   /* o  : high-band CNG synthesis                Qx*/
    1381             :     const Word16 sid_bw,    /* i  : 0-NB/WB, 1-SWB SID                     Q0*/
    1382             :     const Word16 Qsyn       /* i  : Q value of ACELP core synthesis          */
    1383             : )
    1384             : {
    1385        1852 :     test();
    1386        1852 :     IF( EQ_32( st_fx->core_brate, FRAME_NO_DATA ) || EQ_32( st_fx->core_brate, SID_2k40 ) )
    1387             :     {
    1388             :         /* SHB SID decoding and CNG */
    1389           0 :         test();
    1390           0 :         IF( EQ_16( st_fx->cng_type, LP_CNG ) && EQ_16( st_fx->extl, SWB_CNG ) )
    1391             :         {
    1392           0 :             shb_CNG_decod_fx( st_fx, synth_fx, shb_synth_fx, sid_bw, Qsyn );
    1393             :         }
    1394           0 :         st_fx->last_vad_fx = 0;
    1395           0 :         move16();
    1396           0 :         st_fx->hTdCngDec->burst_cnt_fx = 0;
    1397           0 :         move16();
    1398             :     }
    1399             :     ELSE
    1400             :     {
    1401        1852 :         st_fx->last_vad_fx = 1;
    1402        1852 :         move16();
    1403        1852 :         st_fx->hTdCngDec->burst_cnt_fx = add( st_fx->hTdCngDec->burst_cnt_fx, 1 );
    1404        1852 :         move16();
    1405        1852 :         if ( GT_16( st_fx->hTdCngDec->burst_cnt_fx, 10 ) )
    1406             :         {
    1407         167 :             st_fx->hTdCngDec->burst_cnt_fx = 0;
    1408         167 :             move16();
    1409             :         }
    1410             :     }
    1411             : 
    1412        1852 :     return;
    1413             : }
    1414             : 
    1415      213448 : void swb_CNG_dec_ivas_fx(
    1416             :     Decoder_State *st_fx,   /* i/o: State structure                          */
    1417             :     const Word16 *synth_fx, /* i  : ACELP core synthesis at 32kHz        Qsyn*/
    1418             :     Word16 *shb_synth_fx,   /* o  : high-band CNG synthesis                Qx*/
    1419             :     const Word16 sid_bw,    /* i  : 0-NB/WB, 1-SWB SID                     Q0*/
    1420             :     const Word16 Qsyn       /* i  : Q value of ACELP core synthesis          */
    1421             : )
    1422             : {
    1423      213448 :     test();
    1424      213448 :     IF( EQ_32( st_fx->core_brate, FRAME_NO_DATA ) || EQ_32( st_fx->core_brate, SID_2k40 ) )
    1425             :     {
    1426             :         /* SHB SID decoding and CNG */
    1427       12817 :         test();
    1428       12817 :         IF( EQ_16( st_fx->cng_type, LP_CNG ) && EQ_16( st_fx->extl, SWB_CNG ) )
    1429             :         {
    1430        1788 :             shb_CNG_decod_ivas_fx( st_fx, synth_fx, shb_synth_fx, sid_bw, Qsyn );
    1431             :         }
    1432       12817 :         st_fx->last_vad_fx = 0;
    1433       12817 :         move16();
    1434       12817 :         st_fx->hTdCngDec->burst_cnt_fx = 0;
    1435       12817 :         move16();
    1436             :     }
    1437             :     ELSE
    1438             :     {
    1439      200631 :         st_fx->last_vad_fx = 1;
    1440      200631 :         move16();
    1441      200631 :         st_fx->hTdCngDec->burst_cnt_fx = add_sat( st_fx->hTdCngDec->burst_cnt_fx, 1 ); // saturation reached?
    1442      200631 :         move16();
    1443      200631 :         if ( GT_16( st_fx->hTdCngDec->burst_cnt_fx, 10 ) )
    1444             :         {
    1445       17347 :             st_fx->hTdCngDec->burst_cnt_fx = 0;
    1446       17347 :             move16();
    1447             :         }
    1448             :     }
    1449             : 
    1450      213448 :     return;
    1451             : }
    1452             : 
    1453             : /*---------------------------------------------------------------------*
    1454             :  * shb_CNG_decod()
    1455             :  *
    1456             :  * Main routine of SHB SID decoding and CNG
    1457             :  *---------------------------------------------------------------------*/
    1458             : 
    1459           0 : static void shb_CNG_decod_fx(
    1460             :     Decoder_State *st_fx,   /* i/o: State structure                          */
    1461             :     const Word16 *synth_fx, /* i  : ACELP core synthesis at 32kHz        Qsyn*/
    1462             :     Word16 *shb_synth_fx,   /* o  : high-band CNG synthesis                                Qx*/
    1463             :     const Word16 sid_bw,    /* i  : 0-NB/WB, 1-SWB SID                     Q0*/
    1464             :     const Word16 Qsyn       /* i  : Q value of ACELP core synthesis          */
    1465             : )
    1466             : {
    1467             :     Word16 i;
    1468             :     Word16 idx_ener_fx;
    1469             :     TD_CNG_DEC_HANDLE hTdCngDec;
    1470             :     Word16 shb_lpcCNG_fx[LPC_SHB_ORDER + 1];
    1471             :     Word16 shb_lspCNG_fx[LPC_SHB_ORDER];
    1472             :     Word16 excTmp_fx[L_FRAME16k];
    1473             :     Word16 excSHB_fx[L_FRAME16k];
    1474             :     Word16 tmp_lsp[LPC_SHB_ORDER];
    1475             :     Word16 ener_excSHB_fx;
    1476             :     Word32 wb_ener_fx;
    1477             :     Word16 wb_ener16_fx;
    1478             :     Word32 L_gain_fx;
    1479             :     Word16 gain_fx;
    1480             :     Word16 shb_syn16k_fx[L_FRAME16k];
    1481             :     Word16 tmp;
    1482             :     Word16 step_fx;
    1483             :     Word16 interp_fx;
    1484             :     Word16 ener_fx;
    1485             :     Word16 exp, exp1;
    1486             :     Word16 fra;
    1487             :     Word32 L_tmp;
    1488             :     Word16 tmp2;
    1489           0 :     Word16 allow_cn_step_fx = 0;
    1490           0 :     move16();
    1491             :     Word16 q;
    1492             :     TD_BWE_DEC_HANDLE hBWE_TD;
    1493             : 
    1494           0 :     hBWE_TD = st_fx->hBWE_TD;
    1495           0 :     hTdCngDec = st_fx->hTdCngDec;
    1496             : 
    1497           0 :     IF( st_fx->bfi == 0 )
    1498             :     {
    1499           0 :         test();
    1500           0 :         IF( EQ_32( st_fx->core_brate, SID_2k40 ) && EQ_16( sid_bw, 1 ) )
    1501             :         {
    1502           0 :             idx_ener_fx = get_next_indice_fx( st_fx, 4 );
    1503             : 
    1504           0 :             if ( !idx_ener_fx )
    1505             :             {
    1506           0 :                 idx_ener_fx = -15;
    1507           0 :                 move16();
    1508             :             }
    1509           0 :             IF( st_fx->element_mode == EVS_MONO )
    1510             :             {
    1511             :                 /* de-quantization of SHB CNG parameters */
    1512           0 :                 L_tmp = L_mult( idx_ener_fx, 27400 );                                              /*Q14  */
    1513           0 :                 hTdCngDec->last_shb_cng_ener_fx = extract_l( L_shr( L_sub( L_tmp, 295924 ), 6 ) ); /*Q8 */
    1514           0 :                 move16();
    1515             :             }
    1516             :             ELSE
    1517             :             {
    1518             :             }
    1519             :         }
    1520             :     }
    1521             : 
    1522             :     /* SHB spectrum estimation */
    1523             : 
    1524             : 
    1525           0 :     interp_fx = s_min( hTdCngDec->shb_dtx_count_fx, 32 );
    1526           0 :     interp_fx = shl_sat( interp_fx, 10 ); /*Q15*/
    1527           0 :     FOR( i = 0; i < LPC_SHB_ORDER; i++ )
    1528             :     {
    1529           0 :         tmp2 = mult( interp_fx, hTdCngDec->lsp_shb_prev_fx[i] );                   /*Q14*/
    1530           0 :         tmp = mult( sub( 32767, interp_fx ), hTdCngDec->lsp_shb_prev_prev_fx[i] ); /*Q14*/
    1531           0 :         shb_lspCNG_fx[i] = add( tmp2, tmp );
    1532           0 :         move16(); /*Q14*/
    1533             :     }
    1534             : 
    1535           0 :     IF( NE_16( st_fx->element_mode, IVAS_CPE_DFT ) )
    1536             :     {
    1537           0 :         if ( LT_16( hTdCngDec->shb_dtx_count_fx, 1000 ) )
    1538             :         {
    1539           0 :             hTdCngDec->shb_dtx_count_fx = add( hTdCngDec->shb_dtx_count_fx, 1 );
    1540           0 :             move16();
    1541             :         }
    1542             :     }
    1543           0 :     E_LPC_lsf_lsp_conversion( shb_lspCNG_fx, tmp_lsp, LPC_SHB_ORDER ); /*Q14*/
    1544           0 :     E_LPC_f_lsp_a_conversion( tmp_lsp, shb_lpcCNG_fx, LPC_SHB_ORDER );
    1545             : 
    1546           0 :     Copy_Scale_sig( shb_lpcCNG_fx, shb_lpcCNG_fx, LPC_SHB_ORDER + 1, sub( norm_s( shb_lpcCNG_fx[0] ), 2 ) ); /* Q12 */
    1547             : 
    1548             :     /* SHB energy estimation */
    1549           0 :     wb_ener_fx = L_deposit_l( 1 ); /*Q1 */
    1550           0 :     FOR( i = 0; i < L_FRAME32k; i++ )
    1551             :     {
    1552           0 :         wb_ener_fx = L_add( wb_ener_fx, Mpy_32_16_1( L_mult0( synth_fx[i], synth_fx[i] ), 51 ) ); /* 2*Qsyn */
    1553             :     }
    1554           0 :     exp = norm_l( wb_ener_fx );
    1555           0 :     fra = Log2_norm_lc( L_shl( wb_ener_fx, exp ) );
    1556           0 :     exp = sub( 30, add( exp, shl( Qsyn, 1 ) ) );
    1557           0 :     wb_ener_fx = Mpy_32_16( exp, fra, LG10 );
    1558           0 :     wb_ener16_fx = round_fx( L_shl( wb_ener_fx, 10 ) ); /*wb_ener_fx in Q8 */
    1559           0 :     if ( !st_fx->first_CNG )
    1560             :     {
    1561           0 :         hTdCngDec->wb_cng_ener_fx = wb_ener16_fx;
    1562           0 :         move16(); /*Q8 */
    1563             :     }
    1564           0 :     if ( GT_16( abs_s( sub( wb_ener16_fx, hTdCngDec->wb_cng_ener_fx ) ), 3072 ) )
    1565             :     {
    1566           0 :         allow_cn_step_fx = 1;
    1567           0 :         move16();
    1568             :     }
    1569             : 
    1570           0 :     IF( EQ_16( allow_cn_step_fx, 1 ) )
    1571             :     {
    1572           0 :         hTdCngDec->wb_cng_ener_fx = wb_ener16_fx;
    1573           0 :         move16(); /*Q8 */
    1574             :     }
    1575             :     ELSE
    1576             :     {
    1577           0 :         tmp = sub( wb_ener16_fx, hTdCngDec->wb_cng_ener_fx );              /*Q8 */
    1578           0 :         tmp = mult_r( tmp, 29491 );                                        /*Q8 */
    1579           0 :         hTdCngDec->wb_cng_ener_fx = add( hTdCngDec->wb_cng_ener_fx, tmp ); /*Q8 */
    1580           0 :         move16();
    1581             :     }
    1582           0 :     test();
    1583           0 :     test();
    1584           0 :     IF( EQ_32( st_fx->core_brate, SID_2k40 ) && EQ_16( sid_bw, 1 ) && ( st_fx->bfi == 0 ) )
    1585             :     {
    1586           0 :         hTdCngDec->last_wb_cng_ener_fx = hTdCngDec->wb_cng_ener_fx;
    1587           0 :         move16();
    1588             : 
    1589           0 :         if ( !st_fx->first_CNG )
    1590             :         {
    1591           0 :             hTdCngDec->shb_cng_ener_fx = hTdCngDec->last_shb_cng_ener_fx;
    1592           0 :             move16();
    1593             :         }
    1594             :     }
    1595             : 
    1596           0 :     gain_fx = sub( hTdCngDec->wb_cng_ener_fx, hTdCngDec->last_wb_cng_ener_fx ); /* Q8 */
    1597           0 :     if ( GT_16( gain_fx, 15 ) )
    1598             :     {
    1599           0 :         gain_fx = 15;
    1600           0 :         move16();
    1601             :     }
    1602           0 :     step_fx = sub( add( gain_fx, hTdCngDec->last_shb_cng_ener_fx ), hTdCngDec->shb_cng_ener_fx ); /*Q8 */
    1603           0 :     test();
    1604           0 :     IF( EQ_16( allow_cn_step_fx, 1 ) || GT_32( st_fx->last_core_brate, SID_2k40 ) )
    1605             :     {
    1606           0 :         hTdCngDec->shb_cng_ener_fx = add( hTdCngDec->shb_cng_ener_fx, step_fx ); /* Q8 */
    1607           0 :         move16();
    1608             :     }
    1609             :     ELSE
    1610             :     {
    1611           0 :         hTdCngDec->shb_cng_ener_fx = add( hTdCngDec->shb_cng_ener_fx, mult( 8192, step_fx ) ); /*Q8 */
    1612           0 :         move16();
    1613             :     }
    1614             :     /* generate white noise excitation */
    1615           0 :     FOR( i = 0; i < L_FRAME16k; i++ )
    1616             :     {
    1617           0 :         excTmp_fx[i] = shr_r( Random( &hTdCngDec->swb_cng_seed ), 8 );
    1618           0 :         move16(); /*Q-8*/
    1619             :     }
    1620             : 
    1621             :     /* synthesis filtering */
    1622           0 :     Syn_filt_s( 0, shb_lpcCNG_fx, LPC_SHB_ORDER, excTmp_fx, excSHB_fx, L_FRAME16k, hBWE_TD->state_lpc_syn_fx, 1 );
    1623             : 
    1624             : 
    1625             :     /* synthesis signal gain shaping */
    1626           0 :     L_tmp = 0;
    1627           0 :     move32();
    1628           0 :     FOR( i = 0; i < L_FRAME16k; i++ )
    1629             :     {
    1630           0 :         L_tmp = L_add( L_tmp, Mpy_32_16_1( L_mult0( excSHB_fx[i], excSHB_fx[i] ), 102 ) ); /*Q-16*/
    1631             :     }
    1632           0 :     q = norm_l( L_tmp );
    1633           0 :     L_tmp = L_shl( L_tmp, q );
    1634           0 :     q = sub( q, 32 );
    1635           0 :     ener_excSHB_fx = round_fx( L_tmp ); /*Qq */
    1636           0 :     IF( EQ_16( st_fx->last_vad_fx, 1 ) )
    1637             :     {
    1638           0 :         hTdCngDec->trans_cnt_fx = 0;
    1639           0 :         move16();
    1640           0 :         test();
    1641           0 :         IF( GT_16( hTdCngDec->burst_cnt_fx, 3 ) && NE_16( st_fx->last_core, HQ_CORE ) )
    1642             :         {
    1643           0 :             hTdCngDec->trans_cnt_fx = 5;
    1644           0 :             move16();
    1645             :         }
    1646             :     }
    1647             : 
    1648           0 :     ener_fx = hTdCngDec->shb_cng_ener_fx;
    1649           0 :     move16(); /*Q8 */
    1650           0 :     IF( hTdCngDec->trans_cnt_fx > 0 )
    1651             :     {
    1652           0 :         i = extract_l( L_mult0( hTdCngDec->trans_cnt_fx, 17 ) );                                                                                         /*Q0 */
    1653           0 :         ener_fx = add_sat( hTdCngDec->shb_cng_ener_fx, mult( sin_table256_fx[i], sub_sat( hTdCngDec->last_shb_ener_fx, hTdCngDec->shb_cng_ener_fx ) ) ); /*Q8 */
    1654           0 :         hTdCngDec->trans_cnt_fx = sub( hTdCngDec->trans_cnt_fx, 1 );
    1655           0 :         move16();
    1656             :     }
    1657             : 
    1658           0 :     tmp = mult( 3277, ener_fx );  /*Q8 */
    1659           0 :     L_tmp = L_mult( 27213, tmp ); /*Q22, 27213=3.321928 in Q13  */
    1660           0 :     L_tmp = L_shr( L_tmp, 6 );    /*Q16 */
    1661           0 :     L_tmp = L_add( L_tmp, 10 << 16 );
    1662           0 :     if ( L_tmp < 0 )
    1663             :     {
    1664           0 :         L_tmp = 0;
    1665           0 :         move32();
    1666             :     }
    1667           0 :     fra = L_Extract_lc( L_tmp, &exp );
    1668           0 :     L_tmp = L_shl_sat( Pow2( exp, fra ), 5 ); /*Q5 */
    1669           0 :     L_tmp = L_shr( L_tmp, 10 );
    1670           0 :     if ( !L_tmp )
    1671             :     {
    1672           0 :         L_tmp = 1; /*Q5 */
    1673             :     }
    1674           0 :     exp = norm_l( L_tmp );
    1675           0 :     L_tmp = L_shl( L_tmp, exp ); /*Q31*/
    1676           0 :     tmp = extract_h( L_tmp );    /*Q15*/
    1677           0 :     exp = sub( exp, 16 );
    1678           0 :     exp1 = norm_s( ener_excSHB_fx );
    1679           0 :     fra = shl( ener_excSHB_fx, exp1 ); /*Q15*/
    1680             : 
    1681           0 :     IF( GT_16( fra, tmp ) )
    1682             :     {
    1683           0 :         fra = shr( fra, 1 ); /*Q15*/
    1684           0 :         exp1 = sub( exp1, 1 );
    1685             :     }
    1686           0 :     tmp = div_s( fra, tmp ); /*Q15*/
    1687             : 
    1688           0 :     L_tmp = L_deposit_h( tmp ); /*Q31 */
    1689           0 :     tmp = sub( add( 5, exp ), add( q, exp1 ) );
    1690           0 :     L_gain_fx = Isqrt_lc( L_tmp, &tmp ); /*Q31-Qtmp */
    1691             : 
    1692           0 :     FOR( i = 0; i < L_FRAME16k; i++ )
    1693             :     {
    1694           0 :         shb_syn16k_fx[i] = extract_l( L_shr( Mpy_32_16_1( L_gain_fx, excSHB_fx[i] ), sub( 5, tmp ) ) ); /*Q3 = 31-Qtmp-8-15-5+Qtmp */
    1695           0 :         move16();
    1696             :     }
    1697             : 
    1698           0 :     test();
    1699           0 :     IF( EQ_16( st_fx->last_extl, SWB_TBE ) || EQ_16( st_fx->last_extl, FB_TBE ) )
    1700             :     {
    1701             :         /* rescale the Hilbert memories to Q0 */
    1702           0 :         FOR( i = 0; i < HILBERT_MEM_SIZE; i++ )
    1703             :         {
    1704           0 :             hBWE_TD->genSHBsynth_Hilbert_Mem_fx[i] = L_shr( hBWE_TD->genSHBsynth_Hilbert_Mem_fx[i], hBWE_TD->prev_Q_bwe_syn2 ); /* hBWE_TD->prev_Q_bwe_syn2 */
    1705           0 :             move32();
    1706             :         }
    1707             : 
    1708           0 :         FOR( i = 0; i < 2 * ALLPASSSECTIONS_STEEP; i++ )
    1709             :         {
    1710           0 :             hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx[i] = shr( hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx[i], hBWE_TD->prev_Q_bwe_syn2 ); /* hBWE_TD->prev_Q_bwe_syn2 */
    1711           0 :             move16();
    1712             :         }
    1713             :     }
    1714           0 :     GenSHBSynth_fx( shb_syn16k_fx, shb_synth_fx, hBWE_TD->genSHBsynth_Hilbert_Mem_fx, hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx, st_fx->L_frame, &( hBWE_TD->syn_dm_phase ) );
    1715             : 
    1716           0 :     IF( EQ_32( st_fx->output_Fs, 48000 ) )
    1717             :     {
    1718           0 :         interpolate_3_over_2_allpass_fx( shb_synth_fx, L_FRAME32k, shb_synth_fx, hTdCngDec->interpol_3_2_cng_dec_fx, allpass_poles_3_ov_2 );
    1719             :     }
    1720             : 
    1721           0 :     ResetSHBbuffer_Dec_fx( st_fx->hBWE_TD, st_fx->extl );
    1722             : 
    1723           0 :     return;
    1724             : }
    1725             : 
    1726        1788 : static void shb_CNG_decod_ivas_fx(
    1727             :     Decoder_State *st,      /* i/o: State structure                                             */
    1728             :     const Word16 *synth_fx, /* i  : ACELP core synthesis at 32kHz   Qsyn*/
    1729             :     Word16 *shb_synth_fx,   /* o  : high-band CNG synthesis                       Qx*/
    1730             :     const Word16 sid_bw,    /* i  : 0-NB/WB, 1-SWB SID                Q0*/
    1731             :     const Word16 Qsyn )
    1732             : {
    1733             :     Word16 i;
    1734             :     Word16 idx_ener;
    1735             :     TD_CNG_DEC_HANDLE hTdCngDec;
    1736             :     Word16 shb_lpcCNG_fx[LPC_SHB_ORDER + 1];
    1737             :     Word16 shb_lspCNG_fx[LPC_SHB_ORDER];
    1738             :     Word16 excTmp_fx[L_FRAME16k];
    1739             :     Word16 excSHB_fx[L_FRAME16k];
    1740             :     Word16 tmp_lsp[LPC_SHB_ORDER];
    1741             :     Word16 ener_excSHB_fx;
    1742             :     Word32 wb_ener_fx;
    1743             :     Word16 wb_ener16_fx;
    1744             :     Word32 L_gain_fx;
    1745             :     Word32 gain_fx;
    1746             :     Word16 shb_syn16k_fx[L_FRAME16k];
    1747             :     Word32 tmp;
    1748             :     Word32 step_fx;
    1749             :     Word16 interp_fx;
    1750             :     Word32 ener_fx;
    1751             :     Word16 exp, exp1;
    1752             :     Word16 fra;
    1753             :     Word32 L_tmp;
    1754             :     Word16 allow_cn_step_fx;
    1755             :     Word16 q;
    1756             :     TD_BWE_DEC_HANDLE hBWE_TD;
    1757             : 
    1758        1788 :     hBWE_TD = st->hBWE_TD;
    1759        1788 :     hTdCngDec = st->hTdCngDec;
    1760        1788 :     allow_cn_step_fx = 0;
    1761        1788 :     move16();
    1762             : 
    1763        1788 :     IF( st->bfi == 0 )
    1764             :     {
    1765        1788 :         test();
    1766        1788 :         IF( EQ_32( st->core_brate, SID_2k40 ) && EQ_16( sid_bw, 1 ) )
    1767             :         {
    1768         324 :             idx_ener = get_next_indice_fx( st, 4 );
    1769             : 
    1770         324 :             IF( idx_ener == 0 )
    1771             :             {
    1772           5 :                 idx_ener = -15;
    1773           5 :                 move16();
    1774             :             }
    1775             : 
    1776             :             /* de-quantization of SHB CNG parameters */
    1777         324 :             IF( st->element_mode == EVS_MONO )
    1778             :             {
    1779           0 :                 hTdCngDec->last_shb_cng_ener_fx_32 = L_sub( L_mult0( idx_ener, 6850 ), 36991 ); // Q11
    1780           0 :                 move32();
    1781             :             }
    1782             :             ELSE
    1783             :             {
    1784         324 :                 hTdCngDec->last_shb_cng_ener_fx_32 = L_sub( L_mult0( idx_ener, 8807 ), 36991 ); // Q11
    1785         324 :                 move32();
    1786             :             }
    1787             :         }
    1788             :     }
    1789             : 
    1790             :     /* SHB spectrum estimation */
    1791        1788 :     interp_fx = s_min( hTdCngDec->shb_dtx_count_fx, 32 );
    1792        1788 :     interp_fx = shl_sat( interp_fx, 10 ); /*Q15*/
    1793             : 
    1794       19668 :     FOR( i = 0; i < LPC_SHB_ORDER; i++ )
    1795             :     {
    1796       17880 :         shb_lspCNG_fx[i] = add( mult_r( interp_fx, hTdCngDec->lsp_shb_prev_fx[i] ), mult_r( sub( 32767, interp_fx ), hTdCngDec->lsp_shb_prev_prev_fx[i] ) ); // Q14
    1797       17880 :         move16();
    1798             :     }
    1799             : 
    1800        1788 :     IF( LE_16( hTdCngDec->shb_dtx_count_fx, 1000 ) )
    1801             :     {
    1802        1788 :         hTdCngDec->shb_dtx_count_fx = add( hTdCngDec->shb_dtx_count_fx, 1 );
    1803        1788 :         move16();
    1804             :     }
    1805             : 
    1806        1788 :     E_LPC_lsf_lsp_conversion( shb_lspCNG_fx, tmp_lsp, LPC_SHB_ORDER ); /*Q14*/
    1807        1788 :     E_LPC_f_lsp_a_conversion( tmp_lsp, shb_lpcCNG_fx, LPC_SHB_ORDER );
    1808             : 
    1809        1788 :     Copy_Scale_sig( shb_lpcCNG_fx, hTdCngDec->shb_lpcCNG_fx, LPC_SHB_ORDER + 1, sub( norm_s( shb_lpcCNG_fx[0] ), -1 ) ); /* Q15 */
    1810             : 
    1811        1788 :     Copy_Scale_sig( shb_lpcCNG_fx, shb_lpcCNG_fx, LPC_SHB_ORDER + 1, sub( norm_s( shb_lpcCNG_fx[0] ), 2 ) ); /* Q12 */
    1812             : 
    1813             :     /* SHB energy estimation */
    1814        1788 :     wb_ener_fx = L_deposit_l( 1 ); /*Q1 */
    1815        1788 :     IF( NE_16( st->element_mode, IVAS_CPE_DFT ) )
    1816             :     {
    1817           0 :         FOR( i = 0; i < L_FRAME32k; i++ )
    1818             :         {
    1819           0 :             wb_ener_fx = L_add( wb_ener_fx, Mpy_32_16_1( L_mult0( synth_fx[i], synth_fx[i] ), 51 ) ); /* 2*Qsyn */
    1820             :         }
    1821             :     }
    1822        1788 :     exp = norm_l( wb_ener_fx );
    1823        1788 :     fra = Log2_norm_lc( L_shl( wb_ener_fx, exp ) );
    1824        1788 :     exp = sub( 30, add( exp, shl( Qsyn, 1 ) ) );
    1825        1788 :     wb_ener_fx = Mpy_32_16( exp, fra, LG10 );
    1826        1788 :     wb_ener16_fx = round_fx( L_shl( wb_ener_fx, 10 ) ); /*wb_ener_fx in Q8 */
    1827        1788 :     Word32 wb_ener32_fx = L_shl( wb_ener16_fx, 3 );     /*wb_ener_fx in Q11 */
    1828        1788 :     if ( EQ_16( st->first_CNG, 0 ) )
    1829             :     {
    1830          19 :         hTdCngDec->wb_cng_ener_fx_32 = wb_ener32_fx;
    1831          19 :         move32(); /*Q11 */
    1832             :     }
    1833        1788 :     if ( GT_32( L_abs( L_sub( wb_ener32_fx, hTdCngDec->wb_cng_ener_fx_32 ) ), 24576 ) ) /* 12.0f in Q11 */
    1834             :     {
    1835           0 :         allow_cn_step_fx = 1;
    1836           0 :         move16();
    1837             :     }
    1838             : 
    1839        1788 :     IF( EQ_16( allow_cn_step_fx, 1 ) )
    1840             :     {
    1841           0 :         hTdCngDec->wb_cng_ener_fx_32 = wb_ener32_fx;
    1842           0 :         move32(); /*Q11 */
    1843             :     }
    1844             :     ELSE
    1845             :     {
    1846        1788 :         tmp = L_sub( wb_ener32_fx, hTdCngDec->wb_cng_ener_fx_32 );                 /*Q11 */
    1847        1788 :         tmp = Mpy_32_16_1( tmp, 29491 );                                           /*Q11 */
    1848        1788 :         hTdCngDec->wb_cng_ener_fx_32 = L_add( hTdCngDec->wb_cng_ener_fx_32, tmp ); /*Q11 */
    1849        1788 :         move32();
    1850             :     }
    1851        1788 :     test();
    1852        1788 :     test();
    1853        1788 :     IF( EQ_32( st->core_brate, SID_2k40 ) && EQ_16( sid_bw, 1 ) && EQ_16( st->bfi, 0 ) )
    1854             :     {
    1855         324 :         hTdCngDec->last_wb_cng_ener_fx_32 = hTdCngDec->wb_cng_ener_fx_32; /* Q11 */
    1856         324 :         move32();
    1857             : 
    1858         324 :         if ( !st->first_CNG )
    1859             :         {
    1860          19 :             hTdCngDec->shb_cng_ener_fx_32 = hTdCngDec->last_shb_cng_ener_fx_32; /* Q11 */
    1861          19 :             move32();
    1862             :         }
    1863             :     }
    1864             : 
    1865        1788 :     gain_fx = L_sub( hTdCngDec->wb_cng_ener_fx_32, hTdCngDec->last_wb_cng_ener_fx_32 ); /*Q11 */
    1866        1788 :     if ( GT_32( gain_fx, 30720 ) )
    1867             :     {
    1868           0 :         gain_fx = 30720;
    1869           0 :         move32();
    1870             :     }
    1871        1788 :     step_fx = L_sub( L_add( gain_fx, hTdCngDec->last_shb_cng_ener_fx_32 ), hTdCngDec->shb_cng_ener_fx_32 ); /*Q11 */
    1872        1788 :     test();
    1873        1788 :     IF( EQ_16( allow_cn_step_fx, 1 ) || GT_32( st->last_core_brate, SID_2k40 ) )
    1874             :     {
    1875         151 :         hTdCngDec->shb_cng_ener_fx_32 = L_add( hTdCngDec->shb_cng_ener_fx_32, step_fx ); /* Q11 */
    1876         151 :         move32();
    1877             :     }
    1878             :     ELSE
    1879             :     {
    1880        1637 :         hTdCngDec->shb_cng_ener_fx_32 = L_add( hTdCngDec->shb_cng_ener_fx_32, L_shr( step_fx, 2 ) ); /*Q11 */
    1881        1637 :         move32();
    1882             :     }
    1883             :     /* generate white noise excitation */
    1884      573948 :     FOR( i = 0; i < L_FRAME16k; i++ )
    1885             :     {
    1886      572160 :         excTmp_fx[i] = shr_r( Random( &hTdCngDec->swb_cng_seed ), 8 );
    1887      572160 :         move16(); /*Q-8*/
    1888             :     }
    1889             : 
    1890             :     /* synthesis filtering */
    1891        1788 :     Syn_filt_s( 0, shb_lpcCNG_fx, LPC_SHB_ORDER, excTmp_fx, excSHB_fx, L_FRAME16k, hBWE_TD->state_lpc_syn_fx, 1 );
    1892             : 
    1893             : 
    1894             :     /* synthesis signal gain shaping */
    1895        1788 :     L_tmp = 0;
    1896        1788 :     move32();
    1897      573948 :     FOR( i = 0; i < L_FRAME16k; i++ )
    1898             :     {
    1899      572160 :         L_tmp = L_add( L_tmp, Mpy_32_16_1( L_mult0( excSHB_fx[i], excSHB_fx[i] ), 102 ) ); /*Q-16*/
    1900             :     }
    1901        1788 :     q = norm_l( L_tmp );
    1902        1788 :     L_tmp = L_shl( L_tmp, q );
    1903        1788 :     q = sub( q, 32 );
    1904        1788 :     ener_excSHB_fx = round_fx( L_tmp ); /*Qq */
    1905             : 
    1906        1788 :     IF( EQ_16( st->last_vad_fx, 1 ) )
    1907             :     {
    1908         151 :         hTdCngDec->trans_cnt_fx = 0;
    1909         151 :         move16();
    1910         151 :         test();
    1911         151 :         if ( GT_16( hTdCngDec->burst_cnt_fx, 3 ) && NE_16( st->last_core, HQ_CORE ) )
    1912             :         {
    1913          40 :             hTdCngDec->trans_cnt_fx = 5;
    1914          40 :             move16();
    1915             :         }
    1916             :     }
    1917             : 
    1918        1788 :     ener_fx = hTdCngDec->shb_cng_ener_fx_32;
    1919        1788 :     move32(); /*Q11 */
    1920        1788 :     IF( GT_16( st->hTdCngDec->trans_cnt_fx, 0 ) )
    1921             :     {
    1922          85 :         i = extract_l( L_mult0( hTdCngDec->trans_cnt_fx, 17 ) );                                                                                                     /*Q0 */
    1923          85 :         ener_fx = L_add( hTdCngDec->shb_cng_ener_fx_32, Mpy_32_16_1( L_sub( hTdCngDec->last_shb_ener_fx_32, hTdCngDec->shb_cng_ener_fx_32 ), sin_table256_fx[i] ) ); /*Q11 */
    1924          85 :         hTdCngDec->trans_cnt_fx = sub( hTdCngDec->trans_cnt_fx, 1 );
    1925          85 :         move16();
    1926             :     }
    1927             : 
    1928        1788 :     tmp = L_shr( Mpy_32_16_1( ener_fx, 3277 ), 3 ); /*Q8 */
    1929        1788 :     IF( GT_32( tmp, 32767 ) )
    1930           0 :     abort();
    1931             :     Word16 tmp_16;
    1932        1788 :     tmp_16 = (Word16) tmp;
    1933        1788 :     move16();
    1934        1788 :     L_tmp = L_mult( 27213, tmp_16 ); /*Q22, 27213=3.321928 in Q13  */
    1935        1788 :     L_tmp = L_shr( L_tmp, 6 );       /*Q16 */
    1936        1788 :     L_tmp = L_add( L_tmp, L_shl( 10, 16 ) );
    1937        1788 :     if ( ( L_tmp < 0 ) )
    1938             :     {
    1939          36 :         L_tmp = 0;
    1940          36 :         move32();
    1941             :     }
    1942        1788 :     fra = L_Extract_lc( L_tmp, &exp );
    1943        1788 :     L_tmp = L_shr( Pow2( exp, fra ), 5 ); /*Q5 */
    1944        1788 :     if ( !L_tmp )
    1945             :     {
    1946          40 :         L_tmp = 1;
    1947          40 :         move32(); /*Q5 */
    1948             :     }
    1949        1788 :     exp = norm_l( L_tmp );
    1950        1788 :     L_tmp = L_shl( L_tmp, exp ); /*Q31*/
    1951        1788 :     tmp_16 = extract_h( L_tmp ); /*Q15*/
    1952        1788 :     exp = sub( exp, 16 );
    1953        1788 :     exp1 = norm_s( ener_excSHB_fx );
    1954        1788 :     fra = shl( ener_excSHB_fx, exp1 ); /*Q15*/
    1955             : 
    1956        1788 :     IF( GT_16( fra, tmp_16 ) )
    1957             :     {
    1958         758 :         fra = shr( fra, 1 ); /*Q15*/
    1959         758 :         exp1 = sub( exp1, 1 );
    1960             :     }
    1961        1788 :     tmp_16 = div_s( fra, tmp_16 ); /*Q15*/
    1962             : 
    1963        1788 :     L_tmp = L_deposit_h( tmp_16 ); /*Q31 */
    1964        1788 :     tmp_16 = sub( add( 5, exp ), add( q, exp1 ) );
    1965        1788 :     L_gain_fx = Isqrt_lc( L_tmp, &tmp_16 ); /*Q31-Qtmp */
    1966        1788 :     hTdCngDec->shb_cng_gain_fx_32 = ener_fx;
    1967        1788 :     move32();
    1968      573948 :     FOR( i = 0; i < L_FRAME16k; i++ )
    1969             :     {
    1970      572160 :         shb_syn16k_fx[i] = extract_l( L_shr( Mpy_32_16_1( L_gain_fx, excSHB_fx[i] ), sub( 5, tmp_16 ) ) ); /*Q3 = 31-Qtmp-8-15-5+Qtmp */
    1971      572160 :         move16();
    1972             :     }
    1973             : 
    1974        1788 :     test();
    1975        1788 :     IF( EQ_16( st->last_extl, SWB_TBE ) || EQ_16( st->last_extl, FB_TBE ) )
    1976             :     {
    1977             :         /* rescale the Hilbert memories to Q0 */
    1978         528 :         FOR( i = 0; i < HILBERT_MEM_SIZE; i++ )
    1979             :         {
    1980         504 :             hBWE_TD->genSHBsynth_Hilbert_Mem_fx[i] = L_shr( hBWE_TD->genSHBsynth_Hilbert_Mem_fx[i], hBWE_TD->prev_Q_bwe_syn2 ); /* hBWE_TD->prev_Q_bwe_syn2 */
    1981         504 :             move32();
    1982             :         }
    1983             : 
    1984         168 :         FOR( i = 0; i < 2 * ALLPASSSECTIONS_STEEP; i++ )
    1985             :         {
    1986         144 :             hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx[i] = shr( hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx[i], hBWE_TD->prev_Q_bwe_syn2 ); /* hBWE_TD->prev_Q_bwe_syn2 */
    1987         144 :             move16();
    1988             :         }
    1989             :     }
    1990        1788 :     GenSHBSynth_fx( shb_syn16k_fx, shb_synth_fx, hBWE_TD->genSHBsynth_Hilbert_Mem_fx, hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx, st->L_frame, &( hBWE_TD->syn_dm_phase ) );
    1991             : 
    1992        1788 :     IF( EQ_32( st->output_Fs, 48000 ) )
    1993             :     {
    1994         970 :         interpolate_3_over_2_allpass_fx( shb_synth_fx, L_FRAME32k, shb_synth_fx, hTdCngDec->interpol_3_2_cng_dec_fx, allpass_poles_3_ov_2 );
    1995             :     }
    1996             : 
    1997        1788 :     Scale_sig( shb_synth_fx, L_FRAME48k, -3 ); /* Qx - 3 */
    1998             : 
    1999        1788 :     ResetSHBbuffer_Dec_fx( st->hBWE_TD, st->extl );
    2000             : 
    2001        1788 :     return;
    2002             : }
    2003             : 
    2004             : /*-------------------------------------------------------------------*
    2005             :  * td_cng_dec_init_fx()
    2006             :  *
    2007             :  *
    2008             :  *-------------------------------------------------------------------*/
    2009             : 
    2010        1340 : void td_cng_dec_init_fx(
    2011             :     DEC_CORE_HANDLE st /* i/o: decoder state structure     */
    2012             : )
    2013             : {
    2014             :     Word16 i;
    2015             :     TD_CNG_DEC_HANDLE hTdCngDec;
    2016             : 
    2017        1340 :     hTdCngDec = st->hTdCngDec;
    2018             : 
    2019        1340 :     hTdCngDec->cng_seed = RANDOM_INITSEED;
    2020        1340 :     move16();
    2021        1340 :     hTdCngDec->cng_ener_seed = RANDOM_INITSEED;
    2022        1340 :     move16();
    2023        1340 :     hTdCngDec->cng_ener_seed1 = RANDOM_INITSEED;
    2024        1340 :     move16();
    2025        1340 :     hTdCngDec->old_enr_index = -1;
    2026        1340 :     move16();
    2027        1340 :     hTdCngDec->Enew_fx = 0;
    2028        1340 :     move32();
    2029        1340 :     Copy( st->lsp_old_fx, st->lspCNG_fx, M ); // Q(15)
    2030        1340 :     hTdCngDec->last_allow_cn_step = 0;
    2031        1340 :     move16();
    2032        1340 :     hTdCngDec->shb_cng_ener_fx = -1541; // Q8
    2033        1340 :     move16();
    2034        1340 :     hTdCngDec->shb_cng_ener_fx_32 = -12329; // -6.02 in Q(11)
    2035        1340 :     move32();
    2036        1340 :     IF( st->element_mode != EVS_MONO )
    2037             :     {
    2038        1337 :         set16_fx( hTdCngDec->shb_lpcCNG_fx, 0, LPC_SHB_ORDER + 1 );
    2039        1337 :         hTdCngDec->shb_lpcCNG_fx[0] = 32767; // 1 in Q(15)
    2040        1337 :         move16();
    2041        1337 :         hTdCngDec->shb_cng_gain_fx_32 = -167936; //-82.0 in Q(11) /* a  dB value approximately corresponding to  shb  index 0(used as index -15)   */
    2042        1337 :         move32();
    2043             :     }
    2044             : 
    2045        1340 :     hTdCngDec->wb_cng_ener_fx = -1541; // Q8
    2046        1340 :     move16();
    2047        1340 :     hTdCngDec->wb_cng_ener_fx_32 = -12329; // Q(11)
    2048        1340 :     move32();
    2049        1340 :     hTdCngDec->last_wb_cng_ener_fx = -1541; // Q8
    2050        1340 :     move16();
    2051        1340 :     hTdCngDec->last_wb_cng_ener_fx_32 = -12329; // Q(11)
    2052        1340 :     move32();
    2053        1340 :     hTdCngDec->last_shb_cng_ener_fx = -1541; // Q8
    2054        1340 :     move16();
    2055        1340 :     hTdCngDec->last_shb_cng_ener_fx_32 = -12329; // Q(11)
    2056        1340 :     move32();
    2057        1340 :     hTdCngDec->swb_cng_seed = RANDOM_INITSEED;
    2058        1340 :     move16();
    2059        1340 :     hTdCngDec->ho_hist_ptr = -1;
    2060        1340 :     move16();
    2061        1340 :     hTdCngDec->ho_sid_bw = 0;
    2062        1340 :     move16();
    2063        1340 :     set16_fx( hTdCngDec->ho_lsp_hist_fx, 0, HO_HIST_SIZE * M );
    2064        1340 :     set32_fx( hTdCngDec->ho_ener_hist_fx, 0, HO_HIST_SIZE );
    2065        1340 :     set32_fx( hTdCngDec->ho_env_hist_fx, 0, HO_HIST_SIZE * NUM_ENV_CNG );
    2066        1340 :     hTdCngDec->ho_hist_size = 0;
    2067        1340 :     move16();
    2068        1340 :     hTdCngDec->act_cnt = 0;
    2069        1340 :     move16();
    2070        1340 :     hTdCngDec->ho_circ_ptr = -1;
    2071        1340 :     move16();
    2072        1340 :     set16_fx( hTdCngDec->ho_lsp_circ_fx, 0, HO_HIST_SIZE * M );
    2073        1340 :     set32_fx( hTdCngDec->ho_ener_circ_fx, 0, HO_HIST_SIZE );
    2074        1340 :     set32_fx( hTdCngDec->ho_env_circ_fx, 0, HO_HIST_SIZE * NUM_ENV_CNG );
    2075        1340 :     hTdCngDec->ho_circ_size = 0;
    2076        1340 :     move16();
    2077             : 
    2078        1340 :     set16_fx( hTdCngDec->ho_16k_lsp, 0, HO_HIST_SIZE );
    2079        1340 :     st->CNG_mode = -1;
    2080        1340 :     move16();
    2081        1340 :     hTdCngDec->act_cnt2 = 0;
    2082        1340 :     move16();
    2083        1340 :     hTdCngDec->num_ho = 0;
    2084        1340 :     move16();
    2085        1340 :     set32_fx( hTdCngDec->lp_env_fx, 0, NUM_ENV_CNG );
    2086        1340 :     set16_fx( hTdCngDec->exc_mem_fx, 0, 24 );
    2087        1340 :     set16_fx( hTdCngDec->exc_mem1_fx, 0, 30 );
    2088        1340 :     set32_fx( hTdCngDec->old_env_fx, 0, NUM_ENV_CNG );
    2089             : 
    2090       14740 :     FOR( i = 0; i < LPC_SHB_ORDER; i++ )
    2091             :     {
    2092       13400 :         IF( st->element_mode != EVS_MONO )
    2093             :         {
    2094       13370 :             hTdCngDec->lsp_shb_prev_fx[i] = ivas_lsp_shb_prev_tbl_fx[i]; /* Q14 */
    2095       13370 :             move16();
    2096             :         }
    2097             :         ELSE
    2098             :         {
    2099          30 :             hTdCngDec->lsp_shb_prev_fx[i] = lsp_shb_prev_tbl_fx[i]; /* Q14 */
    2100          30 :             move16();
    2101             :         }
    2102       13400 :         hTdCngDec->lsp_shb_prev_prev_fx[i] = hTdCngDec->lsp_shb_prev_fx[i]; /* Q14 */
    2103       13400 :         move16();
    2104             :     }
    2105             : 
    2106        1340 :     hTdCngDec->shb_dtx_count_fx = 0;
    2107        1340 :     move16();
    2108        1340 :     hTdCngDec->trans_cnt_fx = 0;
    2109        1340 :     move16();
    2110        1340 :     hTdCngDec->burst_cnt_fx = 0;
    2111        1340 :     move16();
    2112             : 
    2113        1340 :     hTdCngDec->last_shb_ener_fx = 0; // Q8
    2114        1340 :     move16();
    2115        1340 :     hTdCngDec->last_shb_ener_fx_32 = 2; // 0.001 in Q11
    2116        1340 :     move32();
    2117             : 
    2118        1340 :     set16_fx( hTdCngDec->interpol_3_2_cng_dec_fx, 0, INTERP_3_2_MEM_LEN );
    2119             : 
    2120        1340 :     return;
    2121             : }

Generated by: LCOV version 1.14