LCOV - code coverage report
Current view: top level - lib_dec - fd_cng_dec.c (source / functions) Hit Total Coverage
Test: Coverage on main -- short test vectors @ b5bd5e0684ad2d9250297e1e7a0ddc986cb7b37e Lines: 777 887 87.6 %
Date: 2025-10-27 07:01:45 Functions: 18 18 100.0 %

          Line data    Source code
       1             : /******************************************************************************************************
       2             : 
       3             :    (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB,
       4             :    Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
       5             :    Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
       6             :    Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
       7             :    contributors to this repository. All Rights Reserved.
       8             : 
       9             :    This software is protected by copyright law and by international treaties.
      10             :    The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB,
      11             :    Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
      12             :    Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
      13             :    Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
      14             :    contributors to this repository retain full ownership rights in their respective contributions in
      15             :    the software. This notice grants no license of any kind, including but not limited to patent
      16             :    license, nor is any license granted by implication, estoppel or otherwise.
      17             : 
      18             :    Contributors are required to enter into the IVAS codec Public Collaboration agreement before making
      19             :    contributions.
      20             : 
      21             :    This software is provided "AS IS", without any express or implied warranties. The software is in the
      22             :    development stage. It is intended exclusively for experts who have experience with such software and
      23             :    solely for the purpose of inspection. All implied warranties of non-infringement, merchantability
      24             :    and fitness for a particular purpose are hereby disclaimed and excluded.
      25             : 
      26             :    Any dispute, controversy or claim arising under or in relation to providing this software shall be
      27             :    submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in
      28             :    accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and
      29             :    the United Nations Convention on Contracts on the International Sales of Goods.
      30             : 
      31             : *******************************************************************************************************/
      32             : 
      33             : /*====================================================================================
      34             :     EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0
      35             :   ====================================================================================*/
      36             : 
      37             : #include "ivas_cnst.h"
      38             : #include "ivas_rom_com.h"
      39             : #include <assert.h>
      40             : #include <stdint.h>
      41             : #include "options.h"
      42             : #ifdef DEBUGGING
      43             : #include "debug.h"
      44             : #endif
      45             : #include <math.h>
      46             : #include "prot.h"
      47             : #include "ivas_prot.h"
      48             : #include "rom_com.h"
      49             : #include "wmc_auto.h"
      50             : #include "ivas_prot.h"
      51             : #include "ivas_rom_dec.h"
      52             : 
      53             : /*-------------------------------------------------------------------
      54             :  * Local constants
      55             :  *-------------------------------------------------------------------*/
      56             : 
      57             : #define DELTA_MASKING_NOISE        1e-20f
      58             : #define CNA_ACT_DN_LARGE_PARTITION 50  /* index of the first larger partition */
      59             : #define ST_PERIODOG_FACT           0.9 /* short-term filter factor for periodogram */
      60             : #define CNA_ACT_DN_FACT            0.7 /* downward updating factor for CNA during active frames */
      61             : #define FIRST_CNA_NOISE_UPD_FRAMES 5   /* minimum number of CN initialization frames */
      62             : 
      63             : 
      64             : /*-------------------------------------------------------------------
      65             :  * Local fucntions declarations
      66             :  *-------------------------------------------------------------------*/
      67             : 
      68             : static void perform_noise_estimation_dec( const float *timeDomainInput, float *power_spectrum, HANDLE_FD_CNG_DEC hFdCngDec, const int16_t element_mode, const int16_t bwidth, const int16_t L_frame, const int16_t last_L_frame, const int32_t last_core_brate, const int16_t VAD );
      69             : 
      70             : 
      71             : /*-------------------------------------------------------------------
      72             :  * createFdCngDec()
      73             :  *
      74             :  * Create an instance of type FD_CNG
      75             :  *-------------------------------------------------------------------*/
      76             : 
      77      275093 : ivas_error createFdCngDec(
      78             :     HANDLE_FD_CNG_DEC *hFdCngDec )
      79             : {
      80             :     HANDLE_FD_CNG_DEC hs;
      81             :     ivas_error error;
      82      275093 :     error = IVAS_ERR_OK;
      83             : 
      84             :     /* Set output to NULL in case of errors and early return */
      85      275093 :     *hFdCngDec = NULL;
      86             : 
      87             :     /* Allocate memory */
      88      275093 :     if ( ( hs = (HANDLE_FD_CNG_DEC) malloc( sizeof( FD_CNG_DEC ) ) ) == NULL )
      89             :     {
      90           0 :         return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Cannot allocate memory for FD CNG DEC structure" );
      91             :     }
      92             : 
      93      275093 :     if ( ( error = createFdCngCom( &( hs->hFdCngCom ) ) ) != IVAS_ERR_OK )
      94             :     {
      95           0 :         return error;
      96             :     }
      97             : 
      98      275093 :     *hFdCngDec = hs;
      99             : 
     100      275093 :     return error;
     101             : }
     102             : 
     103             : 
     104             : /*-------------------------------------------------------------------
     105             :  * initFdCngDec()
     106             :  *
     107             :  * Initialize an instance of type FD_CNG
     108             :  *-------------------------------------------------------------------*/
     109             : 
     110      275093 : void initFdCngDec(
     111             :     DEC_CORE_HANDLE st /* i/o: decoder state structure     */
     112             : )
     113             : {
     114             :     HANDLE_FD_CNG_DEC hFdCngDec;
     115             : 
     116      275093 :     hFdCngDec = st->hFdCngDec;
     117             : 
     118             :     /* Initialize common */
     119      275093 :     initFdCngCom( hFdCngDec->hFdCngCom, st->cldfbSyn->scale );
     120             : 
     121             :     /* Set some counters and flags */
     122      275093 :     hFdCngDec->flag_dtx_mode = 0;
     123      275093 :     hFdCngDec->lp_noise = -20.f;
     124      275093 :     hFdCngDec->lp_speech = 25.f;
     125             : 
     126             :     /* Initialize noise estimation algorithm */
     127      275093 :     set_f( hFdCngDec->bandNoiseShape, 0.0f, FFTLEN2 );
     128      275093 :     set_f( hFdCngDec->partNoiseShape, 0.0f, NPART );
     129      275093 :     set_f( hFdCngDec->msPeriodog, 0.0f, NPART_SHAPING );
     130      275093 :     set_f( hFdCngDec->msAlpha, 0.0f, NPART_SHAPING );
     131      275093 :     set_f( hFdCngDec->msBminWin, 0.0f, NPART_SHAPING );
     132      275093 :     set_f( hFdCngDec->msBminSubWin, 0.0f, NPART_SHAPING );
     133      275093 :     set_f( hFdCngDec->msPsd, 0.0f, NPART_SHAPING );
     134      275093 :     set_f( hFdCngDec->msNoiseFloor, 0.0f, NPART_SHAPING );
     135      275093 :     set_f( hFdCngDec->msNoiseEst, 0.0f, NPART_SHAPING );
     136      275093 :     set_f( hFdCngDec->msMinBuf, FLT_MAX, MSNUMSUBFR * NPART_SHAPING );
     137      275093 :     set_f( hFdCngDec->msCurrentMin, FLT_MAX, NPART_SHAPING );
     138      275093 :     set_f( hFdCngDec->msCurrentMinOut, FLT_MAX, NPART_SHAPING );
     139      275093 :     set_f( hFdCngDec->msCurrentMinSubWindow, FLT_MAX, NPART_SHAPING );
     140      275093 :     set_s( hFdCngDec->msLocalMinFlag, 0, NPART_SHAPING );
     141      275093 :     set_s( hFdCngDec->msNewMinFlag, 0, NPART_SHAPING );
     142      275093 :     set_f( hFdCngDec->msPsdFirstMoment, 0.0f, NPART_SHAPING );
     143      275093 :     set_f( hFdCngDec->msPsdSecondMoment, 0.0f, NPART_SHAPING );
     144      275093 :     hFdCngDec->msPeriodogBufPtr = 0;
     145      275093 :     set_f( hFdCngDec->msPeriodogBuf, 0.0f, MSBUFLEN * NPART_SHAPING );
     146      275093 :     set_f( hFdCngDec->msLogPeriodog, 0.0f, NPART_SHAPING );
     147      275093 :     set_f( hFdCngDec->msLogNoiseEst, 0.0f, NPART_SHAPING );
     148      275093 :     set_f( hFdCngDec->psize_shaping, 0.0f, NPART_SHAPING );
     149      275093 :     hFdCngDec->nFFTpart_shaping = 0;
     150             : 
     151      275093 :     set_f( hFdCngDec->hFdCngCom->sidNoiseEstLp, 0.0f, NPART );
     152             : 
     153      275093 :     set_f( hFdCngDec->smoothed_psd, 0.0f, L_FRAME16k );
     154      275093 :     set_f( hFdCngDec->msPeriodog_ST, 0.0f, NPART_SHAPING );
     155             : 
     156      275093 :     hFdCngDec->ms_last_inactive_bwidth = NB;
     157      275093 :     hFdCngDec->ms_cnt_bw_up = 0;
     158             : 
     159      275093 :     hFdCngDec->cna_LR_LT = 0.5f;
     160      275093 :     hFdCngDec->cna_ILD_LT = 0.0f;
     161      275093 :     hFdCngDec->first_cna_noise_updated = 0;
     162      275093 :     hFdCngDec->first_cna_noise_update_cnt = 0;
     163      275093 :     hFdCngDec->cna_nbands = CNA_INIT_NBANDS;
     164      275093 :     mvs2s( cna_init_bands, hFdCngDec->cna_band_limits, CNA_INIT_NBANDS + 1 );
     165      275093 :     hFdCngDec->cna_act_fact = 1.0f;
     166      275093 :     hFdCngDec->cna_rescale_fact = 0.0f;
     167      275093 :     hFdCngDec->cna_seed = 5687;
     168      275093 :     set_zero( hFdCngDec->cna_cm, STEREO_DFT_BAND_MAX );
     169      275093 :     set_zero( hFdCngDec->cna_g_state, STEREO_DFT_BAND_MAX );
     170             : 
     171      275093 :     st->CNG_mode = -1;
     172      275093 :     mvr2r( st->lsp_old, st->lspCNG, M );
     173             : 
     174      275093 :     return;
     175             : }
     176             : 
     177             : 
     178             : /*-------------------------------------------------------------------
     179             :  * configureFdCngDec()
     180             :  *
     181             :  * Configure an instance of type FD_CNG
     182             :  *-------------------------------------------------------------------*/
     183             : 
     184     8567896 : void configureFdCngDec(
     185             :     HANDLE_FD_CNG_DEC hFdCngDec, /* i/o: Contains the variables related to the FD-based CNG process */
     186             :     const int16_t bwidth,
     187             :     const int32_t total_brate,
     188             :     const int16_t L_frame,
     189             :     const int16_t last_L_frame,
     190             :     const int16_t element_mode )
     191             : {
     192             :     int16_t j, stopBandFR;
     193     8567896 :     HANDLE_FD_CNG_COM hsCom = hFdCngDec->hFdCngCom;
     194             : 
     195     8567896 :     hsCom->CngBandwidth = bwidth;
     196     8567896 :     if ( hsCom->CngBandwidth == FB )
     197             :     {
     198     4978217 :         hsCom->CngBandwidth = SWB;
     199             :     }
     200     8567896 :     if ( total_brate != FRAME_NO_DATA && total_brate != SID_2k40 )
     201             :     {
     202     8566904 :         hsCom->CngBitrate = total_brate;
     203             :     }
     204         992 :     else if ( hsCom->CngBitrate == -1 )
     205             :     {
     206             :         /* set minimum active CBR bitrate if CngBitrate is uninitialized */
     207           0 :         if ( element_mode > EVS_MONO )
     208             :         {
     209           0 :             hsCom->CngBitrate = IVAS_13k2;
     210             :         }
     211             :         else
     212             :         {
     213           0 :             hsCom->CngBitrate = ACELP_7k20;
     214             :         }
     215             :     }
     216             : 
     217             :     /* FD-CNG config for MDCT-Stereo is always the same (since for > 48 kbps only) */
     218             :     /* This may need adjustment in the future if 2TC DTX for some mode uses MDCT-Stereo DTX for lower bitrates too */
     219     8567896 :     if ( element_mode == IVAS_CPE_MDCT )
     220             :     {
     221     7231661 :         hsCom->CngBitrate = IVAS_48k;
     222             :     }
     223     8567896 :     hsCom->numSlots = 16;
     224             : 
     225             :     /* NB configuration */
     226     8567896 :     if ( bwidth == NB )
     227             :     {
     228          38 :         hsCom->FdCngSetup = FdCngSetup_nb;
     229          38 :         hsCom->numCoreBands = 16;
     230          38 :         hsCom->regularStopBand = 16;
     231             :     }
     232             : 
     233             :     /* WB configuration */
     234     8567858 :     else if ( bwidth == WB )
     235             :     {
     236             :         /* FFT 6.4kHz, no CLDFB */
     237       93919 :         if ( hsCom->CngBitrate <= ACELP_8k00 && L_frame == L_FRAME )
     238             :         {
     239        2560 :             hsCom->FdCngSetup = FdCngSetup_wb1;
     240        2560 :             hsCom->numCoreBands = 16;
     241        2560 :             hsCom->regularStopBand = 16;
     242             :         }
     243             :         /* FFT 6.4kHz, CLDFB 8.0kHz */
     244       91359 :         else if ( hsCom->CngBitrate <= ACELP_13k20 || L_frame == L_FRAME )
     245             :         {
     246       14196 :             hsCom->FdCngSetup = FdCngSetup_wb2;
     247       14196 :             hsCom->numCoreBands = 16;
     248       14196 :             hsCom->regularStopBand = 20;
     249       14196 :             if ( L_frame == L_FRAME16k )
     250             :             {
     251          24 :                 hsCom->FdCngSetup = FdCngSetup_wb2;
     252          24 :                 hsCom->numCoreBands = 20;
     253          24 :                 hsCom->regularStopBand = 20;
     254          24 :                 hsCom->FdCngSetup.fftlen = 640;
     255          24 :                 hsCom->FdCngSetup.stopFFTbin = 256;
     256             :             }
     257             :         }
     258             :         /* FFT 8.0kHz, no CLDFB */
     259             :         else
     260             :         {
     261       77163 :             hsCom->FdCngSetup = FdCngSetup_wb3;
     262       77163 :             hsCom->numCoreBands = 20;
     263       77163 :             hsCom->regularStopBand = 20;
     264             :         }
     265             :     }
     266             : 
     267             :     /* SWB/FB configuration */
     268             :     else
     269             :     {
     270             :         /* FFT 6.4kHz, CLDFB 14kHz */
     271     8473939 :         if ( L_frame == L_FRAME )
     272             :         {
     273       37692 :             hsCom->FdCngSetup = FdCngSetup_swb1;
     274       37692 :             hsCom->numCoreBands = 16;
     275       37692 :             hsCom->regularStopBand = 35;
     276             :         }
     277             :         /* FFT 8.0kHz, CLDFB 16kHz */
     278             :         else
     279             :         {
     280     8436247 :             hsCom->FdCngSetup = FdCngSetup_swb2;
     281     8436247 :             hsCom->numCoreBands = 20;
     282     8436247 :             hsCom->regularStopBand = 40;
     283     8436247 :             if ( last_L_frame == L_FRAME && element_mode == IVAS_CPE_DFT )
     284             :             {
     285         616 :                 hsCom->regularStopBand = 35;
     286             :             }
     287             :         }
     288             :     }
     289             : 
     290             : 
     291     8567896 :     hsCom->fftlen = hsCom->FdCngSetup.fftlen;
     292     8567896 :     hsCom->stopFFTbin = hsCom->FdCngSetup.stopFFTbin;
     293             : 
     294             :     /* Configure the SID quantizer and the Comfort Noise Generator */
     295             : 
     296     8567896 :     hsCom->startBand = 2;
     297     8567896 :     hsCom->stopBand = hsCom->FdCngSetup.sidPartitions[hsCom->FdCngSetup.numPartitions - 1] + 1;
     298     8567896 :     initPartitions( hsCom->FdCngSetup.sidPartitions, hsCom->FdCngSetup.numPartitions, hsCom->startBand, hsCom->stopBand, hsCom->part, &hsCom->npart, hsCom->midband, hsCom->psize, hsCom->psize_inv, 0 );
     299     8567896 :     if ( hsCom->stopFFTbin == 160 )
     300             :     {
     301          38 :         hsCom->nFFTpart = 17;
     302             :     }
     303     8567858 :     else if ( hsCom->stopFFTbin == 256 )
     304             :     {
     305       54448 :         hsCom->nFFTpart = 20;
     306             :     }
     307             :     else
     308             :     {
     309     8513410 :         hsCom->nFFTpart = 21;
     310             :     }
     311     8567896 :     hsCom->nCLDFBpart = hsCom->npart - hsCom->nFFTpart;
     312    34041601 :     for ( j = 0; j < hsCom->nCLDFBpart; j++ )
     313             :     {
     314    25473705 :         hsCom->CLDFBpart[j] = hsCom->part[j + hsCom->nFFTpart] - ( hsCom->stopFFTbin - hsCom->startBand );
     315    25473705 :         hsCom->CLDFBpsize_inv[j] = hsCom->psize_inv[j + hsCom->nFFTpart];
     316             :     }
     317             : 
     318     8567896 :     stopBandFR = (int16_t) floor( 1000.f /*Hz*/ / 25.f /*Hz/Bin*/ );
     319     8567896 :     if ( stopBandFR > hsCom->stopFFTbin )
     320             :     {
     321           0 :         stopBandFR = hsCom->stopFFTbin;
     322             :     }
     323     8567896 :     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_inv_shaping, stopBandFR );
     324             : 
     325     8567896 :     hFdCngDec->nFFTpart_shaping = hFdCngDec->npart_shaping;
     326             : 
     327     8567896 :     switch ( hsCom->fftlen )
     328             :     {
     329       54462 :         case 512:
     330       54462 :             hsCom->fftSineTab = NULL;
     331       54462 :             hsCom->olapWinAna = olapWinAna512;
     332       54462 :             hsCom->olapWinSyn = olapWinSyn256;
     333       54462 :             break;
     334     8513434 :         case 640:
     335     8513434 :             hsCom->fftSineTab = fftSineTab640;
     336     8513434 :             hsCom->olapWinAna = olapWinAna640;
     337     8513434 :             hsCom->olapWinSyn = olapWinSyn320;
     338     8513434 :             break;
     339           0 :         default:
     340           0 :             assert( !"Unsupported FFT length for FD-based CNG" );
     341             :             break;
     342             :     }
     343     8567896 :     hsCom->frameSize = hsCom->fftlen >> 1;
     344             : 
     345     8567896 :     return;
     346             : }
     347             : 
     348             : 
     349             : /*-------------------------------------------------------------------
     350             :  * deleteFdCngDec()
     351             :  *
     352             :  * Delete the instance of type FD_CNG
     353             :  *-------------------------------------------------------------------*/
     354             : 
     355     2623998 : void deleteFdCngDec(
     356             :     HANDLE_FD_CNG_DEC *hFdCngDec )
     357             : {
     358     2623998 :     HANDLE_FD_CNG_DEC hsDec = *hFdCngDec;
     359             : 
     360     2623998 :     if ( hsDec != NULL )
     361             :     {
     362      275093 :         deleteFdCngCom( &( hsDec->hFdCngCom ) );
     363      275093 :         free( hsDec );
     364      275093 :         *hFdCngDec = NULL;
     365             :     }
     366             : 
     367     2623998 :     return;
     368             : }
     369             : 
     370             : 
     371             : /*-------------------------------------------------------------------
     372             :  * ApplyFdCng()
     373             :  *
     374             :  * Apply the CLDFB-based CNG at the decoder
     375             :  *-------------------------------------------------------------------*/
     376             : 
     377     3819641 : void ApplyFdCng(
     378             :     float *timeDomainInput,
     379             :     float *powerSpectrum,
     380             :     float **realBuffer, /* i/o: Real part of the buffer */
     381             :     float **imagBuffer, /* i/o: Imaginary part of the buffer */
     382             :     Decoder_State *st,
     383             :     const int16_t concealWholeFrame,
     384             :     const int16_t is_music )
     385             : {
     386     3819641 :     HANDLE_FD_CNG_DEC hFdCngDec = st->hFdCngDec;
     387     3819641 :     HANDLE_FD_CNG_COM hFdCngCom = hFdCngDec->hFdCngCom;
     388     3819641 :     float *cngNoiseLevel = hFdCngCom->cngNoiseLevel;
     389     3819641 :     float *sidNoiseEst = hFdCngCom->sidNoiseEst;
     390             :     int16_t j, k;
     391             :     float factor;
     392             :     float lsp_cng[M];
     393             :     int16_t L_frame, last_L_frame;
     394             :     int32_t sr_core;
     395             : 
     396     3819641 :     push_wmops( "ApplyFdCng" );
     397             : 
     398             :     /* limit L_frame and core Fs values for MDCT-Stereo modes which can have higher core sampling than 16kHz, but use a downsampled buffer */
     399     3819641 :     L_frame = min( st->L_frame, L_FRAME16k );
     400     3819641 :     last_L_frame = min( st->last_L_frame, L_FRAME16k );
     401     3819641 :     sr_core = min( st->sr_core, INT_FS_16k );
     402             : 
     403     3819641 :     if ( hFdCngCom->frame_type_previous == ACTIVE_FRAME )
     404             :     {
     405     3768964 :         hFdCngCom->inactive_frame_counter = 0;
     406             :     }
     407             : 
     408     3819641 :     if ( st->element_mode == IVAS_CPE_TD )
     409             :     {
     410       14664 :         hFdCngDec->flag_dtx_mode = hFdCngDec->flag_dtx_mode || st->first_CNG;
     411             :     }
     412             : 
     413     3819641 :     switch ( st->m_frame_type )
     414             :     {
     415             : 
     416     3773860 :         case ACTIVE_FRAME:
     417             :             /**************************
     418             :              * ACTIVE_FRAME at DECODER *
     419             :              **************************/
     420             : 
     421     3773860 :             hFdCngCom->inactive_frame_counter = 0;
     422     3773860 :             hFdCngCom->sid_frame_counter = 0;
     423             :             /* set noise estimation inactive during concealment, as no update with noise generated by concealment should be performed. */
     424             :             /* set noise estimation inactive when we have bit errors, as no update with noise generated by corrupt frame (biterror) should be performed. */
     425     3773860 :             if ( concealWholeFrame == 0 &&
     426     3342828 :                  ( timeDomainInput == NULL ||
     427     3342828 :                    ( *timeDomainInput<FLT_MAX && * timeDomainInput>( -FLT_MAX ) &&
     428     3342828 :                      *( timeDomainInput + hFdCngCom->frameSize - 1 ) < FLT_MAX &&
     429     3342828 :                      *( timeDomainInput + hFdCngCom->frameSize - 1 ) > ( -FLT_MAX ) ) ) &&
     430     3373292 :                  ( ( ( ( st->element_mode != IVAS_CPE_TD && st->element_mode != IVAS_CPE_DFT && hFdCngDec->flag_dtx_mode ) || !st->VAD || ( st->ini_frame < 100 && st->is_ism_format ) ) &&
     431     1606615 :                      !( st->cng_type == LP_CNG && hFdCngDec->flag_dtx_mode ) && ( is_music == 0 ) ) ||
     432     1797523 :                    ( st->element_mode == IVAS_CPE_TD ) ) &&
     433     1590106 :                  ( !st->BER_detect ) )
     434             :             {
     435             :                 /* Perform noise estimation at the decoder */
     436     1590106 :                 perform_noise_estimation_dec( timeDomainInput, powerSpectrum, hFdCngDec, st->element_mode, st->bwidth, L_frame, last_L_frame, st->last_core_brate, st->VAD );
     437             : 
     438     1590106 :                 if ( st->element_mode != IVAS_CPE_TD && st->element_mode != IVAS_CPE_DFT )
     439             :                 {
     440             :                     /* Update the shaping parameters */
     441     1565271 :                     scalebands( hFdCngDec->msNoiseEst, hFdCngDec->part_shaping, hFdCngDec->nFFTpart_shaping, hFdCngDec->midband_shaping, hFdCngDec->nFFTpart_shaping, hFdCngCom->stopFFTbin - hFdCngCom->startBand, hFdCngDec->bandNoiseShape, 1 );
     442             :                 }
     443             : 
     444             :                 /* Update CNG levels */
     445     1590106 :                 if ( hFdCngDec->flag_dtx_mode && st->cng_type == FD_CNG )
     446             :                 {
     447       10355 :                     bandcombinepow( hFdCngDec->bandNoiseShape, hFdCngCom->stopFFTbin - hFdCngCom->startBand, hFdCngCom->part, hFdCngCom->nFFTpart, hFdCngCom->psize_inv, hFdCngDec->partNoiseShape ); /* This needs to be done only once per inactive phase */
     448             : 
     449       10355 :                     j = 0;
     450      222347 :                     for ( k = 0; k < hFdCngCom->nFFTpart; k++ )
     451             :                     {
     452      211992 :                         factor = ( hFdCngCom->sidNoiseEst[k] + DELTA ) / ( hFdCngDec->partNoiseShape[k] + DELTA );
     453     3155250 :                         for ( ; j <= hFdCngCom->part[k]; j++ )
     454             :                         {
     455     2943258 :                             cngNoiseLevel[j] = hFdCngDec->bandNoiseShape[j] * factor;
     456             :                         }
     457             :                     }
     458             :                 }
     459             :                 else
     460             :                 {
     461             :                     /* This sets the new CNG levels until a SID update overwrites it */
     462     1579751 :                     if ( !( st->element_mode == IVAS_CPE_TD ) || ( st->element_mode == IVAS_CPE_TD && !hFdCngDec->flag_dtx_mode && !st->VAD ) )
     463             :                     {
     464     1570274 :                         mvr2r( hFdCngDec->bandNoiseShape, cngNoiseLevel, hFdCngCom->stopFFTbin - hFdCngCom->startBand ); /* This sets the new CNG levels until a SID update overwrites it */
     465             :                     }
     466             :                 }
     467             : 
     468     1590106 :                 if ( st->element_mode == IVAS_CPE_MDCT && timeDomainInput == NULL )
     469             :                 {
     470       30464 :                     st->hTcxDec->CngLevelBackgroundTrace_bfi = sqrtf( sum_f( cngNoiseLevel, hFdCngCom->stopFFTbin - hFdCngCom->startBand ) / NORM_MDCT_FACTOR );
     471             :                 }
     472             :                 else
     473             :                 {
     474     1559642 :                     st->hTcxDec->CngLevelBackgroundTrace_bfi = (float) sqrt( ( sum_f( cngNoiseLevel, hFdCngCom->stopFFTbin - hFdCngCom->startBand ) / 2 * hFdCngCom->fftlen ) / L_frame );
     475             :                 }
     476     1590106 :                 st->cngTDLevel = (float) sqrt( ( sum_f( cngNoiseLevel, hFdCngCom->stopFFTbin - hFdCngCom->startBand ) / 2 * hFdCngCom->fftlen ) / st->L_frame );
     477             :             }
     478     2183754 :             else if ( st->element_mode == IVAS_CPE_TD || st->element_mode == IVAS_CPE_DFT )
     479             :             {
     480      445510 :                 if ( hFdCngCom->active_frame_counter > 0 )
     481             :                 {
     482             :                     /* Perform noise estimation in active frames in the decoder for downward updates */
     483      438164 :                     perform_noise_estimation_dec( timeDomainInput, powerSpectrum, hFdCngDec, st->element_mode, st->bwidth, L_frame, last_L_frame, st->last_core_brate, st->VAD );
     484             :                 }
     485             :             }
     486             : 
     487     3773860 :             if ( ( concealWholeFrame == 1 ) && ( st->nbLostCmpt == 1 ) )
     488             :             {
     489             :                 /* update lsf cng estimate for concealment. Do that during concealment, in order to avoid addition clean channel complexity*/
     490             : 
     491             :                 /* always set psychParameters for MDCT-Stereo ... */
     492      153346 :                 if ( st->element_mode == IVAS_CPE_MDCT && st->hTonalMDCTConc != NULL )
     493             :                 {
     494       85636 :                     st->hTonalMDCTConc->psychParams = ( st->core == TCX_20_CORE ) ? &st->hTonalMDCTConc->psychParamsTCX20 : &st->hTonalMDCTConc->psychParamsTCX10;
     495             :                 }
     496             : 
     497             :                 /* ... but do actual computations only if sufficient energy in noise shape */
     498      153346 :                 if ( sum_f( cngNoiseLevel + hFdCngCom->startBand, hFdCngCom->stopFFTbin - hFdCngCom->startBand ) > 0.01f )
     499             :                 {
     500       48271 :                     if ( st->element_mode == IVAS_CPE_MDCT && st->core != ACELP_CORE )
     501             :                     {
     502        1473 :                         TonalMdctConceal_whiten_noise_shape( st, L_frame, ON_FIRST_LOST_FRAME );
     503             :                     }
     504       46798 :                     else if ( st->element_mode != IVAS_CPE_MDCT || st->core == ACELP_CORE )
     505             :                     {
     506       46798 :                         lpc_from_spectrum( hFdCngCom, hFdCngCom->startBand, hFdCngCom->stopFFTbin, 0.f );
     507       46798 :                         a2lsp_stab( hFdCngCom->A_cng, lsp_cng, st->lspold_cng );
     508       46798 :                         mvr2r( lsp_cng, st->lspold_cng, M );
     509       46798 :                         lsp2lsf( lsp_cng, st->lsf_cng, M, sr_core );
     510             :                     }
     511       48271 :                     st->plcBackgroundNoiseUpdated = 1;
     512             :                 }
     513             :             }
     514     3773860 :             break;
     515             : 
     516        6056 :         case SID_FRAME:
     517        6056 :             hFdCngDec->flag_dtx_mode = 1;
     518             :             /* FALLTHRU */
     519             : 
     520       45781 :         case ZERO_FRAME:
     521             : 
     522       45781 :             if ( st != NULL && st->cng_type == LP_CNG )
     523             :             {
     524             :                 /* Perform noise estimation on inactive phase at the decoder */
     525        3450 :                 perform_noise_estimation_dec( timeDomainInput, powerSpectrum, hFdCngDec, st->element_mode, st->bwidth, L_frame, last_L_frame, st->last_core_brate, st->VAD );
     526             : 
     527        3450 :                 if ( st->element_mode != IVAS_CPE_TD && st->element_mode != IVAS_CPE_DFT )
     528             :                 {
     529             :                     /* Update the shaping parameters */
     530           0 :                     scalebands( hFdCngDec->msNoiseEst, hFdCngDec->part_shaping, hFdCngDec->nFFTpart_shaping, hFdCngDec->midband_shaping, hFdCngDec->nFFTpart_shaping, hFdCngCom->stopFFTbin - hFdCngCom->startBand, hFdCngDec->bandNoiseShape, 1 );
     531             :                 }
     532             : 
     533             :                 /* This sets the new CNG levels until a SID update overwrites it */
     534        3450 :                 mvr2r( hFdCngDec->bandNoiseShape, cngNoiseLevel, hFdCngCom->stopFFTbin - hFdCngCom->startBand ); /* This sets the new CNG levels until a SID update overwrites it */
     535             : 
     536        3450 :                 st->cngTDLevel = (float) sqrt( ( sum_f( cngNoiseLevel, hFdCngCom->stopFFTbin - hFdCngCom->startBand ) / 2 * hFdCngCom->fftlen ) / L_frame );
     537        3450 :                 break;
     538             :             }
     539             : 
     540       42331 :             hFdCngCom->inactive_frame_counter++;
     541             : 
     542             :             /*************************************
     543             :              * SID_FRAME or ZERO_FRAME at DECODER *
     544             :              *************************************/
     545             : 
     546             :             /* Detect first non-active frame */
     547       42331 :             if ( hFdCngCom->inactive_frame_counter == 1 )
     548             :             {
     549             :                 /* Compute the fine spectral structure of the comfort noise shape using the decoder-side noise estimates */
     550        1089 :                 bandcombinepow( hFdCngDec->bandNoiseShape, hFdCngCom->stopFFTbin - hFdCngCom->startBand, hFdCngCom->part, hFdCngCom->nFFTpart, hFdCngCom->psize_inv, hFdCngDec->partNoiseShape );
     551             : 
     552        1089 :                 if ( st->element_mode == IVAS_CPE_DFT )
     553             :                 {
     554         882 :                     mvr2r( st->hFdCngDec->hFdCngCom->sidNoiseEst, st->hFdCngDec->hFdCngCom->sidNoiseEstLp, NPART );
     555             :                 }
     556             :             }
     557             : 
     558       42331 :             if ( st->m_frame_type == SID_FRAME )
     559             :             {
     560        5411 :                 if ( hFdCngCom->msFrCnt_init_counter < hFdCngCom->msFrCnt_init_thresh )
     561             :                 {
     562             :                     /* At initialization, interpolate the bin/band-wise levels from the partition levels */
     563          92 :                     scalebands( sidNoiseEst, hFdCngCom->part, hFdCngCom->npart, hFdCngCom->midband, hFdCngCom->nFFTpart, hFdCngCom->stopBand - hFdCngCom->startBand, cngNoiseLevel, 1 );
     564             :                 }
     565             :                 else
     566             :                 {
     567        5319 :                     if ( st->element_mode == IVAS_CPE_DFT )
     568             :                     {
     569        4521 :                         sidNoiseEst = hFdCngCom->sidNoiseEstLp;
     570             :                     }
     571             : 
     572             :                     /* Interpolate the CLDFB band levels from the SID (partition) levels */
     573        5319 :                     if ( hFdCngCom->regularStopBand > hFdCngCom->numCoreBands )
     574             :                     {
     575        4452 :                         scalebands( sidNoiseEst, hFdCngCom->part, hFdCngCom->npart, hFdCngCom->midband, hFdCngCom->nFFTpart, hFdCngCom->stopBand - hFdCngCom->startBand, cngNoiseLevel, 0 );
     576             :                     }
     577             : 
     578             : 
     579             :                     /* Shape the SID noise levels in each FFT bin */
     580        5319 :                     j = 0;
     581      114894 :                     for ( k = 0; k < hFdCngCom->nFFTpart; k++ )
     582             :                     {
     583      109575 :                         factor = ( sidNoiseEst[k] + DELTA ) / ( hFdCngDec->partNoiseShape[k] + DELTA );
     584     1665081 :                         for ( ; j <= hFdCngCom->part[k]; j++ )
     585             :                         {
     586     1555506 :                             cngNoiseLevel[j] = hFdCngDec->bandNoiseShape[j] * factor;
     587             :                         }
     588             :                     }
     589             :                 }
     590             :             }
     591       36920 :             else if ( st->element_mode == IVAS_CPE_DFT )
     592             :             {
     593       31390 :                 if ( !( hFdCngCom->msFrCnt_init_counter < hFdCngCom->msFrCnt_init_thresh ) )
     594             :                 {
     595       31390 :                     sidNoiseEst = hFdCngCom->sidNoiseEstLp;
     596       31390 :                     j = 0;
     597      677973 :                     for ( k = 0; k < hFdCngCom->nFFTpart; k++ )
     598             :                     {
     599      646583 :                         factor = ( sidNoiseEst[k] + DELTA ) / ( hFdCngDec->partNoiseShape[k] + DELTA );
     600     9821755 :                         for ( ; j <= hFdCngCom->part[k]; j++ )
     601             :                         {
     602     9175172 :                             cngNoiseLevel[j] = hFdCngDec->bandNoiseShape[j] * factor;
     603             :                         }
     604             :                     }
     605             :                 }
     606             :             }
     607       42331 :             if ( st->codec_mode == MODE2 )
     608             :             {
     609             :                 /* Generate comfort noise during SID or zero frames */
     610           0 :                 generate_comfort_noise_dec( realBuffer, imagBuffer, st, -1 );
     611             :             }
     612             : 
     613       42331 :             break;
     614             : 
     615           0 :         default:
     616           0 :             break;
     617             :     }
     618             : 
     619     3819641 :     pop_wmops();
     620             : 
     621     3819641 :     return;
     622             : }
     623             : 
     624             : 
     625             : /*-------------------------------------------------------------------
     626             :  * perform_noise_estimation_dec()
     627             :  *
     628             :  * Perform noise estimation at the decoder
     629             :  *-------------------------------------------------------------------*/
     630             : 
     631     2031720 : static void perform_noise_estimation_dec(
     632             :     const float *timeDomainInput,
     633             :     float *power_spectrum,
     634             :     HANDLE_FD_CNG_DEC hFdCngDec,   /* i/o: FD_CNG structure containing all buffers and variables */
     635             :     const int16_t element_mode,    /* i  : element mode                                          */
     636             :     const int16_t bwidth,          /* i  : audio bandwidth                                       */
     637             :     const int16_t L_frame,         /* i  : frame length at internal Fs                           */
     638             :     const int16_t last_L_frame,    /* i  : frame length of the last frame at internal Fs         */
     639             :     const int32_t last_core_brate, /* i  : previous frame core bitrate                           */
     640             :     const int16_t VAD              /* i  : VAD flag in the decoder                               */
     641             : )
     642             : {
     643             :     float *ptr_r;
     644             :     float *ptr_i;
     645     2031720 :     int16_t startBand = hFdCngDec->hFdCngCom->startBand;
     646     2031720 :     int16_t stopFFTbin = hFdCngDec->hFdCngCom->stopFFTbin;
     647     2031720 :     float *fftBuffer = hFdCngDec->hFdCngCom->fftBuffer;
     648     2031720 :     float *periodog = hFdCngDec->hFdCngCom->periodog;
     649     2031720 :     float *ptr_per = periodog;
     650     2031720 :     float *msPeriodog = hFdCngDec->msPeriodog;
     651     2031720 :     float *msNoiseEst = hFdCngDec->msNoiseEst;
     652             : 
     653     2031720 :     int16_t *part = hFdCngDec->part_shaping;
     654     2031720 :     int16_t npart = hFdCngDec->npart_shaping;
     655     2031720 :     int16_t nFFTpart = hFdCngDec->nFFTpart_shaping;
     656     2031720 :     float *psize_inv = hFdCngDec->psize_inv_shaping;
     657     2031720 :     float *psize = hFdCngDec->psize_shaping;
     658     2031720 :     float *msLogPeriodog = hFdCngDec->msLogPeriodog;
     659     2031720 :     float *msLogNoiseEst = hFdCngDec->msLogNoiseEst;
     660             :     int16_t i;
     661             :     float enr, enr_tot, enr_tot0, enr_ratio, alpha;
     662             :     int16_t p;
     663             :     float temp, ftemp, delta;
     664             :     float wght;
     665             : 
     666     2031720 :     if ( !( element_mode == IVAS_CPE_MDCT && power_spectrum != NULL ) )
     667             :     {
     668             :         /* Perform STFT analysis */
     669     2001256 :         AnalysisSTFT( timeDomainInput, fftBuffer, hFdCngDec->hFdCngCom );
     670             :     }
     671             : 
     672     2031720 :     if ( element_mode == IVAS_CPE_TD || element_mode == IVAS_CPE_DFT )
     673             :     {
     674             :         /* Calculate periodogram (squared magnitude in each FFT bin) */
     675      466449 :         if ( startBand == 0 )
     676             :         {
     677           0 :             ( *ptr_per ) = fftBuffer[0] * fftBuffer[0];
     678           0 :             ptr_per++;
     679           0 :             ptr_r = fftBuffer + 2;
     680             :         }
     681             :         else
     682             :         {
     683      466449 :             ptr_r = fftBuffer + 2 * startBand;
     684             :         }
     685             : 
     686      466449 :         ptr_i = ptr_r + 1;
     687             : 
     688   132097711 :         for ( ; ptr_per < periodog + stopFFTbin - startBand; ptr_per++ )
     689             :         {
     690   131631262 :             ( *ptr_per ) = ( *ptr_r ) * ( *ptr_r ) + ( *ptr_i ) * ( *ptr_i );
     691   131631262 :             ptr_r += 2;
     692   131631262 :             ptr_i += 2;
     693             :         }
     694             : 
     695             :         /* 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*/
     696      466449 :         v_multc( periodog, 4.f / (float) ( hFdCngDec->hFdCngCom->fftlen * hFdCngDec->hFdCngCom->fftlen ), periodog, stopFFTbin - startBand );
     697             : 
     698             :         /* Combine bins of power spectrum into partitions */
     699      466449 :         i = 0;
     700    29180768 :         for ( p = 0; p < npart; p++ )
     701             :         {
     702             : 
     703             :             /* calculate mean over all bins in power partition */
     704    28714319 :             temp = 0;
     705   160345581 :             for ( ; i <= part[p]; i++ )
     706             :             {
     707   131631262 :                 temp += periodog[i];
     708             :             }
     709    28714319 :             msPeriodog[p] = temp * psize_inv[p];
     710             :         }
     711             : 
     712             :         /* compensate for the loss of variance - don't do when first noise update is not completed yet due to risk of msPeriodog[p] < 0 */
     713      466449 :         if ( hFdCngDec->first_cna_noise_updated )
     714             :         {
     715       70183 :             i = 0;
     716     4384663 :             for ( p = 0; p < npart; p++ )
     717             :             {
     718             :                 /* calculate variance over all bins in power partition */
     719     4314480 :                 temp = 0;
     720    24500386 :                 for ( ; i <= part[p]; i++ )
     721             :                 {
     722    20185906 :                     delta = periodog[i] - msPeriodog[p];
     723    20185906 :                     temp += delta * delta;
     724             :                 }
     725     4314480 :                 temp *= psize_inv[p];
     726             : 
     727             :                 /* compensate for the loss of variance */
     728     4314480 :                 msPeriodog[p] = (float) ( msPeriodog[p] + sqrt( temp ) * rand_gauss( &ftemp, &hFdCngDec->cna_seed ) );
     729             : 
     730     4314480 :                 if ( msPeriodog[p] < 1e-5f )
     731             :                 {
     732      210221 :                     msPeriodog[p] = 1e-5f;
     733             :                 }
     734             :             }
     735             :         }
     736             : 
     737             :         /* calculate total energy (short-term and long-term) */
     738      466449 :         enr_tot = sum_f( msPeriodog, npart ) + EPSILON;
     739      466449 :         enr_tot0 = sum_f( msNoiseEst, npart ) + EPSILON;
     740             : 
     741             :         /* update short-term periodogram on larger partitions */
     742     5858318 :         for ( p = CNA_ACT_DN_LARGE_PARTITION; p < npart; p++ )
     743             :         {
     744     5391869 :             if ( L_frame != last_L_frame || last_core_brate <= SID_2k40 )
     745             :             {
     746             :                 /* core Fs has changed or last frame was SID/NO_DATA -> re-initialize short-term periodogram */
     747       82671 :                 hFdCngDec->msPeriodog_ST[p] = msPeriodog[p];
     748             :             }
     749             :             else
     750             :             {
     751     5309198 :                 hFdCngDec->msPeriodog_ST[p] = (float) ( ST_PERIODOG_FACT * hFdCngDec->msPeriodog_ST[p] + ( 1 - ST_PERIODOG_FACT ) * msPeriodog[p] );
     752             :             }
     753             :         }
     754             : 
     755             :         /* core Fs has changed -> partitions have changed -> re-calculate long-term periodogram */
     756             :         /* part L_FRAME16k L_FRAME */
     757             :         /* ...                     */
     758             :         /* [55] 146        146     */
     759             :         /* [56] 174        160     */
     760             :         /* [57] 210        174     */
     761             :         /* [58] 254        190     */
     762             :         /* [59] 306        210     */
     763             :         /* [60] 317        230     */
     764             :         /* [61]            253     */
     765             : 
     766      466449 :         if ( last_L_frame == L_FRAME16k && L_frame == L_FRAME )
     767             :         {
     768        3037 :             msNoiseEst[61] = msNoiseEst[58];
     769        3037 :             msNoiseEst[60] = min( msNoiseEst[58], msNoiseEst[57] );
     770        3037 :             msNoiseEst[59] = msNoiseEst[57];
     771        3037 :             msNoiseEst[58] = msNoiseEst[56];
     772        3037 :             msNoiseEst[57] = msNoiseEst[56];
     773        3037 :             msNoiseEst[56] = min( msNoiseEst[56], msNoiseEst[55] );
     774             :         }
     775      463412 :         else if ( last_L_frame == L_FRAME && L_frame == L_FRAME16k )
     776             :         {
     777         708 :             msNoiseEst[56] = min( msNoiseEst[56], msNoiseEst[57] );
     778         708 :             msNoiseEst[57] = min( msNoiseEst[58], msNoiseEst[59] );
     779         708 :             msNoiseEst[58] = min( msNoiseEst[60], msNoiseEst[61] );
     780         708 :             msNoiseEst[59] = 0.0f;
     781         708 :             msNoiseEst[60] = 0.0f;
     782         708 :             msNoiseEst[61] = 0.0f;
     783             : 
     784         708 :             hFdCngDec->ms_cnt_bw_up = FIRST_CNA_NOISE_UPD_FRAMES;
     785             :         }
     786             : 
     787             :         /* Smooth with IIR filter */
     788      466449 :         if ( !hFdCngDec->first_cna_noise_updated )
     789             :         {
     790      396266 :             if ( !VAD )
     791             :             {
     792             :                 /* background noise update with moving average */
     793        2414 :                 alpha = 1.0f / ( hFdCngDec->first_cna_noise_update_cnt + 1 );
     794      150893 :                 for ( p = 0; p < npart; p++ )
     795             :                 {
     796      148479 :                     msNoiseEst[p] = ( 1 - alpha ) * msNoiseEst[p] + alpha * msPeriodog[p];
     797             :                 }
     798             : 
     799             :                 /* check, if we reached the required number of first CNA noise update frames */
     800        2414 :                 if ( hFdCngDec->first_cna_noise_update_cnt < FIRST_CNA_NOISE_UPD_FRAMES - 1 )
     801             :                 {
     802        2002 :                     hFdCngDec->first_cna_noise_update_cnt++;
     803             :                 }
     804             :                 else
     805             :                 {
     806         412 :                     hFdCngDec->first_cna_noise_updated = 1;
     807         412 :                     if ( hFdCngDec->hFdCngCom->msFrCnt_init_counter == 0 )
     808             :                     {
     809         151 :                         hFdCngDec->hFdCngCom->msFrCnt_init_counter = 1;
     810             :                     }
     811             :                 }
     812             :             }
     813             :             else
     814             :             {
     815      393852 :                 hFdCngDec->first_cna_noise_update_cnt = 0;
     816             :             }
     817             :         }
     818             :         else
     819             :         {
     820       70183 :             hFdCngDec->hFdCngCom->msFrCnt_init_counter = 1;
     821       70183 :             if ( VAD )
     822             :             {
     823             :                 /* no updates during active frames except for significant energy drops */
     824       57659 :                 enr_ratio = enr_tot / enr_tot0;
     825       57659 :                 if ( enr_ratio < 0.5f )
     826             :                 {
     827             :                     /* total energy significantly decreases during active frames -> downward update */
     828        2719 :                     wght = lin_interp( enr_ratio, 0.0f, 0.8f, 0.5f, 0.95f, 1 );
     829      169868 :                     for ( p = 0; p < npart; p++ )
     830             :                     {
     831      167149 :                         if ( msPeriodog[p] < msNoiseEst[p] )
     832             :                         {
     833      123080 :                             msNoiseEst[p] = wght * msNoiseEst[p] + ( 1 - wght ) * msPeriodog[p];
     834             :                         }
     835             :                     }
     836             :                 }
     837             :                 else
     838             :                 {
     839             :                     /* energy significantly decreases in one of the larger partitions during active frames -> downward update */
     840      685840 :                     for ( p = CNA_ACT_DN_LARGE_PARTITION; p < npart; p++ )
     841             :                     {
     842      630900 :                         if ( hFdCngDec->msPeriodog_ST[p] < msNoiseEst[p] )
     843             :                         {
     844       44957 :                             msNoiseEst[p] = (float) ( CNA_ACT_DN_FACT * msNoiseEst[p] + ( 1 - CNA_ACT_DN_FACT ) * hFdCngDec->msPeriodog_ST[p] );
     845             :                         }
     846             :                     }
     847             :                 }
     848             :             }
     849             :             else
     850             :             {
     851             : 
     852       12524 :                 if ( bwidth >= WB && hFdCngDec->ms_last_inactive_bwidth == NB )
     853             :                 {
     854             :                     /* bandwidth increased -> set counter for fast initilization  */
     855         166 :                     hFdCngDec->ms_cnt_bw_up = FIRST_CNA_NOISE_UPD_FRAMES;
     856             :                 }
     857       12524 :                 hFdCngDec->ms_last_inactive_bwidth = bwidth;
     858             :                 /* update background noise during inactive frames */
     859       12524 :                 ptr_per = msNoiseEst;
     860      781955 :                 for ( p = 0; p < npart; p++ )
     861             :                 {
     862      769431 :                     enr = msPeriodog[p];
     863      769431 :                     alpha = 0.95f;
     864             :                     /* bandwidth increased -> do fast re-initilization  */
     865      769431 :                     if ( hFdCngDec->ms_cnt_bw_up > 0 && p > 55 )
     866             :                     {
     867        6266 :                         alpha = 1.0f / ( hFdCngDec->ms_cnt_bw_up + 1 );
     868             :                     }
     869      763165 :                     else if ( enr < *ptr_per && part[p] == 1 )
     870             :                     {
     871             :                         /* faster downward update for single-bin partitions */
     872        4313 :                         alpha = 0.8f;
     873             :                     }
     874      758852 :                     else if ( enr > 2.0f * ( *ptr_per ) )
     875             :                     {
     876             :                         /* prevent abrupt upward updates */
     877      236407 :                         enr = 2.0f * ( *ptr_per );
     878             :                     }
     879             : 
     880             :                     /* IIR smoothing */
     881      769431 :                     *ptr_per *= alpha;
     882      769431 :                     *ptr_per += ( 1 - alpha ) * enr;
     883      769431 :                     ptr_per++;
     884             :                 }
     885             : 
     886       12524 :                 if ( hFdCngDec->ms_cnt_bw_up > 0 )
     887             :                 {
     888        1169 :                     hFdCngDec->ms_cnt_bw_up--;
     889             :                 }
     890             :             }
     891             :         }
     892             : 
     893      466449 :         mvr2r( msNoiseEst, hFdCngDec->msPsd, npart );
     894             : 
     895             :         /* Expand partitions into bins of power spectrum */
     896      466449 :         scalebands( msNoiseEst, part, nFFTpart, hFdCngDec->midband_shaping, nFFTpart, stopFFTbin - startBand, hFdCngDec->bandNoiseShape, 1 );
     897             : 
     898      466449 :         mvr2r( hFdCngDec->bandNoiseShape, &hFdCngDec->smoothed_psd[startBand], stopFFTbin - startBand );
     899      466449 :         set_zero( &hFdCngDec->smoothed_psd[stopFFTbin], L_FRAME16k - stopFFTbin );
     900             :     }
     901             :     else
     902             :     {
     903     1565271 :         if ( element_mode == IVAS_CPE_MDCT && power_spectrum != NULL )
     904             :         {
     905             :             /* use power spectrum calculated in the MDCT-domain instead of calculating new power spectrum */
     906       30464 :             periodog = power_spectrum;
     907             :         }
     908             :         else
     909             :         {
     910             :             /* Compute the squared magnitude in each FFT bin */
     911     1534807 :             if ( startBand == 0 )
     912             :             {
     913           0 :                 ( *ptr_per ) = fftBuffer[0] * fftBuffer[0]; /* DC component */
     914           0 :                 ptr_per++;
     915           0 :                 ptr_r = fftBuffer + 2;
     916             :             }
     917             :             else
     918             :             {
     919     1534807 :                 ptr_r = fftBuffer + 2 * startBand;
     920             :             }
     921             : 
     922     1534807 :             ptr_i = ptr_r + 1;
     923             : 
     924   449258409 :             for ( ; ptr_per < periodog + stopFFTbin - startBand; ptr_per++ )
     925             :             {
     926   447723602 :                 ( *ptr_per ) = ( *ptr_r ) * ( *ptr_r ) + ( *ptr_i ) * ( *ptr_i );
     927   447723602 :                 ptr_r += 2;
     928   447723602 :                 ptr_i += 2;
     929             :             }
     930             :             /* Nyquist frequency is discarded */
     931             : 
     932             :             /* 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*/
     933     1534807 :             v_multc( periodog, 4.f / (float) ( hFdCngDec->hFdCngCom->fftlen * hFdCngDec->hFdCngCom->fftlen ), periodog, stopFFTbin - startBand );
     934             :         }
     935             : 
     936             :         /* Adjust to the desired frequency resolution by averaging over spectral partitions for SID transmission */
     937     1565271 :         bandcombinepow( periodog, stopFFTbin - startBand, part, npart, psize_inv, msPeriodog );
     938             : 
     939             :         /* Compress MS inputs */
     940     1565271 :         compress_range( msPeriodog, msLogPeriodog, npart );
     941             : 
     942             :         /* Call the minimum statistics routine for noise estimation */
     943     1565271 :         minimum_statistics( npart, nFFTpart, psize, msLogPeriodog, hFdCngDec->msNoiseFloor, msLogNoiseEst, hFdCngDec->msAlpha, hFdCngDec->msPsd, hFdCngDec->msPsdFirstMoment, hFdCngDec->msPsdSecondMoment, hFdCngDec->msMinBuf, hFdCngDec->msBminWin, hFdCngDec->msBminSubWin, hFdCngDec->msCurrentMin, hFdCngDec->msCurrentMinOut, hFdCngDec->msCurrentMinSubWindow, hFdCngDec->msLocalMinFlag, hFdCngDec->msNewMinFlag, hFdCngDec->msPeriodogBuf, &( hFdCngDec->msPeriodogBufPtr ), hFdCngDec->hFdCngCom,
     944             :                             DEC, element_mode );
     945             : 
     946             :         /* Expand MS outputs */
     947     1565271 :         expand_range( msLogNoiseEst, msNoiseEst, npart );
     948             :     }
     949             : 
     950     2031720 :     return;
     951             : }
     952             : 
     953             : 
     954             : /*-------------------------------------------------------------------
     955             :  * FdCng_decodeSID()
     956             :  *
     957             :  * Decode the FD-CNG bitstream
     958             :  *-------------------------------------------------------------------*/
     959             : 
     960        6030 : void FdCng_decodeSID(
     961             :     Decoder_State *st /* i/o: decoder state structure */
     962             : )
     963             : {
     964             :     int16_t N;
     965             :     float *sidNoiseEst;
     966             :     float gain;
     967             :     int16_t i, index;
     968             :     float v[32];
     969             :     int16_t indices[32];
     970             :     HANDLE_FD_CNG_COM hFdCngCom;
     971             :     float *invTrfMatrix;
     972             :     float tmpRAM[FDCNG_VQ_MAX_LEN][FDCNG_VQ_DCT_MAXTRUNC];
     973             : 
     974        6030 :     const float gain_q_offset = ( st->element_mode == EVS_MONO ) ? GAIN_Q_OFFSET_EVS : GAIN_Q_OFFSET_IVAS;
     975             : 
     976        6030 :     invTrfMatrix = (float *) tmpRAM;
     977             : 
     978        6030 :     hFdCngCom = ( st->hFdCngDec )->hFdCngCom;
     979             : 
     980        6030 :     sidNoiseEst = hFdCngCom->sidNoiseEst;
     981             : 
     982        6030 :     N = hFdCngCom->npart;
     983        6030 :     gain = 0.0f;
     984        6030 :     hFdCngCom->sid_frame_counter++;
     985             : 
     986             :     /* Read bitstream */
     987       42210 :     for ( i = 0; i < FD_CNG_stages_37bits; i++ )
     988             :     {
     989       36180 :         indices[i] = get_next_indice( st, bits_37bits[i] );
     990             :     }
     991             : 
     992        6030 :     index = get_next_indice( st, 7 );
     993             : 
     994             :     /* MSVQ decoder */
     995             : 
     996        6030 :     if ( st->element_mode != EVS_MONO )
     997             :     {
     998        6030 :         create_IDCT_N_Matrix( invTrfMatrix, FDCNG_VQ_MAX_LEN, FDCNG_VQ_DCT_MAXTRUNC, sizeof( tmpRAM ) / ( sizeof( float ) ) );
     999        6030 :         msvq_dec( cdk_37bits_ivas, NULL, NULL, FD_CNG_stages_37bits, N, FD_CNG_maxN_37bits, indices, 1, invTrfMatrix, v, NULL );
    1000             :     }
    1001             :     else
    1002             :     { /* Legacy EVS_MONO MSVQ tables */
    1003           0 :         msvq_dec( cdk_37bits, NULL, NULL, FD_CNG_stages_37bits, N, FD_CNG_maxN_37bits, indices, 0, NULL, v, NULL );
    1004             :     }
    1005             : 
    1006             : 
    1007             :     /* Decode gain */
    1008        6030 :     gain = ( (float) index - gain_q_offset ) / 1.5f;
    1009             : 
    1010             :     /* Apply gain and undo log */
    1011      146985 :     for ( i = 0; i < N; i++ )
    1012             :     {
    1013      140955 :         sidNoiseEst[i] = (float) pow( 10.f, ( v[i] + gain ) / 10.f );
    1014             :     }
    1015             : 
    1016             :     /* NB last band energy compensation */
    1017             : 
    1018        6030 :     if ( hFdCngCom->CngBandwidth == NB )
    1019             :     {
    1020           0 :         sidNoiseEst[N - 1] *= NB_LAST_BAND_SCALE;
    1021             :     }
    1022             : 
    1023        6030 :     if ( hFdCngCom->CngBandwidth == SWB && hFdCngCom->CngBitrate <= ACELP_13k20 )
    1024             :     {
    1025        1711 :         sidNoiseEst[N - 1] *= SWB_13k2_LAST_BAND_SCALE;
    1026             :     }
    1027             : 
    1028        6030 :     scalebands( sidNoiseEst, hFdCngCom->part, hFdCngCom->npart, hFdCngCom->midband, hFdCngCom->nFFTpart, hFdCngCom->stopBand - hFdCngCom->startBand, hFdCngCom->cngNoiseLevel, 1 );
    1029             : 
    1030        6030 :     lpc_from_spectrum( hFdCngCom, hFdCngCom->startBand, hFdCngCom->stopFFTbin, st->preemph_fac );
    1031             : 
    1032        6030 :     return;
    1033             : }
    1034             : 
    1035             : 
    1036             : /*-------------------------------------------------------------------
    1037             :  * noisy_speech_detection()
    1038             :  *
    1039             :  *
    1040             :  *-------------------------------------------------------------------*/
    1041             : 
    1042     6083377 : void noisy_speech_detection(
    1043             :     HANDLE_FD_CNG_DEC hFdCngDec, /* i/o: FD_CNG structure            */
    1044             :     const int16_t vad,           /* i  : VAD flag                    */
    1045             :     const float syn[]            /* i  : input time-domain frame     */
    1046             : )
    1047             : {
    1048             :     float tmp;
    1049             : 
    1050     6083377 :     if ( vad == 0 )
    1051             :     {
    1052      208098 :         tmp = dotp( hFdCngDec->msNoiseEst, hFdCngDec->psize_shaping, hFdCngDec->nFFTpart_shaping );
    1053      208098 :         hFdCngDec->lp_noise = 0.995f * hFdCngDec->lp_noise + 0.005f * 10.f * (float) log10( tmp + DELTA );
    1054             :     }
    1055             :     else
    1056             :     {
    1057     5875279 :         tmp = dotp( syn, syn, hFdCngDec->hFdCngCom->frameSize ) * 2.f / hFdCngDec->hFdCngCom->frameSize;
    1058     5875279 :         hFdCngDec->lp_speech = 0.995f * hFdCngDec->lp_speech + 0.005f * 10.f * (float) log10( tmp + DELTA );
    1059             :     }
    1060             : 
    1061     6083377 :     tmp = hFdCngDec->lp_speech - 45.f;
    1062     6083377 :     if ( hFdCngDec->lp_noise < tmp )
    1063             :     {
    1064     5141600 :         hFdCngDec->lp_noise = tmp;
    1065             :     }
    1066             : 
    1067     6083377 :     hFdCngDec->hFdCngCom->flag_noisy_speech = ( hFdCngDec->lp_speech - hFdCngDec->lp_noise ) < 28.f;
    1068             : 
    1069     6083377 :     return;
    1070             : }
    1071             : 
    1072             : 
    1073             : /*-------------------------------------------------------------------
    1074             :  * generate_comfort_noise_dec()
    1075             :  *
    1076             :  * Generate the comfort noise based on the target noise level
    1077             :  *-------------------------------------------------------------------*/
    1078             : 
    1079       58473 : void generate_comfort_noise_dec(
    1080             :     float **bufferReal,     /* o  : Real part of input bands      */
    1081             :     float **bufferImag,     /* o  : Imaginary part of input bands */
    1082             :     Decoder_State *st,      /* i/o: decoder state structure       */
    1083             :     const int16_t nchan_out /* i  : number of output channels     */
    1084             : )
    1085             : {
    1086             :     int16_t i, j;
    1087             :     float *ptr_r, *ptr_i;
    1088       58473 :     HANDLE_FD_CNG_DEC hFdCngDec = st->hFdCngDec;
    1089       58473 :     HANDLE_FD_CNG_COM hFdCngCom = hFdCngDec->hFdCngCom;
    1090       58473 :     float *cngNoiseLevel = hFdCngCom->cngNoiseLevel;
    1091       58473 :     float *ptr_level = cngNoiseLevel;
    1092       58473 :     int16_t *seed = &( hFdCngCom->seed );
    1093             :     int16_t *seed2;
    1094             :     float c1, c2;
    1095             :     float tmp1, tmp2;
    1096             :     float scale, scaleCldfb;
    1097       58473 :     float *fftBuffer = hFdCngCom->fftBuffer;
    1098       58473 :     float *timeDomainOutput = hFdCngCom->timeDomainBuffer;
    1099             :     int16_t tcx_transition;
    1100             :     float enr, att;
    1101             : 
    1102       58473 :     scale = 1.f;
    1103       58473 :     scaleCldfb = CLDFB_SCALING / hFdCngCom->scalingFactor;
    1104             : 
    1105             : #ifdef NONBE_MDCT_ST_DTX_FIX_SUBOPT_SPATIAL_CNG
    1106       58473 :     c1 = (float) sqrt( hFdCngCom->coherence[0] );
    1107       58473 :     c2 = (float) sqrt( 1 - hFdCngCom->coherence[0] );
    1108             : #else
    1109             :     c1 = (float) sqrt( hFdCngCom->coherence );
    1110             :     c2 = (float) sqrt( 1 - hFdCngCom->coherence );
    1111             : #endif
    1112             : 
    1113       58473 :     seed2 = &( hFdCngCom->seed2 );
    1114       58473 :     if ( st->element_mode == IVAS_CPE_MDCT && st->idchan == 1 )
    1115             :     {
    1116        9645 :         seed2 = &( hFdCngCom->seed3 );
    1117             :     }
    1118             : 
    1119             :     /* Generate Gaussian random noise in real and imaginary parts of the FFT bins
    1120             :       Amplitudes are adjusted to the estimated noise level cngNoiseLevel in each bin */
    1121             : 
    1122       58473 :     if ( hFdCngCom->startBand == 0 )
    1123             :     {
    1124             : #ifdef NONBE_MDCT_ST_DTX_FIX_SUBOPT_SPATIAL_CNG
    1125           0 :         if ( ( st->element_mode == IVAS_CPE_MDCT && nchan_out != 1 ) || ( st->element_mode == IVAS_SCE && st->cng_ism_flag ) )
    1126             : #else
    1127             :         if ( st->element_mode == IVAS_CPE_MDCT || ( st->element_mode == IVAS_SCE && st->cng_ism_flag ) )
    1128             : #endif
    1129             :         {
    1130           0 :             rand_gauss( &tmp1, seed );
    1131           0 :             rand_gauss( &tmp2, seed2 );
    1132           0 :             fftBuffer[0] = tmp1 * c1 + tmp2 * c2;
    1133             :         }
    1134             :         else
    1135             :         {
    1136           0 :             rand_gauss( &fftBuffer[0], seed );
    1137             :         }
    1138           0 :         fftBuffer[0] *= (float) sqrt( scale * *ptr_level ); /* DC component in FFT */
    1139           0 :         ptr_level++;
    1140           0 :         ptr_r = fftBuffer + 2;
    1141             :     }
    1142             :     else
    1143             :     {
    1144       58473 :         fftBuffer[0] = 0.f;
    1145       58473 :         set_f( fftBuffer + 2, 0.0f, 2 * ( hFdCngCom->startBand - 1 ) );
    1146       58473 :         ptr_r = fftBuffer + 2 * hFdCngCom->startBand;
    1147             :     }
    1148             : 
    1149       58473 :     ptr_i = ptr_r + 1;
    1150             : #ifdef NONBE_MDCT_ST_DTX_FIX_SUBOPT_SPATIAL_CNG
    1151       58473 :     if ( st->element_mode == IVAS_CPE_MDCT && nchan_out != 1 )
    1152       19004 :     {
    1153             :         int16_t band_len_accu;
    1154             : 
    1155       19004 :         band_len_accu = 0;
    1156       19004 :         i = 0;
    1157      114024 :         for ( int16_t b = 0; b < MDCT_ST_DTX_NUM_COHERENCE_BANDS; b++ )
    1158             :         {
    1159       95020 :             band_len_accu += mdct_stereo_dtx_coherence_bandlengths[b];
    1160             : 
    1161             :             /* First band needs to be shortened. The offset from encoder-side estimation is already in, so add it back here */
    1162       95020 :             if ( b == 0 )
    1163             :             {
    1164       19004 :                 band_len_accu += MDCT_ST_DTX_FIRST_BAND_OFFSET - hFdCngCom->startBand;
    1165             :             }
    1166             : 
    1167             :             /*
    1168             :              * for last band, we need to keep going until the end of the fft section - if there is still any
    1169             :              * this way, the coherence value of the last band is used for eveyrthing above as well
    1170             :              */
    1171       95020 :             if ( b == MDCT_ST_DTX_NUM_COHERENCE_BANDS - 1 )
    1172             :             {
    1173       19004 :                 band_len_accu = max( band_len_accu, hFdCngCom->stopFFTbin - hFdCngCom->startBand );
    1174             :             }
    1175             : 
    1176             :             /* mixing values for coherence is now frequency-dependent */
    1177       95020 :             c1 = (float) sqrt( hFdCngCom->coherence[b] );
    1178       95020 :             c2 = (float) sqrt( 1 - hFdCngCom->coherence[b] );
    1179             : 
    1180     6138292 :             for ( ; i < band_len_accu; i++ )
    1181             :             {
    1182             :                 float val_level;
    1183     6043272 :                 val_level = (float) sqrt( ( scale * *ptr_level ) * 0.5f );
    1184             : 
    1185             :                 /* Real part in FFT bins */
    1186     6043272 :                 rand_gauss( &tmp1, seed );
    1187     6043272 :                 rand_gauss( &tmp2, seed2 );
    1188     6043272 :                 *ptr_r = tmp1 * c1 + tmp2 * c2;
    1189     6043272 :                 ( *ptr_r ) *= val_level;
    1190             : 
    1191             :                 /* Imaginary part in FFT bins */
    1192     6043272 :                 rand_gauss( &tmp1, seed );
    1193     6043272 :                 rand_gauss( &tmp2, seed2 );
    1194     6043272 :                 *ptr_i = tmp1 * c1 + tmp2 * c2;
    1195     6043272 :                 ( *ptr_i ) *= val_level;
    1196             : 
    1197             :                 /* advance all pointers together here */
    1198     6043272 :                 ptr_r += 2;
    1199     6043272 :                 ptr_i += 2;
    1200     6043272 :                 ptr_level++;
    1201             :             }
    1202             :         }
    1203             :     }
    1204             :     else
    1205             :     {
    1206    11155347 :         for ( ; ptr_level < cngNoiseLevel + hFdCngCom->stopFFTbin - hFdCngCom->startBand; ptr_level++ )
    1207             :         {
    1208             :             /* Real part in FFT bins */
    1209    11115878 :             if ( st->element_mode == IVAS_SCE && st->cng_ism_flag )
    1210             :             {
    1211     4604348 :                 rand_gauss( &tmp1, seed );
    1212     4604348 :                 rand_gauss( &tmp2, seed2 );
    1213     4604348 :                 *ptr_r = tmp1 * c1 + tmp2 * c2;
    1214             :             }
    1215             :             else
    1216             :             {
    1217     6511530 :                 rand_gauss( ptr_r, seed );
    1218             :             }
    1219    11115878 :             ( *ptr_r ) *= (float) sqrt( ( scale * *ptr_level ) * 0.5f );
    1220    11115878 :             ptr_r += 2;
    1221             : 
    1222             :             /* Imaginary part in FFT bins */
    1223    11115878 :             if ( st->element_mode == IVAS_SCE && st->cng_ism_flag )
    1224             :             {
    1225     4604348 :                 rand_gauss( &tmp1, seed );
    1226     4604348 :                 rand_gauss( &tmp2, seed2 );
    1227     4604348 :                 *ptr_i = tmp1 * c1 + tmp2 * c2;
    1228             :             }
    1229             :             else
    1230             :             {
    1231     6511530 :                 rand_gauss( ptr_i, seed );
    1232             :             }
    1233    11115878 :             ( *ptr_i ) *= (float) sqrt( ( scale * *ptr_level ) * 0.5f );
    1234    11115878 :             ptr_i += 2;
    1235             :         }
    1236             :     }
    1237             : #else
    1238             :     for ( ; ptr_level < cngNoiseLevel + hFdCngCom->stopFFTbin - hFdCngCom->startBand; ptr_level++ )
    1239             :     {
    1240             :         /* Real part in FFT bins */
    1241             : #ifdef NONBE_MDCT_ST_DTX_FIX_SUBOPT_SPATIAL_CNG
    1242             :         if ( ( st->element_mode == IVAS_CPE_MDCT && nchan_out != 1 ) || ( st->element_mode == IVAS_SCE && st->cng_ism_flag ) )
    1243             : #else
    1244             :         if ( st->element_mode == IVAS_CPE_MDCT || ( st->element_mode == IVAS_SCE && st->cng_ism_flag ) )
    1245             : #endif
    1246             :         {
    1247             :             rand_gauss( &tmp1, seed );
    1248             :             rand_gauss( &tmp2, seed2 );
    1249             :             *ptr_r = tmp1 * c1 + tmp2 * c2;
    1250             :         }
    1251             :         else
    1252             :         {
    1253             :             rand_gauss( ptr_r, seed );
    1254             :         }
    1255             :         ( *ptr_r ) *= (float) sqrt( ( scale * *ptr_level ) * 0.5f );
    1256             :         ptr_r += 2;
    1257             : 
    1258             :         /* Imaginary part in FFT bins */
    1259             : #ifdef NONBE_MDCT_ST_DTX_FIX_SUBOPT_SPATIAL_CNG
    1260             :         if ( ( st->element_mode == IVAS_CPE_MDCT && nchan_out != 1 ) || ( st->element_mode == IVAS_SCE && st->cng_ism_flag ) )
    1261             : #else
    1262             :         if ( st->element_mode == IVAS_CPE_MDCT || ( st->element_mode == IVAS_SCE && st->cng_ism_flag ) )
    1263             : #endif
    1264             :         {
    1265             :             rand_gauss( &tmp1, seed );
    1266             :             rand_gauss( &tmp2, seed2 );
    1267             :             *ptr_i = tmp1 * c1 + tmp2 * c2;
    1268             :         }
    1269             :         else
    1270             :         {
    1271             :             rand_gauss( ptr_i, seed );
    1272             :         }
    1273             :         ( *ptr_i ) *= (float) sqrt( ( scale * *ptr_level ) * 0.5f );
    1274             :         ptr_i += 2;
    1275             :     }
    1276             : #endif
    1277             : 
    1278             :     /* Remaining FFT bins are set to zero */
    1279       58473 :     set_f( fftBuffer + 2 * hFdCngCom->stopFFTbin, 0.0f, hFdCngCom->fftlen - 2 * hFdCngCom->stopFFTbin );
    1280             : 
    1281             :     /* Nyquist frequency is discarded */
    1282       58473 :     fftBuffer[1] = 0.f;
    1283             : 
    1284             :     /* If previous frame is active, reset the overlap-add buffer */
    1285       58473 :     tcx_transition = 0;
    1286       58473 :     if ( hFdCngCom->frame_type_previous == ACTIVE_FRAME )
    1287             :     {
    1288        6181 :         set_f( hFdCngCom->olapBufferSynth, 0.0f, hFdCngCom->fftlen );
    1289        6181 :         if ( ( st->core > ACELP_CORE && st->codec_mode == MODE2 ) || st->codec_mode == MODE1 )
    1290             :         {
    1291        6181 :             tcx_transition = 1;
    1292             :         }
    1293             :     }
    1294             : 
    1295             :     /* Perform STFT synthesis */
    1296       58473 :     SynthesisSTFT( fftBuffer, timeDomainOutput, hFdCngCom->olapBufferSynth, hFdCngCom->olapWinSyn, tcx_transition, hFdCngCom, st->element_mode, nchan_out );
    1297             : 
    1298             :     /* update CNG excitation energy for LP_CNG */
    1299             : 
    1300             :     /* calculate the residual signal energy */
    1301       58473 :     enr = dotp( hFdCngCom->exc_cng, hFdCngCom->exc_cng, hFdCngCom->frameSize ) / hFdCngCom->frameSize;
    1302             : 
    1303             :     /* convert log2 of residual signal energy */
    1304       58473 :     enr = (float) log10( enr + 0.1f ) / (float) log10( 2.0f );
    1305             : 
    1306             :     /* decrease the energy in case of WB input */
    1307       58473 :     if ( st->bwidth != NB )
    1308             :     {
    1309       58473 :         if ( st->bwidth == WB )
    1310             :         {
    1311       13050 :             if ( st->CNG_mode >= 0 )
    1312             :             {
    1313             :                 /* Bitrate adapted attenuation */
    1314           3 :                 att = ENR_ATT[st->CNG_mode];
    1315             :             }
    1316             :             else
    1317             :             {
    1318             :                 /* Use least attenuation for higher bitrates */
    1319       13047 :                 att = ENR_ATT[4];
    1320             :             }
    1321             :         }
    1322             :         else
    1323             :         {
    1324       45423 :             att = 1.5f;
    1325             :         }
    1326             : 
    1327       58473 :         enr -= att;
    1328             :     }
    1329             : 
    1330       58473 :     st->lp_ener = (float) ( 0.8f * st->lp_ener + 0.2f * pow( 2.0f, enr ) );
    1331             : 
    1332             :     /* Generate Gaussian random noise in real and imaginary parts of the CLDFB bands
    1333             :       Amplitudes are adjusted to the estimated noise level cngNoiseLevel in each band */
    1334             : 
    1335             : #ifdef NONBE_MDCT_ST_DTX_FIX_SUBOPT_SPATIAL_CNG
    1336             :     /*
    1337             :      * Note: for the stereo DTX noise mixing, c1 and c2 at this point are set to the value calculated for the last band
    1338             :      *       as all the coherence bands are in the FFT region, we do not need the special handling here
    1339             :      */
    1340             : #endif
    1341             : 
    1342       58473 :     if ( bufferReal != NULL && hFdCngCom->numCoreBands < hFdCngCom->regularStopBand )
    1343             :     {
    1344           0 :         for ( j = hFdCngCom->numCoreBands; j < hFdCngCom->regularStopBand; j++ )
    1345             :         {
    1346           0 :             for ( i = 0; i < hFdCngCom->numSlots; i++ )
    1347             :             {
    1348             :                 /* Real part in CLDFB band */
    1349             : #ifdef NONBE_MDCT_ST_DTX_FIX_SUBOPT_SPATIAL_CNG
    1350           0 :                 if ( ( st->element_mode == IVAS_CPE_MDCT && nchan_out != 1 ) || ( st->element_mode == IVAS_SCE && st->cng_ism_flag ) )
    1351             : #else
    1352             :                 if ( st->element_mode == IVAS_CPE_MDCT || ( st->element_mode == IVAS_SCE && st->cng_ism_flag ) )
    1353             : #endif
    1354             :                 {
    1355           0 :                     rand_gauss( &tmp1, seed );
    1356           0 :                     rand_gauss( &tmp2, seed2 );
    1357           0 :                     bufferReal[i][j] = tmp1 * c1 + tmp2 * c2;
    1358             :                 }
    1359             :                 else
    1360             :                 {
    1361           0 :                     rand_gauss( &bufferReal[i][j], seed );
    1362             :                 }
    1363           0 :                 bufferReal[i][j] *= (float) sqrt( ( scaleCldfb * *ptr_level ) * 0.5f );
    1364             : 
    1365             :                 /* Imaginary part in CLDFB band */
    1366             : #ifdef NONBE_MDCT_ST_DTX_FIX_SUBOPT_SPATIAL_CNG
    1367           0 :                 if ( ( st->element_mode == IVAS_CPE_MDCT && nchan_out != 1 ) || ( st->element_mode == IVAS_SCE && st->cng_ism_flag ) )
    1368             : #else
    1369             :                 if ( st->element_mode == IVAS_CPE_MDCT || ( st->element_mode == IVAS_SCE && st->cng_ism_flag ) )
    1370             : #endif
    1371             :                 {
    1372           0 :                     rand_gauss( &tmp1, seed );
    1373           0 :                     rand_gauss( &tmp2, seed2 );
    1374           0 :                     bufferImag[i][j] = tmp1 * c1 + tmp2 * c2;
    1375             :                 }
    1376             :                 else
    1377             :                 {
    1378           0 :                     rand_gauss( &bufferImag[i][j], seed );
    1379             :                 }
    1380           0 :                 bufferImag[i][j] *= (float) sqrt( ( scaleCldfb * *ptr_level ) * 0.5f );
    1381             :             }
    1382           0 :             ptr_level++;
    1383             :         }
    1384             :     }
    1385             : 
    1386             :     /* Overlap-add when previous frame is active */
    1387       58473 :     if ( hFdCngCom->frame_type_previous == ACTIVE_FRAME && st->codec_mode == MODE2 )
    1388             :     {
    1389           0 :         float noise[2048], old_exc_ener = 0.f, gain = 0.f, tmp;
    1390           0 :         int16_t N = hFdCngCom->frameSize;
    1391           0 :         int16_t seed_loc = hFdCngCom->seed;
    1392             :         float *old_exc, old_Aq[M + 1], *old_syn_pe, old_syn;
    1393             : 
    1394           0 :         if ( st->core > ACELP_CORE )
    1395             :         {
    1396           0 :             tcx_windowing_synthesis_current_frame( timeDomainOutput, st->hTcxCfg->tcx_mdct_window, /*Keep sine windows for limiting Time modulation*/
    1397           0 :                                                    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, st->hTcxCfg->tcx_mdct_window_min_length, 0, st->hTcxCfg->tcx_last_overlap_mode == ALDO_WINDOW ? FULL_OVERLAP : st->hTcxCfg->tcx_last_overlap_mode, NULL, NULL, NULL, NULL, NULL, N / 2, st->hTcxCfg->tcx_offset < 0 ? -st->hTcxCfg->tcx_offset : 0, 1, 0, 0 );
    1398             : 
    1399           0 :             if ( st->hTcxCfg->last_aldo )
    1400             :             {
    1401           0 :                 for ( i = 0; i < ( hFdCngCom->frameSize - NS2SA( st->sr_core, N_ZERO_MDCT_NS ) ); i++ )
    1402             :                 {
    1403           0 :                     timeDomainOutput[i] += st->hHQ_core->old_outLB[i + NS2SA( st->sr_core, N_ZERO_MDCT_NS )];
    1404             :                 }
    1405             :             }
    1406             :             else
    1407             :             {
    1408           0 :                 tcx_windowing_synthesis_past_frame( st->hTcxDec->syn_Overl, 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, st->hTcxCfg->tcx_mdct_window_min_length, st->hTcxCfg->tcx_last_overlap_mode );
    1409             : 
    1410           0 :                 for ( i = 0; i < st->hTcxCfg->tcx_mdct_window_length; i++ )
    1411             :                 {
    1412           0 :                     timeDomainOutput[i] += st->hTcxDec->syn_Overl[i];
    1413             :                 }
    1414             :             }
    1415             :         }
    1416             :         else
    1417             :         {
    1418           0 :             mvr2r( st->old_Aq_12_8, old_Aq, M + 1 );
    1419           0 :             old_exc = st->old_exc + L_EXC_MEM_DEC - ( N / 2 );
    1420           0 :             old_syn_pe = st->mem_syn2;
    1421           0 :             old_syn = st->syn[M];
    1422             : 
    1423           0 :             for ( i = 0; i < N / 2; i++ )
    1424             :             {
    1425           0 :                 old_exc_ener += old_exc[i] * old_exc[i];
    1426             :             }
    1427             : 
    1428           0 :             old_exc_ener = (float) sqrt( old_exc_ener / (float) ( N / 2 ) );
    1429             : 
    1430           0 :             for ( i = 0; i < N; i++ )
    1431             :             {
    1432           0 :                 rand_gauss( &( noise[i] ), &( seed_loc ) );
    1433           0 :                 gain += noise[i] * noise[i];
    1434             :             }
    1435             : 
    1436           0 :             gain = old_exc_ener / (float) sqrt( gain / (float) N );
    1437             : 
    1438           0 :             for ( i = 0; i < N; i++ )
    1439             :             {
    1440           0 :                 noise[i] *= gain;
    1441             :             }
    1442             : 
    1443           0 :             syn_filt( old_Aq, M, noise, noise, N, old_syn_pe, 0 );
    1444             : 
    1445           0 :             tmp = old_syn;
    1446             : 
    1447           0 :             deemph( noise, st->preemph_fac, N, &tmp );
    1448             : 
    1449           0 :             for ( i = 0; i < N / 2; i++ )
    1450             :             {
    1451           0 :                 timeDomainOutput[i] += noise[i] * hFdCngCom->olapWinSyn[N / 2 + i];
    1452             :             }
    1453             :         }
    1454             :     }
    1455             : 
    1456       58473 :     return;
    1457             : }
    1458             : 
    1459             : 
    1460             : /*-------------------------------------------------------------------
    1461             :  * generate_comfort_noise_dec_hf()
    1462             :  *
    1463             :  * Generate the comfort noise based on the target noise level for the CLDFB part
    1464             :  *-------------------------------------------------------------------*/
    1465             : 
    1466       48555 : void generate_comfort_noise_dec_hf(
    1467             :     float **bufferReal,          /* o  : Real part of input bands                               */
    1468             :     float **bufferImag,          /* o  : Imaginary part of input bands                          */
    1469             :     HANDLE_FD_CNG_COM hFdCngCom, /* i/o: FD_CNG structure containing all buffers and variables  */
    1470             :     const int16_t cng_coh_flag   /* i  : CNG Flag for coherence handling                        */
    1471             : )
    1472             : {
    1473             :     int16_t i, j;
    1474             :     float *ptr_level;
    1475             : 
    1476       48555 :     int16_t *seed = &( hFdCngCom->seed );
    1477       48555 :     float scale = CLDFB_SCALING / hFdCngCom->scalingFactor;
    1478             : 
    1479       48555 :     int16_t *seed2 = &( hFdCngCom->seed );
    1480             : 
    1481       48555 :     float tmp1, tmp2, c1 = 0.f, c2 = 0.f;
    1482             : 
    1483       48555 :     if ( cng_coh_flag )
    1484             :     {
    1485       17762 :         seed2 = &( hFdCngCom->seed2 );
    1486             : 
    1487             : #ifdef NONBE_MDCT_ST_DTX_FIX_SUBOPT_SPATIAL_CNG
    1488             :         /* alwas use the value for the last band - frequency-wise we are here always above */
    1489       17762 :         c1 = (float) sqrt( hFdCngCom->coherence[MDCT_ST_DTX_NUM_COHERENCE_BANDS - 1] );
    1490       17762 :         c2 = (float) sqrt( 1 - hFdCngCom->coherence[MDCT_ST_DTX_NUM_COHERENCE_BANDS - 1] );
    1491             : #else
    1492             :         c1 = (float) sqrt( hFdCngCom->coherence );
    1493             :         c2 = (float) sqrt( 1 - hFdCngCom->coherence );
    1494             : #endif
    1495             :     }
    1496             : 
    1497       48555 :     ptr_level = hFdCngCom->cngNoiseLevel + hFdCngCom->stopFFTbin - hFdCngCom->startBand;
    1498             :     /*
    1499             :       Generate Gaussian random noise in real and imaginary parts of the CLDFB bands
    1500             :       Amplitudes are adjusted to the estimated noise level cngNoiseLevel in each band
    1501             :     */
    1502       48555 :     if ( hFdCngCom->numCoreBands < hFdCngCom->regularStopBand )
    1503             :     {
    1504      863471 :         for ( j = hFdCngCom->numCoreBands; j < hFdCngCom->regularStopBand; j++ )
    1505             :         {
    1506    13946086 :             for ( i = 0; i < hFdCngCom->numSlots; i++ )
    1507             :             {
    1508    13125728 :                 if ( cng_coh_flag )
    1509             :                 {
    1510             :                     /* Real part in CLDFB band */
    1511     5208528 :                     rand_gauss( &tmp1, seed );
    1512     5208528 :                     rand_gauss( &tmp2, seed2 );
    1513     5208528 :                     bufferReal[i][j] = tmp1 * c1 + tmp2 * c2;
    1514     5208528 :                     bufferReal[i][j] *= (float) sqrt( ( scale * *ptr_level ) * 0.5f );
    1515             : 
    1516             :                     /* Imaginary part in CLDFB band */
    1517     5208528 :                     rand_gauss( &tmp1, seed );
    1518     5208528 :                     rand_gauss( &tmp2, seed2 );
    1519     5208528 :                     bufferImag[i][j] = tmp1 * c1 + tmp2 * c2;
    1520     5208528 :                     bufferImag[i][j] *= (float) sqrt( ( scale * *ptr_level ) * 0.5f );
    1521             :                 }
    1522             :                 else
    1523             :                 {
    1524             :                     /* Real part in CLDFB band */
    1525     7917200 :                     rand_gauss( &bufferReal[i][j], seed );
    1526     7917200 :                     bufferReal[i][j] *= (float) sqrt( ( scale * *ptr_level ) * 0.5f );
    1527             :                     /* Imaginary part in CLDFB band */
    1528     7917200 :                     rand_gauss( &bufferImag[i][j], seed );
    1529     7917200 :                     bufferImag[i][j] *= (float) sqrt( ( scale * *ptr_level ) * 0.5f );
    1530             :                 }
    1531             :             }
    1532      820358 :             ptr_level++;
    1533             :         }
    1534             :     }
    1535             : 
    1536       48555 :     return;
    1537             : }
    1538             : 
    1539             : 
    1540             : /*-------------------------------------------------------------------
    1541             :  * generate_masking_noise()
    1542             :  *
    1543             :  * Generate additional comfort noise (kind of noise filling)
    1544             :  *-------------------------------------------------------------------*/
    1545             : 
    1546      760704 : void generate_masking_noise(
    1547             :     float *timeDomainBuffer,          /* i/o: time-domain signal */
    1548             :     HANDLE_FD_CNG_COM hFdCngCom,      /* i/o: FD_CNG structure containing all buffers and variables */
    1549             :     const int16_t length,             /* i  : frame size                                       */
    1550             :     const int16_t core,               /* i  : core                                             */
    1551             :     const int16_t return_noise,       /* i  : noise is returned instead of added */
    1552             :     const int16_t secondary,          /* i  : flag to indicate secondary noise generation */
    1553             :     const int16_t element_mode,       /* i  : element mode */
    1554             :     STEREO_CNG_DEC_HANDLE hStereoCng, /* i  : stereo CNG handle */
    1555             :     const int16_t nchan_out           /* i  : number of output channels */
    1556             : )
    1557             : {
    1558      760704 :     float *cngNoiseLevel = hFdCngCom->cngNoiseLevel;
    1559      760704 :     float *ptr_level = cngNoiseLevel;
    1560      760704 :     float *fftBuffer = hFdCngCom->fftBuffer;
    1561             :     int16_t i;
    1562             :     float maskingNoise[L_FRAME16k];
    1563             :     float *ptr_r;
    1564             :     float *ptr_i;
    1565      760704 :     int16_t startBand = hFdCngCom->startBand;
    1566      760704 :     int16_t *seed = &( hFdCngCom->seed );
    1567      760704 :     float scale = 1.f;
    1568             : 
    1569             :     /* skip noise generating if level is very low, to avoid problems with possibly running into denormals */
    1570      760704 :     if ( hFdCngCom->likelihood_noisy_speech > DELTA_MASKING_NOISE )
    1571             :     {
    1572       16658 :         if ( core != AMR_WB_CORE )
    1573             :         {
    1574             :             /* Compute additional CN level */
    1575      227822 :             for ( i = 0; i < SIZE_SCALE_TABLE_CN; i++ )
    1576             :             {
    1577      227822 :                 if ( ( hFdCngCom->CngBandwidth == scaleTable_cn_only[i].bwmode ) &&
    1578       65464 :                      ( hFdCngCom->CngBitrate >= scaleTable_cn_only[i].bitrateFrom ) &&
    1579       65464 :                      ( hFdCngCom->CngBitrate < scaleTable_cn_only[i].bitrateTo ) )
    1580             :                 {
    1581       16658 :                     break;
    1582             :                 }
    1583             :             }
    1584             : 
    1585       16658 :             scale *= (float) pow( 10.f, -scaleTable_cn_only[i].scale / 10.f ) - 1.f;
    1586             :         }
    1587             :         else
    1588             :         {
    1589             :             /* Compute additional CN level */
    1590           0 :             for ( i = 0; i < SIZE_SCALE_TABLE_CN_AMRWB; i++ )
    1591             :             {
    1592           0 :                 if ( hFdCngCom->CngBitrate >= scaleTable_cn_only_amrwbio[i][0] )
    1593             :                 {
    1594           0 :                     break;
    1595             :                 }
    1596             :             }
    1597             : 
    1598           0 :             if ( i < SIZE_SCALE_TABLE_CN_AMRWB )
    1599             :             {
    1600           0 :                 scale *= (float) pow( 10.f, -scaleTable_cn_only_amrwbio[i][1] / 10.f ) - 1.f;
    1601             :             }
    1602             :             else
    1603             :             {
    1604           0 :                 scale = 0.f;
    1605             :             }
    1606             :         }
    1607             : 
    1608             :         /* Exclude clean speech */
    1609       16658 :         scale *= hFdCngCom->likelihood_noisy_speech;
    1610             : 
    1611             :         /* Generate Gaussian random noise in real and imaginary parts of the FFT bins
    1612             :           Amplitudes are adjusted to the estimated noise level cngNoiseLevel in each bin */
    1613       16658 :         if ( startBand == 0 )
    1614             :         {
    1615           0 :             rand_gauss( &fftBuffer[0], seed );
    1616           0 :             ptr_r = fftBuffer + 2;
    1617           0 :             fftBuffer[0] *= (float) sqrt( scale * *ptr_level ); /* DC component in FFT */
    1618           0 :             ptr_level++;
    1619             :         }
    1620             :         else
    1621             :         {
    1622       16658 :             fftBuffer[0] = 0.f;
    1623       16658 :             set_f( fftBuffer + 2, 0.0f, 2 * ( startBand - 1 ) );
    1624       16658 :             ptr_r = fftBuffer + 2 * startBand;
    1625             :         }
    1626       16658 :         ptr_i = ptr_r + 1;
    1627     4742766 :         for ( ; ptr_level < cngNoiseLevel + hFdCngCom->stopFFTbin - startBand; ptr_level++ )
    1628             :         {
    1629             :             /* Real part in FFT bins */
    1630     4726108 :             rand_gauss( ptr_r, seed );
    1631     4726108 :             ( *ptr_r ) *= (float) sqrt( ( scale * *ptr_level ) * 0.5f );
    1632     4726108 :             ptr_r += 2;
    1633             :             /* Imaginary part in FFT bins */
    1634     4726108 :             rand_gauss( ptr_i, seed );
    1635     4726108 :             ( *ptr_i ) *= (float) sqrt( ( scale * *ptr_level ) * 0.5f );
    1636     4726108 :             ptr_i += 2;
    1637             :         }
    1638             : 
    1639             :         /* Remaining FFT bins are set to zero */
    1640       16658 :         set_f( fftBuffer + 2 * hFdCngCom->stopFFTbin, 0.0f, hFdCngCom->fftlen - 2 * hFdCngCom->stopFFTbin );
    1641             :         /* Nyquist frequency is discarded */
    1642       16658 :         fftBuffer[1] = 0.f;
    1643             :     }
    1644             :     else
    1645             :     {
    1646             :         /* very low level case - update random seeds and reset FFT buffer; don't fully skip SynthesisSTFT(), because of the buffer updates done there... */
    1647      744046 :         generate_masking_noise_update_seed( hFdCngCom );
    1648             : 
    1649      744046 :         set_f( fftBuffer, 0.f, hFdCngCom->fftlen );
    1650             :     }
    1651             : 
    1652             :     /* Perform STFT synthesis */
    1653      760704 :     if ( secondary )
    1654             :     {
    1655        1374 :         SynthesisSTFT( fftBuffer, maskingNoise, hStereoCng->olapBufferSynth22, hFdCngCom->olapWinSyn, 0, hFdCngCom, element_mode, nchan_out );
    1656             :     }
    1657             :     else
    1658             :     {
    1659      759330 :         SynthesisSTFT( fftBuffer, maskingNoise, hFdCngCom->olapBufferSynth2, hFdCngCom->olapWinSyn, 0, hFdCngCom, element_mode, nchan_out );
    1660             :     }
    1661             : 
    1662             :     /* Add some comfort noise on top of decoded signal */
    1663      760704 :     if ( return_noise )
    1664             :     {
    1665        2748 :         mvr2r( maskingNoise, timeDomainBuffer, min( hFdCngCom->frameSize, length ) );
    1666             :     }
    1667             :     else
    1668             :     {
    1669      757956 :         v_add( maskingNoise, timeDomainBuffer, timeDomainBuffer, min( hFdCngCom->frameSize, length ) );
    1670             :     }
    1671             : 
    1672      760704 :     return;
    1673             : }
    1674             : 
    1675             : 
    1676             : /*-------------------------------------------------------------------
    1677             :  * generate_masking_noise_update_seed()
    1678             :  *
    1679             :  * Update seed for scenarios where generate_masking_noise() is
    1680             :  * not called based on signal statistics
    1681             :  *-------------------------------------------------------------------*/
    1682             : 
    1683      820178 : void generate_masking_noise_update_seed(
    1684             :     HANDLE_FD_CNG_COM hFdCngCom /* i/o: FD_CNG structure containing all buffers and variables */
    1685             : )
    1686             : {
    1687      820178 :     float *cngNoiseLevel = hFdCngCom->cngNoiseLevel;
    1688      820178 :     float *ptr_level = cngNoiseLevel;
    1689      820178 :     int16_t startBand = hFdCngCom->startBand;
    1690      820178 :     int16_t *seed = &( hFdCngCom->seed );
    1691      820178 :     float tmp = 0;
    1692             : 
    1693             :     /*
    1694             :       Generate Gaussian random noise in real and imaginary parts of the FFT bins
    1695             :       Amplitudes are adjusted to the estimated noise level cngNoiseLevel in each bin
    1696             :     */
    1697      820178 :     if ( startBand == 0 )
    1698             :     {
    1699           0 :         rand_gauss( &tmp, seed );
    1700           0 :         ptr_level++;
    1701             :     }
    1702             : 
    1703   221702510 :     for ( ; ptr_level < cngNoiseLevel + hFdCngCom->stopFFTbin - startBand; ptr_level++ )
    1704             :     {
    1705             :         /* Real part in FFT bins */
    1706   220882332 :         rand_gauss( &tmp, seed );
    1707   220882332 :         rand_gauss( &tmp, seed );
    1708             :     }
    1709             : 
    1710      820178 :     return;
    1711             : }
    1712             : 
    1713             : 
    1714             : /*-------------------------------------------------------------------
    1715             :  * generate_masking_noise_mdct()
    1716             :  *
    1717             :  * Generate additional comfort noise (kind of noise filling)
    1718             :  *-------------------------------------------------------------------*/
    1719             : 
    1720      197778 : void generate_masking_noise_mdct(
    1721             :     float *mdctBuffer,          /* i/o: time-domain signal */
    1722             :     HANDLE_FD_CNG_COM hFdCngCom /* i/o: FD_CNG structure containing all buffers and variables */
    1723             : )
    1724             : {
    1725      197778 :     float *cngNoiseLevel = hFdCngCom->cngNoiseLevel;
    1726             :     int16_t i;
    1727             :     float maskingNoise[2 * L_FRAME16k];
    1728             :     float *ptr_r;
    1729      197778 :     float *ptr_level = cngNoiseLevel;
    1730      197778 :     int16_t startBand = hFdCngCom->startBand;
    1731      197778 :     int16_t *seed = &( hFdCngCom->seed );
    1732      197778 :     float scale = 1.f;
    1733             : 
    1734             :     /* skip noise generating if level is very low, to avoid problems with possibly running into denormals */
    1735      197778 :     if ( hFdCngCom->likelihood_noisy_speech > DELTA_MASKING_NOISE )
    1736             :     {
    1737       59708 :         for ( i = 0; i < SIZE_SCALE_TABLE_CN; i++ )
    1738             :         {
    1739       59708 :             if ( ( hFdCngCom->CngBandwidth == scaleTable_cn_only[i].bwmode ) &&
    1740       18061 :                  ( hFdCngCom->CngBitrate >= scaleTable_cn_only[i].bitrateFrom ) &&
    1741       18061 :                  ( hFdCngCom->CngBitrate < scaleTable_cn_only[i].bitrateTo ) )
    1742             :             {
    1743        4295 :                 break;
    1744             :             }
    1745             :         }
    1746             : 
    1747        4295 :         scale *= (float) pow( 10.f, -scaleTable_cn_only[i].scale / 10.f ) - 1.f;
    1748             : 
    1749             :         /* Exclude clean speech */
    1750        4295 :         scale *= hFdCngCom->likelihood_noisy_speech;
    1751             : 
    1752             :         /*
    1753             :           Generate Gaussian random noise in real and imaginary parts of the FFT bins
    1754             :           Amplitudes are adjusted to the estimated noise level cngNoiseLevel in each bin
    1755             :         */
    1756        4295 :         if ( startBand == 0 )
    1757             :         {
    1758           0 :             rand_gauss( &maskingNoise[0], seed );
    1759           0 :             maskingNoise[0] *= (float) sqrt( scale * *ptr_level * 0.5f ); /* DC component in FFT */
    1760           0 :             ptr_level++;
    1761           0 :             ptr_r = maskingNoise + 1;
    1762             :         }
    1763             :         else
    1764             :         {
    1765        4295 :             maskingNoise[0] = 0.f;
    1766        4295 :             set_f( maskingNoise + 1, 0.0f, ( startBand - 1 ) );
    1767        4295 :             ptr_r = maskingNoise + startBand;
    1768             :         }
    1769             : 
    1770     1234809 :         for ( ; ptr_level < cngNoiseLevel + hFdCngCom->stopFFTbin - startBand; ptr_level++ )
    1771             :         {
    1772             :             /* MDCT bins */
    1773     1230514 :             rand_gauss( ptr_r, seed );
    1774     1230514 :             ( *ptr_r ) *= (float) sqrt( scale * *ptr_level * 0.5f );
    1775     1230514 :             ptr_r += 1;
    1776             :         }
    1777             : 
    1778             :         /*re-normalization of energy level: M/sqrt(2)*/
    1779        4295 :         v_multc( maskingNoise, (float) sqrt( NORM_MDCT_FACTOR ), maskingNoise, hFdCngCom->stopFFTbin );
    1780             : 
    1781             :         /* Add some comfort noise on top of decoded signal */
    1782        4295 :         v_add( maskingNoise, mdctBuffer, mdctBuffer, hFdCngCom->stopFFTbin );
    1783             :     }
    1784             :     else
    1785             :     {
    1786             :         /* very low level case - just update random seeds */
    1787      193483 :         if ( startBand == 0 )
    1788             :         {
    1789           0 :             rand_gauss( &maskingNoise[0], seed );
    1790           0 :             ptr_level++;
    1791             :         }
    1792             : 
    1793    51690165 :         for ( ; ptr_level < cngNoiseLevel + hFdCngCom->stopFFTbin - startBand; ptr_level++ )
    1794             :         {
    1795    51496682 :             rand_gauss( &maskingNoise[0], seed );
    1796             :         }
    1797             :     }
    1798             : 
    1799      197778 :     return;
    1800             : }
    1801             : 
    1802             : /*-------------------------------------------------------------------
    1803             :  * generate_stereo_masking_noise()
    1804             :  *
    1805             :  * Generate additional comfort noise (kind of noise filling)
    1806             :  *-------------------------------------------------------------------*/
    1807             : 
    1808        2784 : void generate_stereo_masking_noise(
    1809             :     float *syn,                          /* i/o: time-domain signal              */
    1810             :     Decoder_State *st,                   /* i/o: decoder state structure         */
    1811             :     STEREO_TD_DEC_DATA_HANDLE hStereoTD, /* i  : TD stereo structure             */
    1812             :     const int16_t flag_sec_CNA,          /* i  : CNA flag for secondary channel  */
    1813             :     const int16_t fadeOut,               /* i  : only fade out of previous state */
    1814             :     STEREO_CNG_DEC_HANDLE hStereoCng,    /* i  : Stereo CNG handle               */
    1815             :     const int16_t nchan_out              /* i  : number of output channels       */
    1816             : )
    1817             : {
    1818             :     HANDLE_FD_CNG_COM hFdCngCom;
    1819             :     float gamma, scale, SP_ratio;
    1820             :     float Np[L_FRAME16k];
    1821             :     float Ns[L_FRAME16k];
    1822             :     float N1[L_FRAME16k];
    1823             :     float N2[L_FRAME16k];
    1824             :     int16_t i;
    1825             : 
    1826        2784 :     if ( st->idchan == 0 )
    1827             :     {
    1828        1374 :         hFdCngCom = st->hFdCngDec->hFdCngCom;
    1829        1374 :         mvr2r( hFdCngCom->olapBufferSynth2, Np, hFdCngCom->frameSize / 2 );
    1830        1374 :         mvr2r( hStereoCng->olapBufferSynth22, Ns, hFdCngCom->frameSize / 2 );
    1831        1374 :         set_f( &Np[hFdCngCom->frameSize / 2], 0.0f, hFdCngCom->frameSize / 2 );
    1832        1374 :         set_f( &Ns[hFdCngCom->frameSize / 2], 0.0f, hFdCngCom->frameSize / 2 );
    1833             : 
    1834        1374 :         if ( !fadeOut )
    1835             :         {
    1836        1374 :             generate_masking_noise( N1, hFdCngCom, hFdCngCom->frameSize, 0, 1, 0, st->element_mode, hStereoCng, nchan_out );
    1837             :             /* Generate masking noise for secondary channel */
    1838        1374 :             if ( flag_sec_CNA )
    1839             :             {
    1840        1374 :                 generate_masking_noise( N2, hFdCngCom, hFdCngCom->frameSize, 0, 1, 1, st->element_mode, hStereoCng, nchan_out );
    1841        1374 :                 gamma = hStereoCng->c_PS_LT * hStereoCng->c_PS_LT;
    1842        1374 :                 scale = 1.0f;
    1843        1374 :                 if ( gamma < 0.9f )
    1844             :                 {
    1845        1374 :                     gamma = gamma / ( 1 - gamma );
    1846        1374 :                     gamma = (float) sqrt( gamma + 1 ) - (float) sqrt( gamma );
    1847        1374 :                     scale = 1.0f / (float) sqrt( 1 + gamma * gamma );
    1848             :                 }
    1849             :                 else
    1850             :                 {
    1851           0 :                     gamma = 0.0f;
    1852             :                 }
    1853             : 
    1854      177246 :                 for ( i = 0; i < 2 * hFdCngCom->frameSize / 4; i++ )
    1855             :                 {
    1856      175872 :                     Np[i] += scale * ( N1[i] + gamma * N2[i] );
    1857      175872 :                     Ns[i] += scale * sign( hStereoCng->c_PS_LT ) * ( N1[i] - gamma * N2[i] );
    1858             :                 }
    1859      177246 :                 for ( ; i < hFdCngCom->frameSize; i++ )
    1860             :                 {
    1861      175872 :                     Np[i] = scale * ( N1[i] + gamma * N2[i] );
    1862      175872 :                     Ns[i] = scale * sign( hStereoCng->c_PS_LT ) * ( N1[i] - gamma * N2[i] );
    1863             :                 }
    1864        1374 :                 scale *= (float) ( hFdCngCom->fftlen / 2 );
    1865      177246 :                 for ( i = 0; i < hFdCngCom->frameSize / 2; i++ )
    1866             :                 {
    1867      175872 :                     hFdCngCom->olapBufferSynth2[i] = scale * ( hFdCngCom->olapBufferSynth2[i + 5 * hFdCngCom->frameSize / 4] + gamma * hStereoCng->olapBufferSynth22[i + 5 * hFdCngCom->frameSize / 4] );
    1868      175872 :                     hStereoCng->olapBufferSynth22[i] = sign( hStereoCng->c_PS_LT ) * scale * ( hFdCngCom->olapBufferSynth2[i + 5 * hFdCngCom->frameSize / 4] - gamma * hStereoCng->olapBufferSynth22[i + 5 * hFdCngCom->frameSize / 4] );
    1869             :                 }
    1870             :             }
    1871             :             else
    1872             :             {
    1873           0 :                 for ( i = 0; i < hFdCngCom->frameSize / 2; i++ )
    1874             :                 {
    1875           0 :                     Np[i] += N1[i];
    1876             :                 }
    1877           0 :                 mvr2r( &N1[hFdCngCom->frameSize / 2], &Np[hFdCngCom->frameSize / 2], hFdCngCom->frameSize / 2 );
    1878           0 :                 scale = (float) ( hFdCngCom->fftlen / 2 );
    1879           0 :                 for ( i = 0; i < hFdCngCom->frameSize; i++ )
    1880             :                 {
    1881           0 :                     hFdCngCom->olapBufferSynth2[i] = scale * hFdCngCom->olapBufferSynth2[i + 5 * hFdCngCom->frameSize / 4];
    1882             :                 }
    1883             :             }
    1884             :         }
    1885             :         else
    1886             :         {
    1887           0 :             set_f( hFdCngCom->olapBufferSynth2, 0.0f, hFdCngCom->frameSize / 2 );
    1888           0 :             set_f( hStereoCng->olapBufferSynth22, 0.0f, hFdCngCom->frameSize / 2 );
    1889             :         }
    1890        1374 :         if ( flag_sec_CNA )
    1891             :         {
    1892        1374 :             mvr2r( Ns, hStereoCng->maskingNoiseS, hFdCngCom->frameSize );
    1893        1374 :             hStereoCng->enableSecCNA = 1;
    1894             :         }
    1895             :         else
    1896             :         {
    1897           0 :             set_f( hStereoCng->olapBufferSynth22, 0.0f, hFdCngCom->frameSize );
    1898             :         }
    1899             : 
    1900             :         /* add masking noise */
    1901        1374 :         v_add( Np, syn, syn, hFdCngCom->frameSize );
    1902             :     }
    1903        1410 :     else if ( hStereoCng->enableSecCNA )
    1904             :     {
    1905        1374 :         SP_ratio = hStereoTD->SP_ratio_LT; /* Use long-term SP ratio based on L/R synthesis */
    1906             :         /* scale and add masking noise */
    1907       89310 :         for ( i = 0; i < *hStereoCng->frameSize / 4; i++ )
    1908             :         {
    1909       87936 :             scale = ( ( hStereoTD->prevSP_ratio * ( *hStereoCng->frameSize / 4 - (float) i ) + SP_ratio * (float) i ) / ( *hStereoCng->frameSize / 4 ) );
    1910       87936 :             syn[i] += scale * hStereoCng->maskingNoiseS[i];
    1911             :         }
    1912       89310 :         for ( ; i < *hStereoCng->frameSize / 2; i++ )
    1913             :         {
    1914       87936 :             syn[i] += SP_ratio * hStereoCng->maskingNoiseS[i];
    1915             :         }
    1916      177246 :         for ( ; i < *hStereoCng->frameSize; i++ )
    1917             :         {
    1918      175872 :             syn[i] += SP_ratio * hStereoCng->maskingNoiseS[i];
    1919             :         }
    1920        1374 :         hStereoTD->prevSP_ratio = SP_ratio;
    1921             :     }
    1922             : 
    1923        2784 :     return;
    1924             : }
    1925             : 
    1926             : 
    1927             : /*-------------------------------------------------------------------
    1928             :  * generate_masking_noise_hf_cldfb()
    1929             :  *
    1930             :  * Generate additional comfort noise (kind of noise filling)
    1931             :  *-------------------------------------------------------------------*/
    1932             : 
    1933      302259 : void generate_masking_noise_lb_dirac(
    1934             :     HANDLE_FD_CNG_COM hFdCngCom,                          /* i/o: FD_CNG structure containing all buffers and variables */
    1935             :     float *tdBuffer,                                      /* i/o: time-domain signal, if NULL no LB-CNA                 */
    1936             :     const int16_t nCldfbTs,                               /* i  : number of CLDFB slots that will be rendered           */
    1937             :     SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, /* i  : common spatial rendering parameters handle            */
    1938             :     const int16_t cna_flag                                /* i  : CNA flag for LB and HB                                */
    1939             : )
    1940             : {
    1941             :     int16_t i;
    1942      302259 :     float *cngNoiseLevel = hFdCngCom->cngNoiseLevel;
    1943      302259 :     float *fftBuffer = hFdCngCom->fftBuffer;
    1944             :     float *ptr_r;
    1945             :     float *ptr_i;
    1946             :     float *ptr_level;
    1947      302259 :     int16_t *seed = &( hFdCngCom->seed );
    1948             :     float scale;
    1949             :     int16_t n_samples_out, n_samples_start, n_samples_out_loop;
    1950             : 
    1951      302259 :     push_wmops( "fd_cng_dirac" );
    1952             : 
    1953             :     /* Init */
    1954      302259 :     scale = 0.f;
    1955      302259 :     n_samples_out = hFdCngCom->frameSize / DEFAULT_JBM_CLDFB_TIMESLOTS * nCldfbTs;
    1956      302259 :     n_samples_start = 0;
    1957             : 
    1958             :     /*LB CLDFB - CNA from STFT*/
    1959             : #ifdef DEBUG_MODE_DIRAC
    1960             :     {
    1961             :         int16_t tmp_s;
    1962             :         tmp_s = (int16_t) ( 32768.f * 0.5f * hFdCngCom->likelihood_noisy_speech * cna_flag + 0.5f );
    1963             :         dbgwrite( &tmp_s, sizeof( int16_t ), 1, hFdCngCom->frameSize / 16, "./res/ivas_dirac_likelihood_noisy.pcm" );
    1964             :     }
    1965             : #endif
    1966      302259 :     if ( cna_flag )
    1967             :     {
    1968             :         /* skip noise generating if level is very low, to avoid problems with possibly running into denormals */
    1969       80900 :         if ( hFdCngCom->likelihood_noisy_speech > DELTA_MASKING_NOISE )
    1970             :         {
    1971             :             /* Compute additional CN level */
    1972       72189 :             for ( i = 0; i < 15; i++ )
    1973             :             {
    1974       72189 :                 if ( ( hFdCngCom->CngBandwidth == scaleTable_cn_dirac[i].bwmode ) &&
    1975       15069 :                      ( hFdCngCom->CngBitrate >= scaleTable_cn_dirac[i].bitrateFrom ) &&
    1976       15069 :                      ( hFdCngCom->CngBitrate < scaleTable_cn_dirac[i].bitrateTo ) )
    1977             :                 {
    1978        5712 :                     break;
    1979             :                 }
    1980             :             }
    1981             : 
    1982        5712 :             scale = (float) pow( 10.f, -scaleTable_cn_dirac[i].scale / 10.f ) - 1.f;
    1983        5712 :             scale *= hFdCngCom->likelihood_noisy_speech;
    1984             :         }
    1985             :     }
    1986             : 
    1987             :     /* LB CLDFB - CNA from STFT: CNA applied only in channel 0*/
    1988      302259 :     if ( cna_flag && tdBuffer != NULL )
    1989             :     {
    1990             :         int16_t cur_subframe;
    1991             :         int16_t cur_subframe_start_outfs;
    1992             :         int16_t cur_subframe_start_cngfs;
    1993             :         int16_t slot_size_cng;
    1994             : 
    1995      161800 :         while ( n_samples_out > 0 )
    1996             :         {
    1997       80900 :             n_samples_out_loop = min( hFdCngCom->frameSize, n_samples_out );
    1998       80900 :             if ( scale != 0 )
    1999             :             {
    2000             :                 /*Generate LF comfort noise only at first slot, for the whole frame*/
    2001        5712 :                 ptr_level = cngNoiseLevel;
    2002             : 
    2003             :                 /* Generate Gaussian random noise in real and imaginary parts of the FFT bins
    2004             :               Amplitudes are adjusted to the estimated noise level cngNoiseLevel in each bin */
    2005        5712 :                 if ( hFdCngCom->startBand == 0 )
    2006             :                 {
    2007           0 :                     rand_gauss( &fftBuffer[0], seed );
    2008           0 :                     ptr_r = fftBuffer + 2;
    2009           0 :                     fftBuffer[0] *= (float) sqrt( scale * *ptr_level ); /* DC component in FFT */
    2010           0 :                     ptr_level++;
    2011             :                 }
    2012             :                 else
    2013             :                 {
    2014        5712 :                     fftBuffer[0] = 0.f;
    2015        5712 :                     set_f( fftBuffer + 2, 0.0f, 2 * ( hFdCngCom->startBand - 1 ) );
    2016        5712 :                     ptr_r = fftBuffer + 2 * hFdCngCom->startBand;
    2017             :                 }
    2018        5712 :                 ptr_i = ptr_r + 1;
    2019             : 
    2020     1694448 :                 for ( ; ptr_level < cngNoiseLevel + hFdCngCom->stopFFTbin - hFdCngCom->startBand; ptr_level++ )
    2021             :                 {
    2022             :                     /* Real part in FFT bins */
    2023     1688736 :                     rand_gauss( ptr_r, seed );
    2024     1688736 :                     ( *ptr_r ) *= (float) sqrt( ( scale * *ptr_level ) * 0.5f );
    2025     1688736 :                     ptr_r += 2;
    2026             :                     /* Imaginary part in FFT bins */
    2027     1688736 :                     rand_gauss( ptr_i, seed );
    2028     1688736 :                     ( *ptr_i ) *= (float) sqrt( ( scale * *ptr_level ) * 0.5f );
    2029     1688736 :                     ptr_i += 2;
    2030             :                 }
    2031             : 
    2032             :                 /* Remaining FFT bins are set to zero */
    2033        5712 :                 set_f( fftBuffer + 2 * hFdCngCom->stopFFTbin, 0.0f, hFdCngCom->fftlen - 2 * hFdCngCom->stopFFTbin );
    2034             :                 /* Nyquist frequency is discarded */
    2035        5712 :                 fftBuffer[1] = 0.f;
    2036             : 
    2037             :                 /* Perform STFT synthesis */
    2038        5712 :                 SynthesisSTFT_dirac( fftBuffer, tdBuffer + n_samples_start, hFdCngCom->olapBufferSynth2, hFdCngCom->olapWinSyn, n_samples_out_loop, hFdCngCom );
    2039             : 
    2040             : #ifdef DEBUG_MODE_DIRAC
    2041             :                 {
    2042             :                     int16_t tmp[1000];
    2043             : 
    2044             :                     for ( i = 0; i < hFdCngCom->frameSize; i++ )
    2045             :                     {
    2046             :                         tmp[i] = (int16_t) ( tdBuffer[i] + 0.5f );
    2047             :                     }
    2048             :                     dbgwrite( tmp, sizeof( int16_t ), hFdCngCom->frameSize, 1, "./res/ivas_dirac_cna_fft.pcm" );
    2049             :                 }
    2050             : #endif
    2051             :             }
    2052             : 
    2053             :             else
    2054             :             {
    2055             :                 /* very low level case - update random seeds */
    2056       75188 :                 generate_masking_noise_update_seed( hFdCngCom );
    2057             : 
    2058       75188 :                 set_f( fftBuffer, 0.f, hFdCngCom->fftlen );
    2059             : 
    2060             :                 /* Perform STFT synthesis */
    2061       75188 :                 SynthesisSTFT_dirac( fftBuffer, tdBuffer + n_samples_start, hFdCngCom->olapBufferSynth2, hFdCngCom->olapWinSyn, n_samples_out_loop, hFdCngCom );
    2062             : 
    2063             : #ifdef DEBUG_MODE_DIRAC
    2064             :                 {
    2065             :                     int16_t tmp[1000];
    2066             : 
    2067             :                     for ( i = 0; i < hFdCngCom->frameSize; i++ )
    2068             :                     {
    2069             :                         tmp[i] = (int16_t) ( tdBuffer[i] + 0.5f );
    2070             :                     }
    2071             :                     dbgwrite( tmp, sizeof( int16_t ), hFdCngCom->frameSize, 1, "./res/ivas_dirac_cna_fft.pcm" );
    2072             :                 }
    2073             : #endif
    2074             :             }
    2075       80900 :             n_samples_out -= hFdCngCom->frameSize;
    2076       80900 :             n_samples_start += hFdCngCom->frameSize;
    2077             :         }
    2078             : 
    2079             :         /* move generated noise to the 5ms subframe starts in the tc buffer according to the output sampling frequency to avoid
    2080             :            overwriting it with the synthesis in case of shared tc and synth channel memory, i.e. non-TSM mode */
    2081       80900 :         slot_size_cng = hFdCngCom->frameSize / DEFAULT_JBM_CLDFB_TIMESLOTS;
    2082             :         /* move start indices forward to the end of the last subframe */
    2083       80900 :         cur_subframe_start_outfs = nCldfbTs * hSpatParamRendCom->slot_size;
    2084       80900 :         cur_subframe_start_cngfs = nCldfbTs * slot_size_cng;
    2085             : 
    2086             :         /* go from the last subframe back and move the LB noise */
    2087      404500 :         for ( cur_subframe = hSpatParamRendCom->nb_subframes - 1; cur_subframe >= 0; cur_subframe-- )
    2088             :         {
    2089             :             int16_t move_size, subframe_size_outfs;
    2090      323600 :             move_size = slot_size_cng * hSpatParamRendCom->subframe_nbslots[cur_subframe];
    2091      323600 :             subframe_size_outfs = hSpatParamRendCom->subframe_nbslots[cur_subframe] * hSpatParamRendCom->slot_size;
    2092      323600 :             cur_subframe_start_outfs -= hSpatParamRendCom->subframe_nbslots[cur_subframe] * hSpatParamRendCom->slot_size;
    2093      323600 :             cur_subframe_start_cngfs -= hSpatParamRendCom->subframe_nbslots[cur_subframe] * slot_size_cng;
    2094             :             /* move cna */
    2095      323600 :             mvr2r( tdBuffer + cur_subframe_start_cngfs, tdBuffer + cur_subframe_start_outfs, move_size );
    2096             :             /* set everything else to zero */
    2097      323600 :             set_zero( tdBuffer + cur_subframe_start_outfs + move_size, subframe_size_outfs - move_size );
    2098             :         }
    2099             :     }
    2100             : 
    2101             : 
    2102      302259 :     pop_wmops();
    2103             : 
    2104      302259 :     return;
    2105             : }
    2106             : 
    2107             : 
    2108             : /*-------------------------------------------------------------------
    2109             :  * generate_masking_noise_hf_cldfb()
    2110             :  *
    2111             :  * Generate additional comfort noise (kind of noise filling)
    2112             :  *-------------------------------------------------------------------*/
    2113             : 
    2114     9212304 : void generate_masking_noise_dirac(
    2115             :     HANDLE_FD_CNG_COM hFdCngCom,      /* i/o: FD_CNG structure containing all buffers and variables */
    2116             :     HANDLE_CLDFB_FILTER_BANK h_cldfb, /* i  : filterbank state                                      */
    2117             :     float *tdBuffer,                  /* i/o: time-domain signal, if NULL no LB-CNA                 */
    2118             :     float *Cldfb_RealBuffer,          /* o  : CLDFD real buffer                                     */
    2119             :     float *Cldfb_ImagBuffer,          /* o  : CLDFD imaginary buffer                                */
    2120             :     const int16_t slot_index,         /* i  : CLDFB slot index                                      */
    2121             :     const int16_t cna_flag,           /* i  : CNA flag for LB and HB                                */
    2122             :     const int16_t fd_cng_flag         /* i  : FD-CNG flag for HB                                    */
    2123             : )
    2124             : {
    2125             :     int16_t i;
    2126             :     float *ptr_level;
    2127     9212304 :     int16_t *seed = &( hFdCngCom->seed );
    2128             :     float scale;
    2129             : 
    2130     9212304 :     push_wmops( "fd_cng_dirac" );
    2131             : 
    2132             :     /* Init */
    2133     9212304 :     scale = 0.f;
    2134             : 
    2135             :     /* Resample CLDFB memories if necessary*/
    2136     9212304 :     if ( ( h_cldfb->no_channels * h_cldfb->no_col ) != hFdCngCom->frameSize )
    2137             :     {
    2138        7204 :         resampleCldfb( h_cldfb, hFdCngCom->frameSize * FRAMES_PER_SEC );
    2139             :     }
    2140             : 
    2141     9212304 :     set_zero( Cldfb_RealBuffer, CLDFB_NO_CHANNELS_MAX );
    2142     9212304 :     set_zero( Cldfb_ImagBuffer, CLDFB_NO_CHANNELS_MAX );
    2143             : 
    2144             :     /*LB CLDFB - CNA from STFT*/
    2145             : #ifdef DEBUG_MODE_DIRAC
    2146             :     {
    2147             :         int16_t tmp_s;
    2148             :         tmp_s = (int16_t) ( 32768.f * 0.5f * hFdCngCom->likelihood_noisy_speech * cna_flag + 0.5f );
    2149             :         dbgwrite( &tmp_s, sizeof( int16_t ), 1, hFdCngCom->frameSize / 16, "./res/ivas_dirac_likelihood_noisy.pcm" );
    2150             :     }
    2151             : #endif
    2152     9212304 :     if ( cna_flag )
    2153             :     {
    2154             :         /* skip noise generating if level is very low, to avoid problems with possibly running into denormals */
    2155     2445952 :         if ( hFdCngCom->likelihood_noisy_speech > DELTA_MASKING_NOISE )
    2156             :         {
    2157             :             /* Compute additional CN level */
    2158     1995648 :             for ( i = 0; i < 15; i++ )
    2159             :             {
    2160     1995648 :                 if ( ( hFdCngCom->CngBandwidth == scaleTable_cn_dirac[i].bwmode ) &&
    2161      419808 :                      ( hFdCngCom->CngBitrate >= scaleTable_cn_dirac[i].bitrateFrom ) &&
    2162      419808 :                      ( hFdCngCom->CngBitrate < scaleTable_cn_dirac[i].bitrateTo ) )
    2163             :                 {
    2164      157584 :                     break;
    2165             :                 }
    2166             :             }
    2167             : 
    2168      157584 :             scale = (float) pow( 10.f, -scaleTable_cn_dirac[i].scale / 10.f ) - 1.f;
    2169      157584 :             scale *= hFdCngCom->likelihood_noisy_speech;
    2170             :         }
    2171             :     }
    2172             :     /* LB CLDFB - CNA from STFT: CNA applied only in channel 0*/
    2173     9212304 :     if ( cna_flag && tdBuffer != NULL )
    2174             :     {
    2175     1294400 :         if ( scale != 0 )
    2176             :         {
    2177             :             /* LF CLDFB*/
    2178       91392 :             cldfbAnalysis_ts( &( tdBuffer[hFdCngCom->numCoreBands * slot_index] ), Cldfb_RealBuffer, Cldfb_ImagBuffer, hFdCngCom->numCoreBands, h_cldfb );
    2179             :         }
    2180             :         else
    2181             :         {
    2182             :             /* LB ana CLDFB*/
    2183     1203008 :             cldfbAnalysis_ts( &( tdBuffer[hFdCngCom->numCoreBands * slot_index] ), Cldfb_RealBuffer, Cldfb_ImagBuffer, hFdCngCom->numCoreBands, h_cldfb );
    2184             :         }
    2185             :     }
    2186             : 
    2187             :     /*HF CLDFB - CNA and/or FD-CNG*/
    2188     9212304 :     if ( fd_cng_flag )
    2189             :     {
    2190       29088 :         scale += 1.f;
    2191             :     }
    2192     9212304 :     if ( scale != 0 )
    2193             :     {
    2194      166704 :         scale *= CLDFB_SCALING * ( h_cldfb->scale * h_cldfb->scale * 8.f );
    2195      166704 :         ptr_level = hFdCngCom->cngNoiseLevel + hFdCngCom->stopFFTbin - hFdCngCom->startBand;
    2196             : 
    2197     3449664 :         for ( i = hFdCngCom->numCoreBands; i < hFdCngCom->regularStopBand; i++ )
    2198             :         {
    2199             :             /* Real part in CLDFB band */
    2200     3282960 :             rand_gauss( &Cldfb_RealBuffer[i], seed );
    2201     3282960 :             Cldfb_RealBuffer[i] *= (float) sqrt( ( scale * *ptr_level ) * 0.5f );
    2202             :             /* Imaginary part in CLDFB band */
    2203     3282960 :             rand_gauss( &Cldfb_ImagBuffer[i], seed );
    2204     3282960 :             Cldfb_ImagBuffer[i] *= (float) sqrt( ( scale * *ptr_level ) * 0.5f );
    2205             : 
    2206     3282960 :             ptr_level++;
    2207             :         }
    2208             :     }
    2209             : 
    2210     9212304 :     pop_wmops();
    2211             : 
    2212     9212304 :     return;
    2213             : }
    2214             : 
    2215             : 
    2216             : /*-------------------------------------------------------------------
    2217             :  * FdCngDecodeMDCTStereoSID()
    2218             :  *
    2219             :  * Decode FD-Cng parameters for CNG in MDCT-Stereo mode from the bitstream
    2220             :  *
    2221             :  *-------------------------------------------------------------------*/
    2222             : 
    2223        1313 : void FdCngDecodeMDCTStereoSID(
    2224             :     CPE_DEC_HANDLE hCPE /* i/o: CPE decoder state structure     */
    2225             : )
    2226             : {
    2227             :     DEC_CORE_HANDLE sts[CPE_CHANNELS];
    2228             :     HANDLE_FD_CNG_COM hFdCngCom;
    2229             :     float *ms_ptr[CPE_CHANNELS];
    2230             :     float *lr_ptr[CPE_CHANNELS];
    2231             :     float logNoiseEst[CPE_CHANNELS][NPART];
    2232             :     float gain[CPE_CHANNELS];
    2233             :     int16_t indices[FD_CNG_stages_37bits];
    2234             :     int16_t N, i, ch, p, stages;
    2235             :     int16_t is_out_ms;
    2236             :     float *invTrfMatrix;
    2237             :     float tmpRAM[FDCNG_VQ_MAX_LEN][FDCNG_VQ_DCT_MAXTRUNC];
    2238             : #ifdef NONBE_MDCT_ST_DTX_FIX_SUBOPT_SPATIAL_CNG
    2239             :     int32_t tmp;
    2240             : #endif
    2241             : 
    2242        1313 :     invTrfMatrix = (float *) tmpRAM;
    2243        1313 :     create_IDCT_N_Matrix( invTrfMatrix, FDCNG_VQ_MAX_LEN, FDCNG_VQ_DCT_MAXTRUNC, sizeof( tmpRAM ) / ( sizeof( float ) ) );
    2244             : 
    2245        1313 :     is_out_ms = 0;
    2246        1313 :     if ( hCPE->hCoreCoder[0]->cng_sba_flag )
    2247             :     {
    2248           0 :         is_out_ms = 1;
    2249             :     }
    2250             : 
    2251        1313 :     N = 0; /* to avoid compilation warning */
    2252             : 
    2253        3939 :     for ( ch = 0; ch < CPE_CHANNELS; ch++ )
    2254             :     {
    2255        2626 :         sts[ch] = hCPE->hCoreCoder[ch];
    2256        2626 :         ms_ptr[ch] = &logNoiseEst[ch][0];
    2257        2626 :         lr_ptr[ch] = &sts[ch]->hFdCngDec->hFdCngCom->sidNoiseEst[0];
    2258             :     }
    2259             : 
    2260             :     /* decode noise shapes and gains */
    2261        3939 :     for ( ch = 0; ch < CPE_CHANNELS; ch++ )
    2262             :     {
    2263        2626 :         sts[ch] = hCPE->hCoreCoder[ch];
    2264        2626 :         hFdCngCom = ( sts[ch]->hFdCngDec )->hFdCngCom;
    2265        2626 :         N = hFdCngCom->npart;
    2266        2626 :         hFdCngCom->sid_frame_counter++;
    2267             : 
    2268        2626 :         if ( ch )
    2269             :         {
    2270        1313 :             stages = FD_CNG_JOINT_stages_25bits;
    2271             :         }
    2272             :         else
    2273             :         {
    2274        1313 :             stages = FD_CNG_stages_37bits;
    2275             :         }
    2276             : 
    2277             :         /* read bitstream */
    2278       15756 :         for ( i = 0; i < stages; i++ )
    2279             :         {
    2280       13130 :             indices[i] = get_next_indice( sts[ch], bits_37bits[i] );
    2281             :         }
    2282             :         {
    2283        2626 :             gain[ch] = ( (float) get_next_indice( sts[ch], 7 ) - GAIN_Q_OFFSET_IVAS ) / 1.5f;
    2284             :         }
    2285             : 
    2286             :         /* MSVQ decoder */
    2287        2626 :         msvq_dec( cdk_37bits_ivas, NULL, NULL, stages, N, FD_CNG_maxN_37bits, indices, 1, invTrfMatrix, ms_ptr[ch], NULL );
    2288             :     }
    2289             : 
    2290             : #ifdef NONBE_MDCT_ST_DTX_FIX_SUBOPT_SPATIAL_CNG
    2291        1313 :     tmp = sts[1]->total_brate;
    2292        1313 :     sts[1]->total_brate = sts[1]->total_brate + 16 * FRAMES_PER_SEC;
    2293             :     /* read the four additional coherence values */
    2294        6565 :     for ( int16_t b = 1; b < MDCT_ST_DTX_NUM_COHERENCE_BANDS; b++ )
    2295             :     {
    2296             :         uint16_t tmp_bit;
    2297             : 
    2298        5252 :         tmp_bit = get_next_indice( sts[1], 4 );
    2299        5252 :         sts[0]->hFdCngDec->hFdCngCom->coherence[b] = (float) tmp_bit / 15.f;
    2300        5252 :         sts[1]->hFdCngDec->hFdCngCom->coherence[b] = sts[0]->hFdCngDec->hFdCngCom->coherence[b];
    2301             :     }
    2302        1313 :     sts[1]->total_brate = tmp;
    2303             : #else
    2304             :     dtx_read_padding_bits( sts[1], ( IVAS_SID_5k2 - 4400 ) / FRAMES_PER_SEC );
    2305             : #endif
    2306             : 
    2307        1313 :     if ( sts[0]->hFdCngDec->hFdCngCom->no_side_flag )
    2308             :     {
    2309          41 :         set_zero( ms_ptr[1], NPART );
    2310             :     }
    2311             : 
    2312        1313 :     if ( is_out_ms == 0 )
    2313             :     {
    2314        1313 :         inverseMS( N, ms_ptr[0], ms_ptr[1], 1.f );
    2315             :     }
    2316             : 
    2317        3939 :     for ( ch = 0; ch < CPE_CHANNELS; ch++ )
    2318             :     {
    2319        2626 :         hFdCngCom = sts[ch]->hFdCngDec->hFdCngCom;
    2320       62554 :         for ( p = 0; p < N; p++ )
    2321             :         {
    2322       59928 :             lr_ptr[ch][p] = powf( 10.f, ( ms_ptr[ch][p] + gain[ch] ) / 10.f );
    2323             :         }
    2324             : 
    2325        2626 :         scalebands( hFdCngCom->sidNoiseEst, hFdCngCom->part, hFdCngCom->npart, hFdCngCom->midband, hFdCngCom->nFFTpart, hFdCngCom->stopBand - hFdCngCom->startBand, hFdCngCom->cngNoiseLevel, 1 );
    2326             : 
    2327        2626 :         lpc_from_spectrum( hFdCngCom, hFdCngCom->startBand, hFdCngCom->stopFFTbin, sts[ch]->preemph_fac );
    2328             :     }
    2329             : 
    2330        1313 :     if ( hCPE->nchan_out == 1 && hCPE->last_element_brate <= IVAS_SID_5k2 )
    2331             :     {
    2332             :         /* create proper M noise shape in channel zero after gains have been applied */
    2333        9944 :         for ( p = 0; p < N; p++ )
    2334             :         {
    2335        9534 :             sts[0]->hFdCngDec->hFdCngCom->sidNoiseEst[p] = 0.5f * ( sts[0]->hFdCngDec->hFdCngCom->sidNoiseEst[p] + sts[1]->hFdCngDec->hFdCngCom->sidNoiseEst[p] );
    2336             :         }
    2337             :     }
    2338             : 
    2339        1313 :     return;
    2340             : }
    2341             : 
    2342             : 
    2343             : /*-------------------------------------------------------------------
    2344             :  * FdCngDecodeDiracMDCTStereoSID()
    2345             :  *
    2346             :  * Decode FD-CNG parameters for CNG in 2TC DirAC mode from the bitstream
    2347             :  *-------------------------------------------------------------------*/
    2348             : 
    2349         549 : void FdCngDecodeDiracMDCTStereoSID(
    2350             :     CPE_DEC_HANDLE hCPE /* i/o: CPE decoder state structure     */
    2351             : )
    2352             : {
    2353             :     DEC_CORE_HANDLE sts[CPE_CHANNELS];
    2354             :     HANDLE_FD_CNG_COM hFdCngCom;
    2355             :     float *ms_ptr[CPE_CHANNELS];
    2356             :     float *lr_ptr[CPE_CHANNELS];
    2357             :     float logNoiseEst[CPE_CHANNELS][NPART];
    2358             :     float gain[CPE_CHANNELS];
    2359             :     int16_t indices[FD_CNG_stages_37bits];
    2360             :     int16_t N, i, ch, p;
    2361             :     float *invTrfMatrix;
    2362             :     float tmpRAM[FDCNG_VQ_MAX_LEN][FDCNG_VQ_DCT_MAXTRUNC];
    2363             : 
    2364             : 
    2365         549 :     invTrfMatrix = (float *) tmpRAM; /* dynamically filled  */
    2366         549 :     create_IDCT_N_Matrix( invTrfMatrix, FDCNG_VQ_MAX_LEN, FDCNG_VQ_DCT_MAXTRUNC, sizeof( tmpRAM ) / ( sizeof( float ) ) );
    2367             : 
    2368        1647 :     for ( ch = 0; ch < CPE_CHANNELS; ch++ )
    2369             :     {
    2370        1098 :         sts[ch] = hCPE->hCoreCoder[ch];
    2371        1098 :         ms_ptr[ch] = &logNoiseEst[ch][0];
    2372        1098 :         lr_ptr[ch] = &sts[ch]->hFdCngDec->hFdCngCom->sidNoiseEst[0];
    2373        1098 :         ( sts[ch]->hFdCngDec )->hFdCngCom->sid_frame_counter++;
    2374             :     }
    2375             : 
    2376             :     /* decode noise shapes and gains */
    2377         549 :     hFdCngCom = ( sts[0]->hFdCngDec )->hFdCngCom;
    2378         549 :     N = hFdCngCom->npart;
    2379             : 
    2380             :     /* read bitstream */
    2381        3843 :     for ( i = 0; i < FD_CNG_stages_37bits; i++ )
    2382             :     {
    2383        3294 :         indices[i] = get_next_indice( sts[0], bits_37bits[i] );
    2384             :     }
    2385         549 :     gain[0] = ( (float) get_next_indice( sts[0], 7 ) - GAIN_Q_OFFSET_IVAS ) / 1.5f;
    2386         549 :     gain[1] = gain[0];
    2387             : 
    2388             :     /* MSVQ decoder */
    2389         549 :     msvq_dec( cdk_37bits_ivas, NULL, NULL, FD_CNG_stages_37bits, N, FD_CNG_maxN_37bits, indices, 1, invTrfMatrix, ms_ptr[0], NULL );
    2390         549 :     mvr2r( ms_ptr[0], ms_ptr[1], N );
    2391             : 
    2392             :     /*inverseMS( N, ms_ptr[0], ms_ptr[1], 1.f );*/
    2393             : 
    2394        1647 :     for ( ch = 0; ch < CPE_CHANNELS; ch++ )
    2395             :     {
    2396        1098 :         hFdCngCom = sts[ch]->hFdCngDec->hFdCngCom;
    2397       27450 :         for ( p = 0; p < N; p++ )
    2398             :         {
    2399       26352 :             lr_ptr[ch][p] = powf( 10.f, ( ms_ptr[ch][p] + gain[ch] ) / 10.f );
    2400             :         }
    2401             : 
    2402             :         /* NB last band energy compensation */
    2403        1098 :         if ( hFdCngCom->CngBandwidth == NB )
    2404             :         {
    2405           0 :             lr_ptr[ch][N - 1] *= NB_LAST_BAND_SCALE;
    2406             :         }
    2407        1098 :         else if ( hFdCngCom->CngBandwidth == SWB && hFdCngCom->CngBitrate <= ACELP_13k20 )
    2408             :         {
    2409           0 :             lr_ptr[ch][N - 1] *= SWB_13k2_LAST_BAND_SCALE;
    2410             :         }
    2411             : 
    2412        1098 :         scalebands( hFdCngCom->sidNoiseEst, hFdCngCom->part, hFdCngCom->npart, hFdCngCom->midband, hFdCngCom->nFFTpart, hFdCngCom->stopBand - hFdCngCom->startBand, hFdCngCom->cngNoiseLevel, 1 );
    2413             : 
    2414        1098 :         lpc_from_spectrum( hFdCngCom, hFdCngCom->startBand, hFdCngCom->stopFFTbin, sts[ch]->preemph_fac );
    2415             :     }
    2416             : #ifdef NONBE_MDCT_ST_DTX_FIX_SUBOPT_SPATIAL_CNG
    2417        3294 :     for ( i = 0; i < MDCT_ST_DTX_NUM_COHERENCE_BANDS; i++ )
    2418             :     {
    2419        2745 :         sts[0]->hFdCngDec->hFdCngCom->coherence[i] = 0.0f;
    2420        2745 :         sts[1]->hFdCngDec->hFdCngCom->coherence[i] = 0.0f;
    2421             :     }
    2422             : #else
    2423             :     sts[0]->hFdCngDec->hFdCngCom->coherence = 0.0f;
    2424             :     sts[1]->hFdCngDec->hFdCngCom->coherence = 0.0f;
    2425             : #endif
    2426             : 
    2427         549 :     if ( hCPE->nchan_out == 1 )
    2428             :     {
    2429             :         /* create proper M noise shape in channel zero after gains have been applied */
    2430           0 :         for ( p = 0; p < N; p++ )
    2431             :         {
    2432           0 :             sts[0]->hFdCngDec->hFdCngCom->sidNoiseEst[p] = 0.5f * ( sts[0]->hFdCngDec->hFdCngCom->sidNoiseEst[p] + sts[1]->hFdCngDec->hFdCngCom->sidNoiseEst[p] );
    2433             :         }
    2434             :     }
    2435             : 
    2436         549 :     return;
    2437             : }

Generated by: LCOV version 1.14