LCOV - code coverage report
Current view: top level - lib_com - fd_cng_com.c (source / functions) Hit Total Coverage
Test: Coverage on main -- short test vectors @ 6c9ddc4024a9c0e1ecb8f643f114a84a0e26ec6b Lines: 434 445 97.5 %
Date: 2025-05-23 08:37:30 Functions: 18 18 100.0 %

          Line data    Source code
       1             : /******************************************************************************************************
       2             : 
       3             :    (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB,
       4             :    Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
       5             :    Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
       6             :    Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
       7             :    contributors to this repository. All Rights Reserved.
       8             : 
       9             :    This software is protected by copyright law and by international treaties.
      10             :    The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB,
      11             :    Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
      12             :    Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
      13             :    Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
      14             :    contributors to this repository retain full ownership rights in their respective contributions in
      15             :    the software. This notice grants no license of any kind, including but not limited to patent
      16             :    license, nor is any license granted by implication, estoppel or otherwise.
      17             : 
      18             :    Contributors are required to enter into the IVAS codec Public Collaboration agreement before making
      19             :    contributions.
      20             : 
      21             :    This software is provided "AS IS", without any express or implied warranties. The software is in the
      22             :    development stage. It is intended exclusively for experts who have experience with such software and
      23             :    solely for the purpose of inspection. All implied warranties of non-infringement, merchantability
      24             :    and fitness for a particular purpose are hereby disclaimed and excluded.
      25             : 
      26             :    Any dispute, controversy or claim arising under or in relation to providing this software shall be
      27             :    submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in
      28             :    accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and
      29             :    the United Nations Convention on Contracts on the International Sales of Goods.
      30             : 
      31             : *******************************************************************************************************/
      32             : 
      33             : /*====================================================================================
      34             :     EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0
      35             :   ====================================================================================*/
      36             : 
      37             : #include <assert.h>
      38             : #include <stdint.h>
      39             : #include "options.h"
      40             : #ifdef DEBUGGING
      41             : #include "debug.h"
      42             : #endif
      43             : #include <math.h>
      44             : #include "prot.h"
      45             : #include "rom_com.h"
      46             : #include "wmc_auto.h"
      47             : 
      48             : 
      49             : /*-------------------------------------------------------------------
      50             :  * Local function prototypes
      51             :  *-------------------------------------------------------------------*/
      52             : 
      53             : static void mhvals( const int16_t d, float *m );
      54             : 
      55             : static void getmidbands( int16_t *part, const int16_t npart, int16_t *midband, float *psize, float *psize_inv );
      56             : 
      57             : 
      58             : /*-------------------------------------------------------------------
      59             :  * createFdCngCom()
      60             :  *
      61             :  * Create an instance of type FD_CNG_COM
      62             :  *-------------------------------------------------------------------*/
      63             : 
      64       23802 : ivas_error createFdCngCom(
      65             :     HANDLE_FD_CNG_COM *hFdCngCom /* i/o: FD_CNG structure containing all buffers and variables */
      66             : )
      67             : {
      68             :     HANDLE_FD_CNG_COM hs;
      69             : 
      70             :     /* Allocate memory */
      71       23802 :     if ( ( hs = (HANDLE_FD_CNG_COM) malloc( sizeof( FD_CNG_COM ) ) ) == NULL )
      72             :     {
      73           0 :         return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for FD CNG COM" );
      74             :     }
      75             : 
      76       23802 :     *hFdCngCom = hs;
      77             : 
      78       23802 :     return IVAS_ERR_OK;
      79             : }
      80             : 
      81             : 
      82             : /*-------------------------------------------------------------------
      83             :  * initFdCngCom()
      84             :  *
      85             :  *
      86             :  *-------------------------------------------------------------------*/
      87             : 
      88       23802 : void initFdCngCom(
      89             :     HANDLE_FD_CNG_COM hFdCngCom, /* i/o: FD_CNG structure containing all buffers and variables */
      90             :     const float scale )
      91             : {
      92             :     /* Calculate FFT scaling factor */
      93       23802 :     hFdCngCom->scalingFactor = 1 / ( scale * scale * 8.f );
      94             : 
      95             :     /* Initialize the overlap-add */
      96       23802 :     set_f( hFdCngCom->timeDomainBuffer, 0.0f, L_FRAME16k );
      97       23802 :     set_f( hFdCngCom->olapBufferAna, 0.0f, FFTLEN );
      98       23802 :     set_f( hFdCngCom->olapBufferSynth, 0.0f, FFTLEN );
      99       23802 :     set_f( hFdCngCom->olapBufferSynth2, 0.0f, FFTLEN );
     100             : 
     101             :     /* Initialize the comfort noise generation */
     102       23802 :     set_f( hFdCngCom->fftBuffer, 0.0f, FFTLEN );
     103       23802 :     set_f( hFdCngCom->cngNoiseLevel, 0.0f, FFTCLDFBLEN );
     104             : 
     105             :     /* Initialize quantizer */
     106       23802 :     set_f( hFdCngCom->sidNoiseEst, 0.0f, NPART );
     107       23802 :     set_f( hFdCngCom->A_cng, 0.0f, M + 1 );
     108       23802 :     hFdCngCom->A_cng[0] = 1.f;
     109             : 
     110             :     /* Set some counters and flags */
     111       23802 :     hFdCngCom->inactive_frame_counter = 0; /* Either SID or zero frames */
     112       23802 :     hFdCngCom->active_frame_counter = 0;
     113       23802 :     hFdCngCom->frame_type_previous = ACTIVE_FRAME;
     114       23802 :     hFdCngCom->flag_noisy_speech = 0;
     115       23802 :     hFdCngCom->likelihood_noisy_speech = 0.f;
     116       23802 :     hFdCngCom->numCoreBands = 0;
     117       23802 :     hFdCngCom->stopBand = 0;
     118       23802 :     hFdCngCom->startBand = 0;
     119       23802 :     hFdCngCom->stopFFTbin = 0;
     120       23802 :     hFdCngCom->frameSize = 0;
     121       23802 :     hFdCngCom->fftlen = 0;
     122       23802 :     hFdCngCom->seed = 0;
     123       23802 :     hFdCngCom->seed2 = 1;
     124       23802 :     hFdCngCom->seed3 = 2;
     125       23802 :     hFdCngCom->CngBitrate = -1;
     126             : 
     127             :     /* Initialize noise estimation algorithm */
     128       23802 :     set_f( hFdCngCom->periodog, 0.0f, PERIODOGLEN );
     129       23802 :     mhvals( MSNUMSUBFR * MSSUBFRLEN, &( hFdCngCom->msM_win ) );
     130       23802 :     mhvals( MSSUBFRLEN, &( hFdCngCom->msM_subwin ) );
     131       23802 :     set_f( hFdCngCom->msPeriodogSum, 0.0f, 2 );
     132       23802 :     set_f( hFdCngCom->msPsdSum, 0.0f, 2 );
     133       23802 :     set_f( hFdCngCom->msSlope, 0.0f, 2 );
     134       23802 :     set_f( hFdCngCom->msQeqInvAv, 0.0f, 2 );
     135       23802 :     hFdCngCom->msFrCnt_init_counter = 0;
     136       23802 :     hFdCngCom->msFrCnt_init_thresh = 1;
     137       23802 :     hFdCngCom->init_old = 0;
     138       23802 :     hFdCngCom->offsetflag = 0;
     139       23802 :     hFdCngCom->msFrCnt = MSSUBFRLEN;
     140       23802 :     hFdCngCom->msMinBufferPtr = 0;
     141       23802 :     set_f( hFdCngCom->msAlphaCor, 0.3f, 2 );
     142             : 
     143       23802 :     hFdCngCom->coherence = 0.5f;
     144             : 
     145       23802 :     return;
     146             : }
     147             : 
     148             : 
     149             : /*-------------------------------------------------------------------
     150             :  * deleteFdCngCom()
     151             :  *
     152             :  * Delete an instance of type FD_CNG_COM
     153             :  *-------------------------------------------------------------------*/
     154             : 
     155       23802 : void deleteFdCngCom(
     156             :     HANDLE_FD_CNG_COM *hFdCngCom /* i/o: FD_CNG structure containing all buffers and variables */
     157             : )
     158             : {
     159       23802 :     HANDLE_FD_CNG_COM hsCom = *hFdCngCom;
     160             : 
     161       23802 :     if ( hsCom != NULL )
     162             :     {
     163       23802 :         free( hsCom );
     164       23802 :         *hFdCngCom = NULL;
     165             :     }
     166             : 
     167       23802 :     return;
     168             : }
     169             : 
     170             : 
     171             : /*-------------------------------------------------------------------
     172             :  * initPartitions()
     173             :  *
     174             :  * Initialize the spectral partitioning
     175             :  *-------------------------------------------------------------------*/
     176             : 
     177     3552887 : void initPartitions(
     178             :     const int16_t *part_in,
     179             :     const int16_t npart_in,
     180             :     const int16_t startBand,
     181             :     const int16_t stopBand,
     182             :     int16_t *part_out,
     183             :     int16_t *npart_out,
     184             :     int16_t *midband,
     185             :     float *psize,
     186             :     float *psize_inv,
     187             :     const int16_t stopBandFR )
     188             : {
     189             :     int16_t i, j, len_out;
     190             : 
     191     3552887 :     if ( part_in != NULL )
     192             :     {
     193     3552887 :         if ( stopBandFR > startBand )
     194             :         {
     195     1758441 :             len_out = stopBandFR - startBand; /*part_out*/
     196    68579199 :             for ( i = 0; i < len_out; i++ )
     197             :             {
     198    66820758 :                 part_out[i] = i;
     199             :             }
     200             :         }
     201             :         else
     202             :         {
     203     1794446 :             len_out = 0;
     204             :         } /*npart_in,part_out*/
     205   115177877 :         for ( j = 0; j < npart_in && part_in[j] < stopBand; j++ )
     206             :         {
     207   111624990 :             if ( part_in[j] >= stopBandFR && part_in[j] >= startBand )
     208             :             {
     209    83489934 :                 part_out[len_out++] = part_in[j] - startBand;
     210             :             }
     211             :         }
     212             :     }
     213             :     else
     214             :     {
     215           0 :         len_out = stopBand - startBand; /*part_out*/
     216           0 :         for ( i = 0; i < len_out; i++ )
     217             :         {
     218           0 :             part_out[i] = i;
     219             :         }
     220             :     }
     221             : 
     222     3552887 :     *npart_out = len_out;
     223     3552887 :     getmidbands( part_out, len_out, midband, psize, psize_inv );
     224             : 
     225     3552887 :     return;
     226             : }
     227             : 
     228             : 
     229             : /*-------------------------------------------------------------------
     230             :  * compress_range()
     231             :  *
     232             :  * Apply some dynamic range compression based on the log
     233             :  *-------------------------------------------------------------------*/
     234             : 
     235      272315 : void compress_range(
     236             :     float *in,
     237             :     float *out,
     238             :     const int16_t len )
     239             : {
     240      272315 :     float *ptrIn = in;
     241      272315 :     float *ptrOut = out;
     242             :     int16_t i;
     243             : 
     244             :     /* out = log2( 1 + in ) */
     245    12304829 :     for ( i = 0; i < len; i++ )
     246             :     {
     247    12032514 :         *ptrOut = (float) log10( *ptrIn + 1.f );
     248    12032514 :         ptrIn++;
     249    12032514 :         ptrOut++;
     250             :     }
     251      272315 :     v_multc( out, 1.f / (float) log10( 2.f ), out, len );
     252             : 
     253             :     /* Quantize to simulate a fixed-point representation 6Q9 */
     254      272315 :     v_multc( out, CNG_LOG_SCALING, out, len );
     255    12304829 :     for ( ptrOut = out; ptrOut < out + len; ptrOut++ )
     256             :     {
     257    12032514 :         *ptrOut = (float) ( (int16_t) ( *ptrOut + 0.5f ) );
     258    12032514 :         if ( *ptrOut == 0.f )
     259             :         {
     260     2007324 :             *ptrOut = 1.f;
     261             :         }
     262             :     }
     263      272315 :     v_multc( out, 1. / CNG_LOG_SCALING, out, len );
     264             : 
     265      272315 :     return;
     266             : }
     267             : 
     268             : 
     269             : /*-------------------------------------------------------------------
     270             :  * expand_range()
     271             :  *
     272             :  * Apply some dynamic range expansion to undo the compression
     273             :  *-------------------------------------------------------------------*/
     274             : 
     275      272315 : void expand_range(
     276             :     float *in,
     277             :     float *out,
     278             :     const int16_t len )
     279             : {
     280      272315 :     float *ptrIn = in;
     281      272315 :     float *ptrOut = out;
     282             :     int16_t i;
     283             : 
     284             :     /* out = (2^(in) - 1) */
     285    12304829 :     for ( i = 0; i < len; i++ )
     286             :     {
     287    12032514 :         *ptrOut = (float) pow( 2.f, *ptrIn ) - 1.f;
     288    12032514 :         if ( *ptrOut < 0.0003385080526823181f )
     289             :         {
     290       52996 :             *ptrOut = 0.0003385080526823181f;
     291             :         }
     292    12032514 :         ptrIn++;
     293    12032514 :         ptrOut++;
     294             :     }
     295             : 
     296      272315 :     return;
     297             : }
     298             : 
     299             : 
     300             : /*-------------------------------------------------------------------
     301             :  * minimum_statistics()
     302             :  *
     303             :  * Noise estimation using Minimum Statistics (MS)
     304             :  *-------------------------------------------------------------------*/
     305             : 
     306      272315 : void minimum_statistics(
     307             :     const int16_t len,    /* i  : Vector length */
     308             :     const int16_t lenFFT, /* i  : Length of the FFT part of the vectors */
     309             :     float *psize,
     310             :     float *msPeriodog, /* i  : Periodograms */
     311             :     float *msNoiseFloor,
     312             :     float *msNoiseEst, /* o  : Noise estimates */
     313             :     float *msAlpha,
     314             :     float *msPsd,
     315             :     float *msPsdFirstMoment,
     316             :     float *msPsdSecondMoment,
     317             :     float *msMinBuf,
     318             :     float *msBminWin,
     319             :     float *msBminSubWin,
     320             :     float *msCurrentMin,
     321             :     float *msCurrentMinOut,
     322             :     float *msCurrentMinSubWindow,
     323             :     int16_t *msLocalMinFlag,
     324             :     int16_t *msNewMinFlag,
     325             :     float *msPeriodogBuf,
     326             :     int16_t *msPeriodogBufPtr,
     327             :     HANDLE_FD_CNG_COM hFdCngCom, /* i/o: FD_CNG structure containing all buffers and variables */
     328             :     const int16_t enc_dec,       /* i  : encoder/decoder indicator */
     329             :     const int16_t element_mode   /* i  : IVAS element mode type    */
     330             : )
     331             : {
     332      272315 :     float msM_win = hFdCngCom->msM_win;
     333      272315 :     float msM_subwin = hFdCngCom->msM_subwin;
     334      272315 :     float *msPsdSum = hFdCngCom->msPsdSum;
     335      272315 :     float *msPeriodogSum = hFdCngCom->msPeriodogSum;
     336             :     float slope;
     337             :     float *ptr;
     338      272315 :     float msAlphaCorAlpha = MSALPHACORALPHA;
     339      272315 :     float msAlphaCorAlpha2 = 1.f - MSALPHACORALPHA;
     340             : 
     341             :     int16_t i, j, k;
     342             :     float scalar, scalar2, scalar3;
     343             :     float snr, BminCorr, QeqInv, QeqInvAv;
     344             :     float beta;
     345             :     float msAlphaHatMin2;
     346      272315 :     int16_t len2 = MSNUMSUBFR * len;
     347             :     int16_t current_len;
     348             :     int16_t start, stop, cnt;
     349             :     int16_t totsize;
     350      272315 :     const float inv_buflen = 1.f / MSBUFLEN;
     351             : 
     352             :     /* No minimum statistics at initialization */
     353      272315 :     if ( hFdCngCom->msFrCnt_init_counter < hFdCngCom->msFrCnt_init_thresh )
     354             :     {
     355       18766 :         mvr2r( msPeriodog, msPsd, len );
     356       18766 :         mvr2r( msPeriodog, msNoiseFloor, len );
     357       18766 :         mvr2r( msPeriodog, msNoiseEst, len );
     358       18766 :         mvr2r( msPeriodog, msPsdFirstMoment, len );
     359       18766 :         set_f( msPsdSecondMoment, 0.0f, len );
     360       18766 :         msPeriodogSum[0] = dotp( msPeriodog, psize, lenFFT );
     361       18766 :         msPsdSum[0] = msPeriodogSum[0];
     362       18766 :         if ( lenFFT < len )
     363             :         {
     364        2614 :             msPeriodogSum[1] = dotp( msPeriodog + lenFFT, psize + lenFFT, len - lenFFT );
     365        2614 :             msPsdSum[1] = msPeriodogSum[1];
     366             :         }
     367             : 
     368             :         /* Increment frame counter at initialization */
     369             :         /* Some frames are sometimes zero at initialization => ignore them */
     370       18766 :         if ( msPeriodog[0] < hFdCngCom->init_old )
     371             :         {
     372        3754 :             set_f( msCurrentMinOut, FLT_MAX, len );
     373        3754 :             set_f( msCurrentMin, FLT_MAX, len );
     374        3754 :             set_f( msMinBuf, FLT_MAX, len2 );
     375        3754 :             set_f( msCurrentMinSubWindow, FLT_MAX, len );
     376        3754 :             hFdCngCom->msFrCnt_init_counter++;
     377             :         }
     378       18766 :         hFdCngCom->init_old = msPeriodog[0];
     379             :     }
     380             :     else
     381             :     {
     382             : 
     383             :         /* Consider the FFT and CLDFB bands separately
     384             :            - first iteration for FFT bins,
     385             :            - second one for CLDFB bands in SWB mode */
     386      253549 :         start = 0;
     387      253549 :         stop = lenFFT;
     388      253549 :         totsize = hFdCngCom->stopFFTbin - hFdCngCom->startBand;
     389      253549 :         cnt = 0; /*msAlphaCor*/
     390      628716 :         while ( stop > start )
     391             :         {
     392      375167 :             current_len = stop - start;
     393             : 
     394             :             /* Compute smoothed correction factor for PSD smoothing */
     395      375167 :             msPeriodogSum[cnt] = dotp( msPeriodog + start, psize + start, current_len );
     396      375167 :             scalar = msPeriodogSum[cnt] * msPeriodogSum[cnt] + DELTA;
     397      375167 :             scalar2 = msPsdSum[cnt] - msPeriodogSum[cnt];
     398      375167 :             scalar = max( scalar / ( scalar + scalar2 * scalar2 ), MSALPHACORMAX );
     399      375167 :             hFdCngCom->msAlphaCor[cnt] = msAlphaCorAlpha * hFdCngCom->msAlphaCor[cnt] + msAlphaCorAlpha2 * scalar;
     400             : 
     401             :             /* Compute SNR */
     402      375167 :             snr = dotp( msNoiseFloor + start, psize + start, current_len );
     403      375167 :             snr = ( msPsdSum[cnt] + DELTA ) / ( snr + DELTA );
     404      375167 :             snr = (float) pow( snr, MSSNREXP );
     405      375167 :             msAlphaHatMin2 = min( MSALPHAHATMIN, snr );
     406      375167 :             scalar = MSALPHAMAX * hFdCngCom->msAlphaCor[cnt]; /*msAlpha,msPsd,msPeriodog,msNoiseFloor*/
     407    11351693 :             for ( j = start; j < stop; j++ )
     408             :             {
     409             :                 /* Compute optimal smoothing parameter for PSD estimation */
     410    10976526 :                 scalar2 = msNoiseFloor[j] + DELTA;
     411    10976526 :                 scalar2 *= scalar2;
     412    10976526 :                 scalar3 = msPsd[j] - msNoiseFloor[j];
     413    10976526 :                 msAlpha[j] = max( ( scalar * scalar2 ) / ( scalar2 + scalar3 * scalar3 ), msAlphaHatMin2 );
     414             : 
     415             :                 /* Compute the PSD (smoothed periodogram) in each band */
     416    10976526 :                 msPsd[j] = msAlpha[j] * msPsd[j] + ( 1.f - msAlpha[j] ) * msPeriodog[j];
     417             :             }
     418      375167 :             msPsdSum[cnt] = dotp( msPsd + start, psize + start, current_len );
     419      375167 :             QeqInvAv = 0;
     420      375167 :             scalar = ( (float) ( MSNUMSUBFR * MSSUBFRLEN ) - 1.f ) * ( 1.f - msM_win );
     421      375167 :             scalar2 = ( (float) MSSUBFRLEN - 1.f ) * ( 1.f - msM_subwin ); /*msAlpha,msPsd,msPsdFirstMoment,msPsdSecondMoment,msNoiseFloor,msBminSubWin,msBminWin,psize*/
     422    11351693 :             for ( j = start; j < stop; j++ )
     423             :             {
     424             :                 /* Compute variance of PSD */
     425    10976526 :                 beta = min( msAlpha[j] * msAlpha[j], MSBETAMAX );
     426    10976526 :                 scalar3 = msPsd[j] - msPsdFirstMoment[j];
     427    10976526 :                 msPsdFirstMoment[j] = beta * msPsdFirstMoment[j] + ( 1.f - beta ) * msPsd[j];
     428    10976526 :                 msPsdSecondMoment[j] = beta * msPsdSecondMoment[j] + ( 1.f - beta ) * scalar3 * scalar3;
     429             :                 /* Compute inverse of amount of degrees of freedom */
     430    10976526 :                 QeqInv = min( ( msPsdSecondMoment[j] + DELTA ) / ( 2.f * msNoiseFloor[j] * msNoiseFloor[j] + DELTA ), MSQEQINVMAX );
     431    10976526 :                 QeqInvAv += QeqInv * psize[j];
     432             : 
     433             :                 /* Compute bias correction Bmin */
     434    10976526 :                 msBminWin[j] = 1.f + scalar * QeqInv / ( 0.5f - msM_win * QeqInv );
     435    10976526 :                 msBminSubWin[j] = 1.f + scalar2 * QeqInv / ( 0.5f - msM_subwin * QeqInv );
     436             :             }
     437      375167 :             QeqInvAv /= totsize;
     438      375167 :             hFdCngCom->msQeqInvAv[cnt] = QeqInvAv;
     439             : 
     440             :             /* New minimum? */
     441      375167 :             BminCorr = 1.f + MSAV * (float) sqrt( QeqInvAv ); /*msPsd,msBminWin,msNewMinFlag,msCurrentMin,msCurrentMinSubWindow*/
     442    11351693 :             for ( j = start; j < stop; j++ )
     443             :             {
     444    10976526 :                 scalar = BminCorr * msPsd[j];
     445    10976526 :                 scalar2 = scalar * msBminWin[j];
     446    10976526 :                 if ( scalar2 < msCurrentMin[j] )
     447             :                 {
     448     5277574 :                     msNewMinFlag[j] = 1;
     449     5277574 :                     msCurrentMin[j] = scalar2;
     450     5277574 :                     msCurrentMinSubWindow[j] = scalar * msBminSubWin[j];
     451             :                 }
     452             :                 else
     453             :                 {
     454     5698952 :                     msNewMinFlag[j] = 0;
     455             :                 }
     456             :             }
     457             : 
     458             :             /* This is used later to identify local minima */
     459      375167 :             if ( hFdCngCom->msFrCnt >= MSSUBFRLEN )
     460             :             {
     461       33206 :                 i = 0;
     462       74022 :                 while ( i < 3 )
     463             :                 {
     464       63576 :                     if ( hFdCngCom->msQeqInvAv[cnt] < msQeqInvAv_thresh[i] )
     465             :                     {
     466       22760 :                         break;
     467             :                     }
     468             :                     else
     469             :                     {
     470       40816 :                         i++;
     471             :                     }
     472             :                 }
     473       33206 :                 hFdCngCom->msSlope[cnt] = msNoiseSlopeMax[i];
     474             :             }
     475             : 
     476             :             /* Consider the FFT and CLDFB bands separately */
     477      375167 :             start = stop;
     478      375167 :             stop = len;
     479      375167 :             totsize = hFdCngCom->stopBand - hFdCngCom->stopFFTbin;
     480      375167 :             cnt++;
     481             :         } /*while (stop > start)*/
     482             : 
     483             :         /* Update minimum between sub windows */
     484      253549 :         if ( hFdCngCom->msFrCnt > 1 && hFdCngCom->msFrCnt < MSSUBFRLEN )
     485             :         {
     486             :             /*msNewMinFlag,msCurrentMinSubWindow,msCurrentMinOut*/
     487     9176681 :             for ( j = 0; j < len; j++ )
     488             :             {
     489     8968542 :                 if ( msNewMinFlag[j] > 0 )
     490             :                 {
     491     3833633 :                     msLocalMinFlag[j] = 1;
     492             :                 }
     493     8968542 :                 if ( msCurrentMinSubWindow[j] < msCurrentMinOut[j] )
     494             :                 {
     495     1869347 :                     msCurrentMinOut[j] = msCurrentMinSubWindow[j];
     496             :                 }
     497             :             }
     498             :             /* Get the current noise floor */
     499      208139 :             mvr2r( msCurrentMinOut, msNoiseFloor, len );
     500             :         }
     501             : 
     502             :         /* sub window complete */
     503             :         else
     504             :         {
     505       45410 :             if ( hFdCngCom->msFrCnt >= MSSUBFRLEN )
     506             :             {
     507             :                 /* Collect buffers */
     508       22855 :                 mvr2r( msCurrentMinSubWindow, msMinBuf + len * hFdCngCom->msMinBufferPtr, len );
     509             : 
     510             :                 /* Compute minimum among all buffers */
     511       22855 :                 mvr2r( msMinBuf, msCurrentMinOut, len );
     512       22855 :                 ptr = msMinBuf + len;
     513      137130 :                 for ( i = 1; i < MSNUMSUBFR; i++ )
     514             :                 {
     515             :                     /*msCurrentMinOut*/
     516     5178305 :                     for ( j = 0; j < len; j++ )
     517             :                     {
     518     5064030 :                         if ( *ptr < msCurrentMinOut[j] )
     519             :                         {
     520     1169149 :                             msCurrentMinOut[j] = *ptr;
     521             :                         }
     522     5064030 :                         ptr++;
     523             :                     }
     524             :                 }
     525             : 
     526             :                 /* Take over local minima */
     527       22855 :                 slope = hFdCngCom->msSlope[0]; /*msLocalMinFlag,msNewMinFlag,msCurrentMinSubWindow,msCurrentMinOut*/
     528     1035661 :                 for ( j = 0; j < len; j++ )
     529             :                 {
     530     1012806 :                     if ( j == lenFFT )
     531             :                     {
     532       10351 :                         slope = hFdCngCom->msSlope[1];
     533             :                     }
     534     1012806 :                     if ( msLocalMinFlag[j] && !msNewMinFlag[j] &&
     535      460467 :                          msCurrentMinSubWindow[j] < slope * msCurrentMinOut[j] &&
     536      309798 :                          msCurrentMinSubWindow[j] > msCurrentMinOut[j] )
     537             :                     {
     538      115685 :                         msCurrentMinOut[j] = msCurrentMinSubWindow[j];
     539      115685 :                         i = j;
     540      809795 :                         for ( k = 0; k < MSNUMSUBFR; k++ )
     541             :                         {
     542      694110 :                             msMinBuf[i] = msCurrentMinOut[j];
     543      694110 :                             i += len;
     544             :                         }
     545             :                     }
     546             :                 }
     547             : 
     548             :                 /* Reset */
     549       22855 :                 set_s( msLocalMinFlag, 0, len );
     550       22855 :                 set_f( msCurrentMin, FLT_MAX, len );
     551             : 
     552             :                 /* Get the current noise floor */
     553       22855 :                 mvr2r( msCurrentMinOut, msNoiseFloor, len );
     554             :             }
     555             :         }
     556             : 
     557             :         /* Detect sudden offsets based on the FFT bins (core bandwidth) */
     558      253549 :         if ( msPsdSum[0] > 50.f * msPeriodogSum[0] )
     559             :         {
     560         643 :             if ( hFdCngCom->offsetflag > 0 )
     561             :             {
     562         241 :                 mvr2r( msPeriodog, msPsd, len );
     563         241 :                 mvr2r( msPeriodog, msCurrentMinOut, len );
     564         241 :                 set_f( hFdCngCom->msAlphaCor, 1.0f, cnt );
     565         241 :                 set_f( msAlpha, 0.0f, len );
     566         241 :                 mvr2r( msPeriodog, msPsdFirstMoment, len );
     567         241 :                 set_f( msPsdSecondMoment, 0.0f, len );
     568         241 :                 msPsdSum[0] = dotp( msPeriodog, psize, lenFFT );
     569         241 :                 if ( lenFFT < len )
     570             :                 {
     571          16 :                     msPsdSum[1] = dotp( msPeriodog + lenFFT, psize + lenFFT, len - lenFFT );
     572             :                 }
     573             :             }
     574         643 :             hFdCngCom->offsetflag = 1;
     575             :         }
     576             :         else
     577             :         {
     578      252906 :             hFdCngCom->offsetflag = 0;
     579             :         }
     580             : 
     581             :         /* Increment frame counter */
     582      253549 :         if ( hFdCngCom->msFrCnt == MSSUBFRLEN )
     583             :         {
     584       22855 :             hFdCngCom->msFrCnt = 1;
     585       22855 :             hFdCngCom->msMinBufferPtr++;
     586       22855 :             if ( hFdCngCom->msMinBufferPtr == MSNUMSUBFR )
     587             :             {
     588        2909 :                 hFdCngCom->msMinBufferPtr = 0;
     589             :             }
     590             :         }
     591             :         else
     592             :         {
     593      230694 :             ( hFdCngCom->msFrCnt )++;
     594             :         }
     595             : 
     596             :         /* Smooth noise estimate during CNG phases */ /*msNoiseEst,msNoiseFloor*/
     597    11230075 :         for ( j = 0; j < len; j++ )
     598             :         {
     599    10976526 :             msNoiseEst[j] = 0.95f * msNoiseEst[j] + 0.05f * msNoiseFloor[j];
     600             :         }
     601             :     }
     602             : 
     603      272315 :     if ( enc_dec == DEC && element_mode == IVAS_CPE_TD )
     604             :     {
     605           0 :         v_multc( msNoiseEst, 1.4125f, msNoiseEst, NPART_SHAPING );
     606             :     }
     607             : 
     608             :     /* Collect buffers */
     609      272315 :     mvr2r( msPeriodog, msPeriodogBuf + len * ( *msPeriodogBufPtr ), len );
     610             : 
     611      272315 :     ( *msPeriodogBufPtr )++;
     612      272315 :     if ( ( *msPeriodogBufPtr ) == MSBUFLEN )
     613             :     {
     614       53069 :         ( *msPeriodogBufPtr ) = 0;
     615             :     }
     616             : 
     617             :     /* Upper limit the noise floors with the averaged input energy */ /*msNoiseEst*/
     618    12304829 :     for ( j = 0; j < len; j++ )
     619             :     {
     620    12032514 :         scalar = msPeriodogBuf[j];
     621    60162570 :         for ( i = j + len; i < MSBUFLEN * len; i += len )
     622             :         {
     623    48130056 :             scalar += msPeriodogBuf[i];
     624             :         } /*division by a constant = multiplication by its (constant) inverse */
     625    12032514 :         scalar *= inv_buflen;
     626    12032514 :         if ( msNoiseEst[j] > scalar )
     627             :         {
     628     3791241 :             msNoiseEst[j] = scalar;
     629             :         }
     630    12032514 :         assert( msNoiseEst[j] >= 0 );
     631             :     }
     632             : 
     633      272315 :     return;
     634             : }
     635             : 
     636             : 
     637             : /*-------------------------------------------------------------------
     638             :  * apply_scale()
     639             :  *
     640             :  * Apply bitrate-dependent scale
     641             :  *-------------------------------------------------------------------*/
     642             : 
     643      566595 : void apply_scale(
     644             :     float *scale,                  /* o  : scalefactor             */
     645             :     const int16_t bwidth,          /* i  : audio bandwidth         */
     646             :     const int32_t brate,           /* i  : Bit rate                */
     647             :     const SCALE_SETUP *scaleTable, /* i  : Scale table             */
     648             :     const int16_t scaleTableSize   /* i  : Size of scale table     */
     649             : )
     650             : {
     651             :     int16_t i;
     652             : 
     653     5960730 :     for ( i = 0; i < scaleTableSize; i++ )
     654             :     {
     655     5960730 :         if ( ( bwidth == scaleTable[i].bwmode ) &&
     656     2539263 :              ( brate >= scaleTable[i].bitrateFrom ) &&
     657     2539263 :              ( brate < scaleTable[i].bitrateTo ) )
     658             :         {
     659      566595 :             break;
     660             :         }
     661             :     }
     662             : 
     663      566595 :     assert( i < scaleTableSize );
     664             : 
     665      566595 :     *scale += scaleTable[i].scale;
     666             : 
     667      566595 :     return;
     668             : }
     669             : 
     670             : 
     671             : /*-------------------------------------------------------------------
     672             :  * bandcombinepow()
     673             :  *
     674             :  * Compute the power for each partition
     675             :  *-------------------------------------------------------------------*/
     676             : 
     677      299720 : void bandcombinepow(
     678             :     const float *bandpow,   /* i  : Power for each band                       */
     679             :     const int16_t nband,    /* i  : Number of bands                           */
     680             :     int16_t *part,          /* i  : Partition upper boundaries (band indices starting from 0) */
     681             :     const int16_t npart,    /* i  : Number of partitions                      */
     682             :     const float *psize_inv, /* i  : Inverse partition sizes                   */
     683             :     float *partpow          /* o  : Power for each partition                  */
     684             : )
     685             : {
     686             :     int16_t i, p;
     687             :     float temp;
     688             : 
     689      299720 :     if ( nband == npart )
     690             :     {
     691           0 :         mvr2r( bandpow, partpow, nband );
     692             :     }
     693             :     else
     694             :     {
     695             :         /* Compute the power in each partition */
     696      299720 :         i = 0; /*part,partpow,psize_inv*/
     697    11076853 :         for ( p = 0; p < npart; p++ )
     698             :         {
     699             :             /* Arithmetic averaging of power for all bins in partition */
     700    10777133 :             temp = 0;
     701    63928557 :             for ( ; i <= part[p]; i++ )
     702             :             {
     703    53151424 :                 temp += bandpow[i];
     704             :             }
     705    10777133 :             partpow[p] = temp * psize_inv[p];
     706             :         }
     707             :     }
     708             : 
     709      299720 :     return;
     710             : }
     711             : 
     712             : 
     713             : /*-------------------------------------------------------------------
     714             :  * scalebands()
     715             :  *
     716             :  * Scale partitions (with smoothing)
     717             :  *-------------------------------------------------------------------*/
     718             : 
     719      322450 : void scalebands(
     720             :     const float *partpow,   /* i  : Power for each partition                                    */
     721             :     int16_t *part,          /* i  : Partition upper boundaries (band indices starting from 0)   */
     722             :     const int16_t npart,    /* i  : Number of partitions                                        */
     723             :     int16_t *midband,       /* i  : Central band of each partition                              */
     724             :     const int16_t nFFTpart, /* i  : Number of FFT partitions                                    */
     725             :     const int16_t nband,    /* i  : Number of bands                                             */
     726             :     float *bandpow,         /* o  : Power for each band                                         */
     727             :     const int16_t flag_fft_en )
     728             : {
     729      322450 :     int16_t i, j = 0, nint, startBand, startPart, stopPart;
     730      322450 :     float val, delta = 0.f;
     731             : 
     732             :     /* Interpolate the bin/band-wise levels from the partition levels */
     733      322450 :     if ( nband == npart )
     734             :     {
     735           0 :         mvr2r( partpow, bandpow, npart );
     736             :     }
     737             :     else
     738             :     {
     739      322450 :         startBand = 0;
     740      322450 :         startPart = 0;
     741      322450 :         stopPart = nFFTpart;
     742      658962 :         while ( startBand < nband )
     743             :         {
     744      336512 :             if ( flag_fft_en || startPart >= nFFTpart )
     745             :             {
     746             : 
     747             :                 /* first half partition */
     748      332252 :                 j = startPart;
     749      332252 :                 val = partpow[j];
     750      710852 :                 for ( i = startBand; i <= midband[j]; i++ )
     751             :                 {
     752      378600 :                     bandpow[i] = val;
     753             :                 }
     754      332252 :                 j++;
     755             : 
     756      332252 :                 delta = 1;
     757             :                 /* inner partitions */
     758    19101639 :                 for ( ; j < stopPart; j++ )
     759             :                 {
     760    18769387 :                     nint = midband[j] - midband[j - 1];
     761             :                     /* log-linear interpolation */ /* Only one new LOG needs to be computed per loop iteration */
     762    18769387 :                     delta = (float) exp( ( log( partpow[j] + DELTA ) - log( partpow[j - 1] + DELTA ) ) * normReciprocal[nint] );
     763    18769387 :                     val = partpow[j - 1];
     764    88899547 :                     for ( ; i < midband[j]; i++ )
     765             :                     {
     766    70130160 :                         val *= delta;
     767    70130160 :                         bandpow[i] = val;
     768             :                     }
     769    18769387 :                     bandpow[i++] = partpow[j];
     770             :                 }
     771      332252 :                 if ( delta > 1.f )
     772             :                 {
     773       59865 :                     delta = 1.f;
     774             :                 }
     775             : 
     776             :                 /* last half partition */
     777      332252 :                 val = partpow[stopPart - 1];
     778     3112215 :                 for ( ; i <= part[stopPart - 1]; i++ )
     779             :                 {
     780     2779963 :                     val *= delta;
     781     2779963 :                     bandpow[i] = val;
     782             :                 }
     783             :             }
     784      336512 :             startBand = part[stopPart - 1] + 1;
     785      336512 :             startPart = stopPart;
     786      336512 :             stopPart = npart;
     787             :         }
     788             :     }
     789             : 
     790      322450 :     return;
     791             : }
     792             : 
     793             : 
     794             : /*-------------------------------------------------------------------
     795             :  * getmidbands()
     796             :  *
     797             :  * Get central band for each partition
     798             :  *-------------------------------------------------------------------*/
     799             : 
     800     3552887 : static void getmidbands(
     801             :     int16_t *part,       /* i  : Partition upper boundaries (band indices starting from 0)  */
     802             :     const int16_t npart, /* i  : Number of partitions                                       */
     803             :     int16_t *midband,    /* o  : Central band of each partition                             */
     804             :     float *psize,        /* o  : Partition sizes                                            */
     805             :     float *psize_inv     /* o  : Inverse of partition sizes                                 */
     806             : )
     807             : {
     808             :     int16_t j;
     809             : 
     810             :     /* first half partition */
     811     3552887 :     midband[0] = part[0];
     812     3552887 :     psize[0] = (float) part[0] + 1.f;
     813     3552887 :     psize_inv[0] = normReciprocal[part[0] + 1];
     814             : 
     815             :     /* inner partitions */ /*part,midband,psize_inv*/
     816   150310692 :     for ( j = 1; j < npart; j++ )
     817             :     {
     818   146757805 :         midband[j] = ( part[j - 1] + 1 + part[j] ) >> 1;
     819   146757805 :         psize[j] = (float) ( part[j] - part[j - 1] );
     820   146757805 :         psize_inv[j] = normReciprocal[part[j] - part[j - 1]];
     821             :     }
     822             : 
     823     3552887 :     return;
     824             : }
     825             : 
     826             : 
     827             : /*-------------------------------------------------------------------
     828             :  * AnalysisSTFT()
     829             :  *
     830             :  * STFT analysis filterbank
     831             :  *-------------------------------------------------------------------*/
     832             : 
     833      287547 : void AnalysisSTFT(
     834             :     const float *timeDomainInput,
     835             :     float *fftBuffer,           /* o  : FFT bins                                              */
     836             :     HANDLE_FD_CNG_COM hFdCngCom /* i/o: FD_CNG structure containing all buffers and variables */
     837             : )
     838             : {
     839      287547 :     float *olapBuffer = hFdCngCom->olapBufferAna;
     840      287547 :     const float *olapWin = hFdCngCom->olapWinAna;
     841             : 
     842             :     /* Shift and cascade for overlap-add */
     843      287547 :     mvr2r( olapBuffer + hFdCngCom->frameSize, olapBuffer, hFdCngCom->fftlen - hFdCngCom->frameSize );
     844      287547 :     mvr2r( timeDomainInput, olapBuffer + hFdCngCom->fftlen - hFdCngCom->frameSize, hFdCngCom->frameSize );
     845             : 
     846             :     /* Window the signal */
     847      287547 :     v_mult( olapBuffer, olapWin, fftBuffer, hFdCngCom->fftlen );
     848             : 
     849             :     /* Perform FFT */
     850      287547 :     RFFTN( fftBuffer, hFdCngCom->fftSineTab, hFdCngCom->fftlen, -1 );
     851             : 
     852      287547 :     return;
     853             : }
     854             : 
     855             : 
     856             : /*-------------------------------------------------------------------
     857             :  * SynthesisSTFT()
     858             :  *
     859             :  * STFT synthesis filterbank
     860             :  *-------------------------------------------------------------------*/
     861             : 
     862      272562 : void SynthesisSTFT(
     863             :     float *fftBuffer, /* i  : FFT bins */
     864             :     float *timeDomainOutput,
     865             :     float *olapBuffer,
     866             :     const float *olapWin,
     867             :     const int16_t tcx_transition,
     868             :     HANDLE_FD_CNG_COM hFdCngCom, /* i/o: FD_CNG structure containing all buffers and variables */
     869             :     const int16_t element_mode,  /* i  : element mode */
     870             :     const int16_t nchan_out      /* i  : number of output channels */
     871             : )
     872             : {
     873             :     int16_t i;
     874             :     float buf[M + 1 + 320], tmp;
     875             : 
     876             :     /* Perform IFFT */
     877      272562 :     RFFTN( fftBuffer, hFdCngCom->fftSineTab, hFdCngCom->fftlen, 1 );
     878             : 
     879             :     /* Handle overlap in P/S domain for stereo */
     880      272562 :     if ( ( element_mode == IVAS_CPE_TD || element_mode == IVAS_CPE_DFT ) && nchan_out == 2 )
     881             :     {
     882        2688 :         mvr2r( olapBuffer + 3 * hFdCngCom->frameSize / 4 - ( M + 1 ), buf, hFdCngCom->frameSize + M + 1 );
     883        2688 :         set_f( olapBuffer, 0.0f, hFdCngCom->fftlen );
     884             :     }
     885             :     else
     886             :     {
     887      269874 :         mvr2r( olapBuffer + hFdCngCom->frameSize, olapBuffer, hFdCngCom->frameSize );
     888      269874 :         set_f( olapBuffer + hFdCngCom->frameSize, 0.0f, hFdCngCom->frameSize ); /*olapBuffer, fftBuffer, olapWin*/
     889             :     }
     890             : 
     891      272562 :     if ( tcx_transition )
     892             :     {
     893     2067154 :         for ( i = 0; i < 5 * hFdCngCom->frameSize / 4; i++ )
     894             :         {
     895     2061120 :             olapBuffer[i] = fftBuffer[i];
     896             :         }
     897             :     }
     898             :     else
     899             :     {
     900    38264704 :         for ( i = hFdCngCom->frameSize / 4; i < 3 * hFdCngCom->frameSize / 4; i++ )
     901             :         {
     902    37998176 :             olapBuffer[i] += fftBuffer[i] * olapWin[i - hFdCngCom->frameSize / 4];
     903             :         }
     904    38264704 :         for ( ; i < 5 * hFdCngCom->frameSize / 4; i++ )
     905             :         {
     906    37998176 :             olapBuffer[i] = fftBuffer[i];
     907             :         }
     908             :     }
     909    39095186 :     for ( ; i < 7 * hFdCngCom->frameSize / 4; i++ )
     910             :     {
     911    38822624 :         olapBuffer[i] = fftBuffer[i] * olapWin[i - 3 * hFdCngCom->frameSize / 4];
     912             :     }
     913             : 
     914    19683874 :     for ( ; i < hFdCngCom->fftlen; i++ )
     915             :     {
     916    19411312 :         olapBuffer[i] = 0;
     917             :     }
     918             : 
     919             :     /* Get time-domain signal */
     920      272562 :     v_multc( olapBuffer + hFdCngCom->frameSize / 4, (float) ( hFdCngCom->fftlen / 2 ), timeDomainOutput, hFdCngCom->frameSize );
     921             : 
     922             :     /* Get excitation */
     923      272562 :     if ( ( element_mode == IVAS_CPE_TD || element_mode == IVAS_CPE_DFT ) && nchan_out == 2 )
     924             :     {
     925      346752 :         for ( i = 0; i < hFdCngCom->frameSize / 2; i++ )
     926             :         {
     927      344064 :             buf[i + ( M + 1 )] += olapBuffer[i + hFdCngCom->frameSize / 4];
     928             :         }
     929        2688 :         v_multc( buf, (float) ( hFdCngCom->fftlen / 2 ), buf, M + 1 + hFdCngCom->frameSize );
     930             :     }
     931             :     else
     932             :     {
     933      269874 :         v_multc( olapBuffer + hFdCngCom->frameSize / 4 - ( M + 1 ), (float) ( hFdCngCom->fftlen / 2 ), buf, M + 1 + hFdCngCom->frameSize );
     934             :     }
     935             : 
     936      272562 :     tmp = buf[0];
     937      272562 :     preemph( buf + 1, PREEMPH_FAC, M + hFdCngCom->frameSize, &tmp );
     938      272562 :     residu( hFdCngCom->A_cng, M, buf + 1 + M, hFdCngCom->exc_cng, hFdCngCom->frameSize );
     939             : 
     940      272562 :     return;
     941             : }
     942             : 
     943             : 
     944             : /*-------------------------------------------------------------------
     945             :  * SynthesisSTFT_dirac()
     946             :  *
     947             :  * STFT synthesis filterbank
     948             :  *-------------------------------------------------------------------*/
     949             : 
     950       13485 : void SynthesisSTFT_dirac(
     951             :     float *fftBuffer, /* i  : FFT bins */
     952             :     float *timeDomainOutput,
     953             :     float *olapBuffer,
     954             :     const float *olapWin,
     955             :     const int16_t samples_out,
     956             :     HANDLE_FD_CNG_COM hFdCngCom /* i/o: FD_CNG structure containing all buffers and variables */
     957             : )
     958             : {
     959             :     int16_t i;
     960             :     float buf[M + 1 + 320], tmp;
     961             : 
     962             :     /* Perform IFFT */
     963       13485 :     RFFTN( fftBuffer, hFdCngCom->fftSineTab, hFdCngCom->fftlen, 1 );
     964             : 
     965             :     /* Handle overlap in P/S domain for stereo */
     966       13485 :     mvr2r( olapBuffer + hFdCngCom->frameSize, olapBuffer, hFdCngCom->frameSize );
     967       13485 :     set_f( olapBuffer + hFdCngCom->frameSize, 0.0f, hFdCngCom->frameSize ); /*olapBuffer, fftBuffer, olapWin*/
     968             : 
     969     1989933 :     for ( i = hFdCngCom->frameSize / 4; i < 3 * hFdCngCom->frameSize / 4; i++ )
     970             :     {
     971     1976448 :         olapBuffer[i] += fftBuffer[i] * olapWin[i - hFdCngCom->frameSize / 4];
     972             :     }
     973     1989933 :     for ( ; i < 5 * hFdCngCom->frameSize / 4; i++ )
     974             :     {
     975     1976448 :         olapBuffer[i] = fftBuffer[i];
     976             :     }
     977             : 
     978     1989933 :     for ( ; i < 7 * hFdCngCom->frameSize / 4; i++ )
     979             :     {
     980     1976448 :         olapBuffer[i] = fftBuffer[i];
     981             :     }
     982             : 
     983     1001709 :     for ( ; i < hFdCngCom->fftlen; i++ )
     984             :     {
     985      988224 :         olapBuffer[i] = 0;
     986             :     }
     987             : 
     988             :     /* Get time-domain signal */
     989       13485 :     v_multc( olapBuffer + hFdCngCom->frameSize / 4, (float) ( hFdCngCom->fftlen / 2 ), timeDomainOutput, samples_out );
     990             : 
     991             :     /* Get excitation */
     992       13485 :     v_multc( olapBuffer + hFdCngCom->frameSize / 4 - ( M + 1 ), (float) ( hFdCngCom->fftlen / 2 ), buf, M + 1 + hFdCngCom->frameSize );
     993       13485 :     tmp = buf[0];
     994       13485 :     preemph( buf + 1, PREEMPH_FAC, M + hFdCngCom->frameSize, &tmp );
     995       13485 :     residu( hFdCngCom->A_cng, M, buf + 1 + M, hFdCngCom->exc_cng, hFdCngCom->frameSize );
     996             : 
     997             :     /* update and window olapBuf if we have a output frame that is shorter than the default frame size...*/
     998       13485 :     if ( samples_out < hFdCngCom->frameSize )
     999             :     {
    1000           0 :         mvr2r( olapBuffer + samples_out, olapBuffer + hFdCngCom->frameSize, 3 * hFdCngCom->frameSize / 4 );
    1001             :     }
    1002     1989933 :     for ( i = 5 * hFdCngCom->frameSize / 4; i < 7 * hFdCngCom->frameSize / 4; i++ )
    1003             :     {
    1004     1976448 :         olapBuffer[i] *= olapWin[i - 3 * hFdCngCom->frameSize / 4];
    1005             :     }
    1006             : 
    1007       13485 :     return;
    1008             : }
    1009             : 
    1010             : 
    1011             : /*-------------------------------------------------------------------
    1012             :  * mhvals()
    1013             :  *
    1014             :  * Compute some values used in the bias correction of the minimum statistics algorithm
    1015             :  *-------------------------------------------------------------------*/
    1016             : 
    1017       47604 : static void mhvals(
    1018             :     const int16_t d,
    1019             :     float *m )
    1020             : {
    1021             :     int16_t i, j;
    1022             :     float qi, qj, q;
    1023       47604 :     int16_t len = SIZE_SCALE_TABLE_CN;
    1024             : 
    1025       47604 :     i = 0;
    1026      404634 :     for ( i = 0; i < len; i++ )
    1027             :     {
    1028      404634 :         if ( d <= d_array[i] )
    1029             :         {
    1030       47604 :             break;
    1031             :         }
    1032             :     }
    1033       47604 :     if ( i == len )
    1034             :     {
    1035           0 :         i = len - 1;
    1036           0 :         j = i;
    1037             :     }
    1038             :     else
    1039             :     {
    1040       47604 :         j = i - 1;
    1041             :     }
    1042       47604 :     if ( d == d_array[i] )
    1043             :     {
    1044           0 :         *m = m_array[i];
    1045             :     }
    1046             :     else
    1047             :     {
    1048       47604 :         qj = (float) sqrt( (float) d_array[i - 1] ); /*interpolate using sqrt(d)*/
    1049       47604 :         qi = (float) sqrt( (float) d_array[i] );
    1050       47604 :         q = (float) sqrt( (float) d );
    1051       47604 :         *m = m_array[i] + ( qi * qj / q - qj ) * ( m_array[j] - m_array[i] ) / ( qi - qj );
    1052             :     }
    1053             : 
    1054       47604 :     return;
    1055             : }
    1056             : 
    1057             : /*-------------------------------------------------------------------
    1058             :  * rand_gauss()
    1059             :  *
    1060             :  * Random generator with Gaussian distribution with mean 0 and std 1
    1061             :  *-------------------------------------------------------------------*/
    1062             : 
    1063   435379217 : float rand_gauss(
    1064             :     float *x,
    1065             :     int16_t *seed )
    1066             : {
    1067             :     float temp;
    1068             : 
    1069   435379217 :     temp = (float) own_random( seed );
    1070   435379217 :     temp += (float) own_random( seed );
    1071   435379217 :     temp += (float) own_random( seed );
    1072   435379217 :     temp *= OUTMAX_INV;
    1073             : 
    1074   435379217 :     *x = temp;
    1075             : 
    1076   435379217 :     return temp;
    1077             : }
    1078             : 
    1079             : 
    1080             : /*-------------------------------------------------------------------
    1081             :  * lpc_from_spectrum()
    1082             :  *
    1083             :  *
    1084             :  *-------------------------------------------------------------------*/
    1085             : 
    1086       16498 : void lpc_from_spectrum(
    1087             :     HANDLE_FD_CNG_COM hFdCngCom,
    1088             :     const int16_t start,
    1089             :     const int16_t stop,
    1090             :     const float preemph_fac )
    1091             : {
    1092             :     int16_t i;
    1093             :     float r[32], nf;
    1094             :     float fftBuffer[FFTLEN], *ptr, *pti;
    1095             : 
    1096       16498 :     float *powspec = hFdCngCom->cngNoiseLevel;
    1097       16498 :     int16_t fftlen = hFdCngCom->fftlen;
    1098       16498 :     const float *fftSineTab = hFdCngCom->fftSineTab;
    1099       16498 :     float *A = hFdCngCom->A_cng;
    1100             : 
    1101             :     /* Power Spectrum */
    1102       16498 :     ptr = fftBuffer;
    1103       16498 :     pti = fftBuffer + 1;
    1104       16498 :     nf = 1e-3f;
    1105       49494 :     for ( i = 0; i < start; i++ )
    1106             :     {
    1107       32996 :         *ptr = nf;
    1108       32996 :         *pti = 0.f;
    1109       32996 :         ptr += 2;
    1110       32996 :         pti += 2;
    1111             :     }
    1112     4868878 :     for ( ; i < stop; i++ )
    1113             :     {
    1114     4852380 :         *ptr = max( nf, powspec[i - start] );
    1115     4852380 :         *pti = 0.f;
    1116     4852380 :         ptr += 2;
    1117     4852380 :         pti += 2;
    1118             :     }
    1119       17074 :     for ( ; i < fftlen / 2; i++ )
    1120             :     {
    1121         576 :         *ptr = nf;
    1122         576 :         *pti = 0.f;
    1123         576 :         ptr += 2;
    1124         576 :         pti += 2;
    1125             :     }
    1126       16498 :     fftBuffer[1] = nf;
    1127             : 
    1128             :     /* Pre-emphasis */
    1129       16498 :     ptr = fftBuffer;
    1130     4902450 :     for ( i = 0; i < fftlen / 2; i++ )
    1131             :     {
    1132     4885952 :         *ptr *= ( 1.f + preemph_fac * preemph_fac - 2.0f * preemph_fac * (float) cos( -2.0f * EVS_PI * (float) i / (float) fftlen ) );
    1133             : 
    1134     4885952 :         ptr += 2;
    1135             :     }
    1136       16498 :     fftBuffer[1] *= ( 1.f + preemph_fac * preemph_fac + 2.0f * preemph_fac );
    1137             : 
    1138             :     /* Autocorrelation */
    1139       16498 :     RFFTN( fftBuffer, fftSineTab, fftlen, 1 );
    1140      296964 :     for ( i = 0; i <= M; i++ )
    1141             :     {
    1142      280466 :         r[i] = fftBuffer[i] * ( fftlen / 2 ) * ( fftlen / 2 );
    1143             :     }
    1144       16498 :     if ( r[0] < 100.f )
    1145             :     {
    1146        1299 :         r[0] = 100.f;
    1147             :     }
    1148             : 
    1149       16498 :     r[0] *= 1.0005f;
    1150             : 
    1151             :     /* LPC */
    1152       16498 :     lev_dur( A, r, M, NULL );
    1153             : 
    1154       16498 :     return;
    1155             : }
    1156             : 
    1157             : 
    1158             : /*-------------------------------------------------------------------
    1159             :  * FdCng_exc()
    1160             :  *
    1161             :  * Generate FD-CNG as LP excitation
    1162             :  *-------------------------------------------------------------------*/
    1163             : 
    1164       67845 : void FdCng_exc(
    1165             :     HANDLE_FD_CNG_COM hFdCngCom,
    1166             :     int16_t *CNG_mode,
    1167             :     const int16_t L_frame,
    1168             :     const float *lsp_old,
    1169             :     const int16_t first_CNG,
    1170             :     float *lspCNG,
    1171             :     float *Aq,      /* o  : LPC coeffs */
    1172             :     float *lsp_new, /* o  : lsp  */
    1173             :     float *lsf_new, /* o  : lsf  */
    1174             :     float *exc,     /* o  : LP excitation   */
    1175             :     float *exc2,    /* o  : LP excitation   */
    1176             :     float *bwe_exc  /* o  : LP excitation for BWE */
    1177             : )
    1178             : {
    1179             :     int16_t i;
    1180       67845 :     *CNG_mode = -1;
    1181             : 
    1182             :     /*Get excitation */
    1183      379912 :     for ( i = 0; i < L_frame / L_SUBFR; i++ )
    1184             :     {
    1185      312067 :         mvr2r( hFdCngCom->A_cng, Aq + i * ( M + 1 ), M + 1 );
    1186             :     }
    1187             : 
    1188       67845 :     a2lsp_stab( Aq, lsp_new, lsp_old );
    1189             : 
    1190       67845 :     if ( first_CNG == 0 )
    1191             :     {
    1192       27337 :         mvr2r( lsp_old, lspCNG, M );
    1193             :     }
    1194             : 
    1195     1153365 :     for ( i = 0; i < M; i++ )
    1196             :     {
    1197             :         /* AR low-pass filter  */
    1198     1085520 :         lspCNG[i] = CNG_ISF_FACT * lspCNG[i] + ( 1 - CNG_ISF_FACT ) * lsp_new[i];
    1199             :     }
    1200             : 
    1201       67845 :     if ( L_frame == L_FRAME16k )
    1202             :     {
    1203       40687 :         lsp2lsf( lsp_new, lsf_new, M, INT_FS_16k );
    1204             :     }
    1205             :     else
    1206             :     {
    1207       27158 :         lsp2lsf( lsp_new, lsf_new, M, INT_FS_12k8 );
    1208             :     }
    1209             : 
    1210       67845 :     mvr2r( hFdCngCom->exc_cng, exc, L_frame );
    1211       67845 :     mvr2r( hFdCngCom->exc_cng, exc2, L_frame );
    1212             : 
    1213       67845 :     if ( bwe_exc )
    1214             :     {
    1215       46200 :         if ( L_frame == L_FRAME )
    1216             :         {
    1217       27158 :             interp_code_5over2( exc2, bwe_exc, L_frame );
    1218             :         }
    1219             :         else
    1220             :         {
    1221       19042 :             interp_code_4over2( exc2, bwe_exc, L_frame );
    1222             :         }
    1223             :     }
    1224             : 
    1225       67845 :     return;
    1226             : }

Generated by: LCOV version 1.14