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

Generated by: LCOV version 1.14