LCOV - code coverage report
Current view: top level - lib_com - cng_exc_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main enc/dec/rend @ 3b2f07138c61dcf997bbf4165d0882f794b2995f Lines: 493 585 84.3 %
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             : #include <stdint.h>
       5             : #include "options.h" /* Compilation switches                   */
       6             : #include "cnst.h"    /* Common constants                       */
       7             : #include "prot_fx.h" /* Function prototypes                    */
       8             : #include "rom_com.h"
       9             : #include "ivas_rom_com_fx.h"
      10             : 
      11             : /*---------------------------------------------------------------------*
      12             :  * Local constants
      13             :  *---------------------------------------------------------------------*/
      14             : #define A2       6554
      15             : #define OmA2     ( 32768 - A2 )
      16             : #define GAIN_VAR 11811 /* in Q31 divided by 2 (Q30) */
      17             : const Word16 att_pow_tbl[SIZE_SCALE_TABLE_STEREO + 1] = { 9234, 10361, 13044, 16422, 22669, 31292, 32767, 26634, 28212, 20674, 16422, 27254, 30934, 32767 };
      18             : /*-------------------------------------------------------*
      19             :  * CNG_exc()
      20             :  *
      21             :  * Comfort noise generation routine
      22             :  *-------------------------------------------------------*/
      23             : 
      24        4819 : void CNG_exc_fx(
      25             :     const Word32 core_brate,      /* i  : core bitrate                            */
      26             :     const Word16 L_frame,         /* i  : length of the frame                      */
      27             :     Word32 *Enew,                 /* i/o: decoded SID energy                   Q6  */
      28             :     Word16 *seed,                 /* i/o: random generator seed                    */
      29             :     Word16 exc[],                 /* o  : current non-enhanced excitation   Q_new  */
      30             :     Word16 exc2[],                /* o  : current enhanced excitation       Q_new  */
      31             :     Word32 *lp_ener,              /* i/o: LP filtered E                     Q6       */
      32             :     const Word32 last_core_brate, /* i  : previous frame core bitrate              */
      33             :     Word16 *first_CNG,            /* i/o: first CNG frame flag for energy init.    */
      34             :     Word16 *cng_ener_seed,        /* i/o: random generator seed for CNG energy     */
      35             :     Word16 bwe_exc[],             /* o  : excitation for SWB TBE             Q_syn      */
      36             :     const Word16 allow_cn_step,   /* i  : allow CN step                            */
      37             :     Word16 *last_allow_cn_step,   /* i/o: last allow step                      */
      38             :     const Word16 OldQ_exc,        /* i  : Old excitation scaling                  */
      39             :     const Word16 Q_exc,           /* i  : excitation scaling                      */
      40             :     const Word16 num_ho,          /* i  : number of selected hangover frames    */
      41             :     Word32 q_env[],               /*Q6*/
      42             :     Word32 *lp_env,               /*Q6*/
      43             :     Word32 *old_env,              /*Q6*/
      44             :     Word16 *exc_mem,              /*Q0*/
      45             :     Word16 *exc_mem1,             /*Q0*/
      46             :     Word16 *sid_bw,
      47             :     Word16 *cng_ener_seed1,
      48             :     Word16 exc3[], /*Q_exc*/
      49             :     Word16 Opt_AMR_WB,
      50             :     const Word16 element_mode /* i  : IVAS Element mode                     */
      51             : )
      52             : {
      53             :     Word16 i, tmp, tmp2, exp, exp2, Q_ener;
      54             :     Word32 L_tmp_ener, L_tmp;
      55             :     Word16 i_subfr;
      56             :     Word16 pit_max;
      57             :     Word16 ftmp, j;
      58             :     Word16 *ptR, *ptI;
      59             :     Word16 fft_io[L_FRAME16k];
      60             :     Word32 itmp[129];
      61             :     Word32 env[NUM_ENV_CNG];
      62             :     Word32 enr1;
      63             :     Word32 denv[NUM_ENV_CNG];
      64             :     Word16 fra;
      65             :     Word16 temp_lo_fx, temp_hi_fx;
      66             :     Word16 exp_pow;
      67             :     Word32 L_tmp2;
      68             :     Word16 *pt_fft_io;
      69             : 
      70             :     /*------------------------------------------------------------------*
      71             :      * Initializations
      72             :      *------------------------------------------------------------------*/
      73             : 
      74        4819 :     pit_max = PIT16k_MAX;
      75        4819 :     move16();
      76        4819 :     if ( EQ_16( L_frame, L_FRAME ) )
      77             :     {
      78        1745 :         pit_max = PIT_MAX;
      79        1745 :         move16();
      80             :     }
      81             : 
      82             :     /*---------------------------------------------------------------------*
      83             :      * Initialization of CNG energy for the first CNG frame
      84             :      *---------------------------------------------------------------------*/
      85             : 
      86        4819 :     IF( *first_CNG == 0 )
      87             :     {
      88          57 :         IF( core_brate == FRAME_NO_DATA )
      89             :         {
      90             :             /* needed only in decoder when the very first SID frame was erased and this frame is FRAME_NO_DATA frame */
      91             :             /*fenew = dotp( fexc, fexc, pit_max )/pit_max;*/
      92           0 :             L_tmp_ener = Calc_Energy_Autoscaled( exc - pit_max, OldQ_exc, pit_max, &Q_ener );
      93           0 :             L_tmp_ener = Mult_32_16( L_tmp_ener, 9079 ); /* divide by PIT_MAX (in Q15 + Q6 to get output in Q6)*/
      94           0 :             L_tmp_ener = L_shr( L_tmp_ener, Q_ener );    /* -> If we want ener in Q6 */
      95             : 
      96           0 :             IF( EQ_16( L_frame, L_FRAME16k ) )
      97             :             {
      98           0 :                 L_tmp_ener = Mult_32_16( L_tmp_ener, 26214 /*.8f in Q15*/ ); /* Compensate for 16kHz */
      99             :             }
     100           0 :             *Enew = L_tmp_ener;
     101           0 :             move32();
     102             :         }
     103             : 
     104          57 :         if ( element_mode == EVS_MONO )
     105             :         {
     106          29 :             *lp_ener = *Enew;
     107          29 :             move32();
     108             :         }
     109             :     }
     110             : 
     111             :     /*---------------------------------------------------------------------*
     112             :      * Update CNG energy
     113             :      *---------------------------------------------------------------------*/
     114        4819 :     test();
     115        4819 :     test();
     116        4819 :     IF( NE_32( last_core_brate, SID_1k75 ) && ( last_core_brate != FRAME_NO_DATA ) && NE_32( last_core_brate, SID_2k40 ) )
     117             :     {
     118             :         /* Partially reset CNG energy after active speech period */
     119         405 :         test();
     120         405 :         IF( allow_cn_step == 0 && *last_allow_cn_step == 0 )
     121             :         {
     122         390 :             test();
     123         390 :             IF( LT_16( num_ho, 3 ) || LT_32( Mult_32_16( *Enew, 21845 /*1/1.5f, Q15*/ ), *lp_ener ) )
     124             :             {
     125             :                 /**lp_ener = 0.8f * *lp_ener + 0.2f * *Enew;*/
     126         358 :                 L_tmp_ener = Mult_32_16( *lp_ener, 26214 /*.8f in Q15*/ );
     127         358 :                 L_tmp_ener = Madd_32_16( L_tmp_ener, *Enew, 6554 /*.2f in Q15*/ );
     128             :             }
     129             :             ELSE
     130             :             {
     131             :                 /**lp_ener = 0.95f * *lp_ener + 0.05f * *Enew;*/
     132          32 :                 L_tmp_ener = Mult_32_16( *lp_ener, 31130 /*.95f in Q15*/ );
     133          32 :                 L_tmp_ener = Madd_32_16( L_tmp_ener, *Enew, 1638 /* .05f in Q15*/ );
     134             :             }
     135             :         }
     136             :         ELSE
     137             :         {
     138          15 :             L_tmp_ener = *Enew;
     139          15 :             move32();
     140          15 :             *last_allow_cn_step = 0;
     141          15 :             move16();
     142             :         }
     143             :     }
     144             :     ELSE{
     145             :         /* normal CNG update */
     146        4414 :         IF( *last_allow_cn_step == 0 ){
     147             :             /**lp_ener = (float)(A2 * *Enew + (1-A2) * *lp_ener);*/
     148        4344 :             L_tmp_ener = Mult_32_16( *Enew, A2 );
     149        4344 :     L_tmp_ener = Madd_32_16( L_tmp_ener, *lp_ener, OmA2 );
     150             : }
     151             : ELSE
     152             : {
     153          70 :     test();
     154          70 :     if ( EQ_32( core_brate, SID_1k75 ) || EQ_32( core_brate, SID_2k40 ) )
     155             :     {
     156           0 :         *last_allow_cn_step = 0;
     157           0 :         move16();
     158             :     }
     159             : 
     160          70 :     L_tmp_ener = *Enew;
     161          70 :     move32();
     162             : }
     163             : }
     164        4819 : *lp_ener = L_max( L_tmp_ener, 1 );
     165        4819 : move32(); /*To avoid / per 0*/
     166             : 
     167        4819 : if ( EQ_16( allow_cn_step, 1 ) )
     168             : {
     169          15 :     *last_allow_cn_step = 1;
     170          15 :     move16();
     171             : }
     172             : /* If not mono, skip CNG here */
     173        4819 : IF( GT_16( element_mode, IVAS_SCE ) )
     174             : {
     175        1237 :     return;
     176             : }
     177             : /*---------------------------------------------------------------------*
     178             :  * Generate white noise vector
     179             :  *---------------------------------------------------------------------*/
     180             : 
     181             : /*for ( i=0; i<L_frame; i++ )exc2[i] = (float)own_random( seed );*/
     182        3582 : Random_Fill( seed, L_frame, exc2, 4 );
     183             : /*------------------------------------------------------------*
     184             :  * Insert random variation for excitation energy
     185             :  *  (random variation is scaled according to *lp_ener value)
     186             :  *------------------------------------------------------------*/
     187             : 
     188       20102 : FOR( i_subfr = 0; i_subfr < L_frame; i_subfr += L_SUBFR )
     189             : {
     190             :     /* ener_lp = own_random(cng_ener_seed) * *lp_ener * GAIN_VAR + *lp_ener */
     191             :     /*------------------------------------------------------------*
     192             :      * Insert random variation for excitation energy
     193             :      *  (random variation is scaled according to *lp_ener value)
     194             :      *------------------------------------------------------------*/
     195       16520 :     L_tmp = Mult_32_16( *lp_ener, Random( cng_ener_seed ) ); // Q6
     196       16520 :     L_tmp = Mult_32_16( L_tmp, GAIN_VAR );                   // Q6
     197       16520 :     L_tmp = L_add_sat( L_tmp, *lp_ener );
     198       16520 :     L_tmp = L_max( L_tmp, 1 );
     199             : 
     200             :     /* enr = dot_product( exc2, exc2, L_SUBFR ) + 0.01f */
     201       16520 :     tmp = extract_h( Dot_product12( &exc2[i_subfr], &exc2[i_subfr], L_SUBFR, &exp ) );
     202       16520 :     exp = add( exp, 8 - 6 ); /* 8 from Q-4, -6 from L_SUBFR */
     203             : 
     204             :     /* enr = (float)sqrt(*lp_ener * L_SUBFR / enr) */
     205       16520 :     exp2 = norm_l( L_tmp );
     206       16520 :     tmp2 = extract_h( L_shl( L_tmp, exp2 ) );
     207       16520 :     exp2 = sub( 31 - 6, exp2 ); /* in Q15 (L_tmp in Q6)*/
     208             : 
     209       16520 :     exp = sub( exp, exp2 );
     210             : 
     211       16520 :     IF( GT_16( tmp, tmp2 ) )
     212             :     {
     213        7036 :         exp = add( exp, 1 );
     214             :     }
     215       16520 :     IF( GT_16( tmp, tmp2 ) )
     216             :     {
     217        7036 :         tmp = shr( tmp, 1 );
     218             :     }
     219       16520 :     tmp = div_s( tmp, tmp2 );
     220             : 
     221       16520 :     L_tmp = L_deposit_h( tmp );
     222             : 
     223       16520 :     L_tmp = Isqrt_lc( L_tmp, &exp );
     224       16520 :     tmp = extract_h( L_tmp );
     225             : 
     226       16520 :     exp = add( exp, 4 );     /* From Q15 to Q19 */
     227       16520 :     exp = add( exp, Q_exc ); /* Q_exc+ Q19      */
     228             : 
     229     1073800 :     FOR( i = 0; i < L_SUBFR; i++ )
     230             :     {
     231             :         /* exc2[i] *= enr */
     232     1057280 :         L_tmp = L_mult( exc2[i_subfr + i], tmp ); /* Q-4 * Q_exc+19 -> Q_exc +16 */
     233     1057280 :         exc2[i_subfr + i] = round_fx_sat( L_shl_sat( L_tmp, exp ) );
     234     1057280 :         move16();
     235             :     }
     236             : }
     237        3582 : IF( NE_16( Opt_AMR_WB, 1 ) )
     238             : {
     239        3582 :     Copy( exc2, exc3, L_FRAME16k );
     240             : 
     241             :     /* enr1 = (float)log10( *Enew*L_frame + 0.1f ) / (float)log10( 2.0f ); */
     242        3582 :     exp = norm_l( *Enew );
     243        3582 :     L_tmp = L_shl( *Enew, exp );                    /* Q(exp+6) */
     244        3582 :     L_tmp = Mult_32_16( L_tmp, shl( L_frame, 5 ) ); /* Q(exp+6+5-15=exp-4) */
     245        3582 :     L_tmp = L_shr_sat( L_tmp, sub( exp, 10 ) );     /* Q6 */
     246        3582 :     exp = norm_l( L_tmp );
     247        3582 :     fra = Log2_norm_lc( L_shl( L_tmp, exp ) );
     248        3582 :     exp = sub( sub( 30, exp ), 6 );
     249        3582 :     L_tmp = L_Comp( exp, fra );
     250             :     /* enr1 = round_fx(L_shl(L_tmp,8)); */ /*Q8 */
     251        3582 :     enr1 = L_shr( L_tmp, 10 );             /* Q6 */
     252             : 
     253             : 
     254        3582 :     IF( EQ_32( core_brate, SID_2k40 ) )
     255             :     {
     256         650 :         IF( *sid_bw == 0 )
     257             :         {
     258           0 :             FOR( i = 0; i < NUM_ENV_CNG; i++ )
     259             :             {
     260             :                 /* get quantized envelope */
     261             :                 /* env[i] = pow(2.0f,(enr1 - q_env[i])); */
     262           0 :                 L_tmp = L_sub( enr1, q_env[i] ); /* Q6 */
     263           0 :                 L_tmp = L_shl( L_tmp, 10 );      /* 16 */
     264           0 :                 temp_lo_fx = L_Extract_lc( L_tmp, &temp_hi_fx );
     265             : 
     266           0 :                 exp_pow = sub( 14, temp_hi_fx );
     267           0 :                 L_tmp = Pow2( 14, temp_lo_fx ); /* Qexp_pow */
     268           0 :                 env[i] = L_shl( L_tmp, sub( 6, exp_pow ) );
     269           0 :                 move32(); /* Q6 */
     270             :             }
     271             :         }
     272             : 
     273             :         /* initialize CNG envelope */
     274         650 :         test();
     275         650 :         IF( *first_CNG == 0 && *sid_bw == 0 )
     276             :         {
     277           0 :             Copy32( env, lp_env, NUM_ENV_CNG );
     278             :         }
     279             : 
     280         650 :         IF( *sid_bw == 0 )
     281             :         {
     282           0 :             Copy32( env, old_env, NUM_ENV_CNG );
     283             :         }
     284             :     }
     285             : 
     286       75222 :     FOR( i = 0; i < NUM_ENV_CNG; i++ )
     287             :     {
     288             :         /* get AR low-passed envelope */
     289             :         /* lp_env[i] = 0.9f*lp_env[i] + (1-0.9f)*old_env[i]; */
     290       71640 :         L_tmp = Mult_32_16( lp_env[i], 29491 /*.9f in Q15*/ );
     291       71640 :         lp_env[i] = L_add( L_tmp, Mult_32_16( old_env[i], 3277 /*.1f in Q15*/ ) );
     292       71640 :         move32(); /* Q6 */
     293             :     }
     294             : 
     295             :     /* calculate the spectrum of random excitation signal */
     296        3582 :     Copy( exc2, fft_io, L_frame );
     297             : 
     298        3582 :     IF( EQ_16( L_frame, L_FRAME16k ) )
     299             :     {
     300        2192 :         modify_Fs_fx( fft_io, L_FRAME16k, 16000, fft_io, 12800, exc_mem1, 0 );
     301             :     }
     302             : 
     303             :     /* fft_rel(fft_io, L_FFT, LOG2_L_FFT); */
     304        3582 :     fft_rel_fx( fft_io, L_FFT, LOG2_L_FFT ); /* ??????? */
     305        3582 :     ptR = &fft_io[1];
     306        3582 :     ptI = &fft_io[L_FFT - 1];
     307       75222 :     FOR( i = 0; i < NUM_ENV_CNG; i++ )
     308             :     {
     309             :         /* env[i] = 2.0f*(*ptR * *ptR + *ptI * *ptI)/L_FFT; */
     310       71640 :         L_tmp = L_mult0( *ptR, *ptR );           /* 2*Q_exc */
     311       71640 :         L_tmp = L_mac0_sat( L_tmp, *ptI, *ptI ); /* 2*Q_exc */
     312       71640 :         L_tmp = L_shr( L_tmp, 1 );               /* 2*Q_exc+6 */
     313       71640 :         tmp = add( Q_exc, Q_exc );
     314       71640 :         env[i] = L_shr_sat( L_tmp, tmp );
     315       71640 :         move32(); /* Q6 */
     316       71640 :         ptR++;
     317       71640 :         ptI--;
     318             :     }
     319             : 
     320       75222 :     FOR( i = 0; i < NUM_ENV_CNG; i++ )
     321             :     {
     322             :         /* denv[i] = lp_env[i] + 2*(*lp_ener) - env[i]; */
     323       71640 :         L_tmp = L_add_sat( *lp_ener, *lp_ener );
     324       71640 :         denv[i] = L_sub_sat( L_add_sat( lp_env[i], L_tmp ), env[i] );
     325       71640 :         move32(); /* Q6 */
     326             : 
     327       71640 :         if ( denv[i] < 0 )
     328             :         {
     329       11458 :             denv[i] = 0;
     330       11458 :             move32();
     331             :         }
     332             :     }
     333        3582 :     set32_fx( itmp, 0, NUM_ENV_CNG );
     334             : 
     335        3582 :     set16_fx( fft_io, 0, L_FFT );
     336        3582 :     ptR = &fft_io[1];
     337        3582 :     ptI = &fft_io[L_FFT - 1];
     338       75222 :     FOR( i = 0; i < NUM_ENV_CNG; i++ )
     339             :     {
     340             :         /* *ptR = own_random( cng_ener_seed1 ); */
     341             :         /* *ptI = own_random( cng_ener_seed1 ); */
     342       71640 :         *ptR = Random( cng_ener_seed1 );
     343       71640 :         move16();
     344       71640 :         *ptI = Random( cng_ener_seed1 );
     345       71640 :         move16();
     346             : 
     347             :         /* env[i] = 2.0f*(*ptR * *ptR + *ptI * *ptI)/L_FFT; */
     348       71640 :         L_tmp = L_mult0( *ptR, *ptR );       /* Q0 */
     349       71640 :         L_tmp = L_mac0( L_tmp, *ptI, *ptI ); /* Q0 */
     350       71640 :         env[i] = L_shr( L_tmp, 1 );
     351       71640 :         move32(); /* Q6 */
     352       71640 :         ptR++;
     353       71640 :         ptI--;
     354             :     }
     355             : 
     356       75222 :     FOR( i = 0; i < NUM_ENV_CNG; i++ )
     357             :     {
     358             :         /* itmp[i] += own_random( cng_ener_seed1 )*denv[i]*0.000011f + denv[i]; */
     359       71640 :         L_tmp = Mult_32_16( denv[i], Random( cng_ener_seed1 ) ); // Q6
     360       71640 :         L_tmp = Mult_32_16( L_tmp, GAIN_VAR );                   // Q6
     361       71640 :         L_tmp = L_add_sat( L_tmp, denv[i] );
     362       71640 :         itmp[i] = L_add_sat( L_tmp, itmp[i] );
     363       71640 :         move32(); /* Q6 */
     364             : 
     365       71640 :         if ( itmp[i] < 0 )
     366             :         {
     367           0 :             itmp[i] = 0;
     368           0 :             move32();
     369             :         }
     370             :     }
     371        3582 :     ptR = &fft_io[1];
     372        3582 :     ptI = &fft_io[L_FFT - 1];
     373       75222 :     FOR( i = 0; i < NUM_ENV_CNG; i++ )
     374             :     {
     375             :         /* *ptR *= sqrt(itmp[i]/env[i]); */
     376             :         /* *ptI *= sqrt(itmp[i]/env[i]); */
     377       71640 :         L_tmp = L_max( 1, itmp[i] ); /*Q6*/
     378       71640 :         exp = norm_l( L_tmp );
     379       71640 :         tmp = extract_h( L_shl( L_tmp, exp ) );
     380       71640 :         exp = sub( 31 - 6, exp ); /* in Q15 (L_tmp in Q6)*/
     381             : 
     382       71640 :         exp2 = norm_l( env[i] );
     383       71640 :         tmp2 = extract_h( L_shl( env[i], exp2 ) );
     384       71640 :         exp2 = sub( 31 - 6, exp2 ); /* in Q15 (L_tmp in Q6)*/
     385             : 
     386       71640 :         exp = sub( exp2, exp ); /* Denormalize and substract */
     387       71640 :         IF( GT_16( tmp2, tmp ) )
     388             :         {
     389       43423 :             exp = add( exp, 1 );
     390             :         }
     391       71640 :         IF( GT_16( tmp2, tmp ) )
     392             :         {
     393       43423 :             tmp2 = shr( tmp2, 1 );
     394             :         }
     395       71640 :         tmp = div_s( tmp2, tmp );
     396       71640 :         L_tmp = L_deposit_h( tmp );
     397       71640 :         L_tmp = Isqrt_lc( L_tmp, &exp ); /*Q(31-exp)*/
     398             : 
     399       71640 :         L_tmp2 = Mult_32_16( L_tmp, *ptR );                         /*Q(16-exp)*/
     400       71640 :         *ptR = extract_h( L_shl_sat( L_tmp2, add( exp, Q_exc ) ) ); /*Q_exc*/
     401       71640 :         move16();
     402       71640 :         L_tmp2 = Mult_32_16( L_tmp, *ptI );                         /*Q(16-exp)*/
     403       71640 :         *ptI = extract_h( L_shl_sat( L_tmp2, add( exp, Q_exc ) ) ); /*Q_exc*/
     404       71640 :         move16();
     405       71640 :         ptR++;
     406       71640 :         ptI--;
     407             :     }
     408             : 
     409        3582 :     ifft_rel_fx( fft_io, L_FFT, LOG2_L_FFT );
     410             : 
     411        3582 :     IF( EQ_16( L_frame, L_FRAME16k ) )
     412             :     {
     413        2192 :         modify_Fs_fx( fft_io, L_FFT, 12800, fft_io, 16000, exc_mem, 0 );
     414             :     }
     415             : 
     416             :     /* enr1 = dotp( fft_io, fft_io, L_frame ) / L_frame; */
     417             : 
     418        3582 :     enr1 = 1;
     419        3582 :     move32();
     420        3582 :     pt_fft_io = fft_io;
     421        3582 :     IF( EQ_16( L_frame, L_FRAME ) )
     422             :     {
     423      179310 :         FOR( j = 0; j < 128; j++ )
     424             :         {
     425      177920 :             L_tmp = L_mult0( *pt_fft_io, *pt_fft_io );
     426      177920 :             pt_fft_io++;
     427      177920 :             L_tmp = L_mac0( L_tmp, *pt_fft_io, *pt_fft_io ); /* 2*(Q_exc) */
     428      177920 :             pt_fft_io++;
     429      177920 :             enr1 = L_add( enr1, L_shr( L_tmp, 7 ) ); /* 2*(Q_exc)+1, divide by L_frame done here */
     430             :         }
     431             :     }
     432             :     ELSE /* L_FRAME16k */
     433             :     {
     434      352912 :         FOR( j = 0; j < 160; j++ )
     435             :         {
     436      350720 :             L_tmp = L_mult0( *pt_fft_io, *pt_fft_io );
     437      350720 :             pt_fft_io++;
     438      350720 :             L_tmp = L_mac0( L_tmp, *pt_fft_io, *pt_fft_io ); /* 2*(Q_exc) */
     439      350720 :             pt_fft_io++;
     440      350720 :             enr1 = L_add( enr1, L_shr( Mult_32_16( L_tmp, 26214 /* 256/320, Q15 */ ), 7 ) ); /* 2*(Q_exc)+15+1-16+1, divide by L_frame done here */
     441             :         }
     442             :     }
     443        3582 :     enr1 = L_shr( enr1, sub( add( Q_exc, Q_exc ), 5 ) ); /*Q6*/
     444             : 
     445             :     /* add time domain randomization */
     446       20102 :     FOR( i_subfr = 0; i_subfr < L_frame; i_subfr += L_SUBFR )
     447             :     {
     448             : 
     449       16520 :         L_tmp = Mult_32_16( enr1, Random( cng_ener_seed1 ) );
     450       16520 :         L_tmp = Mult_32_16( L_tmp, GAIN_VAR );
     451       16520 :         L_tmp = L_add( L_tmp, enr1 );
     452       16520 :         L_tmp = L_max( L_tmp, 1 );
     453             : 
     454             :         /* enr = dot_product( fft_io, fft_io, L_SUBFR ) + 0.01f */
     455       16520 :         tmp = extract_h( Dot_product12( &fft_io[i_subfr], &fft_io[i_subfr], L_SUBFR, &exp ) );
     456       16520 :         exp = add( exp, sub( -6, add( Q_exc, Q_exc ) ) ); /* -2*Q_exc from fft_io, -6 from L_SUBFR */
     457             : 
     458             :         /* enr = (float)sqrt( ener_lp*L_SUBFR / enr ) */
     459       16520 :         exp2 = norm_l( L_tmp );
     460       16520 :         tmp2 = extract_h( L_shl( L_tmp, exp2 ) );
     461       16520 :         exp2 = sub( 31 - 6, exp2 ); /* in Q15 (L_tmp in Q6)*/
     462             : 
     463       16520 :         exp = sub( exp, exp2 );
     464             : 
     465       16520 :         IF( GT_16( tmp, tmp2 ) )
     466             :         {
     467        8835 :             exp = add( exp, 1 );
     468             :         }
     469       16520 :         IF( GT_16( tmp, tmp2 ) )
     470             :         {
     471        8835 :             tmp = shr( tmp, 1 );
     472             :         }
     473       16520 :         tmp = div_s( tmp, tmp2 );
     474             : 
     475       16520 :         L_tmp = L_deposit_h( tmp );
     476       16520 :         L_tmp = Isqrt_lc( L_tmp, &exp ); /*Q(31-exp)*/
     477       16520 :         test();
     478       16520 :         test();
     479       16520 :         test();
     480       16520 :         IF( NE_32( last_core_brate, SID_2k40 ) && NE_32( last_core_brate, SID_1k75 ) && ( last_core_brate != FRAME_NO_DATA ) && EQ_32( core_brate, SID_2k40 ) )
     481             :         {
     482        1437 :             IF( GT_32( L_tmp, L_shl_sat( 1, sub( 31, exp ) ) ) )
     483             :             {
     484         790 :                 L_tmp = L_shl( 1, sub( 31, exp ) );
     485             :             }
     486             :         }
     487             : 
     488       16520 :         tmp = extract_h( L_tmp );
     489     1073800 :         FOR( i = 0; i < L_SUBFR; i++ )
     490             :         {
     491             :             /* fft_io[i] *= enr */
     492     1057280 :             L_tmp = L_mult( fft_io[i_subfr + i], tmp );            /* Q_exc + 16 - exp */
     493     1057280 :             fft_io[i_subfr + i] = round_fx( L_shl( L_tmp, exp ) ); /*Q_exc*/
     494     1057280 :             move16();
     495             :         }
     496             :     }
     497             : 
     498     1060862 :     FOR( i = 0; i < L_frame; i++ )
     499             :     {
     500             :         /* fft_io[i] = 0.75f*fft_io[i] + exc2[i];*/
     501     1057280 :         tmp = mult( fft_io[i], 24576 /*.75f in Q15*/ );
     502     1057280 :         fft_io[i] = add_sat( tmp, exc2[i] );
     503     1057280 :         move16(); /*Q_exc*/
     504             :     }
     505             : 
     506             :     /* enr = (dotp( fft_io, fft_io, L_frame ) / L_frame) + 0.01f */
     507             : 
     508        3582 :     L_tmp2 = 1;
     509        3582 :     move32();
     510        3582 :     pt_fft_io = fft_io;
     511        3582 :     IF( EQ_16( L_frame, L_FRAME ) )
     512             :     {
     513      179310 :         FOR( j = 0; j < 128; j++ )
     514             :         {
     515      177920 :             L_tmp = L_mult0( *pt_fft_io, *pt_fft_io );
     516      177920 :             pt_fft_io++;
     517      177920 :             L_tmp = L_mac0_sat( L_tmp, *pt_fft_io, *pt_fft_io ); /* 2*(Q_exc) */
     518      177920 :             pt_fft_io++;
     519      177920 :             L_tmp2 = L_add_sat( L_tmp2, L_shr( L_tmp, 7 ) ); /* 2*(Q_exc)+1, divide by L_frame done here */
     520             :         }
     521             :     }
     522             :     ELSE /* L_FRAME16k */
     523             :     {
     524      352912 :         FOR( j = 0; j < 160; j++ )
     525             :         {
     526      350720 :             L_tmp = L_mult0( *pt_fft_io, *pt_fft_io );
     527      350720 :             pt_fft_io++;
     528      350720 :             L_tmp = L_mac0_sat( L_tmp, *pt_fft_io, *pt_fft_io ); /* 2*(Q_exc) */
     529      350720 :             pt_fft_io++;
     530      350720 :             L_tmp2 = L_add( L_tmp2, L_shr( Mult_32_16( L_tmp, 26214 /* 256/320, Q15 */ ), 7 ) ); /* 2*(Q_exc)+15+1-16+1, divide by L_frame done here */
     531             :         }
     532             :     }
     533        3582 :     L_tmp2 = L_shr( L_tmp2, sub( add( Q_exc, Q_exc ), 5 ) ); /*Q6*/
     534             : 
     535             : 
     536             :     /*  enr = (*lp_ener)/enr; */
     537             :     /*  ftmp = sqrt(enr); */
     538        3582 :     L_tmp = L_max( 1, *lp_ener ); /*Q6*/
     539        3582 :     exp = norm_l( L_tmp );
     540        3582 :     tmp = extract_h( L_shl( L_tmp, exp ) );
     541        3582 :     exp = sub( 31 - 6, exp ); /* in Q15 (L_tmp in Q6)*/
     542             : 
     543        3582 :     exp2 = norm_l( L_tmp2 );
     544        3582 :     tmp2 = extract_h( L_shl( L_tmp2, exp2 ) );
     545        3582 :     exp2 = sub( 31 - 6, exp2 ); /* in Q15 (L_tmp in Q6)*/
     546             : 
     547        3582 :     exp = sub( exp2, exp ); /* Denormalize and substract */
     548        3582 :     IF( GT_16( tmp2, tmp ) )
     549             :     {
     550        1874 :         exp = add( exp, 1 );
     551             :     }
     552        3582 :     IF( GT_16( tmp2, tmp ) )
     553             :     {
     554        1874 :         tmp2 = shr( tmp2, 1 );
     555             :     }
     556        3582 :     tmp = div_s( tmp2, tmp );
     557        3582 :     L_tmp = L_deposit_h( tmp );
     558        3582 :     L_tmp = Isqrt_lc( L_tmp, &exp ); /*Q(31-exp)*/
     559             : 
     560        3582 :     ftmp = extract_h( L_shl_sat( L_tmp, exp ) ); /* Q15 */
     561     1060862 :     FOR( i = 0; i < L_frame; i++ )
     562             :     {
     563             :         /* fft_io[i] *= ftmp;*/
     564     1057280 :         fft_io[i] = mult( fft_io[i], ftmp );
     565     1057280 :         move16(); /* Q_exc */
     566             :     }
     567        3582 :     Copy( fft_io, exc2, L_frame );
     568             : }
     569        3582 : IF( NE_16( Opt_AMR_WB, 1 ) )
     570             : {
     571        3582 :     Copy( exc3, exc, L_frame );
     572             : }
     573             : ELSE
     574             : {
     575           0 :     Copy( exc2, exc, L_frame );
     576             : }
     577             : 
     578        3582 : IF( EQ_16( L_frame, L_FRAME ) )
     579             : {
     580        1390 :     interp_code_5over2_fx( exc2, bwe_exc, L_FRAME );
     581             : }
     582             : ELSE
     583             : {
     584        2192 :     interp_code_4over2_fx( exc2, bwe_exc, L_frame );
     585             : }
     586        3582 : return;
     587             : }
     588             : 
     589             : /*-------------------------------------------------------*
     590             :  * cng_params_postupd_fx
     591             :  *
     592             :  * Post-update of CNG parameters
     593             :  *-------------------------------------------------------*/
     594           0 : void cng_params_postupd_fx(
     595             :     const Word16 ho_circ_ptr,          /* i  : pointer for CNG averaging buffers                  Q0    */
     596             :     Word16 *cng_buf_cnt,               /* i/o: counter for CNG store buffers                      Q0    */
     597             :     const Word16 *const cng_exc2_buf,  /* i  : Excitation buffer                                  Q_exc */
     598             :     const Word16 *const cng_Qexc_buf,  /* i  : Q_exc buffer                                       Q0    */
     599             :     const Word32 *const cng_brate_buf, /* i  : bit rate buffer                                    Q0    */
     600             :     Word32 ho_env_circ[]               /* i/o: Envelope buffer                                    Q6    */
     601             : #ifdef IVAS_CODE_CNG_COM
     602             :     ,
     603             :     const Word16 element_mode, /* i  : Element mode                        */
     604             :     const Word16 bwidth        /* i  : Audio bandwidth                     */
     605             : #endif
     606             : )
     607             : {
     608             :     Word16 i, j;
     609             :     Word16 Q_exc;
     610             :     const Word16 *exc2;
     611             :     Word16 fft_io[L_FFT];
     612             :     Word32 sp[129];
     613             :     Word16 *ptR, *ptI;
     614             :     Word32 env[NUM_ENV_CNG];
     615             :     Word32 L_tmp;
     616             :     Word16 tmp;
     617             :     Word16 temp_lo_fx, temp_hi_fx;
     618             :     Word16 exp_pow;
     619             :     Word16 exp1;
     620             :     Word16 CNG_mode;
     621             :     Word16 ptr;
     622             :     Word32 last_active_brate;
     623             : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
     624           0 :     Flag Overflow = 0;
     625           0 :     move32();
     626             : #endif
     627             : 
     628           0 :     ptr = add( sub( ho_circ_ptr, *cng_buf_cnt ), 1 );
     629           0 :     IF( ptr < 0 )
     630             :     {
     631           0 :         ptr = add( ptr, HO_HIST_SIZE );
     632             :     }
     633             : 
     634           0 :     FOR( j = 0; j < *cng_buf_cnt; j++ )
     635             :     {
     636           0 :         exc2 = &cng_exc2_buf[ptr * L_FFT];
     637           0 :         Q_exc = cng_Qexc_buf[ptr];
     638           0 :         move16();
     639           0 :         last_active_brate = cng_brate_buf[ptr];
     640           0 :         move32();
     641             : 
     642             :         /* calculate the spectrum of residual signal */
     643           0 :         Copy( exc2, fft_io, L_FFT );
     644             : 
     645           0 :         fft_rel_fx( fft_io, L_FFT, LOG2_L_FFT );
     646             : 
     647           0 :         ptR = &fft_io[1];
     648           0 :         ptI = &fft_io[L_FFT - 1];
     649           0 :         FOR( i = 0; i < NUM_ENV_CNG; i++ )
     650             :         {
     651             :             /* sp[i] = 2.0f*(*ptR * *ptR + *ptI * *ptI)/L_FFT; */
     652           0 :             L_tmp = L_mult_o( *ptR, *ptR, &Overflow );                              /* 2*Q_exc+1 */
     653           0 :             L_tmp = L_add_o( L_tmp, L_mult_o( *ptI, *ptI, &Overflow ), &Overflow ); /* 2*Q_exc+1 */
     654           0 :             L_tmp = L_add_o( L_tmp, L_tmp, &Overflow );                             /* 2*Q_exc+1 */
     655           0 :             L_tmp = Mult_32_16( L_tmp, 128 );                                       /* 2*Q_exc+1 */
     656           0 :             tmp = add( add( Q_exc, Q_exc ), 1 );
     657           0 :             sp[i] = L_shr( L_tmp, sub( tmp, 6 ) );
     658           0 :             move32(); /* Q6 */
     659             : 
     660           0 :             ptR++;
     661           0 :             ptI--;
     662             :         }
     663             : 
     664           0 :         Copy32( sp, env, NUM_ENV_CNG );
     665             : #ifdef IVAS_CODE_CNG_COM
     666             :         if ( element_mode == IVAS_SCE || element_mode == IVAS_CPE_DFT )
     667             :         {
     668             :             att = 0.0f;
     669             :             apply_scale( &att, bwidth, last_active_brate, scaleTableStereo, SIZE_SCALE_TABLE_STEREO );
     670             :             att = powf( 10, att / 10.0f );
     671             :         }
     672             :         else
     673             : #endif
     674             :         {
     675             : 
     676           0 :             CNG_mode = get_cng_mode( last_active_brate );
     677             : 
     678             :             /* att = 1/pow(2,ENR_ATT_fx[CNG_mode]); */
     679           0 :             L_tmp = L_shl( L_deposit_l( ENR_ATT_fx[CNG_mode] ), 8 ); /* 16 */
     680           0 :             temp_lo_fx = L_Extract_lc( L_tmp, &temp_hi_fx );
     681             : 
     682           0 :             exp_pow = sub( 14, temp_hi_fx );
     683           0 :             L_tmp = Pow2( 14, temp_lo_fx );             /* Qexp_pow */
     684           0 :             L_tmp = L_shl( L_tmp, sub( 13, exp_pow ) ); /* Q13 */
     685           0 :             tmp = extract_l( L_tmp );                   /* Q13 */
     686             : 
     687           0 :             exp1 = norm_s( tmp );
     688           0 :             tmp = shl( tmp, exp1 );           /*Q(exp1+13) */
     689           0 :             tmp = div_s( 16384, tmp );        /*Q(15+14-exp1-13) */
     690           0 :             tmp = shr( tmp, sub( 1, exp1 ) ); /* Q15 */
     691             :         }
     692             : 
     693           0 :         FOR( i = 0; i < NUM_ENV_CNG; i++ )
     694             :         {
     695           0 :             env[i] = Mult_32_16( env[i], tmp );
     696           0 :             move32();
     697             :         }
     698             : 
     699             :         /* update the circular buffer of old residual envelope */
     700           0 :         Copy32( env, &( ho_env_circ[(ptr) *NUM_ENV_CNG] ), NUM_ENV_CNG );
     701             : 
     702           0 :         ptr = add( ptr, 1 );
     703           0 :         if ( EQ_16( ptr, HO_HIST_SIZE ) )
     704             :         {
     705           0 :             ptr = 0;
     706           0 :             move16();
     707             :         }
     708             :     }
     709             : 
     710           0 :     *cng_buf_cnt = 0;
     711           0 :     move16();
     712             : 
     713           0 :     return;
     714             : }
     715             : 
     716        2441 : void cng_params_postupd_ivas_fx(
     717             :     const Word16 ho_circ_ptr,          /* i  : pointer for CNG averaging buffers                  Q0    */
     718             :     Word16 *cng_buf_cnt,               /* i/o: counter for CNG store buffers                      Q0    */
     719             :     const Word16 *const cng_exc2_buf,  /* i  : Excitation buffer                                  Q_exc */
     720             :     const Word16 *const cng_Qexc_buf,  /* i  : Q_exc buffer                                       Q0    */
     721             :     const Word32 *const cng_brate_buf, /* i  : bit rate buffer                                    Q0    */
     722             :     Word32 ho_env_circ[],              /* i/o: Envelope buffer                                    Q6    */
     723             :     const Word16 element_mode,         /* i  : Element mode                        */
     724             :     const Word16 bwidth                /* i  : Audio bandwidth                     */
     725             : )
     726             : {
     727             :     Word16 i, j;
     728             :     Word16 Q_exc;
     729             :     const Word16 *exc2;
     730             :     Word16 fft_io[L_FFT];
     731             :     Word32 sp[129];
     732             :     Word16 *ptR, *ptI;
     733             :     Word32 env[NUM_ENV_CNG];
     734             :     Word32 L_tmp;
     735             :     Word16 tmp;
     736             :     Word16 temp_lo_fx, temp_hi_fx;
     737             :     Word16 exp_pow;
     738             :     Word16 exp1;
     739             :     Word16 CNG_mode;
     740             :     Word16 ptr;
     741             :     Word32 last_active_brate;
     742             : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
     743        2441 :     Flag Overflow = 0;
     744        2441 :     move32();
     745             : #endif
     746             : 
     747        2441 :     ptr = add( sub( ho_circ_ptr, *cng_buf_cnt ), 1 );
     748        2441 :     IF( ptr < 0 )
     749             :     {
     750          89 :         ptr = add( ptr, HO_HIST_SIZE );
     751             :     }
     752             : 
     753        3267 :     FOR( j = 0; j < *cng_buf_cnt; j++ )
     754             :     {
     755         826 :         exc2 = &cng_exc2_buf[ptr * L_FFT];
     756         826 :         Q_exc = cng_Qexc_buf[ptr];
     757         826 :         move16();
     758         826 :         last_active_brate = cng_brate_buf[ptr];
     759         826 :         move32();
     760             : 
     761             :         /* calculate the spectrum of residual signal */
     762         826 :         Copy( exc2, fft_io, L_FFT );
     763             : 
     764         826 :         fft_rel_fx( fft_io, L_FFT, LOG2_L_FFT );
     765             : 
     766         826 :         ptR = &fft_io[1];
     767         826 :         ptI = &fft_io[L_FFT - 1];
     768       17346 :         FOR( i = 0; i < NUM_ENV_CNG; i++ )
     769             :         {
     770             :             /* sp[i] = 2.0f*(*ptR * *ptR + *ptI * *ptI)/L_FFT; */
     771       16520 :             L_tmp = L_mult_o( *ptR, *ptR, &Overflow );                              /* 2*Q_exc+1 */
     772       16520 :             L_tmp = L_add_o( L_tmp, L_mult_o( *ptI, *ptI, &Overflow ), &Overflow ); /* 2*Q_exc+1 */
     773       16520 :             L_tmp = L_add_o( L_tmp, L_tmp, &Overflow );                             /* 2*Q_exc+1 */
     774       16520 :             L_tmp = Mult_32_16( L_tmp, 128 );                                       /* 2*Q_exc+1 */
     775       16520 :             tmp = add( add( Q_exc, Q_exc ), 1 );
     776             :             // To do : Saturation to be re-validated.
     777       16520 :             sp[i] = L_shr_sat( L_tmp, sub( tmp, 6 ) );
     778       16520 :             move32(); /* Q6 */
     779             : 
     780       16520 :             ptR++;
     781       16520 :             ptI--;
     782             :         }
     783             : 
     784         826 :         Copy32( sp, env, NUM_ENV_CNG );
     785             : 
     786         826 :         test();
     787         826 :         IF( EQ_16( element_mode, IVAS_SCE ) || EQ_16( element_mode, IVAS_CPE_DFT ) )
     788         826 :         {
     789         826 :             Word32 att_fx = 0;
     790         826 :             move32();
     791         826 :             tmp = 0;
     792         826 :             move16();
     793         826 :             apply_scale( &att_fx, bwidth, last_active_brate, scaleTableStereo, SIZE_SCALE_TABLE_STEREO );
     794         826 :             att_fx = L_shr( Mpy_32_16_1( att_fx, 26214 ), 3 ); /* 26214 = 0.1f in Q18 */
     795         826 :             att_fx = BASOP_Util_fPow( 1342177280 /* 10 in Q27 */, 4, att_fx, 8, &tmp );
     796         826 :             tmp = extract_h( L_shl_sat( att_fx, tmp ) ); // Fix for 3gpp #1080 (tmp set to 1.0)
     797             :         }
     798             :         ELSE
     799             :         {
     800             : 
     801           0 :             CNG_mode = get_cng_mode( last_active_brate );
     802             : 
     803             :             /* att = 1/pow(2,ENR_ATT_fx[CNG_mode]); */
     804           0 :             L_tmp = L_shl( L_deposit_l( ENR_ATT_fx[CNG_mode] ), 8 ); /* 16 */
     805           0 :             temp_lo_fx = L_Extract_lc( L_tmp, &temp_hi_fx );
     806             : 
     807           0 :             exp_pow = sub( 14, temp_hi_fx );
     808           0 :             L_tmp = Pow2( 14, temp_lo_fx );             /* Qexp_pow */
     809           0 :             L_tmp = L_shl( L_tmp, sub( 13, exp_pow ) ); /* Q13 */
     810           0 :             tmp = extract_l( L_tmp );                   /* Q13 */
     811             : 
     812           0 :             exp1 = norm_s( tmp );
     813           0 :             tmp = shl( tmp, exp1 );           /*Q(exp1+13) */
     814           0 :             tmp = div_s( 16384, tmp );        /*Q(15+14-exp1-13) */
     815           0 :             tmp = shr( tmp, sub( 1, exp1 ) ); /* Q15 */
     816             :         }
     817             : 
     818       17346 :         FOR( i = 0; i < NUM_ENV_CNG; i++ )
     819             :         {
     820       16520 :             env[i] = Mult_32_16( env[i], tmp );
     821       16520 :             move32();
     822             :         }
     823             : 
     824             :         /* update the circular buffer of old residual envelope */
     825         826 :         Copy32( env, &( ho_env_circ[(ptr) *NUM_ENV_CNG] ), NUM_ENV_CNG );
     826             : 
     827         826 :         ptr = add( ptr, 1 );
     828         826 :         if ( EQ_16( ptr, HO_HIST_SIZE ) )
     829             :         {
     830         107 :             ptr = 0;
     831         107 :             move16();
     832             :         }
     833             :     }
     834             : 
     835        2441 :     *cng_buf_cnt = 0;
     836        2441 :     move16();
     837             : 
     838        2441 :     return;
     839             : }
     840             : 
     841             : 
     842             : /*-------------------------------------------------------*
     843             :  * cng_params_upd_fx()
     844             :  *
     845             :  * update CNG parameters
     846             :  *-------------------------------------------------------*/
     847        2671 : void cng_params_upd_fx(
     848             :     const Word16 lsp_new[],        /* i  : LSP aprameters                                     Q15   */
     849             :     const Word16 exc2[],           /* i  : current enhanced excitation                        Q_exc */
     850             :     const Word16 L_frame,          /* i  : frame length                                       Q0    */
     851             :     Word16 *ho_circ_ptr,           /* i/o: pointer for CNG averaging buffers                  Q0    */
     852             :     Word32 ho_ener_circ[],         /* o  : energy buffer for CNG averaging                    Q6    */
     853             :     Word16 *ho_circ_size,          /* i/o: size of DTX hangover history buffer for averaging  Q0    */
     854             :     Word16 ho_lsp_circ[],          /* o  : old LSP buffer for CNG averaging                   Q15   */
     855             :     const Word16 Q_exc,            /* i  : Q value of excitation                                    */
     856             :     const Word16 enc_dec_flag,     /* i  : Flag indicating encoder or decoder (ENC,DEC)             */
     857             :     Word32 ho_env_circ[],          /* i/o: Envelope buffer                                    Q6    */
     858             :     Word16 *cng_buf_cnt,           /* i/o: Counter of postponed FFT-processing instances            */
     859             :     Word16 cng_exc2_buf[],         /* i/o: Excitation buffer                                  Q_exc */
     860             :     Word16 cng_Qexc_buf[],         /* i/o: Q_exc buffer                                       Q0    */
     861             :     Word32 cng_brate_buf[],        /* i/o: last_active_brate buffer                           Q0    */
     862             :     const Word32 last_active_brate /* i  : Last active bit rate                               Q0    */
     863             : #ifdef IVAS_CODE_CNG_COM
     864             :     ,
     865             :     const Word16 element_mode, /* i  : Element mode                        */
     866             :     const Word16 bwidth        /* i  : Audio bandwidth                     */
     867             : #endif
     868             : )
     869             : {
     870             :     Word32 L_ener, L_tmp;
     871             :     Word16 i, j;
     872             :     const Word16 *pt_exc2;
     873             :     Word16 tmpv, maxv, scale;
     874             :     Word16 fft_io[L_FRAME16k];
     875             :     Word32 sp[129];
     876             :     Word16 *ptR, *ptI;
     877             :     Word32 env[NUM_ENV_CNG];
     878             :     Word16 exp1;
     879             :     Word16 CNG_mode;
     880             :     Word16 tmp;
     881             :     Word16 temp_lo_fx, temp_hi_fx;
     882             :     Word16 exp_pow;
     883             : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
     884        2671 :     Flag Overflow = 0;
     885        2671 :     move32();
     886             : #endif
     887             : 
     888             : 
     889             :     /* update the pointer to circular buffer of old LSP vectors */
     890        2671 :     *ho_circ_ptr = add( *ho_circ_ptr, 1 );
     891        2671 :     move16();
     892             : 
     893        2671 :     if ( EQ_16( *ho_circ_ptr, HO_HIST_SIZE ) )
     894             :     {
     895         332 :         *ho_circ_ptr = 0;
     896         332 :         move16();
     897             :     }
     898             : 
     899             :     /* update the circular buffer of old LSP vectors with the new LSP vector */
     900        2671 :     Copy( lsp_new, &( ho_lsp_circ[( *ho_circ_ptr ) * M] ), M );
     901             : 
     902             :     /* calculate the residual signal energy */
     903             :     /*enr = dotp( exc2, exc2, L_frame ) / L_frame; */
     904             : 
     905        2671 :     maxv = 0;
     906        2671 :     move16();
     907      792239 :     FOR( i = 0; i < L_frame; i++ )
     908             :     {
     909      789568 :         maxv = s_max( maxv, abs_s( exc2[i] ) );
     910             :     }
     911        2671 :     scale = norm_s( maxv );
     912             : 
     913        2671 :     pt_exc2 = exc2;
     914        2671 :     L_ener = 0;
     915        2671 :     move32();
     916        2671 :     IF( EQ_16( L_frame, L_FRAME ) )
     917             :     {
     918      131322 :         FOR( j = 0; j < 128; j++ )
     919             :         {
     920      130304 :             tmpv = shl( *pt_exc2, scale );
     921      130304 :             L_tmp = L_mult0( tmpv, tmpv ); /* 2*(Q_exc+scale) */
     922      130304 :             pt_exc2++;
     923      130304 :             tmpv = shl( *pt_exc2, scale );
     924      130304 :             L_tmp = L_mac0_o( L_tmp, tmpv, tmpv, &Overflow );
     925      130304 :             pt_exc2++;
     926      130304 :             L_ener = L_add_o( L_ener, L_shr_o( L_tmp, 7, &Overflow ), &Overflow ); /* Q(2*(Q_exc+scale)+1) ,division by L_frame done here */
     927             :         }
     928             :     }
     929             :     ELSE /* L_FRAME16k */
     930             :     {
     931      266133 :         FOR( j = 0; j < 160; j++ )
     932             :         {
     933      264480 :             tmpv = shl( *pt_exc2, scale );
     934      264480 :             L_tmp = L_mult0( tmpv, tmpv ); /* 2*(Q_exc+scale) */
     935      264480 :             pt_exc2++;
     936      264480 :             tmpv = shl( *pt_exc2, scale );
     937      264480 :             L_tmp = L_mac0_o( L_tmp, tmpv, tmpv, &Overflow );
     938      264480 :             pt_exc2++;
     939      264480 :             L_ener = L_add_o( L_ener, L_shr_o( Mult_32_16( L_tmp, 26214 /* 256/320, Q15 */ ), 7, &Overflow ), &Overflow ); /* Q(2*(Q_exc+scale)+15+1-16+1) ,division by L_frame done here */
     940             :         }
     941             :     }
     942        2671 :     L_ener = L_shr_o( L_ener, sub( shl( add( Q_exc, scale ), 1 ), 5 ), &Overflow ); /* Q6 (2*(Q_exc+scale)+1-2*(Q_exc+scale)+5) */
     943             : 
     944             :     /* update the circular buffer of old energies */
     945        2671 :     ho_ener_circ[*ho_circ_ptr] = L_ener;
     946        2671 :     move32();
     947             : 
     948        2671 :     IF( enc_dec_flag == ENC )
     949             :     {
     950             :         /* Store residual signal for postponed FFT-processing*/
     951           0 :         *cng_buf_cnt = add( *cng_buf_cnt, 1 );
     952           0 :         move16();
     953           0 :         if ( GT_16( *cng_buf_cnt, HO_HIST_SIZE ) )
     954             :         {
     955           0 :             *cng_buf_cnt = HO_HIST_SIZE;
     956           0 :             move16();
     957             :         }
     958           0 :         Copy( exc2, &( cng_exc2_buf[( *ho_circ_ptr ) * L_FFT] ), L_FFT );
     959           0 :         cng_Qexc_buf[*ho_circ_ptr] = Q_exc;
     960           0 :         move16();
     961           0 :         cng_brate_buf[*ho_circ_ptr] = last_active_brate;
     962           0 :         move32();
     963             :     }
     964             :     ELSE
     965             :     {
     966             :         /* calculate the spectrum of residual signal */
     967        2671 :         Copy( exc2, fft_io, L_frame );
     968             : 
     969        2671 :         fft_rel_fx( fft_io, L_FFT, LOG2_L_FFT );
     970             : 
     971        2671 :         ptR = &fft_io[1];
     972        2671 :         ptI = &fft_io[L_FFT - 1];
     973       56091 :         FOR( i = 0; i < NUM_ENV_CNG; i++ )
     974             :         {
     975             :             /* sp[i] = 2.0f*(*ptR * *ptR + *ptI * *ptI)/L_FFT; */
     976       53420 :             L_tmp = L_mult_o( *ptR, *ptR, &Overflow );                              /* 2*Q_exc+1 */
     977       53420 :             L_tmp = L_add_o( L_tmp, L_mult_o( *ptI, *ptI, &Overflow ), &Overflow ); /* 2*Q_exc+1 */
     978       53420 :             L_tmp = L_add_o( L_tmp, L_tmp, &Overflow );                             /* 2*Q_exc+1 */
     979       53420 :             L_tmp = Mult_32_16( L_tmp, 128 );                                       /* 2*Q_exc+1 */
     980       53420 :             tmp = add( add( Q_exc, Q_exc ), 1 );
     981       53420 :             sp[i] = L_shr( L_tmp, sub( tmp, 6 ) );
     982       53420 :             move32(); /* Q6 */
     983             : 
     984       53420 :             ptR++;
     985       53420 :             ptI--;
     986             :         }
     987             : 
     988        2671 :         Copy32( sp, env, NUM_ENV_CNG );
     989             : #ifdef IVAS_CODE_CNG_COM
     990             :         if ( element_mode == IVAS_SCE || element_mode == IVAS_CPE_DFT )
     991             :         {
     992             :             att = 0.0f;
     993             :             apply_scale( &att, bwidth, last_active_brate, scaleTableStereo, SIZE_SCALE_TABLE_STEREO );
     994             :             att = powf( 10, att / 10.0f );
     995             :         }
     996             :         else
     997             : #endif
     998             :         {
     999        2671 :             CNG_mode = get_cng_mode( last_active_brate );
    1000             :             /* att = 1/pow(2,ENR_ATT_fx[CNG_mode]); */
    1001        2671 :             L_tmp = L_shl( L_deposit_l( ENR_ATT_fx[CNG_mode] ), 8 ); /* 16 */
    1002        2671 :             temp_lo_fx = L_Extract_lc( L_tmp, &temp_hi_fx );
    1003             : 
    1004        2671 :             exp_pow = sub( 14, temp_hi_fx );
    1005        2671 :             L_tmp = Pow2( 14, temp_lo_fx );             /* Qexp_pow */
    1006        2671 :             L_tmp = L_shl( L_tmp, sub( 13, exp_pow ) ); /* Q13 */
    1007        2671 :             tmp = extract_l( L_tmp );                   /* Q13 */
    1008             : 
    1009        2671 :             exp1 = norm_s( tmp );
    1010        2671 :             tmp = shl( tmp, exp1 );           /*Q(exp1+13) */
    1011        2671 :             tmp = div_s( 16384, tmp );        /*Q(15+14-exp1-13) */
    1012        2671 :             tmp = shr( tmp, sub( 1, exp1 ) ); /* Q15 */
    1013             :         }
    1014             : 
    1015       56091 :         FOR( i = 0; i < NUM_ENV_CNG; i++ )
    1016             :         {
    1017       53420 :             env[i] = Mult_32_16( env[i], tmp );
    1018       53420 :             move32();
    1019             :         }
    1020             : 
    1021             :         /* update the circular buffer of old residual envelope */
    1022             :         /* Copy32( env, &(ho_env_circ[add(shl(*ho_circ_ptr,4),shl(*ho_circ_ptr,2))]), NUM_ENV_CNG ); */
    1023        2671 :         Copy32( env, &( ho_env_circ[( *ho_circ_ptr ) * NUM_ENV_CNG] ), NUM_ENV_CNG );
    1024             :     }
    1025        2671 :     *ho_circ_size = add( *ho_circ_size, 1 );
    1026        2671 :     move16();
    1027        2671 :     if ( GT_16( *ho_circ_size, HO_HIST_SIZE ) )
    1028             :     {
    1029        2647 :         *ho_circ_size = HO_HIST_SIZE;
    1030        2647 :         move16();
    1031             :     }
    1032             : 
    1033        2671 :     return;
    1034             : }
    1035             : 
    1036      203381 : void cng_params_upd_ivas_fx(
    1037             :     const Word16 lsp_new[],        /* i  : LSP aprameters                                     Q15   */
    1038             :     const Word16 exc2[],           /* i  : current enhanced excitation                        Q_exc */
    1039             :     const Word16 L_frame,          /* i  : frame length                                       Q0    */
    1040             :     Word16 *ho_circ_ptr,           /* i/o: pointer for CNG averaging buffers                  Q0    */
    1041             :     Word32 ho_ener_circ[],         /* o  : energy buffer for CNG averaging                    Q6    */
    1042             :     Word16 *ho_circ_size,          /* i/o: size of DTX hangover history buffer for averaging  Q0    */
    1043             :     Word16 ho_lsp_circ[],          /* o  : old LSP buffer for CNG averaging                   Q15   */
    1044             :     const Word16 Q_exc,            /* i  : Q value of excitation                                    */
    1045             :     const Word16 enc_dec_flag,     /* i  : Flag indicating encoder or decoder (ENC,DEC)             */
    1046             :     Word32 ho_env_circ[],          /* i/o: Envelope buffer                                    Q(6+shift)    */
    1047             :     Word16 *cng_buf_cnt,           /* i/o: Counter of postponed FFT-processing instances            */
    1048             :     Word16 cng_exc2_buf[],         /* i/o: Excitation buffer                                  Q_exc */
    1049             :     Word16 cng_Qexc_buf[],         /* i/o: Q_exc buffer                                       Q0    */
    1050             :     Word32 cng_brate_buf[],        /* i/o: last_active_brate buffer                           Q0    */
    1051             :     const Word32 last_active_brate /* i  : Last active bit rate                               Q0    */
    1052             :     ,
    1053             :     const Word16 element_mode, /* i  : Element mode                        */
    1054             :     const Word16 bwidth        /* i  : Audio bandwidth                     */
    1055             : )
    1056             : {
    1057             :     Word32 L_ener, L_tmp;
    1058             :     Word16 i, j;
    1059             :     const Word16 *pt_exc2;
    1060             :     Word16 tmpv, maxv, scale;
    1061             :     Word16 fft_io[L_FRAME16k];
    1062             :     Word32 sp[129];
    1063             :     Word16 *ptR, *ptI;
    1064             :     Word32 env[NUM_ENV_CNG];
    1065             :     Word16 exp1;
    1066             :     Word16 CNG_mode;
    1067      203381 :     Word16 tmp = 0;
    1068      203381 :     move16();
    1069             :     Word16 temp_lo_fx, temp_hi_fx;
    1070             :     Word16 exp_pow;
    1071             : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
    1072      203381 :     Flag Overflow = 0;
    1073      203381 :     move32();
    1074             : #endif
    1075             : 
    1076             :     /* update the pointer to circular buffer of old LSP vectors */
    1077      203381 :     *ho_circ_ptr = add( *ho_circ_ptr, 1 );
    1078      203381 :     move16();
    1079             : 
    1080      203381 :     if ( EQ_16( *ho_circ_ptr, HO_HIST_SIZE ) )
    1081             :     {
    1082       24782 :         *ho_circ_ptr = 0;
    1083       24782 :         move16();
    1084             :     }
    1085             : 
    1086             :     /* update the circular buffer of old LSP vectors with the new LSP vector */
    1087      203381 :     Copy( lsp_new, &( ho_lsp_circ[( *ho_circ_ptr ) * M] ), M );
    1088             : 
    1089             :     /* calculate the residual signal energy */
    1090             :     /*enr = dotp( exc2, exc2, L_frame ) / L_frame; */
    1091             : 
    1092      203381 :     maxv = 0;
    1093      203381 :     move16();
    1094    59651317 :     FOR( i = 0; i < L_frame; i++ )
    1095             :     {
    1096    59447936 :         maxv = s_max( maxv, abs_s( exc2[i] ) );
    1097             :     }
    1098      203381 :     scale = norm_s( maxv );
    1099             : 
    1100      203381 :     pt_exc2 = exc2;
    1101      203381 :     L_ener = 0;
    1102      203381 :     move32();
    1103      203381 :     IF( EQ_16( L_frame, L_FRAME ) )
    1104             :     {
    1105    11355999 :         FOR( j = 0; j < 128; j++ )
    1106             :         {
    1107    11267968 :             tmpv = shl( *pt_exc2, scale );
    1108    11267968 :             L_tmp = L_mult0( tmpv, tmpv ); /* 2*(Q_exc+scale) */
    1109    11267968 :             pt_exc2++;
    1110    11267968 :             tmpv = shl( *pt_exc2, scale );
    1111    11267968 :             L_tmp = L_mac0_o( L_tmp, tmpv, tmpv, &Overflow );
    1112    11267968 :             pt_exc2++;
    1113    11267968 :             L_ener = L_add_o( L_ener, L_shr_o( L_tmp, 7, &Overflow ), &Overflow ); /* Q(2*(Q_exc+scale)+1) ,division by L_frame done here */
    1114             :         }
    1115             :     }
    1116             :     ELSE /* L_FRAME16k */
    1117             :     {
    1118    18571350 :         FOR( j = 0; j < 160; j++ )
    1119             :         {
    1120    18456000 :             tmpv = shl( *pt_exc2, scale );
    1121    18456000 :             L_tmp = L_mult0( tmpv, tmpv ); /* 2*(Q_exc+scale) */
    1122    18456000 :             pt_exc2++;
    1123    18456000 :             tmpv = shl( *pt_exc2, scale );
    1124    18456000 :             L_tmp = L_mac0_o( L_tmp, tmpv, tmpv, &Overflow );
    1125    18456000 :             pt_exc2++;
    1126    18456000 :             L_ener = L_add_o( L_ener, L_shr_o( Mult_32_16( L_tmp, 26214 /* 256/320, Q15 */ ), 7, &Overflow ), &Overflow ); /* Q(2*(Q_exc+scale)+15+1-16+1) ,division by L_frame done here */
    1127             :         }
    1128             :     }
    1129      203381 :     L_ener = L_shr_o( L_ener, sub( shl( add( Q_exc, scale ), 1 ), 5 ), &Overflow ); /* Q6 (2*(Q_exc+scale)+1-2*(Q_exc+scale)+5) */
    1130             : 
    1131             :     /* update the circular buffer of old energies */
    1132      203381 :     ho_ener_circ[*ho_circ_ptr] = L_ener;
    1133      203381 :     move32();
    1134             : 
    1135      203381 :     IF( enc_dec_flag == ENC )
    1136             :     {
    1137             :         /* Store residual signal for postponed FFT-processing*/
    1138       33630 :         *cng_buf_cnt = add( *cng_buf_cnt, 1 );
    1139       33630 :         move16();
    1140       33630 :         if ( GT_16( *cng_buf_cnt, HO_HIST_SIZE ) )
    1141             :         {
    1142       31850 :             *cng_buf_cnt = HO_HIST_SIZE;
    1143       31850 :             move16();
    1144             :         }
    1145       33630 :         Copy( exc2, &( cng_exc2_buf[( *ho_circ_ptr ) * L_FFT] ), L_FFT );
    1146       33630 :         cng_Qexc_buf[*ho_circ_ptr] = Q_exc;
    1147       33630 :         move16();
    1148       33630 :         cng_brate_buf[*ho_circ_ptr] = last_active_brate;
    1149       33630 :         move32();
    1150             :     }
    1151             :     ELSE
    1152             :     {
    1153             :         /* calculate the spectrum of residual signal */
    1154      169751 :         Copy( exc2, fft_io, L_frame );
    1155             : 
    1156      169751 :         fft_rel_fx( fft_io, L_FFT, LOG2_L_FFT );
    1157             : 
    1158      169751 :         ptR = &fft_io[1];
    1159      169751 :         ptI = &fft_io[L_FFT - 1];
    1160     3564771 :         FOR( i = 0; i < NUM_ENV_CNG; i++ )
    1161             :         {
    1162             :             /* sp[i] = 2.0f*(*ptR * *ptR + *ptI * *ptI)/L_FFT; */
    1163     3395020 :             L_tmp = L_mult_o( *ptR, *ptR, &Overflow );                              /* 2*Q_exc+1 */
    1164     3395020 :             L_tmp = L_add_o( L_tmp, L_mult_o( *ptI, *ptI, &Overflow ), &Overflow ); /* 2*Q_exc+1 */
    1165     3395020 :             L_tmp = L_add_o( L_tmp, L_tmp, &Overflow );                             /* 2*Q_exc+1 */
    1166     3395020 :             L_tmp = Mult_32_16( L_tmp, 128 );                                       /* 2*Q_exc+1 */
    1167     3395020 :             tmp = add( add( Q_exc, Q_exc ), 1 );
    1168     3395020 :             sp[i] = L_shr_o( L_tmp, sub( tmp, 6 ), &Overflow );
    1169     3395020 :             move32(); /* Q6 */
    1170     3395020 :             ptR++;
    1171     3395020 :             ptI--;
    1172             :         }
    1173             : 
    1174             : 
    1175      169751 :         Copy32( sp, env, NUM_ENV_CNG );
    1176      169751 :         Word16 shift = 0;
    1177      169751 :         move16();
    1178      169751 :         test();
    1179      169751 :         IF( EQ_16( element_mode, IVAS_SCE ) || EQ_16( element_mode, IVAS_CPE_DFT ) )
    1180      166000 :         {
    1181      166000 :             Word32 att_fx = 0;
    1182      166000 :             Word16 index = 0;
    1183      166000 :             move32();
    1184      166000 :             move16();
    1185      166000 :             apply_scale_ivas_fx( &att_fx, bwidth, last_active_brate, scaleTableStereo, SIZE_SCALE_TABLE_STEREO, &index );
    1186      166000 :             att_fx = pow_10_q23[index]; // Q23
    1187      166000 :             move32();
    1188      166000 :             tmp = extract_h( att_fx ); // Q7
    1189      166000 :             shift = 8;
    1190      166000 :             move16();
    1191             :         }
    1192             :         ELSE
    1193             :         {
    1194        3751 :             CNG_mode = get_cng_mode( last_active_brate );
    1195             :             /* att = 1/pow(2,ENR_ATT_fx[CNG_mode]); */
    1196        3751 :             L_tmp = L_shl( L_deposit_l( ENR_ATT_fx[CNG_mode] ), 8 ); /* 16 */
    1197        3751 :             temp_lo_fx = L_Extract_lc( L_tmp, &temp_hi_fx );
    1198             : 
    1199        3751 :             exp_pow = sub( 14, temp_hi_fx );
    1200        3751 :             L_tmp = Pow2( 14, temp_lo_fx );             /* Qexp_pow */
    1201        3751 :             L_tmp = L_shl( L_tmp, sub( 13, exp_pow ) ); /* Q13 */
    1202        3751 :             tmp = extract_l( L_tmp );                   /* Q13 */
    1203             : 
    1204        3751 :             exp1 = norm_s( tmp );
    1205        3751 :             tmp = shl( tmp, exp1 );           /*Q(exp1+13) */
    1206        3751 :             tmp = div_s( 16384, tmp );        /*Q(15+14-exp1-13) */
    1207        3751 :             tmp = shr( tmp, sub( 1, exp1 ) ); /* Q15 */
    1208             :         }
    1209             : 
    1210     3564771 :         FOR( i = 0; i < NUM_ENV_CNG; i++ )
    1211             :         {
    1212     3395020 :             env[i] = Mult_32_16( env[i], tmp );
    1213     3395020 :             move32();
    1214             :         }
    1215             : 
    1216             :         /* update the circular buffer of old residual envelope */
    1217             :         /* Copy32( env, &(ho_env_circ[add(shl(*ho_circ_ptr,4),shl(*ho_circ_ptr,2))]), NUM_ENV_CNG ); */
    1218      169751 :         Copy32( env, &( ho_env_circ[( *ho_circ_ptr ) * NUM_ENV_CNG] ), NUM_ENV_CNG );
    1219      169751 :         scale_sig32( &( ho_env_circ[( *ho_circ_ptr ) * NUM_ENV_CNG] ), NUM_ENV_CNG, shift ); // Q(6+shift)
    1220             :     }
    1221      203381 :     *ho_circ_size = add( *ho_circ_size, 1 );
    1222      203381 :     move16();
    1223      203381 :     if ( GT_16( *ho_circ_size, HO_HIST_SIZE ) )
    1224             :     {
    1225      193912 :         *ho_circ_size = HO_HIST_SIZE;
    1226      193912 :         move16();
    1227             :     }
    1228             : 
    1229      203381 :     return;
    1230             : }
    1231             : 
    1232             : /*---------------------------------------------------------------------*
    1233             :  * get_cng_mode()
    1234             :  *
    1235             :  *
    1236             :  *---------------------------------------------------------------------*/
    1237             : 
    1238        6425 : Word16 get_cng_mode(
    1239             :     const Word32 last_active_brate /* i  : last active bitrate     */
    1240             : )
    1241             : {
    1242             :     Word16 CNG_mode;
    1243             : 
    1244        6425 :     IF( GT_32( last_active_brate, ACELP_13k20 ) )
    1245             :     {
    1246        4142 :         CNG_mode = 4;
    1247        4142 :         move16();
    1248             :     }
    1249        2283 :     ELSE IF( GT_32( last_active_brate, ACELP_9k60 ) )
    1250             :     {
    1251        1727 :         CNG_mode = 3;
    1252        1727 :         move16();
    1253             :     }
    1254         556 :     ELSE IF( GT_32( last_active_brate, ACELP_8k00 ) )
    1255             :     {
    1256         397 :         CNG_mode = 2;
    1257         397 :         move16();
    1258             :     }
    1259         159 :     ELSE IF( GT_32( last_active_brate, ACELP_7k20 ) )
    1260             :     {
    1261         156 :         CNG_mode = 1;
    1262         156 :         move16();
    1263             :     }
    1264             :     ELSE
    1265             :     {
    1266           3 :         CNG_mode = 0;
    1267           3 :         move16();
    1268             :     }
    1269             : 
    1270        6425 :     return ( CNG_mode );
    1271             : }

Generated by: LCOV version 1.14