LCOV - code coverage report
Current view: top level - lib_enc - fd_cng_enc.c (source / functions) Hit Total Coverage
Test: Coverage on main -- long test vectors @ 9b04ec3cb36f5e8dc438cf854fa3e349998fa1e9 Lines: 511 527 97.0 %
Date: 2025-10-31 05:43:07 Functions: 13 13 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 "cnst.h"
      38             : #include "ivas_cnst.h"
      39             : #include <assert.h>
      40             : #include <stdint.h>
      41             : #include "options.h"
      42             : #ifdef DEBUGGING
      43             : #include "debug.h"
      44             : #endif
      45             : #include <math.h>
      46             : #include "rom_enc.h"
      47             : #include "rom_com.h"
      48             : #ifdef NONBE_MDCT_ST_DTX_FIX_SUBOPT_SPATIAL_CNG
      49             : #include "ivas_rom_com.h"
      50             : #endif
      51             : #include "prot.h"
      52             : #include "ivas_prot.h"
      53             : #include "stat_enc.h"
      54             : #include "wmc_auto.h"
      55             : 
      56             : /*-------------------------------------------------------------------*
      57             :  * createFdCngEnc()
      58             :  *
      59             :  *
      60             :  *-------------------------------------------------------------------*/
      61             : 
      62        4465 : ivas_error createFdCngEnc(
      63             :     HANDLE_FD_CNG_ENC *hFdCngEnc /* i/o: FD_CNG structure        */
      64             : )
      65             : {
      66             :     HANDLE_FD_CNG_ENC hs;
      67             :     ivas_error error;
      68        4465 :     error = IVAS_ERR_OK;
      69             : 
      70             :     /* Set output to NULL in case of errors and early return */
      71        4465 :     *hFdCngEnc = NULL;
      72             : 
      73             :     /* Allocate memory */
      74        4465 :     if ( ( hs = (HANDLE_FD_CNG_ENC) malloc( sizeof( FD_CNG_ENC ) ) ) == NULL )
      75             :     {
      76           0 :         return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Cannot allocate memory for FD CNG ENC structure" );
      77             :     }
      78             : 
      79        4465 :     if ( ( error = createFdCngCom( &( hs->hFdCngCom ) ) ) != IVAS_ERR_OK )
      80             :     {
      81           0 :         return error;
      82             :     }
      83             : 
      84        4465 :     *hFdCngEnc = hs;
      85             : 
      86        4465 :     return error;
      87             : }
      88             : 
      89             : /*-------------------------------------------------------------------*
      90             :  * initFdCngEnc()
      91             :  *
      92             :  * Initialize FD_CNG
      93             :  *-------------------------------------------------------------------*/
      94             : 
      95        4465 : void initFdCngEnc(
      96             :     HANDLE_FD_CNG_ENC hFdCngEnc, /* i/o: Contains the variables related to the FD-based CNG process */
      97             :     const int32_t input_Fs,      /* i  : input signal sampling frequency in Hz   */
      98             :     const float scale            /* i  : scaling factor                          */
      99             : )
     100             : {
     101             :     int16_t j;
     102        4465 :     HANDLE_FD_CNG_COM hsCom = hFdCngEnc->hFdCngCom;
     103             : 
     104             :     /* Initialize common */
     105        4465 :     initFdCngCom( hsCom, scale );
     106             : 
     107             :     /* Configure the Noise Estimator */
     108        4465 :     hsCom->numSlots = 16;
     109        4465 :     hsCom->numCoreBands = 16;
     110        4465 :     hsCom->regularStopBand = (int16_t) ( input_Fs * INV_CLDFB_BANDWIDTH );
     111        4465 :     if ( hsCom->regularStopBand > 40 )
     112             :     {
     113        2545 :         hsCom->regularStopBand = 40;
     114             :     }
     115             : 
     116        4465 :     hsCom->startBand = 2;
     117        4465 :     if ( hsCom->regularStopBand == 10 )
     118             :     {
     119           7 :         hsCom->stopFFTbin = 160;
     120           7 :         hsCom->stopBand = 160;
     121           7 :         hsCom->nFFTpart = 17;
     122             :     }
     123             :     else
     124             :     {
     125        4458 :         hsCom->stopFFTbin = 256;
     126        4458 :         hsCom->stopBand = hsCom->regularStopBand - hsCom->numCoreBands + hsCom->stopFFTbin;
     127        4458 :         hsCom->nFFTpart = 20;
     128             :     }
     129             : 
     130        4465 :     initPartitions( sidparts_encoder_noise_est, SIZE_SIDPARTS_ENC_NOISE_EST, hsCom->startBand, hsCom->stopBand, hsCom->part, &hsCom->npart, hsCom->midband, hsCom->psize, hsCom->psize_inv, 0 );
     131             : 
     132        4465 :     hsCom->nCLDFBpart = hsCom->npart - hsCom->nFFTpart;
     133       22153 :     for ( j = 0; j < hsCom->nCLDFBpart; j++ )
     134             :     {
     135       17688 :         hsCom->CLDFBpart[j] = hsCom->part[j + hsCom->nFFTpart] - ( 256 - hsCom->startBand );
     136       17688 :         hsCom->CLDFBpsize_inv[j] = hsCom->psize_inv[j + hsCom->nFFTpart];
     137             :     }
     138             : 
     139             :     /* Initialize the Noise Estimator */
     140        4465 :     set_f( hFdCngEnc->msPeriodog, 0.0f, NPART );
     141        4465 :     set_f( hFdCngEnc->msAlpha, 0.0f, NPART );
     142        4465 :     set_f( hFdCngEnc->msBminWin, 0.0f, NPART );
     143        4465 :     set_f( hFdCngEnc->msBminSubWin, 0.0f, NPART );
     144        4465 :     set_f( hFdCngEnc->msPsd, 0.0f, NPART );
     145        4465 :     set_f( hFdCngEnc->msNoiseFloor, 0.0f, NPART );
     146        4465 :     set_f( hFdCngEnc->msNoiseEst, 0.0f, NPART );
     147        4465 :     set_f( hFdCngEnc->energy_ho, 0.0f, NPART );
     148        4465 :     set_f( hFdCngEnc->msNoiseEst_old, 0.0f, NPART );
     149        4465 :     set_f( hFdCngEnc->msMinBuf, FLT_MAX, MSNUMSUBFR * NPART );
     150        4465 :     set_f( hFdCngEnc->msCurrentMin, FLT_MAX, NPART );
     151        4465 :     set_f( hFdCngEnc->msCurrentMinOut, FLT_MAX, NPART );
     152        4465 :     set_f( hFdCngEnc->msCurrentMinSubWindow, FLT_MAX, NPART );
     153        4465 :     set_s( hFdCngEnc->msLocalMinFlag, 0, NPART );
     154        4465 :     set_s( hFdCngEnc->msNewMinFlag, 0, NPART );
     155        4465 :     set_f( hFdCngEnc->msPsdFirstMoment, 0.0f, NPART );
     156        4465 :     set_f( hFdCngEnc->msPsdSecondMoment, 0.0f, NPART );
     157        4465 :     hFdCngEnc->msPeriodogBufPtr = 0;
     158        4465 :     set_f( hFdCngEnc->msPeriodogBuf, 0.0f, MSBUFLEN * NPART );
     159        4465 :     set_f( hFdCngEnc->msLogPeriodog, 0.0f, NPART );
     160        4465 :     set_f( hFdCngEnc->msLogNoiseEst, 0.0f, NPART );
     161             : 
     162             : #ifdef NONBE_MDCT_ST_DTX_FIX_SUBOPT_SPATIAL_CNG
     163       26790 :     for ( int16_t i = 0; i < MDCT_ST_DTX_NUM_COHERENCE_BANDS; i++ )
     164             :     {
     165       22325 :         set_f( hFdCngEnc->mem_coherence[i], EPSILON, 4 );
     166             :     }
     167             : #else
     168             :     set_f( hFdCngEnc->mem_coherence, EPSILON, 4 );
     169             : #endif
     170             : 
     171        4465 :     return;
     172             : }
     173             : 
     174             : /*-------------------------------------------------------------------*
     175             :  * configureFdCngEnc()
     176             :  *
     177             :  * Configure FD_CNG
     178             :  *-------------------------------------------------------------------*/
     179             : 
     180      425525 : void configureFdCngEnc(
     181             :     HANDLE_FD_CNG_ENC hFdCngEnc, /* i/o: Contains the variables related to the FD-based CNG process */
     182             :     const int16_t bwidth,
     183             :     const int32_t total_brate )
     184             : {
     185      425525 :     HANDLE_FD_CNG_COM hsCom = hFdCngEnc->hFdCngCom;
     186             :     float psizeDec[NPART];
     187             :     float psize_invDec[NPART];
     188             : 
     189      425525 :     hsCom->CngBandwidth = bwidth;
     190      425525 :     if ( hsCom->CngBandwidth == FB )
     191             :     {
     192      346382 :         hsCom->CngBandwidth = SWB;
     193             :     }
     194      425525 :     hsCom->CngBitrate = total_brate;
     195             : 
     196             :     /* NB configuration */
     197      425525 :     if ( bwidth == NB )
     198             :     {
     199          48 :         hsCom->FdCngSetup = FdCngSetup_nb;
     200             :     }
     201             : 
     202             :     /* WB configuration */
     203      425477 :     else if ( bwidth == WB )
     204             :     {
     205             :         /* FFT 6.4kHz, no CLDFB */
     206       16436 :         if ( total_brate <= ACELP_8k00 )
     207             :         {
     208         511 :             hsCom->FdCngSetup = FdCngSetup_wb1;
     209             :         }
     210             :         /* FFT 6.4kHz, CLDFB 8.0kHz */
     211       15925 :         else if ( total_brate <= ACELP_13k20 )
     212             :         {
     213        7293 :             hsCom->FdCngSetup = FdCngSetup_wb2;
     214             :         }
     215             :         /* FFT 8.0kHz, no CLDFB */
     216             :         else
     217             :         {
     218        8632 :             hsCom->FdCngSetup = FdCngSetup_wb3;
     219             :         }
     220             :     }
     221             : 
     222             :     /* SWB/FB configuration */
     223             :     else
     224             :     {
     225             :         /* FFT 6.4kHz, CLDFB 14kHz */
     226      409041 :         if ( total_brate <= ACELP_13k20 )
     227             :         {
     228      204783 :             hsCom->FdCngSetup = FdCngSetup_swb1;
     229             :         }
     230             :         /* FFT 8.0kHz, CLDFB 16kHz */
     231             :         else
     232             :         {
     233      204258 :             hsCom->FdCngSetup = FdCngSetup_swb2;
     234             :         }
     235             :     }
     236      425525 :     hsCom->fftlen = hsCom->FdCngSetup.fftlen;
     237      425525 :     hFdCngEnc->stopFFTbinDec = hsCom->FdCngSetup.stopFFTbin;
     238             : 
     239             :     /* Configure the SID quantizer and the Confort Noise Generator */
     240             : 
     241      425525 :     hFdCngEnc->startBandDec = hsCom->startBand;
     242      425525 :     hFdCngEnc->stopBandDec = hsCom->FdCngSetup.sidPartitions[hsCom->FdCngSetup.numPartitions - 1] + 1;
     243      425525 :     initPartitions( hsCom->FdCngSetup.sidPartitions, hsCom->FdCngSetup.numPartitions, hFdCngEnc->startBandDec, hFdCngEnc->stopBandDec, hFdCngEnc->partDec, &hFdCngEnc->npartDec, hFdCngEnc->midbandDec, psizeDec, psize_invDec, 0 );
     244             : 
     245      425525 :     if ( hFdCngEnc->stopFFTbinDec == 160 )
     246             :     {
     247          48 :         hFdCngEnc->nFFTpartDec = 17;
     248             :     }
     249      425477 :     else if ( hFdCngEnc->stopFFTbinDec == 256 )
     250             :     {
     251      212587 :         hFdCngEnc->nFFTpartDec = 20;
     252             :     }
     253             :     else
     254             :     {
     255      212890 :         hFdCngEnc->nFFTpartDec = 21;
     256             :     }
     257             : 
     258      425525 :     switch ( hsCom->fftlen )
     259             :     {
     260      212635 :         case 512:
     261      212635 :             hsCom->fftSineTab = NULL;
     262      212635 :             hsCom->olapWinAna = olapWinAna512;
     263      212635 :             hsCom->olapWinSyn = olapWinSyn256;
     264      212635 :             break;
     265      212890 :         case 640:
     266      212890 :             hsCom->fftSineTab = fftSineTab640;
     267      212890 :             hsCom->olapWinAna = olapWinAna640;
     268      212890 :             hsCom->olapWinSyn = olapWinSyn320;
     269      212890 :             break;
     270           0 :         default:
     271           0 :             assert( !"Unsupported FFT length for FD-based CNG" );
     272             :             break;
     273             :     }
     274      425525 :     hsCom->frameSize = hsCom->fftlen >> 1;
     275             : 
     276      425525 :     return;
     277             : }
     278             : 
     279             : 
     280             : /*-------------------------------------------------------------------*
     281             :  * deleteFdCngEnc()
     282             :  *
     283             :  * Delete the instance of type FD_CNG
     284             :  *-------------------------------------------------------------------*/
     285             : 
     286      112510 : void deleteFdCngEnc(
     287             :     HANDLE_FD_CNG_ENC *hFdCngEnc /* i/o: FD_CNG structure        */
     288             : )
     289             : {
     290             : 
     291      112510 :     HANDLE_FD_CNG_ENC hsEnc = *hFdCngEnc;
     292             : 
     293      112510 :     if ( hsEnc != NULL )
     294             :     {
     295        4465 :         deleteFdCngCom( &( hsEnc->hFdCngCom ) );
     296        4465 :         free( hsEnc );
     297        4465 :         *hFdCngEnc = NULL;
     298             :     }
     299             : 
     300      112510 :     return;
     301             : }
     302             : 
     303             : /*-------------------------------------------------------------------*
     304             :  * resetFdCngEnc()
     305             :  *
     306             :  * Reset the instance of type FD_CNG
     307             :  *-------------------------------------------------------------------*/
     308             : 
     309     2013252 : void resetFdCngEnc(
     310             :     Encoder_State *st /* i/o: encoder state structure     */
     311             : )
     312             : {
     313             :     int16_t n;
     314             :     float totalNoiseIncrease;
     315             : 
     316             :     /* Detect fast increase of totalNoise */
     317     2013252 :     totalNoiseIncrease = st->hNoiseEst->totalNoise - st->last_totalNoise;
     318     2013252 :     st->last_totalNoise = st->hNoiseEst->totalNoise;
     319     2013252 :     if ( totalNoiseIncrease > 0 )
     320             :     {
     321       35042 :         if ( st->totalNoise_increase_len == TOTALNOISE_HIST_SIZE )
     322             :         {
     323       16024 :             for ( n = 0; n < TOTALNOISE_HIST_SIZE - 1; n++ )
     324             :             {
     325       12018 :                 st->totalNoise_increase_hist[n] = st->totalNoise_increase_hist[n + 1];
     326             :             }
     327        4006 :             st->totalNoise_increase_hist[TOTALNOISE_HIST_SIZE - 1] = totalNoiseIncrease;
     328             :         }
     329             :         else
     330             :         {
     331       31036 :             st->totalNoise_increase_hist[st->totalNoise_increase_len] = totalNoiseIncrease;
     332       31036 :             st->totalNoise_increase_len++;
     333             :         }
     334             :     }
     335             :     else
     336             :     {
     337     1978210 :         st->totalNoise_increase_len = 0;
     338             :     }
     339             : 
     340     2013252 :     totalNoiseIncrease = 0.f;
     341     2077050 :     for ( n = 0; n < st->totalNoise_increase_len; n++ )
     342             :     {
     343       63798 :         totalNoiseIncrease += st->totalNoise_increase_hist[n];
     344             :     }
     345             : 
     346     2013252 :     if (
     347        2446 :         ( totalNoiseIncrease > 5 && st->totalNoise_increase_len == TOTALNOISE_HIST_SIZE && st->ini_frame > 150 ) ||
     348     2013115 :         ( st->input_bwidth > st->last_input_bwidth ) ||
     349     2010286 :         ( st->last_core == AMR_WB_CORE ) )
     350             :     {
     351        2987 :         st->fd_cng_reset_flag = 1;
     352        2987 :         st->hFdCngEnc->hFdCngCom->msFrCnt_init_counter = 0;
     353        2987 :         st->hFdCngEnc->hFdCngCom->init_old = FLT_MAX;
     354             :     }
     355     2010265 :     else if ( st->fd_cng_reset_flag > 0 && st->fd_cng_reset_flag < 10 )
     356             :     {
     357       26379 :         st->fd_cng_reset_flag++;
     358             :     }
     359             :     else
     360             :     {
     361     1983886 :         st->fd_cng_reset_flag = 0;
     362             :     }
     363             : 
     364     2013252 :     return;
     365             : }
     366             : 
     367             : 
     368             : /*-------------------------------------------------------------------*
     369             :  * perform_noise_estimation_enc()
     370             :  *
     371             :  * Perform noise estimation
     372             :  *-------------------------------------------------------------------*/
     373             : 
     374     1715402 : void perform_noise_estimation_enc(
     375             :     float *band_energies,        /* i  : energy in critical bands without minimum noise floor E_MIN*/
     376             :     float *enerBuffer,           /* i  : energy buffer                                             */
     377             :     HANDLE_FD_CNG_ENC hFdCngEnc, /* i/o: CNG structure containing all buffers and variables        */
     378             :     const int32_t input_Fs,      /* i  : input sampling rate                                       */
     379             :     CPE_ENC_HANDLE hCPE          /* i  : CPE encoder structure                                     */
     380             : )
     381             : {
     382             :     int16_t i, j;
     383     1715402 :     int16_t numCoreBands = hFdCngEnc->hFdCngCom->numCoreBands;
     384     1715402 :     int16_t regularStopBand = hFdCngEnc->hFdCngCom->regularStopBand;
     385     1715402 :     int16_t numSlots = hFdCngEnc->hFdCngCom->numSlots;
     386     1715402 :     float numSlots_inv = 1.f / (float) numSlots; /*enough if done only once*/
     387     1715402 :     float *periodog = hFdCngEnc->hFdCngCom->periodog;
     388     1715402 :     float *ptr_per = periodog;
     389     1715402 :     int16_t npart = hFdCngEnc->hFdCngCom->npart;
     390     1715402 :     int16_t nFFTpart = hFdCngEnc->hFdCngCom->nFFTpart;
     391     1715402 :     float *psize = hFdCngEnc->hFdCngCom->psize;
     392     1715402 :     float *msPeriodog = hFdCngEnc->msPeriodog;
     393     1715402 :     float *msNoiseEst = hFdCngEnc->msNoiseEst;
     394             : 
     395     1715402 :     float *msLogPeriodog = hFdCngEnc->msLogPeriodog;
     396     1715402 :     float *msLogNoiseEst = hFdCngEnc->msLogNoiseEst;
     397             : 
     398             :     float band_res_dft, chan_width_f;
     399             :     float chan_width_bins;
     400             :     float scaleEB;
     401             : 
     402     1715402 :     if ( hCPE != NULL && hCPE->hStereoDft != NULL )
     403             :     {
     404      291386 :         band_res_dft = ( (float) input_Fs ) / hCPE->hStereoDft->NFFT;
     405      291386 :         chan_width_f = 24000.f / CLDFB_NO_CHANNELS_MAX;
     406      291386 :         chan_width_bins = chan_width_f / band_res_dft;
     407             : 
     408             :         /* Scaling of Energy buffer to get energy per sample, same scaling as for band_energies, 3 is to compensate for the 1/3 scaling in calculate_energy_buffer */
     409      291386 :         scaleEB = 3 * 4.0f / ( hCPE->hStereoDft->NFFT * hCPE->hStereoDft->NFFT );
     410             : 
     411             :         /* Scale with number of bins in one band */
     412      291386 :         scaleEB = scaleEB / chan_width_bins;
     413             :     }
     414             :     else
     415             :     {
     416     1424016 :         scaleEB = numSlots_inv * hFdCngEnc->hFdCngCom->scalingFactor;
     417             :     }
     418             : 
     419             :     /* preemphasis compensation and grouping of per bin energies into msPeriodog */
     420    36002712 :     for ( i = 0; i < nFFTpart; i++ )
     421             :     {
     422    34287310 :         msPeriodog[i] = 0.5f * ( band_energies[i] + band_energies[i + NB_BANDS] );
     423    34287310 :         msPeriodog[i] *= preemphCompensation[i];
     424             :     }
     425             : 
     426             :     /* Adjust to the desired time resolution by averaging the periodograms over the time slots */
     427    37264930 :     for ( j = numCoreBands; j < regularStopBand; j++ )
     428             :     {
     429    35549528 :         ( *ptr_per ) = enerBuffer[j] * scaleEB;
     430    35549528 :         ptr_per++;
     431             :     }
     432             : 
     433             :     /* Adjust filterbank to the desired frequency resolution by averaging over spectral partitions for SID transmission */
     434     1715402 :     if ( numCoreBands < regularStopBand )
     435             :     {
     436     1708492 :         bandcombinepow( periodog, regularStopBand - numCoreBands, hFdCngEnc->hFdCngCom->CLDFBpart, hFdCngEnc->hFdCngCom->nCLDFBpart, hFdCngEnc->hFdCngCom->CLDFBpsize_inv, &msPeriodog[nFFTpart] );
     437             :     }
     438             : 
     439             :     /* Compress MS inputs */
     440     1715402 :     compress_range( msPeriodog, msLogPeriodog, npart );
     441             : 
     442             :     /* Call the minimum statistics routine for noise estimation */
     443     2675656 :     minimum_statistics( npart, nFFTpart, psize, msLogPeriodog, hFdCngEnc->msNoiseFloor, msLogNoiseEst, hFdCngEnc->msAlpha, hFdCngEnc->msPsd, hFdCngEnc->msPsdFirstMoment, hFdCngEnc->msPsdSecondMoment, hFdCngEnc->msMinBuf, hFdCngEnc->msBminWin, hFdCngEnc->msBminSubWin, hFdCngEnc->msCurrentMin, hFdCngEnc->msCurrentMinOut, hFdCngEnc->msCurrentMinSubWindow, hFdCngEnc->msLocalMinFlag, hFdCngEnc->msNewMinFlag, hFdCngEnc->msPeriodogBuf, &( hFdCngEnc->msPeriodogBufPtr ), hFdCngEnc->hFdCngCom,
     444      960254 :                         ENC, ( hCPE == NULL ) ? 0 : hCPE->element_mode );
     445             : 
     446             :     /* Expand MS outputs */
     447     1715402 :     expand_range( msLogNoiseEst, msNoiseEst, npart );
     448             : 
     449     1715402 :     return;
     450             : }
     451             : 
     452             : 
     453             : /*-------------------------------------------------------------------*
     454             :  * AdjustFirstSID()
     455             :  *
     456             :  * Adjust the noise estimator at the beginning of each CNG phase (encoder-side)
     457             :  *-------------------------------------------------------------------*/
     458             : 
     459     1645788 : void AdjustFirstSID(
     460             :     Encoder_State *st /* i/o: encoder state structure     */
     461             : )
     462             : {
     463             :     float lambda;
     464             :     int16_t i;
     465     1645788 :     int16_t npart = st->hFdCngEnc->hFdCngCom->npart;
     466     1645788 :     float *msPeriodog = st->hFdCngEnc->msPeriodog;
     467     1645788 :     float *energy_ho = st->hFdCngEnc->energy_ho;
     468     1645788 :     float *msNoiseEst = st->hFdCngEnc->msNoiseEst;
     469     1645788 :     float *msNoiseEst_old = st->hFdCngEnc->msNoiseEst_old;
     470     1645788 :     int16_t *active_frame_counter = &( st->hFdCngEnc->hFdCngCom->active_frame_counter );
     471             : 
     472     1645788 :     if ( st->hDtxEnc->cnt_SID == 1 && st->last_core_brate > SID_2k40 )
     473             :     {
     474             :         /* Detect the hangover period and the first SID frame at the beginning of each CNG phase */
     475             : 
     476             :         /* Average input energy over hangover period */
     477       31094 :         mvr2r( msPeriodog, energy_ho, npart ); /*First hangover frame*/
     478             :         /* Set first SID to current input level but add some smoothing */
     479       31094 :         lambda = (float) pow( 0.96f, (float) ( *active_frame_counter + 1 ) );
     480       31094 :         v_multc( msNoiseEst_old, lambda, msNoiseEst_old, npart );
     481       31094 :         v_multc( energy_ho, 1 - lambda, energy_ho, npart );
     482             : 
     483       31094 :         v_add( msNoiseEst_old, energy_ho, energy_ho, npart );
     484      770653 :         for ( i = 0; i < npart; i++ )
     485             :         {
     486      739559 :             if ( msNoiseEst[i] > energy_ho[i] )
     487             :             {
     488      658731 :                 msNoiseEst[i] = energy_ho[i];
     489             :             }
     490             :         }
     491       31094 :         *active_frame_counter = 0;
     492             :     }
     493             : 
     494     1645788 :     if ( st->core_brate != SID_2k40 && st->core_brate != FRAME_NO_DATA )
     495             :     {
     496     1448088 :         ( *active_frame_counter )++; /* Count the number of active frames in a row */
     497             :     }
     498             :     else
     499             :     {
     500      197700 :         mvr2r( msNoiseEst, msNoiseEst_old, npart ); /* Store the noise estimate obtained in the CNG phases */
     501             :     }
     502             : 
     503     1645788 :     return;
     504             : }
     505             : 
     506             : /*-------------------------------------------------------------------*
     507             :  * FdCng_encodeSID()
     508             :  *
     509             :  * Generate a bitstream out of the partition levels
     510             :  *-------------------------------------------------------------------*/
     511             : 
     512        6274 : void FdCng_encodeSID(
     513             :     Encoder_State *st /* i/o: encoder state structure     */
     514             : )
     515             : {
     516             :     int16_t N;
     517        6274 :     HANDLE_FD_CNG_ENC hFdCngEnc = st->hFdCngEnc;
     518        6274 :     HANDLE_FD_CNG_COM hFdCngCom = hFdCngEnc->hFdCngCom;
     519        6274 :     BSTR_ENC_HANDLE hBstr = st->hBstr;
     520        6274 :     float *E = hFdCngEnc->msNoiseEst;
     521             :     float gain;
     522             :     int16_t i, index;
     523             :     float v[32], e;
     524             :     int16_t indices[32];
     525             :     float w[32];
     526        6274 :     float preemph_fac = st->preemph_fac;
     527             : 
     528             :     float *invTrfMatrix;
     529             :     float tmpRAM[FDCNG_VQ_MAX_LEN][FDCNG_VQ_DCT_MAXTRUNC];
     530             :     float dct_target[FDCNG_VQ_DCT_MAXTRUNC];
     531             :     float tot_sig_ext[FDCNG_VQ_MAX_LEN];
     532        6274 :     const float gain_q_offset = ( st->element_mode == EVS_MONO ) ? GAIN_Q_OFFSET_EVS : GAIN_Q_OFFSET_IVAS;
     533             : 
     534             :     /* Init */
     535        6274 :     N = hFdCngEnc->npartDec;
     536             : 
     537        6274 :     invTrfMatrix = (float *) tmpRAM; /* dynamically filled  */
     538        6274 :     set_zero( v, FDCNG_VQ_MAX_LEN );
     539             : 
     540             :     /* Convert to LOG */
     541        6274 :     e = 0.f;
     542      152701 :     for ( i = 0; i < N; i++ )
     543             :     {
     544      146427 :         v[i] = 10.f * (float) log10( E[i] + 1e-4f );
     545      146427 :         e += v[i];
     546             :     }
     547             : 
     548             :     /* Normalize MSVQ input */
     549        6274 :     gain = 0.f;
     550       87836 :     for ( i = N_GAIN_MIN; i < N_GAIN_MAX; i++ )
     551             :     {
     552       81562 :         gain += v[i];
     553             :     }
     554             : 
     555        6274 :     gain /= (float) ( N_GAIN_MAX - N_GAIN_MIN );
     556             : 
     557      152701 :     for ( i = 0; i < N; i++ )
     558             :     {
     559      146427 :         v[i] -= gain;
     560             :     }
     561             : 
     562             :     /* MSVQ encoder */
     563        6274 :     set_f( w, 1.0f, N );
     564             : 
     565        6274 :     if ( st->element_mode != EVS_MONO )
     566             :     {
     567             :         /* DCT domain compressed/truncated indices used for first stage  */
     568             :         /*  quantization with stage1 stored in DCT24 domain,   stages 2 through 6 directly dearched
     569             :            in FDCNG band domain
     570             :         */
     571        6053 :         if ( N == FDCNG_VQ_MAX_LEN_WB )
     572             :         {
     573         989 :             create_IDCT_N_Matrix( invTrfMatrix, N, FDCNG_VQ_DCT_MAXTRUNC, sizeof( tmpRAM ) / ( sizeof( float ) ) );
     574             :             /* truncated DCT21 analysis */
     575         989 :             dctT2_N_apply_matrix( (const float *) v, dct_target, FDCNG_VQ_DCT_MAXTRUNC, N, invTrfMatrix, FDCNG_VQ_DCT_MAXTRUNC, DCT_T2_21_XX );
     576             :             /* truncated IDCT21 extension to 24 bands  */
     577         989 :             extend_dctN_input( v, dct_target, N, tot_sig_ext, FDCNG_VQ_MAX_LEN, invTrfMatrix, FDCNG_VQ_DCT_MAXTRUNC, IDCT_T2_XX_21 );
     578             : 
     579         989 :             mvr2r( tot_sig_ext, v, FDCNG_VQ_MAX_LEN ); /*  write  extended result as input to  VQ stage #1 */
     580             :         }
     581        6053 :         create_IDCT_N_Matrix( invTrfMatrix, FDCNG_VQ_MAX_LEN, FDCNG_VQ_DCT_MAXTRUNC, sizeof( tmpRAM ) / ( sizeof( float ) ) );
     582        6053 :         msvq_enc( cdk_37bits_ivas, NULL, NULL, v, levels_37bits, FD_CNG_maxC_37bits, FD_CNG_stages_37bits, w, N, FD_CNG_maxN_37bits, 1, invTrfMatrix, indices );
     583        6053 :         msvq_dec( cdk_37bits_ivas, NULL, NULL, FD_CNG_stages_37bits, N, FD_CNG_maxN_37bits, indices, 1, invTrfMatrix, v, NULL );
     584             :     }
     585             :     else
     586             :     { /* EVS_MONO tables */
     587         221 :         msvq_enc( cdk_37bits, NULL, NULL, v, levels_37bits, FD_CNG_maxC_37bits, FD_CNG_stages_37bits, w, N, FD_CNG_maxN_37bits, 0, NULL, indices );
     588         221 :         msvq_dec( cdk_37bits, NULL, NULL, FD_CNG_stages_37bits, N, FD_CNG_maxN_37bits, indices, 0, NULL, v, NULL );
     589             :     }
     590             : 
     591             : 
     592             :     /* Compute gain */
     593        6274 :     gain = 0.f;
     594      152701 :     for ( i = 0; i < N; i++ )
     595             :     {
     596      146427 :         gain += v[i];
     597             :     }
     598             : 
     599        6274 :     gain = ( e - gain ) / (float) N;
     600             : 
     601             :     /* Apply bitrate-dependant scale */
     602        6274 :     if ( st->element_mode > EVS_MONO )
     603             :     {
     604        6053 :         apply_scale( &gain, hFdCngCom->CngBandwidth, hFdCngCom->CngBitrate, scaleTableStereo, SIZE_SCALE_TABLE_STEREO );
     605             :     }
     606             :     else
     607             :     {
     608         221 :         apply_scale( &gain, hFdCngCom->CngBandwidth, hFdCngCom->CngBitrate, scaleTableMono, SIZE_SCALE_TABLE_MONO );
     609             :     }
     610             : 
     611             :     /* Quantize gain */
     612        6274 :     index = (int16_t) floor( gain * 1.5f + gain_q_offset + 0.5f );
     613             : 
     614        6274 :     if ( index < 0 )
     615             :     {
     616         872 :         index = 0;
     617             :     }
     618             : 
     619        6274 :     if ( index > 127 )
     620             :     {
     621           0 :         index = 127;
     622             :     }
     623             : 
     624        6274 :     gain = ( (float) index - gain_q_offset ) / 1.5f;
     625             : 
     626             :     /* Apply gain and undo log */
     627      152701 :     for ( i = 0; i < N; i++ )
     628             :     {
     629             : 
     630      146427 :         hFdCngCom->sidNoiseEst[i] = (float) pow( 10.f, ( v[i] + gain ) / 10.f );
     631             :     }
     632             : 
     633             :     /* NB last band energy compensation */
     634        6274 :     if ( hFdCngCom->CngBandwidth == NB )
     635             :     {
     636         121 :         hFdCngCom->sidNoiseEst[N - 1] *= NB_LAST_BAND_SCALE;
     637             :     }
     638             : 
     639        6274 :     if ( hFdCngCom->CngBandwidth == SWB && hFdCngCom->CngBitrate <= ACELP_13k20 )
     640             :     {
     641        2094 :         hFdCngCom->sidNoiseEst[N - 1] *= SWB_13k2_LAST_BAND_SCALE;
     642             :     }
     643             : 
     644             :     /* Write bitstream */
     645        6274 :     if ( st->codec_mode == MODE2 )
     646             :     {
     647         532 :         for ( i = 0; i < FD_CNG_stages_37bits; i++ )
     648             :         {
     649         456 :             push_next_indice( hBstr, indices[i], bits_37bits[i] );
     650             :         }
     651             : 
     652          76 :         push_next_indice( hBstr, index, 7 );
     653             :     }
     654             :     else
     655             :     {
     656        6198 :         push_indice( hBstr, IND_SID_TYPE, 1, 1 );
     657        6198 :         push_indice( hBstr, IND_BWIDTH, st->bwidth, 2 );
     658        6198 :         push_indice( hBstr, IND_ACELP_16KHZ, st->L_frame == L_FRAME16k ? 1 : 0, 1 );
     659             : 
     660       43386 :         for ( i = 0; i < FD_CNG_stages_37bits; i++ )
     661             :         {
     662       37188 :             push_indice( hBstr, IND_LSF, indices[i], bits_37bits[i] );
     663             :         }
     664             : 
     665        6198 :         push_indice( hBstr, IND_ENERGY, index, 7 );
     666             :     }
     667             : 
     668             :     /* Interpolate the bin/band-wise levels from the partition levels */
     669        6274 :     scalebands( hFdCngCom->sidNoiseEst, hFdCngEnc->partDec, hFdCngEnc->npartDec, hFdCngEnc->midbandDec, hFdCngEnc->nFFTpartDec, hFdCngEnc->stopBandDec - hFdCngEnc->startBandDec, hFdCngCom->cngNoiseLevel, 1 );
     670             : 
     671        6274 :     lpc_from_spectrum( hFdCngCom, hFdCngEnc->startBandDec, hFdCngEnc->stopFFTbinDec, preemph_fac );
     672             : 
     673        6274 :     return;
     674             : }
     675             : 
     676             : 
     677             : /*-------------------------------------------------------------------*
     678             :  * generate_comfort_noise_enc()
     679             :  *
     680             :  *
     681             :  *-------------------------------------------------------------------*/
     682             : 
     683       40405 : void generate_comfort_noise_enc(
     684             :     Encoder_State *st /* i/o: encoder state structure     */
     685             : )
     686             : {
     687             :     int16_t i;
     688             :     float *ptr_r;
     689             :     float *ptr_i;
     690       40405 :     HANDLE_FD_CNG_ENC hFdCngEnc = st->hFdCngEnc;
     691       40405 :     HANDLE_FD_CNG_COM hFdCngCom = hFdCngEnc->hFdCngCom;
     692       40405 :     float *cngNoiseLevel = hFdCngCom->cngNoiseLevel;
     693       40405 :     float *ptr_level = cngNoiseLevel;
     694       40405 :     int16_t *seed = &( hFdCngCom->seed );
     695       40405 :     float scale = 1.f;
     696       40405 :     float *fftBuffer = hFdCngCom->fftBuffer;
     697       40405 :     float *timeDomainOutput = hFdCngCom->timeDomainBuffer;
     698       40405 :     float preemph_fac = st->preemph_fac;
     699       40405 :     int16_t tcx_transition = 0;
     700             :     float enr;
     701             : 
     702             :     /* Generate Gaussian random noise in real and imaginary parts of the FFT bins
     703             :       Amplitudes are adjusted to the estimated noise level cngNoiseLevel in each bin */
     704       40405 :     if ( hFdCngEnc->startBandDec == 0 )
     705             :     {
     706           0 :         rand_gauss( &fftBuffer[0], seed );
     707           0 :         fftBuffer[0] *= (float) sqrt( scale * *ptr_level ); /* DC component in FFT */
     708           0 :         ptr_level++;
     709           0 :         ptr_r = fftBuffer + 2;
     710             :     }
     711             :     else
     712             :     {
     713       40405 :         fftBuffer[0] = 0.f;
     714       40405 :         set_f( fftBuffer + 2, 0.0f, 2 * ( hFdCngEnc->startBandDec - 1 ) );
     715       40405 :         ptr_r = fftBuffer + 2 * hFdCngEnc->startBandDec;
     716             :     }
     717             : 
     718       40405 :     ptr_i = ptr_r + 1;
     719    11575531 :     for ( ; ptr_level < cngNoiseLevel + hFdCngEnc->stopFFTbinDec - hFdCngEnc->startBandDec; ptr_level++ )
     720             :     {
     721             :         /* Real part in FFT bins */
     722    11535126 :         rand_gauss( ptr_r, seed );
     723    11535126 :         ( *ptr_r ) *= (float) sqrt( ( scale * *ptr_level ) * 0.5f );
     724    11535126 :         ptr_r += 2;
     725             :         /* Imaginary part in FFT bins */
     726    11535126 :         rand_gauss( ptr_i, seed );
     727    11535126 :         ( *ptr_i ) *= (float) sqrt( ( scale * *ptr_level ) * 0.5f );
     728    11535126 :         ptr_i += 2;
     729             :     }
     730             : 
     731             :     /* Remaining FFT bins are set to zero */
     732       40405 :     set_f( fftBuffer + 2 * hFdCngEnc->stopFFTbinDec, 0.0f, hFdCngCom->fftlen - 2 * hFdCngEnc->stopFFTbinDec );
     733             : 
     734             :     /* Nyquist frequency is discarded */
     735       40405 :     fftBuffer[1] = 0.f;
     736             : 
     737             :     /* If previous frame is active, reset the overlap-add buffer */
     738       40405 :     if ( st->last_core_brate > SID_2k40 )
     739             :     {
     740        2084 :         set_f( hFdCngCom->olapBufferSynth, 0.0f, hFdCngCom->fftlen );
     741             : 
     742        2084 :         if ( ( st->last_core > ACELP_CORE && st->codec_mode == MODE2 ) || st->codec_mode == MODE1 )
     743             :         {
     744        2064 :             tcx_transition = 1;
     745             :         }
     746             :     }
     747             : 
     748             :     /* Perform STFT synthesis */
     749       40405 :     SynthesisSTFT( fftBuffer, timeDomainOutput, hFdCngCom->olapBufferSynth, hFdCngCom->olapWinSyn, tcx_transition, hFdCngCom, -1, -1 );
     750             : 
     751       40405 :     if ( st->hTdCngEnc != NULL )
     752             :     {
     753             :         /* update CNG excitation energy for LP_CNG */
     754             :         /* calculate the residual signal energy */
     755       28499 :         enr = cng_energy( st->element_mode, st->bwidth, st->hDtxEnc->CNG_mode, st->hTdCngEnc->CNG_att, hFdCngCom->exc_cng, hFdCngCom->frameSize );
     756             : 
     757       28499 :         st->hTdCngEnc->lp_ener = (float) ( 0.8f * st->hTdCngEnc->lp_ener + 0.2f * pow( 2.0f, enr ) );
     758             :     }
     759             : 
     760             :     /* Overlap-add when previous frame is active */
     761       40405 :     if ( st->last_core_brate > SID_2k40 && st->codec_mode == MODE2 )
     762             :     {
     763          22 :         float noise[2048], old_exc_ener = 0.f, gain = 0.f, tmp;
     764          22 :         int16_t N = hFdCngCom->frameSize;
     765          22 :         int16_t seed_loc = hFdCngCom->seed;
     766             :         float *old_exc, old_Aq[M + 1], *old_syn_pe, old_syn;
     767             : 
     768          22 :         if ( st->last_core > ACELP_CORE )
     769             :         {
     770           4 :             tcx_windowing_synthesis_current_frame( timeDomainOutput, st->hTcxCfg->tcx_mdct_window, /*Keep sine windows for limiting Time modulation*/
     771           6 :                                                    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 );
     772             : 
     773           2 :             if ( st->hTcxCfg->last_aldo )
     774             :             {
     775         514 :                 for ( i = 0; i < hFdCngCom->frameSize; i++ )
     776             :                 {
     777         512 :                     timeDomainOutput[i] += st->hTcxEnc->old_out[i + NS2SA( st->sr_core, N_ZERO_MDCT_NS )];
     778             :                 }
     779             :             }
     780             :             else
     781             :             {
     782           0 :                 tcx_windowing_synthesis_past_frame( st->hTcxEnc->Txnq, st->hTcxCfg->tcx_aldo_window_1_trunc, 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 );
     783             : 
     784           0 :                 for ( i = 0; i < st->hTcxCfg->tcx_mdct_window_length; i++ )
     785             :                 {
     786           0 :                     timeDomainOutput[i] += st->hTcxEnc->Txnq[i];
     787             :                 }
     788             :             }
     789             :         }
     790             :         else
     791             :         {
     792          20 :             lsp2a_stab( st->lsp_old, old_Aq, M );
     793          20 :             old_exc = st->hLPDmem->old_exc + L_EXC_MEM - ( N / 2 );
     794          20 :             old_syn_pe = st->hLPDmem->mem_syn2;
     795          20 :             old_syn = st->hLPDmem->syn[M];
     796        2580 :             for ( i = 0; i < N / 2; i++ )
     797             :             {
     798        2560 :                 old_exc_ener += old_exc[i] * old_exc[i];
     799             :             }
     800             : 
     801          20 :             old_exc_ener = (float) sqrt( old_exc_ener / (float) ( N / 2 ) );
     802             : 
     803        5140 :             for ( i = 0; i < N; i++ )
     804             :             {
     805        5120 :                 rand_gauss( &( noise[i] ), &( seed_loc ) );
     806        5120 :                 gain += noise[i] * noise[i];
     807             :             }
     808             : 
     809          20 :             gain = old_exc_ener / (float) sqrt( gain / (float) N );
     810             : 
     811        5140 :             for ( i = 0; i < N; i++ )
     812             :             {
     813        5120 :                 noise[i] *= gain;
     814             :             }
     815             : 
     816          20 :             syn_filt( old_Aq, M, noise, noise, N, old_syn_pe, 0 );
     817             : 
     818          20 :             tmp = old_syn;
     819             : 
     820          20 :             deemph( noise, preemph_fac, N, &tmp );
     821             : 
     822        2580 :             for ( i = 0; i < N / 2; i++ )
     823             :             {
     824        2560 :                 timeDomainOutput[i] += noise[i] * hFdCngCom->olapWinSyn[N / 2 + i];
     825             :             }
     826             :         }
     827             :     }
     828             : 
     829       40405 :     return;
     830             : }
     831             : 
     832             : /*-------------------------------------------------------------------*
     833             :  * cng_energy()
     834             :  *
     835             :  *
     836             :  *-------------------------------------------------------------------*/
     837             : 
     838             : /*! r: CNG energy */
     839       32688 : float cng_energy(
     840             :     const int16_t element_mode, /* i  : element mode                */
     841             :     const int16_t bwidth,       /* i  : audio bandwidh              */
     842             :     const int16_t CNG_mode,     /* i  : mode for DTX configuration  */
     843             :     const float CNG_att,        /* i  : attenuation factor for CNG  */
     844             :     const float *exc,           /* i  : input signal                */
     845             :     const int16_t len           /* i  : vector length               */
     846             : )
     847             : {
     848             :     float enr, att;
     849             : 
     850             :     /* calculate the residual signal energy */
     851       32688 :     enr = dotp( exc, exc, len ) / len;
     852             : 
     853             :     /* convert log2 of residual signal energy */
     854       32688 :     enr = (float) log10( enr + 0.1f ) / (float) log10( 2.0f );
     855             : 
     856             :     /* decrease the energy in case of WB input */
     857       32688 :     if ( element_mode == IVAS_CPE_DFT || element_mode == IVAS_CPE_TD )
     858             :     {
     859       24236 :         enr += CNG_att * FAC_LOG2 / 10.0f;
     860             :     }
     861        8452 :     else if ( bwidth != NB )
     862             :     {
     863        7379 :         if ( bwidth == WB )
     864             :         {
     865        2229 :             if ( CNG_mode >= 0 )
     866             :             {
     867             :                 /* Bitrate adapted attenuation */
     868           3 :                 att = ENR_ATT[CNG_mode];
     869             :             }
     870             :             else
     871             :             {
     872             :                 /* Use least attenuation for higher bitrates */
     873        2226 :                 att = ENR_ATT[4];
     874             :             }
     875             :         }
     876             :         else
     877             :         {
     878        5150 :             att = 1.5f;
     879             :         }
     880        7379 :         enr -= att;
     881             :     }
     882             : 
     883       32688 :     return ( enr );
     884             : }
     885             : 
     886             : 
     887             : /*-------------------------------------------------------------------*
     888             :  * stereoFdCngCoherence()
     889             :  *
     890             :  * compute coherence of channels for use in FD-CNG
     891             :  *-------------------------------------------------------------------*/
     892             : 
     893      331242 : void stereoFdCngCoherence(
     894             :     Encoder_State **sts,                    /* i/o: core encoder structures          */
     895             :     const int16_t last_element_mode,        /* i  : last element mode                */
     896             :     float fft_buff[CPE_CHANNELS][2 * L_FFT] /* i  : fft buffers for L and R channels */
     897             : )
     898             : {
     899             :     const float *pt_fftL, *pt_fftR;
     900             :     int16_t i_subfr, i;
     901             :     float cr, ci, eL, eR;
     902             :     float *mem;
     903             : 
     904      331242 :     if ( last_element_mode != IVAS_CPE_MDCT )
     905             :     {
     906             : #ifdef NONBE_MDCT_ST_DTX_FIX_SUBOPT_SPATIAL_CNG
     907        3198 :         for ( i = 0; i < MDCT_ST_DTX_NUM_COHERENCE_BANDS; i++ )
     908             :         {
     909        2665 :             set_f( sts[0]->hFdCngEnc->mem_coherence[i], EPSILON, 4 );
     910             :         }
     911             : #else
     912             :         set_f( sts[0]->hFdCngEnc->mem_coherence, EPSILON, 4 );
     913             : #endif
     914             :     }
     915             : 
     916      331242 :     if ( sts[0]->core_brate == -1 || sts[1]->core_brate == -1 )
     917             :     {
     918             :         /* case: at least one channel has triggered VAD -> ACTIVE FRAME */
     919      321802 :         if ( sts[0]->core_brate == -1 )
     920             :         {
     921      317676 :             sts[1]->total_brate = sts[0]->total_brate;
     922      317676 :             sts[1]->active_cnt = sts[0]->active_cnt;
     923      317676 :             if ( sts[1]->active_cnt >= CNG_TYPE_HO )
     924             :             {
     925      311196 :                 sts[1]->last_total_brate_cng = -1;
     926             :             }
     927             :         }
     928      321802 :         if ( sts[1]->core_brate == -1 )
     929             :         {
     930      311943 :             sts[0]->total_brate = sts[1]->total_brate;
     931      311943 :             sts[0]->active_cnt = sts[1]->active_cnt;
     932      311943 :             if ( sts[0]->active_cnt >= CNG_TYPE_HO )
     933             :             {
     934      305696 :                 sts[0]->last_total_brate_cng = -1;
     935             :             }
     936             :         }
     937      321802 :         sts[0]->core_brate = -1;
     938      321802 :         sts[1]->core_brate = -1;
     939      321802 :         sts[0]->hDtxEnc->cnt_SID = 0;
     940      321802 :         sts[1]->hDtxEnc->cnt_SID = 0;
     941             :     }
     942        9440 :     else if ( sts[0]->core_brate <= SID_2k40 && sts[1]->core_brate <= SID_2k40 )
     943             :     {
     944             :         /* case: no VAD for both channels -> INACTIVE FRAME */
     945        9440 :         reset_indices_enc( sts[0]->hBstr, sts[0]->hBstr->nb_ind_tot );
     946             : 
     947        9440 :         reset_indices_enc( sts[1]->hBstr, sts[1]->hBstr->nb_ind_tot );
     948             : 
     949             :         /* synchronize SID sending for variable SID rate */
     950        9440 :         if ( sts[0]->core_brate != sts[1]->core_brate )
     951             :         {
     952           0 :             sts[0]->core_brate = SID_2k40;
     953           0 :             sts[1]->core_brate = SID_2k40;
     954             :         }
     955             : 
     956             :         /* synchronize SID counters */
     957        9440 :         sts[0]->hDtxEnc->cnt_SID = min( sts[0]->hDtxEnc->cnt_SID, sts[1]->hDtxEnc->cnt_SID );
     958        9440 :         sts[1]->hDtxEnc->cnt_SID = sts[0]->hDtxEnc->cnt_SID;
     959             :     }
     960             : 
     961      331242 :     pt_fftL = fft_buff[0];
     962      331242 :     pt_fftR = fft_buff[1];
     963             : #ifndef NONBE_MDCT_ST_DTX_FIX_SUBOPT_SPATIAL_CNG
     964             :     mem = sts[0]->hFdCngEnc->mem_coherence;
     965             : #endif
     966             : 
     967             :     /* only estimate coherence in inactive frames (or in the first 50 frames to build an initial value) */
     968      331242 :     if ( !( sts[0]->ini_frame <= 50 || ( sts[0]->vad_flag == 0 && sts[1]->vad_flag == 0 ) ) )
     969             :     {
     970      293677 :         return;
     971             :     }
     972             : 
     973             : #ifdef NONBE_MDCT_ST_DTX_FIX_SUBOPT_SPATIAL_CNG
     974      112695 :     for ( i_subfr = 0; i_subfr < 2; i_subfr++ )
     975             :     {
     976             :         int16_t band_len_cum;
     977             : 
     978       75130 :         band_len_cum = 0;
     979       75130 :         i = MDCT_ST_DTX_FIRST_BAND_OFFSET;
     980             : 
     981      450780 :         for ( int16_t b = 0; b < MDCT_ST_DTX_NUM_COHERENCE_BANDS; b++ )
     982             :         {
     983      375650 :             band_len_cum += mdct_stereo_dtx_coherence_bandlengths[b];
     984      375650 :             cr = ci = eL = eR = EPSILON;
     985      375650 :             mem = sts[0]->hFdCngEnc->mem_coherence[b];
     986             : 
     987             :             /* for last band, we need to make adjustments to fit with the FFT buffer layout */
     988             :             /* do the calculations for fftbin 0 (not anymore as it is skipped - we only calculate coherence above the 2nd bin) and L_FFT/2 outside the loop - imaginary part is always zero there, but not part of the buffer */
     989      375650 :             if ( b == MDCT_ST_DTX_NUM_COHERENCE_BANDS - 1 )
     990             :             {
     991             :                 /* this calculates values for fft bin at L_FFT/2 - no imaginary value there, not even part of the array */
     992       75130 :                 cr += pt_fftL[L_FFT / 2] * pt_fftR[L_FFT / 2];
     993       75130 :                 eL += pt_fftL[L_FFT / 2] * pt_fftL[L_FFT / 2];
     994       75130 :                 eR += pt_fftR[L_FFT / 2] * pt_fftR[L_FFT / 2];
     995             : 
     996             :                 /* skip last fft bin (fs/2 Hz) bin in the loop later */
     997       75130 :                 --band_len_cum;
     998             :             }
     999             : 
    1000     9616640 :             for ( ; i < band_len_cum; i++ )
    1001             :             {
    1002     9240990 :                 cr += pt_fftL[i] * pt_fftR[i] + pt_fftL[L_FFT - i] * pt_fftR[L_FFT - i];
    1003     9240990 :                 ci += -pt_fftL[i] * pt_fftR[L_FFT - i] + pt_fftR[i] * pt_fftL[L_FFT - i];
    1004     9240990 :                 eL += pt_fftL[i] * pt_fftL[i] + pt_fftL[L_FFT - i] * pt_fftL[L_FFT - i];
    1005     9240990 :                 eR += pt_fftR[i] * pt_fftR[i] + pt_fftR[L_FFT - i] * pt_fftR[L_FFT - i];
    1006             :             }
    1007             : 
    1008      375650 :             mem[0] = 0.95f * mem[0] + 0.05f * cr;
    1009      375650 :             mem[1] = 0.95f * mem[1] + 0.05f * ci;
    1010      375650 :             mem[2] = 0.95f * mem[2] + 0.05f * eL;
    1011      375650 :             mem[3] = 0.95f * mem[3] + 0.05f * eR;
    1012             : 
    1013             :             /* could be done outside the loop, as the second assignment overwrites the first, but this would mean a second loop over bands */
    1014      375650 :             sts[0]->hFdCngEnc->hFdCngCom->coherence[b] = sqrtf( ( mem[0] * mem[0] + mem[1] * mem[1] ) / ( mem[2] * mem[3] ) );
    1015             :         }
    1016             : 
    1017       75130 :         pt_fftL += L_FFT;
    1018       75130 :         pt_fftR += L_FFT;
    1019             :     }
    1020             : 
    1021             : #else
    1022             :     for ( i_subfr = 0; i_subfr < 2; i_subfr++ )
    1023             :     {
    1024             :         cr = ci = eL = eR = EPSILON;
    1025             : 
    1026             :         cr += pt_fftL[0] * pt_fftR[0] + pt_fftL[L_FFT / 2] * pt_fftR[L_FFT / 2];
    1027             :         eL += pt_fftL[0] * pt_fftL[0] + pt_fftL[L_FFT / 2] * pt_fftL[L_FFT / 2];
    1028             :         eR += pt_fftR[0] * pt_fftR[0] + pt_fftR[L_FFT / 2] * pt_fftR[L_FFT / 2];
    1029             : 
    1030             :         for ( i = 1; i < L_FFT / 2; i++ )
    1031             :         {
    1032             :             cr += pt_fftL[i] * pt_fftR[i] + pt_fftL[L_FFT - i] * pt_fftR[L_FFT - i];
    1033             :             ci += -pt_fftL[i] * pt_fftR[L_FFT - i] + pt_fftR[i] * pt_fftL[L_FFT - i];
    1034             :             eL += pt_fftL[i] * pt_fftL[i] + pt_fftL[L_FFT - i] * pt_fftL[L_FFT - i];
    1035             :             eR += pt_fftR[i] * pt_fftR[i] + pt_fftR[L_FFT - i] * pt_fftR[L_FFT - i];
    1036             :         }
    1037             : 
    1038             :         if ( sts[0]->ini_frame <= 50 || ( sts[0]->vad_flag == 0 && sts[1]->vad_flag == 0 ) )
    1039             :         {
    1040             :             mem[0] = 0.95f * mem[0] + 0.05f * cr;
    1041             :             mem[1] = 0.95f * mem[1] + 0.05f * ci;
    1042             :             mem[2] = 0.95f * mem[2] + 0.05f * eL;
    1043             :             mem[3] = 0.95f * mem[3] + 0.05f * eR;
    1044             :         }
    1045             : 
    1046             :         pt_fftL += L_FFT;
    1047             :         pt_fftR += L_FFT;
    1048             :     }
    1049             : #endif
    1050             : #ifndef NONBE_MDCT_ST_DTX_FIX_SUBOPT_SPATIAL_CNG
    1051             :     sts[0]->hFdCngEnc->hFdCngCom->coherence = sqrtf( ( mem[0] * mem[0] + mem[1] * mem[1] ) / ( mem[2] * mem[3] ) );
    1052             : #endif
    1053             : 
    1054       37565 :     return;
    1055             : }
    1056             : 
    1057             : 
    1058             : /*-------------------------------------------------------------------*
    1059             :  * FdCngEncodeMDCTStereoSID()
    1060             :  *
    1061             :  * Encode DTX parameters and noise shapes into SID for MDCT-Stereo DTX
    1062             :  *-------------------------------------------------------------------*/
    1063             : 
    1064        1111 : void FdCngEncodeMDCTStereoSID(
    1065             :     CPE_ENC_HANDLE hCPE /* i/o: CPE encoder state structure     */
    1066             : )
    1067             : {
    1068             :     ENC_CORE_HANDLE sts[CPE_CHANNELS];
    1069             :     float *lr_in_ptr[CPE_CHANNELS];
    1070             :     float *ms_ptr[CPE_CHANNELS];
    1071             :     float *lr_out_ptr[CPE_CHANNELS];
    1072             :     float logNoiseEst[CPE_CHANNELS][NPART];
    1073             :     float E[CPE_CHANNELS];
    1074             :     float gain[CPE_CHANNELS];
    1075             :     float weights[NPART];
    1076             :     int16_t indices[CPE_CHANNELS][FD_CNG_stages_37bits];
    1077             :     int16_t gain_idx[CPE_CHANNELS];
    1078             :     int16_t N, stages, ch, p, coh_idx;
    1079             :     float side_energy;
    1080             :     int16_t no_side_flag;
    1081             :     int16_t is_inp_ms;
    1082             : 
    1083             :     float tot_sig_ext[FDCNG_VQ_MAX_LEN], dct_target[CPE_CHANNELS][FDCNG_VQ_DCT_MAXTRUNC]; /* 24 +2*18*/
    1084             :     float *invTrfMatrix;
    1085             :     float tmpRAM[FDCNG_VQ_MAX_LEN][FDCNG_VQ_DCT_MAXTRUNC]; /*24*18*/
    1086        1111 :     invTrfMatrix = (float *) tmpRAM;                       /* dynamically filled  */
    1087             : 
    1088             : 
    1089        1111 :     is_inp_ms = 0;
    1090        1111 :     if ( hCPE->hCoreCoder[0]->cng_sba_flag == 1 )
    1091             :     {
    1092           0 :         is_inp_ms = 1;
    1093             :     }
    1094             : 
    1095             :     /* set pointers and initialize */
    1096        3333 :     for ( ch = 0; ch < CPE_CHANNELS; ch++ )
    1097             :     {
    1098        2222 :         sts[ch] = hCPE->hCoreCoder[ch];
    1099        2222 :         lr_in_ptr[ch] = &sts[ch]->hFdCngEnc->msNoiseEst[0];
    1100        2222 :         ms_ptr[ch] = &logNoiseEst[ch][0];
    1101        2222 :         lr_out_ptr[ch] = &sts[ch]->hFdCngEnc->hFdCngCom->sidNoiseEst[0];
    1102             :     }
    1103             : #ifdef DEBUGGING
    1104             :     assert( sts[0]->hFdCngEnc->npartDec == sts[1]->hFdCngEnc->npartDec );
    1105             : #endif
    1106        1111 :     N = sts[0]->hFdCngEnc->npartDec;
    1107        1111 :     set_f( weights, 1.f, NPART );
    1108             : 
    1109             :     /* apply log and save energy of original left and right channels */
    1110        3333 :     for ( ch = 0; ch < CPE_CHANNELS; ch++ )
    1111             :     {
    1112        2222 :         E[ch] = 0.0f;
    1113       52820 :         for ( p = 0; p < N; p++ )
    1114             :         {
    1115       50598 :             ms_ptr[ch][p] = 10.f * log10f( lr_in_ptr[ch][p] + EPSILON );
    1116       50598 :             E[ch] += ms_ptr[ch][p];
    1117             :         }
    1118             :     }
    1119             : 
    1120             :     /* M/S transform on log envelopes */
    1121        1111 :     if ( is_inp_ms == 0 )
    1122             :     {
    1123        1111 :         convertToMS( N, ms_ptr[0], ms_ptr[1], 0.5f );
    1124             :     }
    1125             : 
    1126        1111 :     side_energy = sum2_f( ms_ptr[1], N );
    1127             : 
    1128             :     /* do not transmit side shape if initial noise shapes are very similar */
    1129        1111 :     if ( side_energy <= 0.1f )
    1130             :     {
    1131          37 :         no_side_flag = 1;
    1132             :     }
    1133             :     else
    1134             :     {
    1135        1074 :         no_side_flag = 0;
    1136             :     }
    1137             : 
    1138             :     /* Quantize noise shapes */
    1139        3333 :     for ( ch = 0; ch < CPE_CHANNELS; ch++ )
    1140             :     {
    1141             :         /* Normalize MSVQ input */
    1142        2222 :         gain[ch] = 0.f;
    1143       31108 :         for ( p = N_GAIN_MIN; p < N_GAIN_MAX; p++ )
    1144             :         {
    1145       28886 :             gain[ch] += ms_ptr[ch][p];
    1146             :         }
    1147        2222 :         gain[ch] /= (float) ( N_GAIN_MAX - N_GAIN_MIN );
    1148             : 
    1149       52820 :         for ( p = 0; p < N; p++ )
    1150             :         {
    1151       50598 :             ms_ptr[ch][p] -= gain[ch];
    1152             :         }
    1153             :     }
    1154             :     /* always split channel targetloop */
    1155             : 
    1156             :     /* extend fdcng envelope from length 21 to a 24 length fdncg domain envelope signal */
    1157             :     /* High quality cosine smooth basis extension used  to not introduce noise in stage#1  DCT24 analysis and subsequent VQ-steps */
    1158        1111 :     if ( N == FDCNG_VQ_MAX_LEN_WB )
    1159             :     {
    1160         455 :         create_IDCT_N_Matrix( invTrfMatrix, N, FDCNG_VQ_DCT_MAXTRUNC, sizeof( tmpRAM ) / ( sizeof( float ) ) ); /*WB: create truncated IDCT21 matrix */
    1161             : 
    1162        1365 :         for ( ch = 0; ch < CPE_CHANNELS; ch++ )
    1163             :         {
    1164             :             /* run DCT_N N==21 , truncated at 18/21 ~= 86% , i.e use a bit better better quality in extrapolation , than subsequent DCT24 analysis which is truncated at 75%*/
    1165             : 
    1166             :             /* truncated DCT 21 analysis */
    1167         910 :             dctT2_N_apply_matrix( (const float *) ms_ptr[ch], dct_target[ch], FDCNG_VQ_DCT_MAXTRUNC, N, invTrfMatrix, FDCNG_VQ_DCT_MAXTRUNC, DCT_T2_21_XX );
    1168             : 
    1169             :             /* extrapolate extend fdcng envelope signal in the fdncg ienvelope/"time" domain using DCT21 basis vectors,
    1170             :                 estimated DCT21 coeffs scaling extended basis vectors are used to create extrapolated   length 24 input target envelope signal */
    1171             :             /* this DCT21 extension does not introduce DCT24 coefficient noise for  the subsequent dct24 target analysis, and later in IDCT24 synthesis  */
    1172             : 
    1173             :             /* truncated IDCT 21 extension synthesis  */
    1174         910 :             extend_dctN_input( ms_ptr[ch], dct_target[ch], N, tot_sig_ext, FDCNG_VQ_MAX_LEN, invTrfMatrix /* DCT_N basis vectors */, FDCNG_VQ_DCT_MAXTRUNC, IDCT_T2_XX_21 ); /* use 18 basis vectors*/
    1175             : 
    1176         910 :             mvr2r( tot_sig_ext, ms_ptr[ch], FDCNG_VQ_MAX_LEN ); /*  write  extended result as input to  VQ */
    1177             :         }
    1178             :     }
    1179        1111 :     create_IDCT_N_Matrix( invTrfMatrix, FDCNG_VQ_MAX_LEN, FDCNG_VQ_DCT_MAXTRUNC, sizeof( tmpRAM ) / ( sizeof( float ) ) ); /*always create/set up  IDCT24 matrix in RAM */
    1180             : 
    1181             :     /* end split */
    1182        3333 :     for ( ch = 0; ch < CPE_CHANNELS; ch++ )
    1183             :     {
    1184             :         /* MSVQ */
    1185        2222 :         if ( ch )
    1186             :         {
    1187        1111 :             stages = FD_CNG_JOINT_stages_25bits;
    1188             :         }
    1189             :         else
    1190             :         {
    1191        1111 :             stages = FD_CNG_stages_37bits;
    1192             :         }
    1193             : 
    1194             :         /* DCT24 domain compressed/truncated indices used for first stage  */
    1195             :         /*             mid  channel quantization using stages 1 through 6 */
    1196             :         /*           & side channel quantization using stages 1 through 4 */
    1197             : 
    1198             :         {
    1199        2222 :             msvq_enc( cdk_37bits_ivas, NULL, NULL, ms_ptr[ch], levels_37bits, FD_CNG_maxC_37bits, stages, weights, N, FD_CNG_maxN_37bits, 1, invTrfMatrix, indices[ch] );
    1200        2222 :             msvq_dec( cdk_37bits_ivas, NULL, NULL, stages, N, FD_CNG_maxN_37bits, indices[ch], 1, invTrfMatrix, ms_ptr[ch], NULL );
    1201             :         }
    1202             :     }
    1203             : 
    1204        1111 :     if ( no_side_flag )
    1205             :     {
    1206          37 :         set_zero( ms_ptr[1], N );
    1207             :     }
    1208             : 
    1209             :     /* undo M/S */
    1210        1111 :     if ( is_inp_ms == 0 )
    1211             :     {
    1212        1111 :         convertToMS( N, ms_ptr[0], ms_ptr[1], 1.0f );
    1213             :     }
    1214             : 
    1215             :     /* Compute gain against original left and right channels */
    1216        3333 :     for ( ch = 0; ch < CPE_CHANNELS; ch++ )
    1217             :     {
    1218        2222 :         gain[ch] = 0.f;
    1219       52820 :         for ( p = 0; p < N; p++ )
    1220             :         {
    1221       50598 :             gain[ch] += ms_ptr[ch][p];
    1222             :         }
    1223        2222 :         gain[ch] = ( E[ch] - gain[ch] ) / (float) N;
    1224        2222 :         apply_scale( &gain[ch], sts[ch]->hFdCngEnc->hFdCngCom->CngBandwidth, sts[ch]->element_brate, scaleTableStereo, SIZE_SCALE_TABLE_STEREO );
    1225             : 
    1226             :         /* quantize gain */
    1227        2222 :         gain_idx[ch] = (int16_t) floor( gain[ch] * 1.5f + GAIN_Q_OFFSET_IVAS + .5f );
    1228        2222 :         gain_idx[ch] = max( 0, min( 127, gain_idx[ch] ) );
    1229             : 
    1230        2222 :         gain[ch] = ( (float) gain_idx[ch] - GAIN_Q_OFFSET_IVAS ) / 1.5f;
    1231             :     }
    1232             : 
    1233             :     /* restore channel noise envelopes */
    1234        3333 :     for ( ch = 0; ch < CPE_CHANNELS; ch++ )
    1235             :     {
    1236        2222 :         HANDLE_FD_CNG_ENC hFdCngEnc = sts[ch]->hFdCngEnc;
    1237        2222 :         HANDLE_FD_CNG_COM hFdCngCom = hFdCngEnc->hFdCngCom;
    1238             : 
    1239       52820 :         for ( p = 0; p < N; p++ )
    1240             :         {
    1241       50598 :             lr_out_ptr[ch][p] = powf( 10.f, ( ms_ptr[ch][p] + gain[ch] ) / 10.f );
    1242             :         }
    1243             : 
    1244             :         /* scale bands and get scalefactors */
    1245        2222 :         scalebands( lr_out_ptr[ch], hFdCngEnc->partDec, N, hFdCngEnc->midbandDec, hFdCngEnc->nFFTpartDec, hFdCngEnc->stopBandDec - hFdCngEnc->startBandDec, hFdCngCom->cngNoiseLevel, 1 );
    1246             : 
    1247        2222 :         lpc_from_spectrum( hFdCngCom, hFdCngEnc->startBandDec, hFdCngEnc->stopFFTbinDec, sts[ch]->preemph_fac );
    1248             : 
    1249        2222 :         sts[ch]->hDtxEnc->last_CNG_L_frame = sts[ch]->L_frame;
    1250             :     }
    1251             : 
    1252             :     /* quantize channel coherence */
    1253             : #ifdef NONBE_MDCT_ST_DTX_FIX_SUBOPT_SPATIAL_CNG
    1254        1111 :     coh_idx = (int16_t) floor( sts[0]->hFdCngEnc->hFdCngCom->coherence[0] * 15.f + 0.5f );
    1255             : #else
    1256             :     coh_idx = (int16_t) floor( sts[0]->hFdCngEnc->hFdCngCom->coherence * 15.f + 0.5f );
    1257             : #endif
    1258        1111 :     coh_idx = max( 0, min( coh_idx, 15 ) );
    1259             : 
    1260             :     /* ---- Write SID bitstream ---- */
    1261             : 
    1262             : 
    1263             :     /* noise shapes and channel gains */
    1264        3333 :     for ( ch = 0; ch < CPE_CHANNELS; ch++ )
    1265             :     {
    1266        2222 :         if ( ch )
    1267             :         {
    1268        1111 :             stages = FD_CNG_JOINT_stages_25bits;
    1269        1111 :             sts[ch]->hBstr->ind_list = sts[0]->hBstr->ind_list + sts[0]->hBstr->nb_ind_tot;
    1270             : 
    1271             :             /* side info */
    1272        1111 :             push_indice( sts[ch]->hBstr, IND_SID_TYPE, coh_idx, 4 );
    1273        1111 :             push_indice( sts[ch]->hBstr, IND_SID_TYPE, no_side_flag, 1 );
    1274             :         }
    1275             :         else
    1276             :         {
    1277        1111 :             stages = FD_CNG_stages_37bits;
    1278             :             /* side info */
    1279        1111 :             push_indice( sts[ch]->hBstr, IND_SID_TYPE, 1, 1 );
    1280        1111 :             push_indice( sts[ch]->hBstr, IND_BWIDTH, sts[0]->bwidth, 2 );
    1281        1111 :             push_indice( sts[ch]->hBstr, IND_ACELP_16KHZ, sts[0]->L_frame == L_FRAME16k ? 1 : 0, 1 );
    1282             :         }
    1283             : 
    1284       13332 :         for ( int16_t i = 0; i < stages; i++ )
    1285             :         {
    1286       11110 :             push_indice( sts[ch]->hBstr, IND_LSF, indices[ch][i], bits_37bits[i] );
    1287             :         }
    1288        2222 :         push_indice( sts[ch]->hBstr, IND_ENERGY, gain_idx[ch], 7 );
    1289             :     }
    1290             : 
    1291             : #ifdef NONBE_MDCT_ST_DTX_FIX_SUBOPT_SPATIAL_CNG
    1292             :     /* write the four additional coherence values */
    1293        5555 :     for ( int16_t b = 1; b < MDCT_ST_DTX_NUM_COHERENCE_BANDS; b++ )
    1294             :     {
    1295        4444 :         coh_idx = (int16_t) floor( sts[0]->hFdCngEnc->hFdCngCom->coherence[b] * 15.f + 0.5f );
    1296        4444 :         coh_idx = max( 0, min( coh_idx, 15 ) );
    1297        4444 :         push_indice( sts[1]->hBstr, IND_ENERGY, coh_idx, 4 );
    1298             :     }
    1299             : #else
    1300             :     /* pad with zeros to reach common SID frame size */
    1301             :     push_indice( sts[1]->hBstr, IND_ENERGY, 0, ( IVAS_SID_5k2 - 4400 ) / FRAMES_PER_SEC );
    1302             : #endif
    1303             : 
    1304             : 
    1305        1111 :     return;
    1306             : }
    1307             : 
    1308             : 
    1309             : /*-------------------------------------------------------------------*
    1310             :  * FdCngEncodeDiracMDCTStereoSID()
    1311             :  *
    1312             :  * Encode DTX parameters and noise shapes into SID for MDCT-Stereo DTX
    1313             :  * together with Dirac
    1314             :  *-------------------------------------------------------------------*/
    1315             : 
    1316         339 : void FdCngEncodeDiracMDCTStereoSID(
    1317             :     CPE_ENC_HANDLE hCPE /* i/o: CPE encoder state structure     */
    1318             : )
    1319             : {
    1320             :     ENC_CORE_HANDLE sts[CPE_CHANNELS];
    1321             :     float *lr_in_ptr[CPE_CHANNELS];
    1322             :     float *ms_ptr[CPE_CHANNELS];
    1323             :     float *lr_out_ptr[CPE_CHANNELS];
    1324             :     float logNoiseEst[CPE_CHANNELS][NPART];
    1325             :     float E[CPE_CHANNELS];
    1326             :     float gain[CPE_CHANNELS];
    1327             :     float weights[NPART];
    1328             :     int16_t N[CPE_CHANNELS];
    1329             :     int16_t indices[CPE_CHANNELS][FD_CNG_stages_37bits];
    1330             :     int16_t gain_idx[CPE_CHANNELS];
    1331             :     int16_t ch, p;
    1332             :     float *invTrfMatrix;
    1333             :     float tmpRAM[FDCNG_VQ_MAX_LEN][FDCNG_VQ_DCT_MAXTRUNC];
    1334             :     float dct_target[FDCNG_VQ_DCT_MAXTRUNC];
    1335             :     float tot_sig_ext[FDCNG_VQ_MAX_LEN];
    1336         339 :     invTrfMatrix = (float *) tmpRAM; /* dynamically filled  */
    1337             : 
    1338             :     /* set pointers and initialize */
    1339        1017 :     for ( ch = 0; ch < CPE_CHANNELS; ch++ )
    1340             :     {
    1341         678 :         sts[ch] = hCPE->hCoreCoder[ch];
    1342         678 :         N[ch] = sts[ch]->hFdCngEnc->npartDec;
    1343         678 :         lr_in_ptr[ch] = &sts[ch]->hFdCngEnc->msNoiseEst[0];
    1344         678 :         ms_ptr[ch] = &logNoiseEst[ch][0];
    1345         678 :         lr_out_ptr[ch] = &sts[ch]->hFdCngEnc->hFdCngCom->sidNoiseEst[0];
    1346             :     }
    1347         339 :     set_f( weights, 1.f, NPART );
    1348             : #ifdef DEBUGGING
    1349             :     assert( N[0] == N[1] );
    1350             : #endif
    1351             : 
    1352             :     /* apply log and save energy of original left and right channels */
    1353        1017 :     for ( ch = 0; ch < CPE_CHANNELS; ch++ )
    1354             :     {
    1355         678 :         E[ch] = 0.0f;
    1356       16650 :         for ( p = 0; p < N[ch]; p++ )
    1357             :         {
    1358       15972 :             ms_ptr[ch][p] = 10.f * log10f( lr_in_ptr[ch][p] + EPSILON );
    1359       15972 :             E[ch] += ms_ptr[ch][p];
    1360             :         }
    1361             :     }
    1362             : 
    1363             :     /* M/S transform on log envelopes */
    1364         339 :     convertToMS( N[0], ms_ptr[0], ms_ptr[1], 0.5f );
    1365             : 
    1366         339 :     E[0] = sum_f( ms_ptr[0], N[0] );
    1367             : 
    1368             :     /* Quantize M noise shape */
    1369             :     /* Normalize MSVQ input */
    1370         339 :     gain[0] = sum_f( ms_ptr[0] + N_GAIN_MIN, N_GAIN_MAX - N_GAIN_MIN );
    1371         339 :     gain[0] /= (float) ( N_GAIN_MAX - N_GAIN_MIN );
    1372             : 
    1373        8325 :     for ( p = 0; p < N[0]; p++ )
    1374             :     {
    1375        7986 :         ms_ptr[0][p] -= gain[0];
    1376             :     }
    1377             : 
    1378             :     /* MSVQ */
    1379             :     /* DCT domain compressed/truncated indices used for first stage  */
    1380             :     /*  mid quantization using stages #1 through 6 */
    1381         339 :     if ( N[0] == FDCNG_VQ_MAX_LEN_WB )
    1382             :     {
    1383          50 :         create_IDCT_N_Matrix( invTrfMatrix, N[0], FDCNG_VQ_DCT_MAXTRUNC, sizeof( tmpRAM ) / ( sizeof( float ) ) );
    1384             :         /* truncated DCT 21 analysis */
    1385          50 :         dctT2_N_apply_matrix( (const float *) ms_ptr[0], dct_target, FDCNG_VQ_DCT_MAXTRUNC, N[0], invTrfMatrix, FDCNG_VQ_DCT_MAXTRUNC, DCT_T2_21_XX );
    1386             :         /* truncated IDCT21 extension to 24 synthesis  */
    1387          50 :         extend_dctN_input( ms_ptr[0], dct_target, N[0], tot_sig_ext, FDCNG_VQ_MAX_LEN, invTrfMatrix, FDCNG_VQ_DCT_MAXTRUNC, IDCT_T2_XX_21 ); /* use 18 basis vectors*/
    1388             : 
    1389          50 :         mvr2r( tot_sig_ext, ms_ptr[0], FDCNG_VQ_MAX_LEN ); /*  write  extended result as input to  VQ stage #1 */
    1390             :     }
    1391         339 :     create_IDCT_N_Matrix( invTrfMatrix, FDCNG_VQ_MAX_LEN, FDCNG_VQ_DCT_MAXTRUNC, sizeof( tmpRAM ) / ( sizeof( float ) ) );
    1392             : 
    1393         339 :     msvq_enc( cdk_37bits_ivas, NULL, NULL, ms_ptr[0], levels_37bits, FD_CNG_maxC_37bits, FD_CNG_stages_37bits, weights, N[0], FD_CNG_maxN_37bits, 1, invTrfMatrix, indices[0] );
    1394         339 :     msvq_dec( cdk_37bits_ivas, NULL, NULL, FD_CNG_stages_37bits, N[0], FD_CNG_maxN_37bits, indices[0], 1, invTrfMatrix, ms_ptr[0], NULL );
    1395             : 
    1396             : 
    1397             :     /* set S to zero */
    1398         339 :     set_zero( ms_ptr[1], NPART );
    1399             : 
    1400             :     /* compute M gain */
    1401         339 :     gain[0] = sum_f( ms_ptr[0], N[0] );
    1402         339 :     gain[0] = ( E[0] - gain[0] ) / (float) N[0];
    1403         339 :     apply_scale( &gain[0], sts[0]->hFdCngEnc->hFdCngCom->CngBandwidth, sts[0]->hDtxEnc->last_active_brate, scaleTableStereo, SIZE_SCALE_TABLE_STEREO );
    1404             : 
    1405             :     /* quantize gain */
    1406         339 :     gain_idx[0] = (int16_t) floor( gain[0] * 1.5f + GAIN_Q_OFFSET_IVAS + .5f );
    1407         339 :     gain_idx[0] = max( 0, min( 127, gain_idx[0] ) );
    1408             : 
    1409         339 :     gain[0] = ( (float) gain_idx[0] - GAIN_Q_OFFSET_IVAS ) / 1.5f;
    1410         339 :     gain[1] = gain[0];
    1411             : 
    1412             :     /* undo M/S */
    1413         339 :     convertToMS( NPART, ms_ptr[0], ms_ptr[1], 1.0f );
    1414             : 
    1415             :     /* restore channel noise envelopes */
    1416        1017 :     for ( ch = 0; ch < CPE_CHANNELS; ch++ )
    1417             :     {
    1418         678 :         HANDLE_FD_CNG_ENC hFdCngEnc = sts[ch]->hFdCngEnc;
    1419         678 :         HANDLE_FD_CNG_COM hFdCngCom = hFdCngEnc->hFdCngCom;
    1420             : 
    1421       16650 :         for ( p = 0; p < N[0]; p++ )
    1422             :         {
    1423       15972 :             lr_out_ptr[ch][p] = powf( 10.f, ( ms_ptr[ch][p] + gain[ch] ) / 10.f );
    1424             :         }
    1425             : 
    1426             :         /* NB last band energy compensation */
    1427         678 :         if ( hFdCngCom->CngBandwidth == NB )
    1428             :         {
    1429           0 :             lr_out_ptr[ch][N[ch] - 1] *= NB_LAST_BAND_SCALE;
    1430             :         }
    1431         678 :         else if ( hFdCngCom->CngBandwidth == SWB && hFdCngCom->CngBitrate <= ACELP_13k20 )
    1432             :         {
    1433           6 :             lr_out_ptr[ch][N[ch] - 1] *= SWB_13k2_LAST_BAND_SCALE;
    1434             :         }
    1435             : 
    1436             :         /* scale bands and get scalefactors */
    1437         678 :         scalebands( lr_out_ptr[ch], hFdCngEnc->partDec, N[ch], hFdCngEnc->midbandDec, hFdCngEnc->nFFTpartDec, hFdCngEnc->stopBandDec - hFdCngEnc->startBandDec, hFdCngCom->cngNoiseLevel, 1 );
    1438             : 
    1439         678 :         lpc_from_spectrum( hFdCngCom, hFdCngEnc->startBandDec, hFdCngEnc->stopFFTbinDec, sts[ch]->preemph_fac );
    1440             : 
    1441         678 :         sts[ch]->hDtxEnc->last_CNG_L_frame = sts[ch]->L_frame;
    1442             :     }
    1443             : #ifdef NONBE_MDCT_ST_DTX_FIX_SUBOPT_SPATIAL_CNG
    1444         339 :     sts[0]->hFdCngEnc->hFdCngCom->coherence[0] = 0.0f;
    1445         339 :     sts[1]->hFdCngEnc->hFdCngCom->coherence[0] = 0.0f;
    1446             : #else
    1447             :     sts[0]->hFdCngEnc->hFdCngCom->coherence = 0.0f;
    1448             :     sts[1]->hFdCngEnc->hFdCngCom->coherence = 0.0f;
    1449             : #endif
    1450             : 
    1451             :     /* ---- Write SID bitstream ---- */
    1452             : 
    1453             :     /* side info */
    1454         339 :     push_indice( sts[0]->hBstr, IND_SID_TYPE, 1, 1 );
    1455         339 :     push_indice( sts[0]->hBstr, IND_BWIDTH, sts[0]->bwidth, 2 );
    1456         339 :     push_indice( sts[0]->hBstr, IND_ACELP_16KHZ, sts[0]->L_frame == L_FRAME16k ? 1 : 0, 1 );
    1457             : 
    1458             :     /* noise shapes and channel gains */
    1459        2373 :     for ( int16_t i = 0; i < FD_CNG_stages_37bits; i++ )
    1460             :     {
    1461        2034 :         push_indice( sts[0]->hBstr, IND_LSF, indices[0][i], bits_37bits[i] );
    1462             :     }
    1463         339 :     push_indice( sts[0]->hBstr, IND_ENERGY, gain_idx[0], 7 );
    1464             : 
    1465         339 :     return;
    1466             : }

Generated by: LCOV version 1.14