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

Generated by: LCOV version 1.14