LCOV - code coverage report
Current view: top level - lib_com - fd_cng_com.c (source / functions) Hit Total Coverage
Test: Coverage on main -- merged total coverage @ 9b04ec3cb36f5e8dc438cf854fa3e349998fa1e9 Lines: 435 445 97.8 %
Date: 2025-10-31 05:45:46 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 "ivas_cnst.h"
      38             : #include <assert.h>
      39             : #include <stdint.h>
      40             : #include "options.h"
      41             : #ifdef DEBUGGING
      42             : #include "debug.h"
      43             : #endif
      44             : #include <math.h>
      45             : #include "prot.h"
      46             : #include "rom_com.h"
      47             : #include "wmc_auto.h"
      48             : 
      49             : 
      50             : /*-------------------------------------------------------------------
      51             :  * Local function prototypes
      52             :  *-------------------------------------------------------------------*/
      53             : 
      54             : static void mhvals( const int16_t d, float *m );
      55             : 
      56             : static void getmidbands( int16_t *part, const int16_t npart, int16_t *midband, float *psize, float *psize_inv );
      57             : 
      58             : 
      59             : /*-------------------------------------------------------------------
      60             :  * createFdCngCom()
      61             :  *
      62             :  * Create an instance of type FD_CNG_COM
      63             :  *-------------------------------------------------------------------*/
      64             : 
      65      595638 : ivas_error createFdCngCom(
      66             :     HANDLE_FD_CNG_COM *hFdCngCom /* i/o: FD_CNG structure containing all buffers and variables */
      67             : )
      68             : {
      69             :     HANDLE_FD_CNG_COM hs;
      70             : 
      71             :     /* Allocate memory */
      72      595638 :     if ( ( hs = (HANDLE_FD_CNG_COM) malloc( sizeof( FD_CNG_COM ) ) ) == NULL )
      73             :     {
      74           0 :         return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for FD CNG COM" );
      75             :     }
      76             : 
      77      595638 :     *hFdCngCom = hs;
      78             : 
      79      595638 :     return IVAS_ERR_OK;
      80             : }
      81             : 
      82             : 
      83             : /*-------------------------------------------------------------------
      84             :  * initFdCngCom()
      85             :  *
      86             :  *
      87             :  *-------------------------------------------------------------------*/
      88             : 
      89      595638 : void initFdCngCom(
      90             :     HANDLE_FD_CNG_COM hFdCngCom, /* i/o: FD_CNG structure containing all buffers and variables */
      91             :     const float scale )
      92             : {
      93             :     /* Calculate FFT scaling factor */
      94      595638 :     hFdCngCom->scalingFactor = 1 / ( scale * scale * 8.f );
      95             : 
      96             :     /* Initialize the overlap-add */
      97      595638 :     set_f( hFdCngCom->timeDomainBuffer, 0.0f, L_FRAME16k );
      98      595638 :     set_f( hFdCngCom->olapBufferAna, 0.0f, FFTLEN );
      99      595638 :     set_f( hFdCngCom->olapBufferSynth, 0.0f, FFTLEN );
     100      595638 :     set_f( hFdCngCom->olapBufferSynth2, 0.0f, FFTLEN );
     101             : 
     102             :     /* Initialize the comfort noise generation */
     103      595638 :     set_f( hFdCngCom->fftBuffer, 0.0f, FFTLEN );
     104      595638 :     set_f( hFdCngCom->cngNoiseLevel, 0.0f, FFTCLDFBLEN );
     105             : 
     106             :     /* Initialize quantizer */
     107      595638 :     set_f( hFdCngCom->sidNoiseEst, 0.0f, NPART );
     108      595638 :     set_f( hFdCngCom->A_cng, 0.0f, M + 1 );
     109      595638 :     hFdCngCom->A_cng[0] = 1.f;
     110             : 
     111             :     /* Set some counters and flags */
     112      595638 :     hFdCngCom->inactive_frame_counter = 0; /* Either SID or zero frames */
     113      595638 :     hFdCngCom->active_frame_counter = 0;
     114      595638 :     hFdCngCom->frame_type_previous = ACTIVE_FRAME;
     115      595638 :     hFdCngCom->flag_noisy_speech = 0;
     116      595638 :     hFdCngCom->likelihood_noisy_speech = 0.f;
     117      595638 :     hFdCngCom->numCoreBands = 0;
     118      595638 :     hFdCngCom->stopBand = 0;
     119      595638 :     hFdCngCom->startBand = 0;
     120      595638 :     hFdCngCom->stopFFTbin = 0;
     121      595638 :     hFdCngCom->frameSize = 0;
     122      595638 :     hFdCngCom->fftlen = 0;
     123      595638 :     hFdCngCom->seed = 0;
     124      595638 :     hFdCngCom->seed2 = 1;
     125      595638 :     hFdCngCom->seed3 = 2;
     126      595638 :     hFdCngCom->CngBitrate = -1;
     127             : 
     128             :     /* Initialize noise estimation algorithm */
     129      595638 :     set_f( hFdCngCom->periodog, 0.0f, PERIODOGLEN );
     130      595638 :     mhvals( MSNUMSUBFR * MSSUBFRLEN, &( hFdCngCom->msM_win ) );
     131      595638 :     mhvals( MSSUBFRLEN, &( hFdCngCom->msM_subwin ) );
     132      595638 :     set_f( hFdCngCom->msPeriodogSum, 0.0f, 2 );
     133      595638 :     set_f( hFdCngCom->msPsdSum, 0.0f, 2 );
     134      595638 :     set_f( hFdCngCom->msSlope, 0.0f, 2 );
     135      595638 :     set_f( hFdCngCom->msQeqInvAv, 0.0f, 2 );
     136      595638 :     hFdCngCom->msFrCnt_init_counter = 0;
     137      595638 :     hFdCngCom->msFrCnt_init_thresh = 1;
     138      595638 :     hFdCngCom->init_old = 0;
     139      595638 :     hFdCngCom->offsetflag = 0;
     140      595638 :     hFdCngCom->msFrCnt = MSSUBFRLEN;
     141      595638 :     hFdCngCom->msMinBufferPtr = 0;
     142      595638 :     set_f( hFdCngCom->msAlphaCor, 0.3f, 2 );
     143             : 
     144             : #ifdef NONBE_MDCT_ST_DTX_FIX_SUBOPT_SPATIAL_CNG
     145      595638 :     set_f( hFdCngCom->coherence, 0.5f, MDCT_ST_DTX_NUM_COHERENCE_BANDS );
     146             : #else
     147             :     hFdCngCom->coherence = 0.5f;
     148             : #endif
     149             : 
     150      595638 :     return;
     151             : }
     152             : 
     153             : 
     154             : /*-------------------------------------------------------------------
     155             :  * deleteFdCngCom()
     156             :  *
     157             :  * Delete an instance of type FD_CNG_COM
     158             :  *-------------------------------------------------------------------*/
     159             : 
     160      595638 : void deleteFdCngCom(
     161             :     HANDLE_FD_CNG_COM *hFdCngCom /* i/o: FD_CNG structure containing all buffers and variables */
     162             : )
     163             : {
     164      595638 :     HANDLE_FD_CNG_COM hsCom = *hFdCngCom;
     165             : 
     166      595638 :     if ( hsCom != NULL )
     167             :     {
     168      595638 :         free( hsCom );
     169      595638 :         *hFdCngCom = NULL;
     170             :     }
     171             : 
     172      595638 :     return;
     173             : }
     174             : 
     175             : 
     176             : /*-------------------------------------------------------------------
     177             :  * initPartitions()
     178             :  *
     179             :  * Initialize the spectral partitioning
     180             :  *-------------------------------------------------------------------*/
     181             : 
     182    58255702 : void initPartitions(
     183             :     const int16_t *part_in,
     184             :     const int16_t npart_in,
     185             :     const int16_t startBand,
     186             :     const int16_t stopBand,
     187             :     int16_t *part_out,
     188             :     int16_t *npart_out,
     189             :     int16_t *midband,
     190             :     float *psize,
     191             :     float *psize_inv,
     192             :     const int16_t stopBandFR )
     193             : {
     194             :     int16_t i, j, len_out;
     195             : 
     196    58255702 :     if ( part_in != NULL )
     197             :     {
     198    58255702 :         if ( stopBandFR > startBand )
     199             :         {
     200    28864963 :             len_out = stopBandFR - startBand; /*part_out*/
     201  1125733557 :             for ( i = 0; i < len_out; i++ )
     202             :             {
     203  1096868594 :                 part_out[i] = i;
     204             :             }
     205             :         }
     206             :         else
     207             :         {
     208    29390739 :             len_out = 0;
     209             :         } /*npart_in,part_out*/
     210  1889062479 :         for ( j = 0; j < npart_in && part_in[j] < stopBand; j++ )
     211             :         {
     212  1830806777 :             if ( part_in[j] >= stopBandFR && part_in[j] >= startBand )
     213             :             {
     214  1368967369 :                 part_out[len_out++] = part_in[j] - startBand;
     215             :             }
     216             :         }
     217             :     }
     218             :     else
     219             :     {
     220           0 :         len_out = stopBand - startBand; /*part_out*/
     221           0 :         for ( i = 0; i < len_out; i++ )
     222             :         {
     223           0 :             part_out[i] = i;
     224             :         }
     225             :     }
     226             : 
     227    58255702 :     *npart_out = len_out;
     228    58255702 :     getmidbands( part_out, len_out, midband, psize, psize_inv );
     229             : 
     230    58255702 :     return;
     231             : }
     232             : 
     233             : 
     234             : /*-------------------------------------------------------------------
     235             :  * compress_range()
     236             :  *
     237             :  * Apply some dynamic range compression based on the log
     238             :  *-------------------------------------------------------------------*/
     239             : 
     240     6805286 : void compress_range(
     241             :     float *in,
     242             :     float *out,
     243             :     const int16_t len )
     244             : {
     245     6805286 :     float *ptrIn = in;
     246     6805286 :     float *ptrOut = out;
     247             :     int16_t i;
     248             : 
     249             :     /* out = log2( 1 + in ) */
     250   347939863 :     for ( i = 0; i < len; i++ )
     251             :     {
     252   341134577 :         *ptrOut = (float) log10( *ptrIn + 1.f );
     253   341134577 :         ptrIn++;
     254   341134577 :         ptrOut++;
     255             :     }
     256     6805286 :     v_multc( out, 1.f / (float) log10( 2.f ), out, len );
     257             : 
     258             :     /* Quantize to simulate a fixed-point representation 6Q9 */
     259     6805286 :     v_multc( out, CNG_LOG_SCALING, out, len );
     260   347939863 :     for ( ptrOut = out; ptrOut < out + len; ptrOut++ )
     261             :     {
     262   341134577 :         *ptrOut = (float) ( (int16_t) ( *ptrOut + 0.5f ) );
     263   341134577 :         if ( *ptrOut == 0.f )
     264             :         {
     265   113354163 :             *ptrOut = 1.f;
     266             :         }
     267             :     }
     268     6805286 :     v_multc( out, 1. / CNG_LOG_SCALING, out, len );
     269             : 
     270     6805286 :     return;
     271             : }
     272             : 
     273             : 
     274             : /*-------------------------------------------------------------------
     275             :  * expand_range()
     276             :  *
     277             :  * Apply some dynamic range expansion to undo the compression
     278             :  *-------------------------------------------------------------------*/
     279             : 
     280     6805295 : void expand_range(
     281             :     float *in,
     282             :     float *out,
     283             :     const int16_t len )
     284             : {
     285     6805295 :     float *ptrIn = in;
     286     6805295 :     float *ptrOut = out;
     287             :     int16_t i;
     288             : 
     289             :     /* out = (2^(in) - 1) */
     290   347940430 :     for ( i = 0; i < len; i++ )
     291             :     {
     292   341135135 :         *ptrOut = (float) pow( 2.f, *ptrIn ) - 1.f;
     293   341135135 :         if ( *ptrOut < 0.0003385080526823181f )
     294             :         {
     295     2859756 :             *ptrOut = 0.0003385080526823181f;
     296             :         }
     297   341135135 :         ptrIn++;
     298   341135135 :         ptrOut++;
     299             :     }
     300             : 
     301     6805295 :     return;
     302             : }
     303             : 
     304             : 
     305             : /*-------------------------------------------------------------------
     306             :  * minimum_statistics()
     307             :  *
     308             :  * Noise estimation using Minimum Statistics (MS)
     309             :  *-------------------------------------------------------------------*/
     310             : 
     311     6805286 : void minimum_statistics(
     312             :     const int16_t len,    /* i  : Vector length */
     313             :     const int16_t lenFFT, /* i  : Length of the FFT part of the vectors */
     314             :     float *psize,
     315             :     float *msPeriodog, /* i  : Periodograms */
     316             :     float *msNoiseFloor,
     317             :     float *msNoiseEst, /* o  : Noise estimates */
     318             :     float *msAlpha,
     319             :     float *msPsd,
     320             :     float *msPsdFirstMoment,
     321             :     float *msPsdSecondMoment,
     322             :     float *msMinBuf,
     323             :     float *msBminWin,
     324             :     float *msBminSubWin,
     325             :     float *msCurrentMin,
     326             :     float *msCurrentMinOut,
     327             :     float *msCurrentMinSubWindow,
     328             :     int16_t *msLocalMinFlag,
     329             :     int16_t *msNewMinFlag,
     330             :     float *msPeriodogBuf,
     331             :     int16_t *msPeriodogBufPtr,
     332             :     HANDLE_FD_CNG_COM hFdCngCom, /* i/o: FD_CNG structure containing all buffers and variables */
     333             :     const int16_t enc_dec,       /* i  : encoder/decoder indicator */
     334             :     const int16_t element_mode   /* i  : IVAS element mode type    */
     335             : )
     336             : {
     337     6805286 :     float msM_win = hFdCngCom->msM_win;
     338     6805286 :     float msM_subwin = hFdCngCom->msM_subwin;
     339     6805286 :     float *msPsdSum = hFdCngCom->msPsdSum;
     340     6805286 :     float *msPeriodogSum = hFdCngCom->msPeriodogSum;
     341             :     float slope;
     342             :     float *ptr;
     343     6805286 :     float msAlphaCorAlpha = MSALPHACORALPHA;
     344     6805286 :     float msAlphaCorAlpha2 = 1.f - MSALPHACORALPHA;
     345             : 
     346             :     int16_t i, j, k;
     347             :     float scalar, scalar2, scalar3;
     348             :     float snr, BminCorr, QeqInv, QeqInvAv;
     349             :     float beta;
     350             :     float msAlphaHatMin2;
     351     6805286 :     int16_t len2 = MSNUMSUBFR * len;
     352             :     int16_t current_len;
     353             :     int16_t start, stop, cnt;
     354             :     int16_t totsize;
     355     6805286 :     const float inv_buflen = 1.f / MSBUFLEN;
     356             : 
     357             :     /* No minimum statistics at initialization */
     358     6805286 :     if ( hFdCngCom->msFrCnt_init_counter < hFdCngCom->msFrCnt_init_thresh )
     359             :     {
     360      542606 :         mvr2r( msPeriodog, msPsd, len );
     361      542606 :         mvr2r( msPeriodog, msNoiseFloor, len );
     362      542606 :         mvr2r( msPeriodog, msNoiseEst, len );
     363      542606 :         mvr2r( msPeriodog, msPsdFirstMoment, len );
     364      542606 :         set_f( msPsdSecondMoment, 0.0f, len );
     365      542606 :         msPeriodogSum[0] = dotp( msPeriodog, psize, lenFFT );
     366      542606 :         msPsdSum[0] = msPeriodogSum[0];
     367      542606 :         if ( lenFFT < len )
     368             :         {
     369       58760 :             msPeriodogSum[1] = dotp( msPeriodog + lenFFT, psize + lenFFT, len - lenFFT );
     370       58760 :             msPsdSum[1] = msPeriodogSum[1];
     371             :         }
     372             : 
     373             :         /* Increment frame counter at initialization */
     374             :         /* Some frames are sometimes zero at initialization => ignore them */
     375      542606 :         if ( msPeriodog[0] < hFdCngCom->init_old )
     376             :         {
     377       75941 :             set_f( msCurrentMinOut, FLT_MAX, len );
     378       75941 :             set_f( msCurrentMin, FLT_MAX, len );
     379       75941 :             set_f( msMinBuf, FLT_MAX, len2 );
     380       75941 :             set_f( msCurrentMinSubWindow, FLT_MAX, len );
     381       75941 :             hFdCngCom->msFrCnt_init_counter++;
     382             :         }
     383      542606 :         hFdCngCom->init_old = msPeriodog[0];
     384             :     }
     385             :     else
     386             :     {
     387             : 
     388             :         /* Consider the FFT and CLDFB bands separately
     389             :            - first iteration for FFT bins,
     390             :            - second one for CLDFB bands in SWB mode */
     391     6262680 :         start = 0;
     392     6262680 :         stop = lenFFT;
     393     6262680 :         totsize = hFdCngCom->stopFFTbin - hFdCngCom->startBand;
     394     6262680 :         cnt = 0; /*msAlphaCor*/
     395    14480067 :         while ( stop > start )
     396             :         {
     397     8217387 :             current_len = stop - start;
     398             : 
     399             :             /* Compute smoothed correction factor for PSD smoothing */
     400     8217387 :             msPeriodogSum[cnt] = dotp( msPeriodog + start, psize + start, current_len );
     401     8217387 :             scalar = msPeriodogSum[cnt] * msPeriodogSum[cnt] + DELTA;
     402     8217387 :             scalar2 = msPsdSum[cnt] - msPeriodogSum[cnt];
     403     8217387 :             scalar = max( scalar / ( scalar + scalar2 * scalar2 ), MSALPHACORMAX );
     404     8217387 :             hFdCngCom->msAlphaCor[cnt] = msAlphaCorAlpha * hFdCngCom->msAlphaCor[cnt] + msAlphaCorAlpha2 * scalar;
     405             : 
     406             :             /* Compute SNR */
     407     8217387 :             snr = dotp( msNoiseFloor + start, psize + start, current_len );
     408     8217387 :             snr = ( msPsdSum[cnt] + DELTA ) / ( snr + DELTA );
     409     8217387 :             snr = (float) pow( snr, MSSNREXP );
     410     8217387 :             msAlphaHatMin2 = min( MSALPHAHATMIN, snr );
     411     8217387 :             scalar = MSALPHAMAX * hFdCngCom->msAlphaCor[cnt]; /*msAlpha,msPsd,msPeriodog,msNoiseFloor*/
     412   318259866 :             for ( j = start; j < stop; j++ )
     413             :             {
     414             :                 /* Compute optimal smoothing parameter for PSD estimation */
     415   310042479 :                 scalar2 = msNoiseFloor[j] + DELTA;
     416   310042479 :                 scalar2 *= scalar2;
     417   310042479 :                 scalar3 = msPsd[j] - msNoiseFloor[j];
     418   310042479 :                 msAlpha[j] = max( ( scalar * scalar2 ) / ( scalar2 + scalar3 * scalar3 ), msAlphaHatMin2 );
     419             : 
     420             :                 /* Compute the PSD (smoothed periodogram) in each band */
     421   310042479 :                 msPsd[j] = msAlpha[j] * msPsd[j] + ( 1.f - msAlpha[j] ) * msPeriodog[j];
     422             :             }
     423     8217387 :             msPsdSum[cnt] = dotp( msPsd + start, psize + start, current_len );
     424     8217387 :             QeqInvAv = 0;
     425     8217387 :             scalar = ( (float) ( MSNUMSUBFR * MSSUBFRLEN ) - 1.f ) * ( 1.f - msM_win );
     426     8217387 :             scalar2 = ( (float) MSSUBFRLEN - 1.f ) * ( 1.f - msM_subwin ); /*msAlpha,msPsd,msPsdFirstMoment,msPsdSecondMoment,msNoiseFloor,msBminSubWin,msBminWin,psize*/
     427   318259866 :             for ( j = start; j < stop; j++ )
     428             :             {
     429             :                 /* Compute variance of PSD */
     430   310042479 :                 beta = min( msAlpha[j] * msAlpha[j], MSBETAMAX );
     431   310042479 :                 scalar3 = msPsd[j] - msPsdFirstMoment[j];
     432   310042479 :                 msPsdFirstMoment[j] = beta * msPsdFirstMoment[j] + ( 1.f - beta ) * msPsd[j];
     433   310042479 :                 msPsdSecondMoment[j] = beta * msPsdSecondMoment[j] + ( 1.f - beta ) * scalar3 * scalar3;
     434             :                 /* Compute inverse of amount of degrees of freedom */
     435   310042479 :                 QeqInv = min( ( msPsdSecondMoment[j] + DELTA ) / ( 2.f * msNoiseFloor[j] * msNoiseFloor[j] + DELTA ), MSQEQINVMAX );
     436   310042479 :                 QeqInvAv += QeqInv * psize[j];
     437             : 
     438             :                 /* Compute bias correction Bmin */
     439   310042479 :                 msBminWin[j] = 1.f + scalar * QeqInv / ( 0.5f - msM_win * QeqInv );
     440   310042479 :                 msBminSubWin[j] = 1.f + scalar2 * QeqInv / ( 0.5f - msM_subwin * QeqInv );
     441             :             }
     442     8217387 :             QeqInvAv /= totsize;
     443     8217387 :             hFdCngCom->msQeqInvAv[cnt] = QeqInvAv;
     444             : 
     445             :             /* New minimum? */
     446     8217387 :             BminCorr = 1.f + MSAV * (float) sqrt( QeqInvAv ); /*msPsd,msBminWin,msNewMinFlag,msCurrentMin,msCurrentMinSubWindow*/
     447   318259866 :             for ( j = start; j < stop; j++ )
     448             :             {
     449   310042479 :                 scalar = BminCorr * msPsd[j];
     450   310042479 :                 scalar2 = scalar * msBminWin[j];
     451   310042479 :                 if ( scalar2 < msCurrentMin[j] )
     452             :                 {
     453   157979355 :                     msNewMinFlag[j] = 1;
     454   157979355 :                     msCurrentMin[j] = scalar2;
     455   157979355 :                     msCurrentMinSubWindow[j] = scalar * msBminSubWin[j];
     456             :                 }
     457             :                 else
     458             :                 {
     459   152063124 :                     msNewMinFlag[j] = 0;
     460             :                 }
     461             :             }
     462             : 
     463             :             /* This is used later to identify local minima */
     464     8217387 :             if ( hFdCngCom->msFrCnt >= MSSUBFRLEN )
     465             :             {
     466      713901 :                 i = 0;
     467     1607371 :                 while ( i < 3 )
     468             :                 {
     469     1380261 :                     if ( hFdCngCom->msQeqInvAv[cnt] < msQeqInvAv_thresh[i] )
     470             :                     {
     471      486791 :                         break;
     472             :                     }
     473             :                     else
     474             :                     {
     475      893470 :                         i++;
     476             :                     }
     477             :                 }
     478      713901 :                 hFdCngCom->msSlope[cnt] = msNoiseSlopeMax[i];
     479             :             }
     480             : 
     481             :             /* Consider the FFT and CLDFB bands separately */
     482     8217387 :             start = stop;
     483     8217387 :             stop = len;
     484     8217387 :             totsize = hFdCngCom->stopBand - hFdCngCom->stopFFTbin;
     485     8217387 :             cnt++;
     486             :         } /*while (stop > start)*/
     487             : 
     488             :         /* Update minimum between sub windows */
     489     6262680 :         if ( hFdCngCom->msFrCnt > 1 && hFdCngCom->msFrCnt < MSSUBFRLEN )
     490             :         {
     491             :             /*msNewMinFlag,msCurrentMinSubWindow,msCurrentMinOut*/
     492   260619198 :             for ( j = 0; j < len; j++ )
     493             :             {
     494   255450016 :                 if ( msNewMinFlag[j] > 0 )
     495             :                 {
     496   118349085 :                     msLocalMinFlag[j] = 1;
     497             :                 }
     498   255450016 :                 if ( msCurrentMinSubWindow[j] < msCurrentMinOut[j] )
     499             :                 {
     500    56786594 :                     msCurrentMinOut[j] = msCurrentMinSubWindow[j];
     501             :                 }
     502             :             }
     503             :             /* Get the current noise floor */
     504     5169182 :             mvr2r( msCurrentMinOut, msNoiseFloor, len );
     505             :         }
     506             : 
     507             :         /* sub window complete */
     508             :         else
     509             :         {
     510     1093498 :             if ( hFdCngCom->msFrCnt >= MSSUBFRLEN )
     511             :             {
     512             :                 /* Collect buffers */
     513      549085 :                 mvr2r( msCurrentMinSubWindow, msMinBuf + len * hFdCngCom->msMinBufferPtr, len );
     514             : 
     515             :                 /* Compute minimum among all buffers */
     516      549085 :                 mvr2r( msMinBuf, msCurrentMinOut, len );
     517      549085 :                 ptr = msMinBuf + len;
     518     3294510 :                 for ( i = 1; i < MSNUMSUBFR; i++ )
     519             :                 {
     520             :                     /*msCurrentMinOut*/
     521   139926120 :                     for ( j = 0; j < len; j++ )
     522             :                     {
     523   137180695 :                         if ( *ptr < msCurrentMinOut[j] )
     524             :                         {
     525    34053422 :                             msCurrentMinOut[j] = *ptr;
     526             :                         }
     527   137180695 :                         ptr++;
     528             :                     }
     529             :                 }
     530             : 
     531             :                 /* Take over local minima */
     532      549085 :                 slope = hFdCngCom->msSlope[0]; /*msLocalMinFlag,msNewMinFlag,msCurrentMinSubWindow,msCurrentMinOut*/
     533    27985224 :                 for ( j = 0; j < len; j++ )
     534             :                 {
     535    27436139 :                     if ( j == lenFFT )
     536             :                     {
     537      164816 :                         slope = hFdCngCom->msSlope[1];
     538             :                     }
     539    27436139 :                     if ( msLocalMinFlag[j] && !msNewMinFlag[j] &&
     540    11209373 :                          msCurrentMinSubWindow[j] < slope * msCurrentMinOut[j] &&
     541     7683968 :                          msCurrentMinSubWindow[j] > msCurrentMinOut[j] )
     542             :                     {
     543     2637381 :                         msCurrentMinOut[j] = msCurrentMinSubWindow[j];
     544     2637381 :                         i = j;
     545    18461667 :                         for ( k = 0; k < MSNUMSUBFR; k++ )
     546             :                         {
     547    15824286 :                             msMinBuf[i] = msCurrentMinOut[j];
     548    15824286 :                             i += len;
     549             :                         }
     550             :                     }
     551             :                 }
     552             : 
     553             :                 /* Reset */
     554      549085 :                 set_s( msLocalMinFlag, 0, len );
     555      549085 :                 set_f( msCurrentMin, FLT_MAX, len );
     556             : 
     557             :                 /* Get the current noise floor */
     558      549085 :                 mvr2r( msCurrentMinOut, msNoiseFloor, len );
     559             :             }
     560             :         }
     561             : 
     562             :         /* Detect sudden offsets based on the FFT bins (core bandwidth) */
     563     6262680 :         if ( msPsdSum[0] > 50.f * msPeriodogSum[0] )
     564             :         {
     565        9799 :             if ( hFdCngCom->offsetflag > 0 )
     566             :             {
     567        2952 :                 mvr2r( msPeriodog, msPsd, len );
     568        2952 :                 mvr2r( msPeriodog, msCurrentMinOut, len );
     569        2952 :                 set_f( hFdCngCom->msAlphaCor, 1.0f, cnt );
     570        2952 :                 set_f( msAlpha, 0.0f, len );
     571        2952 :                 mvr2r( msPeriodog, msPsdFirstMoment, len );
     572        2952 :                 set_f( msPsdSecondMoment, 0.0f, len );
     573        2952 :                 msPsdSum[0] = dotp( msPeriodog, psize, lenFFT );
     574        2952 :                 if ( lenFFT < len )
     575             :                 {
     576        1041 :                     msPsdSum[1] = dotp( msPeriodog + lenFFT, psize + lenFFT, len - lenFFT );
     577             :                 }
     578             :             }
     579        9799 :             hFdCngCom->offsetflag = 1;
     580             :         }
     581             :         else
     582             :         {
     583     6252881 :             hFdCngCom->offsetflag = 0;
     584             :         }
     585             : 
     586             :         /* Increment frame counter */
     587     6262680 :         if ( hFdCngCom->msFrCnt == MSSUBFRLEN )
     588             :         {
     589      549085 :             hFdCngCom->msFrCnt = 1;
     590      549085 :             hFdCngCom->msMinBufferPtr++;
     591      549085 :             if ( hFdCngCom->msMinBufferPtr == MSNUMSUBFR )
     592             :             {
     593       64468 :                 hFdCngCom->msMinBufferPtr = 0;
     594             :             }
     595             :         }
     596             :         else
     597             :         {
     598     5713595 :             ( hFdCngCom->msFrCnt )++;
     599             :         }
     600             : 
     601             :         /* Smooth noise estimate during CNG phases */ /*msNoiseEst,msNoiseFloor*/
     602   316305159 :         for ( j = 0; j < len; j++ )
     603             :         {
     604   310042479 :             msNoiseEst[j] = 0.95f * msNoiseEst[j] + 0.05f * msNoiseFloor[j];
     605             :         }
     606             :     }
     607             : 
     608     6805286 :     if ( enc_dec == DEC && element_mode == IVAS_CPE_TD )
     609             :     {
     610           0 :         v_multc( msNoiseEst, 1.4125f, msNoiseEst, NPART_SHAPING );
     611             :     }
     612             : 
     613             :     /* Collect buffers */
     614     6805286 :     mvr2r( msPeriodog, msPeriodogBuf + len * ( *msPeriodogBufPtr ), len );
     615             : 
     616     6805286 :     ( *msPeriodogBufPtr )++;
     617     6805286 :     if ( ( *msPeriodogBufPtr ) == MSBUFLEN )
     618             :     {
     619     1317084 :         ( *msPeriodogBufPtr ) = 0;
     620             :     }
     621             : 
     622             :     /* Upper limit the noise floors with the averaged input energy */ /*msNoiseEst*/
     623   347939863 :     for ( j = 0; j < len; j++ )
     624             :     {
     625   341134577 :         scalar = msPeriodogBuf[j];
     626  1705672885 :         for ( i = j + len; i < MSBUFLEN * len; i += len )
     627             :         {
     628  1364538308 :             scalar += msPeriodogBuf[i];
     629             :         } /*division by a constant = multiplication by its (constant) inverse */
     630   341134577 :         scalar *= inv_buflen;
     631   341134577 :         if ( msNoiseEst[j] > scalar )
     632             :         {
     633   134892892 :             msNoiseEst[j] = scalar;
     634             :         }
     635   341134577 :         assert( msNoiseEst[j] >= 0 );
     636             :     }
     637             : 
     638     6805286 :     return;
     639             : }
     640             : 
     641             : 
     642             : /*-------------------------------------------------------------------
     643             :  * apply_scale()
     644             :  *
     645             :  * Apply bitrate-dependent scale
     646             :  *-------------------------------------------------------------------*/
     647             : 
     648     9868776 : void apply_scale(
     649             :     float *scale,                  /* o  : scalefactor             */
     650             :     const int16_t bwidth,          /* i  : audio bandwidth         */
     651             :     const int32_t brate,           /* i  : Bit rate                */
     652             :     const SCALE_SETUP *scaleTable, /* i  : Scale table             */
     653             :     const int16_t scaleTableSize   /* i  : Size of scale table     */
     654             : )
     655             : {
     656             :     int16_t i;
     657             : 
     658    99124411 :     for ( i = 0; i < scaleTableSize; i++ )
     659             :     {
     660    99124411 :         if ( ( bwidth == scaleTable[i].bwmode ) &&
     661    45144179 :              ( brate >= scaleTable[i].bitrateFrom ) &&
     662    45144179 :              ( brate < scaleTable[i].bitrateTo ) )
     663             :         {
     664     9868776 :             break;
     665             :         }
     666             :     }
     667             : 
     668     9868776 :     assert( i < scaleTableSize );
     669             : 
     670     9868776 :     *scale += scaleTable[i].scale;
     671             : 
     672     9868776 :     return;
     673             : }
     674             : 
     675             : 
     676             : /*-------------------------------------------------------------------
     677             :  * bandcombinepow()
     678             :  *
     679             :  * Compute the power for each partition
     680             :  *-------------------------------------------------------------------*/
     681             : 
     682     7370847 : void bandcombinepow(
     683             :     const float *bandpow,   /* i  : Power for each band                       */
     684             :     const int16_t nband,    /* i  : Number of bands                           */
     685             :     int16_t *part,          /* i  : Partition upper boundaries (band indices starting from 0) */
     686             :     const int16_t npart,    /* i  : Number of partitions                      */
     687             :     const float *psize_inv, /* i  : Inverse partition sizes                   */
     688             :     float *partpow          /* o  : Power for each partition                  */
     689             : )
     690             : {
     691             :     int16_t i, p;
     692             :     float temp;
     693             : 
     694     7370847 :     if ( nband == npart )
     695             :     {
     696           0 :         mvr2r( bandpow, partpow, nband );
     697             :     }
     698             :     else
     699             :     {
     700             :         /* Compute the power in each partition */
     701     7370847 :         i = 0; /*part,partpow,psize_inv*/
     702   322764812 :         for ( p = 0; p < npart; p++ )
     703             :         {
     704             :             /* Arithmetic averaging of power for all bins in partition */
     705   315393965 :             temp = 0;
     706  1940595445 :             for ( ; i <= part[p]; i++ )
     707             :             {
     708  1625201480 :                 temp += bandpow[i];
     709             :             }
     710   315393965 :             partpow[p] = temp * psize_inv[p];
     711             :         }
     712             :     }
     713             : 
     714     7370847 :     return;
     715             : }
     716             : 
     717             : 
     718             : /*-------------------------------------------------------------------
     719             :  * scalebands()
     720             :  *
     721             :  * Scale partitions (with smoothing)
     722             :  *-------------------------------------------------------------------*/
     723             : 
     724     7518302 : void scalebands(
     725             :     const float *partpow,   /* i  : Power for each partition                                    */
     726             :     int16_t *part,          /* i  : Partition upper boundaries (band indices starting from 0)   */
     727             :     const int16_t npart,    /* i  : Number of partitions                                        */
     728             :     int16_t *midband,       /* i  : Central band of each partition                              */
     729             :     const int16_t nFFTpart, /* i  : Number of FFT partitions                                    */
     730             :     const int16_t nband,    /* i  : Number of bands                                             */
     731             :     float *bandpow,         /* o  : Power for each band                                         */
     732             :     const int16_t flag_fft_en )
     733             : {
     734     7518302 :     int16_t i, j = 0, nint, startBand, startPart, stopPart;
     735     7518302 :     float val, delta = 0.f;
     736             : 
     737             :     /* Interpolate the bin/band-wise levels from the partition levels */
     738     7518302 :     if ( nband == npart )
     739             :     {
     740           0 :         mvr2r( partpow, bandpow, npart );
     741             :     }
     742             :     else
     743             :     {
     744     7518302 :         startBand = 0;
     745     7518302 :         startPart = 0;
     746     7518302 :         stopPart = nFFTpart;
     747    15098057 :         while ( startBand < nband )
     748             :         {
     749     7579755 :             if ( flag_fft_en || startPart >= nFFTpart )
     750             :             {
     751             : 
     752             :                 /* first half partition */
     753     7561165 :                 j = startPart;
     754     7561165 :                 val = partpow[j];
     755    15324987 :                 for ( i = startBand; i <= midband[j]; i++ )
     756             :                 {
     757     7763822 :                     bandpow[i] = val;
     758             :                 }
     759     7561165 :                 j++;
     760             : 
     761     7561165 :                 delta = 1;
     762             :                 /* inner partitions */
     763   458606651 :                 for ( ; j < stopPart; j++ )
     764             :                 {
     765   451045486 :                     nint = midband[j] - midband[j - 1];
     766             :                     /* log-linear interpolation */ /* Only one new LOG needs to be computed per loop iteration */
     767   451045486 :                     delta = (float) exp( ( log( partpow[j] + DELTA ) - log( partpow[j - 1] + DELTA ) ) * normReciprocal[nint] );
     768   451045486 :                     val = partpow[j - 1];
     769  2123029290 :                     for ( ; i < midband[j]; i++ )
     770             :                     {
     771  1671983804 :                         val *= delta;
     772  1671983804 :                         bandpow[i] = val;
     773             :                     }
     774   451045486 :                     bandpow[i++] = partpow[j];
     775             :                 }
     776     7561165 :                 if ( delta > 1.f )
     777             :                 {
     778     1235659 :                     delta = 1.f;
     779             :                 }
     780             : 
     781             :                 /* last half partition */
     782     7561165 :                 val = partpow[stopPart - 1];
     783    64942980 :                 for ( ; i <= part[stopPart - 1]; i++ )
     784             :                 {
     785    57381815 :                     val *= delta;
     786    57381815 :                     bandpow[i] = val;
     787             :                 }
     788             :             }
     789     7579755 :             startBand = part[stopPart - 1] + 1;
     790     7579755 :             startPart = stopPart;
     791     7579755 :             stopPart = npart;
     792             :         }
     793             :     }
     794             : 
     795     7518302 :     return;
     796             : }
     797             : 
     798             : 
     799             : /*-------------------------------------------------------------------
     800             :  * getmidbands()
     801             :  *
     802             :  * Get central band for each partition
     803             :  *-------------------------------------------------------------------*/
     804             : 
     805    58255702 : static void getmidbands(
     806             :     int16_t *part,       /* i  : Partition upper boundaries (band indices starting from 0)  */
     807             :     const int16_t npart, /* i  : Number of partitions                                       */
     808             :     int16_t *midband,    /* o  : Central band of each partition                             */
     809             :     float *psize,        /* o  : Partition sizes                                            */
     810             :     float *psize_inv     /* o  : Inverse of partition sizes                                 */
     811             : )
     812             : {
     813             :     int16_t j;
     814             : 
     815             :     /* first half partition */
     816    58255702 :     midband[0] = part[0];
     817    58255702 :     psize[0] = (float) part[0] + 1.f;
     818    58255702 :     psize_inv[0] = normReciprocal[part[0] + 1];
     819             : 
     820             :     /* inner partitions */ /*part,midband,psize_inv*/
     821  2465835963 :     for ( j = 1; j < npart; j++ )
     822             :     {
     823  2407580261 :         midband[j] = ( part[j - 1] + 1 + part[j] ) >> 1;
     824  2407580261 :         psize[j] = (float) ( part[j] - part[j - 1] );
     825  2407580261 :         psize_inv[j] = normReciprocal[part[j] - part[j - 1]];
     826             :     }
     827             : 
     828    58255702 :     return;
     829             : }
     830             : 
     831             : 
     832             : /*-------------------------------------------------------------------
     833             :  * AnalysisSTFT()
     834             :  *
     835             :  * STFT analysis filterbank
     836             :  *-------------------------------------------------------------------*/
     837             : 
     838     6531832 : void AnalysisSTFT(
     839             :     const float *timeDomainInput,
     840             :     float *fftBuffer,           /* o  : FFT bins                                              */
     841             :     HANDLE_FD_CNG_COM hFdCngCom /* i/o: FD_CNG structure containing all buffers and variables */
     842             : )
     843             : {
     844     6531832 :     float *olapBuffer = hFdCngCom->olapBufferAna;
     845     6531832 :     const float *olapWin = hFdCngCom->olapWinAna;
     846             : 
     847             :     /* Shift and cascade for overlap-add */
     848     6531832 :     mvr2r( olapBuffer + hFdCngCom->frameSize, olapBuffer, hFdCngCom->fftlen - hFdCngCom->frameSize );
     849     6531832 :     mvr2r( timeDomainInput, olapBuffer + hFdCngCom->fftlen - hFdCngCom->frameSize, hFdCngCom->frameSize );
     850             : 
     851             :     /* Window the signal */
     852     6531832 :     v_mult( olapBuffer, olapWin, fftBuffer, hFdCngCom->fftlen );
     853             : 
     854             :     /* Perform FFT */
     855     6531832 :     RFFTN( fftBuffer, hFdCngCom->fftSineTab, hFdCngCom->fftlen, -1 );
     856             : 
     857     6531832 :     return;
     858             : }
     859             : 
     860             : 
     861             : /*-------------------------------------------------------------------
     862             :  * SynthesisSTFT()
     863             :  *
     864             :  * STFT synthesis filterbank
     865             :  *-------------------------------------------------------------------*/
     866             : 
     867     3913154 : void SynthesisSTFT(
     868             :     float *fftBuffer, /* i  : FFT bins */
     869             :     float *timeDomainOutput,
     870             :     float *olapBuffer,
     871             :     const float *olapWin,
     872             :     const int16_t tcx_transition,
     873             :     HANDLE_FD_CNG_COM hFdCngCom, /* i/o: FD_CNG structure containing all buffers and variables */
     874             :     const int16_t element_mode,  /* i  : element mode */
     875             :     const int16_t nchan_out      /* i  : number of output channels */
     876             : )
     877             : {
     878             :     int16_t i;
     879             :     float buf[M + 1 + 320], tmp;
     880             : 
     881             :     /* Perform IFFT */
     882     3913154 :     RFFTN( fftBuffer, hFdCngCom->fftSineTab, hFdCngCom->fftlen, 1 );
     883             : 
     884             :     /* Handle overlap in P/S domain for stereo */
     885     3913154 :     if ( ( element_mode == IVAS_CPE_TD || element_mode == IVAS_CPE_DFT ) && nchan_out == 2 )
     886             :     {
     887        7057 :         mvr2r( olapBuffer + 3 * hFdCngCom->frameSize / 4 - ( M + 1 ), buf, hFdCngCom->frameSize + M + 1 );
     888        7057 :         set_f( olapBuffer, 0.0f, hFdCngCom->fftlen );
     889             :     }
     890             :     else
     891             :     {
     892     3906097 :         mvr2r( olapBuffer + hFdCngCom->frameSize, olapBuffer, hFdCngCom->frameSize );
     893     3906097 :         set_f( olapBuffer + hFdCngCom->frameSize, 0.0f, hFdCngCom->frameSize ); /*olapBuffer, fftBuffer, olapWin*/
     894             :     }
     895             : 
     896     3913154 :     if ( tcx_transition )
     897             :     {
     898     8725782 :         for ( i = 0; i < 5 * hFdCngCom->frameSize / 4; i++ )
     899             :         {
     900     8701040 :             olapBuffer[i] = fftBuffer[i];
     901             :         }
     902             :     }
     903             :     else
     904             :     {
     905   569508444 :         for ( i = hFdCngCom->frameSize / 4; i < 3 * hFdCngCom->frameSize / 4; i++ )
     906             :         {
     907   565620032 :             olapBuffer[i] += fftBuffer[i] * olapWin[i - hFdCngCom->frameSize / 4];
     908             :         }
     909   569508444 :         for ( ; i < 5 * hFdCngCom->frameSize / 4; i++ )
     910             :         {
     911   565620032 :             olapBuffer[i] = fftBuffer[i];
     912             :         }
     913             :     }
     914   573013602 :     for ( ; i < 7 * hFdCngCom->frameSize / 4; i++ )
     915             :     {
     916   569100448 :         olapBuffer[i] = fftBuffer[i] * olapWin[i - 3 * hFdCngCom->frameSize / 4];
     917             :     }
     918             : 
     919   288463378 :     for ( ; i < hFdCngCom->fftlen; i++ )
     920             :     {
     921   284550224 :         olapBuffer[i] = 0;
     922             :     }
     923             : 
     924             :     /* Get time-domain signal */
     925     3913154 :     v_multc( olapBuffer + hFdCngCom->frameSize / 4, (float) ( hFdCngCom->fftlen / 2 ), timeDomainOutput, hFdCngCom->frameSize );
     926             : 
     927             :     /* Get excitation */
     928     3913154 :     if ( ( element_mode == IVAS_CPE_TD || element_mode == IVAS_CPE_DFT ) && nchan_out == 2 )
     929             :     {
     930      910353 :         for ( i = 0; i < hFdCngCom->frameSize / 2; i++ )
     931             :         {
     932      903296 :             buf[i + ( M + 1 )] += olapBuffer[i + hFdCngCom->frameSize / 4];
     933             :         }
     934        7057 :         v_multc( buf, (float) ( hFdCngCom->fftlen / 2 ), buf, M + 1 + hFdCngCom->frameSize );
     935             :     }
     936             :     else
     937             :     {
     938     3906097 :         v_multc( olapBuffer + hFdCngCom->frameSize / 4 - ( M + 1 ), (float) ( hFdCngCom->fftlen / 2 ), buf, M + 1 + hFdCngCom->frameSize );
     939             :     }
     940             : 
     941     3913154 :     tmp = buf[0];
     942     3913154 :     preemph( buf + 1, PREEMPH_FAC, M + hFdCngCom->frameSize, &tmp );
     943     3913154 :     residu( hFdCngCom->A_cng, M, buf + 1 + M, hFdCngCom->exc_cng, hFdCngCom->frameSize );
     944             : 
     945     3913154 :     return;
     946             : }
     947             : 
     948             : 
     949             : /*-------------------------------------------------------------------
     950             :  * SynthesisSTFT_dirac()
     951             :  *
     952             :  * STFT synthesis filterbank
     953             :  *-------------------------------------------------------------------*/
     954             : 
     955      246747 : void SynthesisSTFT_dirac(
     956             :     float *fftBuffer, /* i  : FFT bins */
     957             :     float *timeDomainOutput,
     958             :     float *olapBuffer,
     959             :     const float *olapWin,
     960             :     const int16_t samples_out,
     961             :     HANDLE_FD_CNG_COM hFdCngCom /* i/o: FD_CNG structure containing all buffers and variables */
     962             : )
     963             : {
     964             :     int16_t i;
     965             :     float buf[M + 1 + 320], tmp;
     966             : 
     967             :     /* Perform IFFT */
     968      246747 :     RFFTN( fftBuffer, hFdCngCom->fftSineTab, hFdCngCom->fftlen, 1 );
     969             : 
     970             :     /* Handle overlap in P/S domain for stereo */
     971      246747 :     mvr2r( olapBuffer + hFdCngCom->frameSize, olapBuffer, hFdCngCom->frameSize );
     972      246747 :     set_f( olapBuffer + hFdCngCom->frameSize, 0.0f, hFdCngCom->frameSize ); /*olapBuffer, fftBuffer, olapWin*/
     973             : 
     974    35801307 :     for ( i = hFdCngCom->frameSize / 4; i < 3 * hFdCngCom->frameSize / 4; i++ )
     975             :     {
     976    35554560 :         olapBuffer[i] += fftBuffer[i] * olapWin[i - hFdCngCom->frameSize / 4];
     977             :     }
     978    35801307 :     for ( ; i < 5 * hFdCngCom->frameSize / 4; i++ )
     979             :     {
     980    35554560 :         olapBuffer[i] = fftBuffer[i];
     981             :     }
     982             : 
     983    35801307 :     for ( ; i < 7 * hFdCngCom->frameSize / 4; i++ )
     984             :     {
     985    35554560 :         olapBuffer[i] = fftBuffer[i];
     986             :     }
     987             : 
     988    18024027 :     for ( ; i < hFdCngCom->fftlen; i++ )
     989             :     {
     990    17777280 :         olapBuffer[i] = 0;
     991             :     }
     992             : 
     993             :     /* Get time-domain signal */
     994      246747 :     v_multc( olapBuffer + hFdCngCom->frameSize / 4, (float) ( hFdCngCom->fftlen / 2 ), timeDomainOutput, samples_out );
     995             : 
     996             :     /* Get excitation */
     997      246747 :     v_multc( olapBuffer + hFdCngCom->frameSize / 4 - ( M + 1 ), (float) ( hFdCngCom->fftlen / 2 ), buf, M + 1 + hFdCngCom->frameSize );
     998      246747 :     tmp = buf[0];
     999      246747 :     preemph( buf + 1, PREEMPH_FAC, M + hFdCngCom->frameSize, &tmp );
    1000      246747 :     residu( hFdCngCom->A_cng, M, buf + 1 + M, hFdCngCom->exc_cng, hFdCngCom->frameSize );
    1001             : 
    1002             :     /* update and window olapBuf if we have a output frame that is shorter than the default frame size...*/
    1003      246747 :     if ( samples_out < hFdCngCom->frameSize )
    1004             :     {
    1005          45 :         mvr2r( olapBuffer + samples_out, olapBuffer + hFdCngCom->frameSize, 3 * hFdCngCom->frameSize / 4 );
    1006             :     }
    1007    35801307 :     for ( i = 5 * hFdCngCom->frameSize / 4; i < 7 * hFdCngCom->frameSize / 4; i++ )
    1008             :     {
    1009    35554560 :         olapBuffer[i] *= olapWin[i - 3 * hFdCngCom->frameSize / 4];
    1010             :     }
    1011             : 
    1012      246747 :     return;
    1013             : }
    1014             : 
    1015             : 
    1016             : /*-------------------------------------------------------------------
    1017             :  * mhvals()
    1018             :  *
    1019             :  * Compute some values used in the bias correction of the minimum statistics algorithm
    1020             :  *-------------------------------------------------------------------*/
    1021             : 
    1022     1191276 : static void mhvals(
    1023             :     const int16_t d,
    1024             :     float *m )
    1025             : {
    1026             :     int16_t i, j;
    1027             :     float qi, qj, q;
    1028     1191276 :     int16_t len = SIZE_SCALE_TABLE_CN;
    1029             : 
    1030     1191276 :     i = 0;
    1031    10125846 :     for ( i = 0; i < len; i++ )
    1032             :     {
    1033    10125846 :         if ( d <= d_array[i] )
    1034             :         {
    1035     1191276 :             break;
    1036             :         }
    1037             :     }
    1038     1191276 :     if ( i == len )
    1039             :     {
    1040           0 :         i = len - 1;
    1041           0 :         j = i;
    1042             :     }
    1043             :     else
    1044             :     {
    1045     1191276 :         j = i - 1;
    1046             :     }
    1047     1191276 :     if ( d == d_array[i] )
    1048             :     {
    1049           0 :         *m = m_array[i];
    1050             :     }
    1051             :     else
    1052             :     {
    1053     1191276 :         qj = (float) sqrt( (float) d_array[i - 1] ); /*interpolate using sqrt(d)*/
    1054     1191276 :         qi = (float) sqrt( (float) d_array[i] );
    1055     1191276 :         q = (float) sqrt( (float) d );
    1056     1191276 :         *m = m_array[i] + ( qi * qj / q - qj ) * ( m_array[j] - m_array[i] ) / ( qi - qj );
    1057             :     }
    1058             : 
    1059     1191276 :     return;
    1060             : }
    1061             : 
    1062             : /*-------------------------------------------------------------------
    1063             :  * rand_gauss()
    1064             :  *
    1065             :  * Random generator with Gaussian distribution with mean 0 and std 1
    1066             :  *-------------------------------------------------------------------*/
    1067             : 
    1068  5596521282 : float rand_gauss(
    1069             :     float *x,
    1070             :     int16_t *seed )
    1071             : {
    1072             :     float temp;
    1073             : 
    1074  5596521282 :     temp = (float) own_random( seed );
    1075  5596521282 :     temp += (float) own_random( seed );
    1076  5596521282 :     temp += (float) own_random( seed );
    1077  5596521282 :     temp *= OUTMAX_INV;
    1078             : 
    1079  5596521282 :     *x = temp;
    1080             : 
    1081  5596521282 :     return temp;
    1082             : }
    1083             : 
    1084             : 
    1085             : /*-------------------------------------------------------------------
    1086             :  * lpc_from_spectrum()
    1087             :  *
    1088             :  *
    1089             :  *-------------------------------------------------------------------*/
    1090             : 
    1091      245377 : void lpc_from_spectrum(
    1092             :     HANDLE_FD_CNG_COM hFdCngCom,
    1093             :     const int16_t start,
    1094             :     const int16_t stop,
    1095             :     const float preemph_fac )
    1096             : {
    1097             :     int16_t i;
    1098             :     float r[32], nf;
    1099             :     float fftBuffer[FFTLEN], *ptr, *pti;
    1100             : 
    1101      245377 :     float *powspec = hFdCngCom->cngNoiseLevel;
    1102      245377 :     int16_t fftlen = hFdCngCom->fftlen;
    1103      245377 :     const float *fftSineTab = hFdCngCom->fftSineTab;
    1104      245377 :     float *A = hFdCngCom->A_cng;
    1105             : 
    1106             :     /* Power Spectrum */
    1107      245377 :     ptr = fftBuffer;
    1108      245377 :     pti = fftBuffer + 1;
    1109      245377 :     nf = 1e-3f;
    1110      736131 :     for ( i = 0; i < start; i++ )
    1111             :     {
    1112      490754 :         *ptr = nf;
    1113      490754 :         *pti = 0.f;
    1114      490754 :         ptr += 2;
    1115      490754 :         pti += 2;
    1116             :     }
    1117    75024767 :     for ( ; i < stop; i++ )
    1118             :     {
    1119    74779390 :         *ptr = max( nf, powspec[i - start] );
    1120    74779390 :         *pti = 0.f;
    1121    74779390 :         ptr += 2;
    1122    74779390 :         pti += 2;
    1123             :     }
    1124      276289 :     for ( ; i < fftlen / 2; i++ )
    1125             :     {
    1126       30912 :         *ptr = nf;
    1127       30912 :         *pti = 0.f;
    1128       30912 :         ptr += 2;
    1129       30912 :         pti += 2;
    1130             :     }
    1131      245377 :     fftBuffer[1] = nf;
    1132             : 
    1133             :     /* Pre-emphasis */
    1134      245377 :     ptr = fftBuffer;
    1135    75546433 :     for ( i = 0; i < fftlen / 2; i++ )
    1136             :     {
    1137    75301056 :         *ptr *= ( 1.f + preemph_fac * preemph_fac - 2.0f * preemph_fac * (float) cos( -2.0f * EVS_PI * (float) i / (float) fftlen ) );
    1138             : 
    1139    75301056 :         ptr += 2;
    1140             :     }
    1141      245377 :     fftBuffer[1] *= ( 1.f + preemph_fac * preemph_fac + 2.0f * preemph_fac );
    1142             : 
    1143             :     /* Autocorrelation */
    1144      245377 :     RFFTN( fftBuffer, fftSineTab, fftlen, 1 );
    1145     4416786 :     for ( i = 0; i <= M; i++ )
    1146             :     {
    1147     4171409 :         r[i] = fftBuffer[i] * ( fftlen / 2 ) * ( fftlen / 2 );
    1148             :     }
    1149      245377 :     if ( r[0] < 100.f )
    1150             :     {
    1151       16779 :         r[0] = 100.f;
    1152             :     }
    1153             : 
    1154      245377 :     r[0] *= 1.0005f;
    1155             : 
    1156             :     /* LPC */
    1157      245377 :     lev_dur( A, r, M, NULL );
    1158             : 
    1159      245377 :     return;
    1160             : }
    1161             : 
    1162             : 
    1163             : /*-------------------------------------------------------------------
    1164             :  * FdCng_exc()
    1165             :  *
    1166             :  * Generate FD-CNG as LP excitation
    1167             :  *-------------------------------------------------------------------*/
    1168             : 
    1169      290002 : void FdCng_exc(
    1170             :     HANDLE_FD_CNG_COM hFdCngCom,
    1171             :     int16_t *CNG_mode,
    1172             :     const int16_t L_frame,
    1173             :     const float *lsp_old,
    1174             :     const int16_t first_CNG,
    1175             :     float *lspCNG,
    1176             :     float *Aq,      /* o  : LPC coeffs */
    1177             :     float *lsp_new, /* o  : lsp  */
    1178             :     float *lsf_new, /* o  : lsf  */
    1179             :     float *exc,     /* o  : LP excitation   */
    1180             :     float *exc2,    /* o  : LP excitation   */
    1181             :     float *bwe_exc  /* o  : LP excitation for BWE */
    1182             : )
    1183             : {
    1184             :     int16_t i;
    1185      290002 :     *CNG_mode = -1;
    1186             : 
    1187             :     /*Get excitation */
    1188     1628876 :     for ( i = 0; i < L_frame / L_SUBFR; i++ )
    1189             :     {
    1190     1338874 :         mvr2r( hFdCngCom->A_cng, Aq + i * ( M + 1 ), M + 1 );
    1191             :     }
    1192             : 
    1193      290002 :     a2lsp_stab( Aq, lsp_new, lsp_old );
    1194             : 
    1195      290002 :     if ( first_CNG == 0 )
    1196             :     {
    1197      127149 :         mvr2r( lsp_old, lspCNG, M );
    1198             :     }
    1199             : 
    1200     4930034 :     for ( i = 0; i < M; i++ )
    1201             :     {
    1202             :         /* AR low-pass filter  */
    1203     4640032 :         lspCNG[i] = CNG_ISF_FACT * lspCNG[i] + ( 1 - CNG_ISF_FACT ) * lsp_new[i];
    1204             :     }
    1205             : 
    1206      290002 :     if ( L_frame == L_FRAME16k )
    1207             :     {
    1208      178866 :         lsp2lsf( lsp_new, lsf_new, M, INT_FS_16k );
    1209             :     }
    1210             :     else
    1211             :     {
    1212      111136 :         lsp2lsf( lsp_new, lsf_new, M, INT_FS_12k8 );
    1213             :     }
    1214             : 
    1215      290002 :     mvr2r( hFdCngCom->exc_cng, exc, L_frame );
    1216      290002 :     mvr2r( hFdCngCom->exc_cng, exc2, L_frame );
    1217             : 
    1218      290002 :     if ( bwe_exc )
    1219             :     {
    1220      213828 :         if ( L_frame == L_FRAME )
    1221             :         {
    1222      111136 :             interp_code_5over2( exc2, bwe_exc, L_frame );
    1223             :         }
    1224             :         else
    1225             :         {
    1226      102692 :             interp_code_4over2( exc2, bwe_exc, L_frame );
    1227             :         }
    1228             :     }
    1229             : 
    1230      290002 :     return;
    1231             : }

Generated by: LCOV version 1.14