LCOV - code coverage report
Current view: top level - lib_dec - fd_cng_dec_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main -- dec/rend @ 4c82f1d24d39d0296b18d775f18a006f4c7d024b Lines: 2058 2733 75.3 %
Date: 2025-05-17 01:59:02 Functions: 23 26 88.5 %

          Line data    Source code
       1             : /*====================================================================================
       2             :     EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0
       3             :   ====================================================================================*/
       4             : 
       5             : 
       6             : #include <assert.h>
       7             : #include "typedef.h"
       8             : #include <stdint.h>
       9             : #include "options.h"
      10             : #include "rom_com.h"
      11             : #include "stat_dec.h"
      12             : #include "prot_fx.h"
      13             : #include "ivas_prot_fx.h"
      14             : #include "basop_util.h"
      15             : #include "rom_basop_util.h"
      16             : #include "ivas_rom_dec.h"
      17             : #include "ivas_prot_fx.h"
      18             : #ifdef DEBUGGING
      19             : #include "debug.h"
      20             : #endif
      21             : 
      22             : 
      23             : #define CNA_ACT_DN_LARGE_PARTITION   50    /* index of the first larger partition */
      24             : #define ST_PERIODOG_FACT_Q15         29491 /* 0.9 in Q15, short-term filter factor for periodogram */
      25             : #define CNA_ACT_DN_FACT_Q15          22938 /* 0.7 in Q15, downward updating factor for CNA during active frames */
      26             : #define FIRST_CNA_NOISE_UPD_FRAMES   5     /* minimum number of CN initialization frames */
      27             : #define DELTA_MASKING_NOISE_Q15      0
      28             : #define LOG_10_BASE_2                1783446566 /* Q29 */
      29             : #define GAIN_Q_OFFSET_IVAS_FX        45
      30             : #define LOG_10_BASE_2_BY_10_Q31      713378606
      31             : #define TWO_BY_THREE_Q31             1431655765
      32             : #define ONE_BY_FRAMES_PER_SEC_Q15    656
      33             : #define NB_LAST_BAND_SCALE_Q31       1717986918
      34             : #define SWB_13k2_LAST_BAND_SCALE_Q31 1717986918
      35             : 
      36             : /********************************
      37             :  * External tables               *
      38             :  ********************************/
      39             : 
      40             : extern const Word16 T_DIV_L_Frame[]; /* format: 0Q15 * 2^-7 */
      41             : 
      42             : const Word16 maxN_37bits = FD_CNG_maxN_37bits;
      43             : const Word16 maxC_37bits = FD_CNG_maxC_37bits;
      44             : const Word16 stages_37bits = FD_CNG_stages_37bits;
      45             : /*
      46             :    createFdCngDec_fx
      47             : 
      48             :     Parameters:
      49             : 
      50             :     hFdCngDec              i/0  : pointer to cng decoder structure
      51             : 
      52             :     Function:
      53             :     create an instance of type FD_CNG
      54             : */
      55        6430 : ivas_error createFdCngDec_fx( HANDLE_FD_CNG_DEC *hFdCngDec )
      56             : {
      57             :     HANDLE_FD_CNG_DEC hs;
      58             :     ivas_error error;
      59        6430 :     error = IVAS_ERR_OK;
      60             : 
      61             :     /* Allocate memory */
      62        6430 :     hs = (HANDLE_FD_CNG_DEC) malloc( sizeof( FD_CNG_DEC ) );
      63             : 
      64        6430 :     IF( hs == NULL )
      65             :     {
      66           0 :         return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Cannot allocate memory for FD CNG DEC structure" );
      67             :     }
      68        6430 :     IF( ( error = createFdCngCom_fx( &( hs->hFdCngCom ) ) ) != IVAS_ERR_OK )
      69             :     {
      70           0 :         return error;
      71             :     }
      72             : 
      73        6430 :     *hFdCngDec = hs;
      74        6430 :     return error;
      75             : }
      76             : 
      77        6427 : void initFdCngDec_ivas_fx(
      78             :     DEC_CORE_HANDLE st, /* i/o: decoder state structure     */
      79             :     Word16 scale /*Q15*/ )
      80             : {
      81             :     /* Initialize common */
      82             :     HANDLE_FD_CNG_DEC hFdCngDec;
      83             : 
      84        6427 :     hFdCngDec = st->hFdCngDec;
      85             : 
      86        6427 :     ivas_initFdCngCom_fx( hFdCngDec->hFdCngCom, scale );
      87        6427 :     set16_fx( hFdCngDec->olapBufferAna, 0, FFTLEN );
      88        6427 :     hFdCngDec->hFdCngCom->olapBufferAna = hFdCngDec->olapBufferAna;
      89        6427 :     set16_fx( hFdCngDec->olapBufferSynth2, 0, FFTLEN );
      90        6427 :     hFdCngDec->hFdCngCom->olapBufferSynth2 = hFdCngDec->olapBufferSynth2;
      91             : 
      92             :     /* Set some counters and flags */
      93             : 
      94        6427 :     hFdCngDec->flag_dtx_mode = 0;
      95        6427 :     move16();
      96        6427 :     hFdCngDec->lp_noise = -167772160l /*-20.f Q23*/; /* format: Q8.24 */
      97        6427 :     move32();
      98        6427 :     hFdCngDec->lp_speech = 209715200l /* 25.f Q23*/; /* format: Q8.24 */
      99        6427 :     move32();
     100             : 
     101             :     /* Initialization of the noise estimation algorithm */
     102             : 
     103        6427 :     set32_fx( hFdCngDec->bandNoiseShape, 0, FFTLEN2 );
     104        6427 :     set16_fx( &hFdCngDec->bandNoiseShape_exp, 0, 1 );
     105             : 
     106        6427 :     set32_fx( hFdCngDec->partNoiseShape, 0, NPART );
     107        6427 :     set16_fx( &hFdCngDec->partNoiseShape_exp, 0, 1 );
     108             : 
     109        6427 :     set32_fx( hFdCngDec->msPeriodog, 0, NPART_SHAPING );
     110        6427 :     set16_fx( &hFdCngDec->msPeriodog_exp, 0, 1 );
     111             : 
     112        6427 :     set32_fx( hFdCngDec->msAlpha, 0, NPART_SHAPING );
     113             : 
     114        6427 :     set32_fx( hFdCngDec->msBminWin, 0, NPART_SHAPING );
     115             : 
     116        6427 :     set32_fx( hFdCngDec->msBminSubWin, 0, NPART_SHAPING );
     117             : 
     118        6427 :     set16_fx( hFdCngDec->msPsd, 0, NPART_SHAPING );
     119        6427 :     set32_fx( hFdCngDec->msPsd_fx, 0, NPART_SHAPING );
     120        6427 :     set16_fx( hFdCngDec->msNoiseFloor, 0, NPART_SHAPING );
     121             : 
     122        6427 :     set32_fx( hFdCngDec->msNoiseEst, 0, NPART_SHAPING );
     123        6427 :     set16_fx( &hFdCngDec->msNoiseEst_exp, 0, 1 );
     124             : 
     125        6427 :     set32_fx( hFdCngDec->msMinBuf, 2147483647l /*1.0 Q31*/, MSNUMSUBFR * NPART_SHAPING );
     126             : 
     127        6427 :     set32_fx( hFdCngDec->msCurrentMin, 2147483647l /*1.0 Q31*/, NPART_SHAPING );
     128             : 
     129        6427 :     set32_fx( hFdCngDec->msCurrentMinOut, 2147483647l /*1.0 Q31*/, NPART_SHAPING );
     130             : 
     131        6427 :     set32_fx( hFdCngDec->msCurrentMinSubWindow, 2147483647l /*1.0 Q31*/, NPART_SHAPING );
     132             : 
     133        6427 :     set16_fx( hFdCngDec->msLocalMinFlag, 0, NPART_SHAPING );
     134        6427 :     set16_fx( hFdCngDec->msNewMinFlag, 0, NPART_SHAPING );
     135             : 
     136        6427 :     set16_fx( hFdCngDec->msPsdFirstMoment, 0, NPART_SHAPING );
     137             : 
     138        6427 :     set32_fx( hFdCngDec->msPsdSecondMoment, 0, NPART_SHAPING );
     139        6427 :     set16_fx( hFdCngDec->msPeriodogBuf, 0, MSBUFLEN * NPART_SHAPING );
     140             : 
     141        6427 :     hFdCngDec->msPeriodogBufPtr = 0;
     142        6427 :     move16();
     143             : 
     144        6427 :     set16_fx( hFdCngDec->msLogPeriodog, 0, NPART_SHAPING );
     145        6427 :     set16_fx( hFdCngDec->msLogNoiseEst, 0, NPART_SHAPING );
     146             : 
     147        6427 :     set16_fx( hFdCngDec->psize_shaping, 0, NPART_SHAPING );
     148        6427 :     hFdCngDec->nFFTpart_shaping = 0;
     149        6427 :     move16();
     150        6427 :     set32_fx( hFdCngDec->msPeriodog_ST_fx, 0, NPART_SHAPING );
     151        6427 :     hFdCngDec->msPeriodog_ST_exp = 0;
     152        6427 :     move16();
     153        6427 :     hFdCngDec->hFdCngCom->fftBuffer_exp = 0;
     154        6427 :     move16();
     155        6427 :     hFdCngDec->hFdCngCom->periodog_exp = 0;
     156        6427 :     move16();
     157        6427 :     set32_fx( hFdCngDec->smoothed_psd_fx, 0, L_FRAME16k );
     158        6427 :     hFdCngDec->smoothed_psd_exp = 0;
     159        6427 :     move16();
     160        6427 :     set32_fx( hFdCngDec->hFdCngCom->sidNoiseEstLp, 0, NPART );
     161             : 
     162        6427 :     hFdCngDec->ms_last_inactive_bwidth = NB;
     163        6427 :     move16();
     164        6427 :     hFdCngDec->ms_cnt_bw_up = 0;
     165        6427 :     move16();
     166             : 
     167        6427 :     hFdCngDec->cna_LR_LT_fx = 16384; /* 0.5 in Q15 */
     168        6427 :     move16();
     169        6427 :     hFdCngDec->cna_ILD_LT_fx = 0;
     170        6427 :     move16();
     171        6427 :     hFdCngDec->first_cna_noise_updated = 0;
     172        6427 :     move16();
     173        6427 :     hFdCngDec->first_cna_noise_update_cnt = 0;
     174        6427 :     move16();
     175        6427 :     hFdCngDec->cna_nbands = CNA_INIT_NBANDS;
     176        6427 :     move16();
     177        6427 :     Copy( cna_init_bands, hFdCngDec->cna_band_limits, CNA_INIT_NBANDS + 1 );
     178        6427 :     hFdCngDec->cna_act_fact_fx = 32767; /* 1.0f in Q15 */
     179        6427 :     move16();
     180        6427 :     hFdCngDec->cna_rescale_fact_fx = 0;
     181        6427 :     move16();
     182        6427 :     hFdCngDec->cna_seed = 5687; /*Q0*/
     183        6427 :     move16();
     184        6427 :     set16_fx( hFdCngDec->cna_cm_fx, 0, STEREO_DFT_BAND_MAX );
     185        6427 :     set16_fx( hFdCngDec->cna_g_state_fx, 0, STEREO_DFT_BAND_MAX );
     186             : 
     187        6427 :     st->CNG_mode = -1;
     188        6427 :     move16();
     189        6427 :     Copy( st->lsp_old_fx, st->lspCNG_fx, M ); /*Q15*/
     190        6427 :     hFdCngDec->hFdCngCom->sid_frame_counter = 0;
     191        6427 :     return;
     192             : }
     193             : 
     194           3 : void initFdCngDec_fx(
     195             :     DEC_CORE_HANDLE st, /* i/o: decoder state structure     */
     196             :     Word16 scale /*Q15*/ )
     197             : {
     198             :     /* Initialize common */
     199             :     HANDLE_FD_CNG_DEC hFdCngDec;
     200             : 
     201           3 :     hFdCngDec = st->hFdCngDec;
     202             : 
     203           3 :     initFdCngCom( hFdCngDec->hFdCngCom, scale );
     204           3 :     set16_fx( hFdCngDec->olapBufferAna, 0, 320 );
     205           3 :     hFdCngDec->hFdCngCom->olapBufferAna = hFdCngDec->olapBufferAna;
     206           3 :     move16();
     207           3 :     set16_fx( hFdCngDec->olapBufferSynth2, 0, FFTLEN );
     208           3 :     hFdCngDec->hFdCngCom->olapBufferSynth2 = hFdCngDec->olapBufferSynth2;
     209           3 :     move16();
     210             : 
     211             :     /* Set some counters and flags */
     212             : 
     213           3 :     hFdCngDec->flag_dtx_mode = 0;
     214           3 :     move16();
     215           3 :     hFdCngDec->lp_noise = -167772160l /*-20.f Q23*/; /* format: Q8.24 */
     216           3 :     move32();
     217           3 :     hFdCngDec->lp_speech = 209715200l /* 25.f Q23*/; /* format: Q8.24 */
     218           3 :     move32();
     219             : 
     220             :     /* Initialization of the noise estimation algorithm */
     221             : 
     222           3 :     set32_fx( hFdCngDec->bandNoiseShape, 0, FFTLEN2 );
     223           3 :     set16_fx( &hFdCngDec->bandNoiseShape_exp, 0, 1 );
     224             : 
     225           3 :     set32_fx( hFdCngDec->partNoiseShape, 0, NPART );
     226           3 :     set16_fx( &hFdCngDec->partNoiseShape_exp, 0, 1 );
     227             : 
     228           3 :     set32_fx( hFdCngDec->msPeriodog, 0, NPART_SHAPING );
     229           3 :     set16_fx( &hFdCngDec->msPeriodog_exp, 0, 1 );
     230             : 
     231           3 :     set32_fx( hFdCngDec->msAlpha, 0, NPART_SHAPING );
     232             : 
     233           3 :     set32_fx( hFdCngDec->msBminWin, 0, NPART_SHAPING );
     234             : 
     235           3 :     set32_fx( hFdCngDec->msBminSubWin, 0, NPART_SHAPING );
     236             : 
     237           3 :     set16_fx( hFdCngDec->msPsd, 0, NPART_SHAPING );
     238           3 :     set32_fx( hFdCngDec->msPsd_fx, 0, NPART_SHAPING );
     239           3 :     set16_fx( hFdCngDec->msNoiseFloor, 0, NPART_SHAPING );
     240             : 
     241           3 :     set32_fx( hFdCngDec->msNoiseEst, 0, NPART_SHAPING );
     242           3 :     set16_fx( &hFdCngDec->msNoiseEst_exp, 0, 1 );
     243             : 
     244           3 :     set32_fx( hFdCngDec->msMinBuf, 2147483647l /*1.0 Q31*/, MSNUMSUBFR * NPART_SHAPING );
     245             : 
     246           3 :     set32_fx( hFdCngDec->msCurrentMin, 2147483647l /*1.0 Q31*/, NPART_SHAPING );
     247             : 
     248           3 :     set32_fx( hFdCngDec->msCurrentMinOut, 2147483647l /*1.0 Q31*/, NPART_SHAPING );
     249             : 
     250           3 :     set32_fx( hFdCngDec->msCurrentMinSubWindow, 2147483647l /*1.0 Q31*/, NPART_SHAPING );
     251             : 
     252           3 :     set16_fx( hFdCngDec->msLocalMinFlag, 0, NPART_SHAPING );
     253           3 :     set16_fx( hFdCngDec->msNewMinFlag, 0, NPART_SHAPING );
     254             : 
     255           3 :     set16_fx( hFdCngDec->msPsdFirstMoment, 0, NPART_SHAPING );
     256             : 
     257           3 :     set32_fx( hFdCngDec->msPsdSecondMoment, 0, NPART_SHAPING );
     258           3 :     set16_fx( hFdCngDec->msPeriodogBuf, 0, MSBUFLEN * NPART_SHAPING );
     259             : 
     260           3 :     hFdCngDec->msPeriodogBufPtr = 0;
     261           3 :     move16();
     262             : 
     263           3 :     set16_fx( hFdCngDec->msLogPeriodog, 0, NPART_SHAPING );
     264           3 :     set16_fx( hFdCngDec->msLogNoiseEst, 0, NPART_SHAPING );
     265             : 
     266           3 :     set16_fx( hFdCngDec->psize_shaping, 0, NPART_SHAPING );
     267           3 :     hFdCngDec->nFFTpart_shaping = 0;
     268           3 :     move16();
     269           3 :     set32_fx( hFdCngDec->msPeriodog_ST_fx, 0, NPART_SHAPING );
     270           3 :     hFdCngDec->msPeriodog_ST_exp = 0;
     271           3 :     move16();
     272           3 :     hFdCngDec->hFdCngCom->fftBuffer_exp = 0;
     273           3 :     move16();
     274           3 :     hFdCngDec->hFdCngCom->periodog_exp = 0;
     275           3 :     move16();
     276           3 :     set32_fx( hFdCngDec->smoothed_psd_fx, 0, L_FRAME16k );
     277           3 :     hFdCngDec->smoothed_psd_exp = 0;
     278           3 :     move16();
     279             : 
     280           3 :     return;
     281             : }
     282             : /*
     283             :    configureFdCngDec_fx
     284             : 
     285             :     Parameters:
     286             : 
     287             :     hs                      i/o: Contains the variables related to the FD-based CNG process
     288             :     numSlots                i  : Number of time slots in CLDFB matrix
     289             :     numCoreBands            i  : Number of core bands
     290             :     regularStopBand         i  : Number of CLDFB bands to be considered
     291             :     CLDFBscale                i  : cldfb scale factor
     292             : 
     293             :     Function:
     294             :     configure FD_CNG
     295             : 
     296             :     Returns:
     297             :     void
     298             : */
     299        5504 : void configureFdCngDec_fx(
     300             :     HANDLE_FD_CNG_DEC hFdCngDec, /* i/o: Contains the variables related to the CLDFB-based CNG process */
     301             :     Word16 bwidth,               /*Q0*/
     302             :     Word32 total_brate,          /*Q0*/
     303             :     Word16 L_frame,              /*Q0*/
     304             :     const Word16 Last_L_frame,   /*Q0*/
     305             :     const Word16 element_mode /*Q0*/ )
     306             : {
     307             :     Word16 j, stopBandFR;
     308        5504 :     HANDLE_FD_CNG_COM hsCom = hFdCngDec->hFdCngCom;
     309             : 
     310             : 
     311        5504 :     hsCom->CngBandwidth = bwidth; /*Q0*/
     312        5504 :     move16();
     313        5504 :     if ( EQ_16( hsCom->CngBandwidth, FB ) )
     314             :     {
     315         789 :         hsCom->CngBandwidth = SWB;
     316         789 :         move16();
     317             :     }
     318        5504 :     test();
     319        5504 :     IF( total_brate != FRAME_NO_DATA && NE_32( total_brate, SID_2k40 ) )
     320             :     {
     321        5504 :         hsCom->CngBitrate = total_brate; /*Q0*/
     322        5504 :         move32();
     323             :     }
     324           0 :     ELSE IF( EQ_32( hsCom->CngBitrate, -1 ) )
     325             :     {
     326             :         /* set minimum active CBR bitrate if CngBitrate is uninitialized */
     327           0 :         hsCom->CngBitrate = ACELP_7k20;
     328           0 :         move32();
     329           0 :         if ( element_mode > EVS_MONO )
     330             :         {
     331           0 :             hsCom->CngBitrate = IVAS_13k2;
     332           0 :             move32();
     333             :         }
     334             :     }
     335             : 
     336             :     /* FD-CNG config for MDCT-Stereo is always the same (since for > 48 kbps only) */
     337             :     /* This may need adjustment in the future if 2TC DTX for some mode uses MDCT-Stereo DTX for lower bitrates too */
     338        5504 :     if ( EQ_16( element_mode, IVAS_CPE_MDCT ) )
     339             :     {
     340           0 :         hsCom->CngBitrate = IVAS_48k;
     341           0 :         move32();
     342             :     }
     343             : 
     344        5504 :     hsCom->numSlots = 16;
     345        5504 :     move16();
     346             : 
     347             :     /* NB configuration */
     348        5504 :     IF( bwidth == NB )
     349             :     {
     350           0 :         hsCom->FdCngSetup = FdCngSetup_nb;
     351           0 :         hsCom->numCoreBands = 16;
     352           0 :         move16();
     353           0 :         hsCom->regularStopBand = 16;
     354           0 :         move16();
     355             :     }
     356             : 
     357             :     /* WB configuration */
     358        5504 :     ELSE IF( EQ_16( bwidth, WB ) )
     359             :     {
     360             :         /* FFT 6.4kHz, no CLDFB */
     361        1643 :         test();
     362        1643 :         test();
     363        1643 :         IF( LE_32( hsCom->CngBitrate, ACELP_8k00 ) && EQ_16( L_frame, L_FRAME ) )
     364             :         {
     365           0 :             hsCom->FdCngSetup = FdCngSetup_wb1;
     366           0 :             hsCom->numCoreBands = 16;
     367           0 :             move16();
     368           0 :             hsCom->regularStopBand = 16;
     369           0 :             move16();
     370             :         }
     371             :         /* FFT 6.4kHz, CLDFB 8.0kHz */
     372        1643 :         ELSE IF( LE_32( hsCom->CngBitrate, ACELP_13k20 ) || EQ_16( L_frame, L_FRAME ) )
     373             :         {
     374         699 :             hsCom->FdCngSetup = FdCngSetup_wb2;
     375         699 :             hsCom->numCoreBands = 16;
     376         699 :             move16();
     377         699 :             hsCom->regularStopBand = 20;
     378         699 :             move16();
     379         699 :             IF(
     380             :                 EQ_16( L_frame, L_FRAME16k ) )
     381             :             {
     382           0 :                 hsCom->FdCngSetup = FdCngSetup_wb2;
     383           0 :                 hsCom->numCoreBands = 20;
     384           0 :                 move16();
     385           0 :                 hsCom->regularStopBand = 20;
     386           0 :                 move16();
     387           0 :                 hsCom->FdCngSetup.fftlen = 640;
     388           0 :                 move16();
     389           0 :                 hsCom->FdCngSetup.stopFFTbin = 256;
     390           0 :                 move16();
     391             :             }
     392             :         }
     393             :         /* FFT 8.0kHz, no CLDFB */
     394             :         ELSE
     395             :         {
     396         944 :             hsCom->FdCngSetup = FdCngSetup_wb3;
     397         944 :             hsCom->numCoreBands = 20;
     398         944 :             move16();
     399         944 :             hsCom->regularStopBand = 20;
     400         944 :             move16();
     401             :         }
     402             :     }
     403             : 
     404             :     /* SWB/FB configuration */
     405             :     ELSE
     406             :     {
     407             :         /* FFT 6.4kHz, CLDFB 14kHz */
     408        3861 :         IF(
     409             :             EQ_16( L_frame, L_FRAME ) )
     410             :         {
     411        1805 :             hsCom->FdCngSetup = FdCngSetup_swb1;
     412        1805 :             hsCom->numCoreBands = 16;
     413        1805 :             move16();
     414        1805 :             hsCom->regularStopBand = 35;
     415        1805 :             move16();
     416             :         }
     417             :         /* FFT 8.0kHz, CLDFB 16kHz */
     418             :         ELSE
     419             :         {
     420        2056 :             hsCom->FdCngSetup = FdCngSetup_swb2;
     421        2056 :             hsCom->numCoreBands = 20;
     422        2056 :             move16();
     423        2056 :             hsCom->regularStopBand = 40;
     424        2056 :             move16();
     425        2056 :             test();
     426        2056 :             if ( EQ_16( Last_L_frame, L_FRAME ) && EQ_16( element_mode, IVAS_CPE_DFT ) )
     427             :             {
     428           3 :                 hsCom->regularStopBand = 35;
     429           3 :                 move16();
     430             :             }
     431             :         }
     432             :     }
     433        5504 :     hsCom->fftlen = hsCom->FdCngSetup.fftlen; /*Q0*/
     434        5504 :     move16();
     435        5504 :     hsCom->stopFFTbin = hsCom->FdCngSetup.stopFFTbin; /*Q0*/
     436        5504 :     move16();
     437             : 
     438             :     /* Configure the SID quantizer and the Confort Noise Generator */
     439             : 
     440        5504 :     hsCom->startBand = 2;
     441        5504 :     move16();
     442        5504 :     hsCom->stopBand = add( hsCom->FdCngSetup.sidPartitions[( hsCom->FdCngSetup.numPartitions - 1 )], 1 ); /*Q0*/
     443        5504 :     move16();
     444        5504 :     initPartitions( hsCom->FdCngSetup.sidPartitions, hsCom->FdCngSetup.numPartitions, hsCom->startBand, hsCom->stopBand, hsCom->part,
     445        5504 :                     &hsCom->npart, hsCom->midband, hsCom->psize, hsCom->psize_norm, &hsCom->psize_norm_exp, hsCom->psize_inv, 0 );
     446             : 
     447        5504 :     hsCom->nFFTpart = 21;
     448        5504 :     move16();
     449        5504 :     if ( EQ_16( hsCom->stopFFTbin, 256 ) )
     450             :     {
     451        2504 :         hsCom->nFFTpart = 20;
     452        2504 :         move16();
     453             :     }
     454        5504 :     if ( EQ_16( hsCom->stopFFTbin, 160 ) )
     455             :     {
     456           0 :         hsCom->nFFTpart = 17;
     457           0 :         move16();
     458             :     }
     459             : 
     460        5504 :     hsCom->nCLDFBpart = sub( hsCom->npart, hsCom->nFFTpart );
     461        5504 :     move16();
     462       19591 :     FOR( j = 0; j < hsCom->nCLDFBpart; j++ )
     463             :     {
     464       14087 :         hsCom->CLDFBpart[j] = sub( hsCom->part[( j + hsCom->nFFTpart )], sub( hsCom->stopFFTbin, hsCom->startBand ) ); /*Q0*/
     465       14087 :         move16();
     466       14087 :         hsCom->CLDFBpsize_inv[j] = hsCom->psize_inv[( j + hsCom->nFFTpart )]; /*Q15*/
     467       14087 :         move16();
     468             :     }
     469             : 
     470        5504 :     stopBandFR = 1000 / 25;
     471        5504 :     move16();
     472        5504 :     if ( GT_16( stopBandFR, hsCom->stopFFTbin ) )
     473             :     {
     474           0 :         stopBandFR = hsCom->stopFFTbin; /*Q0*/
     475           0 :         move16();
     476             :     }
     477        5504 :     initPartitions( hsCom->FdCngSetup.shapingPartitions, hsCom->FdCngSetup.numShapingPartitions,
     478        5504 :                     hsCom->startBand, hsCom->stopFFTbin, hFdCngDec->part_shaping, &hFdCngDec->npart_shaping, hFdCngDec->midband_shaping,
     479        5504 :                     hFdCngDec->psize_shaping, hFdCngDec->psize_shaping_norm, &hFdCngDec->psize_shaping_norm_exp, hFdCngDec->psize_inv_shaping,
     480             :                     stopBandFR );
     481        5504 :     hFdCngDec->nFFTpart_shaping = hFdCngDec->npart_shaping; /*Q0*/
     482        5504 :     move16();
     483             : 
     484        5504 :     SWITCH( hsCom->fftlen )
     485             :     {
     486        2504 :         case 512:
     487        2504 :             hsCom->fftlenShift = 8;
     488        2504 :             move16();
     489        2504 :             hsCom->fftlenFac = 32767 /*1.0 Q15*/;
     490        2504 :             move16();
     491        2504 :             BREAK;
     492        3000 :         case 640:
     493        3000 :             hsCom->fftlenShift = 9;
     494        3000 :             move16();
     495        3000 :             hsCom->fftlenFac = 20480 /*0.625 Q15*/;
     496        3000 :             move16();
     497        3000 :             BREAK;
     498           0 :         default:
     499           0 :             assert( !"Unsupported FFT length for FD-based CNG" );
     500             :             BREAK;
     501             :     }
     502        5504 :     BASOP_getTables( &hsCom->olapWinAna, NULL, NULL, shr( hsCom->fftlen, 1 ) );
     503        5504 :     BASOP_getTables( &hsCom->olapWinSyn, NULL, NULL, shr( hsCom->fftlen, 2 ) );
     504        5504 :     hsCom->frameSize = shr( hsCom->fftlen, 1 );
     505        5504 :     move16();
     506        5504 : }
     507             : 
     508             : 
     509             : /*
     510             :    deleteFdCngDec_fx
     511             : 
     512             :     Parameters:
     513             : 
     514             :     hFdCngDec              i/0  : pointer to cng decoder structure
     515             : 
     516             :     Function:
     517             :     delete the instance of type FD_CNG
     518             : 
     519             :     Returns:
     520             :     void
     521             : */
     522      171883 : void deleteFdCngDec_fx( HANDLE_FD_CNG_DEC *hFdCngDec )
     523             : {
     524      171883 :     HANDLE_FD_CNG_DEC hsDec = *hFdCngDec;
     525             : 
     526      171883 :     IF( hsDec != NULL )
     527             :     {
     528        6430 :         deleteFdCngCom_fx( &( hsDec->hFdCngCom ) );
     529        6430 :         free( hsDec );
     530        6430 :         *hFdCngDec = NULL;
     531             :     }
     532      171883 : }
     533             : 
     534             : 
     535             : /*
     536             :    ApplyFdCng_fx
     537             : 
     538             :     Parameters:
     539             : 
     540             :     timeDomainInput,       i  : pointer to time domain input
     541             :     cldfbBufferReal          i/o: real part of the CLDFB buffer
     542             :     cldfbBufferImag          i/o: imaginary part of the CLDFB buffer
     543             :     cldfbBufferScale         o  : pointer to the scalefactor for real and imaginary part of the CLDFB buffer
     544             :     st                     i/o: pointer to FD_CNG structure containing all buffers and variables
     545             :     m_frame_type           i  : type of frame at the decoder side
     546             :     stcod                  i  : pointer to Coder_State structure
     547             :     st                  i  : pointer to Decoder_State structure
     548             :     bitrate                i  : bitrate
     549             :     concealWholeFrame      i  : binary flag indicating frame loss
     550             : 
     551             :     Function:
     552             :     apply the CLDFB-based CNG at the decoder
     553             : 
     554             :     Returns:
     555             :     error
     556             : */
     557             : 
     558      261632 : Word16 ApplyFdCng_fx(
     559             :     Word16 *timeDomainInput, /* i  : pointer to time domain input Q*/
     560             :     Word16 Q,
     561             :     Word32 *powerSpectrum, /*Q_power_spectrum*/
     562             :     Word16 Q_power_spectrum,
     563             :     Word32 **cldfbBufferReal, /* i/o: real part of the CLDFB buffer    cldfbBufferScale*/
     564             :     Word32 **cldfbBufferImag, /* i/o: imaginary part of the CLDFB buffer   cldfbBufferScale*/
     565             :     Word16 *cldfbBufferScale, /* o  : pointer to the scalefactor for real and imaginary part of the CLDFB buffer */
     566             :     Decoder_State *st,
     567             :     const Word16 concealWholeFrame, /* i  : binary flag indicating frame loss Q0*/
     568             :     Word16 is_music /*Q0*/ )
     569             : {
     570             :     Word16 j, k, nBins;
     571             :     Word16 s, s1, s2, num, denom;
     572             :     Word32 *cngNoiseLevel;
     573             :     Word16 *cngNoiseLevel_exp;
     574             :     Word32 L_tmp;
     575             :     Word16 L_tmp_exp;
     576             :     Word16 facTab[NPART];
     577             :     Word16 facTabExp[NPART];
     578             :     Word16 tmp_loop;
     579             :     Word32 L_c;
     580             :     Word16 lsp_cng[M];
     581             :     HANDLE_FD_CNG_DEC hFdCngDec;
     582             :     HANDLE_FD_CNG_COM hFdCngCom;
     583             : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
     584      261632 :     Flag Overflow = 0;
     585      261632 :     Flag Carry = 0;
     586      261632 :     move16();
     587      261632 :     move16();
     588             : #endif
     589             :     Word16 L_frame, last_L_frame;
     590             : 
     591      261632 :     hFdCngDec = st->hFdCngDec;
     592      261632 :     hFdCngCom = hFdCngDec->hFdCngCom;
     593             : 
     594      261632 :     Word32 *sidNoiseEst = hFdCngCom->sidNoiseEst; /*Q31 - hFdCngCom->sidNoiseEstExp*/
     595             : 
     596             :     /* limit L_frame and core fs values for MDCT-Stereo modes which can have higher core sampling than 16kHz, but use a downsampled buffer */
     597      261632 :     L_frame = s_min( st->L_frame, L_FRAME16k );
     598      261632 :     last_L_frame = s_min( st->last_L_frame, L_FRAME16k );
     599             : 
     600      261632 :     if ( EQ_16( hFdCngCom->frame_type_previous, ACTIVE_FRAME ) )
     601             :     {
     602      241712 :         hFdCngCom->inactive_frame_counter = 0;
     603      241712 :         move16();
     604             :     }
     605      261632 :     IF( EQ_16( st->element_mode, IVAS_CPE_TD ) )
     606             :     {
     607        3751 :         hFdCngDec->flag_dtx_mode = hFdCngDec->flag_dtx_mode || st->first_CNG;
     608        3751 :         move16();
     609             :     }
     610      261632 :     cngNoiseLevel = hFdCngCom->cngNoiseLevel;
     611      261632 :     move32();
     612      261632 :     cngNoiseLevel_exp = &hFdCngCom->cngNoiseLevelExp;
     613      261632 :     move16();
     614      261632 :     nBins = sub( hFdCngCom->stopFFTbin, hFdCngCom->startBand );
     615             : 
     616      261632 :     SWITCH( st->m_frame_type )
     617             :     {
     618      242961 :         case ACTIVE_FRAME:
     619             : 
     620             :             /**************************
     621             :              * ACTIVE_FRAME at DECODER *
     622             :              **************************/
     623             : 
     624      242961 :             hFdCngCom->inactive_frame_counter = 0;
     625      242961 :             move16();
     626      242961 :             hFdCngCom->sid_frame_counter = 0;
     627      242961 :             move16();
     628             : 
     629             :             /* set noise estimation inactive during concealment, as no update with noise generated by concealment should be performed. */
     630             :             /* set noise estimation inactive during concealment, no update with noise generated by concealment should be performed. */
     631             : 
     632      242961 :             test();
     633      242961 :             test();
     634      242961 :             test();
     635      242961 :             test();
     636      242961 :             test();
     637      242961 :             test();
     638      242961 :             test();
     639      242961 :             test();
     640      242961 :             test();
     641      242961 :             test();
     642      242961 :             test();
     643      242961 :             test();
     644      242961 :             test();
     645      242961 :             test();
     646      242961 :             test();
     647      242961 :             test();
     648      242961 :             test();
     649      242961 :             IF( EQ_16( concealWholeFrame, 0 ) &&
     650             :                 ( timeDomainInput == NULL ||
     651             :                   ( LT_16( *timeDomainInput, MAXVAL_WORD16 ) && GT_16( *timeDomainInput, MINVAL_WORD16 ) &&
     652             :                     LT_16( *( timeDomainInput + sub( hFdCngCom->frameSize, 1 ) ), MAXVAL_WORD16 ) &&
     653             :                     GT_16( *( timeDomainInput + sub( hFdCngCom->frameSize, 1 ) ), MINVAL_WORD16 ) ) ) &&
     654             :                 ( ( ( ( NE_16( st->element_mode, IVAS_CPE_TD ) && NE_16( st->element_mode, IVAS_CPE_DFT ) && hFdCngDec->flag_dtx_mode ) || !st->VAD || ( LT_16( st->ini_frame, 100 ) && st->is_ism_format ) ) &&
     655             :                     !( st->cng_type == LP_CNG && hFdCngDec->flag_dtx_mode ) && ( is_music == 0 ) ) ||
     656             :                   EQ_16( st->element_mode, IVAS_CPE_TD ) ) &&
     657             :                 ( !st->BER_detect ) )
     658             :             {
     659             :                 /* Perform noise estimation at the decoder */
     660       48627 :                 IF( EQ_16( st->element_mode, EVS_MONO ) )
     661             :                 {
     662          15 :                     perform_noise_estimation_dec_fx( timeDomainInput, Q, hFdCngDec );
     663             :                 }
     664             :                 ELSE
     665             :                 {
     666       48612 :                     perform_noise_estimation_dec_ivas_fx( timeDomainInput, Q, powerSpectrum, Q_power_spectrum, hFdCngDec, st->element_mode, st->bwidth, L_frame, last_L_frame, st->last_core_brate, st->VAD );
     667             :                 }
     668             : 
     669             :                 /* Update the shaping parameters */
     670       48627 :                 test();
     671       48627 :                 IF( EQ_16( st->element_mode, EVS_MONO ) )
     672             :                 {
     673          15 :                     scalebands( hFdCngDec->msNoiseEst, hFdCngDec->part_shaping, hFdCngDec->nFFTpart_shaping, hFdCngDec->midband_shaping, hFdCngDec->nFFTpart_shaping, nBins, hFdCngDec->bandNoiseShape, 1 );
     674             :                 }
     675       48612 :                 ELSE IF( NE_16( st->element_mode, IVAS_CPE_TD ) && NE_16( st->element_mode, IVAS_CPE_DFT ) )
     676             :                 {
     677       42138 :                     scalebands_fx( hFdCngDec->msNoiseEst, hFdCngDec->part_shaping, hFdCngDec->nFFTpart_shaping, hFdCngDec->midband_shaping, hFdCngDec->nFFTpart_shaping, nBins, hFdCngDec->bandNoiseShape, 1 );
     678             :                 }
     679       48627 :                 hFdCngDec->bandNoiseShape_exp = hFdCngDec->msNoiseEst_exp;
     680       48627 :                 move16();
     681             : 
     682             : 
     683             :                 /* Update CNG levels */
     684       48627 :                 test();
     685       48627 :                 IF( hFdCngDec->flag_dtx_mode != 0 && EQ_16( st->cng_type, FD_CNG ) )
     686             :                 {
     687             :                     /* This needs to be done only once per inactive phase */
     688        3355 :                     bandcombinepow(
     689        3355 :                         hFdCngDec->bandNoiseShape,
     690        3355 :                         hFdCngDec->bandNoiseShape_exp,
     691             :                         nBins,
     692        3355 :                         hFdCngCom->part,
     693        3355 :                         hFdCngCom->nFFTpart,
     694        3355 :                         hFdCngCom->psize_inv,
     695        3355 :                         hFdCngDec->partNoiseShape,
     696             :                         &hFdCngDec->partNoiseShape_exp );
     697             : 
     698             : 
     699        3355 :                     j = 0;
     700        3355 :                     move16();
     701             :                     // s2 = -( WORD32_BITS - 1 );
     702        3355 :                     s2 = -( WORD32_BITS - 1 );
     703        3355 :                     move16();
     704       72007 :                     FOR( k = 0; k < hFdCngCom->nFFTpart; k++ )
     705             :                     {
     706       68652 :                         assert( hFdCngDec->partNoiseShape[k] >= 0 );
     707       68652 :                         assert( hFdCngCom->sidNoiseEst[k] >= 0 );
     708             : 
     709             :                         /* add DELTA as it is done in FLC version, in order to avoid num > denom */
     710       68652 :                         facTab[k] = 0;
     711       68652 :                         move16();
     712       68652 :                         IF( hFdCngDec->partNoiseShape[k] != 0 )
     713             :                         {
     714       68608 :                             s1 = norm_l( hFdCngCom->sidNoiseEst[k] );
     715       68608 :                             L_tmp = L_shl( hFdCngCom->sidNoiseEst[k], s1 ); /*Q31 - hFdCngCom->sidNoiseEstExp + s1*/
     716       68608 :                             L_tmp_exp = sub( hFdCngCom->sidNoiseEstExp, s1 );
     717       68608 :                             L_tmp = BASOP_Util_Add_Mant32Exp( L_tmp, L_tmp_exp, DELTA_MANTISSA_W32, DELTA_EXPONENT, &L_tmp_exp );
     718       68608 :                             L_tmp = L_shr( L_tmp, 1 );
     719       68608 :                             s = add( L_tmp_exp, 1 );
     720       68608 :                             num = extract_h( L_tmp ); /*Q15 - L_tmp_exp*/
     721             : 
     722       68608 :                             s1 = norm_l( hFdCngDec->partNoiseShape[k] );
     723       68608 :                             L_tmp = L_shl( hFdCngDec->partNoiseShape[k], s1 ); /*Q31 - hFdCngDec->partNoiseShape_exp + s1*/
     724       68608 :                             L_tmp_exp = sub( hFdCngDec->partNoiseShape_exp, s1 );
     725       68608 :                             L_tmp = BASOP_Util_Add_Mant32Exp( L_tmp, L_tmp_exp, DELTA_MANTISSA_W32, DELTA_EXPONENT, &L_tmp_exp );
     726       68608 :                             s = sub( s, L_tmp_exp );
     727       68608 :                             denom = extract_h( L_tmp ); /*Q15 - L_tmp_exp*/
     728             : 
     729       68608 :                             facTab[k] = div_s( num, denom ); /*Q15 - s*/
     730       68608 :                             move16();
     731       68608 :                             facTabExp[k] = s;
     732       68608 :                             move16();
     733             :                         }
     734             :                         /* Set unique exponent, if mantissa is equal to zero */
     735       68652 :                         IF( EQ_16( facTab[k], 0 ) )
     736             :                         {
     737          44 :                             facTabExp[k] = -( ( WORD32_BITS - 1 ) );
     738          44 :                             move16();
     739             :                         }
     740       68652 :                         s2 = s_max( s2, facTabExp[k] );
     741             :                     }
     742             : 
     743       72007 :                     FOR( k = 0; k < hFdCngCom->nFFTpart; k++ )
     744             :                     {
     745       68652 :                         s = sub( facTabExp[k], s2 );
     746       68652 :                         s = s_max( s_min( s, ( WORD32_BITS - 1 ) ), -( ( WORD32_BITS - 1 ) ) );
     747     1020150 :                         FOR( ; j <= hFdCngCom->part[k]; j++ )
     748             :                         {
     749      951498 :                             cngNoiseLevel[j] = L_shl( Mpy_32_16_1( hFdCngDec->bandNoiseShape[j], facTab[k] ), s ); /*Q31 - hFdCngDec->bandNoiseShape_exp*/
     750      951498 :                             move32();
     751             :                         }
     752             :                     }
     753             : 
     754             :                     /* adapt scaling for rest of the buffer */
     755        3355 :                     IF( NE_16( s2, -( WORD32_BITS - 1 ) ) )
     756             :                     {
     757        2480 :                         s = sub( *cngNoiseLevel_exp, add( hFdCngDec->bandNoiseShape_exp, s2 ) );
     758        2480 :                         Word16 e_shift = 0;
     759        2480 :                         move16();
     760        2480 :                         IF( s > 0 )
     761             :                         {
     762          52 :                             Word16 q_norm = L_norm_arr( &cngNoiseLevel[j], sub( FFTCLDFBLEN, j ) );
     763          52 :                             IF( GT_16( s, q_norm ) )
     764             :                             {
     765           0 :                                 scale_sig32( cngNoiseLevel, j, sub( q_norm, s ) ); /*q_norm*/
     766           0 :                                 e_shift = sub( s, q_norm );
     767             :                             }
     768             :                         }
     769      145232 :                         FOR( ; j < FFTCLDFBLEN; j++ )
     770             :                         {
     771      142752 :                             cngNoiseLevel[j] = L_shl( cngNoiseLevel[j], sub( s, e_shift ) ); /*Q: s*/
     772      142752 :                             move32();
     773             :                         }
     774             : 
     775        2480 :                         *cngNoiseLevel_exp = add( add( hFdCngDec->bandNoiseShape_exp, s2 ), e_shift );
     776        2480 :                         move16();
     777             :                     }
     778             :                 }
     779             :                 ELSE
     780             :                 {
     781             :                     /* This sets the new CNG levels until a SID update overwrites it */
     782       45272 :                     test();
     783       45272 :                     test();
     784       45272 :                     test();
     785       45272 :                     IF( !( EQ_16( st->element_mode, IVAS_CPE_TD ) ) || ( EQ_16( st->element_mode, IVAS_CPE_TD ) && !hFdCngDec->flag_dtx_mode && !st->VAD ) )
     786             :                     {
     787       43153 :                         Copy32( hFdCngDec->bandNoiseShape, cngNoiseLevel, nBins ); /*Q31 - hFdCngDec->bandNoiseShape_exp*/
     788       43153 :                         *cngNoiseLevel_exp = hFdCngDec->bandNoiseShape_exp;
     789       43153 :                         move16();
     790             :                     }
     791             :                 }
     792             : 
     793       48627 :                 IF( ( EQ_16( st->element_mode, IVAS_CPE_MDCT ) && timeDomainInput == NULL ) )
     794             :                 {
     795             : 
     796        6028 :                     tmp_loop = sub( hFdCngCom->stopFFTbin, hFdCngCom->startBand );
     797        6028 :                     L_tmp = L_deposit_h( 0 );
     798        6028 :                     L_c = L_deposit_h( 0 );
     799     1922932 :                     FOR( j = 0; j < tmp_loop; j++ )
     800             :                     {
     801             : 
     802     1916904 :                         Carry = 0;
     803     1916904 :                         move16();
     804     1916904 :                         L_tmp = L_add_co( L_tmp, *( cngNoiseLevel + j ), &Carry, &Overflow ); /*Q31*/
     805     1916904 :                         Overflow = 0;
     806     1916904 :                         move16();
     807             : 
     808     1916904 :                         IF( *( cngNoiseLevel + j ) < 0 )
     809             :                         {
     810           0 :                             L_c = L_msuNs( L_c, 0, 0 ); /*Q-1*/
     811             :                         }
     812     1916904 :                         IF( *( cngNoiseLevel + j ) >= 0 )
     813             :                         {
     814     1916904 :                             L_c = L_macNs_co( L_c, 0, 0, &Carry, &Overflow ); /*Q-1*/
     815             :                         }
     816             :                     }
     817        6028 :                     L_tmp = norm_llQ31( L_c, L_tmp, &L_tmp_exp ); /*Q31 - L_tmp_exp*/
     818        6028 :                     L_tmp_exp = sub( add( L_tmp_exp, *cngNoiseLevel_exp ), 1 );
     819             : 
     820        6028 :                     L_tmp = Mpy_32_16_1( L_tmp, 1 ); /*Q16 - L_tmp_exp*/
     821             : 
     822        6028 :                     L_tmp = Mpy_32_16_1( L_tmp, shr( T_DIV_L_Frame[L_shl( L_mac( -28000, NORM_MDCT_FACTOR, 95 ), 1 - 15 )], 1 ) ); /*Q16,exp -7*/
     823        6028 :                     L_tmp_exp = add( L_tmp_exp, -7 );                                                                              /*->Q16, L_tmp_exp */
     824        6028 :                     L_tmp_exp = add( L_tmp_exp, 31 - 16 );                                                                         /*->Q31, L_tmp_exp*/
     825             : 
     826        6028 :                     st->hTcxDec->conCngLevelBackgroundTrace = round_fx_sat( Sqrt32( L_tmp, &L_tmp_exp ) ); /*Q15 - L_tmp_exp*/
     827        6028 :                     move16();
     828        6028 :                     L_tmp_exp = add( L_tmp_exp, 1 );
     829        6028 :                     st->hTcxDec->conCngLevelBackgroundTrace_e = L_tmp_exp;
     830        6028 :                     move16();
     831             :                 }
     832             :                 ELSE
     833             :                 {
     834             : 
     835       42599 :                     tmp_loop = sub( hFdCngCom->stopFFTbin, hFdCngCom->startBand );
     836       42599 :                     L_tmp = L_deposit_h( 0 );
     837       42599 :                     L_c = L_deposit_h( 0 );
     838    12172761 :                     FOR( j = 0; j < tmp_loop; j++ )
     839             :                     {
     840             : 
     841    12130162 :                         Carry = 0;
     842    12130162 :                         move16();
     843    12130162 :                         L_tmp = L_add_co( L_tmp, *( cngNoiseLevel + j ), &Carry, &Overflow ); /*Q31 - L_tmp_exp*/
     844    12130162 :                         Overflow = 0;
     845    12130162 :                         move16();
     846             : 
     847    12130162 :                         IF( *( cngNoiseLevel + j ) < 0 )
     848             :                         {
     849           0 :                             L_c = L_msuNs( L_c, 0, 0 ); /*Q-1*/
     850             :                         }
     851    12130162 :                         IF( *( cngNoiseLevel + j ) >= 0 )
     852             :                         {
     853    12130162 :                             L_c = L_macNs_co( L_c, 0, 0, &Carry, &Overflow ); /*Q-1*/
     854             :                         }
     855             :                     }
     856       42599 :                     L_tmp = norm_llQ31( L_c, L_tmp, &L_tmp_exp ); /*Q31 - L_tmp_exp*/
     857       42599 :                     L_tmp_exp = sub( add( L_tmp_exp, *cngNoiseLevel_exp ), 1 );
     858             : 
     859       42599 :                     L_tmp = Mpy_32_16_1( L_tmp, hFdCngCom->fftlen ); /*Q16 - L_tmp_exp*/
     860             : 
     861       42599 :                     L_tmp = Mpy_32_16_1( L_tmp, T_DIV_L_Frame[L_shl( L_mac( -28000, st->L_frame, 95 ), 1 - 15 )] ); /*Q16,exp -7*/
     862       42599 :                     L_tmp_exp = add( L_tmp_exp, -7 );                                                               /*->Q16, L_tmp_exp */
     863       42599 :                     L_tmp_exp = add( L_tmp_exp, 31 - 16 );                                                          /*->Q31, L_tmp_exp*/
     864             : 
     865       42599 :                     st->hTcxDec->conCngLevelBackgroundTrace = round_fx_sat( Sqrt32( L_tmp, &L_tmp_exp ) ); /*Q15 - L_tmp_exp*/
     866       42599 :                     move16();
     867       42599 :                     st->hTcxDec->conCngLevelBackgroundTrace_e = L_tmp_exp;
     868       42599 :                     move16();
     869             :                 }
     870             : 
     871       48627 :                 tmp_loop = sub( hFdCngCom->stopFFTbin, hFdCngCom->startBand );
     872       48627 :                 L_tmp = L_deposit_h( 0 );
     873       48627 :                 L_c = L_deposit_h( 0 );
     874    14095693 :                 FOR( j = 0; j < tmp_loop; j++ )
     875             :                 {
     876             : 
     877    14047066 :                     Carry = 0;
     878    14047066 :                     move16();
     879    14047066 :                     L_tmp = L_add_co( L_tmp, *( cngNoiseLevel + j ), &Carry, &Overflow ); /*Q31 - L_tmp_exp*/
     880    14047066 :                     Overflow = 0;
     881    14047066 :                     move16();
     882             : 
     883    14047066 :                     IF( *( cngNoiseLevel + j ) < 0 )
     884             :                     {
     885           0 :                         L_c = L_msuNs( L_c, 0, 0 ); /*Q-1*/
     886             :                     }
     887    14047066 :                     IF( *( cngNoiseLevel + j ) >= 0 )
     888             :                     {
     889    14047066 :                         L_c = L_macNs_co( L_c, 0, 0, &Carry, &Overflow ); /*Q-1*/
     890             :                     }
     891             :                 }
     892       48627 :                 L_tmp = norm_llQ31( L_c, L_tmp, &L_tmp_exp ); /*Q31 - L_tmp_exp*/
     893       48627 :                 L_tmp_exp = sub( add( L_tmp_exp, *cngNoiseLevel_exp ), 1 );
     894             : 
     895       48627 :                 L_tmp = Mpy_32_16_1( L_tmp, hFdCngCom->fftlen ); /*Q16 - L_tmp_exp*/
     896             : 
     897       48627 :                 L_tmp = Mpy_32_16_1( L_tmp, T_DIV_L_Frame[L_shl( L_mac( -28000, st->L_frame, 95 ), 1 - 15 )] ); /*Q16,exp -7*/
     898       48627 :                 L_tmp_exp = add( L_tmp_exp, -7 );                                                               /*->Q16, L_tmp_exp */
     899       48627 :                 L_tmp_exp = add( L_tmp_exp, 31 - 16 );                                                          /*->Q31, L_tmp_exp*/
     900             : 
     901       48627 :                 st->cngTDLevel = round_fx_sat( Sqrt32( L_tmp, &L_tmp_exp ) ); /*Q15 - L_tmp_exp*/
     902       48627 :                 move16();
     903       48627 :                 st->cngTDLevel_e = L_tmp_exp;
     904       48627 :                 move16();
     905             :             }
     906      194334 :             ELSE IF( EQ_16( st->element_mode, IVAS_CPE_TD ) || EQ_16( st->element_mode, IVAS_CPE_DFT ) )
     907             :             {
     908       44631 :                 IF( hFdCngCom->active_frame_counter > 0 )
     909             :                 {
     910             :                     /* Perform noise estimation in active frames in the decoder for downward updates */
     911       44236 :                     IF( EQ_16( st->element_mode, EVS_MONO ) )
     912             :                     {
     913           0 :                         perform_noise_estimation_dec_fx( timeDomainInput, Q, hFdCngDec );
     914             :                     }
     915             :                     ELSE
     916             :                     {
     917       44236 :                         perform_noise_estimation_dec_ivas_fx( timeDomainInput, Q, powerSpectrum, Q_power_spectrum, hFdCngDec, st->element_mode, st->bwidth, L_frame, last_L_frame, st->last_core_brate, st->VAD );
     918             :                     }
     919             :                 }
     920             :             }
     921             : 
     922      242961 :             test();
     923      242961 :             IF( EQ_16( concealWholeFrame, 1 ) && EQ_16( st->nbLostCmpt, 1 ) )
     924             :             {
     925             :                 /* always set psychParameters for MDCT-Stereo ... */
     926        3123 :                 test();
     927        3123 :                 IF( EQ_16( st->element_mode, IVAS_CPE_MDCT ) && st->hTonalMDCTConc != NULL )
     928             :                 {
     929        1984 :                     st->hTonalMDCTConc->psychParams = EQ_16( st->core, TCX_20_CORE ) ? &st->hTonalMDCTConc->psychParamsTCX20 : &st->hTonalMDCTConc->psychParamsTCX10;
     930             :                 }
     931             :                 /* update isf cng estimate for concealment. Do that during concealment, in order to avoid addition clean channel complexity*/
     932             : 
     933        3123 :                 L_tmp = 0;
     934        3123 :                 move32();
     935      970765 :                 FOR( j = hFdCngCom->startBand; j < hFdCngCom->stopFFTbin; j++ )
     936             :                 {
     937      967642 :                     L_tmp = L_add_sat( L_tmp, L_shl_sat( cngNoiseLevel[j], sub( 31, *cngNoiseLevel_exp ) ) ); /*Q31*/
     938             :                 }
     939        3123 :                 L_tmp_exp = 0;
     940        3123 :                 move16();
     941        3123 :                 IF( GT_32( L_shl_o( L_tmp, L_tmp_exp, &Overflow ), 21474836 ) /*0.01f Q31*/ )
     942             :                 {
     943        1039 :                     test();
     944        1039 :                     test();
     945        1039 :                     IF( EQ_16( st->element_mode, IVAS_CPE_MDCT ) && NE_16( st->core, ACELP_CORE ) )
     946             :                     {
     947         304 :                         TonalMdctConceal_whiten_noise_shape_ivas_fx( st, L_frame, ON_FIRST_LOST_FRAME );
     948             :                     }
     949         735 :                     ELSE IF( NE_16( st->element_mode, IVAS_CPE_MDCT ) || EQ_16( st->core, ACELP_CORE ) )
     950             :                     {
     951         735 :                         lpc_from_spectrum( hFdCngCom, hFdCngCom->startBand, hFdCngCom->stopFFTbin, 0 );
     952         735 :                         E_LPC_a_lsp_conversion( hFdCngCom->A_cng, lsp_cng, st->lspold_cng, M );
     953         735 :                         Copy( lsp_cng, st->lspold_cng, M ); /*Q15*/
     954             : 
     955         735 :                         lsp2lsf_fx( lsp_cng, st->lsf_cng, M, st->sr_core ); /*x2.56*/
     956             :                     }
     957             : 
     958        1039 :                     st->plcBackgroundNoiseUpdated = 1;
     959        1039 :                     move16();
     960             :                 }
     961             :             }
     962      242961 :             BREAK;
     963             : 
     964        2573 :         case SID_FRAME:
     965             : 
     966        2573 :             hFdCngDec->flag_dtx_mode = 1;
     967        2573 :             move16();
     968             :             /* no break */
     969             : 
     970       18671 :         case ZERO_FRAME:
     971             : 
     972       18671 :             test();
     973       18671 :             IF( st != NULL && EQ_16( st->cng_type, LP_CNG ) )
     974             :             {
     975             :                 /* Perform noise estimation on inactive phase at the decoder */
     976        1141 :                 IF( EQ_16( st->element_mode, EVS_MONO ) )
     977             :                 {
     978           0 :                     perform_noise_estimation_dec_fx( timeDomainInput, Q, hFdCngDec );
     979             :                 }
     980             :                 ELSE
     981             :                 {
     982        1141 :                     perform_noise_estimation_dec_ivas_fx( timeDomainInput, Q, powerSpectrum, Q_power_spectrum, hFdCngDec, st->element_mode, st->bwidth, L_frame, last_L_frame, st->last_core_brate, st->VAD );
     983             :                 }
     984             : 
     985             :                 /* Update the shaping parameters */
     986        1141 :                 test();
     987        1141 :                 IF( EQ_16( st->element_mode, EVS_MONO ) )
     988             :                 {
     989           0 :                     scalebands( hFdCngDec->msNoiseEst, hFdCngDec->part_shaping, hFdCngDec->nFFTpart_shaping, hFdCngDec->midband_shaping, hFdCngDec->nFFTpart_shaping, sub( hFdCngCom->stopFFTbin, hFdCngCom->startBand ), hFdCngDec->bandNoiseShape, 1 );
     990             :                 }
     991        1141 :                 ELSE IF( NE_16( st->element_mode, IVAS_CPE_TD ) && NE_16( st->element_mode, IVAS_CPE_DFT ) )
     992             :                 {
     993           0 :                     scalebands_fx( hFdCngDec->msNoiseEst, hFdCngDec->part_shaping, hFdCngDec->nFFTpart_shaping, hFdCngDec->midband_shaping, hFdCngDec->nFFTpart_shaping, sub( hFdCngCom->stopFFTbin, hFdCngCom->startBand ), hFdCngDec->bandNoiseShape, 1 );
     994             :                 }
     995        1141 :                 hFdCngDec->bandNoiseShape_exp = hFdCngDec->msNoiseEst_exp;
     996        1141 :                 move16();
     997             : 
     998             :                 /* This sets the new CNG levels until a SID update overwrites it */
     999        1141 :                 Copy32( hFdCngDec->bandNoiseShape, cngNoiseLevel, sub( hFdCngCom->stopFFTbin, hFdCngCom->startBand ) ); /* This sets the new CNG levels until a SID update overwrites it */ /*Q31 - hFdCngDec->bandNoiseShape_exp*/
    1000             : 
    1001        1141 :                 IF( EQ_16( st->element_mode, EVS_MONO ) )
    1002             :                 {
    1003           0 :                     *cngNoiseLevel_exp = hFdCngDec->bandNoiseShape_exp;
    1004           0 :                     move16();
    1005             :                 }
    1006             :                 ELSE
    1007             :                 {
    1008        1141 :                     Word16 shift1 = L_norm_arr( cngNoiseLevel, sub( hFdCngCom->stopFFTbin, hFdCngCom->startBand ) );
    1009        1141 :                     Word16 shift2 = L_norm_arr( cngNoiseLevel + sub( hFdCngCom->stopFFTbin, hFdCngCom->startBand ), sub( FFTCLDFBLEN, sub( hFdCngCom->stopFFTbin, hFdCngCom->startBand ) ) );
    1010        1141 :                     Word16 shift = s_max( sub( hFdCngDec->bandNoiseShape_exp, shift1 ), sub( *cngNoiseLevel_exp, shift2 ) );
    1011             : 
    1012        1141 :                     scale_sig32( cngNoiseLevel, sub( hFdCngCom->stopFFTbin, hFdCngCom->startBand ), sub( hFdCngDec->bandNoiseShape_exp, shift ) );
    1013        1141 :                     scale_sig32( cngNoiseLevel + sub( hFdCngCom->stopFFTbin, hFdCngCom->startBand ), sub( FFTCLDFBLEN, sub( hFdCngCom->stopFFTbin, hFdCngCom->startBand ) ), sub( *cngNoiseLevel_exp, shift ) );
    1014             : 
    1015        1141 :                     *cngNoiseLevel_exp = shift;
    1016        1141 :                     move16();
    1017             :                 }
    1018             : 
    1019             :                 /*st->cngTDLevel = (float)sqrt( (sumFLOAT(cngNoiseLevel, hFdCngCom->stopFFTbin - hFdCngCom->startBand) / 2 * hFdCngCom->fftlen) / st->Mode2_L_frame);*/
    1020        1141 :                 tmp_loop = sub( hFdCngCom->stopFFTbin, hFdCngCom->startBand );
    1021        1141 :                 L_tmp = L_deposit_h( 0 );
    1022        1141 :                 L_c = L_deposit_h( 0 );
    1023      328779 :                 FOR( j = 0; j < tmp_loop; j++ )
    1024             :                 {
    1025             : 
    1026      327638 :                     Carry = 0;
    1027      327638 :                     move16();
    1028      327638 :                     L_tmp = L_add_co( L_tmp, *( cngNoiseLevel + j ), &Carry, &Overflow ); /*Q31 - L_tmp_exp*/
    1029      327638 :                     Overflow = 0;
    1030      327638 :                     move16();
    1031             : 
    1032      327638 :                     IF( *( cngNoiseLevel + j ) < 0 )
    1033             :                     {
    1034           0 :                         L_c = L_msuNs_co( L_c, 0, 0, &Carry, &Overflow ); /*Q-1*/
    1035             :                     }
    1036      327638 :                     IF( *( cngNoiseLevel + j ) >= 0 )
    1037             :                     {
    1038      327638 :                         L_c = L_macNs_co( L_c, 0, 0, &Carry, &Overflow ); /*Q-1*/
    1039             :                     }
    1040             :                 }
    1041        1141 :                 L_tmp = norm_llQ31( L_c, L_tmp, &L_tmp_exp ); /*Q31 - L_tmp_exp*/
    1042        1141 :                 L_tmp_exp = sub( add( L_tmp_exp, *cngNoiseLevel_exp ), 1 );
    1043             : 
    1044        1141 :                 L_tmp = Mpy_32_16_1( L_tmp, hFdCngCom->fftlen ); /*Q16 - L_tmp_exp*/
    1045             : 
    1046        1141 :                 L_tmp = Mpy_32_16_1( L_tmp, T_DIV_L_Frame[L_shl( L_mac( -28000, st->L_frame, 95 ), 1 - 15 )] ); /*Q16,exp -7*/
    1047        1141 :                 L_tmp_exp = add( L_tmp_exp, -7 );                                                               /*->Q16, L_tmp_exp */
    1048        1141 :                 L_tmp_exp = add( L_tmp_exp, 31 - 16 );                                                          /*->Q31, L_tmp_exp*/
    1049             : 
    1050        1141 :                 st->cngTDLevel = round_fx_o( Sqrt32( L_tmp, &L_tmp_exp ), &Overflow ); /*Q15 - L_tmp_exp*/
    1051        1141 :                 move16();
    1052        1141 :                 st->cngTDLevel_e = L_tmp_exp;
    1053        1141 :                 move16();
    1054        1141 :                 BREAK;
    1055             :             }
    1056       17530 :             hFdCngCom->inactive_frame_counter = add( hFdCngCom->inactive_frame_counter, 1 );
    1057       17530 :             move16();
    1058             : 
    1059             :             /*************************************
    1060             :              * SID_FRAME or ZERO_FRAME at DECODER *
    1061             :              *************************************/
    1062             : 
    1063             :             /* Detect first non-active frame */
    1064       17530 :             IF( EQ_16( hFdCngCom->inactive_frame_counter, 1 ) )
    1065             :             {
    1066             :                 /* Compute the fine spectral structure of the comfort noise shape using the decoder-side noise estimates */
    1067         451 :                 bandcombinepow(
    1068         451 :                     hFdCngDec->bandNoiseShape,
    1069         451 :                     hFdCngDec->bandNoiseShape_exp,
    1070             :                     nBins,
    1071         451 :                     hFdCngCom->part,
    1072         451 :                     hFdCngCom->nFFTpart,
    1073         451 :                     hFdCngCom->psize_inv,
    1074         451 :                     hFdCngDec->partNoiseShape,
    1075             :                     &hFdCngDec->partNoiseShape_exp );
    1076         451 :                 IF( EQ_16( st->element_mode, IVAS_CPE_DFT ) )
    1077             :                 {
    1078         384 :                     Copy32( hFdCngDec->hFdCngCom->sidNoiseEst, hFdCngDec->hFdCngCom->sidNoiseEstLp, NPART ); /*Q31 - hFdCngDec->sidNoiseEstExp*/
    1079             :                 }
    1080             :             }
    1081             : 
    1082       17530 :             IF( EQ_16( st->m_frame_type, SID_FRAME ) )
    1083             :             {
    1084        2371 :                 IF( LT_32( hFdCngCom->msFrCnt_init_counter, L_deposit_l( hFdCngCom->msFrCnt_init_thresh ) ) )
    1085             :                 {
    1086             :                     /* At initialization, interpolate the bin/band-wise levels from the partition levels */
    1087          56 :                     IF( EQ_16( st->element_mode, EVS_MONO ) )
    1088             :                     {
    1089           0 :                         scalebands( hFdCngCom->sidNoiseEst, hFdCngCom->part, hFdCngCom->npart, hFdCngCom->midband, hFdCngCom->nFFTpart, sub( hFdCngCom->stopBand, hFdCngCom->startBand ), cngNoiseLevel, 1 );
    1090             :                     }
    1091             :                     ELSE
    1092             :                     {
    1093          56 :                         scalebands_fx( hFdCngCom->sidNoiseEst, hFdCngCom->part, hFdCngCom->npart, hFdCngCom->midband, hFdCngCom->nFFTpart, sub( hFdCngCom->stopBand, hFdCngCom->startBand ), cngNoiseLevel, 1 );
    1094             :                     }
    1095             : 
    1096          56 :                     *cngNoiseLevel_exp = hFdCngCom->sidNoiseEstExp;
    1097          56 :                     move16();
    1098             :                 }
    1099             :                 ELSE
    1100             :                 {
    1101        2315 :                     if ( EQ_16( st->element_mode, IVAS_CPE_DFT ) )
    1102             :                     {
    1103        2083 :                         sidNoiseEst = hFdCngCom->sidNoiseEstLp; /*Q31 - hFdCngDec->sidNoiseEstExp*/
    1104             :                     }
    1105             :                     /* Interpolate the CLDFB band levels from the SID (partition) levels */
    1106        2315 :                     IF( GT_16( hFdCngCom->regularStopBand, hFdCngCom->numCoreBands ) )
    1107             :                     {
    1108        1995 :                         IF( EQ_16( st->element_mode, EVS_MONO ) )
    1109             :                         {
    1110           0 :                             scalebands( sidNoiseEst, hFdCngCom->part, hFdCngCom->npart, hFdCngCom->midband, hFdCngCom->nFFTpart, sub( hFdCngCom->stopBand, hFdCngCom->startBand ), cngNoiseLevel, 0 );
    1111             :                         }
    1112             :                         ELSE
    1113             :                         {
    1114        1995 :                             scalebands_fx( sidNoiseEst, hFdCngCom->part, hFdCngCom->npart, hFdCngCom->midband, hFdCngCom->nFFTpart, sub( hFdCngCom->stopBand, hFdCngCom->startBand ), cngNoiseLevel, 0 );
    1115             :                         }
    1116             : 
    1117        1995 :                         *cngNoiseLevel_exp = hFdCngCom->sidNoiseEstExp;
    1118        1995 :                         move16();
    1119             :                     }
    1120             : 
    1121        2315 :                     s2 = -( ( WORD32_BITS - 1 ) );
    1122        2315 :                     move16();
    1123             :                     /* Shape the SID noise levels in each FFT bin */
    1124        2315 :                     j = 0;
    1125        2315 :                     move16();
    1126       50051 :                     FOR( k = 0; k < hFdCngCom->nFFTpart; k++ )
    1127             :                     {
    1128       47736 :                         assert( hFdCngDec->partNoiseShape[k] >= 0 );
    1129             : 
    1130             :                         /* add DELTA as it is done in FLC version, in order to avoid num > denom */
    1131       47736 :                         facTab[k] = 0;
    1132       47736 :                         move16();
    1133       47736 :                         IF( hFdCngDec->partNoiseShape[k] != 0 )
    1134             :                         {
    1135       47448 :                             s1 = norm_l( sidNoiseEst[k] );
    1136       47448 :                             L_tmp = L_shl( sidNoiseEst[k], s1 ); /*Q31 - ( hFdCngCom->sidNoiseEstExp - s1 )*/
    1137       47448 :                             L_tmp_exp = sub( hFdCngCom->sidNoiseEstExp, s1 );
    1138       47448 :                             L_tmp = BASOP_Util_Add_Mant32Exp( sidNoiseEst[k], hFdCngCom->sidNoiseEstExp, DELTA_MANTISSA_W32, DELTA_EXPONENT, &L_tmp_exp );
    1139       47448 :                             L_tmp = L_shr( L_tmp, 1 );
    1140       47448 :                             s = add( L_tmp_exp, 1 );
    1141       47448 :                             num = extract_h( L_tmp ); /*Q15 - L_tmp_exp*/
    1142             : 
    1143       47448 :                             s1 = norm_l( hFdCngDec->partNoiseShape[k] );
    1144       47448 :                             L_tmp = L_shl( hFdCngDec->partNoiseShape[k], s1 ); /*Q31 - ( hFdCngDec->partNoiseShape_ex - s1 )*/
    1145       47448 :                             L_tmp_exp = sub( hFdCngDec->partNoiseShape_exp, s1 );
    1146       47448 :                             L_tmp = BASOP_Util_Add_Mant32Exp( L_tmp, L_tmp_exp, DELTA_MANTISSA_W32, DELTA_EXPONENT, &L_tmp_exp );
    1147       47448 :                             s = sub( s, L_tmp_exp );
    1148       47448 :                             denom = extract_h( L_tmp ); /*Q15 - L_tmp_exp*/
    1149             : 
    1150       47448 :                             facTab[k] = div_s( num, denom ); /*Q15 - s*/
    1151       47448 :                             move16();
    1152       47448 :                             facTabExp[k] = s;
    1153       47448 :                             move16();
    1154             :                         }
    1155             :                         /* Set unique exponent, IF mantissa is equal to zero */
    1156       47736 :                         IF( EQ_16( facTab[k], 0 ) )
    1157             :                         {
    1158         566 :                             facTabExp[k] = -( ( WORD32_BITS - 1 ) );
    1159         566 :                             move16();
    1160             :                         }
    1161       47736 :                         s2 = s_max( s2, facTabExp[k] );
    1162             :                     }
    1163        2315 :                     if ( EQ_16( s2, -31 ) )
    1164             :                     {
    1165         306 :                         s2 = 0;
    1166         306 :                         move16();
    1167             :                     }
    1168       50051 :                     FOR( k = 0; k < hFdCngCom->nFFTpart; k++ )
    1169             :                     {
    1170       47736 :                         s = sub( facTabExp[k], s2 );
    1171       47736 :                         s = s_max( s_min( s, ( WORD32_BITS - 1 ) ), -( ( WORD32_BITS - 1 ) ) );
    1172      727650 :                         FOR( ; j <= hFdCngCom->part[k]; j++ )
    1173             :                         {
    1174      679914 :                             cngNoiseLevel[j] = L_shl( Mpy_32_16_1( hFdCngDec->bandNoiseShape[j], facTab[k] ), s ); /*Q31 - hFdCngDec->bandNoiseShape_exp*/
    1175      679914 :                             move32();
    1176             :                         }
    1177             :                     }
    1178             : 
    1179        2315 :                     IF( EQ_16( st->element_mode, EVS_MONO ) )
    1180             :                     {
    1181             :                         /* adapt scaling for rest of the buffer */
    1182           0 :                         s = sub( *cngNoiseLevel_exp, add( hFdCngDec->bandNoiseShape_exp, s2 ) );
    1183           0 :                         FOR( ; k < hFdCngCom->npart; k++ )
    1184             :                         {
    1185           0 :                             FOR( ; j <= hFdCngCom->part[k]; j++ )
    1186             :                             {
    1187           0 :                                 cngNoiseLevel[j] = L_shl( cngNoiseLevel[j], s ); /*Q31 - hFdCngDec->bandNoiseShape_exp + s*/
    1188           0 :                                 move32();
    1189             :                             }
    1190             :                         }
    1191           0 :                         *cngNoiseLevel_exp = add( hFdCngDec->bandNoiseShape_exp, s2 );
    1192           0 :                         move16();
    1193             :                     }
    1194             :                     ELSE
    1195             :                     {
    1196        2315 :                         Word16 shift1 = L_norm_arr( cngNoiseLevel, j );
    1197        2315 :                         Word16 shift2 = L_norm_arr( &cngNoiseLevel[j], sub( FFTCLDFBLEN, j ) );
    1198        2315 :                         Word16 shift = s_max( sub( add( hFdCngDec->bandNoiseShape_exp, s2 ), shift1 ), sub( *cngNoiseLevel_exp, shift2 ) );
    1199             : 
    1200        2315 :                         scale_sig32( cngNoiseLevel, j, sub( add( hFdCngDec->bandNoiseShape_exp, s2 ), shift ) );
    1201        2315 :                         scale_sig32( &cngNoiseLevel[j], sub( FFTCLDFBLEN, j ), sub( *cngNoiseLevel_exp, shift ) );
    1202             : 
    1203        2315 :                         *cngNoiseLevel_exp = shift;
    1204        2315 :                         move16();
    1205             :                     }
    1206             :                 }
    1207             :             }
    1208       15159 :             ELSE IF( EQ_16( st->element_mode, IVAS_CPE_DFT ) )
    1209             :             {
    1210       13370 :                 IF( !( LT_16( hFdCngCom->msFrCnt_init_counter, hFdCngCom->msFrCnt_init_thresh ) ) )
    1211             :                 {
    1212       13370 :                     s2 = -( ( WORD32_BITS - 1 ) );
    1213             :                     /* Shape the SID noise levels in each FFT bin */
    1214       13370 :                     j = 0;
    1215       13370 :                     move16();
    1216      288976 :                     FOR( k = 0; k < hFdCngCom->nFFTpart; k++ )
    1217             :                     {
    1218      275606 :                         assert( hFdCngDec->partNoiseShape[k] >= 0 );
    1219             : 
    1220             :                         /* add DELTA as it is done in FLC version, in order to avoid num > denom */
    1221      275606 :                         facTab[k] = 0;
    1222      275606 :                         move16();
    1223      275606 :                         IF( hFdCngDec->partNoiseShape[k] != 0 )
    1224             :                         {
    1225      273728 :                             s1 = norm_l( hFdCngCom->sidNoiseEstLp[k] );
    1226      273728 :                             L_tmp = L_shl( hFdCngCom->sidNoiseEstLp[k], s1 ); /*Q31 - ( hFdCngCom->sidNoiseEstExp - s1 )*/
    1227      273728 :                             L_tmp_exp = sub( hFdCngCom->sidNoiseEstExp, s1 );
    1228      273728 :                             L_tmp = BASOP_Util_Add_Mant32Exp( hFdCngCom->sidNoiseEstLp[k], hFdCngCom->sidNoiseEstExp, DELTA_MANTISSA_W32, DELTA_EXPONENT, &L_tmp_exp );
    1229      273728 :                             L_tmp = L_shr( L_tmp, 1 );
    1230      273728 :                             s = add( L_tmp_exp, 1 );
    1231      273728 :                             num = extract_h( L_tmp ); /*Q15 - L_tmp_exp*/
    1232             : 
    1233      273728 :                             s1 = norm_l( hFdCngDec->partNoiseShape[k] );
    1234      273728 :                             L_tmp = L_shl( hFdCngDec->partNoiseShape[k], s1 ); /*Q31 - ( hFdCngDec->partNoiseShape_exp - s1 )*/
    1235      273728 :                             L_tmp_exp = sub( hFdCngDec->partNoiseShape_exp, s1 );
    1236      273728 :                             L_tmp = BASOP_Util_Add_Mant32Exp( L_tmp, L_tmp_exp, DELTA_MANTISSA_W32, DELTA_EXPONENT, &L_tmp_exp );
    1237      273728 :                             s = sub( s, L_tmp_exp );
    1238      273728 :                             denom = extract_h( L_tmp ); /*Q15 - L_tmp_exp*/
    1239             : 
    1240      273728 :                             facTab[k] = div_s( num, denom ); /*Q15 - s*/
    1241      273728 :                             move16();
    1242      273728 :                             facTabExp[k] = s;
    1243      273728 :                             move16();
    1244             :                         }
    1245             :                         /* Set unique exponent, IF mantissa is equal to zero */
    1246      275606 :                         if ( facTab[k] == 0 )
    1247             :                         {
    1248        3056 :                             facTabExp[k] = -( WORD32_BITS - 1 );
    1249        3056 :                             move16();
    1250             :                         }
    1251      275606 :                         s2 = s_max( s2, facTabExp[k] );
    1252             :                     }
    1253       13370 :                     IF( EQ_16( s2, -31 ) )
    1254             :                     {
    1255        3189 :                         s2 = 0;
    1256        3189 :                         move16();
    1257             :                     }
    1258      288976 :                     FOR( k = 0; k < hFdCngCom->nFFTpart; k++ )
    1259             :                     {
    1260      275606 :                         s = sub( facTabExp[k], s2 );
    1261      275606 :                         s = s_max( s_min( s, sub( WORD32_BITS, 1 ) ), negate( sub( WORD32_BITS, 1 ) ) );
    1262     4196770 :                         FOR( ; j <= hFdCngCom->part[k]; j++ )
    1263             :                         {
    1264     3921164 :                             cngNoiseLevel[j] = L_shl( Mpy_32_16_1( hFdCngDec->bandNoiseShape[j], facTab[k] ), s ); /*Q31 - hFdCngDec->bandNoiseShape_exp*/
    1265     3921164 :                             move32();
    1266             :                         }
    1267             :                     }
    1268             : 
    1269       13370 :                     Word16 shift1 = L_norm_arr( cngNoiseLevel, j );
    1270       13370 :                     Word16 shift2 = L_norm_arr( &cngNoiseLevel[j], sub( FFTCLDFBLEN, j ) );
    1271       13370 :                     Word16 shift = s_max( sub( add( hFdCngDec->bandNoiseShape_exp, s2 ), shift1 ), sub( *cngNoiseLevel_exp, shift2 ) );
    1272             : 
    1273       13370 :                     scale_sig32( cngNoiseLevel, j, sub( add( hFdCngDec->bandNoiseShape_exp, s2 ), shift ) );
    1274       13370 :                     scale_sig32( &cngNoiseLevel[j], sub( FFTCLDFBLEN, j ), sub( *cngNoiseLevel_exp, shift ) );
    1275             : 
    1276       13370 :                     *cngNoiseLevel_exp = shift;
    1277       13370 :                     move16();
    1278             :                 }
    1279             :             }
    1280       17530 :             IF( EQ_16( st->codec_mode, MODE2 ) )
    1281             :             {
    1282             :                 /* Generate comfort noise during SID or zero frames */
    1283           0 :                 IF( EQ_16( st->element_mode, EVS_MONO ) )
    1284             :                 {
    1285           0 :                     generate_comfort_noise_dec_fx( cldfbBufferReal, cldfbBufferImag, cldfbBufferScale, st, &( st->Q_exc ), 2, -1 );
    1286             :                 }
    1287             :                 ELSE
    1288             :                 {
    1289           0 :                     generate_comfort_noise_dec_ivas_fx( cldfbBufferReal, cldfbBufferImag, cldfbBufferScale, st, &( st->Q_exc ), 2, -1 );
    1290             :                 }
    1291             :             }
    1292             : 
    1293       17530 :             BREAK;
    1294             : 
    1295           0 :         default:
    1296           0 :             return -1;
    1297             :     }
    1298             : 
    1299             : 
    1300      261632 :     return 0;
    1301             : }
    1302             : 
    1303             : /*
    1304             :    perform_noise_estimation_dec_fx
    1305             : 
    1306             :     Parameters:
    1307             : 
    1308             :     timeDomainInput,      i:   pointer to time domain input
    1309             :     bitrate,              i:   bitrate
    1310             :     st                    i/o: FD_CNG structure containing all buffers and variables
    1311             : 
    1312             :     Function:
    1313             :     perform noise estimation
    1314             : 
    1315             :     Returns:
    1316             :     void
    1317             : */
    1318          15 : void perform_noise_estimation_dec_fx(
    1319             :     const Word16 *timeDomainInput, /* i:   pointer to time domain input Q*/
    1320             :     const Word16 Q,
    1321             :     HANDLE_FD_CNG_DEC hFdCngDec /* i/o: FD_CNG structure containing all buffers and variables */
    1322             : )
    1323             : {
    1324             :     Word16 i, tmp_r, tmp_i, fac, fftBuffer_exp;
    1325             :     Word16 s, len, npart, nFFTpart;
    1326             :     Word16 startBand, stopFFTbin;
    1327             : 
    1328             :     Word16 *part, *psize_inv, *psize_norm;
    1329             :     Word32 tmp, *fftBuffer, *periodog, *ptr_per, *ptr_r, *ptr_i;
    1330             : 
    1331             :     /* pointer initialization */
    1332          15 :     periodog = hFdCngDec->hFdCngCom->periodog;   /*Q31 - hFdCngDec->hFdCngCom->periodog_exp*/
    1333          15 :     fftBuffer = hFdCngDec->hFdCngCom->fftBuffer; /*Q31 - hFdCngDec->hFdCngCom->fftBuffer_exp*/
    1334             : 
    1335          15 :     part = hFdCngDec->part_shaping;             /*Q0*/
    1336          15 :     psize_inv = hFdCngDec->psize_inv_shaping;   /*Q15*/
    1337          15 :     psize_norm = hFdCngDec->psize_shaping_norm; /*Q15 - hFdCngDec->psize_shaping_norm_exp*/
    1338             : 
    1339             :     /* variable initialization */
    1340          15 :     startBand = hFdCngDec->hFdCngCom->startBand; /*Q0*/
    1341          15 :     move16();
    1342          15 :     stopFFTbin = hFdCngDec->hFdCngCom->stopFFTbin; /*Q0*/
    1343          15 :     move16();
    1344             : 
    1345          15 :     npart = hFdCngDec->npart_shaping; /*Q0*/
    1346          15 :     move16();
    1347          15 :     nFFTpart = hFdCngDec->nFFTpart_shaping; /*Q0*/
    1348          15 :     move16();
    1349             : 
    1350             :     /* Perform STFT analysis */
    1351             :     /* Perform STFT analysis */
    1352          15 :     AnalysisSTFT( timeDomainInput, Q, fftBuffer, &fftBuffer_exp, hFdCngDec->hFdCngCom );
    1353          15 :     fftBuffer_exp = add( fftBuffer_exp, WORD16_BITS - 1 );
    1354             : 
    1355             :     {
    1356          15 :         assert( startBand != 0 );
    1357             : 
    1358          15 :         len = sub( stopFFTbin, startBand );
    1359             : 
    1360          15 :         s = getScaleFactor32( &fftBuffer[( startBand * 2 )], shl( len, 1 ) );
    1361          15 :         s = sub( s, 1 );
    1362             : 
    1363          15 :         ptr_per = periodog;
    1364          15 :         IF( startBand == 0 )
    1365             :         {
    1366             :             /* DC component */
    1367           0 :             tmp_r = extract_h( L_shl( fftBuffer[0], s ) ); /*Q15 - fftBuffer_exp + s*/
    1368             : 
    1369           0 :             tmp = L_mult( tmp_r, tmp_r ); /*Q31 - 2*(fftBuffer_exp - s)*/
    1370           0 :             *ptr_per = tmp;               /*Q31 - 2*(fftBuffer_exp - s)*/
    1371           0 :             move32();
    1372             : 
    1373           0 :             ptr_per++;
    1374           0 :             ptr_r = fftBuffer + 2; /*Q31 - fftBuffer_exp*/
    1375           0 :             len = sub( len, 1 );
    1376             :         }
    1377             :         ELSE
    1378             :         {
    1379          15 :             ptr_r = fftBuffer + shl( startBand, 1 ); /*fftBuffer_exp*/
    1380             :         }
    1381             : 
    1382          15 :         ptr_i = ptr_r + 1;
    1383        4337 :         FOR( i = 0; i < len; i++ )
    1384             :         {
    1385        4322 :             tmp_r = extract_h( L_shl( *ptr_r, s ) ); /*Q15 - fftBuffer_exp + s*/
    1386        4322 :             tmp_i = extract_h( L_shl( *ptr_i, s ) ); /*Q15 - fftBuffer_exp + s*/
    1387             : 
    1388        4322 :             tmp = L_mac( L_mult( tmp_r, tmp_r ), tmp_i, tmp_i ); /*Q31 - 2*(fftBuffer_exp - s)*/
    1389        4322 :             *ptr_per = tmp;                                      /*Q31 - 2*(fftBuffer_exp - s)*/
    1390        4322 :             move32();
    1391             : 
    1392        4322 :             ptr_r += 2;
    1393        4322 :             ptr_i += 2;
    1394        4322 :             ptr_per++;
    1395             :         }
    1396             : 
    1397          15 :         hFdCngDec->hFdCngCom->periodog_exp = shl( sub( fftBuffer_exp, s ), 1 );
    1398          15 :         move16();
    1399             : 
    1400             :         /* Rescale */
    1401          15 :         assert( ( hFdCngDec->hFdCngCom->fftlen == 640 ) || ( hFdCngDec->hFdCngCom->fftlen == 512 ) || ( hFdCngDec->hFdCngCom->fftlen == 320 ) );
    1402             : 
    1403          15 :         fac = 20972 /*0.64 Q15*/;
    1404          15 :         move16();
    1405          15 :         if ( EQ_16( hFdCngDec->hFdCngCom->fftlen, 512 ) )
    1406             :         {
    1407           7 :             fac = 16384 /*0.5 Q15*/;
    1408           7 :             move16();
    1409             :         }
    1410             : 
    1411          15 :         if ( EQ_16( hFdCngDec->hFdCngCom->fftlen, 640 ) )
    1412             :         {
    1413           8 :             s = 18;
    1414           8 :             move16();
    1415             :         }
    1416          15 :         if ( EQ_16( hFdCngDec->hFdCngCom->fftlen, 512 ) )
    1417             :         {
    1418           7 :             s = 17;
    1419           7 :             move16();
    1420             :         }
    1421          15 :         if ( EQ_16( hFdCngDec->hFdCngCom->fftlen, 320 ) )
    1422             :         {
    1423           0 :             s = 16;
    1424           0 :             move16();
    1425             :         }
    1426             : 
    1427          15 :         len = sub( stopFFTbin, startBand );
    1428        4337 :         FOR( i = 0; i < len; i++ )
    1429             :         {
    1430        4322 :             hFdCngDec->hFdCngCom->periodog[i] = Mpy_32_16_1( hFdCngDec->hFdCngCom->periodog[i], fac ); /*Q31 - hFdCngDec->hFdCngCom->periodog_exp*/
    1431        4322 :             move32();
    1432             :         }
    1433          15 :         hFdCngDec->hFdCngCom->periodog_exp = add( hFdCngDec->hFdCngCom->periodog_exp, sub( 2, s ) );
    1434          15 :         move16();
    1435             : 
    1436             :         /* Adjust to the desired frequency resolution by averaging over spectral partitions for SID transmission */
    1437          15 :         bandcombinepow( periodog, hFdCngDec->hFdCngCom->periodog_exp, sub( stopFFTbin, startBand ), part, npart, psize_inv, hFdCngDec->msPeriodog, &hFdCngDec->msPeriodog_exp );
    1438             : 
    1439             : 
    1440          15 :         hFdCngDec->msPeriodog_exp_fft = hFdCngDec->msPeriodog_exp;
    1441          15 :         move16();
    1442          15 :         hFdCngDec->msPeriodog_exp_cldfb = hFdCngDec->msPeriodog_exp;
    1443          15 :         move16();
    1444             : 
    1445             : 
    1446             :         /* Compress MS inputs */
    1447          15 :         compress_range( hFdCngDec->msPeriodog, hFdCngDec->msPeriodog_exp, hFdCngDec->msLogPeriodog, npart );
    1448             : 
    1449             :         /* Call the minimum statistics routine for noise estimation */
    1450          15 :         minimum_statistics(
    1451             :             npart,
    1452             :             nFFTpart,
    1453             :             psize_norm,
    1454          15 :             hFdCngDec->msLogPeriodog,
    1455          15 :             hFdCngDec->msNoiseFloor,
    1456          15 :             hFdCngDec->msLogNoiseEst,
    1457          15 :             hFdCngDec->msAlpha,
    1458          15 :             hFdCngDec->msPsd,
    1459          15 :             hFdCngDec->msPsdFirstMoment,
    1460          15 :             hFdCngDec->msPsdSecondMoment,
    1461          15 :             hFdCngDec->msMinBuf,
    1462          15 :             hFdCngDec->msBminWin,
    1463          15 :             hFdCngDec->msBminSubWin,
    1464          15 :             hFdCngDec->msCurrentMin,
    1465          15 :             hFdCngDec->msCurrentMinOut,
    1466          15 :             hFdCngDec->msCurrentMinSubWindow,
    1467          15 :             hFdCngDec->msLocalMinFlag,
    1468          15 :             hFdCngDec->msNewMinFlag,
    1469          15 :             hFdCngDec->msPeriodogBuf,
    1470             :             &( hFdCngDec->msPeriodogBufPtr ),
    1471             :             hFdCngDec->hFdCngCom );
    1472             : 
    1473             :         /* Expand MS outputs */
    1474          15 :         expand_range( hFdCngDec->msLogNoiseEst, hFdCngDec->msNoiseEst, &hFdCngDec->msNoiseEst_exp, npart );
    1475             :     }
    1476          15 : }
    1477             : 
    1478       93989 : void perform_noise_estimation_dec_ivas_fx(
    1479             :     const Word16 *timeDomainInput, /* i:   pointer to time domain input Q*/
    1480             :     const Word16 Q,
    1481             :     Word32 *power_spectrum, /*Q_power_spectrum*/
    1482             :     Word16 Q_power_spectrum,
    1483             :     HANDLE_FD_CNG_DEC hFdCngDec,  /* i/o: FD_CNG structure containing all buffers and variables */
    1484             :     const Word16 element_mode,    /* i  : element mode                                          Q0*/
    1485             :     const Word16 bwidth,          /* i  : audio bandwidth                                       Q0*/
    1486             :     const Word16 L_frame,         /* i  : frame length at internal Fs                           Q0*/
    1487             :     const Word16 last_L_frame,    /* i  : frame length of the last frame at internal Fs         Q0*/
    1488             :     const Word32 last_core_brate, /* i  : previous frame core bitrate                           Q0*/
    1489             :     const Word16 VAD              /* i  : VAD flag in the decoder                               Q0*/
    1490             : )
    1491             : {
    1492       93989 :     Word16 i, p, fftBuffer_exp = 0;
    1493             :     Word16 npart, nFFTpart;
    1494             :     Word16 startBand, stopFFTbin;
    1495             : 
    1496             :     Word16 *part, *psize_inv, *psize_norm;
    1497             :     Word32 *fftBuffer, *periodog, *ptr_per, *ptr_r, *ptr_i;
    1498             :     Word32 temp, ftemp, delta, L_tmp;
    1499             :     Word16 e_temp, wght, periodog_exp;
    1500             :     Word32 enr, enr_tot, enr_tot0;
    1501             :     Word16 enr_e, enr_ratio, alpha;
    1502             :     Word32 *msPeriodog;
    1503             :     Word32 *msNoiseEst;
    1504             :     Word32 *reIter;
    1505       93989 :     Word32 rescale_fac = 0;
    1506             :     Word64 W_tmp;
    1507       93989 :     Word16 tmp_s, tmp_q, min_q = 31;
    1508             :     Word16 q_shift;
    1509             :     Word32 max_l;
    1510             :     Word16 norm_shift;
    1511             : 
    1512             :     /* pointer initialization */
    1513       93989 :     periodog = hFdCngDec->hFdCngCom->periodog;   /*Q31 - hFdCngDec->hFdCngCom->periodog_exp*/
    1514       93989 :     fftBuffer = hFdCngDec->hFdCngCom->fftBuffer; /*Q31 - hFdCngDec->hFdCngCom->fftBuffer_exp*/
    1515       93989 :     ptr_per = periodog;                          /*Q31 - hFdCngDec->hFdCngCom->periodog_exp*/
    1516       93989 :     msPeriodog = hFdCngDec->msPeriodog;          /*Q31 - hFdCngDec->msPeriodog_exp*/
    1517       93989 :     msNoiseEst = hFdCngDec->msNoiseEst;          /*Q31 - hFdCngDec->msNoiseEst_exp*/
    1518             : 
    1519       93989 :     part = hFdCngDec->part_shaping;             /*Q0*/
    1520       93989 :     psize_inv = hFdCngDec->psize_inv_shaping;   /*Q15*/
    1521       93989 :     psize_norm = hFdCngDec->psize_shaping_norm; /*Q15 - hFdCngDec->psize_shaping_norm_exp*/
    1522             : 
    1523             :     /* variable initialization */
    1524       93989 :     startBand = hFdCngDec->hFdCngCom->startBand;
    1525       93989 :     move16();
    1526       93989 :     stopFFTbin = hFdCngDec->hFdCngCom->stopFFTbin;
    1527       93989 :     move16();
    1528             : 
    1529       93989 :     npart = hFdCngDec->npart_shaping;
    1530       93989 :     move16();
    1531       93989 :     nFFTpart = hFdCngDec->nFFTpart_shaping;
    1532       93989 :     move16();
    1533             : 
    1534             :     /* Perform STFT analysis */
    1535       93989 :     test();
    1536       93989 :     IF( !( EQ_16( element_mode, IVAS_CPE_MDCT ) && power_spectrum != NULL ) )
    1537             :     {
    1538             :         /* Perform STFT analysis */
    1539       87961 :         AnalysisSTFT_fx( timeDomainInput, Q, fftBuffer, &fftBuffer_exp, hFdCngDec->hFdCngCom );
    1540             :     }
    1541             : 
    1542       93989 :     test();
    1543       93989 :     IF( EQ_16( element_mode, IVAS_CPE_TD ) || EQ_16( element_mode, IVAS_CPE_DFT ) )
    1544             :     {
    1545       51851 :         SWITCH( hFdCngDec->hFdCngCom->fftlen )
    1546             :         {
    1547       28061 :             case 640:
    1548       28061 :                 rescale_fac = 335544; // 4/(640 * 640) in Q35
    1549       28061 :                 move32();
    1550       28061 :                 BREAK;
    1551       23790 :             case 512:
    1552       23790 :                 rescale_fac = 524288; // 4/(512 * 512) in Q35
    1553       23790 :                 move32();
    1554       23790 :                 BREAK;
    1555           0 :             case 320:
    1556           0 :                 rescale_fac = 1342177; // 4/(320 * 320) in Q35
    1557           0 :                 move32();
    1558           0 :                 BREAK;
    1559           0 :             default:
    1560           0 :                 assert( 0 );
    1561             :         }
    1562             :         /* Calculate periodogram (squared magnitude in each FFT bin) */
    1563       51851 :         IF( startBand == 0 )
    1564             :         {
    1565           0 :             W_tmp = W_mult0_32_32( fftBuffer[0], fftBuffer[0] ); /*Q31 - 2*fftBuffer_exp*/
    1566           0 :             tmp_s = W_norm( W_tmp );
    1567           0 :             ( *ptr_per ) = W_extract_h( W_shl( W_tmp, tmp_s ) ); /*tmp_q*/
    1568           0 :             tmp_q = sub( add( i_mult( sub( 31, fftBuffer_exp ), 2 ), tmp_s ), 32 );
    1569           0 :             min_q = tmp_q;
    1570           0 :             move16();
    1571           0 :             ptr_per++;
    1572           0 :             ptr_r = fftBuffer + 2; /*Q31 - fftBuffer_exp*/
    1573             :         }
    1574             :         ELSE
    1575             :         {
    1576       51851 :             ptr_r = fftBuffer + i_mult( 2, startBand ); /*Q31 - fftBuffer_exp*/
    1577             :         }
    1578             : 
    1579       51851 :         ptr_i = ptr_r + 1; /*Q31 - fftBuffer_exp*/
    1580             : 
    1581    15014133 :         FOR( ; ptr_per < periodog + sub( stopFFTbin, startBand ); ptr_per++ )
    1582             :         {
    1583    14962282 :             W_tmp = W_add( W_mult0_32_32( ( *ptr_r ), ( *ptr_r ) ), W_mult0_32_32( ( *ptr_i ), ( *ptr_i ) ) ); /*Q31 - 2*(fftBuffer_exp)*/
    1584             : 
    1585    14962282 :             tmp_s = W_norm( W_tmp );
    1586    14962282 :             tmp_q = sub( add( i_mult( sub( 31, fftBuffer_exp ), 2 ), tmp_s ), 32 );
    1587    14962282 :             *ptr_per = W_extract_h( W_shl( W_tmp, tmp_s ) ); /*tmp_q*/
    1588    14962282 :             IF( LT_16( tmp_q, min_q ) )
    1589             :             {
    1590      178022 :                 reIter = ptr_per; /*tmp_q*/
    1591             :                 Word16 diff;
    1592      178022 :                 diff = sub( min_q, tmp_q );
    1593             : 
    1594     1797549 :                 WHILE( reIter > periodog )
    1595             :                 {
    1596     1619527 :                     reIter--;
    1597     1619527 :                     *reIter = L_shr( *reIter, diff ); /*tmp_q*/
    1598     1619527 :                     move32();
    1599             :                 }
    1600      178022 :                 min_q = tmp_q;
    1601      178022 :                 move16();
    1602             :             }
    1603             :             ELSE
    1604             :             {
    1605             :                 Word16 diff;
    1606    14784260 :                 diff = sub( tmp_q, min_q );
    1607    14784260 :                 ( *ptr_per ) = L_shr( ( *ptr_per ), diff ); /*min_q*/
    1608             :             }
    1609             : 
    1610             :             /* Rescale to get energy/sample: it should be 2*(1/N)*(2/N), parseval relation with 1/N,*2 for nrg computed till Nyquist only, 2/N as windowed samples correspond to half a frame*/
    1611    14962282 :             ( *ptr_per ) = Mpy_32_32_r( ( *ptr_per ), rescale_fac ); // Q = min_q+36-31=min_q+5
    1612    14962282 :             move32();
    1613             : 
    1614    14962282 :             ptr_r += 2;
    1615    14962282 :             ptr_i += 2;
    1616             :         }
    1617             : 
    1618       51851 :         hFdCngDec->hFdCngCom->periodog_exp = sub( 31 - 4, min_q );
    1619       51851 :         hFdCngDec->hFdCngCom->fftBuffer_exp = fftBuffer_exp;
    1620       51851 :         move16();
    1621       51851 :         move16();
    1622             : 
    1623       51851 :         tmp_s = getScaleFactor32( periodog, sub( stopFFTbin, startBand ) );
    1624       51851 :         IF( GT_16( tmp_s, 7 ) )
    1625             :         {
    1626       51811 :             tmp_s = sub( tmp_s, 7 );
    1627       51811 :             hFdCngDec->hFdCngCom->periodog_exp = sub( hFdCngDec->hFdCngCom->periodog_exp, tmp_s );
    1628       51811 :             move16();
    1629    15001501 :             FOR( p = 0; p < stopFFTbin - startBand; p++ )
    1630             :             {
    1631    14949690 :                 periodog[p] = L_shl( periodog[p], tmp_s ); /*Q31 - hFdCngDec->hFdCngCom->periodog_exp*/
    1632    14949690 :                 move32();
    1633             :             }
    1634             :         }
    1635             : 
    1636             :         /* Combine bins of power spectrum into partitions */
    1637       51851 :         i = 0;
    1638       51851 :         move16();
    1639     3238611 :         FOR( p = 0; p < npart; p++ )
    1640             :         {
    1641             : 
    1642             :             /* calculate mean over all bins in power partition */
    1643     3186760 :             temp = 0;
    1644     3186760 :             move16();
    1645    18149042 :             FOR( ; i <= part[p]; i++ )
    1646             :             {
    1647    14962282 :                 temp = L_add( temp, periodog[i] ); /*Q31 - hFdCngDec->hFdCngCom->periodog_exp*/
    1648             :             }
    1649     3186760 :             msPeriodog[p] = Mpy_32_16_1( temp, psize_inv[p] ); /*Q31 - hFdCngDec->hFdCngCom->periodog_exp*/
    1650     3186760 :             move32();
    1651             :         }
    1652             : 
    1653       51851 :         hFdCngDec->msPeriodog_exp = hFdCngDec->hFdCngCom->periodog_exp;
    1654       51851 :         move16();
    1655             : 
    1656             :         /* compensate for the loss of variance - don't do when first noise update is not completed yet due to risk of msPeriodog[p] < 0 */
    1657       51851 :         IF( hFdCngDec->first_cna_noise_updated )
    1658             :         {
    1659       22032 :             i = 0;
    1660       22032 :             move16();
    1661             : 
    1662             :             /* This is done to avoid overflow when checking "if ( msPeriodog[p] < 1e-5f )" */
    1663       22032 :             IF( LT_16( hFdCngDec->msPeriodog_exp, -16 ) )
    1664             :             {
    1665           0 :                 FOR( p = 0; p < NPART_SHAPING; p++ )
    1666             :                 {
    1667           0 :                     msPeriodog[p] = L_shr( msPeriodog[p], sub( -16, hFdCngDec->msPeriodog_exp ) ); /*Q31 - (-16)*/
    1668           0 :                     move32();
    1669             :                 }
    1670           0 :                 hFdCngDec->msPeriodog_exp = -16;
    1671           0 :                 move16();
    1672             :             }
    1673             : 
    1674     1376515 :             FOR( p = 0; p < npart; p++ )
    1675             :             {
    1676             :                 /* calculate variance over all bins in power partition */
    1677     1354483 :                 temp = 0;
    1678     1354483 :                 move32();
    1679     1354483 :                 W_tmp = 0;
    1680     1354483 :                 move64();
    1681     7686675 :                 FOR( ; i <= part[p]; i++ )
    1682             :                 {
    1683     6332192 :                     delta = L_sub( periodog[i], msPeriodog[p] );           /*Q31 - hFdCngDec->hFdCngCom->periodog_exp*/
    1684     6332192 :                     W_tmp = W_add( W_tmp, W_mult0_32_32( delta, delta ) ); /*Q31 - 2*(hFdCngDec->hFdCngCom->periodog_exp)*/
    1685             :                 }
    1686     1354483 :                 tmp_s = W_norm( W_tmp );
    1687     1354483 :                 temp = W_extract_h( W_shl( W_tmp, tmp_s ) ); // Q = 63 - 2*(31-exp) - tmp_s
    1688             : 
    1689     1354483 :                 temp = Mpy_32_16_1( temp, psize_inv[p] ); // Qtemp
    1690             : 
    1691             :                 /* compensate for the loss of variance */
    1692     1354483 :                 e_temp = sub( 63, add( i_mult( sub( 31, hFdCngDec->hFdCngCom->periodog_exp ), 2 ), tmp_s ) );
    1693     1354483 :                 temp = Sqrt32( temp, &e_temp ); /*Q31 - e_temp*/
    1694     1354483 :                 IF( LT_16( e_temp, 0 ) )
    1695             :                 {
    1696      785901 :                     temp = L_shr( temp, abs_s( e_temp ) ); /*Q31*/
    1697      785901 :                     e_temp = 0;
    1698      785901 :                     move16();
    1699             :                 }
    1700             : 
    1701     1354483 :                 ftemp = rand_gauss( &hFdCngDec->cna_seed ); /*Q29*/
    1702             : 
    1703     1354483 :                 L_tmp = Mpy_32_32( temp, ftemp );                                                    /*Q29*/
    1704     1354483 :                 L_tmp = L_shr( L_tmp, sub( sub( hFdCngDec->hFdCngCom->periodog_exp, e_temp ), 2 ) ); /*Q31 - hFdCngDec->msPeriodog_exp*/
    1705             : 
    1706     1354483 :                 msPeriodog[p] = L_add( msPeriodog[p], L_tmp ); /*Q31 - hFdCngDec->msPeriodog_exp*/
    1707     1354483 :                 move32();
    1708             : 
    1709     1354483 :                 IF( LT_32( msPeriodog[p], L_shr( 21474 /*Q31*/, hFdCngDec->msPeriodog_exp ) ) )
    1710             :                 {
    1711       67030 :                     msPeriodog[p] = L_shr( 21474 /*Q31*/, hFdCngDec->msPeriodog_exp ); /*Q31 - hFdCngDec->msPeriodog_exp*/
    1712       67030 :                     move32();
    1713             :                 }
    1714             :             }
    1715             :         }
    1716             : 
    1717             :         /* calculate total energy (short-term and long-term) */
    1718       51851 :         tmp_s = getScaleFactor32( msPeriodog, npart );
    1719       51851 :         IF( LT_16( tmp_s, 5 ) )
    1720             :         {
    1721        2482 :             FOR( p = 0; p < npart; p++ )
    1722             :             {
    1723        2442 :                 msPeriodog[p] = L_shr( msPeriodog[p], sub( 5, tmp_s ) ); /*Q31 - hFdCngDec->msPeriodog_exp - 5 + tmp_s*/
    1724        2442 :                 move32();
    1725             :             }
    1726          40 :             hFdCngDec->msPeriodog_exp = add( hFdCngDec->msPeriodog_exp, sub( 5, tmp_s ) );
    1727          40 :             move16();
    1728             :         }
    1729       51851 :         enr_tot = 1;
    1730       51851 :         move32();
    1731       51851 :         enr_tot0 = 1;
    1732       51851 :         move32();
    1733       51851 :         IF( GE_16( hFdCngDec->msNoiseEst_exp, hFdCngDec->msPeriodog_exp ) )
    1734             :         {
    1735         527 :             enr_tot = L_add_sat( L_shr( sum32_fx( msPeriodog, npart ), sub( hFdCngDec->msNoiseEst_exp, hFdCngDec->msPeriodog_exp ) ), 1 ); /*Q31 - hFdCngDec->msNoiseEst_exp*/
    1736         527 :             enr_tot0 = L_add_sat( sum32_fx( msNoiseEst, npart ), 1 );
    1737             :         }
    1738       51324 :         ELSE IF( LT_16( hFdCngDec->msNoiseEst_exp, hFdCngDec->msPeriodog_exp ) )
    1739             :         {
    1740       51324 :             enr_tot = L_add_sat( sum32_fx( msPeriodog, npart ), 1 );
    1741       51324 :             enr_tot0 = L_add_sat( L_shr( sum32_fx( msNoiseEst, npart ), sub( hFdCngDec->msPeriodog_exp, hFdCngDec->msNoiseEst_exp ) ), 1 ); /*Q31 - hFdCngDec->msPeriodog_exp*/
    1742             :         }
    1743             : 
    1744             :         /* update short-term periodogram on larger partitions */
    1745       51851 :         maximum_32_fx( &msPeriodog[CNA_ACT_DN_LARGE_PARTITION], sub( npart, CNA_ACT_DN_LARGE_PARTITION ), &max_l );
    1746       51851 :         q_shift = sub( hFdCngDec->hFdCngCom->periodog_exp, hFdCngDec->msPeriodog_ST_exp );
    1747       51851 :         norm_shift = norm_l( max_l );
    1748       51851 :         test();
    1749       51851 :         IF( max_l && GT_16( q_shift, norm_shift ) )
    1750             :         {
    1751        3782 :             scale_sig32( hFdCngDec->msPeriodog_ST_fx, NPART_SHAPING, sub( norm_shift, q_shift ) ); /*Q31 - hFdCngDec->msPeriodog_ST_exp + ( norm_shift - q_shift )*/
    1752        3782 :             hFdCngDec->msPeriodog_ST_exp = sub( hFdCngDec->msPeriodog_ST_exp, sub( norm_shift, q_shift ) );
    1753        3782 :             move16();
    1754        3782 :             q_shift = norm_shift;
    1755        3782 :             move16();
    1756             :         }
    1757      646061 :         FOR( p = CNA_ACT_DN_LARGE_PARTITION; p < npart; p++ )
    1758             :         {
    1759      594210 :             test();
    1760      594210 :             q_shift = sub( hFdCngDec->hFdCngCom->periodog_exp, hFdCngDec->msPeriodog_ST_exp );
    1761      594210 :             IF( NE_16( L_frame, last_L_frame ) || LE_32( last_core_brate, SID_2k40 ) )
    1762             :             {
    1763             :                 /* core Fs has changed or last frame was SID/NO_DATA -> re-initialize short-term periodogram */
    1764       20578 :                 hFdCngDec->msPeriodog_ST_fx[p] = L_shl( msPeriodog[p], q_shift ); /*Q31 - hFdCngDec->hFdCngCom->periodog_exp*/
    1765       20578 :                 move32();
    1766             :             }
    1767             :             ELSE
    1768             :             {
    1769      573632 :                 temp = L_shl( msPeriodog[p], q_shift );                                                                                                                  /*Q31 - hFdCngDec->hFdCngCom->periodog_exp*/
    1770      573632 :                 hFdCngDec->msPeriodog_ST_fx[p] = Madd_32_16( Mpy_32_16_1( hFdCngDec->msPeriodog_ST_fx[p], ST_PERIODOG_FACT_Q15 ), temp, MAX_16 - ST_PERIODOG_FACT_Q15 ); /*Q31 - hFdCngDec->msPeriodog_ST_exp*/
    1771      573632 :                 move32();
    1772             :             }
    1773             :         }
    1774       51851 :         maximum_32_fx( hFdCngDec->msPeriodog_ST_fx, NPART_SHAPING, &max_l );
    1775       51851 :         IF( max_l )
    1776             :         {
    1777       51851 :             q_shift = sub( norm_l( max_l ), 2 );
    1778       51851 :             scale_sig32( hFdCngDec->msPeriodog_ST_fx, NPART_SHAPING, q_shift ); /*Q31 - hFdCngDec->msPeriodog_ST_exp + q_shift*/
    1779       51851 :             hFdCngDec->msPeriodog_ST_exp = sub( hFdCngDec->msPeriodog_ST_exp, q_shift );
    1780       51851 :             move16();
    1781             :         }
    1782             : 
    1783             :         /* core Fs has changed -> partitions have changed -> re-calculate long-term periodogram */
    1784             :         /* part L_FRAME16k L_FRAME */
    1785             :         /* ...                     */
    1786             :         /* [55] 146        146     */
    1787             :         /* [56] 174        160     */
    1788             :         /* [57] 210        174     */
    1789             :         /* [58] 254        190     */
    1790             :         /* [59] 306        210     */
    1791             :         /* [60] 317        230     */
    1792             :         /* [61]            253     */
    1793             : 
    1794       51851 :         test();
    1795       51851 :         test();
    1796       51851 :         IF( EQ_16( last_L_frame, L_FRAME16k ) && EQ_16( L_frame, L_FRAME ) )
    1797             :         {
    1798         546 :             msNoiseEst[61] = msNoiseEst[58]; /*Q31 - hFdCngDec->msNoiseEst_exp*/
    1799         546 :             move32();
    1800         546 :             msNoiseEst[60] = L_min( msNoiseEst[58], msNoiseEst[57] ); /*Q31 - hFdCngDec->msNoiseEst_exp*/
    1801         546 :             move32();
    1802         546 :             msNoiseEst[59] = msNoiseEst[57]; /*Q31 - hFdCngDec->msNoiseEst_exp*/
    1803         546 :             move32();
    1804         546 :             msNoiseEst[58] = msNoiseEst[56]; /*Q31 - hFdCngDec->msNoiseEst_exp*/
    1805         546 :             move32();
    1806         546 :             msNoiseEst[57] = msNoiseEst[56]; /*Q31 - hFdCngDec->msNoiseEst_exp*/
    1807         546 :             move32();
    1808         546 :             msNoiseEst[56] = L_min( msNoiseEst[56], msNoiseEst[55] ); /*Q31 - hFdCngDec->msNoiseEst_exp*/
    1809         546 :             move32();
    1810             :         }
    1811       51305 :         ELSE IF( EQ_16( last_L_frame, L_FRAME ) && EQ_16( L_frame, L_FRAME16k ) )
    1812             :         {
    1813         123 :             msNoiseEst[56] = L_min( msNoiseEst[56], msNoiseEst[57] ); /*Q31 - hFdCngDec->msNoiseEst_exp*/
    1814         123 :             move32();
    1815         123 :             msNoiseEst[57] = L_min( msNoiseEst[58], msNoiseEst[59] ); /*Q31 - hFdCngDec->msNoiseEst_exp*/
    1816         123 :             move32();
    1817         123 :             msNoiseEst[58] = L_min( msNoiseEst[60], msNoiseEst[61] ); /*Q31 - hFdCngDec->msNoiseEst_exp*/
    1818         123 :             move32();
    1819         123 :             msNoiseEst[59] = 0; /*Q31 - hFdCngDec->msNoiseEst_exp*/
    1820         123 :             move32();
    1821         123 :             msNoiseEst[60] = 0; /*Q31 - hFdCngDec->msNoiseEst_exp*/
    1822         123 :             move32();
    1823         123 :             msNoiseEst[61] = 0; /*Q31 - hFdCngDec->msNoiseEst_exp*/
    1824         123 :             move32();
    1825             : 
    1826         123 :             hFdCngDec->ms_cnt_bw_up = FIRST_CNA_NOISE_UPD_FRAMES;
    1827         123 :             move16();
    1828             :         }
    1829             : 
    1830             :         /* Smooth with IIR filter */
    1831       51851 :         IF( !hFdCngDec->first_cna_noise_updated )
    1832             :         {
    1833       29819 :             IF( !VAD )
    1834             :             {
    1835         548 :                 Word16 e = 15;
    1836         548 :                 move16();
    1837             :                 /* background noise update with moving average */
    1838         548 :                 IF( hFdCngDec->first_cna_noise_update_cnt != 0 )
    1839             :                 {
    1840         352 :                     alpha = Inv16( add( hFdCngDec->first_cna_noise_update_cnt, 1 ), &e ); /*Q15*/
    1841         352 :                     alpha = shl_sat( alpha, e );                                          // Q15
    1842         352 :                     maximum_32_fx( msPeriodog, npart, &max_l );
    1843         352 :                     q_shift = sub( hFdCngDec->hFdCngCom->periodog_exp, hFdCngDec->msNoiseEst_exp );
    1844         352 :                     norm_shift = norm_l( max_l );
    1845         352 :                     test();
    1846         352 :                     IF( max_l && GT_16( q_shift, norm_shift ) )
    1847             :                     {
    1848          10 :                         scale_sig32( msNoiseEst, NPART_SHAPING, sub( norm_shift, q_shift ) ); /*Q31 - hFdCngDec->msNoiseEst_exp + ( norm_shift - q_shift )*/
    1849          10 :                         hFdCngDec->msNoiseEst_exp = sub( hFdCngDec->msNoiseEst_exp, sub( norm_shift, q_shift ) );
    1850          10 :                         move16();
    1851          10 :                         q_shift = norm_shift;
    1852          10 :                         move16();
    1853             :                     }
    1854       21992 :                     FOR( p = 0; p < npart; p++ )
    1855             :                     {
    1856       21640 :                         temp = L_shl( msPeriodog[p], q_shift );
    1857       21640 :                         msNoiseEst[p] = Madd_32_16( Mpy_32_16_1( msNoiseEst[p], sub( MAX_16, alpha ) ), temp, alpha ); /*Q31 - hFdCngDec->msNoiseEst_exp*/
    1858       21640 :                         move32();
    1859             :                     }
    1860             :                 }
    1861             :                 ELSE
    1862             :                 {
    1863         196 :                     Copy32( msPeriodog, msNoiseEst, npart );
    1864             : 
    1865         196 :                     Word16 shift1 = L_norm_arr( msNoiseEst, npart );
    1866         196 :                     Word16 shift2 = L_norm_arr( &msNoiseEst[npart], sub( NPART_SHAPING, npart ) );
    1867         196 :                     Word16 shift = s_max( sub( hFdCngDec->msPeriodog_exp, shift1 ), sub( hFdCngDec->msNoiseEst_exp, shift2 ) );
    1868             : 
    1869         196 :                     scale_sig32( msNoiseEst, npart, sub( hFdCngDec->msPeriodog_exp, shift ) );
    1870         196 :                     scale_sig32( &msNoiseEst[npart], sub( NPART_SHAPING, npart ), sub( hFdCngDec->msNoiseEst_exp, shift ) );
    1871             : 
    1872         196 :                     hFdCngDec->msNoiseEst_exp = shift;
    1873         196 :                     move16();
    1874             :                 }
    1875             : 
    1876             :                 /* check, if we reached the required number of first CNA noise update frames */
    1877         548 :                 IF( LT_16( hFdCngDec->first_cna_noise_update_cnt, FIRST_CNA_NOISE_UPD_FRAMES - 1 ) )
    1878             :                 {
    1879         493 :                     hFdCngDec->first_cna_noise_update_cnt = add( hFdCngDec->first_cna_noise_update_cnt, 1 ); /*Q0*/
    1880         493 :                     move16();
    1881             :                 }
    1882             :                 ELSE
    1883             :                 {
    1884          55 :                     hFdCngDec->first_cna_noise_updated = 1;
    1885          55 :                     move16();
    1886          55 :                     if ( EQ_16( hFdCngDec->hFdCngCom->msFrCnt_init_counter, 0 ) )
    1887             :                     {
    1888          47 :                         hFdCngDec->hFdCngCom->msFrCnt_init_counter = 1;
    1889          47 :                         move16();
    1890             :                     }
    1891             :                 }
    1892             :             }
    1893             :             ELSE
    1894             :             {
    1895       29271 :                 hFdCngDec->first_cna_noise_update_cnt = 0;
    1896       29271 :                 move16();
    1897             :             }
    1898             :         }
    1899             :         ELSE
    1900             :         {
    1901       22032 :             hFdCngDec->hFdCngCom->msFrCnt_init_counter = 1;
    1902       22032 :             move16();
    1903       22032 :             IF( VAD )
    1904             :             {
    1905             :                 Word16 scale;
    1906             :                 /* no updates during active frames except for significant energy drops */
    1907       18287 :                 enr_ratio = BASOP_Util_Divide3232_Scale( enr_tot, enr_tot0, &scale ); /*Q15 - scale*/
    1908       18287 :                 IF( scale <= 0 )
    1909             :                 {
    1910         912 :                     enr_ratio = shl( enr_ratio, scale ); /*Q15*/
    1911         912 :                     scale = 15;
    1912         912 :                     move16();
    1913             :                 }
    1914             :                 ELSE
    1915             :                 {
    1916       17375 :                     scale = sub( 15, scale );
    1917             :                 }
    1918       18287 :                 IF( LT_16( enr_ratio, shl( 1, sub( scale, 1 ) ) ) )
    1919             :                 {
    1920             :                     /* total energy significantly decreases during active frames -> downward update */
    1921         720 :                     wght = lin_interp_fx( enr_ratio, 0, shr( 26214, sub( 15, scale ) ) /*0.8f in Q15*/, shr( 16384, sub( 15, scale ) ) /*0.5f in Q15*/, shr( 31130, sub( 15, scale ) ) /*0.95f in Q15*/, shr( 32767, sub( 15, scale ) ) /*1 in Q15*/ ); /*scale*/
    1922             :                     Word16 temp_q_msNoiseEst[NPART_SHAPING];
    1923         720 :                     Word16 min_q_msNoiseEst = MAX_16;
    1924         720 :                     move16();
    1925       45360 :                     FOR( p = 0; p < NPART_SHAPING; p++ )
    1926             :                     {
    1927       44640 :                         temp_q_msNoiseEst[p] = hFdCngDec->msNoiseEst_exp;
    1928       44640 :                         move16();
    1929             :                     }
    1930       44983 :                     FOR( p = 0; p < npart; p++ )
    1931             :                     {
    1932       44263 :                         L_tmp = L_shr( msPeriodog[p], sub( sub( 31, hFdCngDec->hFdCngCom->periodog_exp ), 4 ) );
    1933       44263 :                         IF( LT_32( L_tmp, msNoiseEst[p] ) )
    1934             :                         {
    1935       42915 :                             msNoiseEst[p] = Madd_32_16( Mpy_32_16_1( msNoiseEst[p], wght ), L_tmp, (Word16) L_sub( shr( MAX_16, sub( 15, scale ) ), wght ) ); /*temp_q_msNoiseEst[p]*/
    1936       42915 :                             move32();
    1937       42915 :                             temp_q_msNoiseEst[p] = sub( add( hFdCngDec->msNoiseEst_exp, scale ), 15 );
    1938       42915 :                             move16();
    1939             :                         }
    1940       44263 :                         min_q_msNoiseEst = s_min( temp_q_msNoiseEst[p], min_q_msNoiseEst );
    1941             :                     }
    1942       45360 :                     FOR( p = 0; p < NPART_SHAPING; p++ )
    1943             :                     {
    1944       44640 :                         msNoiseEst[p] = L_shl( msNoiseEst[p], sub( min_q_msNoiseEst, temp_q_msNoiseEst[p] ) ); /*min_q_msNoiseEst*/
    1945       44640 :                         move32();
    1946             :                     }
    1947         720 :                     hFdCngDec->msNoiseEst_exp = min_q_msNoiseEst;
    1948         720 :                     move16();
    1949             :                 }
    1950             :                 ELSE
    1951             :                 {
    1952             :                     /* energy significantly decreases in one of the larger partitions during active frames -> downward update */
    1953      219348 :                     FOR( p = CNA_ACT_DN_LARGE_PARTITION; p < npart; p++ )
    1954             :                     {
    1955      201781 :                         L_tmp = L_shr_sat( hFdCngDec->msPeriodog_ST_fx[p], sub( hFdCngDec->msNoiseEst_exp, hFdCngDec->msPeriodog_ST_exp ) ); /*Q31 - hFdCngDec->msPeriodog_ST_exp*/
    1956      201781 :                         IF( LT_32( L_tmp, msNoiseEst[p] ) )
    1957             :                         {
    1958       16330 :                             msNoiseEst[p] = Madd_32_16( Mpy_32_16_1( msNoiseEst[p], CNA_ACT_DN_FACT_Q15 ), L_tmp, ONE_IN_Q15 - CNA_ACT_DN_FACT_Q15 ); /*Q31 - hFdCngDec->msNoiseEst_exp*/
    1959       16330 :                             move32();
    1960             :                         }
    1961             :                     }
    1962             :                 }
    1963             :             }
    1964             :             ELSE
    1965             :             {
    1966        3745 :                 test();
    1967        3745 :                 if ( GE_16( bwidth, WB ) && hFdCngDec->ms_last_inactive_bwidth == NB )
    1968             :                 {
    1969             :                     /* bandwidth increased -> set counter for fast initilization  */
    1970          52 :                     hFdCngDec->ms_cnt_bw_up = FIRST_CNA_NOISE_UPD_FRAMES;
    1971          52 :                     move16();
    1972             :                 }
    1973        3745 :                 hFdCngDec->ms_last_inactive_bwidth = bwidth;
    1974        3745 :                 move16();
    1975             :                 /* update background noise during inactive frames */
    1976        3745 :                 ptr_per = msNoiseEst; /*Q31 - hFdCngDec->msNoiseEst_exp*/
    1977      233834 :                 FOR( p = 0; p < npart; p++ )
    1978             :                 {
    1979      230089 :                     Word16 i_e = 15;
    1980      230089 :                     move16();
    1981      230089 :                     enr = msPeriodog[p]; /*Q31 - hFdCngDec->msPeriodog_exp*/
    1982      230089 :                     move32();
    1983      230089 :                     enr_e = hFdCngDec->msPeriodog_exp;
    1984      230089 :                     move16();
    1985      230089 :                     alpha = 31130; // 0.95f in Q15
    1986      230089 :                     move16();
    1987             :                     /* bandwidth increased -> do fast re-initilization  */
    1988      230089 :                     test();
    1989      230089 :                     IF( GT_16( hFdCngDec->ms_cnt_bw_up, 0 ) && GT_16( p, 55 ) )
    1990             :                     {
    1991        1905 :                         alpha = Inv16( add( hFdCngDec->ms_cnt_bw_up, 1 ), &i_e ); /*Q15 - i_e*/
    1992        1905 :                         IF( i_e < 0 )
    1993             :                         {
    1994        1905 :                             alpha = shr( alpha, negate( i_e ) ); // Q15
    1995             :                         }
    1996             :                     }
    1997      228184 :                     ELSE IF( ( BASOP_Util_Cmp_Mant32Exp( enr, enr_e, *ptr_per, hFdCngDec->msNoiseEst_exp ) < 0 ) && EQ_16( part[p], 1 ) )
    1998             :                     {
    1999             :                         /* faster downward update for single-bin partitions */
    2000        1136 :                         alpha = 26214; // 0.8f in Q15
    2001        1136 :                         move16();
    2002             :                     }
    2003      227048 :                     ELSE IF( BASOP_Util_Cmp_Mant32Exp( enr, enr_e, *ptr_per, add( hFdCngDec->msNoiseEst_exp, 1 ) ) > 0 )
    2004             :                     {
    2005             :                         /* prevent abrupt upward updates */
    2006       98889 :                         test();
    2007       98889 :                         IF( ( norm_l( *ptr_per ) == 0 ) && *ptr_per )
    2008             :                         {
    2009          18 :                             enr = *ptr_per; /*Q31 - hFdCngDec->msNoiseEst_exp*/
    2010          18 :                             scale_sig32( msNoiseEst, NPART_SHAPING, -1 );
    2011          18 :                             hFdCngDec->msNoiseEst_exp = add( hFdCngDec->msNoiseEst_exp, 1 );
    2012          18 :                             move16();
    2013             :                         }
    2014             :                         ELSE
    2015             :                         {
    2016       98871 :                             enr = L_shl( *ptr_per, 1 ); /*Q31 - hFdCngDec->msNoiseEst_exp*/
    2017             :                         }
    2018       98889 :                         enr_e = hFdCngDec->msNoiseEst_exp;
    2019       98889 :                         move16();
    2020             :                     }
    2021             : 
    2022             :                     /* IIR smoothing */
    2023      230089 :                     test();
    2024      230089 :                     IF( *ptr_per != 0 && alpha != 0 )
    2025             :                     {
    2026      229361 :                         *ptr_per = Mpy_32_16_1( ( *ptr_per ), alpha ); /*Q31 - hFdCngDec->msNoiseEst_exp*/
    2027      229361 :                         move32();
    2028      229361 :                         if ( *ptr_per == 0 )
    2029             :                         {
    2030          62 :                             *ptr_per = 1;
    2031          62 :                             move32();
    2032             :                         }
    2033             :                     }
    2034             :                     ELSE
    2035             :                     {
    2036         728 :                         *ptr_per = 0;
    2037         728 :                         move32();
    2038             :                     }
    2039      230089 :                     IF( enr )
    2040             :                     {
    2041      218868 :                         q_shift = sub( enr_e, hFdCngDec->msNoiseEst_exp );
    2042      218868 :                         norm_shift = norm_l( enr );
    2043      218868 :                         IF( LE_16( q_shift, norm_shift ) )
    2044             :                         {
    2045      218868 :                             enr = L_shl( enr, q_shift ); /*Q31 - hFdCngDec->msNoiseEst_exp + q_shift*/
    2046      218868 :                             move32();
    2047             :                         }
    2048             :                         ELSE
    2049             :                         {
    2050           0 :                             enr_e = sub( enr_e, norm_shift );
    2051           0 :                             enr = L_shl( enr, norm_shift );                                       /*Q31 - hFdCngDec->msNoiseEst_exp + norm_shift*/
    2052           0 :                             scale_sig32( msNoiseEst, NPART_SHAPING, sub( norm_shift, q_shift ) ); /*Q31 - ( hFdCngDec->msNoiseEst_exp - ( norm_shift - q_shift ) )*/
    2053           0 :                             hFdCngDec->msNoiseEst_exp = sub( hFdCngDec->msNoiseEst_exp, sub( norm_shift, q_shift ) );
    2054           0 :                             move16();
    2055             :                         }
    2056             :                     }
    2057      230089 :                     *ptr_per = Madd_32_16( ( *ptr_per ), enr, sub( MAX_16, alpha ) ); /*Q31 - enr_e*/
    2058      230089 :                     move32();
    2059      230089 :                     ptr_per++;
    2060             :                 }
    2061             : 
    2062        3745 :                 IF( hFdCngDec->ms_cnt_bw_up > 0 )
    2063             :                 {
    2064         357 :                     hFdCngDec->ms_cnt_bw_up = sub( hFdCngDec->ms_cnt_bw_up, 1 );
    2065         357 :                     move16();
    2066             :                 }
    2067             :             }
    2068             :         }
    2069       51851 :         maximum_32_fx( msNoiseEst, NPART_SHAPING, &max_l );
    2070       51851 :         IF( max_l )
    2071             :         {
    2072       24631 :             q_shift = sub( norm_l( max_l ), 2 );
    2073       24631 :             scale_sig32( msNoiseEst, NPART_SHAPING, q_shift ); /*Q31 - ( hFdCngDec->msNoiseEst_exp - q_shift )*/
    2074       24631 :             hFdCngDec->msNoiseEst_exp = sub( hFdCngDec->msNoiseEst_exp, q_shift );
    2075       24631 :             move16();
    2076             :         }
    2077             : 
    2078       51851 :         Copy32( msNoiseEst, hFdCngDec->msPsd_fx, npart ); /*Q31 - ( hFdCngDec->msNoiseEst_exp )*/
    2079       51851 :         hFdCngDec->msPsd_exp_fft = hFdCngDec->msNoiseEst_exp;
    2080       51851 :         move16();
    2081             : 
    2082             :         /* Expand partitions into bins of power spectrum */
    2083       51851 :         scalebands_fx( msNoiseEst, part, nFFTpart, hFdCngDec->midband_shaping, nFFTpart, sub( stopFFTbin, startBand ), hFdCngDec->bandNoiseShape, 1 );
    2084       51851 :         hFdCngDec->bandNoiseShape_exp = hFdCngDec->msNoiseEst_exp;
    2085       51851 :         move16();
    2086       51851 :         Copy32( hFdCngDec->bandNoiseShape, &hFdCngDec->smoothed_psd_fx[startBand], sub( stopFFTbin, startBand ) ); /*Q31 - hFdCngDec->bandNoiseShape_exp*/
    2087       51851 :         hFdCngDec->smoothed_psd_exp = hFdCngDec->bandNoiseShape_exp;
    2088       51851 :         move16();
    2089       51851 :         set32_fx( &hFdCngDec->smoothed_psd_fx[stopFFTbin], 0, sub( L_FRAME16k, stopFFTbin ) );
    2090             :     }
    2091             :     ELSE
    2092             :     {
    2093       42138 :         test();
    2094       42138 :         IF( EQ_16( element_mode, IVAS_CPE_MDCT ) && power_spectrum != NULL )
    2095             :         {
    2096             :             /* use power spectrum calculated in the MDCT-domain instead of calculating new power spectrum */
    2097        6028 :             periodog = power_spectrum; /*Q_power_spectrum*/
    2098        6028 :             periodog_exp = sub( 31, Q_power_spectrum );
    2099             :         }
    2100             :         ELSE
    2101             :         {
    2102             :             /* Compute the squared magnitude in each FFT bin */
    2103       36110 :             IF( startBand == 0 )
    2104             :             {
    2105           0 :                 W_tmp = W_mult0_32_32( fftBuffer[0], fftBuffer[0] ); /* DC component */ /*Q31 - 2*fftBuffer_exp*/
    2106           0 :                 min_q = 2;
    2107           0 :                 move16();
    2108           0 :                 ( *ptr_per ) = W_extract_l( W_shr( W_tmp, sub( i_mult( sub( 31, fftBuffer_exp ), 2 ), min_q ) ) );
    2109           0 :                 move32();
    2110           0 :                 ptr_per++;
    2111           0 :                 ptr_r = fftBuffer + 2; /*Q31 - fftBuffer_exp*/
    2112             :             }
    2113             :             ELSE
    2114             :             {
    2115       36110 :                 ptr_r = fftBuffer + i_mult( 2, startBand ); /*Q31 - fftBuffer_exp*/
    2116             :             }
    2117             : 
    2118       36110 :             ptr_i = ptr_r + 1; /*Q31 - fftBuffer_exp*/
    2119             : 
    2120       36110 :             SWITCH( hFdCngDec->hFdCngCom->fftlen )
    2121             :             {
    2122       16851 :                 case 640:
    2123       16851 :                     rescale_fac = 20972; // 4/(640 * 640) in Q31
    2124       16851 :                     move32();
    2125       16851 :                     BREAK;
    2126       19259 :                 case 512:
    2127       19259 :                     rescale_fac = 32768; // 4/(512 * 512) in Q31
    2128       19259 :                     move32();
    2129       19259 :                     BREAK;
    2130           0 :                 case 320:
    2131           0 :                     rescale_fac = 83886; // 4/(320 * 320) in Q31
    2132           0 :                     move32();
    2133           0 :                     BREAK;
    2134           0 :                 default:
    2135           0 :                     assert( 0 );
    2136             :             }
    2137             : 
    2138    10286514 :             FOR( ; ptr_per < periodog + stopFFTbin - startBand; ptr_per++ )
    2139             :             {
    2140    10250404 :                 W_tmp = W_add( W_mult0_32_32( ( *ptr_r ), ( *ptr_r ) ), W_mult0_32_32( ( *ptr_i ), ( *ptr_i ) ) ); /*Q31 - 2*(fftBuffer_exp)*/
    2141             : 
    2142    10250404 :                 tmp_s = W_norm( W_tmp ); /*tmp_q*/
    2143    10250404 :                 tmp_q = sub( add( i_mult( sub( 31, fftBuffer_exp ), 2 ), tmp_s ), 32 );
    2144    10250404 :                 IF( tmp_q < 0 )
    2145             :                 {
    2146      195471 :                     W_tmp = W_shr( W_tmp, negate( tmp_q ) ); /*Q31 - 2*(fftBuffer_exp) + tmp_q*/
    2147             :                 }
    2148    10250404 :                 IF( LT_16( tmp_q, min_q ) )
    2149             :                 {
    2150      244000 :                     reIter = ptr_per; /*tmp_q*/
    2151             :                     Word16 diff;
    2152      244000 :                     IF( ( tmp_q <= 0 ) )
    2153             :                     {
    2154      200048 :                         diff = min_q;
    2155      200048 :                         move16();
    2156             :                     }
    2157             :                     ELSE
    2158             :                     {
    2159       43952 :                         diff = sub( min_q, tmp_q );
    2160             :                     }
    2161     4678436 :                     WHILE( reIter > periodog )
    2162             :                     {
    2163     4434436 :                         reIter--;
    2164     4434436 :                         *reIter = L_shr( *reIter, diff ); /*tmp_q*/
    2165     4434436 :                         move32();
    2166             :                     }
    2167      244000 :                     IF( tmp_q >= 0 )
    2168             :                     {
    2169       48529 :                         min_q = tmp_q;
    2170       48529 :                         move16();
    2171             :                     }
    2172      195471 :                     ELSE IF( tmp_q < 0 )
    2173             :                     {
    2174      195471 :                         min_q = 0;
    2175      195471 :                         move16();
    2176             :                     }
    2177             :                 }
    2178    10250404 :                 ( *ptr_per ) = W_extract_l( W_shr( W_tmp, sub( i_mult( sub( 31, fftBuffer_exp ), 2 ), min_q ) ) ); // Q = min_q
    2179    10250404 :                 move32();
    2180             : 
    2181             :                 /* Rescale to get energy/sample: it should be 2*(1/N)*(2/N), parseval relation with 1/N,*2 for nrg computed till Nyquist only, 2/N as windowed samples correspond to half a frame*/
    2182    10250404 :                 ( *ptr_per ) = Mpy_32_32_r( ( *ptr_per ), rescale_fac ); // Q = min_q
    2183    10250404 :                 move32();
    2184    10250404 :                 IF( tmp_q <= 0 )
    2185             :                 {
    2186      266083 :                     ( *ptr_per ) = L_shl( ( *ptr_per ), negate( tmp_q ) );
    2187      266083 :                     move32();
    2188             :                 }
    2189             : 
    2190    10250404 :                 ptr_r += 2;
    2191    10250404 :                 ptr_i += 2;
    2192             :             }
    2193             : 
    2194       36110 :             hFdCngDec->hFdCngCom->periodog_exp = sub( 31, min_q );
    2195       36110 :             move16();
    2196       36110 :             hFdCngDec->hFdCngCom->fftBuffer_exp = fftBuffer_exp;
    2197       36110 :             move16();
    2198             : 
    2199       36110 :             tmp_s = getScaleFactor32( periodog, L_frame );
    2200       36110 :             IF( GT_16( tmp_s, 3 ) )
    2201             :             {
    2202       24902 :                 tmp_s = sub( tmp_s, 3 );
    2203       24902 :                 hFdCngDec->hFdCngCom->periodog_exp = sub( hFdCngDec->hFdCngCom->periodog_exp, tmp_s );
    2204       24902 :                 move16();
    2205     6712122 :                 FOR( p = 0; p < stopFFTbin - startBand; p++ )
    2206             :                 {
    2207     6687220 :                     periodog[p] = L_shl( periodog[p], tmp_s ); /*Q31 - hFdCngDec->hFdCngCom->periodog_exp + tmp_s*/
    2208     6687220 :                     move32();
    2209             :                 }
    2210             :             }
    2211       36110 :             periodog_exp = hFdCngDec->hFdCngCom->periodog_exp;
    2212       36110 :             move16();
    2213             :         }
    2214             : 
    2215             :         /* Adjust to the desired frequency resolution by averaging over spectral partitions for SID transmission */
    2216       42138 :         bandcombinepow( periodog, periodog_exp, sub( stopFFTbin, startBand ), part, npart, psize_inv, hFdCngDec->msPeriodog, &hFdCngDec->msPeriodog_exp );
    2217             : 
    2218             : 
    2219       42138 :         hFdCngDec->msPeriodog_exp_fft = hFdCngDec->msPeriodog_exp;
    2220       42138 :         move16();
    2221       42138 :         hFdCngDec->msPeriodog_exp_cldfb = hFdCngDec->msPeriodog_exp;
    2222       42138 :         move16();
    2223             : 
    2224             : 
    2225             :         /* Compress MS inputs */
    2226       42138 :         compress_range( hFdCngDec->msPeriodog, hFdCngDec->msPeriodog_exp, hFdCngDec->msLogPeriodog, npart );
    2227             : 
    2228             :         /* Call the minimum statistics routine for noise estimation */
    2229       42138 :         minimum_statistics_fx(
    2230             :             npart,
    2231             :             nFFTpart,
    2232             :             psize_norm,
    2233       42138 :             hFdCngDec->msLogPeriodog,
    2234       42138 :             hFdCngDec->msNoiseFloor,
    2235       42138 :             hFdCngDec->msLogNoiseEst,
    2236       42138 :             hFdCngDec->msAlpha,
    2237       42138 :             hFdCngDec->msPsd,
    2238       42138 :             hFdCngDec->msPsdFirstMoment,
    2239       42138 :             hFdCngDec->msPsdSecondMoment,
    2240       42138 :             hFdCngDec->msMinBuf,
    2241       42138 :             hFdCngDec->msBminWin,
    2242       42138 :             hFdCngDec->msBminSubWin,
    2243       42138 :             hFdCngDec->msCurrentMin,
    2244       42138 :             hFdCngDec->msCurrentMinOut,
    2245       42138 :             hFdCngDec->msCurrentMinSubWindow,
    2246       42138 :             hFdCngDec->msLocalMinFlag,
    2247       42138 :             hFdCngDec->msNewMinFlag,
    2248       42138 :             hFdCngDec->msPeriodogBuf,
    2249             :             &( hFdCngDec->msPeriodogBufPtr ),
    2250             :             hFdCngDec->hFdCngCom,
    2251             :             DEC, element_mode );
    2252             : 
    2253     2631815 :         FOR( i = 0; i < hFdCngDec->npart_shaping; i++ )
    2254             :         {
    2255     2589677 :             hFdCngDec->msPsd_fx[i] = (Word32) hFdCngDec->msPsd[i];
    2256     2589677 :             move32();
    2257             :         }
    2258       42138 :         hFdCngDec->msPsd_exp_fft = 6 + WORD16_BITS;
    2259       42138 :         move16();
    2260             : 
    2261             :         /* Expand MS outputs */
    2262       42138 :         expand_range( hFdCngDec->msLogNoiseEst, hFdCngDec->msNoiseEst, &hFdCngDec->msNoiseEst_exp, npart );
    2263             :     }
    2264       93989 : }
    2265             : 
    2266             : 
    2267             : /*
    2268             :    FdCng_decodeSID_fx
    2269             : 
    2270             :     Parameters:
    2271             : 
    2272             :     st               i/o: FD_CNG structure containing all buffers and variables
    2273             :     bs_word16        i  : Bitstream
    2274             :     amrwb_io         i  : amr wideband mode
    2275             :     preemph_fac      i  : preemphase factor
    2276             : 
    2277             :     Function:
    2278             :     decode the FD-CNG bitstream
    2279             : 
    2280             :     Returns:
    2281             :     void
    2282             : */
    2283           0 : void FdCng_decodeSID_fx( HANDLE_FD_CNG_COM st, Decoder_State *corest )
    2284             : {
    2285             :     Word16 i, N, index;
    2286             :     Word32 *sidNoiseEst;
    2287             : 
    2288             :     Word16 indices[32], v16[32];
    2289             :     Word32 v[32], gain;
    2290             : 
    2291             :     Word32 tmp, maxVal, E_ExpLd64;
    2292             :     Word16 sidNoiseEst_Exp;
    2293             : 
    2294             :     Word16 preemph_fac;
    2295             :     Word32 *invTrfMatrix_fx;
    2296             :     Word32 tmpRAM_fx[FDCNG_VQ_MAX_LEN][FDCNG_VQ_DCT_MAXTRUNC];
    2297           0 :     invTrfMatrix_fx = (Word32 *) tmpRAM_fx;
    2298             : 
    2299             : 
    2300           0 :     sidNoiseEst = st->sidNoiseEst; /*Q31 - st->sidNoiseEstExp*/
    2301           0 :     move16();
    2302           0 :     preemph_fac = corest->preemph_fac; /*Q15*/
    2303           0 :     move16();
    2304             : 
    2305           0 :     N = st->npart; /*Q0*/
    2306           0 :     move16();
    2307             : 
    2308           0 :     st->sid_frame_counter = add( st->sid_frame_counter, 1 ); /*Q15*/
    2309           0 :     move16();
    2310             : 
    2311             :     /* Read bitstream */
    2312           0 :     FOR( i = 0; i < stages_37bits; i++ )
    2313             :     {
    2314           0 :         indices[i] = get_next_indice_fx( corest, bits_37bits[i] ); /*Q0*/
    2315           0 :         move16();
    2316             :     }
    2317           0 :     index = get_next_indice_fx( corest, 7 ); /*Q0*/
    2318             : 
    2319             :     /* MSVQ decoder */
    2320           0 :     IF( corest->element_mode != EVS_MONO )
    2321             :     {
    2322           0 :         create_IDCT_N_Matrix_fx( invTrfMatrix_fx, FDCNG_VQ_MAX_LEN, FDCNG_VQ_DCT_MAXTRUNC, FDCNG_VQ_MAX_LEN * FDCNG_VQ_DCT_MAXTRUNC );
    2323           0 :         msvq_dec_fx( ivas_cdk_37bits_fx, NULL, NULL, stages_37bits, N, maxN_37bits, indices, 1, invTrfMatrix_fx, v, NULL, 7 );
    2324             :     }
    2325             :     ELSE
    2326             :     {
    2327           0 :         msvq_decoder(
    2328             :             cdk_37bits,
    2329             :             stages_37bits,
    2330             :             N,
    2331             :             maxN_37bits,
    2332             :             indices,
    2333             :             v16 );
    2334             : 
    2335           0 :         FOR( i = 0; i < N; i++ )
    2336             :         {
    2337           0 :             v[i] = L_deposit_h( v16[i] ); /*Q23*/
    2338           0 :             move32();
    2339             :         }
    2340             :     }
    2341             : 
    2342             : 
    2343             :     /* decode gain, format gain: Q9.23 */
    2344           0 :     gain = L_shl( L_deposit_l( index ), WORD32_BITS - 1 - 8 );
    2345           0 :     gain = L_sub( gain, 503316480l /*60.0 Q23*/ );       /*Q23*/
    2346           0 :     gain = Mpy_32_16_1( gain, 21845 /*2.0f/3.0f Q15*/ ); /*Q23*/
    2347             : 
    2348             : 
    2349             :     /* Apply gain and undo log */
    2350             : 
    2351             :     /* calculate worst case for scaling */
    2352           0 :     maxVal = L_add( 0x80000000 /*-1.0 Q31*/, 0 );
    2353           0 :     FOR( i = 0; i < N; i++ )
    2354             :     {
    2355           0 :         maxVal = L_max( maxVal, v[i] ); /*Q23*/
    2356             :     }
    2357             : 
    2358           0 :     maxVal = L_add( maxVal, gain );                                          /*Q23*/
    2359           0 :     maxVal = L_shl( Mpy_32_16_1( maxVal, 21771 /*0.66438561897 Q15*/ ), 1 ); /*Q23*/
    2360             : 
    2361           0 :     sidNoiseEst_Exp = 0;
    2362           0 :     move16();
    2363           0 :     FOR( ; maxVal >= 0; maxVal -= 33554432l /*0.015625 Q31*/ )
    2364             :     {
    2365           0 :         sidNoiseEst_Exp = add( sidNoiseEst_Exp, 1 );
    2366             :     }
    2367           0 :     st->sidNoiseEstExp = sidNoiseEst_Exp;
    2368           0 :     move16();
    2369           0 :     E_ExpLd64 = L_shl( sidNoiseEst_Exp, WORD32_BITS - 1 - LD_DATA_SCALE );
    2370             : 
    2371             :     /* format v: Q9.23, format sidNoiseEst: Q6.26, 0.66438561897 = log10(10)/log10(2.0) / 10.0 * 2.0 */
    2372           0 :     FOR( i = 0; i < N; i++ )
    2373             :     {
    2374           0 :         tmp = L_add( v[i], gain );                                         /*Q23*/
    2375           0 :         tmp = L_shl( Mpy_32_16_1( tmp, 21771 /*0.66438561897 Q15*/ ), 1 ); /*Q23*/
    2376           0 :         tmp = L_sub( tmp, E_ExpLd64 );
    2377           0 :         assert( tmp < 0 );
    2378           0 :         st->sidNoiseEst[i] = BASOP_Util_InvLog2( tmp ); /*Q31 - st->sidNoiseEstExp*/
    2379           0 :         move32();
    2380             :     }
    2381             : 
    2382             :     /* NB last band energy compensation */
    2383           0 :     IF( st->CngBandwidth == NB )
    2384             :     {
    2385           0 :         st->sidNoiseEst[( N - 1 )] = Mpy_32_16_1( st->sidNoiseEst[( N - 1 )], NB_LAST_BAND_SCALE ); /*Q31 - st->sidNoiseEstExp*/
    2386           0 :         move32();
    2387             :     }
    2388             : 
    2389           0 :     test();
    2390           0 :     IF( EQ_16( st->CngBandwidth, SWB ) && LE_32( st->CngBitrate, ACELP_13k20 ) )
    2391             :     {
    2392           0 :         st->sidNoiseEst[( N - 1 )] = Mpy_32_16_1( st->sidNoiseEst[( N - 1 )], SWB_13k2_LAST_BAND_SCALE ); /*Q31 - st->sidNoiseEstExp*/
    2393           0 :         move32();
    2394             :     }
    2395             : 
    2396             : 
    2397           0 :     scalebands( sidNoiseEst, st->part, st->npart, st->midband, st->nFFTpart, sub( st->stopBand, st->startBand ), st->cngNoiseLevel, 1 );
    2398           0 :     st->cngNoiseLevelExp = st->sidNoiseEstExp;
    2399           0 :     move16();
    2400             : 
    2401             : 
    2402           0 :     lpc_from_spectrum( st, st->startBand, st->stopFFTbin, preemph_fac );
    2403           0 : }
    2404             : 
    2405             : /*
    2406             :     noisy_speech_detection_fx
    2407             : 
    2408             :     Parameters:
    2409             : 
    2410             :     vad                 i  : VAD decision
    2411             :     Etot                i  : total channel E
    2412             :     Etot_exp            i  : exponent for total channel E
    2413             :     totalNoise          i  : noise estimate over all critical bands
    2414             :     totalNoise_exp      i  : exponent for noise estimate over all critical bands
    2415             :     lp_noise            i/o: pointer to long term total Noise energy average
    2416             :     lp_speech           i/o: pointer to long term active speech energy average
    2417             : 
    2418             :     Function:
    2419             :     detector for noisy speech, lp_noise and lp_speech are scaled by LD_DATA_SCALE+2 bits
    2420             : 
    2421             :     Returns: flag, that indicates whether noisy speech has been detected
    2422             : 
    2423             :     void
    2424             : */
    2425      395818 : void noisy_speech_detection_fx(
    2426             :     HANDLE_FD_CNG_DEC hFdCngDec, /* i/o: FD_CNG structure            */
    2427             :     const Word16 vad,            /*Q0*/
    2428             :     const Word16 *syn,           /* i  : input time-domain frame                  Q*/
    2429             :     const Word16 Q )
    2430             : {
    2431             :     Word16 i;
    2432             :     Word32 tmp;
    2433             :     Word32 Etot;
    2434             :     Word16 Etot_exp;
    2435             :     Word32 logEtot;
    2436             :     Word32 logEtotExp;
    2437             :     Word32 totalNoise;
    2438             :     Word16 totalNoise_exp;
    2439             :     Word32 logTotalNoise;
    2440             :     Word32 logTotalNoiseExp;
    2441             : 
    2442             : 
    2443      395818 :     IF( vad == 0 )
    2444             :     {
    2445       38198 :         totalNoise = dotWord32_16_Mant32Exp( hFdCngDec->msNoiseEst, hFdCngDec->msNoiseEst_exp, hFdCngDec->psize_shaping_norm, hFdCngDec->psize_shaping_norm_exp, hFdCngDec->nFFTpart_shaping, &totalNoise_exp ); /*Q31 - totalNoise_exp*/
    2446             : 
    2447             :         /*
    2448             :           - logTotalNoise is scaled by LD_DATA_SCALE+2
    2449             :           - logTotalNoise = 10.0 * log10(totalNoise + DELTA);
    2450             :           - constant: -0.78125 = 10.0*log10(DELTA)/(1<<(LD_DATA_SCALE+2))
    2451             :           - constant:  0.75257498916 = 10.0 * log10(2.0)/log10(10.0)/(1<<2)
    2452             :         */
    2453       38198 :         IF( totalNoise == 0 )
    2454             :         {
    2455         562 :             logTotalNoise = L_add( -1677721600l /*-0.78125 Q31*/, 0 ); /*Q31*/
    2456             :         }
    2457             :         ELSE
    2458             :         {
    2459       37636 :             logTotalNoise = BASOP_Util_Log2( totalNoise ); /*Q25*/
    2460       37636 :             logTotalNoiseExp = L_shl( L_deposit_l( totalNoise_exp ), WORD32_BITS - 1 - LD_DATA_SCALE );
    2461       37636 :             logTotalNoise = Mpy_32_16_1( L_add( logTotalNoise, logTotalNoiseExp ), 24660 /*0.75257498916 Q15*/ ); /*Q31 - logTotalNoiseExp*/
    2462             :         }
    2463             : 
    2464       38198 :         hFdCngDec->lp_noise = L_add( Mpy_32_16_1( hFdCngDec->lp_noise, 32604 /*0.995 Q15*/ ), L_shr( Mpy_32_16_1( logTotalNoise, 20972 /*0.64 Q15*/ ), 7 ) ); /*hFdCngDec->q_lp_noise*/
    2465       38198 :         move32();
    2466             :     }
    2467             :     ELSE
    2468             :     {
    2469      357620 :         Etot = 0;
    2470      357620 :         move32();
    2471      357620 :         Etot_exp = 31;
    2472      357620 :         move16();
    2473   108222068 :         FOR( i = 0; i < hFdCngDec->hFdCngCom->frameSize; i++ )
    2474             :         {
    2475   107864448 :             tmp = L_shr_r( L_mult0( syn[i], syn[i] ), sub( Etot_exp, 31 ) ); /*2*(Q) - (Etot_exp - 31)*/
    2476   107864448 :             IF( LT_32( L_sub( maxWord32, tmp ), Etot ) )
    2477             :             {
    2478       48861 :                 Etot_exp = add( Etot_exp, 1 );
    2479       48861 :                 Etot = L_shr_r( Etot, 1 ); /*Q31 - Etot_exp*/
    2480       48861 :                 tmp = L_shr_r( tmp, 1 );
    2481             :             }
    2482   107864448 :             Etot = L_add( Etot, tmp );
    2483             :         }
    2484      357620 :         Etot_exp = sub( Etot_exp, shl( Q, 1 ) );
    2485             : 
    2486             :         /*
    2487             :           - logEtot is scaled by LD_DATA_SCALE+2
    2488             :           - logEtot = 10.0 * log10(totalNoise + DELTA);
    2489             :           - constant: -0.78125 = 10.0*log10(DELTA)/(1<<(LD_DATA_SCALE+2))
    2490             :           - constant:  0.75257498916 = 10.0 * log10(2.0)/log10(10.0)/(1<<2)
    2491             :         */
    2492      357620 :         IF( Etot == 0 )
    2493             :         {
    2494        3639 :             logEtot = L_add( -1677721600l /*-0.78125 Q31*/, 0 ); /*Q31*/
    2495             :         }
    2496             :         ELSE
    2497             :         {
    2498      353981 :             logEtot = BASOP_Util_Log2( Etot ); /*Q25*/
    2499      353981 :             logEtotExp = L_shl( L_deposit_l( Etot_exp ), WORD32_BITS - 1 - LD_DATA_SCALE );
    2500      353981 :             logEtot = Mpy_32_16_1( L_add( logEtot, logEtotExp ), 24660 /*0.75257498916 Q15*/ ); /*Q31 - logEtotExp*/
    2501      353981 :             IF( EQ_16( hFdCngDec->hFdCngCom->frameSize, L_FRAME16k ) )
    2502             :             {
    2503      251267 :                 logEtot = L_add( logEtot, -184894985l /*-0.086098436822497 Q31*/ ); /*Q31 - logEtotExp*/
    2504             :             }
    2505             :             ELSE
    2506             :             {
    2507      102714 :                 logEtot = L_add( logEtot, -176765584l /*-0.082312889439370 Q31*/ ); /*Q31 - logEtotExp*/
    2508             :             }
    2509             :         }
    2510             : 
    2511      357620 :         hFdCngDec->lp_speech = L_add( Mpy_32_16_1( hFdCngDec->lp_speech, 32604 /*0.995 Q15*/ ), L_shr( Mpy_32_16_1( logEtot, 20972 /*0.64 Q15*/ ), 7 ) ); /*hFdCngDec->q_lp_speech*/
    2512      357620 :         move32();
    2513             :     }
    2514             : 
    2515      395818 :     tmp = L_sub( hFdCngDec->lp_speech, 377487360l /*45.0 Q23*/ ); /*Q23*/
    2516             : 
    2517      395818 :     if ( LT_32( hFdCngDec->lp_noise, tmp ) )
    2518             :     {
    2519      177043 :         hFdCngDec->lp_noise = tmp; /*Q23*/
    2520      177043 :         move32();
    2521             :     }
    2522             : 
    2523      395818 :     hFdCngDec->hFdCngCom->flag_noisy_speech = 0;
    2524      395818 :     move16();
    2525      395818 :     if ( LT_32( L_sub( hFdCngDec->lp_speech, hFdCngDec->lp_noise ), 234881024l /*28.0 Q23*/ ) )
    2526             :     {
    2527       31179 :         hFdCngDec->hFdCngCom->flag_noisy_speech = 1;
    2528       31179 :         move16();
    2529             :     }
    2530             : 
    2531             : 
    2532      395818 :     return;
    2533             : }
    2534             : 
    2535           0 : void generate_comfort_noise_dec_fx(
    2536             :     Word32 **bufferReal, /* o   : matrix to real part of input bands  bufferScale*/
    2537             :     Word32 **bufferImag, /* o   : matrix to imaginary part of input bands  bufferScale*/
    2538             :     Word16 *bufferScale, /* o   : pointer to scalefactor for real and imaginary part of input bands */
    2539             :     Decoder_State *st,
    2540             :     Word16 *Q_new,
    2541             :     Word16 gen_exc,        /*Q0*/
    2542             :     const Word16 nchan_out /* i  : number of output channels     Q0*/
    2543             : )
    2544             : {
    2545             :     Word16 i, j, s, sc, sn, cnt;
    2546             :     Word16 startBand2;
    2547             :     Word16 stopFFTbin2;
    2548             :     Word16 scaleCLDFB;
    2549             :     Word16 preemph_fac;
    2550             :     Word32 sqrtNoiseLevel;
    2551             :     Word16 randGaussExp;
    2552             :     Word16 fftBufferExp;
    2553             :     Word16 cngNoiseLevelExp;
    2554             :     Word16 *seed;
    2555             :     Word16 *timeDomainOutput;
    2556             :     Word32 *ptr_r, *ptr_i;
    2557             :     Word32 *cngNoiseLevel;
    2558             :     Word32 *ptr_level;
    2559             :     Word32 *fftBuffer;
    2560             :     Word16 old_syn_pe_tmp[16];
    2561           0 :     Word16 tcx_transition = 0;
    2562           0 :     HANDLE_FD_CNG_DEC hFdCngDec = st->hFdCngDec;
    2563           0 :     HANDLE_FD_CNG_COM hFdCngCom = hFdCngDec->hFdCngCom;
    2564             :     TCX_DEC_HANDLE hTcxDec;
    2565           0 :     move16();
    2566             : 
    2567           0 :     hTcxDec = st->hTcxDec;
    2568             : 
    2569             :     /* Warning fix */
    2570           0 :     s = 0;
    2571           0 :     move16();
    2572             :     // PMTE(); /*IVAS CODE need to be added */
    2573             : 
    2574             :     /* pointer initialization */
    2575             : 
    2576           0 :     cngNoiseLevel = hFdCngCom->cngNoiseLevel; /*Q31 - hFdCngCom->cngNoiseLevelExp*/
    2577           0 :     cngNoiseLevelExp = hFdCngCom->cngNoiseLevelExp;
    2578           0 :     ptr_level = cngNoiseLevel; /*Q31 - hFdCngCom->cngNoiseLevelExp*/
    2579           0 :     seed = &( hFdCngCom->seed );
    2580           0 :     fftBuffer = hFdCngCom->fftBuffer; /*Q31 - hFdCngCom->fftBuffer_exp*/
    2581           0 :     timeDomainOutput = hFdCngCom->timeDomainBuffer;
    2582             : 
    2583             :     /* scaleCLDFB: CLDFBinvScalingFactor_EXP + 1 */
    2584           0 :     scaleCLDFB = mult( hFdCngCom->invScalingFactor, CLDFB_SCALING ); /*CLDFBinvScalingFactor_EXP + 1*/
    2585             : 
    2586             :     /*
    2587             :       Generate Gaussian random noise in real and imaginary parts of the FFT bins
    2588             :       Amplitudes are adjusted to the estimated noise level cngNoiseLevel in each bin
    2589             :       scaling Gaussian random noise: format Q3.29
    2590             :     */
    2591           0 :     sn = 0;
    2592           0 :     move16();
    2593           0 :     IF( s_and( cngNoiseLevelExp, 1 ) != 0 )
    2594             :     {
    2595           0 :         sn = add( sn, 1 );
    2596           0 :         cngNoiseLevelExp = add( cngNoiseLevelExp, sn );
    2597           0 :         move16();
    2598             :     }
    2599             : 
    2600           0 :     randGaussExp = CNG_RAND_GAUSS_SHIFT;
    2601           0 :     move16();
    2602           0 :     cnt = sub( hFdCngCom->stopFFTbin, hFdCngCom->startBand );
    2603           0 :     IF( hFdCngCom->startBand == 0 )
    2604             :     {
    2605             :         /* DC component in FFT */
    2606           0 :         s = 0;
    2607           0 :         move16();
    2608           0 :         sqrtNoiseLevel = Sqrt32( L_shr( *ptr_level, sn ), &s ); /*Q31 - s*/
    2609             : 
    2610           0 :         fftBuffer[0] = L_shl( Mpy_32_32( rand_gauss( seed ), sqrtNoiseLevel ), s ); /*Q31 - hFdCngCom->fftBuffer_exp*/
    2611           0 :         move32();
    2612             : 
    2613             :         /* Nyquist frequency is discarded */
    2614           0 :         fftBuffer[1] = L_deposit_l( 0 );
    2615             : 
    2616           0 :         ptr_level = ptr_level + 1;
    2617           0 :         ptr_r = fftBuffer + 2; /*Q31 - hFdCngCom->fftBuffer_exp*/
    2618           0 :         cnt = sub( cnt, 1 );
    2619             :     }
    2620             :     ELSE
    2621             :     {
    2622           0 :         startBand2 = shl( hFdCngCom->startBand, 1 ); /*Q0*/
    2623           0 :         set32_fx( fftBuffer, 0, startBand2 );
    2624           0 :         ptr_r = fftBuffer + startBand2; /*Q31 - hFdCngCom->fftBuffer_exp*/
    2625             :     }
    2626             : 
    2627           0 :     sn = add( sn, 1 );
    2628           0 :     ptr_i = ptr_r + 1; /*Q31 - hFdCngCom->fftBuffer_exp*/
    2629           0 :     FOR( i = 0; i < cnt; i++ )
    2630             :     {
    2631           0 :         s = 0;
    2632           0 :         move16();
    2633           0 :         sqrtNoiseLevel = Sqrt32( L_shr( *ptr_level, sn ), &s ); /*Q31 - s*/
    2634             : 
    2635             :         /* Real part in FFT bins */
    2636           0 :         *ptr_r = L_shl( Mpy_32_32( rand_gauss( seed ), sqrtNoiseLevel ), s );
    2637           0 :         move32();
    2638             : 
    2639             :         /* Imaginary part in FFT bins */
    2640           0 :         *ptr_i = L_shl( Mpy_32_32( rand_gauss( seed ), sqrtNoiseLevel ), s );
    2641           0 :         move32();
    2642             : 
    2643           0 :         ptr_r = ptr_r + 2;
    2644           0 :         ptr_i = ptr_i + 2;
    2645           0 :         ptr_level = ptr_level + 1;
    2646             :     }
    2647             : 
    2648             :     /* Remaining FFT bins are set to zero */
    2649           0 :     stopFFTbin2 = shl( hFdCngCom->stopFFTbin, 1 );
    2650           0 :     set32_fx( fftBuffer + stopFFTbin2, 0, sub( hFdCngCom->fftlen, stopFFTbin2 ) );
    2651             : 
    2652           0 :     fftBufferExp = add( shr( cngNoiseLevelExp, 1 ), randGaussExp );
    2653             : 
    2654             :     /* If previous frame is active, reset the overlap-add buffer */
    2655           0 :     IF( EQ_16( hFdCngCom->frame_type_previous, ACTIVE_FRAME ) )
    2656             :     {
    2657           0 :         set16_fx( hFdCngCom->olapBufferSynth, 0, hFdCngCom->fftlen );
    2658           0 :         test();
    2659           0 :         test();
    2660           0 :         if ( ( st->last_core_bfi > ACELP_CORE && EQ_16( st->codec_mode, MODE2 ) ) || EQ_16( st->codec_mode, MODE1 ) )
    2661             :         {
    2662           0 :             tcx_transition = 1;
    2663           0 :             move16();
    2664             :         }
    2665             :     }
    2666             : 
    2667             :     /* Perform STFT synthesis */
    2668           0 :     SynthesisSTFT( fftBuffer, fftBufferExp, timeDomainOutput, hFdCngCom->olapBufferSynth, hFdCngCom->olapWinSyn,
    2669           0 :                    tcx_transition, hFdCngCom, gen_exc, Q_new, st->element_mode, nchan_out );
    2670             : 
    2671             :     {
    2672             :         Word32 Lener, att;
    2673             :         Word16 exp;
    2674             :         /* update CNG excitation energy for LP_CNG */
    2675             : 
    2676             :         /* calculate the residual signal energy */
    2677             :         /*enr = dotp( hFdCngCom->exc_cng, hFdCngCom->exc_cng, hFdCngCom->frameSize ) / hFdCngCom->frameSize;*/
    2678           0 :         Lener = Dot_productSq16HQ( 1, hFdCngCom->exc_cng, st->L_frame, &exp ); /*Q31 - exp*/
    2679           0 :         exp = add( sub( shl( sub( 15, *Q_new ), 1 ), 8 ), exp );               /*8 = log2(256)*/
    2680             : 
    2681             :         /* convert log2 of residual signal energy */
    2682             :         /*(float)log10( enr + 0.1f ) / (float)log10( 2.0f );*/
    2683           0 :         Lener = BASOP_Util_Log2( Lener );                                                     /*Q25*/
    2684           0 :         Lener = L_add( Lener, L_shl( L_deposit_l( exp ), WORD32_BITS - 1 - LD_DATA_SCALE ) ); /*Q25*/
    2685           0 :         if ( EQ_16( st->L_frame, L_FRAME16k ) )
    2686             :         {
    2687           0 :             Lener = L_sub( Lener, 10802114l /*0.3219280949f Q25*/ ); /*log2(320) = 8.3219280949f Q25*/
    2688             :         }
    2689             :         /* decrease the energy in case of WB input */
    2690           0 :         IF( st->bwidth != NB )
    2691             :         {
    2692           0 :             IF( EQ_16( st->bwidth, WB ) )
    2693             :             {
    2694           0 :                 IF( st->CNG_mode >= 0 )
    2695             :                 {
    2696             :                     /* Bitrate adapted attenuation */
    2697           0 :                     att = L_shl( L_deposit_l( ENR_ATT_fx[st->CNG_mode] ), 17 ); /*Q23*/
    2698             :                 }
    2699             :                 ELSE
    2700             :                 {
    2701             :                     /* Use least attenuation for higher bitrates */
    2702           0 :                     att = L_shl( L_deposit_l( ENR_ATT_fx[4] ), 17 ); /*Q23*/
    2703             :                 }
    2704             :             }
    2705             :             ELSE
    2706             :             {
    2707           0 :                 att = 384 << 17; /*1.5 Q8<<17=Q25*/
    2708           0 :                 move16();
    2709             :             }
    2710           0 :             Lener = L_sub( Lener, att ); /*Q23*/
    2711             :         }
    2712             :         /*st->lp_ener = 0.8f * stcod->lp_ener + 0.2f * pow( 2.0f, enr );*/
    2713           0 :         Lener = BASOP_util_Pow2( Lener, 6, &exp );      /*Q31 - exp*/
    2714           0 :         Lener = Mult_32_16( Lener, 6554 /*0.2f Q15*/ ); /*Q31 - exp*/
    2715           0 :         exp = sub( 25, exp );
    2716           0 :         Lener = L_shr( Lener, exp );                                                       /*Q6*/
    2717           0 :         st->lp_ener_fx = L_add( Mult_32_16( st->lp_ener_fx, 26214 /*0.8f Q15*/ ), Lener ); /*Q6*/
    2718           0 :         move32();
    2719             :     }
    2720             : 
    2721             :     /*
    2722             :       Generate Gaussian random noise in real and imaginary parts of the CLDFB bands
    2723             :       Amplitudes are adjusted to the estimated noise level cngNoiseLevel in each band
    2724             :     */
    2725           0 :     test();
    2726           0 :     IF( bufferReal != NULL && ( LT_16( hFdCngCom->numCoreBands, hFdCngCom->regularStopBand ) ) )
    2727             :     {
    2728             : 
    2729           0 :         sn = sub( sn, 1 );
    2730           0 :         sc = add( shr( add( cngNoiseLevelExp, CLDFBinvScalingFactor_EXP + 1 - 1 ), 1 ), randGaussExp );
    2731           0 :         move16();
    2732           0 :         assert( ( ( cngNoiseLevelExp + CLDFBinvScalingFactor_EXP + 1 - 1 ) & 1 ) == 0 );
    2733             : 
    2734           0 :         FOR( j = hFdCngCom->numCoreBands; j < hFdCngCom->regularStopBand; j++ )
    2735             :         {
    2736             :             /* scaleCLDFB:  CLDFBinvScalingFactor_EXP + 1 */
    2737           0 :             s = 0;
    2738           0 :             move16();
    2739           0 :             sqrtNoiseLevel = Sqrt32( L_shr( Mpy_32_16_1( *ptr_level, scaleCLDFB ), sn ), &s ); /*Q31 - s*/
    2740             : 
    2741           0 :             FOR( i = 0; i < hFdCngCom->numSlots; i++ )
    2742             :             {
    2743             :                 /* Real part in CLDFB band */
    2744           0 :                 bufferReal[i][j] = L_shl( Mpy_32_32( rand_gauss( seed ), sqrtNoiseLevel ), s ); /*bufferScale*/
    2745           0 :                 move32();
    2746             :                 /*fprintf(pFile,"%13.10f\n",WORD322FL_SCALE(bufferReal[i][j],sc));*/
    2747             : 
    2748             :                 /* Imaginary part in CLDFB band */
    2749           0 :                 bufferImag[i][j] = L_shl( Mpy_32_32( rand_gauss( seed ), sqrtNoiseLevel ), s ); /*bufferScale*/
    2750           0 :                 move32();
    2751             :                 /*fprintf(pFile,"%13.10f\n",WORD322FL_SCALE(bufferImag[i][j],sc));*/
    2752             :             }
    2753           0 :             ptr_level = ptr_level + 1;
    2754             :         }
    2755           0 :         *bufferScale = sub( sc, 15 );
    2756           0 :         move16();
    2757             :     }
    2758             : 
    2759             :     /* Overlap-add when previous frame is active */
    2760           0 :     test();
    2761           0 :     IF( EQ_16( hFdCngCom->frame_type_previous, ACTIVE_FRAME ) && EQ_16( st->codec_mode, MODE2 ) )
    2762             :     {
    2763             :         Word32 old_exc_ener, gain, noise32;
    2764             :         Word16 seed_loc, lpcorder, old_syn, tmp, gain16, N, N2, N4, N8;
    2765             :         Word16 old_exc_ener_exp, gain_exp;
    2766             :         Word16 normFacE, normShiftE, normShiftEM1;
    2767             :         Word16 normFacG, normShiftG, normShiftGM1;
    2768             :         Word16 noiseExp, *old_exc, *old_Aq, *old_syn_pe;
    2769             :         Word16 noise[640], normShiftP2;
    2770             :         Word16 Q_exc, Q_syn;
    2771             : 
    2772             : 
    2773           0 :         assert( hFdCngCom->frameSize <= 640 );
    2774             : 
    2775           0 :         seed_loc = hFdCngCom->seed;
    2776           0 :         move16();
    2777           0 :         N = hFdCngCom->frameSize; /*Q0*/
    2778           0 :         move16();
    2779           0 :         N2 = shr( hFdCngCom->frameSize, 1 );
    2780             : 
    2781           0 :         IF( st->last_core_bfi > ACELP_CORE )
    2782             :         {
    2783             :             Word16 left_overlap_mode;
    2784           0 :             left_overlap_mode = st->hTcxCfg->tcx_last_overlap_mode; /*Q0*/
    2785           0 :             move16();
    2786           0 :             if ( EQ_16( left_overlap_mode, ALDO_WINDOW ) )
    2787             :             {
    2788           0 :                 left_overlap_mode = FULL_OVERLAP;
    2789           0 :                 move16();
    2790             :             }
    2791           0 :             tcx_windowing_synthesis_current_frame( timeDomainOutput, st->hTcxCfg->tcx_mdct_window, st->hTcxCfg->tcx_mdct_window_half, st->hTcxCfg->tcx_mdct_window_minimum, st->hTcxCfg->tcx_mdct_window_length, st->hTcxCfg->tcx_mdct_window_half_length,
    2792           0 :                                                    st->hTcxCfg->tcx_mdct_window_min_length, 0, left_overlap_mode, NULL, NULL, NULL, NULL, NULL, shr( N, 1 ), shr( sub( abs_s( st->hTcxCfg->tcx_offset ), st->hTcxCfg->tcx_offset ), 1 ), 1, 0, 0 );
    2793             : 
    2794           0 :             IF( st->hTcxCfg->last_aldo != 0 )
    2795             :             {
    2796           0 :                 FOR( i = 0; i < hFdCngCom->frameSize - NS2SA( st->sr_core, N_ZERO_MDCT_NS ); i++ )
    2797             :                 {
    2798           0 :                     timeDomainOutput[i] = add( timeDomainOutput[i], shr_r( st->hHQ_core->old_out_LB_fx[i + NS2SA_FX2( st->sr_core, N_ZERO_MDCT_NS )], st->hHQ_core->Q_old_wtda_LB ) ); /*st->q_old_outLB_fx*/
    2799           0 :                     move16();
    2800             :                 }
    2801             :             }
    2802             :             ELSE
    2803             :             {
    2804           0 :                 tcx_windowing_synthesis_past_frame( hTcxDec->syn_Overl, st->hTcxCfg->tcx_mdct_window, st->hTcxCfg->tcx_mdct_window_half, st->hTcxCfg->tcx_mdct_window_minimum,
    2805           0 :                                                     st->hTcxCfg->tcx_mdct_window_length, st->hTcxCfg->tcx_mdct_window_half_length, st->hTcxCfg->tcx_mdct_window_min_length, st->hTcxCfg->tcx_last_overlap_mode );
    2806             : 
    2807           0 :                 FOR( i = 0; i < st->hTcxCfg->tcx_mdct_window_length; i++ )
    2808             :                 {
    2809           0 :                     timeDomainOutput[i] = add( timeDomainOutput[i], shl( hTcxDec->syn_Overl[i], TCX_IMDCT_HEADROOM ) ); /*st->q_old_outLB_fx*/
    2810           0 :                     move16();
    2811             :                 }
    2812             :             }
    2813             :         }
    2814             :         ELSE
    2815             :         {
    2816             : 
    2817             :             /*
    2818             :               - the scaling of the LPCs (e.g. old_Aq) is always Q12 (encoder or decoder)
    2819             : 
    2820             :               - the scaling of the deemphasized signals (e.g. old_syn) is always Q0 (encoder or decoder)
    2821             : 
    2822             :               - the scaling of the excitation signals in the encoder (e.g. old_exc) is Q_new
    2823             :               - the scaling of the preemphasized signals in the encoder (e.g. old_syn_pe) is Q_new-1
    2824             : 
    2825             :               - the scaling of the excitation signals in the decoder (e.g. old_exc) is Q_exc (or stdec->Q_exc)
    2826             :               - the scaling of the preemphasized signals in the decoder (e.g. old_syn_pe) is Q_syn (or stdec->Q_syn)
    2827             :             */
    2828             : 
    2829           0 :             lpcorder = M;
    2830           0 :             move16();
    2831           0 :             old_Aq = st->old_Aq_12_8_fx;                         /*Q12*/
    2832           0 :             old_exc = st->old_exc_fx + sub( L_EXC_MEM_DEC, N2 ); /*Q_exc*/
    2833           0 :             old_syn_pe = st->mem_syn2_fx;                        /*Q_syn*/
    2834           0 :             old_syn = st->syn[lpcorder];                         /*Q_syn*/
    2835           0 :             move16();
    2836           0 :             preemph_fac = st->preemph_fac; /*Q15*/
    2837           0 :             move16();
    2838           0 :             Q_exc = st->Q_exc;
    2839           0 :             move16();
    2840           0 :             Q_syn = st->Q_syn;
    2841           0 :             move16();
    2842             : 
    2843             :             /* shift to be in the range of values supported by getNormReciprocalWord16() */
    2844           0 :             N8 = shr( N2, CNG_NORM_RECIPROCAL_RANGE_SHIFT );
    2845             : 
    2846           0 :             assert( N2 == ( N8 << CNG_NORM_RECIPROCAL_RANGE_SHIFT ) );
    2847             : 
    2848           0 :             normFacE = getNormReciprocalWord16( N8 );
    2849           0 :             normShiftE = BASOP_util_norm_s_bands2shift( N8 );
    2850           0 :             normShiftEM1 = sub( normShiftE, 1 );
    2851           0 :             normShiftP2 = add( normShiftE, CNG_NORM_RECIPROCAL_RANGE_SHIFT );
    2852             : 
    2853           0 :             old_exc_ener = L_shr( L_mult( old_exc[0], old_exc[0] ), normShiftP2 ); /*2*(Q_exc)+1+normShiftP2*/
    2854           0 :             FOR( i = 1; i < N2; i++ )
    2855             :             {
    2856           0 :                 old_exc_ener = L_add( old_exc_ener, L_shr( L_mult( old_exc[i], old_exc[i] ), normShiftP2 ) ); /*2*(Q_exc)+1+normShiftP2*/
    2857             :             }
    2858           0 :             old_exc_ener = L_shl( Mpy_32_16_1( old_exc_ener, shl( normFacE, normShiftEM1 ) ), 1 ); /*Q31*/
    2859             : 
    2860           0 :             old_exc_ener_exp = 0;
    2861           0 :             move16();
    2862           0 :             old_exc_ener = Sqrt32( old_exc_ener, &old_exc_ener_exp ); /*Q31 - old_exc_ener_exp*/
    2863           0 :             old_exc_ener_exp = add( old_exc_ener_exp, ( sub( 15, Q_exc ) ) );
    2864             : 
    2865             :             /* shift to be in the range of values supported by getNormReciprocalWord16() */
    2866           0 :             N4 = shr( N, CNG_NORM_RECIPROCAL_RANGE_SHIFT );
    2867             : 
    2868           0 :             assert( N == ( N4 << CNG_NORM_RECIPROCAL_RANGE_SHIFT ) );
    2869             : 
    2870           0 :             normFacG = getNormReciprocalWord16( N4 );
    2871           0 :             normShiftG = BASOP_util_norm_s_bands2shift( N4 );
    2872           0 :             normShiftGM1 = sub( normShiftG, 1 );
    2873           0 :             normShiftP2 = add( normShiftG, CNG_NORM_RECIPROCAL_RANGE_SHIFT );
    2874             : 
    2875           0 :             gain = L_deposit_l( 0 );
    2876           0 :             FOR( i = 0; i < N; i++ )
    2877             :             {
    2878           0 :                 noise32 = rand_gauss( &seed_loc );
    2879           0 :                 noise[i] = extract_h( noise32 );
    2880           0 :                 move16();
    2881           0 :                 gain = L_add( gain, L_shr( L_mult( noise[i], noise[i] ), normShiftP2 ) );
    2882             :             }
    2883           0 :             gain = L_shl( Mpy_32_16_1( gain, shl( normFacG, normShiftGM1 ) ), 1 ); /*Q31 - gain_exp*/
    2884             : 
    2885           0 :             gain_exp = 2 * CNG_RAND_GAUSS_SHIFT;
    2886           0 :             move16();
    2887           0 :             gain = ISqrt32( gain, &gain_exp ); /*Q31 - gain_exp*/
    2888             : 
    2889           0 :             gain = Mpy_32_32( old_exc_ener, gain ); /*Q31 - old_exc_ener_exp - gain_exp*/
    2890           0 :             gain16 = extract_h( gain );             /*Q15 - old_exc_ener_exp - gain_exp*/
    2891             : 
    2892           0 :             gain_exp = add( old_exc_ener_exp, gain_exp );
    2893           0 :             noiseExp = add( CNG_RAND_GAUSS_SHIFT, gain_exp );
    2894             : 
    2895           0 :             s = sub( 15 - NOISE_HEADROOM, noiseExp );
    2896           0 :             FOR( i = 0; i < N; i++ )
    2897             :             {
    2898           0 :                 noise[i] = shr_sat( mult( noise[i], gain16 ), s ); /*Q15 - noiseExp*/
    2899           0 :                 move16();
    2900             :             }
    2901             : 
    2902           0 :             assert( lpcorder <= 16 );
    2903             : 
    2904           0 :             s = sub( 15 - NOISE_HEADROOM, ( sub( 15, Q_syn ) ) );
    2905           0 :             FOR( i = 0; i < lpcorder; i++ )
    2906             :             {
    2907           0 :                 old_syn_pe_tmp[i] = shr_sat( old_syn_pe[i], s ); /*Q0*/
    2908           0 :                 move16();
    2909             :             }
    2910             : 
    2911           0 :             E_UTIL_synthesis(
    2912             :                 0,              /* i  : scaling to apply for a[0]                 Q0   */
    2913             :                 old_Aq,         /* i  : LP filter coefficients                    Q12  */
    2914             :                 noise,          /* i  : input signal                              Qx   */
    2915             :                 noise,          /* o  : output signal                             Qx-s */
    2916             :                 N,              /* i  : size of filtering                         Q0   */
    2917             :                 old_syn_pe_tmp, /* i/o: memory associated with this filtering.    Q0 */
    2918             :                 0,              /* i  : 0=no update, 1=update of memory.          Q0   */
    2919             :                 lpcorder        /* i  : order of LP filter                        Q0   */
    2920             :             );
    2921             : 
    2922           0 :             tmp = old_syn;
    2923           0 :             move16();
    2924             : 
    2925           0 :             E_UTIL_deemph2(
    2926             :                 NOISE_HEADROOM,
    2927             :                 noise,       /* I/O: signal                       Qx */
    2928             :                 preemph_fac, /* I: deemphasis factor      Qx */
    2929             :                 N,           /* I: vector size              */
    2930             :                 &tmp         /* I/O: memory (signal[-1]) Qx */
    2931             :             );
    2932             : 
    2933           0 :             FOR( i = 0; i < N4; i++ )
    2934             :             {
    2935           0 :                 tmp = mult( noise[i], hFdCngCom->olapWinSyn[i].v.re ); /*Q15 - noiseExp*/
    2936           0 :                 timeDomainOutput[i] = add( timeDomainOutput[i], tmp );
    2937           0 :                 move16();
    2938           0 :                 tmp = mult( noise[( i + N4 )], hFdCngCom->olapWinSyn[( ( N4 - 1 ) - i )].v.im ); /*Q15 - noiseExp*/
    2939           0 :                 timeDomainOutput[( i + N4 )] = add( timeDomainOutput[( i + N4 )], tmp );
    2940           0 :                 move16();
    2941             :             }
    2942             :         }
    2943             :     }
    2944           0 : }
    2945             : 
    2946       18381 : void generate_comfort_noise_dec_ivas_fx(
    2947             :     Word32 **bufferReal, /* o  : Real part of input bands      bufferScale*/
    2948             :     Word32 **bufferImag, /* o  : Imaginary part of input bands bufferScale*/
    2949             :     Word16 *bufferScale, /* o   : pointer to scalefactor for real and imaginary part of input bands */
    2950             :     Decoder_State *st,   /* i/o: decoder state structure       */
    2951             :     Word16 *Q_new,
    2952             :     Word16 gen_exc,        /*Q0*/
    2953             :     const Word16 nchan_out /* i  : number of output channels     Q0*/
    2954             : )
    2955             : {
    2956             :     Word16 i, j, s;
    2957             :     Word32 *ptr_r, *ptr_i;
    2958       18381 :     HANDLE_FD_CNG_DEC hFdCngDec = st->hFdCngDec;
    2959       18381 :     HANDLE_FD_CNG_COM hFdCngCom = hFdCngDec->hFdCngCom;
    2960       18381 :     Word32 *cngNoiseLevel = hFdCngCom->cngNoiseLevel;
    2961       18381 :     Word16 cngNoiseLevel_exp = hFdCngCom->cngNoiseLevelExp;
    2962       18381 :     move16();
    2963             : 
    2964       18381 :     Word32 *ptr_level = cngNoiseLevel;
    2965       18381 :     Word16 *seed = &( hFdCngCom->seed );
    2966             :     Word16 *seed2;
    2967             :     Word16 c1, c2;
    2968             :     Word32 tmp1, tmp2;
    2969             :     Word16 scaleCldfb;
    2970       18381 :     Word32 *fftBuffer = hFdCngCom->fftBuffer; /*hFdCngCom->fftBuffer_exp*/
    2971       18381 :     Word16 fftBuffer_exp = hFdCngCom->fftBuffer_exp;
    2972             :     Word16 fftBuffer_temp_exp[FFTLEN];
    2973       18381 :     Word16 *timeDomainOutput = hFdCngCom->timeDomainBuffer;
    2974             :     Word16 temp;
    2975             :     Word32 sqrtNoiseLevel;
    2976             :     Word16 sqrtNoiseLevel_exp;
    2977       18381 :     Word16 idx = 0;
    2978       18381 :     move16();
    2979             :     Word16 preemph_fac;
    2980             :     Word16 old_syn_pe_tmp[16];
    2981       18381 :     Word16 tcx_transition = 0;
    2982             :     TCX_DEC_HANDLE hTcxDec;
    2983       18381 :     move16();
    2984             : 
    2985       18381 :     hTcxDec = st->hTcxDec;
    2986             : 
    2987       18381 :     scaleCldfb = mult( hFdCngCom->invScalingFactor, CLDFB_SCALING ); /*CLDFBinvScalingFactor_EXP + 1*/
    2988             : 
    2989       18381 :     temp = 0;
    2990       18381 :     move16();
    2991       18381 :     c1 = Sqrt16( hFdCngCom->coherence_fx, &temp ); /*Q15 - temp*/
    2992       18381 :     c1 = shl( c1, temp );                          /*Q15*/
    2993       18381 :     temp = 0;
    2994       18381 :     move16();
    2995       18381 :     c2 = Sqrt16( sub( MAX_16, hFdCngCom->coherence_fx ), &temp ); /*Q15 - temp*/
    2996       18381 :     c2 = shl( c2, temp );                                         /*Q15*/
    2997             : 
    2998       18381 :     temp = getScaleFactor32( fftBuffer, FFTLEN );
    2999       18381 :     scale_sig32( fftBuffer, FFTLEN, temp ); /*Q31 - hFdCngCom->fftBuffer_exp + temp*/
    3000       18381 :     fftBuffer_exp = sub( fftBuffer_exp, temp );
    3001       18381 :     hFdCngCom->fftBuffer_exp = fftBuffer_exp;
    3002       18381 :     move16();
    3003       18381 :     set16_fx( fftBuffer_temp_exp, fftBuffer_exp, FFTLEN );
    3004       18381 :     fftBuffer_exp = 0;
    3005       18381 :     move16();
    3006             : 
    3007       18381 :     seed2 = &( hFdCngCom->seed2 );
    3008       18381 :     test();
    3009       18381 :     if ( EQ_16( st->element_mode, IVAS_CPE_MDCT ) && EQ_16( st->idchan, 1 ) )
    3010             :     {
    3011        3082 :         seed2 = &( hFdCngCom->seed3 );
    3012             :     }
    3013             : 
    3014             :     /* Generate Gaussian random noise in real and imaginary parts of the FFT bins
    3015             :       Amplitudes are adjusted to the estimated noise level cngNoiseLevel_flt in each bin */
    3016             : 
    3017       18381 :     IF( hFdCngCom->startBand == 0 )
    3018             :     {
    3019           0 :         test();
    3020           0 :         test();
    3021           0 :         IF( EQ_16( st->element_mode, IVAS_CPE_MDCT ) || ( EQ_16( st->element_mode, IVAS_SCE ) && st->cng_ism_flag ) )
    3022             :         {
    3023           0 :             rand_gauss_fx( &tmp1, seed, Q15 );
    3024           0 :             rand_gauss_fx( &tmp2, seed2, Q15 );
    3025           0 :             fftBuffer[0] = L_add( Mpy_32_16_1( tmp1, c1 ), Mpy_32_16_1( tmp2, c2 ) ); /*Q0*/
    3026           0 :             move32();
    3027           0 :             fftBuffer_temp_exp[0] = Q16 + Q15;
    3028           0 :             move16();
    3029             :         }
    3030             :         ELSE
    3031             :         {
    3032           0 :             rand_gauss_fx( &fftBuffer[0], seed, Q15 );
    3033           0 :             fftBuffer_temp_exp[0] = Q16;
    3034           0 :             move16();
    3035             :         }
    3036           0 :         sqrtNoiseLevel_exp = cngNoiseLevel_exp;
    3037           0 :         move16();
    3038           0 :         sqrtNoiseLevel = Sqrt32( *ptr_level, &sqrtNoiseLevel_exp ); /*Q31 - sqrtNoiseLevel_exp*/
    3039           0 :         fftBuffer[0] = Mpy_32_32( fftBuffer[0], sqrtNoiseLevel );   /*Q31 - (sqrtNoiseLevel_exp + fftBuffer_temp_exp[0])*/
    3040           0 :         move32();
    3041           0 :         fftBuffer_temp_exp[0] = add( sqrtNoiseLevel_exp, fftBuffer_temp_exp[0] );
    3042           0 :         move16();
    3043           0 :         ptr_level++;
    3044           0 :         ptr_r = fftBuffer + 2; /*Q31 - (fftBuffer_temp_exp)*/
    3045           0 :         idx = 2;
    3046             :     }
    3047             :     ELSE
    3048             :     {
    3049       18381 :         fftBuffer[0] = 0;
    3050       18381 :         move16();
    3051       18381 :         set32_fx( fftBuffer + 2, 0, shl( sub( hFdCngCom->startBand, 1 ), 1 ) );
    3052       18381 :         ptr_r = fftBuffer + shl( hFdCngCom->startBand, 1 ); /*Q31 - fftBuffer_exp*/
    3053       18381 :         idx = shl( hFdCngCom->startBand, 1 );               /*Q0*/
    3054             :     }
    3055             : 
    3056       18381 :     ptr_i = ptr_r + 1; /*Q31 - fftBuffer_exp*/
    3057     5423155 :     FOR( ; ptr_level < cngNoiseLevel + sub( hFdCngCom->stopFFTbin, hFdCngCom->startBand ); ptr_level++ )
    3058             :     {
    3059             :         /* Real part in FFT bins */
    3060     5404774 :         test();
    3061     5404774 :         test();
    3062     5404774 :         IF( EQ_16( st->element_mode, IVAS_CPE_MDCT ) || ( EQ_16( st->element_mode, IVAS_SCE ) && st->cng_ism_flag ) )
    3063             :         {
    3064     3683032 :             rand_gauss_fx( &tmp1, seed, Q15 );                                  /*Q15*/
    3065     3683032 :             rand_gauss_fx( &tmp2, seed2, Q15 );                                 /*Q15*/
    3066     3683032 :             *ptr_r = L_add( Mpy_32_16_1( tmp1, c1 ), Mpy_32_16_1( tmp2, c2 ) ); /*Q15*/
    3067     3683032 :             move32();
    3068     3683032 :             fftBuffer_temp_exp[idx] = Q16;
    3069     3683032 :             move16();
    3070             :         }
    3071             :         ELSE
    3072             :         {
    3073     1721742 :             rand_gauss_fx( ptr_r, seed, Q15 ); /*Q15*/
    3074     1721742 :             fftBuffer_temp_exp[idx] = Q16;
    3075     1721742 :             move16();
    3076             :         }
    3077             : 
    3078     5404774 :         sqrtNoiseLevel_exp = sub( cngNoiseLevel_exp, 1 );
    3079     5404774 :         sqrtNoiseLevel = Sqrt32( *ptr_level, &sqrtNoiseLevel_exp ); /*Q31 - sqrtNoiseLevel_exp*/
    3080     5404774 :         ( *ptr_r ) = Mpy_32_32( ( *ptr_r ), sqrtNoiseLevel );       /*Q15 - sqrtNoiseLevel_exp*/
    3081     5404774 :         move32();
    3082     5404774 :         fftBuffer_temp_exp[idx] = add( fftBuffer_temp_exp[idx], sqrtNoiseLevel_exp );
    3083     5404774 :         move16();
    3084     5404774 :         idx = add( idx, 1 );
    3085     5404774 :         ptr_r += 2;
    3086             : 
    3087             :         /* Imaginary part in FFT bins */
    3088     5404774 :         test();
    3089     5404774 :         test();
    3090     5404774 :         IF( EQ_16( st->element_mode, IVAS_CPE_MDCT ) || ( EQ_16( st->element_mode, IVAS_SCE ) && st->cng_ism_flag ) )
    3091             :         {
    3092     3683032 :             rand_gauss_fx( &tmp1, seed, Q15 );                                  /*Q15*/
    3093     3683032 :             rand_gauss_fx( &tmp2, seed2, Q15 );                                 /*Q15*/
    3094     3683032 :             *ptr_i = L_add( Mpy_32_16_1( tmp1, c1 ), Mpy_32_16_1( tmp2, c2 ) ); /*Q15*/
    3095     3683032 :             move32();
    3096     3683032 :             fftBuffer_temp_exp[idx] = Q16;
    3097     3683032 :             move16();
    3098             :         }
    3099             :         ELSE
    3100             :         {
    3101     1721742 :             rand_gauss_fx( ptr_i, seed, Q15 ); /*Q15*/
    3102     1721742 :             fftBuffer_temp_exp[idx] = Q16;
    3103     1721742 :             move16();
    3104             :         }
    3105     5404774 :         sqrtNoiseLevel_exp = sub( cngNoiseLevel_exp, 1 );
    3106     5404774 :         sqrtNoiseLevel = Sqrt32( *ptr_level, &sqrtNoiseLevel_exp ); /*Q31 - sqrtNoiseLevel_exp*/
    3107     5404774 :         ( *ptr_i ) = Mpy_32_32( ( *ptr_i ), sqrtNoiseLevel );       /*Q15 - sqrtNoiseLevel_exp*/
    3108     5404774 :         move32();
    3109     5404774 :         fftBuffer_temp_exp[idx] = add( fftBuffer_temp_exp[idx], sqrtNoiseLevel_exp );
    3110     5404774 :         move16();
    3111     5404774 :         idx = add( idx, 1 );
    3112     5404774 :         ptr_i += 2;
    3113             :     }
    3114             : 
    3115             :     /* Remaining FFT bins are set to zero */
    3116       18381 :     set32_fx( fftBuffer + shl( hFdCngCom->stopFFTbin, 1 ), 0, sub( hFdCngCom->fftlen, shl( hFdCngCom->stopFFTbin, 1 ) ) );
    3117       18381 :     set16_fx( fftBuffer_temp_exp + shl( hFdCngCom->stopFFTbin, 1 ), 0, sub( hFdCngCom->fftlen, shl( hFdCngCom->stopFFTbin, 1 ) ) );
    3118             : 
    3119             :     /* Nyquist frequency is discarded */
    3120       18381 :     fftBuffer[1] = 0;
    3121       18381 :     move32();
    3122             : 
    3123       18381 :     fftBuffer_exp = MAX_16;
    3124       18381 :     move16();
    3125    10904525 :     FOR( i = 0; i < hFdCngCom->fftlen; i++ )
    3126             :     {
    3127    10886144 :         IF( fftBuffer[i] != 0 )
    3128             :         {
    3129     8545166 :             fftBuffer_exp = s_min( fftBuffer_exp, add( sub( 31, fftBuffer_temp_exp[i] ), norm_l( fftBuffer[i] ) ) );
    3130             :         }
    3131             :     }
    3132       18381 :     if ( EQ_16( fftBuffer_exp, MAX_16 ) )
    3133             :     {
    3134        2232 :         fftBuffer_exp = 0;
    3135        2232 :         move16();
    3136             :     }
    3137       18381 :     fftBuffer_exp = sub( 31, fftBuffer_exp );
    3138    10904525 :     FOR( i = 0; i < hFdCngCom->fftlen; i++ )
    3139             :     {
    3140    10886144 :         fftBuffer[i] = L_shr( fftBuffer[i], sub( fftBuffer_exp, fftBuffer_temp_exp[i] ) ); /*Q31 - fftBuffer_temp_exp[i]*/
    3141    10886144 :         move32();
    3142             :     }
    3143             : 
    3144             :     /* If previous frame is active, reset the overlap-add buffer */
    3145       18381 :     tcx_transition = 0;
    3146       18381 :     move16();
    3147       18381 :     IF( EQ_16( hFdCngCom->frame_type_previous, ACTIVE_FRAME ) )
    3148             :     {
    3149        1772 :         set16_fx( hFdCngCom->olapBufferSynth, 0, hFdCngCom->fftlen );
    3150        1772 :         test();
    3151        1772 :         test();
    3152        1772 :         if ( ( st->last_core_bfi > ACELP_CORE && EQ_16( st->codec_mode, MODE2 ) ) || EQ_16( st->codec_mode, MODE1 ) )
    3153             :         {
    3154        1772 :             tcx_transition = 1;
    3155        1772 :             move16();
    3156             :         }
    3157             :     }
    3158             : 
    3159             :     /* Perform STFT synthesis */
    3160       18381 :     SynthesisSTFT_ivas_fx( fftBuffer, fftBuffer_exp, timeDomainOutput, hFdCngCom->olapBufferSynth, hFdCngCom->olapWinSyn,
    3161       18381 :                            tcx_transition, hFdCngCom, gen_exc, Q_new, st->element_mode, nchan_out );
    3162       18381 :     scale_sig32( fftBuffer + hFdCngCom->fftlen, sub( FFTLEN, hFdCngCom->fftlen ), sub( fftBuffer_exp, hFdCngCom->fftBuffer_exp ) ); /*Q31 - fftBuffer_exp*/
    3163             : 
    3164             :     {
    3165             :         Word32 Lener, att;
    3166             :         Word16 exp;
    3167             :         /* update CNG excitation energy for LP_CNG */
    3168             : 
    3169             :         /* calculate the residual signal energy */
    3170             :         /*enr = dotp( hFdCngCom->exc_cng, hFdCngCom->exc_cng, hFdCngCom->frameSize ) / hFdCngCom->frameSize;*/
    3171       18381 :         Lener = Dot_productSq16HQ( 1, hFdCngCom->exc_cng, st->L_frame, &exp ); /*Q31 - exp*/
    3172       18381 :         exp = add( sub( shl( sub( 15, *Q_new ), 1 ), 8 ), exp );               /*8 = log2(256)*/
    3173             : 
    3174             :         /* convert log2 of residual signal energy */
    3175             :         /*(float)log10( enr + 0.1f ) / (float)log10( 2.0f );*/
    3176       18381 :         Lener = BASOP_Util_Log2( Lener );                                                     /*Q25*/
    3177       18381 :         Lener = L_add( Lener, L_shl( L_deposit_l( exp ), WORD32_BITS - 1 - LD_DATA_SCALE ) ); /*Q25*/
    3178       18381 :         if ( EQ_16( st->L_frame, L_FRAME16k ) )
    3179             :         {
    3180       11524 :             Lener = L_sub( Lener, 10802114l /*0.3219280949f Q25*/ ); /*log2(320) = 8.3219280949f*/
    3181             :         }
    3182             :         /* decrease the energy in case of WB input */
    3183       18381 :         IF( st->bwidth != NB )
    3184             :         {
    3185       18381 :             IF( EQ_16( st->bwidth, WB ) )
    3186             :             {
    3187        4105 :                 IF( st->CNG_mode >= 0 )
    3188             :                 {
    3189             :                     /* Bitrate adapted attenuation */
    3190           1 :                     att = L_shl( L_deposit_l( ENR_ATT_fx[st->CNG_mode] ), 17 ); /*Q25*/
    3191             :                 }
    3192             :                 ELSE
    3193             :                 {
    3194             :                     /* Use least attenuation for higher bitrates */
    3195        4104 :                     att = L_shl( L_deposit_l( ENR_ATT_fx[4] ), 17 ); /*Q25*/
    3196             :                 }
    3197             :             }
    3198             :             ELSE
    3199             :             {
    3200       14276 :                 att = 384 << 17; /*1.5 Q8<<17=Q25*/
    3201       14276 :                 move16();
    3202             :             }
    3203       18381 :             Lener = L_sub( Lener, att );
    3204             :         }
    3205             :         /*st->lp_ener = 0.8f * stcod->lp_ener + 0.2f * pow( 2.0f, enr );*/
    3206       18381 :         Lener = BASOP_util_Pow2( Lener, 6, &exp );      /*Q31 - exp*/
    3207       18381 :         Lener = Mult_32_16( Lener, 6554 /*0.2f Q15*/ ); /*Q31 - exp*/
    3208       18381 :         exp = sub( 25, exp );
    3209       18381 :         Lener = L_shr( Lener, exp );                                                       /*Q6*/
    3210       18381 :         st->lp_ener_fx = L_add( Mult_32_16( st->lp_ener_fx, 26214 /*0.8f Q15*/ ), Lener ); /*Q6*/
    3211       18381 :         move32();
    3212             :     }
    3213             : 
    3214             :     /* Generate Gaussian random noise in real and imaginary parts of the CLDFB bands
    3215             :       Amplitudes are adjusted to the estimated noise level cngNoiseLevel_flt in each band */
    3216             : 
    3217       18381 :     test();
    3218       18381 :     IF( bufferReal != NULL && ( LT_16( hFdCngCom->numCoreBands, hFdCngCom->regularStopBand ) ) )
    3219             :     {
    3220             :         Word16 bufferReal_exp[CLDFB_NO_COL_MAX];
    3221             :         Word16 bufferImag_exp[CLDFB_NO_COL_MAX];
    3222           0 :         *bufferScale = 0;
    3223           0 :         move16();
    3224           0 :         FOR( j = hFdCngCom->numCoreBands; j < hFdCngCom->regularStopBand; j++ )
    3225             :         {
    3226           0 :             sqrtNoiseLevel_exp = add( CLDFBinvScalingFactor_EXP, sub( cngNoiseLevel_exp, 1 ) );
    3227           0 :             sqrtNoiseLevel = Sqrt32( Mpy_32_16_1( *ptr_level, scaleCldfb ), &sqrtNoiseLevel_exp ); /*Q31 - sqrtNoiseLevel_exp*/
    3228             : 
    3229           0 :             FOR( i = 0; i < hFdCngCom->numSlots; i++ )
    3230             :             {
    3231             :                 /* Real part in CLDFB band */
    3232           0 :                 IF( EQ_16( st->element_mode, IVAS_CPE_MDCT ) || ( EQ_16( st->element_mode, IVAS_SCE ) && st->cng_ism_flag ) )
    3233             :                 {
    3234           0 :                     rand_gauss_fx( &tmp1, seed, Q15 );                                            /*Q15*/
    3235           0 :                     rand_gauss_fx( &tmp2, seed2, Q15 );                                           /*Q15*/
    3236           0 :                     bufferReal[i][j] = L_add( Mpy_32_16_1( tmp1, c1 ), Mpy_32_16_1( tmp2, c2 ) ); /*Q15*/
    3237           0 :                     move32();
    3238           0 :                     bufferReal_exp[j] = Q16;
    3239           0 :                     move16();
    3240             :                 }
    3241             :                 ELSE
    3242             :                 {
    3243           0 :                     rand_gauss_fx( &bufferReal[i][j], seed, Q15 ); /*Q15*/
    3244           0 :                     move32();
    3245           0 :                     bufferReal_exp[j] = Q16;
    3246           0 :                     move16();
    3247             :                 }
    3248             : 
    3249           0 :                 bufferReal[i][j] = Mpy_32_32( bufferReal[i][j], sqrtNoiseLevel ); /*Q31 - ( bufferReal_exp[j] + sqrtNoiseLevel_exp )*/
    3250           0 :                 move32();
    3251           0 :                 bufferReal_exp[j] = add( bufferReal_exp[j], sqrtNoiseLevel_exp );
    3252           0 :                 move16();
    3253             : 
    3254             :                 /* Imaginary part in CLDFB band */
    3255           0 :                 IF( EQ_16( st->element_mode, IVAS_CPE_MDCT ) || ( EQ_16( st->element_mode, IVAS_SCE ) && st->cng_ism_flag ) )
    3256             :                 {
    3257           0 :                     rand_gauss_fx( &tmp1, seed, Q15 );                                            /*Q15*/
    3258           0 :                     rand_gauss_fx( &tmp2, seed2, Q15 );                                           /*Q15*/
    3259           0 :                     bufferImag[i][j] = L_add( Mpy_32_16_1( tmp1, c1 ), Mpy_32_16_1( tmp2, c2 ) ); /*Q15*/
    3260           0 :                     move32();
    3261           0 :                     bufferImag_exp[j] = Q16;
    3262           0 :                     move16();
    3263             :                 }
    3264             :                 ELSE
    3265             :                 {
    3266           0 :                     rand_gauss_fx( &bufferImag[i][j], seed, Q15 ); /*Q15*/
    3267           0 :                     bufferImag_exp[j] = Q16;
    3268           0 :                     move16();
    3269             :                 }
    3270           0 :                 bufferImag[i][j] = Mpy_32_32( bufferImag[i][j], sqrtNoiseLevel ); /*Q31 - ( bufferReal_exp[j] + sqrtNoiseLevel_exp )*/
    3271           0 :                 bufferImag_exp[j] = add( bufferImag_exp[j], sqrtNoiseLevel_exp );
    3272           0 :                 move16();
    3273             : 
    3274           0 :                 move32();
    3275             :             }
    3276           0 :             ptr_level++;
    3277             :         }
    3278             : 
    3279           0 :         FOR( j = hFdCngCom->numCoreBands; j < hFdCngCom->regularStopBand; j++ )
    3280             :         {
    3281           0 :             *bufferScale = s_max( *bufferScale, bufferReal_exp[j] );
    3282           0 :             move16();
    3283           0 :             *bufferScale = s_max( *bufferScale, bufferImag_exp[j] );
    3284           0 :             move16();
    3285             :         }
    3286             : 
    3287           0 :         FOR( j = hFdCngCom->numCoreBands; j < hFdCngCom->regularStopBand; j++ )
    3288             :         {
    3289           0 :             FOR( i = 0; i < hFdCngCom->numSlots; i++ )
    3290             :             {
    3291           0 :                 bufferImag[i][j] = L_shr( bufferImag[i][j], sub( *bufferScale, bufferImag_exp[j] ) ); /*bufferImag_exp*/
    3292           0 :                 move32();
    3293           0 :                 bufferReal[i][j] = L_shr( bufferReal[i][j], sub( *bufferScale, bufferReal_exp[j] ) ); /*bufferReal_exp*/
    3294           0 :                 move32();
    3295             :             }
    3296             :         }
    3297             :     }
    3298             : 
    3299       18381 :     test();
    3300       18381 :     IF( EQ_16( hFdCngCom->frame_type_previous, ACTIVE_FRAME ) && EQ_16( st->codec_mode, MODE2 ) )
    3301             :     {
    3302             :         Word32 old_exc_ener, gain, noise32;
    3303             :         Word16 seed_loc, lpcorder, old_syn, tmp, gain16, N, N2, N4, N8;
    3304             :         Word16 old_exc_ener_exp, gain_exp;
    3305             :         Word16 normFacE, normShiftE, normShiftEM1;
    3306             :         Word16 normFacG, normShiftG, normShiftGM1;
    3307             :         Word16 noiseExp, *old_exc, *old_Aq, *old_syn_pe;
    3308             :         Word16 noise[640], normShiftP2;
    3309             :         Word16 Q_exc, Q_syn;
    3310             : 
    3311             : 
    3312           0 :         assert( hFdCngCom->frameSize <= 640 );
    3313             : 
    3314           0 :         seed_loc = hFdCngCom->seed; /*Q0*/
    3315           0 :         move16();
    3316           0 :         N = hFdCngCom->frameSize; /*Q0*/
    3317           0 :         move16();
    3318           0 :         N2 = shr( hFdCngCom->frameSize, 1 );
    3319             : 
    3320           0 :         IF( st->last_core_bfi > ACELP_CORE )
    3321             :         {
    3322             :             Word16 left_overlap_mode;
    3323           0 :             left_overlap_mode = st->hTcxCfg->tcx_last_overlap_mode;
    3324           0 :             move16();
    3325           0 :             if ( EQ_16( left_overlap_mode, ALDO_WINDOW ) )
    3326             :             {
    3327           0 :                 left_overlap_mode = FULL_OVERLAP;
    3328           0 :                 move16();
    3329             :             }
    3330           0 :             tcx_windowing_synthesis_current_frame( timeDomainOutput, st->hTcxCfg->tcx_mdct_window, st->hTcxCfg->tcx_mdct_window_half, st->hTcxCfg->tcx_mdct_window_minimum, st->hTcxCfg->tcx_mdct_window_length, st->hTcxCfg->tcx_mdct_window_half_length,
    3331           0 :                                                    st->hTcxCfg->tcx_mdct_window_min_length, 0, left_overlap_mode, NULL, NULL, NULL, NULL, NULL, shr( N, 1 ), shr( sub( abs_s( st->hTcxCfg->tcx_offset ), st->hTcxCfg->tcx_offset ), 1 ), 1, 0, 0 );
    3332             : 
    3333           0 :             IF( st->hTcxCfg->last_aldo != 0 )
    3334             :             {
    3335           0 :                 FOR( i = 0; i < hFdCngCom->frameSize - NS2SA( st->sr_core, N_ZERO_MDCT_NS ); i++ )
    3336             :                 {
    3337           0 :                     timeDomainOutput[i] = add( timeDomainOutput[i], shr_r( st->hHQ_core->old_out_LB_fx[i + NS2SA_FX2( st->sr_core, N_ZERO_MDCT_NS )], st->hHQ_core->Q_old_wtda_LB ) ); /*st->q_old_outLB_fx*/
    3338           0 :                     move16();
    3339             :                 }
    3340             :             }
    3341             :             ELSE
    3342             :             {
    3343           0 :                 tcx_windowing_synthesis_past_frame( hTcxDec->syn_Overl, st->hTcxCfg->tcx_mdct_window, st->hTcxCfg->tcx_mdct_window_half, st->hTcxCfg->tcx_mdct_window_minimum,
    3344           0 :                                                     st->hTcxCfg->tcx_mdct_window_length, st->hTcxCfg->tcx_mdct_window_half_length, st->hTcxCfg->tcx_mdct_window_min_length, st->hTcxCfg->tcx_last_overlap_mode );
    3345             : 
    3346           0 :                 FOR( i = 0; i < st->hTcxCfg->tcx_mdct_window_length; i++ )
    3347             :                 {
    3348           0 :                     timeDomainOutput[i] = add( timeDomainOutput[i], shl( hTcxDec->syn_Overl[i], TCX_IMDCT_HEADROOM ) ); /*st->q_old_outLB_fx*/
    3349           0 :                     move16();
    3350             :                 }
    3351             :             }
    3352             :         }
    3353             :         ELSE
    3354             :         {
    3355             : 
    3356             :             /*
    3357             :               - the scaling of the LPCs (e.g. old_Aq) is always Q12 (encoder or decoder)
    3358             : 
    3359             :               - the scaling of the deemphasized signals (e.g. old_syn) is always Q0 (encoder or decoder)
    3360             : 
    3361             :               - the scaling of the excitation signals in the encoder (e.g. old_exc) is Q_new
    3362             :               - the scaling of the preemphasized signals in the encoder (e.g. old_syn_pe) is Q_new-1
    3363             : 
    3364             :               - the scaling of the excitation signals in the decoder (e.g. old_exc) is Q_exc (or stdec->Q_exc)
    3365             :               - the scaling of the preemphasized signals in the decoder (e.g. old_syn_pe) is Q_syn (or stdec->Q_syn)
    3366             :             */
    3367             : 
    3368           0 :             lpcorder = M;
    3369           0 :             move16();
    3370           0 :             old_Aq = st->old_Aq_12_8_fx;                         /*Q12*/
    3371           0 :             old_exc = st->old_exc_fx + sub( L_EXC_MEM_DEC, N2 ); /*Q_exc*/
    3372           0 :             old_syn_pe = st->mem_syn2_fx;                        /*Q_syn*/
    3373           0 :             old_syn = st->syn[lpcorder];                         /*Q_syn*/
    3374           0 :             move16();
    3375           0 :             preemph_fac = st->preemph_fac; /*Q15*/
    3376           0 :             move16();
    3377           0 :             Q_exc = st->Q_exc;
    3378           0 :             move16();
    3379           0 :             Q_syn = st->Q_syn;
    3380           0 :             move16();
    3381             : 
    3382             :             /* shift to be in the range of values supported by getNormReciprocalWord16() */
    3383           0 :             N8 = shr( N2, CNG_NORM_RECIPROCAL_RANGE_SHIFT );
    3384             : 
    3385           0 :             assert( N2 == ( N8 << CNG_NORM_RECIPROCAL_RANGE_SHIFT ) );
    3386             : 
    3387           0 :             normFacE = getNormReciprocalWord16( N8 );
    3388           0 :             normShiftE = BASOP_util_norm_s_bands2shift( N8 );
    3389           0 :             normShiftEM1 = sub( normShiftE, 1 );
    3390           0 :             normShiftP2 = add( normShiftE, CNG_NORM_RECIPROCAL_RANGE_SHIFT );
    3391             : 
    3392           0 :             old_exc_ener = L_shr( L_mult( old_exc[0], old_exc[0] ), normShiftP2 ); /*2*(Q_exc)+1+normShiftP2*/
    3393           0 :             FOR( i = 1; i < N2; i++ )
    3394             :             {
    3395           0 :                 old_exc_ener = L_add( old_exc_ener, L_shr( L_mult( old_exc[i], old_exc[i] ), normShiftP2 ) ); /*2*(Q_exc)+1+normShiftP2*/
    3396             :             }
    3397           0 :             old_exc_ener = L_shl( Mpy_32_16_1( old_exc_ener, shl( normFacE, normShiftEM1 ) ), 1 ); /*Q31*/
    3398             : 
    3399           0 :             old_exc_ener_exp = 0;
    3400           0 :             move16();
    3401           0 :             old_exc_ener = Sqrt32( old_exc_ener, &old_exc_ener_exp ); /*Q31 - old_exc_ener_exp*/
    3402           0 :             old_exc_ener_exp = add( old_exc_ener_exp, ( sub( 15, Q_exc ) ) );
    3403             : 
    3404             :             /* shift to be in the range of values supported by getNormReciprocalWord16() */
    3405           0 :             N4 = shr( N, CNG_NORM_RECIPROCAL_RANGE_SHIFT );
    3406             : 
    3407           0 :             assert( N == ( N4 << CNG_NORM_RECIPROCAL_RANGE_SHIFT ) );
    3408             : 
    3409           0 :             normFacG = getNormReciprocalWord16( N4 );
    3410           0 :             normShiftG = BASOP_util_norm_s_bands2shift( N4 );
    3411           0 :             normShiftGM1 = sub( normShiftG, 1 );
    3412           0 :             normShiftP2 = add( normShiftG, CNG_NORM_RECIPROCAL_RANGE_SHIFT );
    3413             : 
    3414           0 :             gain = L_deposit_l( 0 );
    3415           0 :             FOR( i = 0; i < N; i++ )
    3416             :             {
    3417           0 :                 noise32 = rand_gauss( &seed_loc );
    3418           0 :                 noise[i] = extract_h( noise32 );
    3419           0 :                 move16();
    3420           0 :                 gain = L_add( gain, L_shr( L_mult( noise[i], noise[i] ), normShiftP2 ) );
    3421             :             }
    3422           0 :             gain = L_shl( Mpy_32_16_1( gain, shl( normFacG, normShiftGM1 ) ), 1 ); /*Q31 - gain_exp*/
    3423             : 
    3424           0 :             gain_exp = 2 * CNG_RAND_GAUSS_SHIFT;
    3425           0 :             move16();
    3426           0 :             gain = ISqrt32( gain, &gain_exp ); /*Q31 - gain_exp*/
    3427             : 
    3428           0 :             gain = Mpy_32_32( old_exc_ener, gain ); /*Q31 - old_exc_ener_exp - gain_exp*/
    3429           0 :             gain16 = extract_h( gain );             /*Q15 - old_exc_ener_exp - gain_exp*/
    3430             : 
    3431           0 :             gain_exp = add( old_exc_ener_exp, gain_exp );
    3432           0 :             noiseExp = add( CNG_RAND_GAUSS_SHIFT, gain_exp );
    3433             : 
    3434           0 :             s = sub( 15 - NOISE_HEADROOM, noiseExp );
    3435           0 :             FOR( i = 0; i < N; i++ )
    3436             :             {
    3437           0 :                 noise[i] = shr_sat( mult( noise[i], gain16 ), s ); /*Q15 - noiseExp*/
    3438           0 :                 move16();
    3439             :             }
    3440             : 
    3441           0 :             assert( lpcorder <= 16 );
    3442             : 
    3443           0 :             s = sub( 15 - NOISE_HEADROOM, ( sub( 15, Q_syn ) ) );
    3444           0 :             FOR( i = 0; i < lpcorder; i++ )
    3445             :             {
    3446           0 :                 old_syn_pe_tmp[i] = shr_sat( old_syn_pe[i], s ); /*Q0*/
    3447           0 :                 move16();
    3448             :             }
    3449             : 
    3450           0 :             E_UTIL_synthesis(
    3451             :                 0,              /* i  : scaling to apply for a[0]                 Q0   */
    3452             :                 old_Aq,         /* i  : LP filter coefficients                    Q12  */
    3453             :                 noise,          /* i  : input signal                              Qx   */
    3454             :                 noise,          /* o  : output signal                             Qx-s */
    3455             :                 N,              /* i  : size of filtering                         Q0   */
    3456             :                 old_syn_pe_tmp, /* i/o: memory associated with this filtering.    Q0 */
    3457             :                 0,              /* i  : 0=no update, 1=update of memory.          Q0   */
    3458             :                 lpcorder        /* i  : order of LP filter                        Q0   */
    3459             :             );
    3460             : 
    3461           0 :             tmp = old_syn;
    3462           0 :             move16();
    3463             : 
    3464           0 :             E_UTIL_deemph2(
    3465             :                 NOISE_HEADROOM,
    3466             :                 noise,       /* I/O: signal                       Qx */
    3467             :                 preemph_fac, /* I: deemphasis factor      Qx */
    3468             :                 N,           /* I: vector size              */
    3469             :                 &tmp         /* I/O: memory (signal[-1]) Qx */
    3470             :             );
    3471             : 
    3472           0 :             FOR( i = 0; i < N4; i++ )
    3473             :             {
    3474           0 :                 tmp = mult( noise[i], hFdCngCom->olapWinSyn[i].v.re ); /*Q15 - noiseExp*/
    3475           0 :                 timeDomainOutput[i] = add( timeDomainOutput[i], tmp );
    3476           0 :                 move16();
    3477           0 :                 tmp = mult( noise[( i + N4 )], hFdCngCom->olapWinSyn[( ( N4 - 1 ) - i )].v.im ); /*Q15 - noiseExp*/
    3478           0 :                 timeDomainOutput[( i + N4 )] = add( timeDomainOutput[( i + N4 )], tmp );
    3479           0 :                 move16();
    3480           0 :                 move16();
    3481             :             }
    3482             :         }
    3483             :     }
    3484       18381 :     return;
    3485             : }
    3486             : 
    3487           0 : void generate_comfort_noise_dec_hf_fx(
    3488             :     Word32 **bufferReal, /* o   : matrix to real part of input bands  bufferScale*/
    3489             :     Word32 **bufferImag, /* o   : matrix to imaginary part of input bands  bufferScale*/
    3490             :     Word16 *bufferScale, /* o   : pointer to scalefactor for real and imaginary part of input bands */
    3491             :     Decoder_State *st )
    3492             : {
    3493             :     Word16 i, j, s, sc, sn;
    3494             :     Word16 scaleCLDFB;
    3495             :     Word32 sqrtNoiseLevel;
    3496             :     Word16 randGaussExp;
    3497             :     Word16 cngNoiseLevelExp;
    3498             :     Word16 *seed;
    3499             :     Word32 *cngNoiseLevel;
    3500             :     Word32 *ptr_level;
    3501           0 :     HANDLE_FD_CNG_COM hFdCngCom = st->hFdCngDec->hFdCngCom;
    3502             : 
    3503           0 :     cngNoiseLevel = hFdCngCom->cngNoiseLevel + sub( hFdCngCom->stopFFTbin, hFdCngCom->startBand ); /*Q31 - hFdCngCom->cngNoiseLevelExp*/
    3504           0 :     cngNoiseLevelExp = hFdCngCom->cngNoiseLevelExp;
    3505           0 :     move16();
    3506           0 :     ptr_level = cngNoiseLevel; /*Q31 - hFdCngCom->cngNoiseLevelExp*/
    3507           0 :     seed = &( hFdCngCom->seed );
    3508             : 
    3509             :     /* scaleCLDFB: CLDFBinvScalingFactor_EXP + 1 */
    3510           0 :     scaleCLDFB = mult( hFdCngCom->invScalingFactor, CLDFB_SCALING ); /*CLDFBinvScalingFactor_EXP + 1*/
    3511             : 
    3512           0 :     sn = 0;
    3513           0 :     move16();
    3514           0 :     IF( s_and( cngNoiseLevelExp, 1 ) != 0 )
    3515             :     {
    3516           0 :         sn = add( sn, 1 );
    3517           0 :         cngNoiseLevelExp = add( cngNoiseLevelExp, sn );
    3518             :     }
    3519             : 
    3520           0 :     randGaussExp = CNG_RAND_GAUSS_SHIFT;
    3521           0 :     move16();
    3522             : 
    3523           0 :     IF( LT_16( hFdCngCom->numCoreBands, hFdCngCom->regularStopBand ) )
    3524             :     {
    3525             : 
    3526           0 :         sc = add( shr( add( cngNoiseLevelExp, CLDFBinvScalingFactor_EXP + 1 - 1 ), 1 ), randGaussExp );
    3527           0 :         move16();
    3528           0 :         assert( ( ( cngNoiseLevelExp + CLDFBinvScalingFactor_EXP + 1 - 1 ) & 1 ) == 0 );
    3529             : 
    3530           0 :         FOR( j = hFdCngCom->numCoreBands; j < hFdCngCom->regularStopBand; j++ )
    3531             :         {
    3532             :             /* scaleCLDFB:  CLDFBinvScalingFactor_EXP + 1 */
    3533           0 :             s = 0;
    3534           0 :             move16();
    3535           0 :             sqrtNoiseLevel = Sqrt32( L_shr( Mpy_32_16_1( *ptr_level, scaleCLDFB ), sn ), &s ); /*Q31 - s*/
    3536             : 
    3537           0 :             FOR( i = 0; i < hFdCngCom->numSlots; i++ )
    3538             :             {
    3539             :                 /* Real part in CLDFB band */
    3540           0 :                 bufferReal[i][j] = L_shl( Mpy_32_32( rand_gauss( seed ), sqrtNoiseLevel ), s ); /*bufferScale*/
    3541           0 :                 move32();
    3542             :                 /*fprintf(pFile,"%13.10f\n",WORD322FL_SCALE(bufferReal[i][j],sc));*/
    3543             : 
    3544             :                 /* Imaginary part in CLDFB band */
    3545           0 :                 bufferImag[i][j] = L_shl( Mpy_32_32( rand_gauss( seed ), sqrtNoiseLevel ), s ); /*bufferScale*/
    3546           0 :                 move32();
    3547             :                 /*fprintf(pFile,"%13.10f\n",WORD322FL_SCALE(bufferImag[i][j],sc));*/
    3548             :             }
    3549           0 :             ptr_level = ptr_level + 1; /*Q31 - hFdCngCom->cngNoiseLevelExp*/
    3550             :         }
    3551           0 :         *bufferScale = sub( sc, 15 );
    3552           0 :         move16();
    3553             :     }
    3554           0 : }
    3555             : 
    3556       15059 : void generate_comfort_noise_dec_hf_ivas_fx(
    3557             :     Word32 **bufferReal,         /* o   : matrix to real part of input bands   bufferScale*/
    3558             :     Word32 **bufferImag,         /* o   : matrix to imaginary part of input bands  bufferScale*/
    3559             :     Word16 *bufferScale,         /* o   : pointer to scalefactor for real and imaginary part of input bands */
    3560             :     HANDLE_FD_CNG_COM hFdCngCom, /* i/o: FD_CNG structure containing all buffers and variables  */
    3561             :     const Word16 cng_coh_flag    /* i  : CNG Flag for coherence handling                        Q0*/
    3562             : )
    3563             : {
    3564             :     Word16 i, j, s, sc, sn;
    3565             :     Word16 scaleCLDFB;
    3566             :     Word32 sqrtNoiseLevel;
    3567             :     Word16 randGaussExp;
    3568             :     Word16 cngNoiseLevelExp;
    3569             :     Word16 *seed;
    3570             :     Word16 *seed2;
    3571             :     Word16 c1, c2;
    3572             :     Word32 *ptr_level;
    3573             :     Word32 *cngNoiseLevel;
    3574             :     Word32 tmp1, tmp2;
    3575             : 
    3576       15059 :     cngNoiseLevel = hFdCngCom->cngNoiseLevel + sub( hFdCngCom->stopFFTbin, hFdCngCom->startBand ); /*Q31 - hFdCngCom->cngNoiseLevelExp*/
    3577       15059 :     cngNoiseLevelExp = hFdCngCom->cngNoiseLevelExp;
    3578       15059 :     move16();
    3579       15059 :     ptr_level = cngNoiseLevel; /*Q31 - hFdCngCom->cngNoiseLevelExp*/
    3580             : 
    3581       15059 :     seed = &( hFdCngCom->seed );
    3582             : 
    3583             :     /* scaleCLDFB: CLDFBinvScalingFactor_EXP + 1 */
    3584       15059 :     scaleCLDFB = mult( hFdCngCom->invScalingFactor, CLDFB_SCALING ); /*CLDFBinvScalingFactor_EXP + 1*/
    3585             : 
    3586       15059 :     seed2 = &( hFdCngCom->seed );
    3587             : 
    3588       15059 :     c1 = 0;
    3589       15059 :     move16();
    3590       15059 :     c2 = 0;
    3591       15059 :     move16();
    3592       15059 :     sc = 0;
    3593       15059 :     move16();
    3594             : 
    3595       15059 :     IF( cng_coh_flag )
    3596             :     {
    3597        5310 :         seed2 = &( hFdCngCom->seed2 );
    3598             : 
    3599        5310 :         s = 0;
    3600        5310 :         move16();
    3601             : 
    3602        5310 :         c1 = Sqrt16( hFdCngCom->coherence_fx, &s ); /*Q15 - s*/
    3603        5310 :         c1 = shl( c1, s );                          // Q15
    3604             : 
    3605        5310 :         s = 0;
    3606        5310 :         move16();
    3607        5310 :         c2 = Sqrt16( sub( MAX16B, hFdCngCom->coherence_fx ), &s ); /*Q15 - s*/
    3608        5310 :         c2 = shl( c2, s );                                         // Q15
    3609             :     }
    3610             : 
    3611       15059 :     sn = 0;
    3612       15059 :     move16();
    3613       15059 :     IF( s_and( cngNoiseLevelExp, 1 ) != 0 )
    3614             :     {
    3615        6821 :         sn = add( sn, 1 );
    3616        6821 :         cngNoiseLevelExp = add( cngNoiseLevelExp, sn );
    3617        6821 :         move16();
    3618             :     }
    3619             : 
    3620       15059 :     randGaussExp = CNG_RAND_GAUSS_SHIFT + 1;
    3621       15059 :     move16();
    3622             : 
    3623             :     /*
    3624             :       Generate Gaussian random noise in real and imaginary parts of the CLDFB bands
    3625             :       Amplitudes are adjusted to the estimated noise level cngNoiseLevel_flt in each band
    3626             :     */
    3627       15059 :     IF( LT_16( hFdCngCom->numCoreBands, hFdCngCom->regularStopBand ) )
    3628             :     {
    3629       13431 :         sc = add( shr( add( cngNoiseLevelExp, CLDFBinvScalingFactor_EXP + 1 - 1 ), 1 ), randGaussExp );
    3630       13431 :         move16();
    3631       13431 :         assert( ( ( cngNoiseLevelExp + CLDFBinvScalingFactor_EXP + 1 - 1 ) & 1 ) == 0 );
    3632             : 
    3633      269588 :         FOR( j = hFdCngCom->numCoreBands; j < hFdCngCom->regularStopBand; j++ )
    3634             :         {
    3635     4354669 :             FOR( i = 0; i < hFdCngCom->numSlots; i++ )
    3636             :             {
    3637             :                 /* scaleCLDFB:  CLDFBinvScalingFactor_EXP + 1 */
    3638     4098512 :                 s = 0;
    3639     4098512 :                 move16();
    3640     4098512 :                 sqrtNoiseLevel = Sqrt32( L_shr( Mpy_32_16_1( *ptr_level, scaleCLDFB ), sn ), &s ); /*Q31 - s*/
    3641             : 
    3642     4098512 :                 IF( cng_coh_flag )
    3643             :                 {
    3644     1545152 :                     rand_gauss_fx( &tmp1, seed, Q28 );  /*Q28*/
    3645     1545152 :                     rand_gauss_fx( &tmp2, seed2, Q28 ); /*Q28*/
    3646             : 
    3647     1545152 :                     bufferReal[i][j] = L_add( Mpy_32_16_1( tmp1, c1 ), Mpy_32_16_1( tmp2, c2 ) ); /*bufferScale*/
    3648     1545152 :                     move32();
    3649     1545152 :                     bufferReal[i][j] = L_shl( Mpy_32_32( bufferReal[i][j], sqrtNoiseLevel ), s ); /*bufferScale*/
    3650     1545152 :                     move32();
    3651             : 
    3652     1545152 :                     rand_gauss_fx( &tmp1, seed, Q28 );  /*Q28*/
    3653     1545152 :                     rand_gauss_fx( &tmp2, seed2, Q28 ); /*Q28*/
    3654             : 
    3655     1545152 :                     bufferImag[i][j] = L_add( Mpy_32_16_1( tmp1, c1 ), Mpy_32_16_1( tmp2, c2 ) ); /*bufferScale*/
    3656     1545152 :                     move32();
    3657     1545152 :                     bufferImag[i][j] = L_shl( Mpy_32_32( bufferImag[i][j], sqrtNoiseLevel ), s ); /*bufferScale*/
    3658     1545152 :                     move32();
    3659             :                 }
    3660             :                 ELSE
    3661             :                 {
    3662             :                     /* Real part in CLDFB band */
    3663     2553360 :                     bufferReal[i][j] = L_shl( Mpy_32_32( L_shr( rand_gauss( seed ), 1 ), sqrtNoiseLevel ), s ); /*bufferScale*/
    3664     2553360 :                     move32();
    3665             : 
    3666             :                     /* Imaginary part in CLDFB band */
    3667     2553360 :                     bufferImag[i][j] = L_shl( Mpy_32_32( L_shr( rand_gauss( seed ), 1 ), sqrtNoiseLevel ), s ); /*bufferScale*/
    3668     2553360 :                     move32();
    3669             :                 }
    3670             :             }
    3671      256157 :             ptr_level = ptr_level + 1; /*Q31 - hFdCngCom->cngNoiseLevelExp*/
    3672             :         }
    3673       13431 :         *bufferScale = sub( sc, 15 );
    3674       13431 :         move16();
    3675             :     }
    3676             : 
    3677       15059 :     return;
    3678             : }
    3679             : 
    3680             : 
    3681             : /*
    3682             :     generate_masking_noise_fx
    3683             : 
    3684             :     Parameters:
    3685             : 
    3686             :     timeDomainBuffer       i/o : pointer to time domain output buffer 15Q0
    3687             :     st                     i/o : pointer to FD_CNG_COM structure
    3688             :     bitrate                i   : bitrate
    3689             : 
    3690             :     Function:
    3691             :     Generate additional comfort noise (kind of noise filling)
    3692             : 
    3693             :     Returns: none
    3694             : 
    3695             :     void
    3696             : */
    3697        1023 : void generate_masking_noise_fx(
    3698             :     Word16 *timeDomainBuffer, /* i/o : pointer to time domain output buffer 15Q0 */
    3699             :     Word16 Q,
    3700             :     HANDLE_FD_CNG_COM hFdCngCom /* i/o : pointer to FD_CNG_COM structure */
    3701             :     ,
    3702             :     Word16 length, /*Q0*/
    3703             :     Word16 core /*Q0*/ )
    3704             : {
    3705             :     Word16 i, s, s1, s2, sq, cnt, startBand2, stopFFTbin2;
    3706             :     Word16 scaleExp, fftBufferExp, cngNoiseLevelExp;
    3707             :     Word16 scale, scaleTableSize;
    3708             :     Word16 maskingNoise[L_FRAME16k];
    3709             :     Word32 sqrtNoiseLevel;
    3710             :     Word32 *cngNoiseLevel;
    3711             :     Word32 *fftBuffer;
    3712             :     Word16 *seed;
    3713             : 
    3714             :     // PMTE(); /*IVAS CODE need to be added */
    3715             : 
    3716             :     /* pointer initializations */
    3717        1023 :     cngNoiseLevel = hFdCngCom->cngNoiseLevel; /*Q31 - hFdCngCom->cngNoiseLevelExp*/
    3718        1023 :     fftBuffer = hFdCngCom->fftBuffer;         /*Q31 - hFdCngCom->fftBuffer_exp*/
    3719        1023 :     seed = &( hFdCngCom->seed );
    3720             : 
    3721             :     /* Compute additional CN level */
    3722        1023 :     cngNoiseLevelExp = hFdCngCom->cngNoiseLevelExp;
    3723        1023 :     move16();
    3724             : 
    3725        1023 :     IF( NE_16( core, AMR_WB_CORE ) )
    3726             :     {
    3727        1023 :         scaleTableSize = 18;
    3728        1023 :         move16();
    3729        1023 :         assert( scaleTableSize == ( sizeof( scaleTable_cn_only ) / sizeof( scaleTable_cn_only[0] ) ) );
    3730             : 
    3731        1023 :         scale = -1;
    3732        1023 :         move16();
    3733       15345 :         FOR( i = 0; i < scaleTableSize; i++ )
    3734             :         {
    3735       15345 :             test();
    3736       15345 :             test();
    3737       15345 :             IF( ( EQ_16( hFdCngCom->CngBandwidth, scaleTable_cn_only[i].bwmode ) ) && ( GE_32( hFdCngCom->CngBitrate, scaleTable_cn_only[i].bitrateFrom ) ) && ( LT_32( hFdCngCom->CngBitrate, scaleTable_cn_only[i].bitrateTo ) ) )
    3738             : 
    3739             :             {
    3740        1023 :                 scale = scaleTable_cn_only[i].scale; /*Q14*/
    3741        1023 :                 move16();
    3742        1023 :                 BREAK;
    3743             :             }
    3744             :         }
    3745        1023 :         assert( scale >= 0 );
    3746             :     }
    3747             :     ELSE
    3748             :     {
    3749           0 :         scaleTableSize = 3;
    3750           0 :         move16();
    3751           0 :         assert( scaleTableSize == ( sizeof( scaleTable_cn_only_amrwbio ) / sizeof( scaleTable_cn_only_amrwbio[0] ) ) );
    3752             : 
    3753           0 :         scale = 0;
    3754           0 :         move16();
    3755           0 :         FOR( i = 0; i < scaleTableSize; i++ )
    3756             :         {
    3757           0 :             IF( GE_32( hFdCngCom->CngBitrate, scaleTable_cn_only_amrwbio[i][0] ) )
    3758             :             {
    3759           0 :                 scale = scaleTable_cn_only_amrwbio[i][1]; /*Q14*/
    3760           0 :                 move16();
    3761           0 :                 BREAK;
    3762             :             }
    3763             :         }
    3764             :     }
    3765             : 
    3766             :     /* Exclude clean speech */
    3767             : 
    3768        1023 :     s1 = norm_s( scale );
    3769        1023 :     s2 = norm_s( hFdCngCom->likelihood_noisy_speech );
    3770             : 
    3771             :     /* scaleTable_cn_only[i].scale is scaled by 1 bit */
    3772        1023 :     scaleExp = sub( 1, add( s1, s2 ) );
    3773        1023 :     scale = mult_r( shl( scale, s1 ), shl( hFdCngCom->likelihood_noisy_speech, s2 ) ); /*Q15 - scaleExp*/
    3774             : 
    3775             :     {
    3776             :         /* add exponent of scale and cngNoiseLevel */
    3777        1023 :         fftBufferExp = add( scaleExp, cngNoiseLevelExp );
    3778             : 
    3779             :         /* even scalefactor needed for sqrt calculation */
    3780        1023 :         s = s_and( fftBufferExp, 1 );
    3781        1023 :         fftBufferExp = add( fftBufferExp, s );
    3782             : 
    3783             :         /* sqrt calculation => shift exponent */
    3784        1023 :         fftBufferExp = shr( fftBufferExp, 1 );
    3785             : 
    3786             :         /* consider scaling of random noise */
    3787        1023 :         fftBufferExp = add( fftBufferExp, CNG_RAND_GAUSS_SHIFT );
    3788             : 
    3789        1023 :         cnt = sub( hFdCngCom->stopFFTbin, hFdCngCom->startBand ); /*Q0*/
    3790             :         /*
    3791             :           Generate Gaussian random noise in real and imaginary parts of the FFT bins
    3792             :           Amplitudes are adjusted to the estimated noise level cngNoiseLevel in each bin
    3793             :         */
    3794        1023 :         IF( hFdCngCom->startBand == 0 )
    3795             :         {
    3796             :             /* random noise is scaled by CNG_RAND_GAUSS_SHIFT bits */
    3797             : 
    3798             :             /* DC component in FFT */
    3799             : 
    3800             :             /* -s => consider scalefactor adaptation for sqrt calculation */
    3801           0 :             sq = sub( 0, s );
    3802           0 :             sqrtNoiseLevel = Sqrt32( Mpy_32_16_1( *cngNoiseLevel, scale ), &sq );                   /*Q31 - sq*/
    3803           0 :             hFdCngCom->fftBuffer[0] = L_shl( Mpy_32_32( rand_gauss( seed ), sqrtNoiseLevel ), sq ); /*q31 - hFdCngCom->fftBuffer_exp*/
    3804           0 :             move32();
    3805           0 :             hFdCngCom->fftBuffer[1] = 0;
    3806           0 :             move32();
    3807             : 
    3808           0 :             fftBuffer = hFdCngCom->fftBuffer + 2;
    3809           0 :             cngNoiseLevel++;
    3810             : 
    3811           0 :             cnt = sub( cnt, 1 );
    3812             :         }
    3813             :         ELSE
    3814             :         {
    3815        1023 :             startBand2 = shl( hFdCngCom->startBand, 1 );
    3816        1023 :             set32_fx( hFdCngCom->fftBuffer, 0, startBand2 );
    3817        1023 :             fftBuffer = hFdCngCom->fftBuffer + startBand2; /*Q31 - hFdCngCom->fftBuffer_exp*/
    3818             :         }
    3819             : 
    3820      260865 :         FOR( i = 0; i < cnt; i++ )
    3821             :         {
    3822             :             /* -1 => weighting with 0.5, -s => consider scalefactor adaptation for sqrt calculation */
    3823      259842 :             sq = sub( -1, s );
    3824      259842 :             sqrtNoiseLevel = Sqrt32( Mpy_32_16_1( *cngNoiseLevel, scale ), &sq ); /*Q31 - sq*/
    3825             : 
    3826             :             /* real part in FFT bins */
    3827             : 
    3828             :             /* random noise is scaled by CNG_RAND_GAUSS_SHIFT bits */
    3829      259842 :             *fftBuffer = L_shl( Mpy_32_32( rand_gauss( seed ), sqrtNoiseLevel ), sq ); /*Q31 - hFdCngCom->fftBuffer_exp*/
    3830      259842 :             move32();
    3831      259842 :             fftBuffer++;
    3832             : 
    3833             :             /* imaginary part in FFT bins */
    3834             : 
    3835             :             /* random noise is scaled by CNG_RAND_GAUSS_SHIFT bits */
    3836      259842 :             *fftBuffer = L_shl( Mpy_32_32( rand_gauss( seed ), sqrtNoiseLevel ), sq ); /*Q31 - hFdCngCom->fftBuffer_exp*/
    3837      259842 :             move32();
    3838      259842 :             fftBuffer++;
    3839             : 
    3840      259842 :             cngNoiseLevel++;
    3841             :         }
    3842             : 
    3843             :         /* remaining FFT bins are set to zero */
    3844        1023 :         stopFFTbin2 = shl( hFdCngCom->stopFFTbin, 1 );
    3845        1023 :         set32_fx( hFdCngCom->fftBuffer + stopFFTbin2, 0, sub( hFdCngCom->fftlen, stopFFTbin2 ) );
    3846             : 
    3847             : 
    3848             :         /* perform STFT synthesis */
    3849        1023 :         assert( hFdCngCom->olapBufferSynth2 != NULL );
    3850        1023 :         SynthesisSTFT( hFdCngCom->fftBuffer, fftBufferExp, maskingNoise, hFdCngCom->olapBufferSynth2, hFdCngCom->olapWinSyn,
    3851             :                        0, hFdCngCom, 0, NULL, -1 /*st->element_mode*/, -1 /*nchan_out*/ );
    3852             :         // PMT("parameters need update")
    3853             : 
    3854             : 
    3855             :         /* add some comfort noise on top of decoded signal */
    3856        1023 :         IF( hFdCngCom->frameSize > length )
    3857             :         {
    3858         645 :             FOR( i = 0; i < length; i++ )
    3859             :             {
    3860         640 :                 timeDomainBuffer[i] = add( timeDomainBuffer[i], shr_r( maskingNoise[i], -Q ) ); /*Q0*/
    3861         640 :                 move16();
    3862             :             }
    3863             :         }
    3864             :         ELSE
    3865             :         {
    3866      261626 :             FOR( i = 0; i < hFdCngCom->frameSize; i++ )
    3867             :             {
    3868      260608 :                 timeDomainBuffer[i] = add_sat( timeDomainBuffer[i], shr_r_sat( maskingNoise[i], -Q ) ); /*Q0*/
    3869      260608 :                 move16();
    3870             :             }
    3871             :         }
    3872             :     }
    3873        1023 : }
    3874             : 
    3875             : /*-------------------------------------------------------------------
    3876             :  * generate_masking_noise_update_seed_fx()
    3877             :  *
    3878             :  * Update seed for scenarios where generate_masking_noise_fx() is
    3879             :  * not called based on signal statistics
    3880             :  *-------------------------------------------------------------------*/
    3881             : 
    3882       58348 : void generate_masking_noise_update_seed_fx(
    3883             :     HANDLE_FD_CNG_COM hFdCngCom /* i/o : pointer to FD_CNG_COM structure */
    3884             : )
    3885             : {
    3886             :     Word16 *seed;
    3887             :     Word16 cnt, i;
    3888             : 
    3889             :     /* pointer initializations */
    3890       58348 :     seed = &( hFdCngCom->seed );
    3891             : 
    3892       58348 :     cnt = sub( hFdCngCom->stopFFTbin, hFdCngCom->startBand ); /*Q0*/
    3893             : 
    3894       58348 :     IF( hFdCngCom->startBand == 0 )
    3895             :     {
    3896           0 :         rand_gauss( seed ); /*Q15*/
    3897           0 :         cnt = sub( cnt, 1 );
    3898             :     }
    3899             : 
    3900    16669204 :     FOR( i = 0; i < cnt; i++ )
    3901             :     {
    3902    16610856 :         rand_gauss( seed ); /*Q15*/
    3903    16610856 :         rand_gauss( seed ); /*Q15*/
    3904             :     }
    3905             : 
    3906             : 
    3907       58348 :     return;
    3908             : }
    3909             : 
    3910             : /************************************************************
    3911             :  * Generate additional comfort noise (kind of noise filling) *
    3912             :  ************************************************************/
    3913         264 : void generate_masking_noise_mdct_fx(
    3914             :     Word32 *mdctBuffer,         /* i/o: time-domain signal Q31 - mdctBuffer_e*/
    3915             :     Word16 *mdctBuffer_e,       /* i/o: exponent time-domain signal */
    3916             :     HANDLE_FD_CNG_COM hFdCngCom /* i/o: FD_CNG structure containing all buffers and variables */
    3917             :     ,
    3918             :     Word16 L_frame )
    3919             : {
    3920             :     Word16 i, s, s1, s2, sq, cnt;
    3921             :     Word16 scaleExp, maskingNoiseExp, cngNoiseLevelExp;
    3922             :     Word16 scale, scaleTableSize;
    3923             :     Word32 noise;
    3924             :     Word32 sqrtNoiseLevel;
    3925             :     Word32 maskingNoise[2 * L_FRAME16k];
    3926             :     Word32 *pMaskingNoise;
    3927             :     Word32 *cngNoiseLevel;
    3928             :     Word16 *seed;
    3929             : 
    3930             :     // PMTE(); /*IVAS CODE need to be added */
    3931             :     /* pointer initializations */
    3932         264 :     cngNoiseLevel = hFdCngCom->cngNoiseLevel; /*Q31 - hFdCngCom->cngNoiseLevelExp*/
    3933         264 :     seed = &( hFdCngCom->seed );
    3934             : 
    3935             :     /* Compute additional CN level */
    3936         264 :     cngNoiseLevelExp = hFdCngCom->cngNoiseLevelExp;
    3937         264 :     move16();
    3938             : 
    3939             :     /* Compute additional CN level */
    3940         264 :     scaleTableSize = 18;
    3941         264 :     move16();
    3942         264 :     assert( scaleTableSize == ( sizeof( scaleTable_cn_only ) / sizeof( scaleTable_cn_only[0] ) ) );
    3943             : 
    3944         264 :     scale = -1;
    3945         264 :     move16();
    3946        3960 :     FOR( i = 0; i < scaleTableSize; i++ )
    3947             :     {
    3948        3960 :         test();
    3949        3960 :         test();
    3950        3960 :         IF( ( EQ_16( hFdCngCom->CngBandwidth, scaleTable_cn_only[i].bwmode ) ) && ( GE_32( hFdCngCom->CngBitrate, scaleTable_cn_only[i].bitrateFrom ) ) && ( LT_32( hFdCngCom->CngBitrate, scaleTable_cn_only[i].bitrateTo ) ) )
    3951             :         {
    3952         264 :             scale = scaleTable_cn_only[i].scale; /*Q14*/
    3953         264 :             move16();
    3954         264 :             BREAK;
    3955             :         }
    3956             :     }
    3957         264 :     assert( scale >= 0 );
    3958             : 
    3959             :     /* Exclude clean speech */
    3960         264 :     s1 = norm_s( scale );
    3961         264 :     s2 = norm_s( hFdCngCom->likelihood_noisy_speech );
    3962             : 
    3963             :     /* scaleTable_cn_only[i].scale is scaled by 1 bit */
    3964         264 :     scaleExp = sub( 1, add( s1, s2 ) );
    3965         264 :     scale = mult_r( shl( scale, s1 ), shl( hFdCngCom->likelihood_noisy_speech, s2 ) ); /*Q15 - scaleExp*/
    3966             : 
    3967             :     /* add exponent of scale and cngNoiseLevel */
    3968         264 :     maskingNoiseExp = add( scaleExp, cngNoiseLevelExp );
    3969             : 
    3970             :     /* even scalefactor needed for sqrt calculation */
    3971         264 :     s = s_and( maskingNoiseExp, 1 );
    3972         264 :     maskingNoiseExp = add( maskingNoiseExp, s );
    3973             : 
    3974             :     /* sqrt calculation => shift exponent */
    3975         264 :     maskingNoiseExp = shr( maskingNoiseExp, 1 );
    3976             : 
    3977             :     /* consider scaling of random noise */
    3978         264 :     maskingNoiseExp = add( maskingNoiseExp, CNG_RAND_GAUSS_SHIFT );
    3979             : 
    3980         264 :     cnt = sub( hFdCngCom->stopFFTbin, hFdCngCom->startBand ); /*Q0*/
    3981             : 
    3982             :     /*
    3983             :       Generate Gaussian random noise in real and imaginary parts of the FFT bins
    3984             :       Amplitudes are adjusted to the estimated noise level cngNoiseLevel in each bin
    3985             :     */
    3986         264 :     IF( hFdCngCom->startBand == 0 )
    3987             :     {
    3988             :         /* random noise is scaled by CNG_RAND_GAUSS_SHIFT bits */
    3989             : 
    3990             :         /* DC component in FFT */
    3991             : 
    3992             :         /* -1 => weighting with 0.5, -s => consider scalefactor adaptation for sqrt calculation */
    3993           0 :         sq = sub( -1, s );
    3994           0 :         sqrtNoiseLevel = Sqrt32( Mpy_32_16_1( *cngNoiseLevel, scale ), &sq );           /*Q31 - sq*/
    3995           0 :         maskingNoise[0] = L_shl( Mpy_32_32( rand_gauss( seed ), sqrtNoiseLevel ), sq ); /*Q15*/
    3996           0 :         move32();
    3997             : 
    3998           0 :         pMaskingNoise = &maskingNoise[1]; /*Q15*/
    3999           0 :         cngNoiseLevel++;
    4000             : 
    4001           0 :         cnt = sub( cnt, 1 );
    4002             :     }
    4003             :     ELSE
    4004             :     {
    4005         264 :         set32_fx( maskingNoise, 0, hFdCngCom->startBand );
    4006         264 :         pMaskingNoise = maskingNoise + hFdCngCom->startBand; /*Q15*/
    4007             :     }
    4008             : 
    4009       67320 :     FOR( i = 0; i < cnt; i++ )
    4010             :     {
    4011             :         /* -1 => weighting with 0.5, -s => consider scalefactor adaptation for sqrt calculation */
    4012       67056 :         sq = sub( -1, s );
    4013       67056 :         sqrtNoiseLevel = Sqrt32( Mpy_32_16_1( *cngNoiseLevel, scale ), &sq ); /*Q31 - sq*/
    4014             : 
    4015             :         /* real part in FFT bins */
    4016             : 
    4017             :         /* random noise is scaled by CNG_RAND_GAUSS_SHIFT bits */
    4018       67056 :         *pMaskingNoise = L_shl( Mpy_32_32( rand_gauss( seed ), sqrtNoiseLevel ), sq ); /*Q15*/
    4019       67056 :         move32();
    4020       67056 :         pMaskingNoise++;
    4021             : 
    4022       67056 :         cngNoiseLevel++;
    4023             :     }
    4024             : 
    4025             :     /* re-normalization of energy level
    4026             :        16 * 0.79056941504 = sqrt(NORM_MDCT_FACTOR)
    4027             :     */
    4028             :     assert( NORM_MDCT_FACTOR == 160 );
    4029             : 
    4030             :     /* do weighting with factor 0.79056941504 later */
    4031         264 :     maskingNoiseExp = add( maskingNoiseExp, 4 );
    4032             : 
    4033         264 :     s = s_max( *mdctBuffer_e, maskingNoiseExp );
    4034         264 :     s1 = sub( s, *mdctBuffer_e );
    4035         264 :     s2 = sub( s, maskingNoiseExp );
    4036             : 
    4037             :     /* avoid rescaling of mdct samples if no comfort noise is added */
    4038         264 :     IF( scale != 0 )
    4039             :     {
    4040             :         /* Add some comfort noise on top of decoded signal */
    4041           0 :         IF( s1 == 0 )
    4042             :         {
    4043           0 :             FOR( i = 0; i < hFdCngCom->stopFFTbin; i++ )
    4044             :             {
    4045             :                 /* If shifting negative noise values the lowest result is -1 but never 0.
    4046             :                    Shift positive noise values to avoid unwanted amplification of these small values later */
    4047           0 :                 noise = L_shr( Mpy_32_16_1( L_abs( maskingNoise[i] ), 25905 /*0.79056941504 Q15*/ ), s2 ); /*Q31 - maskingNoiseExp - s2*/
    4048             : 
    4049           0 :                 if ( maskingNoise[i] < 0 )
    4050             :                 {
    4051           0 :                     noise = L_negate( noise );
    4052             :                 }
    4053             : 
    4054           0 :                 mdctBuffer[i] = L_add( mdctBuffer[i], noise ); /*Q31 - s*/
    4055           0 :                 move32();
    4056             :             }
    4057             :         }
    4058             :         ELSE
    4059             :         {
    4060           0 :             FOR( i = 0; i < hFdCngCom->stopFFTbin; i++ )
    4061             :             {
    4062           0 :                 mdctBuffer[i] = L_add( L_shr( mdctBuffer[i], s1 ),
    4063             :                                        Mpy_32_16_1( maskingNoise[i], 25905 /*0.79056941504 Q15*/ ) ); /*Q31 - s*/
    4064           0 :                 move32();
    4065             :             }
    4066           0 :             FOR( i = hFdCngCom->stopFFTbin; i < L_frame; i++ )
    4067             :             {
    4068           0 :                 mdctBuffer[i] = L_shr( mdctBuffer[i], s1 ); /*Q31 - s*/
    4069           0 :                 move32();
    4070             :             }
    4071           0 :             *mdctBuffer_e = s;
    4072           0 :             move16();
    4073             :         }
    4074             :     }
    4075         264 : }
    4076             : 
    4077       22705 : void generate_masking_noise_mdct_ivas_fx(
    4078             :     Word32 *mdctBuffer,   /* i/o: time-domain signal Q31 - mdctBuffer_e*/
    4079             :     Word16 *mdctBuffer_e, /* i/o: exponent time-domain signal */
    4080             :     HANDLE_FD_CNG_COM hFdCngCom /* i/o: FD_CNG structure containing all buffers and variables */ )
    4081             : {
    4082             :     Word16 i, sq, cnt;
    4083             :     Word16 cngNoiseLevelExp;
    4084             :     Word32 scale, temp;
    4085             :     Word32 sqrtNoiseLevel;
    4086             :     Word32 maskingNoise[2 * L_FRAME16k];
    4087             :     Word32 *pMaskingNoise;
    4088             :     Word32 *cngNoiseLevel;
    4089             :     Word16 *seed;
    4090             : 
    4091             :     // PMTE(); /*IVAS CODE need to be added */
    4092             :     /* pointer initializations */
    4093       22705 :     cngNoiseLevel = hFdCngCom->cngNoiseLevel; /*Q31 - hFdCngCom->cngNoiseLevelExp*/
    4094       22705 :     seed = &( hFdCngCom->seed );
    4095             : 
    4096             :     /* Compute additional CN level */
    4097       22705 :     cngNoiseLevelExp = hFdCngCom->cngNoiseLevelExp;
    4098       22705 :     move16();
    4099             : 
    4100       22705 :     scale = ONE_IN_Q30;
    4101       22705 :     move32();
    4102             : 
    4103       22705 :     cnt = sub( hFdCngCom->stopFFTbin, hFdCngCom->startBand );
    4104             : 
    4105             :     /* skip noise generating if level is very low, to avoid problems with possibly running into denormals */
    4106       22705 :     IF( hFdCngCom->likelihood_noisy_speech > 0 )
    4107             :     {
    4108       11144 :         FOR( i = 0; i < SIZE_SCALE_TABLE_CN; i++ )
    4109             :         {
    4110       11144 :             test();
    4111       11144 :             test();
    4112       11144 :             IF( EQ_16( hFdCngCom->CngBandwidth, scaleTable_cn_only[i].bwmode ) &&
    4113             :                 GE_32( hFdCngCom->CngBitrate, scaleTable_cn_only[i].bitrateFrom ) &&
    4114             :                 LE_32( hFdCngCom->CngBitrate, scaleTable_cn_only[i].bitrateTo ) )
    4115             :             {
    4116         810 :                 BREAK;
    4117             :             }
    4118             :         }
    4119             : 
    4120             :         /* Exclude clean speech */
    4121         810 :         scale = L_mult( scaleTable_cn_only[i].scale, hFdCngCom->likelihood_noisy_speech ); // Q30 (14 + 15 + 1)
    4122             : 
    4123             :         /*
    4124             :           Generate Gaussian random noise in real and imaginary parts of the FFT bins
    4125             :           Amplitudes are adjusted to the estimated noise level cngNoiseLevel in each bin
    4126             :         */
    4127         810 :         IF( hFdCngCom->startBand == 0 )
    4128             :         {
    4129             :             /* *cngNoiseLevel * scale * 0.5 */
    4130           0 :             temp = Mpy_32_32( *cngNoiseLevel, scale ); // exp = cngNoiseLevelExp (cngNoiseLevelExp + Q30(scale) + 1(0.5f) - 31)
    4131           0 :             sq = cngNoiseLevelExp;
    4132           0 :             move16();
    4133             : 
    4134           0 :             sqrtNoiseLevel = Sqrt32( temp, &sq ); /*Q31 - sq*/
    4135             : 
    4136           0 :             rand_gauss_fx( &temp, seed, Q15 ); // Q15
    4137             : 
    4138           0 :             maskingNoise[0] = L_shl( Mpy_32_32( temp, sqrtNoiseLevel ), sq ); // Q15
    4139           0 :             move32();
    4140             : 
    4141           0 :             pMaskingNoise = &maskingNoise[1]; /*Q15*/
    4142           0 :             cngNoiseLevel++;
    4143           0 :             cnt = sub( cnt, 1 );
    4144             :         }
    4145             :         ELSE
    4146             :         {
    4147         810 :             set32_fx( maskingNoise, 0, hFdCngCom->startBand );
    4148         810 :             pMaskingNoise = maskingNoise + hFdCngCom->startBand; /*Q15*/
    4149             :         }
    4150             : 
    4151      226902 :         FOR( i = 0; i < cnt; i++ )
    4152             :         {
    4153             :             /* MDCT bins */
    4154             :             /* *cngNoiseLevel * scale * 0.5 */
    4155      226092 :             temp = Mpy_32_32( *cngNoiseLevel, scale ); // exp = cngNoiseLevelExp (cngNoiseLevelExp + Q30(scale) + 1(0.5f) - 31)
    4156      226092 :             sq = cngNoiseLevelExp;
    4157      226092 :             move16();
    4158             : 
    4159      226092 :             sqrtNoiseLevel = Sqrt32( temp, &sq ); /*Q31 - sq*/
    4160             : 
    4161      226092 :             rand_gauss_fx( &temp, seed, Q15 ); // Q15
    4162             : 
    4163      226092 :             *pMaskingNoise = L_shl( Mpy_32_32( temp, sqrtNoiseLevel ), sq ); // Q15
    4164      226092 :             move32();
    4165             : 
    4166      226092 :             pMaskingNoise++;
    4167      226092 :             cngNoiseLevel++;
    4168             :         }
    4169             : 
    4170             :         /*re-normalization of energy level: M/sqrt(2)*/
    4171         810 :         v_multc_fixed( maskingNoise, SQRT_NORM_MDCT_FACTOR_Q27, maskingNoise, hFdCngCom->stopFFTbin ); // Q11
    4172             : 
    4173         810 :         scale_sig32( maskingNoise, hFdCngCom->stopFFTbin, sub( 20, *mdctBuffer_e ) ); // exp = *mdctBuffer_e
    4174             : 
    4175             :         /* Add some comfort noise on top of decoded signal */
    4176         810 :         v_add_fixed( maskingNoise, mdctBuffer, mdctBuffer, hFdCngCom->stopFFTbin, 1 );
    4177         810 :         *mdctBuffer_e = sub( *mdctBuffer_e, 1 );
    4178         810 :         move16();
    4179             :     }
    4180             :     ELSE
    4181             :     {
    4182             :         /* very low level case - just update random seeds */
    4183       21895 :         IF( hFdCngCom->startBand == 0 )
    4184             :         {
    4185           0 :             rand_gauss_fx( &maskingNoise[0], seed, Q15 ); // Q15
    4186           0 :             cngNoiseLevel++;
    4187           0 :             cnt = sub( cnt, 1 );
    4188             :         }
    4189             : 
    4190     6261817 :         FOR( i = 0; i < cnt; i++ )
    4191             :         {
    4192     6239922 :             rand_gauss_fx( &maskingNoise[0], seed, Q15 ); // Q15
    4193     6239922 :             move32();
    4194             :         }
    4195             :     }
    4196             : 
    4197       22705 :     return;
    4198             : }
    4199             : 
    4200             : 
    4201             : /*-------------------------------------------------------------------
    4202             :  * initFdCngDec()
    4203             :  *
    4204             :  * Initialize an instance of type FD_CNG
    4205             :  *-------------------------------------------------------------------*/
    4206      524837 : void configureFdCngDec_ivas_fx(
    4207             :     HANDLE_FD_CNG_DEC hFdCngDec, /* i/o: Contains the variables related to the FD-based CNG process */
    4208             :     const Word16 bwidth,         /*Q0*/
    4209             :     const Word32 total_brate,    /*Q0*/
    4210             :     const Word16 L_frame,        /*Q0*/
    4211             :     const Word16 last_L_frame,   /*Q0*/
    4212             :     const Word16 element_mode /*Q0*/ )
    4213             : {
    4214             :     Word16 j, stopBandFR;
    4215      524837 :     HANDLE_FD_CNG_COM hsCom = hFdCngDec->hFdCngCom;
    4216             : 
    4217      524837 :     hsCom->CngBandwidth = bwidth; /*Q0*/
    4218      524837 :     move16();
    4219      524837 :     if ( EQ_16( hsCom->CngBandwidth, FB ) )
    4220             :     {
    4221      347807 :         hsCom->CngBandwidth = SWB;
    4222      347807 :         move16();
    4223             :     }
    4224      524837 :     test();
    4225      524837 :     IF( NE_32( total_brate, FRAME_NO_DATA ) && NE_32( total_brate, SID_2k40 ) )
    4226             :     {
    4227      524540 :         hsCom->CngBitrate = total_brate; /*Q0*/
    4228      524540 :         move32();
    4229             :     }
    4230         297 :     ELSE IF( EQ_32( hsCom->CngBitrate, -1 ) )
    4231             :     {
    4232             :         /* set minimum active CBR bitrate IF CngBitrate is uninitialized */
    4233           0 :         IF( element_mode > EVS_MONO )
    4234             :         {
    4235           0 :             hsCom->CngBitrate = IVAS_13k2;
    4236           0 :             move32();
    4237             :         }
    4238             :         ELSE
    4239             :         {
    4240           0 :             hsCom->CngBitrate = ACELP_7k20;
    4241           0 :             move32();
    4242             :         }
    4243             :     }
    4244             : 
    4245             :     /* FD-CNG config for MDCT-Stereo is always the same (since for > 48 kbps only) */
    4246             :     /* This may need adjustment in the future IF 2TC DTX for some mode uses MDCT-Stereo DTX for lower bitrates too */
    4247      524837 :     if ( EQ_16( element_mode, IVAS_CPE_MDCT ) )
    4248             :     {
    4249      417535 :         hsCom->CngBitrate = IVAS_48k;
    4250      417535 :         move32();
    4251             :     }
    4252      524837 :     hsCom->numSlots = 16;
    4253      524837 :     move32();
    4254             : 
    4255             :     /* NB configuration */
    4256      524837 :     IF( EQ_16( bwidth, NB ) )
    4257             :     {
    4258           0 :         hsCom->FdCngSetup = FdCngSetup_nb;
    4259           0 :         hsCom->numCoreBands = 16;
    4260           0 :         move16();
    4261           0 :         hsCom->regularStopBand = 16;
    4262           0 :         move16();
    4263             :     }
    4264             : 
    4265             :     /* WB configuration */
    4266      524837 :     ELSE IF( EQ_16( bwidth, WB ) )
    4267             :     {
    4268             :         /* FFT 6.4kHz, no CLDFB */
    4269        1064 :         test();
    4270        1064 :         test();
    4271        1064 :         IF( LE_32( hsCom->CngBitrate, ACELP_8k00 ) && EQ_16( L_frame, L_FRAME ) )
    4272             :         {
    4273         312 :             hsCom->FdCngSetup = FdCngSetup_wb1;
    4274         312 :             hsCom->numCoreBands = 16;
    4275         312 :             move16();
    4276         312 :             hsCom->regularStopBand = 16;
    4277         312 :             move16();
    4278             :         }
    4279             :         /* FFT 6.4kHz, CLDFB 8.0kHz */
    4280         752 :         ELSE IF( LE_32( hsCom->CngBitrate, ACELP_13k20 ) || EQ_16( L_frame, L_FRAME ) )
    4281             :         {
    4282         149 :             hsCom->FdCngSetup = FdCngSetup_wb2;
    4283         149 :             hsCom->numCoreBands = 16;
    4284         149 :             move16();
    4285         149 :             hsCom->regularStopBand = 20;
    4286         149 :             move16();
    4287         149 :             IF( EQ_16( L_frame, L_FRAME16k ) )
    4288             :             {
    4289           8 :                 hsCom->FdCngSetup = FdCngSetup_wb2;
    4290           8 :                 hsCom->numCoreBands = 20;
    4291           8 :                 move16();
    4292           8 :                 hsCom->regularStopBand = 20;
    4293           8 :                 move16();
    4294           8 :                 hsCom->FdCngSetup.fftlen = 640;
    4295           8 :                 move16();
    4296           8 :                 hsCom->FdCngSetup.stopFFTbin = 256;
    4297           8 :                 move16();
    4298             :             }
    4299             :         }
    4300             :         /* FFT 8.0kHz, no CLDFB */
    4301             :         ELSE
    4302             :         {
    4303         603 :             hsCom->FdCngSetup = FdCngSetup_wb3;
    4304         603 :             hsCom->numCoreBands = 20;
    4305         603 :             move16();
    4306         603 :             hsCom->regularStopBand = 20;
    4307         603 :             move16();
    4308             :         }
    4309             :     }
    4310             : 
    4311             :     /* SWB/FB configuration */
    4312             :     ELSE
    4313             :     {
    4314             :         /* FFT 6.4kHz, CLDFB 14kHz */
    4315      523773 :         IF( EQ_16( L_frame, L_FRAME ) )
    4316             :         {
    4317        2663 :             hsCom->FdCngSetup = FdCngSetup_swb1;
    4318        2663 :             hsCom->numCoreBands = 16;
    4319        2663 :             move16();
    4320        2663 :             hsCom->regularStopBand = 35;
    4321        2663 :             move16();
    4322             :         }
    4323             :         /* FFT 8.0kHz, CLDFB 16kHz */
    4324             :         ELSE
    4325             :         {
    4326      521110 :             hsCom->FdCngSetup = FdCngSetup_swb2;
    4327      521110 :             hsCom->numCoreBands = 20;
    4328      521110 :             move16();
    4329      521110 :             hsCom->regularStopBand = 40;
    4330      521110 :             move16();
    4331      521110 :             test();
    4332      521110 :             if ( EQ_16( last_L_frame, L_FRAME ) && EQ_16( element_mode, IVAS_CPE_DFT ) )
    4333             :             {
    4334         139 :                 hsCom->regularStopBand = 35;
    4335         139 :                 move16();
    4336             :             }
    4337             :         }
    4338             :     }
    4339             : 
    4340             : 
    4341      524837 :     hsCom->fftlen = hsCom->FdCngSetup.fftlen;
    4342      524837 :     move16();
    4343      524837 :     hsCom->stopFFTbin = hsCom->FdCngSetup.stopFFTbin;
    4344      524837 :     move16();
    4345             : 
    4346             :     /* Configure the SID quantizer and the Comfort Noise Generator */
    4347             : 
    4348      524837 :     hsCom->startBand = 2;
    4349      524837 :     move16();
    4350      524837 :     hsCom->stopBand = add( hsCom->FdCngSetup.sidPartitions[( hsCom->FdCngSetup.numPartitions - 1 )], 1 ); /*Q0*/
    4351      524837 :     initPartitions( hsCom->FdCngSetup.sidPartitions, hsCom->FdCngSetup.numPartitions, hsCom->startBand, hsCom->stopBand, hsCom->part, &hsCom->npart, hsCom->midband, hsCom->psize, hsCom->psize_norm, &hsCom->psize_norm_exp, hsCom->psize_inv, 0 );
    4352             : 
    4353      524837 :     IF( EQ_16( hsCom->stopFFTbin, 160 ) )
    4354             :     {
    4355           0 :         hsCom->nFFTpart = 17;
    4356           0 :         move16();
    4357             :     }
    4358      524837 :     ELSE IF( EQ_16( hsCom->stopFFTbin, 256 ) )
    4359             :     {
    4360        3124 :         hsCom->nFFTpart = 20;
    4361        3124 :         move16();
    4362             :     }
    4363             :     ELSE
    4364             :     {
    4365      521713 :         hsCom->nFFTpart = 21;
    4366      521713 :         move16();
    4367             :     }
    4368      524837 :     hsCom->nCLDFBpart = sub( hsCom->npart, hsCom->nFFTpart ); /*Q0*/
    4369      524837 :     move16();
    4370     2098968 :     FOR( j = 0; j < hsCom->nCLDFBpart; j++ )
    4371             :     {
    4372     1574131 :         hsCom->CLDFBpart[j] = sub( hsCom->part[( j + hsCom->nFFTpart )], sub( hsCom->stopFFTbin, hsCom->startBand ) ); /*Q0*/
    4373     1574131 :         move16();
    4374     1574131 :         hsCom->CLDFBpsize_inv[j] = hsCom->psize_inv[( j + hsCom->nFFTpart )];
    4375     1574131 :         move16();
    4376             :     }
    4377             : 
    4378      524837 :     stopBandFR = 40; //(Word16)floor(1000.f /*Hz*/ / 25.f /*Hz/Bin*/);
    4379      524837 :     move16();
    4380      524837 :     if ( GT_16( stopBandFR, hsCom->stopFFTbin ) )
    4381             :     {
    4382           0 :         stopBandFR = hsCom->stopFFTbin; /*Q0*/
    4383           0 :         move16();
    4384             :     }
    4385             : 
    4386      524837 :     initPartitions( hsCom->FdCngSetup.shapingPartitions, hsCom->FdCngSetup.numShapingPartitions, hsCom->startBand, hsCom->stopFFTbin, hFdCngDec->part_shaping, &hFdCngDec->npart_shaping, hFdCngDec->midband_shaping, hFdCngDec->psize_shaping, hFdCngDec->psize_shaping_norm, &hFdCngDec->psize_shaping_norm_exp, hFdCngDec->psize_inv_shaping, stopBandFR );
    4387             : 
    4388      524837 :     hFdCngDec->nFFTpart_shaping = hFdCngDec->npart_shaping; /*Q0*/
    4389      524837 :     move16();
    4390             : 
    4391      524837 :     BASOP_getTables( &hsCom->olapWinAna, NULL, NULL, shr( hsCom->fftlen, 1 ) );
    4392      524837 :     BASOP_getTables( &hsCom->olapWinSyn, NULL, NULL, shr( hsCom->fftlen, 2 ) );
    4393             : 
    4394      524837 :     SWITCH( hsCom->fftlen )
    4395             :     {
    4396        3116 :         case 512:
    4397        3116 :             hsCom->olapWinAna_fx = olapWinAna512_fx; /*Q30*/
    4398        3116 :             hsCom->fftSineTab_fx = NULL;
    4399        3116 :             hsCom->olapWinSyn_fx = olapWinSyn256_fx; /*Q15*/
    4400        3116 :             hsCom->fftlenShift = 8;
    4401        3116 :             move16();
    4402        3116 :             hsCom->fftlenFac = 32767 /*1.0 Q15*/;
    4403        3116 :             move16();
    4404        3116 :             BREAK;
    4405      521721 :         case 640:
    4406      521721 :             hsCom->olapWinAna_fx = olapWinAna640_fx; /*Q30*/
    4407      521721 :             hsCom->fftSineTab_fx = fftSineTab640_fx; /*Q15*/
    4408      521721 :             hsCom->olapWinSyn_fx = olapWinSyn320_fx; /*Q15*/
    4409      521721 :             hsCom->fftlenShift = 9;
    4410      521721 :             move16();
    4411      521721 :             hsCom->fftlenFac = 20480 /*0.625 Q15*/;
    4412      521721 :             move16();
    4413      521721 :             BREAK;
    4414           0 :         default:
    4415           0 :             assert( !"Unsupported FFT length for FD-based CNG" );
    4416             :             BREAK;
    4417             :     }
    4418      524837 :     BASOP_getTables( &hsCom->olapWinAna, NULL, NULL, shr( hsCom->fftlen, 1 ) );
    4419      524837 :     BASOP_getTables( &hsCom->olapWinSyn, NULL, NULL, shr( hsCom->fftlen, 2 ) );
    4420      524837 :     hsCom->frameSize = shr( hsCom->fftlen, 1 );
    4421             : 
    4422      524837 :     return;
    4423             : }
    4424             : 
    4425             : /*-------------------------------------------------------------------
    4426             :  * FdCng_decodeSID_ivas_fx()
    4427             :  *
    4428             :  * Decode the FD-CNG bitstream
    4429             :  *-------------------------------------------------------------------*/
    4430             : 
    4431        1913 : void FdCng_decodeSID_ivas_fx(
    4432             :     Decoder_State *st /* i/o: decoder state structure */
    4433             : )
    4434             : {
    4435             :     Word16 N;
    4436             :     Word32 *sidNoiseEst;
    4437             :     Word32 gain;
    4438             :     Word16 i, index;
    4439             :     Word32 v[32];
    4440             :     Word16 indices[32];
    4441             :     HANDLE_FD_CNG_COM hFdCngCom;
    4442             :     Word32 *invTrfMatrix_fx;
    4443             :     Word32 tmpRAM_fx[FDCNG_VQ_MAX_LEN][FDCNG_VQ_DCT_MAXTRUNC];
    4444             :     Word16 tmp16;
    4445             : 
    4446        1913 :     IF( st->element_mode == EVS_MONO )
    4447             :     {
    4448           0 :         tmp16 = GAIN_Q_OFFSET_EVS_FX_Q0;
    4449           0 :         move16();
    4450             :     }
    4451             :     ELSE
    4452             :     {
    4453        1913 :         tmp16 = GAIN_Q_OFFSET_IVAS_FX_Q0;
    4454        1913 :         move16();
    4455             :     }
    4456             : 
    4457        1913 :     const Word16 gain_q_offset = tmp16; /* Q0 */
    4458        1913 :     move16();
    4459             : 
    4460        1913 :     invTrfMatrix_fx = (Word32 *) tmpRAM_fx; /*Q31*/
    4461             : 
    4462        1913 :     hFdCngCom = ( st->hFdCngDec )->hFdCngCom;
    4463             : 
    4464        1913 :     sidNoiseEst = hFdCngCom->sidNoiseEst; /*Q16*/
    4465             : 
    4466        1913 :     N = hFdCngCom->npart; /*Q0*/
    4467        1913 :     move16();
    4468        1913 :     gain = 0;
    4469        1913 :     move32();
    4470        1913 :     hFdCngCom->sid_frame_counter = add( hFdCngCom->sid_frame_counter, 1 );
    4471        1913 :     move16();
    4472             : 
    4473             :     /* Read bitstream */
    4474       13391 :     FOR( i = 0; i < FD_CNG_stages_37bits; i++ )
    4475             :     {
    4476       11478 :         indices[i] = get_next_indice_fx( st, bits_37bits[i] ); /*Q0*/
    4477       11478 :         move16();
    4478             :     }
    4479             : 
    4480        1913 :     index = get_next_indice_fx( st, 7 );
    4481             : 
    4482             :     /* MSVQ decoder */
    4483             : 
    4484        1913 :     IF( st->element_mode != EVS_MONO )
    4485             :     {
    4486        1913 :         create_IDCT_N_Matrix_fx( invTrfMatrix_fx, FDCNG_VQ_MAX_LEN, FDCNG_VQ_DCT_MAXTRUNC, FDCNG_VQ_MAX_LEN * FDCNG_VQ_DCT_MAXTRUNC );
    4487        1913 :         msvq_dec_fx( ivas_cdk_37bits_fx, NULL, NULL, FD_CNG_stages_37bits, N, FD_CNG_maxN_37bits, indices, 1, invTrfMatrix_fx, v, NULL, 7 );
    4488             :     }
    4489             :     ELSE
    4490             :     { /* Legacy EVS_MONO MSVQ tables */
    4491           0 :         msvq_dec_fx( cdk_37bits, NULL, NULL, FD_CNG_stages_37bits, N, FD_CNG_maxN_37bits, indices, 0, NULL, v, NULL, 7 );
    4492             :     }
    4493             : 
    4494             : 
    4495             :     /* Decode gain */
    4496             :     // gain = ((float)index - gain_q_offset) / 1.5f;
    4497        1913 :     gain = L_mult0( sub( index, gain_q_offset ), 21845 ); // Q15
    4498             : 
    4499             :     /* Apply gain and undo log */
    4500             :     Word16 res_exp[NPART];
    4501        1913 :     Word16 max_res_exp = 0;
    4502        1913 :     move16();
    4503       46554 :     FOR( i = 0; i < N; i++ )
    4504             :     {
    4505       44641 :         sidNoiseEst[i] = BASOP_util_Pow2( Mpy_32_32( L_add( v[i], gain ), LOG_10_BASE_2_BY_10_Q31 ), Q16, &res_exp[i] ); /*Q31 - res_exp[i]*/
    4506       44641 :         move32();
    4507       44641 :         if ( LT_16( max_res_exp, res_exp[i] ) )
    4508             :         {
    4509        1299 :             max_res_exp = res_exp[i];
    4510        1299 :             move16();
    4511             :         }
    4512             :     }
    4513             : 
    4514       46554 :     FOR( i = 0; i < N; i++ )
    4515             :     {
    4516       44641 :         sidNoiseEst[i] = L_shr( sidNoiseEst[i], sub( max_res_exp, res_exp[i] ) ); /*Q31 - max_res_exp*/
    4517       44641 :         move32();
    4518             :     }
    4519             : 
    4520        1913 :     hFdCngCom->sidNoiseEstExp = max_res_exp;
    4521        1913 :     move16();
    4522             : 
    4523             :     /* NB last band energy compensation */
    4524             : 
    4525        1913 :     IF( hFdCngCom->CngBandwidth == NB )
    4526             :     {
    4527           0 :         sidNoiseEst[( N - 1 )] = Mpy_32_16_1( sidNoiseEst[( N - 1 )], NB_LAST_BAND_SCALE ); /*Q31 - max_res_exp*/
    4528           0 :         move32();
    4529             :     }
    4530             : 
    4531        1913 :     test();
    4532        1913 :     IF( EQ_16( hFdCngCom->CngBandwidth, SWB ) && LE_32( hFdCngCom->CngBitrate, ACELP_13k20 ) )
    4533             :     {
    4534         475 :         sidNoiseEst[( N - 1 )] = Mpy_32_16_1( sidNoiseEst[( N - 1 )], SWB_13k2_LAST_BAND_SCALE ); /*Q31 - max_res_exp*/
    4535         475 :         move32();
    4536             :     }
    4537             : 
    4538        1913 :     scalebands( sidNoiseEst, hFdCngCom->part, hFdCngCom->npart, hFdCngCom->midband, hFdCngCom->nFFTpart, sub( hFdCngCom->stopBand, hFdCngCom->startBand ), hFdCngCom->cngNoiseLevel, 1 );
    4539        1913 :     Word16 shift1 = L_norm_arr( hFdCngCom->cngNoiseLevel, sub( hFdCngCom->stopBand, hFdCngCom->startBand ) );
    4540        1913 :     Word16 shift2 = L_norm_arr( hFdCngCom->cngNoiseLevel + sub( hFdCngCom->stopBand, hFdCngCom->startBand ), sub( FFTCLDFBLEN, sub( hFdCngCom->stopBand, hFdCngCom->startBand ) ) );
    4541        1913 :     Word16 shift = s_max( sub( hFdCngCom->sidNoiseEstExp, shift1 ), sub( hFdCngCom->cngNoiseLevelExp, shift2 ) );
    4542             : 
    4543        1913 :     scale_sig32( hFdCngCom->cngNoiseLevel, sub( hFdCngCom->stopBand, hFdCngCom->startBand ), sub( hFdCngCom->sidNoiseEstExp, shift ) );
    4544        1913 :     scale_sig32( hFdCngCom->cngNoiseLevel + sub( hFdCngCom->stopBand, hFdCngCom->startBand ), sub( FFTCLDFBLEN, sub( hFdCngCom->stopBand, hFdCngCom->startBand ) ), sub( hFdCngCom->cngNoiseLevelExp, shift ) );
    4545             : 
    4546        1913 :     hFdCngCom->cngNoiseLevelExp = shift;
    4547        1913 :     move16();
    4548             : 
    4549        1913 :     lpc_from_spectrum( hFdCngCom, hFdCngCom->startBand, hFdCngCom->stopFFTbin, st->preemph_fac );
    4550             : 
    4551        1913 :     return;
    4552             : }
    4553             : 
    4554             : /*-------------------------------------------------------------------
    4555             :  * generate_masking_noise_ivas_fx()
    4556             :  *
    4557             :  * Generate additional comfort noise (kind of noise filling)
    4558             :  *-------------------------------------------------------------------*/
    4559             : 
    4560       59366 : void generate_masking_noise_ivas_fx(
    4561             :     Word32 *timeDomainBuffer,         /* i/o: time-domain signal Q31 - *exp_out*/
    4562             :     Word16 *exp_out,                  /* o  : time-domain signal exp */
    4563             :     HANDLE_FD_CNG_COM hFdCngCom,      /* i/o: FD_CNG structure containing all buffers and variables */
    4564             :     const Word16 length,              /* i  : frame size                                       Q0*/
    4565             :     const Word16 core,                /* i  : core                                             Q0*/
    4566             :     const Word16 return_noise,        /* i  : noise is returned instead of added Q0*/
    4567             :     const Word16 secondary,           /* i  : flag to indicate secondary noise generation Q0*/
    4568             :     const Word16 element_mode,        /* i  : element mode Q0*/
    4569             :     STEREO_CNG_DEC_HANDLE hStereoCng, /* i  : stereo CNG handle */
    4570             :     const Word16 nchan_out            /* i  : number of output channels Q0*/
    4571             : )
    4572             : {
    4573       59366 :     Word32 *cngNoiseLevel_fx = hFdCngCom->cngNoiseLevel;
    4574       59366 :     Word32 *ptr_level_fx = cngNoiseLevel_fx;
    4575       59366 :     Word32 *fftBuffer_fx = hFdCngCom->fftBuffer;
    4576             :     Word16 i;
    4577             :     Word32 maskingNoise_fx[L_FRAME16k];
    4578             :     Word32 *ptr_r_fx;
    4579             :     Word32 *ptr_i_fx;
    4580             :     Word16 startBand;
    4581       59366 :     Word16 *seed = &( hFdCngCom->seed );
    4582             :     Word32 scale_fx;
    4583             :     Word16 shift;
    4584       59366 :     scale_fx = 0x40000000; // 1.0 in Q30
    4585       59366 :     move32();
    4586       59366 :     startBand = hFdCngCom->startBand; /*Q0*/
    4587       59366 :     move16();
    4588       59366 :     shift = getScaleFactor32( hFdCngCom->cngNoiseLevel, FFTCLDFBLEN );
    4589       59366 :     if ( LT_16( sub( hFdCngCom->cngNoiseLevelExp, shift ), 4 ) )
    4590             :     {
    4591        5596 :         shift = sub( hFdCngCom->cngNoiseLevelExp, 4 ); /*Q0*/
    4592             :     }
    4593       59366 :     scale_sig32( hFdCngCom->cngNoiseLevel, FFTCLDFBLEN, shift ); /*hFdCngCom->cngNoiseLevelExp*/
    4594       59366 :     hFdCngCom->cngNoiseLevelExp = sub( hFdCngCom->cngNoiseLevelExp, shift );
    4595       59366 :     move16();
    4596             : 
    4597             :     /* skip noise generating if level is very low, to avoid problems with possibly running into denormals */
    4598       59366 :     *exp_out = Q15;
    4599       59366 :     move16();
    4600       59366 :     IF( GT_16( hFdCngCom->likelihood_noisy_speech, DELTA_MASKING_NOISE_Q15 ) )
    4601             :     {
    4602        3404 :         IF( NE_16( core, AMR_WB_CORE ) )
    4603             :         {
    4604             :             /* Compute additional CN level */
    4605       45357 :             FOR( i = 0; i < SIZE_SCALE_TABLE_CN; i++ )
    4606             :             {
    4607       45357 :                 test();
    4608       45357 :                 test();
    4609       57458 :                 if ( EQ_16( hFdCngCom->CngBandwidth, scaleTable_cn_only[i].bwmode ) &&
    4610       24202 :                      GE_32( hFdCngCom->CngBitrate, scaleTable_cn_only[i].bitrateFrom ) &&
    4611       12101 :                      LT_32( hFdCngCom->CngBitrate, scaleTable_cn_only[i].bitrateTo ) )
    4612             :                 {
    4613        3404 :                     BREAK;
    4614             :                 }
    4615             :             }
    4616             : 
    4617        3404 :             scale_fx = L_deposit_h( scaleTable_cn_only[i].scale_ivas ); /* Q30 */
    4618             :         }
    4619             :         ELSE
    4620             :         {
    4621             :             /* Compute additional CN level */
    4622           0 :             FOR( i = 0; i < SIZE_SCALE_TABLE_CN_AMRWB; i++ )
    4623             :             {
    4624           0 :                 if ( GE_32( hFdCngCom->CngBitrate, scaleTable_cn_only_amrwbio[i][0] ) )
    4625             :                 {
    4626           0 :                     BREAK;
    4627             :                 }
    4628             :             }
    4629             : 
    4630           0 :             IF( LT_16( i, SIZE_SCALE_TABLE_CN_AMRWB ) )
    4631             :             {
    4632           0 :                 scale_fx = L_deposit_h( scaleTable_cn_only_amrwbio[i][1] ); /* Q30 */
    4633             :             }
    4634             :             ELSE
    4635             :             {
    4636           0 :                 scale_fx = 0;
    4637           0 :                 move32();
    4638             :             }
    4639             :         }
    4640             : 
    4641             :         /* Exclude clean speech */
    4642        3404 :         scale_fx = Mpy_32_16_1( scale_fx, hFdCngCom->likelihood_noisy_speech ); // Q30
    4643             : 
    4644             :         /* Generate Gaussian random noise in real and imaginary parts of the FFT bins
    4645             :           Amplitudes are adjusted to the estimated noise level cngNoiseLevel_flt in each bin */
    4646        3404 :         IF( startBand == 0 )
    4647             :         {
    4648           0 :             rand_gauss_fx( &fftBuffer_fx[0], seed, *exp_out ); // Q15
    4649           0 :             ptr_r_fx = fftBuffer_fx + 2;                       /*Q31 - hFdCngCom->fftBuffer_exp*/
    4650             :             Word16 exp1;
    4651           0 :             exp1 = add( hFdCngCom->cngNoiseLevelExp, 1 );
    4652             :             Word32 mpy1;
    4653           0 :             mpy1 = Sqrt32( Mpy_32_32( scale_fx, *ptr_level_fx ), &exp1 );                   /*Q31 - exp1*/
    4654           0 :             mpy1 = L_shl( mpy1, exp1 );                                                     // Q31
    4655           0 :             fftBuffer_fx[0] = Mpy_32_32( fftBuffer_fx[0], mpy1 ); /* DC component in FFT */ // Q = Q15
    4656           0 :             ptr_level_fx++;
    4657             :         }
    4658             :         ELSE
    4659             :         {
    4660        3404 :             fftBuffer_fx[0] = 0;
    4661        3404 :             move32();
    4662        3404 :             set32_fx( fftBuffer_fx + 2, 0, shl( sub( startBand, 1 ), 1 ) );
    4663        3404 :             ptr_r_fx = fftBuffer_fx + shl( startBand, 1 ); /*Q31 - hFdCngCom->fftBuffer_exp*/
    4664             :         }
    4665        3404 :         ptr_i_fx = ptr_r_fx + 1;
    4666      926580 :         FOR( ; ptr_level_fx < cngNoiseLevel_fx + hFdCngCom->stopFFTbin - startBand; ptr_level_fx++ )
    4667             :         {
    4668             :             /* Real part in FFT bins */
    4669      923176 :             rand_gauss_fx( ptr_r_fx, seed, *exp_out ); // Q15
    4670             :             Word16 exp2;
    4671      923176 :             exp2 = add( hFdCngCom->cngNoiseLevelExp, 1 );
    4672             :             Word32 mpy2;
    4673      923176 :             mpy2 = Sqrt32( L_shr( Mpy_32_32( scale_fx, *ptr_level_fx ), 1 ), &exp2 ); /*Q31 - exp2*/
    4674      923176 :             ( *ptr_r_fx ) = L_shl( Mpy_32_32( *ptr_r_fx, mpy2 ), exp2 );              // Q = Q15
    4675      923176 :             move32();
    4676      923176 :             ptr_r_fx += 2;
    4677             : 
    4678             :             /* Imaginary part in FFT bins */
    4679      923176 :             rand_gauss_fx( ptr_i_fx, seed, *exp_out );                   // Q15
    4680      923176 :             ( *ptr_i_fx ) = L_shl( Mpy_32_32( *ptr_i_fx, mpy2 ), exp2 ); // Q = Q15
    4681      923176 :             ptr_i_fx += 2;
    4682             :         }
    4683             : 
    4684             :         /* Remaining FFT bins are set to zero */
    4685        3404 :         set32_fx( fftBuffer_fx + shl( hFdCngCom->stopFFTbin, 1 ), 0, sub( hFdCngCom->fftlen, shl( hFdCngCom->stopFFTbin, 1 ) ) );
    4686             :         /* Nyquist frequency is discarded */
    4687        3404 :         fftBuffer_fx[1] = 0;
    4688        3404 :         move32();
    4689             :     }
    4690             :     ELSE
    4691             :     {
    4692             :         /* very low level case - update random seeds and reset FFT buffer; don't fully skip SynthesisSTFT_flt(), because of the buffer updates done there... */
    4693       55962 :         generate_masking_noise_update_seed_fx( hFdCngCom );
    4694             : 
    4695       55962 :         set32_fx( fftBuffer_fx, 0, hFdCngCom->fftlen );
    4696             :     }
    4697             : 
    4698             :     /* Perform STFT synthesis */
    4699       59366 :     IF( secondary )
    4700             :     {
    4701         438 :         SynthesisSTFT_fx( fftBuffer_fx, maskingNoise_fx, hStereoCng->olapBufferSynth22_32fx, hFdCngCom->olapWinSyn_fx, 0, hFdCngCom, element_mode, nchan_out );
    4702             :     }
    4703             :     ELSE
    4704             :     {
    4705       58928 :         SynthesisSTFT_fx( fftBuffer_fx, maskingNoise_fx, hFdCngCom->olapBufferSynth2_fx, hFdCngCom->olapWinSyn_fx, 0, hFdCngCom, element_mode, nchan_out );
    4706             :     }
    4707       59366 :     *exp_out = sub( *exp_out, Q9 );
    4708       59366 :     move16();
    4709             : 
    4710             :     /* Add some comfort noise on top of decoded signal */
    4711       59366 :     IF( return_noise )
    4712             :     {
    4713         876 :         Copy32( maskingNoise_fx, timeDomainBuffer, s_min( hFdCngCom->frameSize, length ) ); /*Q31 - *exp_out*/
    4714             :     }
    4715             :     ELSE
    4716             :     {
    4717             : #ifdef VEC_ARITH_OPT_v1
    4718       58490 :         v_add_fixed_no_hdrm( maskingNoise_fx, timeDomainBuffer, timeDomainBuffer, s_min( hFdCngCom->frameSize, length ) ); /*Q31 - *exp_out*/
    4719             : #else                                                                                                                      /* VEC_ARITH_OPT_v1 */
    4720             :         v_add_fixed( maskingNoise_fx, timeDomainBuffer, timeDomainBuffer, s_min( hFdCngCom->frameSize, length ), 0 ); /*Q31 - *exp_out*/
    4721             : #endif                                                                                                                     /* VEC_ARITH_OPT_v1 */
    4722             :     }
    4723             : 
    4724       59366 :     return;
    4725             : }
    4726             : 
    4727             : /*-------------------------------------------------------------------
    4728             :  * generate_stereo_masking_noise_fx()
    4729             :  *
    4730             :  * Generate additional comfort noise (kind of noise filling)
    4731             :  *-------------------------------------------------------------------*/
    4732             : 
    4733         888 : void generate_stereo_masking_noise_fx(
    4734             :     Word16 *syn, /* i/o: time-domain signal              Q_syn*/
    4735             :     Word16 Q_syn,
    4736             :     Decoder_State *st,                   /* i/o: decoder state structure         */
    4737             :     STEREO_TD_DEC_DATA_HANDLE hStereoTD, /* i  : TD stereo structure             */
    4738             :     const Word16 flag_sec_CNA,           /* i  : CNA flag for secondary channel  Q0*/
    4739             :     const Word16 fadeOut,                /* i  : only fade out of previous state Q0*/
    4740             :     STEREO_CNG_DEC_HANDLE hStereoCng,    /* i  : Stereo CNG handle               */
    4741             :     const Word16 nchan_out               /* i  : number of output channels       Q0*/
    4742             : )
    4743             : {
    4744             :     HANDLE_FD_CNG_COM hFdCngCom;
    4745             :     Word32 gamma_fx, scale_fx /*, SP_ratio_fx needs to be integrated*/;
    4746             :     Word32 Np_fx[L_FRAME16k];
    4747             :     Word32 Ns_fx[L_FRAME16k];
    4748             :     Word32 N1_fx[L_FRAME16k];
    4749             :     Word32 N2_fx[L_FRAME16k];
    4750             :     Word16 N1_fx_exp, N2_fx_exp;
    4751             :     Word16 i;
    4752             : 
    4753         888 :     IF( st->idchan == 0 )
    4754             :     {
    4755         438 :         hFdCngCom = st->hFdCngDec->hFdCngCom;
    4756         438 :         Copy_Scale_sig_16_32_no_sat( hStereoCng->olapBufferSynth22_fx, Ns_fx, shr( hFdCngCom->frameSize, 1 ), sub( Q6, st->Q_syn ) ); /*Q6*/
    4757         438 :         Copy32( hFdCngCom->olapBufferSynth2_fx, Np_fx, shr( hFdCngCom->frameSize, 1 ) );                                              /*st->Q_syn*/
    4758             : 
    4759         438 :         set32_fx( &Np_fx[( hFdCngCom->frameSize / 2 )], 0, shr( hFdCngCom->frameSize, 1 ) );
    4760         438 :         set32_fx( &Ns_fx[( hFdCngCom->frameSize / 2 )], 0, shr( hFdCngCom->frameSize, 1 ) );
    4761             : 
    4762         438 :         IF( !fadeOut )
    4763             :         {
    4764         438 :             Copy_Scale_sig_16_32_no_sat( hStereoCng->olapBufferSynth22_fx, hStereoCng->olapBufferSynth22_32fx, hFdCngCom->fftlen, sub( Q15, st->Q_syn ) ); /*Q15*/
    4765         438 :             generate_masking_noise_ivas_fx( N1_fx, &N1_fx_exp, hFdCngCom, hFdCngCom->frameSize, 0, 1, 0, st->element_mode, hStereoCng, nchan_out );        // N1_fx Q6
    4766             :             /* Generate masking noise for secondary channel */
    4767         438 :             IF( flag_sec_CNA )
    4768             :             {
    4769         438 :                 generate_masking_noise_ivas_fx( N2_fx, &N2_fx_exp, hFdCngCom, hFdCngCom->frameSize, 0, 1, 1, st->element_mode, hStereoCng, nchan_out ); // N2_fx Q6
    4770         438 :                 gamma_fx = L_shr( Mpy_32_32( hStereoCng->c_PS_LT_fx, hStereoCng->c_PS_LT_fx ), 1 );                                                     /*Q30*/
    4771         438 :                 scale_fx = ONE_IN_Q30;
    4772         438 :                 move32();
    4773         438 :                 IF( LT_32( gamma_fx, 966367642 /* 0.9 in Q30 */ ) )
    4774             :                 {
    4775             :                     Word16 exp_gamma;
    4776         438 :                     exp_gamma = 0;
    4777         438 :                     move16();
    4778             :                     Word16 divisor1;
    4779         438 :                     divisor1 = Inv16( (Word16) L_shr( L_sub( ONE_IN_Q30, gamma_fx ), Q15 ), &exp_gamma ); // Q15-exp_gamma
    4780         438 :                     gamma_fx = L_shl( Mpy_32_16_1( gamma_fx, divisor1 ), exp_gamma );                     // Q30
    4781             :                     Word16 exp_gamma1, exp_gamma2, exp_gamma3;
    4782         438 :                     exp_gamma1 = Q1;
    4783         438 :                     exp_gamma2 = Q1;
    4784         438 :                     exp_gamma3 = Q1;
    4785         438 :                     move16();
    4786         438 :                     move16();
    4787         438 :                     move16();
    4788         438 :                     gamma_fx = Sqrt32( L_add( gamma_fx, ONE_IN_Q30 ), &exp_gamma1 ); /*Q31 - exp_gamma1*/
    4789             :                     Word32 temp;
    4790         438 :                     temp = Sqrt32( gamma_fx, &exp_gamma2 );                                     // Q31-exp_gamma1
    4791         438 :                     gamma_fx = L_sub( gamma_fx, L_shl( temp, sub( exp_gamma2, exp_gamma1 ) ) ); // Q31-exp_gamma1
    4792         438 :                     gamma_fx = L_shl( gamma_fx, sub( exp_gamma1, Q1 ) );                        // Q30
    4793             :                     Word32 divisor2;
    4794         438 :                     divisor2 = Sqrt32( L_add( ONE_IN_Q30, L_shl( Mpy_32_32( gamma_fx, gamma_fx ), Q1 ) ), &exp_gamma3 ); // Q31 - exp_gamma3
    4795         438 :                     scale_fx = L_shl( divide3232( ONE_IN_Q30, divisor2 ), add( Q15, exp_gamma3 ) );                      // Q30
    4796             :                 }
    4797             :                 ELSE
    4798             :                 {
    4799           0 :                     gamma_fx = 0;
    4800           0 :                     move16();
    4801             :                 }
    4802             : 
    4803       56502 :                 FOR( i = 0; i < 2 * hFdCngCom->frameSize / 4; i++ )
    4804             :                 {
    4805       56064 :                     Np_fx[i] = L_add( Np_fx[i],
    4806             :                                       Mpy_32_32( scale_fx, L_shl( L_add( N1_fx[i], Mpy_32_32( gamma_fx, L_shl( N2_fx[i], Q1 ) ) ), Q1 ) ) ); // Q6
    4807       56064 :                     move32();
    4808             :                     Word32 add2;
    4809       56064 :                     add2 = Mpy_32_32( scale_fx, L_shl( L_sub( N1_fx[i], Mpy_32_32( gamma_fx, L_shl( N2_fx[i], Q1 ) ) ), Q1 ) ); // Q6
    4810       56064 :                     if ( hStereoCng->c_PS_LT_fx < 0 )
    4811             :                     {
    4812       35200 :                         add2 = L_negate( add2 ); /*Q6*/
    4813             :                     }
    4814       56064 :                     Ns_fx[i] = L_add( Ns_fx[i], add2 ); /*Q6*/
    4815       56064 :                     move32();
    4816             :                 }
    4817       56502 :                 FOR( ; i < hFdCngCom->frameSize; i++ )
    4818             :                 {
    4819       56064 :                     Np_fx[i] = Mpy_32_32( scale_fx, L_shl( L_add( N1_fx[i], Mpy_32_32( gamma_fx, L_shl( N2_fx[i], Q1 ) ) ), Q1 ) ); // Q6
    4820       56064 :                     move32();
    4821       56064 :                     Ns_fx[i] = Mpy_32_32( scale_fx, L_shl( L_sub( N1_fx[i], Mpy_32_32( gamma_fx, L_shl( N2_fx[i], Q1 ) ) ), Q1 ) ); // Q6
    4822       56064 :                     move32();
    4823       56064 :                     IF( hStereoCng->c_PS_LT_fx < 0 )
    4824             :                     {
    4825       35200 :                         Ns_fx[i] = L_negate( Ns_fx[i] );
    4826       35200 :                         move32();
    4827             :                     }
    4828             :                 }
    4829             :                 /* Below code to be converted */
    4830         438 :                 Word32 scale_fx_tmp = Mpy_32_32( scale_fx, L_shl( shr( hFdCngCom->fftlen, 1 ), Q22 ) ); // Q21
    4831       56502 :                 FOR( i = 0; i < shr( hFdCngCom->frameSize, 1 ); i++ )
    4832             :                 {
    4833       56064 :                     hFdCngCom->olapBufferSynth2[i] = (Word16) L_shr( Mpy_32_32( scale_fx_tmp,
    4834       56064 :                                                                                 L_add( L_shr( hFdCngCom->olapBufferSynth2[( i + ( 5 * ( hFdCngCom->frameSize / 4 ) ) )], Q15 ),
    4835       56064 :                                                                                        Mpy_32_16_1( gamma_fx, hStereoCng->olapBufferSynth22_fx[( i + ( 5 * ( hFdCngCom->frameSize / 4 ) ) )] ) ) ),
    4836             :                                                                      Q14 ); // Q_olap
    4837       56064 :                     move16();
    4838       56064 :                     hStereoCng->olapBufferSynth22_fx[i] = (Word16) L_shr( Mpy_32_32( scale_fx_tmp,
    4839       56064 :                                                                                      L_sub( L_shr( hFdCngCom->olapBufferSynth2[( i + ( 5 * ( hFdCngCom->frameSize / 4 ) ) )], Q15 ),
    4840       56064 :                                                                                             Mpy_32_16_1( gamma_fx, hStereoCng->olapBufferSynth22_fx[( i + ( 5 * ( hFdCngCom->frameSize / 4 ) ) )] ) ) ),
    4841             :                                                                           Q14 ); // Q_olap
    4842       56064 :                     move16();
    4843             :                 }
    4844             :             }
    4845             :             ELSE
    4846             :             {
    4847           0 :                 FOR( i = 0; i < shr( hFdCngCom->frameSize, 1 ); i++ )
    4848             :                 {
    4849           0 :                     Np_fx[i] = L_add( Np_fx[i], N1_fx[i] ); // Q6
    4850           0 :                     move32();
    4851             :                 }
    4852           0 :                 Copy32( &N1_fx[( hFdCngCom->frameSize / 2 )], &Np_fx[( hFdCngCom->frameSize / 2 )], shr( hFdCngCom->frameSize, 1 ) ); /*Q6*/
    4853           0 :                 scale_fx = L_shl( shr( hFdCngCom->fftlen, 1 ), Q22 );                                                                 // Q21
    4854           0 :                 FOR( i = 0; i < hFdCngCom->frameSize; i++ )
    4855             :                 {
    4856           0 :                     hFdCngCom->olapBufferSynth2[i] = (Word16) L_shr( Mpy_32_16_1( scale_fx, hFdCngCom->olapBufferSynth2[( i + ( 5 * ( hFdCngCom->frameSize / 4 ) ) )] ), Q6 ); // Q_olap
    4857           0 :                     move16();
    4858             :                 }
    4859             :             }
    4860             : 
    4861         438 :             Copy_Scale_sig_32_16( hStereoCng->olapBufferSynth22_32fx, hStereoCng->olapBufferSynth22_fx, hFdCngCom->fftlen, sub( st->Q_syn, 15 ) ); /*st->Q_syn*/
    4862             :         }
    4863             :         ELSE
    4864             :         {
    4865           0 :             set16_fx( hFdCngCom->olapBufferSynth2, 0, shr( hFdCngCom->frameSize, 1 ) );
    4866           0 :             set16_fx( hStereoCng->olapBufferSynth22_fx, 0, shr( hFdCngCom->frameSize, 1 ) );
    4867             :         }
    4868         438 :         IF( flag_sec_CNA )
    4869             :         {
    4870         438 :             Copy_Scale_sig_32_16( Ns_fx, hStereoCng->maskingNoiseS_fx, hFdCngCom->frameSize, 0 ); // Q6
    4871         438 :             hStereoCng->enableSecCNA = 1;
    4872         438 :             move16();
    4873             :         }
    4874             :         ELSE
    4875             :         {
    4876           0 :             set16_fx( hStereoCng->olapBufferSynth22_fx, 0, hFdCngCom->frameSize );
    4877             :         }
    4878             : 
    4879             :         /* add masking noise */
    4880      112566 :         FOR( i = 0; i < hFdCngCom->frameSize; i++ )
    4881             :         {
    4882      112128 :             syn[i] = add( syn[i], (Word16) L_shr( Np_fx[i], sub( Q16 + Q6, Q_syn ) ) ); // Q_syn
    4883      112128 :             move16();
    4884             :         }
    4885             :     }
    4886         450 :     ELSE IF( hStereoCng->enableSecCNA )
    4887             :     {
    4888             :         Word16 SP_ratio_fx;
    4889         438 :         SP_ratio_fx = extract_h( hStereoTD->SP_ratio_LT_fx ); /* Use long-term SP ratio based on L/R synthesis Q15*/
    4890             :         Word16 prevSP_ratio_fx;
    4891         438 :         prevSP_ratio_fx = hStereoTD->prevSP_ratio_fx; /* Use long-term SP ratio based on L/R synthesis Q15*/
    4892         438 :         move16();
    4893             :         /* scale and add masking noise */
    4894       28470 :         FOR( i = 0; i < shr( *hStereoCng->frameSize, 2 ); i++ )
    4895             :         {
    4896             :             Word16 s;
    4897             :             Word16 scale_fx_tmp;
    4898       28032 :             scale_fx_tmp = BASOP_Util_Divide3216_Scale( L_add( L_mult0( prevSP_ratio_fx, sub( shr( *hStereoCng->frameSize, 2 ), i ) ), L_mult0( SP_ratio_fx, i ) ), shr( *hStereoCng->frameSize, 2 ), &s ); // Q15
    4899       28032 :             scale_fx_tmp = shl( scale_fx_tmp, s );
    4900       28032 :             syn[i] = add( syn[i], mult( scale_fx_tmp, shr( hStereoCng->maskingNoiseS_fx[i], sub( Q6, Q_syn ) ) ) ); /*Q_syn*/
    4901       28032 :             move16();
    4902             :         }
    4903       28470 :         FOR( ; i < *hStereoCng->frameSize / 2; i++ )
    4904             :         {
    4905       28032 :             syn[i] = add( syn[i], mult( SP_ratio_fx, shr( hStereoCng->maskingNoiseS_fx[i], sub( Q6, Q_syn ) ) ) ); /*Q_syn*/
    4906       28032 :             move16();
    4907             :         }
    4908       56502 :         FOR( ; i < *hStereoCng->frameSize; i++ )
    4909             :         {
    4910       56064 :             syn[i] = add( syn[i], mult( SP_ratio_fx, shr( hStereoCng->maskingNoiseS_fx[i], sub( Q6, Q_syn ) ) ) ); /*Q_syn*/
    4911       56064 :             move16();
    4912             :         }
    4913         438 :         hStereoTD->prevSP_ratio_fx = extract_h( hStereoTD->SP_ratio_LT_fx ); /*Q15*/
    4914         438 :         move16();
    4915             :     }
    4916             : 
    4917         888 :     return;
    4918             : }
    4919       15697 : void generate_masking_noise_lb_dirac_fx(
    4920             :     HANDLE_FD_CNG_COM hFdCngCom, /* i/o: FD_CNG structure containing all buffers and variables */
    4921             :     Word32 *tdBuffer,            /* i/o: time-domain signal, if NULL no LB-CNA                 Q11*/
    4922             :     const Word16 nCldfbTs,       /* i  : number of CLDFB slots that will be rendered           Q0*/
    4923             :     const Word16 cna_flag        /* i  : CNA flag for LB and HB                                Q0*/
    4924             : )
    4925             : {
    4926             :     Word16 i;
    4927       15697 :     Word32 *cngNoiseLevel = hFdCngCom->cngNoiseLevel; /*hFdCngCom->cngNoiseLevelExp*/
    4928       15697 :     Word32 *fftBuffer = hFdCngCom->fftBuffer;         /*hFdCngCom->fftBuffer_exp*/
    4929             :     Word32 *ptr_r;
    4930             :     Word32 *ptr_i;
    4931             :     Word32 *ptr_level;
    4932       15697 :     Word16 *seed = &( hFdCngCom->seed );
    4933             :     Word32 scale;
    4934             :     Word16 n_samples_out, n_samples_start, n_samples_out_loop;
    4935             : 
    4936       15697 :     push_wmops( "fd_cng_dirac" );
    4937             : 
    4938             :     /* Init */
    4939       15697 :     scale = 0;
    4940       15697 :     move32();
    4941       15697 :     n_samples_out = i_mult( shr( hFdCngCom->frameSize, 4 ), nCldfbTs );
    4942       15697 :     n_samples_start = 0;
    4943       15697 :     move16();
    4944       15697 :     Word16 exp_out = Q11;
    4945       15697 :     move16();
    4946             :     /*LB CLDFB - CNA from STFT*/
    4947       15697 :     IF( cna_flag )
    4948             :     {
    4949             :         /* skip noise generating if level is very low, to avoid problems with possibly running into denormals */
    4950        4095 :         IF( GT_16( hFdCngCom->likelihood_noisy_speech, DELTA_MASKING_NOISE_Q15 ) )
    4951             :         {
    4952             :             /* Compute additional CN level */
    4953       21523 :             FOR( i = 0; i < 15; i++ )
    4954             :             {
    4955       21523 :                 test();
    4956       21523 :                 test();
    4957       25956 :                 if ( ( EQ_16( hFdCngCom->CngBandwidth, scaleTable_cn_dirac[i].bwmode ) ) &&
    4958        8866 :                      GE_32( hFdCngCom->CngBitrate, scaleTable_cn_dirac[i].bitrateFrom ) &&
    4959        4433 :                      LT_32( hFdCngCom->CngBitrate, scaleTable_cn_dirac[i].bitrateTo ) )
    4960             :                 {
    4961        1709 :                     BREAK;
    4962             :                 }
    4963             :             }
    4964             : 
    4965        1709 :             scale = L_deposit_h( scaleTable_cn_dirac[i].scale_ivas );         /* Q30 */
    4966        1709 :             scale = Mpy_32_16_1( scale, hFdCngCom->likelihood_noisy_speech ); /* Q30 */
    4967             :         }
    4968             :     }
    4969             : 
    4970             :     /* LB CLDFB - CNA from STFT: CNA applied only in channel 0*/
    4971       15697 :     test();
    4972       15697 :     IF( cna_flag && tdBuffer != NULL )
    4973             :     {
    4974        8190 :         WHILE( n_samples_out > 0 )
    4975             :         {
    4976        4095 :             n_samples_out_loop = s_min( hFdCngCom->frameSize, n_samples_out );
    4977        4095 :             IF( scale != 0 )
    4978             :             {
    4979             :                 /*Generate LF comfort noise only at first slot, for the whole frame*/
    4980        1709 :                 ptr_level = cngNoiseLevel; /*hFdCngCom->cngNoiseLevelExp*/
    4981             : 
    4982             :                 /* Generate Gaussian random noise in real and imaginary parts of the FFT bins
    4983             :                    Amplitudes are adjusted to the estimated noise level cngNoiseLevel_flt in each bin */
    4984        1709 :                 IF( EQ_16( hFdCngCom->startBand, 0 ) )
    4985             :                 {
    4986           0 :                     rand_gauss_fx( &fftBuffer[0], seed, exp_out );
    4987           0 :                     ptr_r = fftBuffer + 2; /*hFdCngCom->fftBuffer_exp*/
    4988             : 
    4989           0 :                     Word16 exp2 = sub( 31, hFdCngCom->cngNoiseLevelExp );
    4990           0 :                     Word32 sqr = Sqrt32( L_shr( Mpy_32_32( scale, *ptr_level ), 1 ), &exp2 ); /* DC component in FFT Q31 - exp2*/
    4991           0 :                     sqr = L_shl( sqr, exp2 );                                                 /*Q31*/
    4992           0 :                     fftBuffer[0] = Mpy_32_32( fftBuffer[0], sqr );                            /* DC component in FFT Q31 - hFdCngCom->fftBuffer_exp*/
    4993           0 :                     move32();
    4994           0 :                     ptr_level++;
    4995             :                 }
    4996             :                 ELSE
    4997             :                 {
    4998        1709 :                     fftBuffer[0] = 0;
    4999        1709 :                     move32();
    5000        1709 :                     set32_fx( fftBuffer + 2, 0, shl( sub( hFdCngCom->startBand, 1 ), 1 ) );
    5001        1709 :                     ptr_r = fftBuffer + shl( hFdCngCom->startBand, 1 ); /*hFdCngCom->fftBuffer_exp*/
    5002             :                 }
    5003        1709 :                 ptr_i = ptr_r + 1; /*hFdCngCom->fftBuffer_exp*/
    5004             : 
    5005      508691 :                 FOR( ; ptr_level < cngNoiseLevel + sub( hFdCngCom->stopFFTbin, hFdCngCom->startBand ); ptr_level++ )
    5006             :                 {
    5007      506982 :                     rand_gauss_fx( ptr_r, seed, exp_out );
    5008      506982 :                     Word16 exp2 = hFdCngCom->cngNoiseLevelExp;
    5009      506982 :                     Word32 mpy2 = Sqrt32( Mpy_32_32( scale, *ptr_level ), &exp2 ); /*Q31 - exp2*/
    5010      506982 :                     ( *ptr_r ) = L_shl( Mpy_32_32( *ptr_r, mpy2 ), exp2 );         /*Q31 - hFdCngCom->fftBuffer_exp*/
    5011      506982 :                     move32();
    5012      506982 :                     ptr_r += 2;
    5013             : 
    5014             :                     /* Imaginary part in FFT bins */
    5015      506982 :                     rand_gauss_fx( ptr_i, seed, exp_out );
    5016      506982 :                     ( *ptr_i ) = L_shl( Mpy_32_32( *ptr_i, mpy2 ), exp2 ); /*Q31 - hFdCngCom->fftBuffer_exp*/
    5017      506982 :                     move32();
    5018      506982 :                     ptr_i += 2;
    5019             :                 }
    5020             :                 /* Remaining FFT bins are set to zero */
    5021        1709 :                 set32_fx( fftBuffer + shl( hFdCngCom->stopFFTbin, 1 ), 0, sub( hFdCngCom->fftlen, shl( hFdCngCom->stopFFTbin, 1 ) ) );
    5022             :                 /* Nyquist frequency is discarded */
    5023        1709 :                 fftBuffer[1] = 0;
    5024        1709 :                 move32();
    5025             : 
    5026             :                 /* Perform STFT synthesis */
    5027        1709 :                 SynthesisSTFT_dirac_fx( fftBuffer, tdBuffer + n_samples_start, hFdCngCom->olapBufferSynth2_fx, hFdCngCom->olapWinSyn_fx, n_samples_out_loop, hFdCngCom );
    5028        1709 :                 scale_sig32( tdBuffer + n_samples_start, n_samples_out_loop, Q9 ); // Q2 -> Q11
    5029             :             }
    5030             : 
    5031             :             ELSE
    5032             :             {
    5033             :                 /* very low level case - update random seeds */
    5034        2386 :                 generate_masking_noise_update_seed_fx( hFdCngCom );
    5035             : 
    5036        2386 :                 set32_fx( fftBuffer, 0, hFdCngCom->fftlen );
    5037             :                 /* Perform STFT synthesis */
    5038        2386 :                 SynthesisSTFT_dirac_fx( fftBuffer, tdBuffer + n_samples_start, hFdCngCom->olapBufferSynth2_fx, hFdCngCom->olapWinSyn_fx, n_samples_out_loop, hFdCngCom );
    5039             :             }
    5040        4095 :             hFdCngCom->fftBuffer_exp = 31 - 11;
    5041        4095 :             move16();
    5042        4095 :             n_samples_out = sub( n_samples_out, hFdCngCom->frameSize );
    5043        4095 :             n_samples_start = add( n_samples_start, hFdCngCom->frameSize );
    5044             :         }
    5045             :     }
    5046             : 
    5047       15697 :     pop_wmops();
    5048             : 
    5049       15697 :     return;
    5050             : }
    5051      467712 : void generate_masking_noise_dirac_ivas_fx(
    5052             :     HANDLE_FD_CNG_COM hFdCngCom,      /* i/o: FD_CNG structure containing all buffers and variables */
    5053             :     HANDLE_CLDFB_FILTER_BANK h_cldfb, /* i  : filterbank state                                      */
    5054             :     Word32 *tdBuffer_fx,              /* i/o: time-domain signal, if NULL no LB-CNA                 q_input*/
    5055             :     Word32 *Cldfb_RealBuffer_fx,      /* o  : CLDFD real buffer                                     q_cldfb*/
    5056             :     Word32 *Cldfb_ImagBuffer_fx,      /* o  : CLDFD imaginary buffer                                q_cldfb*/
    5057             :     const Word16 slot_index,          /* i  : CLDFB slot index                                      Q0*/
    5058             :     const Word16 cna_flag,            /* i  : CNA flag for LB and HB                                Q0*/
    5059             :     const Word16 fd_cng_flag,         /* i  : FD-CNG flag for HB                                    Q0*/
    5060             :     Word16 q_input,
    5061             :     Word16 *q_cldfb )
    5062             : {
    5063             :     Word16 i;
    5064             :     Word32 *ptr_level_fx;
    5065      467712 :     Word16 *seed = &( hFdCngCom->seed );
    5066             :     Word32 scale_fx;
    5067             :     Word16 q_scale, q_shift, q_ptr_level;
    5068             : 
    5069      467712 :     push_wmops( "fd_cng_dirac" );
    5070             : 
    5071             :     /* Init */
    5072      467712 :     scale_fx = 0;
    5073      467712 :     move32();
    5074             : 
    5075             :     /* Resample CLDFB memories if necessary*/
    5076      467712 :     IF( NE_16( i_mult( h_cldfb->no_channels, h_cldfb->no_col ), hFdCngCom->frameSize ) )
    5077             :     {
    5078         519 :         resampleCldfb_ivas_fx( h_cldfb, hFdCngCom->frameSize * FRAMES_PER_SEC );
    5079             :     }
    5080             : 
    5081      467712 :     set32_fx( Cldfb_RealBuffer_fx, 0, CLDFB_NO_CHANNELS_MAX );
    5082      467712 :     set32_fx( Cldfb_ImagBuffer_fx, 0, CLDFB_NO_CHANNELS_MAX );
    5083             : 
    5084             :     /*LB CLDFB - CNA from STFT*/
    5085      467712 :     IF( cna_flag != 0 )
    5086             :     {
    5087             :         /* skip noise generating if level is very low, to avoid problems with possibly running into denormals */
    5088      113708 :         IF( hFdCngCom->likelihood_noisy_speech > 0 )
    5089             :         {
    5090             :             /* Compute additional CN level */
    5091      599604 :             FOR( i = 0; i < 15; i++ )
    5092             :             {
    5093      599604 :                 test();
    5094      599604 :                 test();
    5095      724368 :                 if ( ( EQ_16( hFdCngCom->CngBandwidth, scaleTable_cn_dirac[i].bwmode ) ) &&
    5096      249528 :                      ( GE_32( hFdCngCom->CngBitrate, scaleTable_cn_dirac[i].bitrateFrom ) ) &&
    5097      124764 :                      ( LT_32( hFdCngCom->CngBitrate, scaleTable_cn_dirac[i].bitrateTo ) ) )
    5098             :                 {
    5099       47484 :                     BREAK;
    5100             :                 }
    5101             :             }
    5102             : 
    5103       47484 :             scale_fx = L_shr( L_deposit_h( scaleTable_cn_dirac[i].scale_ivas ), Q3 ); /* Q27 */
    5104       47484 :             scale_fx = Mpy_32_16_1( scale_fx, hFdCngCom->likelihood_noisy_speech );
    5105             :         }
    5106             :     }
    5107             :     /* LB CLDFB - CNA from STFT: CNA applied only in channel 0*/
    5108      467712 :     IF( cna_flag && tdBuffer_fx != NULL )
    5109             :     {
    5110       65496 :         *q_cldfb = q_input;
    5111       65496 :         move16();
    5112       65496 :         IF( scale_fx != 0 )
    5113             :         {
    5114             :             /* LF CLDFB*/
    5115       27320 :             cldfbAnalysis_ts_fx_fixed_q( &( tdBuffer_fx[( hFdCngCom->numCoreBands * slot_index )] ), Cldfb_RealBuffer_fx, Cldfb_ImagBuffer_fx, hFdCngCom->numCoreBands, h_cldfb, q_cldfb );
    5116             :         }
    5117             :         ELSE
    5118             :         {
    5119             :             /* LB ana CLDFB*/
    5120       38176 :             cldfbAnalysis_ts_fx_fixed_q( &( tdBuffer_fx[( hFdCngCom->numCoreBands * slot_index )] ), Cldfb_RealBuffer_fx, Cldfb_ImagBuffer_fx, hFdCngCom->numCoreBands, h_cldfb, q_cldfb );
    5121             :         }
    5122             :     }
    5123             : 
    5124             :     /*HF CLDFB - CNA and/or FD-CNG*/
    5125      467712 :     if ( fd_cng_flag )
    5126             :     {
    5127        9696 :         scale_fx = L_add( scale_fx, ONE_IN_Q27 ); // 1 in Q27
    5128             :     }
    5129      467712 :     IF( scale_fx != 0 )
    5130             :     {
    5131       50524 :         q_scale = 27;
    5132       50524 :         move16();
    5133       50524 :         q_shift = norm_l( scale_fx );
    5134       50524 :         scale_fx = L_shl( scale_fx, q_shift ); /*q_scale+q_shift*/
    5135       50524 :         q_scale = add( q_scale, q_shift );
    5136       50524 :         scale_fx = Mpy_32_32( scale_fx, Mpy_32_16_1( L_mult( h_cldfb->scale, h_cldfb->scale ), CLDFB_SCALING ) ); // Q = q_scale + 2 * Q8 - 34
    5137       50524 :         q_scale = sub( add( q_scale, 2 * Q8 ), 31 + 3 );
    5138       50524 :         ptr_level_fx = hFdCngCom->cngNoiseLevel + sub( hFdCngCom->stopFFTbin, hFdCngCom->startBand ); /*Q31 - hFdCngCom->cngNoiseLevelExp*/
    5139       50524 :         q_ptr_level = sub( 31, hFdCngCom->cngNoiseLevelExp );
    5140             : 
    5141     1046448 :         FOR( i = hFdCngCom->numCoreBands; i < hFdCngCom->regularStopBand; i++ )
    5142             :         {
    5143             :             Word32 num;
    5144             :             Word16 exp, q_num;
    5145      995924 :             q_shift = norm_l( scale_fx );
    5146      995924 :             scale_fx = L_shl( scale_fx, q_shift ); /*q_scale+q_shift*/
    5147      995924 :             q_scale = add( q_scale, q_shift );
    5148      995924 :             num = Mpy_32_32( scale_fx, *ptr_level_fx );         /*q_num*/
    5149      995924 :             q_num = sub( add( q_scale, q_ptr_level ), 31 - 1 ); // num = ( scale * *ptr_level ) * 0.5f
    5150      995924 :             exp = sub( 31, q_num );
    5151      995924 :             num = Sqrt32( num, &exp ); /*Q31 - exp*/
    5152             :             /* Real part in CLDFB band */
    5153      995924 :             rand_gauss_fx( &Cldfb_RealBuffer_fx[i], seed, *q_cldfb );
    5154      995924 :             Cldfb_RealBuffer_fx[i] = L_shl( Mpy_32_32( Cldfb_RealBuffer_fx[i], num ), exp );
    5155      995924 :             move32();
    5156             :             /* Imaginary part in CLDFB band */
    5157      995924 :             rand_gauss_fx( &Cldfb_ImagBuffer_fx[i], seed, *q_cldfb );
    5158      995924 :             Cldfb_ImagBuffer_fx[i] = L_shl( Mpy_32_32( Cldfb_ImagBuffer_fx[i], num ), exp );
    5159      995924 :             move32();
    5160             : 
    5161      995924 :             ptr_level_fx++;
    5162             :         }
    5163             :     }
    5164             : 
    5165      467712 :     pop_wmops();
    5166             : 
    5167      467712 :     return;
    5168             : }
    5169             : 
    5170             : 
    5171             : /*-------------------------------------------------------------------
    5172             :  * FdCngDecodeMDCTStereoSID()
    5173             :  *
    5174             :  * Decode FD-Cng parameters for CNG in MDCT-Stereo mode from the bitstream
    5175             :  *
    5176             :  *-------------------------------------------------------------------*/
    5177             : 
    5178         410 : void FdCngDecodeMDCTStereoSID_fx(
    5179             :     CPE_DEC_HANDLE hCPE /* i/o: CPE decoder state structure     */
    5180             : )
    5181             : {
    5182             :     DEC_CORE_HANDLE sts[CPE_CHANNELS];
    5183             :     HANDLE_FD_CNG_COM hFdCngCom;
    5184             :     Word32 *ms_ptr_fx[CPE_CHANNELS];
    5185             :     Word32 *lr_ptr_fx[CPE_CHANNELS];
    5186             :     Word32 logNoiseEst_fx[CPE_CHANNELS][NPART];
    5187             :     Word32 gain_fx[CPE_CHANNELS];
    5188             :     Word16 indices[FD_CNG_stages_37bits];
    5189             :     Word16 N, i, ch, p, stages;
    5190             :     Word16 is_out_ms;
    5191             :     Word32 *invTrfMatrix_fx;
    5192             :     Word32 tmpRAM_fx[FDCNG_VQ_MAX_LEN][FDCNG_VQ_DCT_MAXTRUNC];
    5193             :     Word16 shift, exp_diff, max_exp_idx;
    5194             :     Word16 exp_arr[NPART];
    5195             :     Word32 tmp32, tmp32_arr[NPART];
    5196             : 
    5197         410 :     invTrfMatrix_fx = (Word32 *) tmpRAM_fx;
    5198         410 :     create_IDCT_N_Matrix_fx( invTrfMatrix_fx, FDCNG_VQ_MAX_LEN, FDCNG_VQ_DCT_MAXTRUNC, FDCNG_VQ_MAX_LEN * FDCNG_VQ_DCT_MAXTRUNC ); // Q31
    5199             : 
    5200         410 :     is_out_ms = 0;
    5201         410 :     move16();
    5202         410 :     if ( hCPE->hCoreCoder[0]->cng_sba_flag )
    5203             :     {
    5204           0 :         is_out_ms = 1;
    5205           0 :         move16();
    5206             :     }
    5207             : 
    5208         410 :     N = 0; /* to avoid compilation warning */
    5209         410 :     move16();
    5210             : 
    5211        1230 :     FOR( ch = 0; ch < CPE_CHANNELS; ch++ )
    5212             :     {
    5213         820 :         sts[ch] = hCPE->hCoreCoder[ch];
    5214         820 :         ms_ptr_fx[ch] = &logNoiseEst_fx[ch][0];                         /*Q20*/
    5215         820 :         lr_ptr_fx[ch] = &sts[ch]->hFdCngDec->hFdCngCom->sidNoiseEst[0]; /*Q18*/
    5216             :     }
    5217             : 
    5218             :     /* decode noise shapes and gains */
    5219        1230 :     FOR( ch = 0; ch < CPE_CHANNELS; ch++ )
    5220             :     {
    5221         820 :         sts[ch] = hCPE->hCoreCoder[ch];
    5222         820 :         hFdCngCom = ( sts[ch]->hFdCngDec )->hFdCngCom;
    5223         820 :         N = hFdCngCom->npart;
    5224         820 :         move16();
    5225         820 :         hFdCngCom->sid_frame_counter = add( hFdCngCom->sid_frame_counter, 1 ); /*Q0*/
    5226         820 :         move16();
    5227             : 
    5228         820 :         IF( ch )
    5229             :         {
    5230         410 :             stages = FD_CNG_JOINT_stages_25bits;
    5231         410 :             move16();
    5232             :         }
    5233             :         ELSE
    5234             :         {
    5235         410 :             stages = FD_CNG_stages_37bits;
    5236         410 :             move16();
    5237             :         }
    5238             : 
    5239             :         /* read bitstream */
    5240        4920 :         FOR( i = 0; i < stages; i++ )
    5241             :         {
    5242        4100 :             indices[i] = get_next_indice_fx( sts[ch], bits_37bits[i] ); /*Q0*/
    5243        4100 :             move16();
    5244             :         }
    5245             :         {
    5246         820 :             gain_fx[ch] = Mpy_32_32( L_shl( L_sub( get_next_indice_fx( sts[ch], 7 ), GAIN_Q_OFFSET_IVAS_FX ), Q20 ), TWO_BY_THREE_Q31 /* 2/3 in Q31 */ ); // Q20
    5247         820 :             move32();
    5248             :         }
    5249             : 
    5250             :         /* MSVQ decoder */
    5251         820 :         shift = find_guarded_bits_fx( N );
    5252         820 :         msvq_dec_fx( ivas_cdk_37bits_fx, NULL, NULL, stages, N, FD_CNG_maxN_37bits, indices, 1, invTrfMatrix_fx, ms_ptr_fx[ch], NULL, 7 ); // Q20 - shift
    5253             : 
    5254         820 :         Scale_sig32( ms_ptr_fx[ch], N, shift ); // Q20
    5255             :     }
    5256             : 
    5257         410 :     dtx_read_padding_bits_fx( sts[1], mult( sub( IVAS_SID_5k2, 4400 ), ONE_BY_FRAMES_PER_SEC_Q15 ) );
    5258             : 
    5259         410 :     IF( sts[0]->hFdCngDec->hFdCngCom->no_side_flag )
    5260             :     {
    5261          12 :         set32_fx( ms_ptr_fx[1], 0, NPART );
    5262             :     }
    5263             : 
    5264         410 :     IF( EQ_16( is_out_ms, 0 ) )
    5265             :     {
    5266         410 :         inverseMS_fx( N, ms_ptr_fx[0], ms_ptr_fx[1], ONE_IN_Q31 );
    5267             :     }
    5268             : 
    5269        1230 :     FOR( ch = 0; ch < CPE_CHANNELS; ch++ )
    5270             :     {
    5271         820 :         max_exp_idx = 0;
    5272         820 :         move16();
    5273         820 :         hFdCngCom = sts[ch]->hFdCngDec->hFdCngCom;
    5274       19504 :         FOR( p = 0; p < N; p++ )
    5275             :         {
    5276       18684 :             tmp32 = L_add( ms_ptr_fx[ch][p], gain_fx[ch] );                                                  // Q20
    5277       18684 :             tmp32_arr[p] = BASOP_util_Pow2( Mpy_32_32( tmp32, LOG_10_BASE_2_BY_10_Q31 ), Q11, &exp_arr[p] ); /*Q31 - exp_arr[p]*/
    5278       18684 :             move32();
    5279       18684 :             if ( LT_16( exp_arr[max_exp_idx], exp_arr[p] ) )
    5280             :             {
    5281          74 :                 max_exp_idx = p; /*Q0*/
    5282          74 :                 move16();
    5283             :             }
    5284             :         }
    5285             : 
    5286             :         // Bringing in same exponent
    5287       19504 :         FOR( p = 0; p < N; p++ )
    5288             :         {
    5289       18684 :             lr_ptr_fx[ch][p] = L_shl( tmp32_arr[p], sub( exp_arr[p], exp_arr[max_exp_idx] ) ); /*Q31 - exp_arr[max_exp_idx]*/
    5290       18684 :             move32();
    5291             :         }
    5292             : 
    5293         820 :         hFdCngCom->sidNoiseEstExp = exp_arr[max_exp_idx];
    5294         820 :         move16();
    5295             : 
    5296         820 :         scalebands( hFdCngCom->sidNoiseEst, hFdCngCom->part, hFdCngCom->npart, hFdCngCom->midband, hFdCngCom->nFFTpart, sub( hFdCngCom->stopBand, hFdCngCom->startBand ), hFdCngCom->cngNoiseLevel, 1 );
    5297             : 
    5298         820 :         hFdCngCom->cngNoiseLevelExp = hFdCngCom->sidNoiseEstExp;
    5299         820 :         move16();
    5300             : 
    5301         820 :         lpc_from_spectrum( hFdCngCom, hFdCngCom->startBand, hFdCngCom->stopFFTbin, sts[ch]->preemph_fac );
    5302             :     }
    5303             : 
    5304         410 :     test();
    5305         410 :     IF( EQ_16( hCPE->nchan_out, 1 ) && LE_32( hCPE->last_element_brate, IVAS_SID_5k2 ) )
    5306             :     {
    5307             :         /* create proper M noise shape in channel zero after gains have been applied */
    5308         120 :         exp_diff = sub( sts[0]->hFdCngDec->hFdCngCom->sidNoiseEstExp, sts[1]->hFdCngDec->hFdCngCom->sidNoiseEstExp );
    5309         120 :         move16();
    5310        2883 :         FOR( p = 0; p < N; p++ )
    5311             :         {
    5312        2763 :             IF( GT_16( exp_diff, 0 ) )
    5313             :             {
    5314         159 :                 sts[0]->hFdCngDec->hFdCngCom->sidNoiseEst[p] = L_add( L_shr( sts[0]->hFdCngDec->hFdCngCom->sidNoiseEst[p], 1 ), L_shr( sts[1]->hFdCngDec->hFdCngCom->sidNoiseEst[p], add( exp_diff, 1 ) ) ); /*Q18*/
    5315         159 :                 move32();
    5316             :             }
    5317             :             ELSE
    5318             :             {
    5319        2604 :                 sts[0]->hFdCngDec->hFdCngCom->sidNoiseEst[p] = L_add( L_shr( sts[0]->hFdCngDec->hFdCngCom->sidNoiseEst[p], sub( 1, exp_diff ) ), L_shr( sts[1]->hFdCngDec->hFdCngCom->sidNoiseEst[p], 1 ) ); /*Q18*/
    5320        2604 :                 move32();
    5321             :             }
    5322             :         }
    5323         120 :         IF( LT_16( exp_diff, 0 ) )
    5324             :         {
    5325          44 :             sts[0]->hFdCngDec->hFdCngCom->sidNoiseEstExp = add( sts[0]->hFdCngDec->hFdCngCom->sidNoiseEstExp, negate( exp_diff ) );
    5326          44 :             move16();
    5327             :         }
    5328             :     }
    5329             : 
    5330         410 :     return;
    5331             : }
    5332             : 
    5333             : 
    5334             : /*-------------------------------------------------------------------
    5335             :  * FdCngDecodeDiracMDCTStereoSID_fx()
    5336             :  *
    5337             :  * Decode FD-CNG parameters for CNG in 2TC DirAC mode from the bitstream
    5338             :  *-------------------------------------------------------------------*/
    5339             : 
    5340         167 : void FdCngDecodeDiracMDCTStereoSID_fx(
    5341             :     CPE_DEC_HANDLE hCPE /* i/o: CPE decoder state structure     */
    5342             : )
    5343             : {
    5344             :     DEC_CORE_HANDLE sts[CPE_CHANNELS];
    5345             :     HANDLE_FD_CNG_COM hFdCngCom;
    5346             :     Word32 *ms_ptr_fx[CPE_CHANNELS];
    5347             :     Word32 *lr_ptr_fx[CPE_CHANNELS];
    5348             :     Word32 logNoiseEst_fx[CPE_CHANNELS][NPART];
    5349             :     Word32 gain_fx[CPE_CHANNELS];
    5350             :     Word16 indices[FD_CNG_stages_37bits];
    5351             :     Word16 N, i, ch, p;
    5352             :     Word32 *invTrfMatrix_fx;
    5353             :     Word32 tmpRAM_fx[FDCNG_VQ_MAX_LEN][FDCNG_VQ_DCT_MAXTRUNC];
    5354             :     Word16 shift, exp_diff, max_exp_idx;
    5355             :     Word16 exp_arr[NPART];
    5356             :     Word32 tmp32, tmp32_arr[NPART];
    5357             : 
    5358         167 :     invTrfMatrix_fx = (Word32 *) tmpRAM_fx;                                                                                        /* dynamically filled  */
    5359         167 :     create_IDCT_N_Matrix_fx( invTrfMatrix_fx, FDCNG_VQ_MAX_LEN, FDCNG_VQ_DCT_MAXTRUNC, FDCNG_VQ_MAX_LEN * FDCNG_VQ_DCT_MAXTRUNC ); // Q31
    5360             : 
    5361         501 :     FOR( ch = 0; ch < CPE_CHANNELS; ch++ )
    5362             :     {
    5363         334 :         sts[ch] = hCPE->hCoreCoder[ch];
    5364         334 :         ms_ptr_fx[ch] = &logNoiseEst_fx[ch][0];                         /*Q20*/
    5365         334 :         lr_ptr_fx[ch] = &sts[ch]->hFdCngDec->hFdCngCom->sidNoiseEst[0]; /*Q20*/
    5366         334 :         ( sts[ch]->hFdCngDec )->hFdCngCom->sid_frame_counter++;         /*Q18*/
    5367             :     }
    5368             : 
    5369             :     /* decode noise shapes and gains */
    5370         167 :     hFdCngCom = ( sts[0]->hFdCngDec )->hFdCngCom;
    5371         167 :     N = hFdCngCom->npart; /*Q0*/
    5372         167 :     move16();
    5373             : 
    5374             :     /* read bitstream */
    5375        1169 :     FOR( i = 0; i < FD_CNG_stages_37bits; i++ )
    5376             :     {
    5377        1002 :         indices[i] = get_next_indice_fx( sts[0], bits_37bits[i] ); /*Q0*/
    5378        1002 :         move16();
    5379             :     }
    5380         167 :     gain_fx[0] = Mpy_32_32( L_shl( L_sub( get_next_indice_fx( sts[0], 7 ), GAIN_Q_OFFSET_IVAS_FX ), Q20 ), TWO_BY_THREE_Q31 /* 2/3 in Q31 */ ); // Q20
    5381         167 :     move32();
    5382             : 
    5383         167 :     gain_fx[1] = gain_fx[0]; /*Q20*/
    5384         167 :     move32();
    5385             : 
    5386             :     /* MSVQ decoder */
    5387         167 :     shift = find_guarded_bits_fx( N );
    5388         167 :     msvq_dec_fx( ivas_cdk_37bits_fx, NULL, NULL, FD_CNG_stages_37bits, N, FD_CNG_maxN_37bits, indices, 1, invTrfMatrix_fx, ms_ptr_fx[0], NULL, 7 ); // Q20 - shift
    5389             : 
    5390         167 :     Scale_sig32( ms_ptr_fx[0], N, shift ); // Q20
    5391             : 
    5392         167 :     Copy32( ms_ptr_fx[0], ms_ptr_fx[1], N ); /*Q20*/
    5393             : 
    5394         501 :     FOR( ch = 0; ch < CPE_CHANNELS; ch++ )
    5395             :     {
    5396         334 :         max_exp_idx = 0;
    5397         334 :         move16();
    5398         334 :         hFdCngCom = sts[ch]->hFdCngDec->hFdCngCom;
    5399             : 
    5400        8350 :         FOR( p = 0; p < N; p++ )
    5401             :         {
    5402        8016 :             tmp32 = L_add( ms_ptr_fx[ch][p], gain_fx[ch] );                                                  // Q20
    5403        8016 :             tmp32_arr[p] = BASOP_util_Pow2( Mpy_32_32( tmp32, LOG_10_BASE_2_BY_10_Q31 ), Q11, &exp_arr[p] ); /*Q31 - exp_arr[p]*/
    5404        8016 :             move32();
    5405        8016 :             if ( LT_16( exp_arr[max_exp_idx], exp_arr[p] ) )
    5406             :             {
    5407          26 :                 max_exp_idx = p; /*Q0*/
    5408          26 :                 move16();
    5409             :             }
    5410             :         }
    5411             : 
    5412             :         // Bringing in same exponent
    5413        8350 :         FOR( p = 0; p < N; p++ )
    5414             :         {
    5415        8016 :             lr_ptr_fx[ch][p] = L_shl( tmp32_arr[p], sub( exp_arr[p], exp_arr[max_exp_idx] ) ); /*Q20*/
    5416        8016 :             move32();
    5417             :         }
    5418             : 
    5419         334 :         hFdCngCom->sidNoiseEstExp = exp_arr[max_exp_idx]; /*Q0*/
    5420         334 :         move16();
    5421             : 
    5422             :         /* NB last band energy compensation */
    5423         334 :         test();
    5424         334 :         IF( hFdCngCom->CngBandwidth == NB )
    5425             :         {
    5426           0 :             lr_ptr_fx[ch][( N - 1 )] = Mpy_32_32( lr_ptr_fx[ch][( N - 1 )], NB_LAST_BAND_SCALE_Q31 ); /*Q20*/
    5427           0 :             move32();
    5428             :         }
    5429         334 :         ELSE IF( EQ_16( hFdCngCom->CngBandwidth, SWB ) && LE_32( hFdCngCom->CngBitrate, ACELP_13k20 ) )
    5430             :         {
    5431           0 :             lr_ptr_fx[ch][( N - 1 )] = Mpy_32_32( lr_ptr_fx[ch][( N - 1 )], SWB_13k2_LAST_BAND_SCALE_Q31 ); /*Q20*/
    5432           0 :             move32();
    5433             :         }
    5434             : 
    5435         334 :         scalebands( hFdCngCom->sidNoiseEst, hFdCngCom->part, hFdCngCom->npart, hFdCngCom->midband, hFdCngCom->nFFTpart, sub( hFdCngCom->stopBand, hFdCngCom->startBand ), hFdCngCom->cngNoiseLevel, 1 );
    5436             : 
    5437         334 :         hFdCngCom->cngNoiseLevelExp = hFdCngCom->sidNoiseEstExp;
    5438         334 :         move16();
    5439             : 
    5440         334 :         lpc_from_spectrum( hFdCngCom, hFdCngCom->startBand, hFdCngCom->stopFFTbin, sts[ch]->preemph_fac );
    5441             :     }
    5442         167 :     sts[0]->hFdCngDec->hFdCngCom->coherence_fx = 0;
    5443         167 :     move16();
    5444         167 :     sts[1]->hFdCngDec->hFdCngCom->coherence_fx = 0;
    5445         167 :     move16();
    5446             : 
    5447         167 :     IF( EQ_16( hCPE->nchan_out, 1 ) )
    5448             :     {
    5449             :         /* create proper M noise shape in channel zero after gains have been applied */
    5450           0 :         exp_diff = sub( sts[0]->hFdCngDec->hFdCngCom->sidNoiseEstExp, sts[1]->hFdCngDec->hFdCngCom->sidNoiseEstExp );
    5451           0 :         FOR( p = 0; p < N; p++ )
    5452             :         {
    5453           0 :             IF( exp_diff > 0 )
    5454             :             {
    5455           0 :                 sts[0]->hFdCngDec->hFdCngCom->sidNoiseEst[p] = L_add( L_shr( sts[0]->hFdCngDec->hFdCngCom->sidNoiseEst[p], 1 ), L_shr( sts[1]->hFdCngDec->hFdCngCom->sidNoiseEst[p], add( exp_diff, 1 ) ) ); /*Q18*/
    5456           0 :                 move32();
    5457             :             }
    5458             :             ELSE
    5459             :             {
    5460           0 :                 sts[0]->hFdCngDec->hFdCngCom->sidNoiseEst[p] = L_add( L_shr( sts[0]->hFdCngDec->hFdCngCom->sidNoiseEst[p], sub( 1, exp_diff ) ), L_shr( sts[1]->hFdCngDec->hFdCngCom->sidNoiseEst[p], 1 ) ); /*Q18*/
    5461           0 :                 move32();
    5462             :             }
    5463             :         }
    5464           0 :         IF( exp_diff < 0 )
    5465             :         {
    5466           0 :             sts[0]->hFdCngDec->hFdCngCom->sidNoiseEstExp = add( sts[0]->hFdCngDec->hFdCngCom->sidNoiseEstExp, negate( exp_diff ) );
    5467           0 :             move16();
    5468             :         }
    5469             :     }
    5470             : 
    5471         167 :     return;
    5472             : }

Generated by: LCOV version 1.14