LCOV - code coverage report
Current view: top level - lib_enc - fd_cng_enc.c (source / functions) Hit Total Coverage
Test: Coverage on main -- short test vectors @ b5bd5e0684ad2d9250297e1e7a0ddc986cb7b37e Lines: 471 527 89.4 %
Date: 2025-10-27 07:01:45 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        1921 : 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        1921 :     error = IVAS_ERR_OK;
      69             : 
      70             :     /* Set output to NULL in case of errors and early return */
      71        1921 :     *hFdCngEnc = NULL;
      72             : 
      73             :     /* Allocate memory */
      74        1921 :     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        1921 :     if ( ( error = createFdCngCom( &( hs->hFdCngCom ) ) ) != IVAS_ERR_OK )
      80             :     {
      81           0 :         return error;
      82             :     }
      83             : 
      84        1921 :     *hFdCngEnc = hs;
      85             : 
      86        1921 :     return error;
      87             : }
      88             : 
      89             : /*-------------------------------------------------------------------*
      90             :  * initFdCngEnc()
      91             :  *
      92             :  * Initialize FD_CNG
      93             :  *-------------------------------------------------------------------*/
      94             : 
      95        1921 : 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        1921 :     HANDLE_FD_CNG_COM hsCom = hFdCngEnc->hFdCngCom;
     103             : 
     104             :     /* Initialize common */
     105        1921 :     initFdCngCom( hsCom, scale );
     106             : 
     107             :     /* Configure the Noise Estimator */
     108        1921 :     hsCom->numSlots = 16;
     109        1921 :     hsCom->numCoreBands = 16;
     110        1921 :     hsCom->regularStopBand = (int16_t) ( input_Fs * INV_CLDFB_BANDWIDTH );
     111        1921 :     if ( hsCom->regularStopBand > 40 )
     112             :     {
     113         919 :         hsCom->regularStopBand = 40;
     114             :     }
     115             : 
     116        1921 :     hsCom->startBand = 2;
     117        1921 :     if ( hsCom->regularStopBand == 10 )
     118             :     {
     119          16 :         hsCom->stopFFTbin = 160;
     120          16 :         hsCom->stopBand = 160;
     121          16 :         hsCom->nFFTpart = 17;
     122             :     }
     123             :     else
     124             :     {
     125        1905 :         hsCom->stopFFTbin = 256;
     126        1905 :         hsCom->stopBand = hsCom->regularStopBand - hsCom->numCoreBands + hsCom->stopFFTbin;
     127        1905 :         hsCom->nFFTpart = 20;
     128             :     }
     129             : 
     130        1921 :     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        1921 :     hsCom->nCLDFBpart = hsCom->npart - hsCom->nFFTpart;
     133        8110 :     for ( j = 0; j < hsCom->nCLDFBpart; j++ )
     134             :     {
     135        6189 :         hsCom->CLDFBpart[j] = hsCom->part[j + hsCom->nFFTpart] - ( 256 - hsCom->startBand );
     136        6189 :         hsCom->CLDFBpsize_inv[j] = hsCom->psize_inv[j + hsCom->nFFTpart];
     137             :     }
     138             : 
     139             :     /* Initialize the Noise Estimator */
     140        1921 :     set_f( hFdCngEnc->msPeriodog, 0.0f, NPART );
     141        1921 :     set_f( hFdCngEnc->msAlpha, 0.0f, NPART );
     142        1921 :     set_f( hFdCngEnc->msBminWin, 0.0f, NPART );
     143        1921 :     set_f( hFdCngEnc->msBminSubWin, 0.0f, NPART );
     144        1921 :     set_f( hFdCngEnc->msPsd, 0.0f, NPART );
     145        1921 :     set_f( hFdCngEnc->msNoiseFloor, 0.0f, NPART );
     146        1921 :     set_f( hFdCngEnc->msNoiseEst, 0.0f, NPART );
     147        1921 :     set_f( hFdCngEnc->energy_ho, 0.0f, NPART );
     148        1921 :     set_f( hFdCngEnc->msNoiseEst_old, 0.0f, NPART );
     149        1921 :     set_f( hFdCngEnc->msMinBuf, FLT_MAX, MSNUMSUBFR * NPART );
     150        1921 :     set_f( hFdCngEnc->msCurrentMin, FLT_MAX, NPART );
     151        1921 :     set_f( hFdCngEnc->msCurrentMinOut, FLT_MAX, NPART );
     152        1921 :     set_f( hFdCngEnc->msCurrentMinSubWindow, FLT_MAX, NPART );
     153        1921 :     set_s( hFdCngEnc->msLocalMinFlag, 0, NPART );
     154        1921 :     set_s( hFdCngEnc->msNewMinFlag, 0, NPART );
     155        1921 :     set_f( hFdCngEnc->msPsdFirstMoment, 0.0f, NPART );
     156        1921 :     set_f( hFdCngEnc->msPsdSecondMoment, 0.0f, NPART );
     157        1921 :     hFdCngEnc->msPeriodogBufPtr = 0;
     158        1921 :     set_f( hFdCngEnc->msPeriodogBuf, 0.0f, MSBUFLEN * NPART );
     159        1921 :     set_f( hFdCngEnc->msLogPeriodog, 0.0f, NPART );
     160        1921 :     set_f( hFdCngEnc->msLogNoiseEst, 0.0f, NPART );
     161             : 
     162             : #ifdef NONBE_MDCT_ST_DTX_FIX_SUBOPT_SPATIAL_CNG
     163       11526 :     for ( int16_t i = 0; i < MDCT_ST_DTX_NUM_COHERENCE_BANDS; i++ )
     164             :     {
     165        9605 :         set_f( hFdCngEnc->mem_coherence[i], EPSILON, 4 );
     166             :     }
     167             : #else
     168             :     set_f( hFdCngEnc->mem_coherence, EPSILON, 4 );
     169             : #endif
     170             : 
     171        1921 :     return;
     172             : }
     173             : 
     174             : /*-------------------------------------------------------------------*
     175             :  * configureFdCngEnc()
     176             :  *
     177             :  * Configure FD_CNG
     178             :  *-------------------------------------------------------------------*/
     179             : 
     180       68915 : 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       68915 :     HANDLE_FD_CNG_COM hsCom = hFdCngEnc->hFdCngCom;
     186             :     float psizeDec[NPART];
     187             :     float psize_invDec[NPART];
     188             : 
     189       68915 :     hsCom->CngBandwidth = bwidth;
     190       68915 :     if ( hsCom->CngBandwidth == FB )
     191             :     {
     192       52825 :         hsCom->CngBandwidth = SWB;
     193             :     }
     194       68915 :     hsCom->CngBitrate = total_brate;
     195             : 
     196             :     /* NB configuration */
     197       68915 :     if ( bwidth == NB )
     198             :     {
     199          27 :         hsCom->FdCngSetup = FdCngSetup_nb;
     200             :     }
     201             : 
     202             :     /* WB configuration */
     203       68888 :     else if ( bwidth == WB )
     204             :     {
     205             :         /* FFT 6.4kHz, no CLDFB */
     206        4602 :         if ( total_brate <= ACELP_8k00 )
     207             :         {
     208          49 :             hsCom->FdCngSetup = FdCngSetup_wb1;
     209             :         }
     210             :         /* FFT 6.4kHz, CLDFB 8.0kHz */
     211        4553 :         else if ( total_brate <= ACELP_13k20 )
     212             :         {
     213        1711 :             hsCom->FdCngSetup = FdCngSetup_wb2;
     214             :         }
     215             :         /* FFT 8.0kHz, no CLDFB */
     216             :         else
     217             :         {
     218        2842 :             hsCom->FdCngSetup = FdCngSetup_wb3;
     219             :         }
     220             :     }
     221             : 
     222             :     /* SWB/FB configuration */
     223             :     else
     224             :     {
     225             :         /* FFT 6.4kHz, CLDFB 14kHz */
     226       64286 :         if ( total_brate <= ACELP_13k20 )
     227             :         {
     228       35453 :             hsCom->FdCngSetup = FdCngSetup_swb1;
     229             :         }
     230             :         /* FFT 8.0kHz, CLDFB 16kHz */
     231             :         else
     232             :         {
     233       28833 :             hsCom->FdCngSetup = FdCngSetup_swb2;
     234             :         }
     235             :     }
     236       68915 :     hsCom->fftlen = hsCom->FdCngSetup.fftlen;
     237       68915 :     hFdCngEnc->stopFFTbinDec = hsCom->FdCngSetup.stopFFTbin;
     238             : 
     239             :     /* Configure the SID quantizer and the Confort Noise Generator */
     240             : 
     241       68915 :     hFdCngEnc->startBandDec = hsCom->startBand;
     242       68915 :     hFdCngEnc->stopBandDec = hsCom->FdCngSetup.sidPartitions[hsCom->FdCngSetup.numPartitions - 1] + 1;
     243       68915 :     initPartitions( hsCom->FdCngSetup.sidPartitions, hsCom->FdCngSetup.numPartitions, hFdCngEnc->startBandDec, hFdCngEnc->stopBandDec, hFdCngEnc->partDec, &hFdCngEnc->npartDec, hFdCngEnc->midbandDec, psizeDec, psize_invDec, 0 );
     244             : 
     245       68915 :     if ( hFdCngEnc->stopFFTbinDec == 160 )
     246             :     {
     247          27 :         hFdCngEnc->nFFTpartDec = 17;
     248             :     }
     249       68888 :     else if ( hFdCngEnc->stopFFTbinDec == 256 )
     250             :     {
     251       37213 :         hFdCngEnc->nFFTpartDec = 20;
     252             :     }
     253             :     else
     254             :     {
     255       31675 :         hFdCngEnc->nFFTpartDec = 21;
     256             :     }
     257             : 
     258       68915 :     switch ( hsCom->fftlen )
     259             :     {
     260       37240 :         case 512:
     261       37240 :             hsCom->fftSineTab = NULL;
     262       37240 :             hsCom->olapWinAna = olapWinAna512;
     263       37240 :             hsCom->olapWinSyn = olapWinSyn256;
     264       37240 :             break;
     265       31675 :         case 640:
     266       31675 :             hsCom->fftSineTab = fftSineTab640;
     267       31675 :             hsCom->olapWinAna = olapWinAna640;
     268       31675 :             hsCom->olapWinSyn = olapWinSyn320;
     269       31675 :             break;
     270           0 :         default:
     271           0 :             assert( !"Unsupported FFT length for FD-based CNG" );
     272             :             break;
     273             :     }
     274       68915 :     hsCom->frameSize = hsCom->fftlen >> 1;
     275             : 
     276       68915 :     return;
     277             : }
     278             : 
     279             : 
     280             : /*-------------------------------------------------------------------*
     281             :  * deleteFdCngEnc()
     282             :  *
     283             :  * Delete the instance of type FD_CNG
     284             :  *-------------------------------------------------------------------*/
     285             : 
     286       28838 : void deleteFdCngEnc(
     287             :     HANDLE_FD_CNG_ENC *hFdCngEnc /* i/o: FD_CNG structure        */
     288             : )
     289             : {
     290             : 
     291       28838 :     HANDLE_FD_CNG_ENC hsEnc = *hFdCngEnc;
     292             : 
     293       28838 :     if ( hsEnc != NULL )
     294             :     {
     295        1921 :         deleteFdCngCom( &( hsEnc->hFdCngCom ) );
     296        1921 :         free( hsEnc );
     297        1921 :         *hFdCngEnc = NULL;
     298             :     }
     299             : 
     300       28838 :     return;
     301             : }
     302             : 
     303             : /*-------------------------------------------------------------------*
     304             :  * resetFdCngEnc()
     305             :  *
     306             :  * Reset the instance of type FD_CNG
     307             :  *-------------------------------------------------------------------*/
     308             : 
     309      261645 : 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      261645 :     totalNoiseIncrease = st->hNoiseEst->totalNoise - st->last_totalNoise;
     318      261645 :     st->last_totalNoise = st->hNoiseEst->totalNoise;
     319      261645 :     if ( totalNoiseIncrease > 0 )
     320             :     {
     321       20347 :         if ( st->totalNoise_increase_len == TOTALNOISE_HIST_SIZE )
     322             :         {
     323       15176 :             for ( n = 0; n < TOTALNOISE_HIST_SIZE - 1; n++ )
     324             :             {
     325       11382 :                 st->totalNoise_increase_hist[n] = st->totalNoise_increase_hist[n + 1];
     326             :             }
     327        3794 :             st->totalNoise_increase_hist[TOTALNOISE_HIST_SIZE - 1] = totalNoiseIncrease;
     328             :         }
     329             :         else
     330             :         {
     331       16553 :             st->totalNoise_increase_hist[st->totalNoise_increase_len] = totalNoiseIncrease;
     332       16553 :             st->totalNoise_increase_len++;
     333             :         }
     334             :     }
     335             :     else
     336             :     {
     337      241298 :         st->totalNoise_increase_len = 0;
     338             :     }
     339             : 
     340      261645 :     totalNoiseIncrease = 0.f;
     341      302232 :     for ( n = 0; n < st->totalNoise_increase_len; n++ )
     342             :     {
     343       40587 :         totalNoiseIncrease += st->totalNoise_increase_hist[n];
     344             :     }
     345             : 
     346      261645 :     if (
     347        1901 :         ( totalNoiseIncrease > 5 && st->totalNoise_increase_len == TOTALNOISE_HIST_SIZE && st->ini_frame > 150 ) ||
     348      261628 :         ( st->input_bwidth > st->last_input_bwidth ) ||
     349      261184 :         ( st->last_core == AMR_WB_CORE ) )
     350             :     {
     351         465 :         st->fd_cng_reset_flag = 1;
     352         465 :         st->hFdCngEnc->hFdCngCom->msFrCnt_init_counter = 0;
     353         465 :         st->hFdCngEnc->hFdCngCom->init_old = FLT_MAX;
     354             :     }
     355      261180 :     else if ( st->fd_cng_reset_flag > 0 && st->fd_cng_reset_flag < 10 )
     356             :     {
     357        4142 :         st->fd_cng_reset_flag++;
     358             :     }
     359             :     else
     360             :     {
     361      257038 :         st->fd_cng_reset_flag = 0;
     362             :     }
     363             : 
     364      261645 :     return;
     365             : }
     366             : 
     367             : 
     368             : /*-------------------------------------------------------------------*
     369             :  * perform_noise_estimation_enc()
     370             :  *
     371             :  * Perform noise estimation
     372             :  *-------------------------------------------------------------------*/
     373             : 
     374      225777 : 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      225777 :     int16_t numCoreBands = hFdCngEnc->hFdCngCom->numCoreBands;
     384      225777 :     int16_t regularStopBand = hFdCngEnc->hFdCngCom->regularStopBand;
     385      225777 :     int16_t numSlots = hFdCngEnc->hFdCngCom->numSlots;
     386      225777 :     float numSlots_inv = 1.f / (float) numSlots; /*enough if done only once*/
     387      225777 :     float *periodog = hFdCngEnc->hFdCngCom->periodog;
     388      225777 :     float *ptr_per = periodog;
     389      225777 :     int16_t npart = hFdCngEnc->hFdCngCom->npart;
     390      225777 :     int16_t nFFTpart = hFdCngEnc->hFdCngCom->nFFTpart;
     391      225777 :     float *psize = hFdCngEnc->hFdCngCom->psize;
     392      225777 :     float *msPeriodog = hFdCngEnc->msPeriodog;
     393      225777 :     float *msNoiseEst = hFdCngEnc->msNoiseEst;
     394             : 
     395      225777 :     float *msLogPeriodog = hFdCngEnc->msLogPeriodog;
     396      225777 :     float *msLogNoiseEst = hFdCngEnc->msLogNoiseEst;
     397             : 
     398             :     float band_res_dft, chan_width_f;
     399             :     float chan_width_bins;
     400             :     float scaleEB;
     401             : 
     402      225777 :     if ( hCPE != NULL && hCPE->hStereoDft != NULL )
     403             :     {
     404       34018 :         band_res_dft = ( (float) input_Fs ) / hCPE->hStereoDft->NFFT;
     405       34018 :         chan_width_f = 24000.f / CLDFB_NO_CHANNELS_MAX;
     406       34018 :         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       34018 :         scaleEB = 3 * 4.0f / ( hCPE->hStereoDft->NFFT * hCPE->hStereoDft->NFFT );
     410             : 
     411             :         /* Scale with number of bins in one band */
     412       34018 :         scaleEB = scaleEB / chan_width_bins;
     413             :     }
     414             :     else
     415             :     {
     416      191759 :         scaleEB = numSlots_inv * hFdCngEnc->hFdCngCom->scalingFactor;
     417             :     }
     418             : 
     419             :     /* preemphasis compensation and grouping of per bin energies into msPeriodog */
     420     4738917 :     for ( i = 0; i < nFFTpart; i++ )
     421             :     {
     422     4513140 :         msPeriodog[i] = 0.5f * ( band_energies[i] + band_energies[i + NB_BANDS] );
     423     4513140 :         msPeriodog[i] *= preemphCompensation[i];
     424             :     }
     425             : 
     426             :     /* Adjust to the desired time resolution by averaging the periodograms over the time slots */
     427     4872825 :     for ( j = numCoreBands; j < regularStopBand; j++ )
     428             :     {
     429     4647048 :         ( *ptr_per ) = enerBuffer[j] * scaleEB;
     430     4647048 :         ptr_per++;
     431             :     }
     432             : 
     433             :     /* Adjust filterbank to the desired frequency resolution by averaging over spectral partitions for SID transmission */
     434      225777 :     if ( numCoreBands < regularStopBand )
     435             :     {
     436      224977 :         bandcombinepow( periodog, regularStopBand - numCoreBands, hFdCngEnc->hFdCngCom->CLDFBpart, hFdCngEnc->hFdCngCom->nCLDFBpart, hFdCngEnc->hFdCngCom->CLDFBpsize_inv, &msPeriodog[nFFTpart] );
     437             :     }
     438             : 
     439             :     /* Compress MS inputs */
     440      225777 :     compress_range( msPeriodog, msLogPeriodog, npart );
     441             : 
     442             :     /* Call the minimum statistics routine for noise estimation */
     443      318531 :     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       92754 :                         ENC, ( hCPE == NULL ) ? 0 : hCPE->element_mode );
     445             : 
     446             :     /* Expand MS outputs */
     447      225777 :     expand_range( msLogNoiseEst, msNoiseEst, npart );
     448             : 
     449      225777 :     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      215047 : void AdjustFirstSID(
     460             :     Encoder_State *st /* i/o: encoder state structure     */
     461             : )
     462             : {
     463             :     float lambda;
     464             :     int16_t i;
     465      215047 :     int16_t npart = st->hFdCngEnc->hFdCngCom->npart;
     466      215047 :     float *msPeriodog = st->hFdCngEnc->msPeriodog;
     467      215047 :     float *energy_ho = st->hFdCngEnc->energy_ho;
     468      215047 :     float *msNoiseEst = st->hFdCngEnc->msNoiseEst;
     469      215047 :     float *msNoiseEst_old = st->hFdCngEnc->msNoiseEst_old;
     470      215047 :     int16_t *active_frame_counter = &( st->hFdCngEnc->hFdCngCom->active_frame_counter );
     471             : 
     472      215047 :     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        2897 :         mvr2r( msPeriodog, energy_ho, npart ); /*First hangover frame*/
     478             :         /* Set first SID to current input level but add some smoothing */
     479        2897 :         lambda = (float) pow( 0.96f, (float) ( *active_frame_counter + 1 ) );
     480        2897 :         v_multc( msNoiseEst_old, lambda, msNoiseEst_old, npart );
     481        2897 :         v_multc( energy_ho, 1 - lambda, energy_ho, npart );
     482             : 
     483        2897 :         v_add( msNoiseEst_old, energy_ho, energy_ho, npart );
     484       71837 :         for ( i = 0; i < npart; i++ )
     485             :         {
     486       68940 :             if ( msNoiseEst[i] > energy_ho[i] )
     487             :             {
     488       42838 :                 msNoiseEst[i] = energy_ho[i];
     489             :             }
     490             :         }
     491        2897 :         *active_frame_counter = 0;
     492             :     }
     493             : 
     494      215047 :     if ( st->core_brate != SID_2k40 && st->core_brate != FRAME_NO_DATA )
     495             :     {
     496      178132 :         ( *active_frame_counter )++; /* Count the number of active frames in a row */
     497             :     }
     498             :     else
     499             :     {
     500       36915 :         mvr2r( msNoiseEst, msNoiseEst_old, npart ); /* Store the noise estimate obtained in the CNG phases */
     501             :     }
     502             : 
     503      215047 :     return;
     504             : }
     505             : 
     506             : /*-------------------------------------------------------------------*
     507             :  * FdCng_encodeSID()
     508             :  *
     509             :  * Generate a bitstream out of the partition levels
     510             :  *-------------------------------------------------------------------*/
     511             : 
     512        2325 : void FdCng_encodeSID(
     513             :     Encoder_State *st /* i/o: encoder state structure     */
     514             : )
     515             : {
     516             :     int16_t N;
     517        2325 :     HANDLE_FD_CNG_ENC hFdCngEnc = st->hFdCngEnc;
     518        2325 :     HANDLE_FD_CNG_COM hFdCngCom = hFdCngEnc->hFdCngCom;
     519        2325 :     BSTR_ENC_HANDLE hBstr = st->hBstr;
     520        2325 :     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        2325 :     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        2325 :     const float gain_q_offset = ( st->element_mode == EVS_MONO ) ? GAIN_Q_OFFSET_EVS : GAIN_Q_OFFSET_IVAS;
     533             : 
     534             :     /* Init */
     535        2325 :     N = hFdCngEnc->npartDec;
     536             : 
     537        2325 :     invTrfMatrix = (float *) tmpRAM; /* dynamically filled  */
     538        2325 :     set_zero( v, FDCNG_VQ_MAX_LEN );
     539             : 
     540             :     /* Convert to LOG */
     541        2325 :     e = 0.f;
     542       56412 :     for ( i = 0; i < N; i++ )
     543             :     {
     544       54087 :         v[i] = 10.f * (float) log10( E[i] + 1e-4f );
     545       54087 :         e += v[i];
     546             :     }
     547             : 
     548             :     /* Normalize MSVQ input */
     549        2325 :     gain = 0.f;
     550       32550 :     for ( i = N_GAIN_MIN; i < N_GAIN_MAX; i++ )
     551             :     {
     552       30225 :         gain += v[i];
     553             :     }
     554             : 
     555        2325 :     gain /= (float) ( N_GAIN_MAX - N_GAIN_MIN );
     556             : 
     557       56412 :     for ( i = 0; i < N; i++ )
     558             :     {
     559       54087 :         v[i] -= gain;
     560             :     }
     561             : 
     562             :     /* MSVQ encoder */
     563        2325 :     set_f( w, 1.0f, N );
     564             : 
     565        2325 :     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        2325 :         if ( N == FDCNG_VQ_MAX_LEN_WB )
     572             :         {
     573         571 :             create_IDCT_N_Matrix( invTrfMatrix, N, FDCNG_VQ_DCT_MAXTRUNC, sizeof( tmpRAM ) / ( sizeof( float ) ) );
     574             :             /* truncated DCT21 analysis */
     575         571 :             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         571 :             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         571 :             mvr2r( tot_sig_ext, v, FDCNG_VQ_MAX_LEN ); /*  write  extended result as input to  VQ stage #1 */
     580             :         }
     581        2325 :         create_IDCT_N_Matrix( invTrfMatrix, FDCNG_VQ_MAX_LEN, FDCNG_VQ_DCT_MAXTRUNC, sizeof( tmpRAM ) / ( sizeof( float ) ) );
     582        2325 :         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        2325 :         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           0 :         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           0 :         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        2325 :     gain = 0.f;
     594       56412 :     for ( i = 0; i < N; i++ )
     595             :     {
     596       54087 :         gain += v[i];
     597             :     }
     598             : 
     599        2325 :     gain = ( e - gain ) / (float) N;
     600             : 
     601             :     /* Apply bitrate-dependant scale */
     602        2325 :     if ( st->element_mode > EVS_MONO )
     603             :     {
     604        2325 :         apply_scale( &gain, hFdCngCom->CngBandwidth, hFdCngCom->CngBitrate, scaleTableStereo, SIZE_SCALE_TABLE_STEREO );
     605             :     }
     606             :     else
     607             :     {
     608           0 :         apply_scale( &gain, hFdCngCom->CngBandwidth, hFdCngCom->CngBitrate, scaleTableMono, SIZE_SCALE_TABLE_MONO );
     609             :     }
     610             : 
     611             :     /* Quantize gain */
     612        2325 :     index = (int16_t) floor( gain * 1.5f + gain_q_offset + 0.5f );
     613             : 
     614        2325 :     if ( index < 0 )
     615             :     {
     616         315 :         index = 0;
     617             :     }
     618             : 
     619        2325 :     if ( index > 127 )
     620             :     {
     621           0 :         index = 127;
     622             :     }
     623             : 
     624        2325 :     gain = ( (float) index - gain_q_offset ) / 1.5f;
     625             : 
     626             :     /* Apply gain and undo log */
     627       56412 :     for ( i = 0; i < N; i++ )
     628             :     {
     629             : 
     630       54087 :         hFdCngCom->sidNoiseEst[i] = (float) pow( 10.f, ( v[i] + gain ) / 10.f );
     631             :     }
     632             : 
     633             :     /* NB last band energy compensation */
     634        2325 :     if ( hFdCngCom->CngBandwidth == NB )
     635             :     {
     636           0 :         hFdCngCom->sidNoiseEst[N - 1] *= NB_LAST_BAND_SCALE;
     637             :     }
     638             : 
     639        2325 :     if ( hFdCngCom->CngBandwidth == SWB && hFdCngCom->CngBitrate <= ACELP_13k20 )
     640             :     {
     641         971 :         hFdCngCom->sidNoiseEst[N - 1] *= SWB_13k2_LAST_BAND_SCALE;
     642             :     }
     643             : 
     644             :     /* Write bitstream */
     645        2325 :     if ( st->codec_mode == MODE2 )
     646             :     {
     647           0 :         for ( i = 0; i < FD_CNG_stages_37bits; i++ )
     648             :         {
     649           0 :             push_next_indice( hBstr, indices[i], bits_37bits[i] );
     650             :         }
     651             : 
     652           0 :         push_next_indice( hBstr, index, 7 );
     653             :     }
     654             :     else
     655             :     {
     656        2325 :         push_indice( hBstr, IND_SID_TYPE, 1, 1 );
     657        2325 :         push_indice( hBstr, IND_BWIDTH, st->bwidth, 2 );
     658        2325 :         push_indice( hBstr, IND_ACELP_16KHZ, st->L_frame == L_FRAME16k ? 1 : 0, 1 );
     659             : 
     660       16275 :         for ( i = 0; i < FD_CNG_stages_37bits; i++ )
     661             :         {
     662       13950 :             push_indice( hBstr, IND_LSF, indices[i], bits_37bits[i] );
     663             :         }
     664             : 
     665        2325 :         push_indice( hBstr, IND_ENERGY, index, 7 );
     666             :     }
     667             : 
     668             :     /* Interpolate the bin/band-wise levels from the partition levels */
     669        2325 :     scalebands( hFdCngCom->sidNoiseEst, hFdCngEnc->partDec, hFdCngEnc->npartDec, hFdCngEnc->midbandDec, hFdCngEnc->nFFTpartDec, hFdCngEnc->stopBandDec - hFdCngEnc->startBandDec, hFdCngCom->cngNoiseLevel, 1 );
     670             : 
     671        2325 :     lpc_from_spectrum( hFdCngCom, hFdCngEnc->startBandDec, hFdCngEnc->stopFFTbinDec, preemph_fac );
     672             : 
     673        2325 :     return;
     674             : }
     675             : 
     676             : 
     677             : /*-------------------------------------------------------------------*
     678             :  * generate_comfort_noise_enc()
     679             :  *
     680             :  *
     681             :  *-------------------------------------------------------------------*/
     682             : 
     683       14213 : 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       14213 :     HANDLE_FD_CNG_ENC hFdCngEnc = st->hFdCngEnc;
     691       14213 :     HANDLE_FD_CNG_COM hFdCngCom = hFdCngEnc->hFdCngCom;
     692       14213 :     float *cngNoiseLevel = hFdCngCom->cngNoiseLevel;
     693       14213 :     float *ptr_level = cngNoiseLevel;
     694       14213 :     int16_t *seed = &( hFdCngCom->seed );
     695       14213 :     float scale = 1.f;
     696       14213 :     float *fftBuffer = hFdCngCom->fftBuffer;
     697       14213 :     float *timeDomainOutput = hFdCngCom->timeDomainBuffer;
     698       14213 :     float preemph_fac = st->preemph_fac;
     699       14213 :     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       14213 :     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       14213 :         fftBuffer[0] = 0.f;
     714       14213 :         set_f( fftBuffer + 2, 0.0f, 2 * ( hFdCngEnc->startBandDec - 1 ) );
     715       14213 :         ptr_r = fftBuffer + 2 * hFdCngEnc->startBandDec;
     716             :     }
     717             : 
     718       14213 :     ptr_i = ptr_r + 1;
     719     4042299 :     for ( ; ptr_level < cngNoiseLevel + hFdCngEnc->stopFFTbinDec - hFdCngEnc->startBandDec; ptr_level++ )
     720             :     {
     721             :         /* Real part in FFT bins */
     722     4028086 :         rand_gauss( ptr_r, seed );
     723     4028086 :         ( *ptr_r ) *= (float) sqrt( ( scale * *ptr_level ) * 0.5f );
     724     4028086 :         ptr_r += 2;
     725             :         /* Imaginary part in FFT bins */
     726     4028086 :         rand_gauss( ptr_i, seed );
     727     4028086 :         ( *ptr_i ) *= (float) sqrt( ( scale * *ptr_level ) * 0.5f );
     728     4028086 :         ptr_i += 2;
     729             :     }
     730             : 
     731             :     /* Remaining FFT bins are set to zero */
     732       14213 :     set_f( fftBuffer + 2 * hFdCngEnc->stopFFTbinDec, 0.0f, hFdCngCom->fftlen - 2 * hFdCngEnc->stopFFTbinDec );
     733             : 
     734             :     /* Nyquist frequency is discarded */
     735       14213 :     fftBuffer[1] = 0.f;
     736             : 
     737             :     /* If previous frame is active, reset the overlap-add buffer */
     738       14213 :     if ( st->last_core_brate > SID_2k40 )
     739             :     {
     740         900 :         set_f( hFdCngCom->olapBufferSynth, 0.0f, hFdCngCom->fftlen );
     741             : 
     742         900 :         if ( ( st->last_core > ACELP_CORE && st->codec_mode == MODE2 ) || st->codec_mode == MODE1 )
     743             :         {
     744         900 :             tcx_transition = 1;
     745             :         }
     746             :     }
     747             : 
     748             :     /* Perform STFT synthesis */
     749       14213 :     SynthesisSTFT( fftBuffer, timeDomainOutput, hFdCngCom->olapBufferSynth, hFdCngCom->olapWinSyn, tcx_transition, hFdCngCom, -1, -1 );
     750             : 
     751       14213 :     if ( st->hTdCngEnc != NULL )
     752             :     {
     753             :         /* update CNG excitation energy for LP_CNG */
     754             :         /* calculate the residual signal energy */
     755       11583 :         enr = cng_energy( st->element_mode, st->bwidth, st->hDtxEnc->CNG_mode, st->hTdCngEnc->CNG_att, hFdCngCom->exc_cng, hFdCngCom->frameSize );
     756             : 
     757       11583 :         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       14213 :     if ( st->last_core_brate > SID_2k40 && st->codec_mode == MODE2 )
     762             :     {
     763           0 :         float noise[2048], old_exc_ener = 0.f, gain = 0.f, tmp;
     764           0 :         int16_t N = hFdCngCom->frameSize;
     765           0 :         int16_t seed_loc = hFdCngCom->seed;
     766             :         float *old_exc, old_Aq[M + 1], *old_syn_pe, old_syn;
     767             : 
     768           0 :         if ( st->last_core > ACELP_CORE )
     769             :         {
     770           0 :             tcx_windowing_synthesis_current_frame( timeDomainOutput, st->hTcxCfg->tcx_mdct_window, /*Keep sine windows for limiting Time modulation*/
     771           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 );
     772             : 
     773           0 :             if ( st->hTcxCfg->last_aldo )
     774             :             {
     775           0 :                 for ( i = 0; i < hFdCngCom->frameSize; i++ )
     776             :                 {
     777           0 :                     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           0 :             lsp2a_stab( st->lsp_old, old_Aq, M );
     793           0 :             old_exc = st->hLPDmem->old_exc + L_EXC_MEM - ( N / 2 );
     794           0 :             old_syn_pe = st->hLPDmem->mem_syn2;
     795           0 :             old_syn = st->hLPDmem->syn[M];
     796           0 :             for ( i = 0; i < N / 2; i++ )
     797             :             {
     798           0 :                 old_exc_ener += old_exc[i] * old_exc[i];
     799             :             }
     800             : 
     801           0 :             old_exc_ener = (float) sqrt( old_exc_ener / (float) ( N / 2 ) );
     802             : 
     803           0 :             for ( i = 0; i < N; i++ )
     804             :             {
     805           0 :                 rand_gauss( &( noise[i] ), &( seed_loc ) );
     806           0 :                 gain += noise[i] * noise[i];
     807             :             }
     808             : 
     809           0 :             gain = old_exc_ener / (float) sqrt( gain / (float) N );
     810             : 
     811           0 :             for ( i = 0; i < N; i++ )
     812             :             {
     813           0 :                 noise[i] *= gain;
     814             :             }
     815             : 
     816           0 :             syn_filt( old_Aq, M, noise, noise, N, old_syn_pe, 0 );
     817             : 
     818           0 :             tmp = old_syn;
     819             : 
     820           0 :             deemph( noise, preemph_fac, N, &tmp );
     821             : 
     822           0 :             for ( i = 0; i < N / 2; i++ )
     823             :             {
     824           0 :                 timeDomainOutput[i] += noise[i] * hFdCngCom->olapWinSyn[N / 2 + i];
     825             :             }
     826             :         }
     827             :     }
     828             : 
     829       14213 :     return;
     830             : }
     831             : 
     832             : /*-------------------------------------------------------------------*
     833             :  * cng_energy()
     834             :  *
     835             :  *
     836             :  *-------------------------------------------------------------------*/
     837             : 
     838             : /*! r: CNG energy */
     839       13174 : 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       13174 :     enr = dotp( exc, exc, len ) / len;
     852             : 
     853             :     /* convert log2 of residual signal energy */
     854       13174 :     enr = (float) log10( enr + 0.1f ) / (float) log10( 2.0f );
     855             : 
     856             :     /* decrease the energy in case of WB input */
     857       13174 :     if ( element_mode == IVAS_CPE_DFT || element_mode == IVAS_CPE_TD )
     858             :     {
     859        9740 :         enr += CNG_att * FAC_LOG2 / 10.0f;
     860             :     }
     861        3434 :     else if ( bwidth != NB )
     862             :     {
     863        3434 :         if ( bwidth == WB )
     864             :         {
     865        2352 :             if ( CNG_mode >= 0 )
     866             :             {
     867             :                 /* Bitrate adapted attenuation */
     868           0 :                 att = ENR_ATT[CNG_mode];
     869             :             }
     870             :             else
     871             :             {
     872             :                 /* Use least attenuation for higher bitrates */
     873        2352 :                 att = ENR_ATT[4];
     874             :             }
     875             :         }
     876             :         else
     877             :         {
     878        1082 :             att = 1.5f;
     879             :         }
     880        3434 :         enr -= att;
     881             :     }
     882             : 
     883       13174 :     return ( enr );
     884             : }
     885             : 
     886             : 
     887             : /*-------------------------------------------------------------------*
     888             :  * stereoFdCngCoherence()
     889             :  *
     890             :  * compute coherence of channels for use in FD-CNG
     891             :  *-------------------------------------------------------------------*/
     892             : 
     893       28468 : 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       28468 :     if ( last_element_mode != IVAS_CPE_MDCT )
     905             :     {
     906             : #ifdef NONBE_MDCT_ST_DTX_FIX_SUBOPT_SPATIAL_CNG
     907         546 :         for ( i = 0; i < MDCT_ST_DTX_NUM_COHERENCE_BANDS; i++ )
     908             :         {
     909         455 :             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       28468 :     if ( sts[0]->core_brate == -1 || sts[1]->core_brate == -1 )
     917             :     {
     918             :         /* case: at least one channel has triggered VAD -> ACTIVE FRAME */
     919       23478 :         if ( sts[0]->core_brate == -1 )
     920             :         {
     921       23028 :             sts[1]->total_brate = sts[0]->total_brate;
     922       23028 :             sts[1]->active_cnt = sts[0]->active_cnt;
     923       23028 :             if ( sts[1]->active_cnt >= CNG_TYPE_HO )
     924             :             {
     925       21820 :                 sts[1]->last_total_brate_cng = -1;
     926             :             }
     927             :         }
     928       23478 :         if ( sts[1]->core_brate == -1 )
     929             :         {
     930       22916 :             sts[0]->total_brate = sts[1]->total_brate;
     931       22916 :             sts[0]->active_cnt = sts[1]->active_cnt;
     932       22916 :             if ( sts[0]->active_cnt >= CNG_TYPE_HO )
     933             :             {
     934       21838 :                 sts[0]->last_total_brate_cng = -1;
     935             :             }
     936             :         }
     937       23478 :         sts[0]->core_brate = -1;
     938       23478 :         sts[1]->core_brate = -1;
     939       23478 :         sts[0]->hDtxEnc->cnt_SID = 0;
     940       23478 :         sts[1]->hDtxEnc->cnt_SID = 0;
     941             :     }
     942        4990 :     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        4990 :         reset_indices_enc( sts[0]->hBstr, sts[0]->hBstr->nb_ind_tot );
     946             : 
     947        4990 :         reset_indices_enc( sts[1]->hBstr, sts[1]->hBstr->nb_ind_tot );
     948             : 
     949             :         /* synchronize SID sending for variable SID rate */
     950        4990 :         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        4990 :         sts[0]->hDtxEnc->cnt_SID = min( sts[0]->hDtxEnc->cnt_SID, sts[1]->hDtxEnc->cnt_SID );
     958        4990 :         sts[1]->hDtxEnc->cnt_SID = sts[0]->hDtxEnc->cnt_SID;
     959             :     }
     960             : 
     961       28468 :     pt_fftL = fft_buff[0];
     962       28468 :     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       28468 :     if ( !( sts[0]->ini_frame <= 50 || ( sts[0]->vad_flag == 0 && sts[1]->vad_flag == 0 ) ) )
     969             :     {
     970       13644 :         return;
     971             :     }
     972             : 
     973             : #ifdef NONBE_MDCT_ST_DTX_FIX_SUBOPT_SPATIAL_CNG
     974       44472 :     for ( i_subfr = 0; i_subfr < 2; i_subfr++ )
     975             :     {
     976             :         int16_t band_len_cum;
     977             : 
     978       29648 :         band_len_cum = 0;
     979       29648 :         i = MDCT_ST_DTX_FIRST_BAND_OFFSET;
     980             : 
     981      177888 :         for ( int16_t b = 0; b < MDCT_ST_DTX_NUM_COHERENCE_BANDS; b++ )
     982             :         {
     983      148240 :             band_len_cum += mdct_stereo_dtx_coherence_bandlengths[b];
     984      148240 :             cr = ci = eL = eR = EPSILON;
     985      148240 :             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      148240 :             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       29648 :                 cr += pt_fftL[L_FFT / 2] * pt_fftR[L_FFT / 2];
     993       29648 :                 eL += pt_fftL[L_FFT / 2] * pt_fftL[L_FFT / 2];
     994       29648 :                 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       29648 :                 --band_len_cum;
     998             :             }
     999             : 
    1000     3794944 :             for ( ; i < band_len_cum; i++ )
    1001             :             {
    1002     3646704 :                 cr += pt_fftL[i] * pt_fftR[i] + pt_fftL[L_FFT - i] * pt_fftR[L_FFT - i];
    1003     3646704 :                 ci += -pt_fftL[i] * pt_fftR[L_FFT - i] + pt_fftR[i] * pt_fftL[L_FFT - i];
    1004     3646704 :                 eL += pt_fftL[i] * pt_fftL[i] + pt_fftL[L_FFT - i] * pt_fftL[L_FFT - i];
    1005     3646704 :                 eR += pt_fftR[i] * pt_fftR[i] + pt_fftR[L_FFT - i] * pt_fftR[L_FFT - i];
    1006             :             }
    1007             : 
    1008      148240 :             mem[0] = 0.95f * mem[0] + 0.05f * cr;
    1009      148240 :             mem[1] = 0.95f * mem[1] + 0.05f * ci;
    1010      148240 :             mem[2] = 0.95f * mem[2] + 0.05f * eL;
    1011      148240 :             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      148240 :             sts[0]->hFdCngEnc->hFdCngCom->coherence[b] = sqrtf( ( mem[0] * mem[0] + mem[1] * mem[1] ) / ( mem[2] * mem[3] ) );
    1015             :         }
    1016             : 
    1017       29648 :         pt_fftL += L_FFT;
    1018       29648 :         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       14824 :     return;
    1055             : }
    1056             : 
    1057             : 
    1058             : /*-------------------------------------------------------------------*
    1059             :  * FdCngEncodeMDCTStereoSID()
    1060             :  *
    1061             :  * Encode DTX parameters and noise shapes into SID for MDCT-Stereo DTX
    1062             :  *-------------------------------------------------------------------*/
    1063             : 
    1064         471 : 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         471 :     invTrfMatrix = (float *) tmpRAM;                       /* dynamically filled  */
    1087             : 
    1088             : 
    1089         471 :     is_inp_ms = 0;
    1090         471 :     if ( hCPE->hCoreCoder[0]->cng_sba_flag == 1 )
    1091             :     {
    1092           0 :         is_inp_ms = 1;
    1093             :     }
    1094             : 
    1095             :     /* set pointers and initialize */
    1096        1413 :     for ( ch = 0; ch < CPE_CHANNELS; ch++ )
    1097             :     {
    1098         942 :         sts[ch] = hCPE->hCoreCoder[ch];
    1099         942 :         lr_in_ptr[ch] = &sts[ch]->hFdCngEnc->msNoiseEst[0];
    1100         942 :         ms_ptr[ch] = &logNoiseEst[ch][0];
    1101         942 :         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         471 :     N = sts[0]->hFdCngEnc->npartDec;
    1107         471 :     set_f( weights, 1.f, NPART );
    1108             : 
    1109             :     /* apply log and save energy of original left and right channels */
    1110        1413 :     for ( ch = 0; ch < CPE_CHANNELS; ch++ )
    1111             :     {
    1112         942 :         E[ch] = 0.0f;
    1113       22482 :         for ( p = 0; p < N; p++ )
    1114             :         {
    1115       21540 :             ms_ptr[ch][p] = 10.f * log10f( lr_in_ptr[ch][p] + EPSILON );
    1116       21540 :             E[ch] += ms_ptr[ch][p];
    1117             :         }
    1118             :     }
    1119             : 
    1120             :     /* M/S transform on log envelopes */
    1121         471 :     if ( is_inp_ms == 0 )
    1122             :     {
    1123         471 :         convertToMS( N, ms_ptr[0], ms_ptr[1], 0.5f );
    1124             :     }
    1125             : 
    1126         471 :     side_energy = sum2_f( ms_ptr[1], N );
    1127             : 
    1128             :     /* do not transmit side shape if initial noise shapes are very similar */
    1129         471 :     if ( side_energy <= 0.1f )
    1130             :     {
    1131          16 :         no_side_flag = 1;
    1132             :     }
    1133             :     else
    1134             :     {
    1135         455 :         no_side_flag = 0;
    1136             :     }
    1137             : 
    1138             :     /* Quantize noise shapes */
    1139        1413 :     for ( ch = 0; ch < CPE_CHANNELS; ch++ )
    1140             :     {
    1141             :         /* Normalize MSVQ input */
    1142         942 :         gain[ch] = 0.f;
    1143       13188 :         for ( p = N_GAIN_MIN; p < N_GAIN_MAX; p++ )
    1144             :         {
    1145       12246 :             gain[ch] += ms_ptr[ch][p];
    1146             :         }
    1147         942 :         gain[ch] /= (float) ( N_GAIN_MAX - N_GAIN_MIN );
    1148             : 
    1149       22482 :         for ( p = 0; p < N; p++ )
    1150             :         {
    1151       21540 :             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         471 :     if ( N == FDCNG_VQ_MAX_LEN_WB )
    1159             :     {
    1160         178 :         create_IDCT_N_Matrix( invTrfMatrix, N, FDCNG_VQ_DCT_MAXTRUNC, sizeof( tmpRAM ) / ( sizeof( float ) ) ); /*WB: create truncated IDCT21 matrix */
    1161             : 
    1162         534 :         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         356 :             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         356 :             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         356 :             mvr2r( tot_sig_ext, ms_ptr[ch], FDCNG_VQ_MAX_LEN ); /*  write  extended result as input to  VQ */
    1177             :         }
    1178             :     }
    1179         471 :     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        1413 :     for ( ch = 0; ch < CPE_CHANNELS; ch++ )
    1183             :     {
    1184             :         /* MSVQ */
    1185         942 :         if ( ch )
    1186             :         {
    1187         471 :             stages = FD_CNG_JOINT_stages_25bits;
    1188             :         }
    1189             :         else
    1190             :         {
    1191         471 :             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         942 :             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         942 :             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         471 :     if ( no_side_flag )
    1205             :     {
    1206          16 :         set_zero( ms_ptr[1], N );
    1207             :     }
    1208             : 
    1209             :     /* undo M/S */
    1210         471 :     if ( is_inp_ms == 0 )
    1211             :     {
    1212         471 :         convertToMS( N, ms_ptr[0], ms_ptr[1], 1.0f );
    1213             :     }
    1214             : 
    1215             :     /* Compute gain against original left and right channels */
    1216        1413 :     for ( ch = 0; ch < CPE_CHANNELS; ch++ )
    1217             :     {
    1218         942 :         gain[ch] = 0.f;
    1219       22482 :         for ( p = 0; p < N; p++ )
    1220             :         {
    1221       21540 :             gain[ch] += ms_ptr[ch][p];
    1222             :         }
    1223         942 :         gain[ch] = ( E[ch] - gain[ch] ) / (float) N;
    1224         942 :         apply_scale( &gain[ch], sts[ch]->hFdCngEnc->hFdCngCom->CngBandwidth, sts[ch]->element_brate, scaleTableStereo, SIZE_SCALE_TABLE_STEREO );
    1225             : 
    1226             :         /* quantize gain */
    1227         942 :         gain_idx[ch] = (int16_t) floor( gain[ch] * 1.5f + GAIN_Q_OFFSET_IVAS + .5f );
    1228         942 :         gain_idx[ch] = max( 0, min( 127, gain_idx[ch] ) );
    1229             : 
    1230         942 :         gain[ch] = ( (float) gain_idx[ch] - GAIN_Q_OFFSET_IVAS ) / 1.5f;
    1231             :     }
    1232             : 
    1233             :     /* restore channel noise envelopes */
    1234        1413 :     for ( ch = 0; ch < CPE_CHANNELS; ch++ )
    1235             :     {
    1236         942 :         HANDLE_FD_CNG_ENC hFdCngEnc = sts[ch]->hFdCngEnc;
    1237         942 :         HANDLE_FD_CNG_COM hFdCngCom = hFdCngEnc->hFdCngCom;
    1238             : 
    1239       22482 :         for ( p = 0; p < N; p++ )
    1240             :         {
    1241       21540 :             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         942 :         scalebands( lr_out_ptr[ch], hFdCngEnc->partDec, N, hFdCngEnc->midbandDec, hFdCngEnc->nFFTpartDec, hFdCngEnc->stopBandDec - hFdCngEnc->startBandDec, hFdCngCom->cngNoiseLevel, 1 );
    1246             : 
    1247         942 :         lpc_from_spectrum( hFdCngCom, hFdCngEnc->startBandDec, hFdCngEnc->stopFFTbinDec, sts[ch]->preemph_fac );
    1248             : 
    1249         942 :         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         471 :     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         471 :     coh_idx = max( 0, min( coh_idx, 15 ) );
    1259             : 
    1260             :     /* ---- Write SID bitstream ---- */
    1261             : 
    1262             : 
    1263             :     /* noise shapes and channel gains */
    1264        1413 :     for ( ch = 0; ch < CPE_CHANNELS; ch++ )
    1265             :     {
    1266         942 :         if ( ch )
    1267             :         {
    1268         471 :             stages = FD_CNG_JOINT_stages_25bits;
    1269         471 :             sts[ch]->hBstr->ind_list = sts[0]->hBstr->ind_list + sts[0]->hBstr->nb_ind_tot;
    1270             : 
    1271             :             /* side info */
    1272         471 :             push_indice( sts[ch]->hBstr, IND_SID_TYPE, coh_idx, 4 );
    1273         471 :             push_indice( sts[ch]->hBstr, IND_SID_TYPE, no_side_flag, 1 );
    1274             :         }
    1275             :         else
    1276             :         {
    1277         471 :             stages = FD_CNG_stages_37bits;
    1278             :             /* side info */
    1279         471 :             push_indice( sts[ch]->hBstr, IND_SID_TYPE, 1, 1 );
    1280         471 :             push_indice( sts[ch]->hBstr, IND_BWIDTH, sts[0]->bwidth, 2 );
    1281         471 :             push_indice( sts[ch]->hBstr, IND_ACELP_16KHZ, sts[0]->L_frame == L_FRAME16k ? 1 : 0, 1 );
    1282             :         }
    1283             : 
    1284        5652 :         for ( int16_t i = 0; i < stages; i++ )
    1285             :         {
    1286        4710 :             push_indice( sts[ch]->hBstr, IND_LSF, indices[ch][i], bits_37bits[i] );
    1287             :         }
    1288         942 :         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        2355 :     for ( int16_t b = 1; b < MDCT_ST_DTX_NUM_COHERENCE_BANDS; b++ )
    1294             :     {
    1295        1884 :         coh_idx = (int16_t) floor( sts[0]->hFdCngEnc->hFdCngCom->coherence[b] * 15.f + 0.5f );
    1296        1884 :         coh_idx = max( 0, min( coh_idx, 15 ) );
    1297        1884 :         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         471 :     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         231 : 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         231 :     invTrfMatrix = (float *) tmpRAM; /* dynamically filled  */
    1337             : 
    1338             :     /* set pointers and initialize */
    1339         693 :     for ( ch = 0; ch < CPE_CHANNELS; ch++ )
    1340             :     {
    1341         462 :         sts[ch] = hCPE->hCoreCoder[ch];
    1342         462 :         N[ch] = sts[ch]->hFdCngEnc->npartDec;
    1343         462 :         lr_in_ptr[ch] = &sts[ch]->hFdCngEnc->msNoiseEst[0];
    1344         462 :         ms_ptr[ch] = &logNoiseEst[ch][0];
    1345         462 :         lr_out_ptr[ch] = &sts[ch]->hFdCngEnc->hFdCngCom->sidNoiseEst[0];
    1346             :     }
    1347         231 :     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         693 :     for ( ch = 0; ch < CPE_CHANNELS; ch++ )
    1354             :     {
    1355         462 :         E[ch] = 0.0f;
    1356       11550 :         for ( p = 0; p < N[ch]; p++ )
    1357             :         {
    1358       11088 :             ms_ptr[ch][p] = 10.f * log10f( lr_in_ptr[ch][p] + EPSILON );
    1359       11088 :             E[ch] += ms_ptr[ch][p];
    1360             :         }
    1361             :     }
    1362             : 
    1363             :     /* M/S transform on log envelopes */
    1364         231 :     convertToMS( N[0], ms_ptr[0], ms_ptr[1], 0.5f );
    1365             : 
    1366         231 :     E[0] = sum_f( ms_ptr[0], N[0] );
    1367             : 
    1368             :     /* Quantize M noise shape */
    1369             :     /* Normalize MSVQ input */
    1370         231 :     gain[0] = sum_f( ms_ptr[0] + N_GAIN_MIN, N_GAIN_MAX - N_GAIN_MIN );
    1371         231 :     gain[0] /= (float) ( N_GAIN_MAX - N_GAIN_MIN );
    1372             : 
    1373        5775 :     for ( p = 0; p < N[0]; p++ )
    1374             :     {
    1375        5544 :         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         231 :     if ( N[0] == FDCNG_VQ_MAX_LEN_WB )
    1382             :     {
    1383           0 :         create_IDCT_N_Matrix( invTrfMatrix, N[0], FDCNG_VQ_DCT_MAXTRUNC, sizeof( tmpRAM ) / ( sizeof( float ) ) );
    1384             :         /* truncated DCT 21 analysis */
    1385           0 :         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           0 :         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           0 :         mvr2r( tot_sig_ext, ms_ptr[0], FDCNG_VQ_MAX_LEN ); /*  write  extended result as input to  VQ stage #1 */
    1390             :     }
    1391         231 :     create_IDCT_N_Matrix( invTrfMatrix, FDCNG_VQ_MAX_LEN, FDCNG_VQ_DCT_MAXTRUNC, sizeof( tmpRAM ) / ( sizeof( float ) ) );
    1392             : 
    1393         231 :     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         231 :     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         231 :     set_zero( ms_ptr[1], NPART );
    1399             : 
    1400             :     /* compute M gain */
    1401         231 :     gain[0] = sum_f( ms_ptr[0], N[0] );
    1402         231 :     gain[0] = ( E[0] - gain[0] ) / (float) N[0];
    1403         231 :     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         231 :     gain_idx[0] = (int16_t) floor( gain[0] * 1.5f + GAIN_Q_OFFSET_IVAS + .5f );
    1407         231 :     gain_idx[0] = max( 0, min( 127, gain_idx[0] ) );
    1408             : 
    1409         231 :     gain[0] = ( (float) gain_idx[0] - GAIN_Q_OFFSET_IVAS ) / 1.5f;
    1410         231 :     gain[1] = gain[0];
    1411             : 
    1412             :     /* undo M/S */
    1413         231 :     convertToMS( NPART, ms_ptr[0], ms_ptr[1], 1.0f );
    1414             : 
    1415             :     /* restore channel noise envelopes */
    1416         693 :     for ( ch = 0; ch < CPE_CHANNELS; ch++ )
    1417             :     {
    1418         462 :         HANDLE_FD_CNG_ENC hFdCngEnc = sts[ch]->hFdCngEnc;
    1419         462 :         HANDLE_FD_CNG_COM hFdCngCom = hFdCngEnc->hFdCngCom;
    1420             : 
    1421       11550 :         for ( p = 0; p < N[0]; p++ )
    1422             :         {
    1423       11088 :             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         462 :         if ( hFdCngCom->CngBandwidth == NB )
    1428             :         {
    1429           0 :             lr_out_ptr[ch][N[ch] - 1] *= NB_LAST_BAND_SCALE;
    1430             :         }
    1431         462 :         else if ( hFdCngCom->CngBandwidth == SWB && hFdCngCom->CngBitrate <= ACELP_13k20 )
    1432             :         {
    1433           0 :             lr_out_ptr[ch][N[ch] - 1] *= SWB_13k2_LAST_BAND_SCALE;
    1434             :         }
    1435             : 
    1436             :         /* scale bands and get scalefactors */
    1437         462 :         scalebands( lr_out_ptr[ch], hFdCngEnc->partDec, N[ch], hFdCngEnc->midbandDec, hFdCngEnc->nFFTpartDec, hFdCngEnc->stopBandDec - hFdCngEnc->startBandDec, hFdCngCom->cngNoiseLevel, 1 );
    1438             : 
    1439         462 :         lpc_from_spectrum( hFdCngCom, hFdCngEnc->startBandDec, hFdCngEnc->stopFFTbinDec, sts[ch]->preemph_fac );
    1440             : 
    1441         462 :         sts[ch]->hDtxEnc->last_CNG_L_frame = sts[ch]->L_frame;
    1442             :     }
    1443             : #ifdef NONBE_MDCT_ST_DTX_FIX_SUBOPT_SPATIAL_CNG
    1444         231 :     sts[0]->hFdCngEnc->hFdCngCom->coherence[0] = 0.0f;
    1445         231 :     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         231 :     push_indice( sts[0]->hBstr, IND_SID_TYPE, 1, 1 );
    1455         231 :     push_indice( sts[0]->hBstr, IND_BWIDTH, sts[0]->bwidth, 2 );
    1456         231 :     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        1617 :     for ( int16_t i = 0; i < FD_CNG_stages_37bits; i++ )
    1460             :     {
    1461        1386 :         push_indice( sts[0]->hBstr, IND_LSF, indices[0][i], bits_37bits[i] );
    1462             :     }
    1463         231 :     push_indice( sts[0]->hBstr, IND_ENERGY, gain_idx[0], 7 );
    1464             : 
    1465         231 :     return;
    1466             : }

Generated by: LCOV version 1.14