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

Generated by: LCOV version 1.14