LCOV - code coverage report
Current view: top level - lib_dec - cng_dec_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main -- dec/rend @ 4c82f1d24d39d0296b18d775f18a006f4c7d024b Lines: 541 745 72.6 %
Date: 2025-05-17 01:59:02 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             :  * CNG_dec_fx()
      26             :  *
      27             :  * Decode residual signal energy
      28             :  *-----------------------------------------------------------------*/
      29             : 
      30        2378 : void CNG_dec_fx(
      31             :     Decoder_State *st_fx,           /* i/o: State structure                          */
      32             :     const Word16 last_element_mode, /* i  : last element mode                    Q0  */
      33             :     Word16 Aq[],                    /* o  : LP coefficients                     Q12  */
      34             :     Word16 *lsp_new,                /* i/o: current frame LSPs                  Q15  */
      35             :     Word16 *lsf_new,                /* i/o: current frame LSFs                  Qlog2(2.56) */
      36             :     Word16 *allow_cn_step,          /* o  : allow CN step                       Q0   */
      37             :     Word16 *sid_bw,                 /* i  : 0-NB/WB, 1-SWB SID                  Q0   */
      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        2378 :     Word16 m = 0;
      48        2378 :     move16();
      49             :     Word16 tmp[HO_HIST_SIZE * M];
      50        2378 :     Word16 burst_ho_cnt = 0;
      51        2378 :     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             :     Word16 LSF_Q_prediction; /* o  : LSF prediction mode - just temporary variable in CNG                */
      76             :     TD_CNG_DEC_HANDLE hTdCngDec;
      77             : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
      78        2378 :     Flag Overflow = 0;
      79        2378 :     move32();
      80             : #endif
      81        2378 :     hTdCngDec = st_fx->hTdCngDec;
      82             : 
      83        2378 :     m = 0;
      84        2378 :     move16();
      85             :     /*-----------------------------------------------------------------*
      86             :      * Decode CNG spectral envelope (only in SID frame)
      87             :      *-----------------------------------------------------------------*/
      88        2378 :     test();
      89        2378 :     IF( EQ_32( st_fx->core_brate, SID_1k75 ) || EQ_32( st_fx->core_brate, SID_2k40 ) )
      90             :     {
      91             :         /* de-quantize the LSF vector */
      92         417 :         IF( st_fx->Opt_AMR_WB != 0 )
      93             :         {
      94             :             /* Flt function */
      95           0 :             isf_dec_amr_wb_fx( st_fx, Aq, lsf_new, lsp_new );
      96             :             /* check IF ISPs  may trigger too much synthesis energy */
      97             : 
      98           0 :             E_LPC_f_isp_a_conversion( lsp_new, Aq_tmp, M );
      99           0 :             enr_new = Enr_1_Az_fx( Aq_tmp, 2 * L_SUBFR );
     100             : 
     101           0 :             IF( ( shr( enr_new, 14 ) > 0 ) )
     102             :             {
     103             :                 /* Use old LSP vector */
     104           0 :                 Copy( st_fx->lsp_old_fx, lsp_new, M ); /* Q15 */
     105           0 :                 Copy( st_fx->lsf_old_fx, lsf_new, M ); /* Q2.56 */
     106             :             }
     107             :         }
     108             :         ELSE
     109             :         {
     110         417 :             lsf_dec_fx( st_fx, 0, Aq, &LSF_Q_prediction, lsf_new, lsp_new, 0, 0, NULL );
     111             : 
     112             :             /* check IF LSPs  may trigger too much synthesis energy */
     113         417 :             E_LPC_f_lsp_a_conversion( lsp_new, Aq_tmp, M );
     114         417 :             enr_new = Enr_1_Az_fx( Aq_tmp, 2 * L_SUBFR );
     115             : 
     116         417 :             IF( shr( enr_new, 14 ) > 0 )
     117             :             {
     118             :                 /* Use old LSP vector */
     119           0 :                 Copy( st_fx->lsp_old_fx, lsp_new, M ); /* Q15 */
     120           0 :                 Copy( st_fx->lsf_old_fx, lsf_new, M ); /* Q2.56 */
     121             :             }
     122             :         }
     123             :     }
     124             :     ELSE
     125             :     {
     126             :         /* Use old LSP vector */
     127        1961 :         Copy( st_fx->lsp_old_fx, lsp_new, M ); /* Q15 */
     128        1961 :         Copy( st_fx->lsf_old_fx, lsf_new, M ); /* Q2.56 */
     129             :     }
     130             : 
     131             :     /* Initialize the CNG spectral envelope in case of the very first CNG frame */
     132        2378 :     IF( st_fx->first_CNG == 0 )
     133             :     {
     134          28 :         Copy( st_fx->lsp_old_fx, st_fx->lspCNG_fx, M ); /* Q15 */
     135             :     }
     136             : 
     137             :     /*-----------------------------------------------------------------*
     138             :      * Decode residual signal energy
     139             :      *-----------------------------------------------------------------*/
     140             : 
     141        2378 :     *allow_cn_step = 0;
     142        2378 :     move16();
     143        2378 :     test();
     144        2378 :     IF( EQ_32( st_fx->core_brate, SID_1k75 ) || EQ_32( st_fx->core_brate, SID_2k40 ) )
     145             :     {
     146         417 :         istep = ISTEP_AMR_WB_SID_FX; /* Q15 */
     147         417 :         move16();
     148         417 :         if ( EQ_32( st_fx->core_brate, SID_2k40 ) )
     149             :         {
     150         417 :             istep = ISTEP_SID_FX; /* Q15 */
     151         417 :             move16();
     152             :         }
     153             : 
     154             :         /* initialize the energy quantization parameters */
     155         417 :         num_bits = 6;
     156         417 :         move16();
     157         417 :         if ( st_fx->Opt_AMR_WB == 0 )
     158             :         {
     159         417 :             num_bits = 7;
     160         417 :             move16();
     161             :         }
     162             : 
     163             :         /* decode the energy index */
     164         417 :         L_enr_index = get_next_indice_fx( st_fx, num_bits );
     165             : 
     166         417 :         IF( LE_32( st_fx->last_core_brate, SID_2k40 ) || EQ_16( st_fx->prev_bfi, 1 ) )
     167             :         {
     168         228 :             tmp1 = add( hTdCngDec->old_enr_index, 20 );
     169             :         }
     170             :         ELSE
     171             :         {
     172         189 :             tmp1 = add( hTdCngDec->old_enr_index, 40 );
     173             :         }
     174         417 :         IF( GT_16( L_enr_index, tmp1 ) && hTdCngDec->old_enr_index >= 0 ) /* Likely bit error and not startup */
     175             :         {
     176           0 :             L_enr_index = tmp1;
     177           0 :             move16();
     178           0 :             L_enr_index = s_min( L_enr_index, 127 ); /* Q0 */
     179           0 :             IF( st_fx->Opt_AMR_WB )
     180             :             {
     181           0 :                 L_enr_index = s_min( L_enr_index, 63 ); /* Q0 */
     182             :             }
     183             :         }
     184             : 
     185         417 :         test();
     186         417 :         test();
     187         417 :         test();
     188         417 :         IF( GT_32( st_fx->last_core_brate, SID_1k75 ) &&
     189             :             NE_16( st_fx->first_CNG, 0 ) &&
     190             :             GE_16( hTdCngDec->old_enr_index, 0 ) &&
     191             :             GT_16( L_enr_index, add( hTdCngDec->old_enr_index, 1 ) ) )
     192             :         {
     193           0 :             *allow_cn_step = 1;
     194           0 :             move16();
     195             :         }
     196             : 
     197         417 :         hTdCngDec->old_enr_index = L_enr_index;
     198         417 :         move16();
     199         417 :         if ( !L_enr_index )
     200             :         {
     201          18 :             L_enr_index = -5;
     202          18 :             move16();
     203             :         }
     204             :         /* st_fx->Enew = L_enr_index / step - 2.0f;*/
     205         417 :         L_ener = L_mult( L_enr_index, istep ); /* Q16 (0+15) */
     206             :         /* subtract by 2 not done to leave Energy in Q2 */
     207             : 
     208             :         /* extract integral and fractional parts */
     209         417 :         ener_fra = L_Extract_lc( L_ener, &ener_int );
     210         417 :         ener_int = add( ener_int, 4 ); /* Q2 to Q6 */
     211             : 
     212             :         /* find the new energy value */
     213         417 :         hTdCngDec->Enew_fx = Pow2( ener_int, ener_fra );
     214         417 :         move32();
     215             : 
     216         417 :         IF( EQ_32( st_fx->core_brate, SID_2k40 ) )
     217             :         {
     218         417 :             burst_ho_cnt = get_next_indice_fx( st_fx, 3 ); /* 3bit */
     219             : 
     220         417 :             *sid_bw = get_next_indice_fx( st_fx, 1 );
     221         417 :             move16();
     222         417 :             IF( *sid_bw == 0 )
     223             :             {
     224           0 :                 env_idx[0] = get_next_indice_fx( st_fx, 6 );
     225           0 :                 move16();
     226             : 
     227             :                 /* get quantized res_env_details */
     228           0 :                 FOR( i = 0; i < NUM_ENV_CNG; i++ )
     229             :                 {
     230           0 :                     q_env[i] = L_deposit_l( CNG_details_codebook_fx[env_idx[0]][i] );
     231           0 :                     move32();
     232             :                 }
     233             :             }
     234             :         }
     235             :         /* Reset CNG history IF CNG frame length is changed */
     236         417 :         test();
     237         417 :         test();
     238         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 ) )
     239             :         {
     240           1 :             hTdCngDec->ho_hist_size = 0;
     241           1 :             move16();
     242             :         }
     243             :     }
     244             : 
     245             :     /*---------------------------------------------------------------------*
     246             :      * CNG spectral envelope update
     247             :      * Find A(z) coefficients
     248             :      *---------------------------------------------------------------------*/
     249        2378 :     test();
     250        2378 :     test();
     251        2378 :     test();
     252        2378 :     IF( LE_32( st_fx->last_core_brate, SID_2k40 ) )
     253             :     {
     254             :         /* Reset hangover counter if not first SID period */
     255        2189 :         if ( GT_32( st_fx->core_brate, FRAME_NO_DATA ) )
     256             :         {
     257         228 :             hTdCngDec->num_ho = 0;
     258         228 :             move16();
     259             :         }
     260             :         /* Update LSPs IF last SID energy not outliers or insufficient number of hangover frames */
     261        2189 :         test();
     262        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 ) )
     263             :         {
     264       36669 :             FOR( i = 0; i < M; i++ )
     265             :             {
     266             :                 /* AR low-pass filter  */
     267       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] );
     268       34512 :                 move16(); /* Q15 (15+15+1-16) */
     269             :             }
     270             :         }
     271             :     }
     272             :     ELSE
     273             :     {
     274             :         /* Update CNG_mode IF allowed */
     275         189 :         test();
     276         189 :         test();
     277         189 :         test();
     278         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 ) ) )
     279             :         {
     280           6 :             IF( GT_32( st_fx->last_active_brate, ACELP_16k40 ) )
     281             :             {
     282           3 :                 st_fx->CNG_mode = -1;
     283           3 :                 move16();
     284             :             }
     285             :             ELSE
     286             :             {
     287           3 :                 st_fx->CNG_mode = get_cng_mode( st_fx->last_active_brate );
     288           3 :                 move16();
     289             :             }
     290             :         }
     291             : 
     292             :         /* If first sid after active burst update LSF history from circ buffer */
     293         189 :         burst_ho_cnt = s_min( burst_ho_cnt, hTdCngDec->ho_circ_size ); /* MODE1_DTX_IN_CODEC_B_FIX   Q0*/
     294         189 :         hTdCngDec->act_cnt = 0;
     295         189 :         move16();
     296         189 :         s_ptr = add( sub( hTdCngDec->ho_circ_ptr, burst_ho_cnt ), 1 );
     297         189 :         IF( s_ptr < 0 )
     298             :         {
     299          34 :             s_ptr = add( s_ptr, hTdCngDec->ho_circ_size );
     300             :         }
     301             : 
     302         478 :         FOR( ll = burst_ho_cnt; ll > 0; ll-- )
     303             :         {
     304         289 :             hTdCngDec->ho_hist_ptr = add( hTdCngDec->ho_hist_ptr, 1 ); /* Q0 */
     305         289 :             move16();
     306         289 :             if ( EQ_16( hTdCngDec->ho_hist_ptr, HO_HIST_SIZE ) )
     307             :             {
     308          25 :                 hTdCngDec->ho_hist_ptr = 0;
     309          25 :                 move16();
     310             :             }
     311             : 
     312             :             /* Conversion between 12.8k and 16k LSPs */
     313         289 :             test();
     314         289 :             test();
     315         289 :             test();
     316         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 ) ) )
     317             :             {
     318             :                 /* Conversion from 16k LPSs to 12k8 */
     319          61 :                 lsp_convert_poly_fx( &( hTdCngDec->ho_lsp_circ_fx[s_ptr * M] ), st_fx->L_frame, 0 );
     320             :             }
     321             :             /* update the circular buffers */
     322         289 :             Copy( &( hTdCngDec->ho_lsp_circ_fx[s_ptr * M] ), &( hTdCngDec->ho_lsp_hist_fx[hTdCngDec->ho_hist_ptr * M] ), M ); /* Qx */
     323         289 :             Copy32( &( hTdCngDec->ho_ener_circ_fx[s_ptr] ), &( hTdCngDec->ho_ener_hist_fx[hTdCngDec->ho_hist_ptr] ), 1 );     /* Q6 */
     324         289 :             hTdCngDec->ho_sid_bw = L_shl( L_and( hTdCngDec->ho_sid_bw, (Word32) 0x3fffffffL ), 1 );
     325         289 :             move32();
     326         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 */
     327             : 
     328         289 :             hTdCngDec->ho_hist_size = add( hTdCngDec->ho_hist_size, 1 );
     329         289 :             move16();
     330             : 
     331         289 :             if ( GT_16( hTdCngDec->ho_hist_size, HO_HIST_SIZE ) )
     332             :             {
     333          32 :                 hTdCngDec->ho_hist_size = HO_HIST_SIZE;
     334          32 :                 move16();
     335             :             }
     336             : 
     337         289 :             s_ptr = add( s_ptr, 1 );
     338         289 :             if ( EQ_16( s_ptr, hTdCngDec->ho_circ_size ) )
     339             :             {
     340          36 :                 s_ptr = 0;
     341          36 :                 move16();
     342             :             }
     343             :         }
     344             : 
     345         189 :         IF( hTdCngDec->ho_hist_size > 0 ) /* can be -1 at init    MODE1_DTX_IN_CODEC_B_FIX    */
     346             :         {
     347             :             /* *allow_cn_step |= ( st_fx->ho_ener_hist[st_fx->ho_hist_ptr] > 4.0f * st_fx->lp_ener );*/
     348         137 :             L_tmp1 = L_shr( hTdCngDec->ho_ener_hist_fx[hTdCngDec->ho_hist_ptr], 2 );
     349         137 :             L_tmp1 = L_sub( L_tmp1, st_fx->lp_ener_fx );
     350             : 
     351         137 :             test();
     352         137 :             test();
     353         137 :             IF( ( L_tmp1 > 0 && ( st_fx->first_CNG || st_fx->element_mode == EVS_MONO ) ) )
     354             :             {
     355           8 :                 *allow_cn_step = s_or( *allow_cn_step, 1 );
     356           8 :                 move16();
     357             :             }
     358             :         }
     359         189 :         IF( EQ_16( last_element_mode, IVAS_CPE_TD ) )
     360             :         {
     361          15 :             *allow_cn_step = 1;
     362          15 :             move16();
     363             :         }
     364         189 :         test();
     365         189 :         IF( EQ_16( *allow_cn_step, 0 ) && GT_16( hTdCngDec->ho_hist_size, 0 ) )
     366             :         {
     367             :             /* Use average of energies below last energy */
     368         122 :             ptr = hTdCngDec->ho_hist_ptr;
     369         122 :             move16();
     370         122 :             Copy( &( hTdCngDec->ho_lsp_hist_fx[ptr * M] ), tmp, M ); /* Qx */
     371         122 :             m1 = 0;
     372         122 :             move16();
     373         122 :             IF( L_and( hTdCngDec->ho_sid_bw, (Word32) 0x1 ) == 0 )
     374             :             {
     375          77 :                 Copy32( &hTdCngDec->ho_env_hist_fx[ptr * NUM_ENV_CNG], tmp_env, NUM_ENV_CNG );
     376          77 :                 m1 = 1;
     377          77 :                 move16();
     378             :             }
     379         122 :             L_enr = Mult_32_16( hTdCngDec->ho_ener_hist_fx[ptr], W_DTX_HO_FX[0] ); /* Q6+15-15->Q6 */
     380             : 
     381         122 :             weights = W_DTX_HO_FX[0]; /* Q15 */
     382         122 :             move16();
     383             : 
     384         122 :             m = 1;
     385         122 :             move16();
     386         531 :             FOR( k = 1; k < hTdCngDec->ho_hist_size; k++ )
     387             :             {
     388         409 :                 ptr--;
     389         409 :                 if ( ptr < 0 )
     390             :                 {
     391          22 :                     ptr = HO_HIST_SIZE - 1;
     392          22 :                     move16();
     393             :                 }
     394             : 
     395         409 :                 test();
     396         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] ) &&
     397             :                     GT_32( hTdCngDec->ho_ener_hist_fx[ptr], Mult_32_16( hTdCngDec->ho_ener_hist_fx[hTdCngDec->ho_hist_ptr], BUF_L_NRG_FX ) ) )
     398             :                 {
     399             :                     /*enr += W_DTX_HO[k] * st_fx->ho_ener_hist[ptr];*/
     400         185 :                     L_tmp1 = Mult_32_16( hTdCngDec->ho_ener_hist_fx[ptr], W_DTX_HO_FX[k] ); /* Q6+15-15->Q6 */
     401         185 :                     L_enr = L_add( L_enr, L_tmp1 );                                         /* Q6 */
     402             : 
     403             :                     /*weights += W_DTX_HO[k];*/
     404         185 :                     weights = add( weights, W_DTX_HO_FX[k] ); /* Q15 */
     405             : 
     406         185 :                     Copy( &hTdCngDec->ho_lsp_hist_fx[ptr * M], &tmp[m * M], M ); /* Qx */
     407         185 :                     IF( EQ_32( L_and( hTdCngDec->ho_sid_bw, L_shl( (Word32) 0x1, k ) ), 0 ) )
     408             :                     {
     409         122 :                         Copy32( &hTdCngDec->ho_env_hist_fx[ptr * NUM_ENV_CNG], &tmp_env[m1 * NUM_ENV_CNG], NUM_ENV_CNG ); /* Qx */
     410         122 :                         m1++;
     411             :                     }
     412         185 :                     m++;
     413             :                 }
     414             :             }
     415             : 
     416             :             /*enr /= weights;*/
     417         122 :             exp = norm_s( weights );
     418         122 :             tmp1 = div_s( shl( 1, sub( 14, exp ) ), weights ); /* Q(15+14-exp-15) */
     419         122 :             L_tmp1 = Mult_32_16( L_enr, tmp1 );                /* Q(14-exp+6-15)->Q(5-exp) */
     420         122 :             L_enr = L_shl( L_tmp1, add( exp, 1 ) );            /* Q6 */
     421             : 
     422         122 :             st_fx->lp_ener_fx = L_enr; /* Q6 */
     423         122 :             move32();
     424         122 :             set32_fx( max_val, 0, 2 );
     425         122 :             set16_fx( max_idx, 0, 2 );
     426             : 
     427         429 :             FOR( i = 0; i < m; i++ )
     428             :             {
     429         307 :                 IF( EQ_16( st_fx->L_frame, L_FRAME ) )
     430             :                 {
     431         201 :                     lsp2lsf_fx( &tmp[i * M], lsf_tmp, M, INT_FS_FX );
     432         201 :                     ftmp_fx = 964;
     433         201 :                     move16();                                            /*X2.56 */
     434         201 :                     tmpv = sub( 16384, add( lsf_tmp[M - 1], ftmp_fx ) ); /*QX2.56*/
     435         201 :                     L_tmp = L_mult0( tmpv, tmpv );                       /*QX6.5536*/
     436             :                 }
     437             :                 ELSE
     438             :                 {
     439         106 :                     lsp2lsf_fx( &tmp[i * M], lsf_tmp, M, INT_FS_16k_FX );
     440         106 :                     ftmp_fx = 1205;
     441         106 :                     move16();                                            /*QX2.56*/
     442         106 :                     tmpv = sub( 20480, add( lsf_tmp[M - 1], ftmp_fx ) ); /*QX2.56*/
     443         106 :                     L_tmp = L_mult0( tmpv, tmpv );                       /*QX6.5536*/
     444             :                 }
     445             : 
     446         307 :                 tmpv = sub( lsf_tmp[0], ftmp_fx );   /*QX2.56*/
     447         307 :                 L_tmp = L_mac0( L_tmp, tmpv, tmpv ); /*QX6.5536*/
     448        4912 :                 FOR( j = 0; j < M - 1; j++ )
     449             :                 {
     450        4605 :                     tmpv = sub( sub( lsf_tmp[j + 1], lsf_tmp[j] ), ftmp_fx ); /*QX2.56*/
     451        4605 :                     L_tmp = L_mac0( L_tmp, tmpv, tmpv );                      /*QX6.5536*/
     452             :                 }
     453             : 
     454         307 :                 C[i] = Mpy_32_16_1( L_tmp, 1928 ); /*QX6.5536*/
     455         307 :                 move32();
     456             : 
     457         307 :                 IF( GT_32( C[i], max_val[0] ) )
     458             :                 {
     459         220 :                     max_val[1] = max_val[0];
     460         220 :                     move32();
     461         220 :                     max_idx[1] = max_idx[0];
     462         220 :                     move16();
     463         220 :                     max_val[0] = C[i];
     464         220 :                     move32();
     465         220 :                     max_idx[0] = i;
     466         220 :                     move16();
     467             :                 }
     468          87 :                 ELSE IF( GT_32( C[i], max_val[1] ) )
     469             :                 {
     470          49 :                     max_val[1] = C[i];
     471          49 :                     move32();
     472          49 :                     max_idx[1] = i;
     473          49 :                     move16();
     474             :                 }
     475             :             }
     476             : 
     477         122 :             IF( EQ_16( m, 1 ) )
     478             :             {
     479          42 :                 Copy( tmp, lsp_tmp, M ); /* Qx */
     480             :             }
     481          80 :             ELSE IF( LT_16( m, 4 ) )
     482             :             {
     483        1020 :                 FOR( i = 0; i < M; i++ )
     484             :                 {
     485         960 :                     L_tmp1 = 0;
     486         960 :                     move32();
     487        3504 :                     FOR( j = 0; j < m; j++ )
     488             :                     {
     489        2544 :                         L_tmp1 = L_add( L_tmp1, L_deposit_l( tmp[j * M + i] ) );
     490             :                     }
     491             : 
     492         960 :                     L_tmp1 = L_sub( L_tmp1, L_deposit_l( tmp[max_idx[0] * M + i] ) );
     493         960 :                     tmpv = div_s( 1, sub( m, 1 ) );       /*Q15*/
     494         960 :                     L_tmp1 = Mpy_32_16_1( L_tmp1, tmpv ); /*Q15*/
     495         960 :                     lsp_tmp[i] = extract_l( L_tmp1 );     /*Q15*/
     496         960 :                     move16();
     497             :                 }
     498             :             }
     499             :             ELSE
     500             :             {
     501         340 :                 FOR( i = 0; i < M; i++ )
     502             :                 {
     503         320 :                     L_tmp1 = 0;
     504         320 :                     move32();
     505        2016 :                     FOR( j = 0; j < m; j++ )
     506             :                     {
     507        1696 :                         L_tmp1 = L_add( L_tmp1, L_deposit_l( tmp[j * M + i] ) );
     508             :                     }
     509             : 
     510         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*/
     511         320 :                     tmpv = div_s( 1, sub( m, 2 ) );                                                                                    /*Q15*/
     512         320 :                     L_tmp1 = Mpy_32_16_1( L_tmp1, tmpv );                                                                              /*Q15*/
     513         320 :                     lsp_tmp[i] = extract_l( L_tmp1 );                                                                                  /*Q15*/
     514         320 :                     move16();
     515             :                 }
     516             :             }
     517             : 
     518         122 :             dist = 0;
     519         122 :             move16(); /*Q15*/
     520         122 :             max_dev = 0;
     521         122 :             move16(); /*Q15*/
     522        2074 :             FOR( i = 0; i < M; i++ )
     523             :             {
     524        1952 :                 dev = abs_s( sub( lsp_tmp[i], lsp_new[i] ) ); /*Q15*/
     525        1952 :                 dist = add_o( dist, dev, &Overflow );         /*Q15*/
     526        1952 :                 if ( GT_16( dev, max_dev ) )
     527             :                 {
     528         610 :                     max_dev = dev;
     529         610 :                     move16();
     530             :                 }
     531             :             }
     532             : 
     533         122 :             test();
     534         122 :             IF( GT_16( dist, 13107 ) || GT_16( max_dev, 3277 ) ) /* 0.4 and 0.1 in Q15 */
     535             :             {
     536          34 :                 FOR( i = 0; i < M; i++ )
     537             :                 {
     538          32 :                     st_fx->lspCNG_fx[i] = lsp_tmp[i];
     539          32 :                     move16(); /*Q15*/
     540             :                 }
     541             :             }
     542             :             ELSE
     543             :             {
     544        2040 :                 FOR( i = 0; i < M; i++ )
     545             :                 {
     546             :                     /* AR low-pass filter  */
     547        1920 :                     st_fx->lspCNG_fx[i] = add( mult_r( 26214, lsp_tmp[i] ), mult_r( 6554, lsp_new[i] ) ); /* Q15 */
     548        1920 :                     move16();
     549             :                 }
     550             :             }
     551         122 :             IF( m1 > 0 )
     552             :             {
     553        1953 :                 FOR( i = 0; i < NUM_ENV_CNG; i++ )
     554             :                 {
     555        1860 :                     L_tmp = L_deposit_l( 0 );
     556        5840 :                     FOR( j = 0; j < m1; j++ )
     557             :                     {
     558             :                         /* env[i] += tmp_env[j*NUM_ENV_CNG+i];*/
     559        3980 :                         L_tmp = L_add_sat( L_tmp, tmp_env[j * NUM_ENV_CNG + i] );
     560             :                     }
     561             :                     /*    env[i] /= (float)m1;  */
     562             :                     /*    env[i] = env[i] - 2*st_fx->lp_ener_fx; */
     563        1860 :                     IF( EQ_16( m1, 1 ) )
     564             :                     {
     565         680 :                         L_tmp = L_sub_sat( L_tmp, L_add_sat( st_fx->lp_ener_fx, st_fx->lp_ener_fx ) ); /* Q6 */
     566             :                     }
     567             :                     ELSE
     568             :                     {
     569        1180 :                         tmp1 = div_s( 1, m1 );
     570        1180 :                         L_tmp = Mult_32_16( L_tmp, tmp1 );                                             /* Q6 */
     571        1180 :                         L_tmp = L_sub_sat( L_tmp, L_add_sat( st_fx->lp_ener_fx, st_fx->lp_ener_fx ) ); /* Q6 */
     572             :                     }
     573        1860 :                     env[i] = L_tmp; /* Q6 */
     574        1860 :                     move32();
     575             :                 }
     576             : 
     577          93 :                 Copy32( env, hTdCngDec->lp_env_fx, NUM_ENV_CNG ); /* Q6 */
     578             :             }
     579             :         }
     580             :         ELSE
     581             :         {
     582          67 :             Copy( lsp_new, st_fx->lspCNG_fx, M ); /* use newly analyzed ISFs */ /* Q15 */
     583             :         }
     584             :     }
     585             : 
     586        2378 :     test();
     587        2378 :     IF( EQ_32( st_fx->core_brate, SID_1k75 ) || EQ_32( st_fx->core_brate, SID_2k40 ) )
     588             :     {
     589             :         /* Update hangover memory during CNG */
     590         417 :         test();
     591         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 ) ) ) )
     592             :         {
     593             :             /* update the pointer to circular buffer of old LSP vectors */
     594         285 :             hTdCngDec->ho_hist_ptr++;
     595         285 :             move16();
     596         285 :             if ( EQ_16( hTdCngDec->ho_hist_ptr, HO_HIST_SIZE ) )
     597             :             {
     598          34 :                 hTdCngDec->ho_hist_ptr = 0;
     599          34 :                 move16();
     600             :             }
     601             : 
     602             :             /* update the circular buffer of old LSP vectors with the new LSP vector */
     603         285 :             Copy( lsp_new, &( hTdCngDec->ho_lsp_hist_fx[( hTdCngDec->ho_hist_ptr ) * M] ), M ); /* Q15 */
     604             : 
     605             :             /* update the hangover energy buffer */
     606         285 :             hTdCngDec->ho_ener_hist_fx[hTdCngDec->ho_hist_ptr] = hTdCngDec->Enew_fx; /* Q6 */
     607         285 :             move32();
     608         285 :             test();
     609         285 :             IF( EQ_32( st_fx->core_brate, SID_2k40 ) && ( *sid_bw == 0 ) )
     610             :             {
     611             :                 /*  enr1 = (float)log10( st->Enew*L_frame + 0.1f ) / (float)log10( 2.0f );*/
     612           0 :                 exp = norm_l( hTdCngDec->Enew_fx );
     613           0 :                 L_tmp = L_shl( hTdCngDec->Enew_fx, exp );              /*Q(exp+6)*/
     614           0 :                 L_tmp = Mult_32_16( L_tmp, shl( st_fx->L_frame, 5 ) ); /*Q(exp+6+5-15=exp-4)*/
     615           0 :                 L_tmp = L_shr_sat( L_tmp, sub( exp, 10 ) );            /*Q6*/
     616           0 :                 exp = norm_l( L_tmp );
     617           0 :                 fra = Log2_norm_lc( L_shl( L_tmp, exp ) );
     618           0 :                 exp = sub( sub( 30, exp ), 6 );
     619           0 :                 L_tmp = L_Comp( exp, fra );
     620           0 :                 enr1 = L_shr( L_tmp, 10 ); /* Q6 */
     621             : 
     622           0 :                 FOR( i = 0; i < NUM_ENV_CNG; i++ )
     623             :                 {
     624             :                     /* get quantized envelope */
     625             :                     /*  env[i] = pow(2.0f,(enr1 - q_env[i])) + 2*st->Enew;*/
     626           0 :                     L_tmp = L_sub( enr1, q_env[i] ); /* Q6 */
     627           0 :                     L_tmp = L_shl( L_tmp, 10 );      /* 16 */
     628           0 :                     temp_lo_fx = L_Extract_lc( L_tmp, &temp_hi_fx );
     629             : 
     630           0 :                     exp_pow = sub( 14, temp_hi_fx );
     631           0 :                     L_tmp = Pow2( 14, temp_lo_fx );             /* Qexp_pow */
     632           0 :                     env[i] = L_shl( L_tmp, sub( 6, exp_pow ) ); /* Q6 */
     633           0 :                     move32();
     634           0 :                     L_tmp = L_add( hTdCngDec->Enew_fx, hTdCngDec->Enew_fx );
     635           0 :                     env[i] = L_add( env[i], L_tmp ); /* Q6 */
     636           0 :                     move32();
     637             :                 }
     638           0 :                 hTdCngDec->ho_sid_bw = L_shl( L_and( hTdCngDec->ho_sid_bw, (Word32) 0x3fffffffL ), 1 ); /* Q0 */
     639           0 :                 move32();
     640           0 :                 Copy32( env, &( hTdCngDec->ho_env_hist_fx[hTdCngDec->ho_hist_ptr * NUM_ENV_CNG] ), NUM_ENV_CNG ); /* Q6 */
     641             :             }
     642         285 :             ELSE IF( ( *sid_bw != 0 ) )
     643             :             {
     644         285 :                 hTdCngDec->ho_sid_bw = L_shl( L_and( hTdCngDec->ho_sid_bw, (Word32) 0x3fffffffL ), 1 ); /* Q0 */
     645         285 :                 move32();
     646         285 :                 hTdCngDec->ho_sid_bw = L_or( hTdCngDec->ho_sid_bw, 0x1L ); /* Q0 */
     647         285 :                 move32();
     648             :             }
     649             : 
     650         285 :             hTdCngDec->ho_hist_size = add( hTdCngDec->ho_hist_size, 1 );
     651         285 :             move16();
     652         285 :             if ( GT_16( hTdCngDec->ho_hist_size, HO_HIST_SIZE ) )
     653             :             {
     654         169 :                 hTdCngDec->ho_hist_size = HO_HIST_SIZE;
     655         169 :                 move16();
     656             :             }
     657             :         }
     658             :         /* Update the frame length memory */
     659         417 :         st_fx->last_CNG_L_frame = st_fx->L_frame;
     660         417 :         move16();
     661             : 
     662         417 :         if ( NE_32( st_fx->core_brate, SID_1k75 ) )
     663             :         {
     664         417 :             hTdCngDec->num_ho = m;
     665         417 :             move16();
     666             :         }
     667             :     }
     668             : 
     669        2378 :     IF( st_fx->element_mode == EVS_MONO )
     670             :     {
     671           0 :         st_fx->last_CNG_L_frame = st_fx->L_frame;
     672           0 :         move16();
     673             : 
     674           0 :         IF( NE_32( st_fx->core_brate, SID_1k75 ) )
     675             :         {
     676           0 :             hTdCngDec->num_ho = m;
     677           0 :             move16();
     678             :         }
     679             :     }
     680        2378 :     IF( st_fx->Opt_AMR_WB )
     681             :     {
     682           0 :         E_LPC_f_isp_a_conversion( st_fx->lspCNG_fx, Aq, M );
     683             :     }
     684             :     ELSE
     685             :     {
     686        2378 :         E_LPC_f_lsp_a_conversion( st_fx->lspCNG_fx, Aq, M );
     687             :     }
     688             : 
     689        2378 :     tmp_loop = shr( st_fx->L_frame, 6 );
     690       11044 :     FOR( i = 1; i < tmp_loop; i++ ) /* L_frame/L_SUBFR */
     691             :     {
     692        8666 :         Copy( Aq, &Aq[i * ( M + 1 )], add( M, 1 ) ); /* Q12 */
     693             :     }
     694             : 
     695        2378 :     return;
     696             : }
     697             : 
     698             : /*---------------------------------------------------------------------*
     699             :  * swb_CNG_dec()
     700             :  *
     701             :  * Comfort noise generation for SHB signal
     702             :  *---------------------------------------------------------------------*/
     703             : 
     704        1852 : void swb_CNG_dec_fx(
     705             :     Decoder_State *st_fx,   /* i/o: State structure                          */
     706             :     const Word16 *synth_fx, /* i  : ACELP core synthesis at 32kHz                Qsyn*/
     707             :     Word16 *shb_synth_fx,   /* o  : high-band CNG synthesis                Qx*/
     708             :     const Word16 sid_bw,    /* i  : 0-NB/WB, 1-SWB SID                     Q0*/
     709             :     const Word16 Qsyn       /* i  : Q value of ACELP core synthesis          */
     710             : )
     711             : {
     712        1852 :     test();
     713        1852 :     IF( EQ_32( st_fx->core_brate, FRAME_NO_DATA ) || EQ_32( st_fx->core_brate, SID_2k40 ) )
     714             :     {
     715             :         /* SHB SID decoding and CNG */
     716           0 :         test();
     717           0 :         IF( EQ_16( st_fx->cng_type, LP_CNG ) && EQ_16( st_fx->extl, SWB_CNG ) )
     718             :         {
     719           0 :             shb_CNG_decod_fx( st_fx, synth_fx, shb_synth_fx, sid_bw, Qsyn );
     720             :         }
     721           0 :         st_fx->last_vad_fx = 0;
     722           0 :         move16();
     723           0 :         st_fx->hTdCngDec->burst_cnt_fx = 0;
     724           0 :         move16();
     725             :     }
     726             :     ELSE
     727             :     {
     728        1852 :         st_fx->last_vad_fx = 1;
     729        1852 :         move16();
     730        1852 :         st_fx->hTdCngDec->burst_cnt_fx = add( st_fx->hTdCngDec->burst_cnt_fx, 1 );
     731        1852 :         move16();
     732        1852 :         if ( GT_16( st_fx->hTdCngDec->burst_cnt_fx, 10 ) )
     733             :         {
     734         167 :             st_fx->hTdCngDec->burst_cnt_fx = 0;
     735         167 :             move16();
     736             :         }
     737             :     }
     738             : 
     739        1852 :     return;
     740             : }
     741             : 
     742      213448 : void swb_CNG_dec_ivas_fx(
     743             :     Decoder_State *st_fx,   /* i/o: State structure                          */
     744             :     const Word16 *synth_fx, /* i  : ACELP core synthesis at 32kHz        Qsyn*/
     745             :     Word16 *shb_synth_fx,   /* o  : high-band CNG synthesis                Qx*/
     746             :     const Word16 sid_bw,    /* i  : 0-NB/WB, 1-SWB SID                     Q0*/
     747             :     const Word16 Qsyn       /* i  : Q value of ACELP core synthesis          */
     748             : )
     749             : {
     750      213448 :     test();
     751      213448 :     IF( EQ_32( st_fx->core_brate, FRAME_NO_DATA ) || EQ_32( st_fx->core_brate, SID_2k40 ) )
     752             :     {
     753             :         /* SHB SID decoding and CNG */
     754       12817 :         test();
     755       12817 :         IF( EQ_16( st_fx->cng_type, LP_CNG ) && EQ_16( st_fx->extl, SWB_CNG ) )
     756             :         {
     757        1788 :             shb_CNG_decod_ivas_fx( st_fx, synth_fx, shb_synth_fx, sid_bw, Qsyn );
     758             :         }
     759       12817 :         st_fx->last_vad_fx = 0;
     760       12817 :         move16();
     761       12817 :         st_fx->hTdCngDec->burst_cnt_fx = 0;
     762       12817 :         move16();
     763             :     }
     764             :     ELSE
     765             :     {
     766      200631 :         st_fx->last_vad_fx = 1;
     767      200631 :         move16();
     768      200631 :         st_fx->hTdCngDec->burst_cnt_fx = add_sat( st_fx->hTdCngDec->burst_cnt_fx, 1 ); // saturation reached?
     769      200631 :         move16();
     770      200631 :         if ( GT_16( st_fx->hTdCngDec->burst_cnt_fx, 10 ) )
     771             :         {
     772       17347 :             st_fx->hTdCngDec->burst_cnt_fx = 0;
     773       17347 :             move16();
     774             :         }
     775             :     }
     776             : 
     777      213448 :     return;
     778             : }
     779             : 
     780             : /*---------------------------------------------------------------------*
     781             :  * shb_CNG_decod()
     782             :  *
     783             :  * Main routine of SHB SID decoding and CNG
     784             :  *---------------------------------------------------------------------*/
     785             : 
     786           0 : static void shb_CNG_decod_fx(
     787             :     Decoder_State *st_fx,   /* i/o: State structure                          */
     788             :     const Word16 *synth_fx, /* i  : ACELP core synthesis at 32kHz        Qsyn*/
     789             :     Word16 *shb_synth_fx,   /* o  : high-band CNG synthesis                                Qx*/
     790             :     const Word16 sid_bw,    /* i  : 0-NB/WB, 1-SWB SID                     Q0*/
     791             :     const Word16 Qsyn       /* i  : Q value of ACELP core synthesis          */
     792             : )
     793             : {
     794             :     Word16 i;
     795             :     Word16 idx_ener_fx;
     796             :     TD_CNG_DEC_HANDLE hTdCngDec;
     797             :     Word16 shb_lpcCNG_fx[LPC_SHB_ORDER + 1];
     798             :     Word16 shb_lspCNG_fx[LPC_SHB_ORDER];
     799             :     Word16 excTmp_fx[L_FRAME16k];
     800             :     Word16 excSHB_fx[L_FRAME16k];
     801             :     Word16 tmp_lsp[LPC_SHB_ORDER];
     802             :     Word16 ener_excSHB_fx;
     803             :     Word32 wb_ener_fx;
     804             :     Word16 wb_ener16_fx;
     805             :     Word32 L_gain_fx;
     806             :     Word16 gain_fx;
     807             :     Word16 shb_syn16k_fx[L_FRAME16k];
     808             :     Word16 tmp;
     809             :     Word16 step_fx;
     810             :     Word16 interp_fx;
     811             :     Word16 ener_fx;
     812             :     Word16 exp, exp1;
     813             :     Word16 fra;
     814             :     Word32 L_tmp;
     815             :     Word16 tmp2;
     816           0 :     Word16 allow_cn_step_fx = 0;
     817           0 :     move16();
     818             :     Word16 q;
     819             :     TD_BWE_DEC_HANDLE hBWE_TD;
     820             : 
     821           0 :     hBWE_TD = st_fx->hBWE_TD;
     822           0 :     hTdCngDec = st_fx->hTdCngDec;
     823             : 
     824           0 :     IF( st_fx->bfi == 0 )
     825             :     {
     826           0 :         test();
     827           0 :         IF( EQ_32( st_fx->core_brate, SID_2k40 ) && EQ_16( sid_bw, 1 ) )
     828             :         {
     829           0 :             idx_ener_fx = get_next_indice_fx( st_fx, 4 );
     830             : 
     831           0 :             if ( !idx_ener_fx )
     832             :             {
     833           0 :                 idx_ener_fx = -15;
     834           0 :                 move16();
     835             :             }
     836           0 :             IF( st_fx->element_mode == EVS_MONO )
     837             :             {
     838             :                 /* de-quantization of SHB CNG parameters */
     839           0 :                 L_tmp = L_mult( idx_ener_fx, 27400 );                                              /*Q14  */
     840           0 :                 hTdCngDec->last_shb_cng_ener_fx = extract_l( L_shr( L_sub( L_tmp, 295924 ), 6 ) ); /*Q8 */
     841           0 :                 move16();
     842             :             }
     843             :             ELSE
     844             :             {
     845             :             }
     846             :         }
     847             :     }
     848             : 
     849             :     /* SHB spectrum estimation */
     850             : 
     851             : 
     852           0 :     interp_fx = s_min( hTdCngDec->shb_dtx_count_fx, 32 );
     853           0 :     interp_fx = shl_sat( interp_fx, 10 ); /*Q15*/
     854           0 :     FOR( i = 0; i < LPC_SHB_ORDER; i++ )
     855             :     {
     856           0 :         tmp2 = mult( interp_fx, hTdCngDec->lsp_shb_prev_fx[i] );                   /*Q14*/
     857           0 :         tmp = mult( sub( 32767, interp_fx ), hTdCngDec->lsp_shb_prev_prev_fx[i] ); /*Q14*/
     858           0 :         shb_lspCNG_fx[i] = add( tmp2, tmp );
     859           0 :         move16(); /*Q14*/
     860             :     }
     861             : 
     862           0 :     IF( NE_16( st_fx->element_mode, IVAS_CPE_DFT ) )
     863             :     {
     864           0 :         if ( LT_16( hTdCngDec->shb_dtx_count_fx, 1000 ) )
     865             :         {
     866           0 :             hTdCngDec->shb_dtx_count_fx = add( hTdCngDec->shb_dtx_count_fx, 1 );
     867           0 :             move16();
     868             :         }
     869             :     }
     870           0 :     E_LPC_lsf_lsp_conversion( shb_lspCNG_fx, tmp_lsp, LPC_SHB_ORDER ); /*Q14*/
     871           0 :     E_LPC_f_lsp_a_conversion( tmp_lsp, shb_lpcCNG_fx, LPC_SHB_ORDER );
     872             : 
     873           0 :     Copy_Scale_sig( shb_lpcCNG_fx, shb_lpcCNG_fx, LPC_SHB_ORDER + 1, sub( norm_s( shb_lpcCNG_fx[0] ), 2 ) ); /* Q12 */
     874             : 
     875             :     /* SHB energy estimation */
     876           0 :     wb_ener_fx = L_deposit_l( 1 ); /*Q1 */
     877           0 :     FOR( i = 0; i < L_FRAME32k; i++ )
     878             :     {
     879           0 :         wb_ener_fx = L_add( wb_ener_fx, Mpy_32_16_1( L_mult0( synth_fx[i], synth_fx[i] ), 51 ) ); /* 2*Qsyn */
     880             :     }
     881           0 :     exp = norm_l( wb_ener_fx );
     882           0 :     fra = Log2_norm_lc( L_shl( wb_ener_fx, exp ) );
     883           0 :     exp = sub( 30, add( exp, shl( Qsyn, 1 ) ) );
     884           0 :     wb_ener_fx = Mpy_32_16( exp, fra, LG10 );
     885           0 :     wb_ener16_fx = round_fx( L_shl( wb_ener_fx, 10 ) ); /*wb_ener_fx in Q8 */
     886           0 :     if ( !st_fx->first_CNG )
     887             :     {
     888           0 :         hTdCngDec->wb_cng_ener_fx = wb_ener16_fx;
     889           0 :         move16(); /*Q8 */
     890             :     }
     891           0 :     if ( GT_16( abs_s( sub( wb_ener16_fx, hTdCngDec->wb_cng_ener_fx ) ), 3072 ) )
     892             :     {
     893           0 :         allow_cn_step_fx = 1;
     894           0 :         move16();
     895             :     }
     896             : 
     897           0 :     IF( EQ_16( allow_cn_step_fx, 1 ) )
     898             :     {
     899           0 :         hTdCngDec->wb_cng_ener_fx = wb_ener16_fx;
     900           0 :         move16(); /*Q8 */
     901             :     }
     902             :     ELSE
     903             :     {
     904           0 :         tmp = sub( wb_ener16_fx, hTdCngDec->wb_cng_ener_fx );              /*Q8 */
     905           0 :         tmp = mult_r( tmp, 29491 );                                        /*Q8 */
     906           0 :         hTdCngDec->wb_cng_ener_fx = add( hTdCngDec->wb_cng_ener_fx, tmp ); /*Q8 */
     907           0 :         move16();
     908             :     }
     909           0 :     test();
     910           0 :     test();
     911           0 :     IF( EQ_32( st_fx->core_brate, SID_2k40 ) && EQ_16( sid_bw, 1 ) && ( st_fx->bfi == 0 ) )
     912             :     {
     913           0 :         hTdCngDec->last_wb_cng_ener_fx = hTdCngDec->wb_cng_ener_fx;
     914           0 :         move16();
     915             : 
     916           0 :         if ( !st_fx->first_CNG )
     917             :         {
     918           0 :             hTdCngDec->shb_cng_ener_fx = hTdCngDec->last_shb_cng_ener_fx;
     919           0 :             move16();
     920             :         }
     921             :     }
     922             : 
     923           0 :     gain_fx = sub( hTdCngDec->wb_cng_ener_fx, hTdCngDec->last_wb_cng_ener_fx ); /* Q8 */
     924           0 :     if ( GT_16( gain_fx, 15 ) )
     925             :     {
     926           0 :         gain_fx = 15;
     927           0 :         move16();
     928             :     }
     929           0 :     step_fx = sub( add( gain_fx, hTdCngDec->last_shb_cng_ener_fx ), hTdCngDec->shb_cng_ener_fx ); /*Q8 */
     930           0 :     test();
     931           0 :     IF( EQ_16( allow_cn_step_fx, 1 ) || GT_32( st_fx->last_core_brate, SID_2k40 ) )
     932             :     {
     933           0 :         hTdCngDec->shb_cng_ener_fx = add( hTdCngDec->shb_cng_ener_fx, step_fx ); /* Q8 */
     934           0 :         move16();
     935             :     }
     936             :     ELSE
     937             :     {
     938           0 :         hTdCngDec->shb_cng_ener_fx = add( hTdCngDec->shb_cng_ener_fx, mult( 8192, step_fx ) ); /*Q8 */
     939           0 :         move16();
     940             :     }
     941             :     /* generate white noise excitation */
     942           0 :     FOR( i = 0; i < L_FRAME16k; i++ )
     943             :     {
     944           0 :         excTmp_fx[i] = shr_r( Random( &hTdCngDec->swb_cng_seed ), 8 );
     945           0 :         move16(); /*Q-8*/
     946             :     }
     947             : 
     948             :     /* synthesis filtering */
     949           0 :     Syn_filt_s( 0, shb_lpcCNG_fx, LPC_SHB_ORDER, excTmp_fx, excSHB_fx, L_FRAME16k, hBWE_TD->state_lpc_syn_fx, 1 );
     950             : 
     951             : 
     952             :     /* synthesis signal gain shaping */
     953           0 :     L_tmp = 0;
     954           0 :     move32();
     955           0 :     FOR( i = 0; i < L_FRAME16k; i++ )
     956             :     {
     957           0 :         L_tmp = L_add( L_tmp, Mpy_32_16_1( L_mult0( excSHB_fx[i], excSHB_fx[i] ), 102 ) ); /*Q-16*/
     958             :     }
     959           0 :     q = norm_l( L_tmp );
     960           0 :     L_tmp = L_shl( L_tmp, q );
     961           0 :     q = sub( q, 32 );
     962           0 :     ener_excSHB_fx = round_fx( L_tmp ); /*Qq */
     963           0 :     IF( EQ_16( st_fx->last_vad_fx, 1 ) )
     964             :     {
     965           0 :         hTdCngDec->trans_cnt_fx = 0;
     966           0 :         move16();
     967           0 :         test();
     968           0 :         IF( GT_16( hTdCngDec->burst_cnt_fx, 3 ) && NE_16( st_fx->last_core, HQ_CORE ) )
     969             :         {
     970           0 :             hTdCngDec->trans_cnt_fx = 5;
     971           0 :             move16();
     972             :         }
     973             :     }
     974             : 
     975           0 :     ener_fx = hTdCngDec->shb_cng_ener_fx;
     976           0 :     move16(); /*Q8 */
     977           0 :     IF( hTdCngDec->trans_cnt_fx > 0 )
     978             :     {
     979           0 :         i = extract_l( L_mult0( hTdCngDec->trans_cnt_fx, 17 ) );                                                                                         /*Q0 */
     980           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 */
     981           0 :         hTdCngDec->trans_cnt_fx = sub( hTdCngDec->trans_cnt_fx, 1 );
     982           0 :         move16();
     983             :     }
     984             : 
     985           0 :     tmp = mult( 3277, ener_fx );  /*Q8 */
     986           0 :     L_tmp = L_mult( 27213, tmp ); /*Q22, 27213=3.321928 in Q13  */
     987           0 :     L_tmp = L_shr( L_tmp, 6 );    /*Q16 */
     988           0 :     L_tmp = L_add( L_tmp, 10 << 16 );
     989           0 :     if ( L_tmp < 0 )
     990             :     {
     991           0 :         L_tmp = 0;
     992           0 :         move32();
     993             :     }
     994           0 :     fra = L_Extract_lc( L_tmp, &exp );
     995           0 :     L_tmp = L_shl_sat( Pow2( exp, fra ), 5 ); /*Q5 */
     996           0 :     L_tmp = L_shr( L_tmp, 10 );
     997           0 :     if ( !L_tmp )
     998             :     {
     999           0 :         L_tmp = 1; /*Q5 */
    1000             :     }
    1001           0 :     exp = norm_l( L_tmp );
    1002           0 :     L_tmp = L_shl( L_tmp, exp ); /*Q31*/
    1003           0 :     tmp = extract_h( L_tmp );    /*Q15*/
    1004           0 :     exp = sub( exp, 16 );
    1005           0 :     exp1 = norm_s( ener_excSHB_fx );
    1006           0 :     fra = shl( ener_excSHB_fx, exp1 ); /*Q15*/
    1007             : 
    1008           0 :     IF( GT_16( fra, tmp ) )
    1009             :     {
    1010           0 :         fra = shr( fra, 1 ); /*Q15*/
    1011           0 :         exp1 = sub( exp1, 1 );
    1012             :     }
    1013           0 :     tmp = div_s( fra, tmp ); /*Q15*/
    1014             : 
    1015           0 :     L_tmp = L_deposit_h( tmp ); /*Q31 */
    1016           0 :     tmp = sub( add( 5, exp ), add( q, exp1 ) );
    1017           0 :     L_gain_fx = Isqrt_lc( L_tmp, &tmp ); /*Q31-Qtmp */
    1018             : 
    1019           0 :     FOR( i = 0; i < L_FRAME16k; i++ )
    1020             :     {
    1021           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 */
    1022           0 :         move16();
    1023             :     }
    1024             : 
    1025           0 :     test();
    1026           0 :     IF( EQ_16( st_fx->last_extl, SWB_TBE ) || EQ_16( st_fx->last_extl, FB_TBE ) )
    1027             :     {
    1028             :         /* rescale the Hilbert memories to Q0 */
    1029           0 :         FOR( i = 0; i < HILBERT_MEM_SIZE; i++ )
    1030             :         {
    1031           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 */
    1032           0 :             move32();
    1033             :         }
    1034             : 
    1035           0 :         FOR( i = 0; i < 2 * ALLPASSSECTIONS_STEEP; i++ )
    1036             :         {
    1037           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 */
    1038           0 :             move16();
    1039             :         }
    1040             :     }
    1041           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 ) );
    1042             : 
    1043           0 :     IF( EQ_32( st_fx->output_Fs, 48000 ) )
    1044             :     {
    1045           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 );
    1046             :     }
    1047             : 
    1048           0 :     ResetSHBbuffer_Dec_fx( st_fx->hBWE_TD, st_fx->extl );
    1049             : 
    1050           0 :     return;
    1051             : }
    1052             : 
    1053        1788 : static void shb_CNG_decod_ivas_fx(
    1054             :     Decoder_State *st,      /* i/o: State structure                                             */
    1055             :     const Word16 *synth_fx, /* i  : ACELP core synthesis at 32kHz   Qsyn*/
    1056             :     Word16 *shb_synth_fx,   /* o  : high-band CNG synthesis                       Qx*/
    1057             :     const Word16 sid_bw,    /* i  : 0-NB/WB, 1-SWB SID                Q0*/
    1058             :     const Word16 Qsyn )
    1059             : {
    1060             :     Word16 i;
    1061             :     Word16 idx_ener;
    1062             :     TD_CNG_DEC_HANDLE hTdCngDec;
    1063             :     Word16 shb_lpcCNG_fx[LPC_SHB_ORDER + 1];
    1064             :     Word16 shb_lspCNG_fx[LPC_SHB_ORDER];
    1065             :     Word16 excTmp_fx[L_FRAME16k];
    1066             :     Word16 excSHB_fx[L_FRAME16k];
    1067             :     Word16 tmp_lsp[LPC_SHB_ORDER];
    1068             :     Word16 ener_excSHB_fx;
    1069             :     Word32 wb_ener_fx;
    1070             :     Word16 wb_ener16_fx;
    1071             :     Word32 L_gain_fx;
    1072             :     Word32 gain_fx;
    1073             :     Word16 shb_syn16k_fx[L_FRAME16k];
    1074             :     Word32 tmp;
    1075             :     Word32 step_fx;
    1076             :     Word16 interp_fx;
    1077             :     Word32 ener_fx;
    1078             :     Word16 exp, exp1;
    1079             :     Word16 fra;
    1080             :     Word32 L_tmp;
    1081             :     Word16 allow_cn_step_fx;
    1082             :     Word16 q;
    1083             :     TD_BWE_DEC_HANDLE hBWE_TD;
    1084             : 
    1085        1788 :     hBWE_TD = st->hBWE_TD;
    1086        1788 :     hTdCngDec = st->hTdCngDec;
    1087        1788 :     allow_cn_step_fx = 0;
    1088        1788 :     move16();
    1089             : 
    1090        1788 :     IF( st->bfi == 0 )
    1091             :     {
    1092        1788 :         test();
    1093        1788 :         IF( EQ_32( st->core_brate, SID_2k40 ) && EQ_16( sid_bw, 1 ) )
    1094             :         {
    1095         324 :             idx_ener = get_next_indice_fx( st, 4 );
    1096             : 
    1097         324 :             IF( idx_ener == 0 )
    1098             :             {
    1099           5 :                 idx_ener = -15;
    1100           5 :                 move16();
    1101             :             }
    1102             : 
    1103             :             /* de-quantization of SHB CNG parameters */
    1104         324 :             IF( st->element_mode == EVS_MONO )
    1105             :             {
    1106           0 :                 hTdCngDec->last_shb_cng_ener_fx_32 = L_sub( L_mult0( idx_ener, 6850 ), 36991 ); // Q11
    1107           0 :                 move32();
    1108             :             }
    1109             :             ELSE
    1110             :             {
    1111         324 :                 hTdCngDec->last_shb_cng_ener_fx_32 = L_sub( L_mult0( idx_ener, 8807 ), 36991 ); // Q11
    1112         324 :                 move32();
    1113             :             }
    1114             :         }
    1115             :     }
    1116             : 
    1117             :     /* SHB spectrum estimation */
    1118        1788 :     interp_fx = s_min( hTdCngDec->shb_dtx_count_fx, 32 );
    1119        1788 :     interp_fx = shl_sat( interp_fx, 10 ); /*Q15*/
    1120             : 
    1121       19668 :     FOR( i = 0; i < LPC_SHB_ORDER; i++ )
    1122             :     {
    1123       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
    1124       17880 :         move16();
    1125             :     }
    1126             : 
    1127        1788 :     IF( LE_16( hTdCngDec->shb_dtx_count_fx, 1000 ) )
    1128             :     {
    1129        1788 :         hTdCngDec->shb_dtx_count_fx = add( hTdCngDec->shb_dtx_count_fx, 1 );
    1130        1788 :         move16();
    1131             :     }
    1132             : 
    1133        1788 :     E_LPC_lsf_lsp_conversion( shb_lspCNG_fx, tmp_lsp, LPC_SHB_ORDER ); /*Q14*/
    1134        1788 :     E_LPC_f_lsp_a_conversion( tmp_lsp, shb_lpcCNG_fx, LPC_SHB_ORDER );
    1135             : 
    1136        1788 :     Copy_Scale_sig( shb_lpcCNG_fx, hTdCngDec->shb_lpcCNG_fx, LPC_SHB_ORDER + 1, sub( norm_s( shb_lpcCNG_fx[0] ), -1 ) ); /* Q15 */
    1137             : 
    1138        1788 :     Copy_Scale_sig( shb_lpcCNG_fx, shb_lpcCNG_fx, LPC_SHB_ORDER + 1, sub( norm_s( shb_lpcCNG_fx[0] ), 2 ) ); /* Q12 */
    1139             : 
    1140             :     /* SHB energy estimation */
    1141        1788 :     wb_ener_fx = L_deposit_l( 1 ); /*Q1 */
    1142        1788 :     IF( NE_16( st->element_mode, IVAS_CPE_DFT ) )
    1143             :     {
    1144           0 :         FOR( i = 0; i < L_FRAME32k; i++ )
    1145             :         {
    1146           0 :             wb_ener_fx = L_add( wb_ener_fx, Mpy_32_16_1( L_mult0( synth_fx[i], synth_fx[i] ), 51 ) ); /* 2*Qsyn */
    1147             :         }
    1148             :     }
    1149        1788 :     exp = norm_l( wb_ener_fx );
    1150        1788 :     fra = Log2_norm_lc( L_shl( wb_ener_fx, exp ) );
    1151        1788 :     exp = sub( 30, add( exp, shl( Qsyn, 1 ) ) );
    1152        1788 :     wb_ener_fx = Mpy_32_16( exp, fra, LG10 );
    1153        1788 :     wb_ener16_fx = round_fx( L_shl( wb_ener_fx, 10 ) ); /*wb_ener_fx in Q8 */
    1154        1788 :     Word32 wb_ener32_fx = L_shl( wb_ener16_fx, 3 );     /*wb_ener_fx in Q11 */
    1155        1788 :     if ( EQ_16( st->first_CNG, 0 ) )
    1156             :     {
    1157          19 :         hTdCngDec->wb_cng_ener_fx_32 = wb_ener32_fx;
    1158          19 :         move32(); /*Q11 */
    1159             :     }
    1160        1788 :     if ( GT_32( L_abs( L_sub( wb_ener32_fx, hTdCngDec->wb_cng_ener_fx_32 ) ), 24576 ) ) /* 12.0f in Q11 */
    1161             :     {
    1162           0 :         allow_cn_step_fx = 1;
    1163           0 :         move16();
    1164             :     }
    1165             : 
    1166        1788 :     IF( EQ_16( allow_cn_step_fx, 1 ) )
    1167             :     {
    1168           0 :         hTdCngDec->wb_cng_ener_fx_32 = wb_ener32_fx;
    1169           0 :         move32(); /*Q11 */
    1170             :     }
    1171             :     ELSE
    1172             :     {
    1173        1788 :         tmp = L_sub( wb_ener32_fx, hTdCngDec->wb_cng_ener_fx_32 );                 /*Q11 */
    1174        1788 :         tmp = Mpy_32_16_1( tmp, 29491 );                                           /*Q11 */
    1175        1788 :         hTdCngDec->wb_cng_ener_fx_32 = L_add( hTdCngDec->wb_cng_ener_fx_32, tmp ); /*Q11 */
    1176        1788 :         move32();
    1177             :     }
    1178        1788 :     test();
    1179        1788 :     test();
    1180        1788 :     IF( EQ_32( st->core_brate, SID_2k40 ) && EQ_16( sid_bw, 1 ) && EQ_16( st->bfi, 0 ) )
    1181             :     {
    1182         324 :         hTdCngDec->last_wb_cng_ener_fx_32 = hTdCngDec->wb_cng_ener_fx_32; /* Q11 */
    1183         324 :         move32();
    1184             : 
    1185         324 :         if ( !st->first_CNG )
    1186             :         {
    1187          19 :             hTdCngDec->shb_cng_ener_fx_32 = hTdCngDec->last_shb_cng_ener_fx_32; /* Q11 */
    1188          19 :             move32();
    1189             :         }
    1190             :     }
    1191             : 
    1192        1788 :     gain_fx = L_sub( hTdCngDec->wb_cng_ener_fx_32, hTdCngDec->last_wb_cng_ener_fx_32 ); /*Q11 */
    1193        1788 :     if ( GT_32( gain_fx, 30720 ) )
    1194             :     {
    1195           0 :         gain_fx = 30720;
    1196           0 :         move32();
    1197             :     }
    1198        1788 :     step_fx = L_sub( L_add( gain_fx, hTdCngDec->last_shb_cng_ener_fx_32 ), hTdCngDec->shb_cng_ener_fx_32 ); /*Q11 */
    1199        1788 :     test();
    1200        1788 :     IF( EQ_16( allow_cn_step_fx, 1 ) || GT_32( st->last_core_brate, SID_2k40 ) )
    1201             :     {
    1202         151 :         hTdCngDec->shb_cng_ener_fx_32 = L_add( hTdCngDec->shb_cng_ener_fx_32, step_fx ); /* Q11 */
    1203         151 :         move32();
    1204             :     }
    1205             :     ELSE
    1206             :     {
    1207        1637 :         hTdCngDec->shb_cng_ener_fx_32 = L_add( hTdCngDec->shb_cng_ener_fx_32, L_shr( step_fx, 2 ) ); /*Q11 */
    1208        1637 :         move32();
    1209             :     }
    1210             :     /* generate white noise excitation */
    1211      573948 :     FOR( i = 0; i < L_FRAME16k; i++ )
    1212             :     {
    1213      572160 :         excTmp_fx[i] = shr_r( Random( &hTdCngDec->swb_cng_seed ), 8 );
    1214      572160 :         move16(); /*Q-8*/
    1215             :     }
    1216             : 
    1217             :     /* synthesis filtering */
    1218        1788 :     Syn_filt_s( 0, shb_lpcCNG_fx, LPC_SHB_ORDER, excTmp_fx, excSHB_fx, L_FRAME16k, hBWE_TD->state_lpc_syn_fx, 1 );
    1219             : 
    1220             : 
    1221             :     /* synthesis signal gain shaping */
    1222        1788 :     L_tmp = 0;
    1223        1788 :     move32();
    1224      573948 :     FOR( i = 0; i < L_FRAME16k; i++ )
    1225             :     {
    1226      572160 :         L_tmp = L_add( L_tmp, Mpy_32_16_1( L_mult0( excSHB_fx[i], excSHB_fx[i] ), 102 ) ); /*Q-16*/
    1227             :     }
    1228        1788 :     q = norm_l( L_tmp );
    1229        1788 :     L_tmp = L_shl( L_tmp, q );
    1230        1788 :     q = sub( q, 32 );
    1231        1788 :     ener_excSHB_fx = round_fx( L_tmp ); /*Qq */
    1232             : 
    1233        1788 :     IF( EQ_16( st->last_vad_fx, 1 ) )
    1234             :     {
    1235         151 :         hTdCngDec->trans_cnt_fx = 0;
    1236         151 :         move16();
    1237         151 :         test();
    1238         151 :         if ( GT_16( hTdCngDec->burst_cnt_fx, 3 ) && NE_16( st->last_core, HQ_CORE ) )
    1239             :         {
    1240          40 :             hTdCngDec->trans_cnt_fx = 5;
    1241          40 :             move16();
    1242             :         }
    1243             :     }
    1244             : 
    1245        1788 :     ener_fx = hTdCngDec->shb_cng_ener_fx_32;
    1246        1788 :     move32(); /*Q11 */
    1247        1788 :     IF( GT_16( st->hTdCngDec->trans_cnt_fx, 0 ) )
    1248             :     {
    1249          85 :         i = extract_l( L_mult0( hTdCngDec->trans_cnt_fx, 17 ) );                                                                                                     /*Q0 */
    1250          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 */
    1251          85 :         hTdCngDec->trans_cnt_fx = sub( hTdCngDec->trans_cnt_fx, 1 );
    1252          85 :         move16();
    1253             :     }
    1254             : 
    1255        1788 :     tmp = L_shr( Mpy_32_16_1( ener_fx, 3277 ), 3 ); /*Q8 */
    1256        1788 :     IF( GT_32( tmp, 32767 ) )
    1257           0 :     abort();
    1258             :     Word16 tmp_16;
    1259        1788 :     tmp_16 = (Word16) tmp;
    1260        1788 :     move16();
    1261        1788 :     L_tmp = L_mult( 27213, tmp_16 ); /*Q22, 27213=3.321928 in Q13  */
    1262        1788 :     L_tmp = L_shr( L_tmp, 6 );       /*Q16 */
    1263        1788 :     L_tmp = L_add( L_tmp, L_shl( 10, 16 ) );
    1264        1788 :     if ( ( L_tmp < 0 ) )
    1265             :     {
    1266          36 :         L_tmp = 0;
    1267          36 :         move32();
    1268             :     }
    1269        1788 :     fra = L_Extract_lc( L_tmp, &exp );
    1270        1788 :     L_tmp = L_shr( Pow2( exp, fra ), 5 ); /*Q5 */
    1271        1788 :     if ( !L_tmp )
    1272             :     {
    1273          40 :         L_tmp = 1;
    1274          40 :         move32(); /*Q5 */
    1275             :     }
    1276        1788 :     exp = norm_l( L_tmp );
    1277        1788 :     L_tmp = L_shl( L_tmp, exp ); /*Q31*/
    1278        1788 :     tmp_16 = extract_h( L_tmp ); /*Q15*/
    1279        1788 :     exp = sub( exp, 16 );
    1280        1788 :     exp1 = norm_s( ener_excSHB_fx );
    1281        1788 :     fra = shl( ener_excSHB_fx, exp1 ); /*Q15*/
    1282             : 
    1283        1788 :     IF( GT_16( fra, tmp_16 ) )
    1284             :     {
    1285         758 :         fra = shr( fra, 1 ); /*Q15*/
    1286         758 :         exp1 = sub( exp1, 1 );
    1287             :     }
    1288        1788 :     tmp_16 = div_s( fra, tmp_16 ); /*Q15*/
    1289             : 
    1290        1788 :     L_tmp = L_deposit_h( tmp_16 ); /*Q31 */
    1291        1788 :     tmp_16 = sub( add( 5, exp ), add( q, exp1 ) );
    1292        1788 :     L_gain_fx = Isqrt_lc( L_tmp, &tmp_16 ); /*Q31-Qtmp */
    1293        1788 :     hTdCngDec->shb_cng_gain_fx_32 = ener_fx;
    1294        1788 :     move32();
    1295      573948 :     FOR( i = 0; i < L_FRAME16k; i++ )
    1296             :     {
    1297      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 */
    1298      572160 :         move16();
    1299             :     }
    1300             : 
    1301        1788 :     test();
    1302        1788 :     IF( EQ_16( st->last_extl, SWB_TBE ) || EQ_16( st->last_extl, FB_TBE ) )
    1303             :     {
    1304             :         /* rescale the Hilbert memories to Q0 */
    1305         528 :         FOR( i = 0; i < HILBERT_MEM_SIZE; i++ )
    1306             :         {
    1307         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 */
    1308         504 :             move32();
    1309             :         }
    1310             : 
    1311         168 :         FOR( i = 0; i < 2 * ALLPASSSECTIONS_STEEP; i++ )
    1312             :         {
    1313         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 */
    1314         144 :             move16();
    1315             :         }
    1316             :     }
    1317        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 ) );
    1318             : 
    1319        1788 :     IF( EQ_32( st->output_Fs, 48000 ) )
    1320             :     {
    1321         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 );
    1322             :     }
    1323             : 
    1324        1788 :     Scale_sig( shb_synth_fx, L_FRAME48k, -3 ); /* Qx - 3 */
    1325             : 
    1326        1788 :     ResetSHBbuffer_Dec_fx( st->hBWE_TD, st->extl );
    1327             : 
    1328        1788 :     return;
    1329             : }
    1330             : 
    1331             : /*-------------------------------------------------------------------*
    1332             :  * td_cng_dec_init_fx()
    1333             :  *
    1334             :  *
    1335             :  *-------------------------------------------------------------------*/
    1336             : 
    1337        1340 : void td_cng_dec_init_fx(
    1338             :     DEC_CORE_HANDLE st /* i/o: decoder state structure     */
    1339             : )
    1340             : {
    1341             :     Word16 i;
    1342             :     TD_CNG_DEC_HANDLE hTdCngDec;
    1343             : 
    1344        1340 :     hTdCngDec = st->hTdCngDec;
    1345             : 
    1346        1340 :     hTdCngDec->cng_seed = RANDOM_INITSEED;
    1347        1340 :     move16();
    1348        1340 :     hTdCngDec->cng_ener_seed = RANDOM_INITSEED;
    1349        1340 :     move16();
    1350        1340 :     hTdCngDec->cng_ener_seed1 = RANDOM_INITSEED;
    1351        1340 :     move16();
    1352        1340 :     hTdCngDec->old_enr_index = -1;
    1353        1340 :     move16();
    1354        1340 :     hTdCngDec->Enew_fx = 0;
    1355        1340 :     move32();
    1356        1340 :     Copy( st->lsp_old_fx, st->lspCNG_fx, M ); // Q(15)
    1357        1340 :     hTdCngDec->last_allow_cn_step = 0;
    1358        1340 :     move16();
    1359        1340 :     hTdCngDec->shb_cng_ener_fx = -1541; // Q8
    1360        1340 :     move16();
    1361        1340 :     hTdCngDec->shb_cng_ener_fx_32 = -12329; // -6.02 in Q(11)
    1362        1340 :     move32();
    1363        1340 :     IF( st->element_mode != EVS_MONO )
    1364             :     {
    1365        1337 :         set16_fx( hTdCngDec->shb_lpcCNG_fx, 0, LPC_SHB_ORDER + 1 );
    1366        1337 :         hTdCngDec->shb_lpcCNG_fx[0] = 32767; // 1 in Q(15)
    1367        1337 :         move16();
    1368        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)   */
    1369        1337 :         move32();
    1370             :     }
    1371             : 
    1372        1340 :     hTdCngDec->wb_cng_ener_fx = -1541; // Q8
    1373        1340 :     move16();
    1374        1340 :     hTdCngDec->wb_cng_ener_fx_32 = -12329; // Q(11)
    1375        1340 :     move32();
    1376        1340 :     hTdCngDec->last_wb_cng_ener_fx = -1541; // Q8
    1377        1340 :     move16();
    1378        1340 :     hTdCngDec->last_wb_cng_ener_fx_32 = -12329; // Q(11)
    1379        1340 :     move32();
    1380        1340 :     hTdCngDec->last_shb_cng_ener_fx = -1541; // Q8
    1381        1340 :     move16();
    1382        1340 :     hTdCngDec->last_shb_cng_ener_fx_32 = -12329; // Q(11)
    1383        1340 :     move32();
    1384        1340 :     hTdCngDec->swb_cng_seed = RANDOM_INITSEED;
    1385        1340 :     move16();
    1386        1340 :     hTdCngDec->ho_hist_ptr = -1;
    1387        1340 :     move16();
    1388        1340 :     hTdCngDec->ho_sid_bw = 0;
    1389        1340 :     move16();
    1390        1340 :     set16_fx( hTdCngDec->ho_lsp_hist_fx, 0, HO_HIST_SIZE * M );
    1391        1340 :     set32_fx( hTdCngDec->ho_ener_hist_fx, 0, HO_HIST_SIZE );
    1392        1340 :     set32_fx( hTdCngDec->ho_env_hist_fx, 0, HO_HIST_SIZE * NUM_ENV_CNG );
    1393        1340 :     hTdCngDec->ho_hist_size = 0;
    1394        1340 :     move16();
    1395        1340 :     hTdCngDec->act_cnt = 0;
    1396        1340 :     move16();
    1397        1340 :     hTdCngDec->ho_circ_ptr = -1;
    1398        1340 :     move16();
    1399        1340 :     set16_fx( hTdCngDec->ho_lsp_circ_fx, 0, HO_HIST_SIZE * M );
    1400        1340 :     set32_fx( hTdCngDec->ho_ener_circ_fx, 0, HO_HIST_SIZE );
    1401        1340 :     set32_fx( hTdCngDec->ho_env_circ_fx, 0, HO_HIST_SIZE * NUM_ENV_CNG );
    1402        1340 :     hTdCngDec->ho_circ_size = 0;
    1403        1340 :     move16();
    1404             : 
    1405        1340 :     set16_fx( hTdCngDec->ho_16k_lsp, 0, HO_HIST_SIZE );
    1406        1340 :     st->CNG_mode = -1;
    1407        1340 :     move16();
    1408        1340 :     hTdCngDec->act_cnt2 = 0;
    1409        1340 :     move16();
    1410        1340 :     hTdCngDec->num_ho = 0;
    1411        1340 :     move16();
    1412        1340 :     set32_fx( hTdCngDec->lp_env_fx, 0, NUM_ENV_CNG );
    1413        1340 :     set16_fx( hTdCngDec->exc_mem_fx, 0, 24 );
    1414        1340 :     set16_fx( hTdCngDec->exc_mem1_fx, 0, 30 );
    1415        1340 :     set32_fx( hTdCngDec->old_env_fx, 0, NUM_ENV_CNG );
    1416             : 
    1417       14740 :     FOR( i = 0; i < LPC_SHB_ORDER; i++ )
    1418             :     {
    1419       13400 :         IF( st->element_mode != EVS_MONO )
    1420             :         {
    1421       13370 :             hTdCngDec->lsp_shb_prev_fx[i] = ivas_lsp_shb_prev_tbl_fx[i]; /* Q14 */
    1422       13370 :             move16();
    1423             :         }
    1424             :         ELSE
    1425             :         {
    1426          30 :             hTdCngDec->lsp_shb_prev_fx[i] = lsp_shb_prev_tbl_fx[i]; /* Q14 */
    1427          30 :             move16();
    1428             :         }
    1429       13400 :         hTdCngDec->lsp_shb_prev_prev_fx[i] = hTdCngDec->lsp_shb_prev_fx[i]; /* Q14 */
    1430       13400 :         move16();
    1431             :     }
    1432             : 
    1433        1340 :     hTdCngDec->shb_dtx_count_fx = 0;
    1434        1340 :     move16();
    1435        1340 :     hTdCngDec->trans_cnt_fx = 0;
    1436        1340 :     move16();
    1437        1340 :     hTdCngDec->burst_cnt_fx = 0;
    1438        1340 :     move16();
    1439             : 
    1440        1340 :     hTdCngDec->last_shb_ener_fx = 0; // Q8
    1441        1340 :     move16();
    1442        1340 :     hTdCngDec->last_shb_ener_fx_32 = 2; // 0.001 in Q11
    1443        1340 :     move32();
    1444             : 
    1445        1340 :     set16_fx( hTdCngDec->interpol_3_2_cng_dec_fx, 0, INTERP_3_2_MEM_LEN );
    1446             : 
    1447        1340 :     return;
    1448             : }

Generated by: LCOV version 1.14