LCOV - code coverage report
Current view: top level - lib_enc - cod_tcx.c (source / functions) Hit Total Coverage
Test: Coverage on main -- short test vectors @ 6c9ddc4024a9c0e1ecb8f643f114a84a0e26ec6b Lines: 727 765 95.0 %
Date: 2025-05-23 08:37:30 Functions: 12 13 92.3 %

          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             : #include <math.h>
      41             : #include "cnst.h"
      42             : #include "prot.h"
      43             : #include "wmc_auto.h"
      44             : #include "ivas_prot.h"
      45             : #include "ivas_rom_com.h"
      46             : #ifdef DEBUGGING
      47             : #include <string.h>
      48             : #endif
      49             : #ifdef DEBUG_PLOT
      50             : #include "deb_out.h"
      51             : #endif
      52             : 
      53             : /*-------------------------------------------------------------------*
      54             :  * HBAutocorrelation()
      55             :  *
      56             :  *
      57             :  *-------------------------------------------------------------------*/
      58             : 
      59      108975 : void HBAutocorrelation(
      60             :     TCX_CONFIG_HANDLE hTcxCfg,        /* i  : configuration of TCX              */
      61             :     const int16_t left_overlap_mode,  /* i  : overlap mode of left window half  */
      62             :     const int16_t right_overlap_mode, /* i  : overlap mode of right window half */
      63             :     float speech[],                   /* i  : synthesis                         */
      64             :     int16_t L_frame,                  /* i  : frame length                      */
      65             :     float *r                          /* o  : autocorrelations vector           */
      66             : )
      67             : {
      68             :     int16_t i, j, left_overlap, right_overlap;
      69             :     float s;
      70             :     float xn_buf[L_MDCT_OVLP_MAX + L_FRAME_PLUS + L_MDCT_OVLP_MAX];
      71             : 
      72             :     /*-----------------------------------------------------------*
      73             :      * Windowing                                                 *
      74             :      *-----------------------------------------------------------*/
      75             : 
      76      108975 :     WindowSignal( hTcxCfg, hTcxCfg->tcx_offset, left_overlap_mode, right_overlap_mode, &left_overlap, &right_overlap, speech, &L_frame, xn_buf, 1, 0 );
      77             : 
      78             :     /*-----------------------------------------------------------*
      79             :      * Autocorrelation                                           *
      80             :      *-----------------------------------------------------------*/
      81             : 
      82     1961550 :     for ( i = 0; i <= M; i++ )
      83             :     {
      84     1852575 :         s = 0.0;
      85             : 
      86  1628698175 :         for ( j = 0; j < L_frame + ( left_overlap + right_overlap ) / 2 - i; j++ )
      87             :         {
      88  1626845600 :             s += xn_buf[j] * xn_buf[j + i];
      89             :         }
      90     1852575 :         r[i] = s;
      91             :     }
      92             : 
      93      108975 :     if ( r[0] < 100.0 )
      94             :     {
      95         324 :         r[0] = 100.0;
      96             :     }
      97             : 
      98      108975 :     return;
      99             : }
     100             : 
     101             : 
     102             : /*-------------------------------------------------------------------*
     103             :  * TNSAnalysisStereo()
     104             :  *
     105             :  *
     106             :  *-------------------------------------------------------------------*/
     107             : 
     108             : #define SIMILAR_TNS_THRESHOLD        ( 0.04f )
     109             : #define TNS_GAIN_THRESHOLD_FOR_WHITE ( 3.0f )
     110             : 
     111      705898 : void TNSAnalysisStereo(
     112             :     Encoder_State **sts,                        /* i  : encoder state handle                    */
     113             :     float *mdst_spectrum[CPE_CHANNELS][NB_DIV], /* o  : MDST spectrum                           */
     114             :     const int16_t bWhitenedDomain,              /* i  : whitened domain flag                    */
     115             :     int16_t tnsSize[CPE_CHANNELS][NB_DIV],      /* i  : number of tns parameters put into prm   */
     116             :     int16_t tnsBits[CPE_CHANNELS][NB_DIV],      /* i  : number of tns bits in the frame         */
     117             :     int16_t param_core[][NB_DIV * NPRM_DIV],    /* o  : TNS parameters                          */
     118             :     const int16_t mct_on                        /* i  : flag mct block (1) or stereo (0)          */
     119             : )
     120             : {
     121             :     int16_t ch, k, L_spec, L_frame, nSubframes, iFilter;
     122             :     float *spectrum;
     123      705898 :     Encoder_State *st = NULL;
     124      705898 :     TCX_ENC_HANDLE hTcxEnc = NULL;
     125             :     int16_t individual_decision[NB_DIV];
     126      705898 :     float maxPredictionGain = 0.f, meanPredictionGain;
     127             : 
     128      705898 :     individual_decision[0] = 0;
     129      705898 :     individual_decision[1] = 0;
     130      705898 :     L_spec = -1;
     131      705898 :     L_frame = -1;
     132             : 
     133             :     /* TNS filter analysis, loop over channels */
     134     2117694 :     for ( ch = 0; ch < CPE_CHANNELS; ch++ )
     135             :     {
     136     1411796 :         st = sts[ch];
     137     1411796 :         if ( st->mct_chan_mode == MCT_CHAN_MODE_IGNORE )
     138             :         {
     139      126223 :             continue;
     140             :         }
     141             : 
     142     1285573 :         hTcxEnc = st->hTcxEnc;
     143             : 
     144     1285573 :         nSubframes = ( hTcxEnc->tcxMode == TCX_20 ) ? 1 : NB_DIV;
     145             : 
     146     2600768 :         for ( k = 0; k < nSubframes; k++ )
     147             :         {
     148             :             /* reset tns on whitened domain flag */
     149     1315195 :             if ( !bWhitenedDomain )
     150             :             {
     151      661880 :                 hTcxEnc->bTnsOnWhithenedSpectra[k] = 0;
     152      661880 :                 hTcxEnc->fUseTns[k] = 0;
     153             :             }
     154             : 
     155     1315195 :             if ( st->hTcxCfg->fIsTNSAllowed && ( !bWhitenedDomain || hTcxEnc->bTnsOnWhithenedSpectra[k] ) )
     156             :             {
     157             : 
     158     1292867 :                 spectrum = hTcxEnc->spectrum[k];
     159     1292867 :                 L_frame = hTcxEnc->L_frameTCX;
     160     1292867 :                 st->hTcxCfg->pCurrentTnsConfig = &st->hTcxCfg->tnsConfig[hTcxEnc->transform_type[k] == TCX_20][( k == 0 ) && ( st->last_core == ACELP_CORE )];
     161     1292867 :                 L_spec = st->hTcxCfg->pCurrentTnsConfig->iFilterBorders[0];
     162             : 
     163             :                 /*-----------------------------------------------------------*
     164             :                  * Temporal Noise Shaping analysis                           *
     165             :                  *-----------------------------------------------------------*/
     166             : 
     167     1292867 :                 if ( hTcxEnc->transform_type[k] == TCX_5 )
     168             :                 {
     169             :                     /* rearrange LF sub-window lines prior to TNS analysis & filtering */
     170       15305 :                     tcx5TnsGrouping( L_frame >> 2, L_spec >> 1, spectrum );
     171             :                 }
     172             : 
     173             :                 /* WMOPS: All initializations are either for safety or static (tables) and thus not to be counted */
     174     1292867 :                 ResetTnsData( &hTcxEnc->tnsData[k] );
     175     1292867 :                 if ( st->hTcxCfg->pCurrentTnsConfig->maxOrder <= 0 )
     176             :                 {
     177           0 :                     break;
     178             :                 }
     179             : 
     180     1292867 :                 CalculateTnsFilt( st->hTcxCfg->pCurrentTnsConfig, spectrum, &hTcxEnc->tnsData[k], NULL );
     181             :             }
     182             :         }
     183             :     }
     184             : 
     185      705898 :     if ( !mct_on )
     186             :     {
     187             :         /* TNS decision */
     188             :         /* if framing differs between channels, keep the filter decision per channel */
     189      165282 :         if ( ( sts[0]->hTcxEnc->transform_type[0] != sts[1]->hTcxEnc->transform_type[0] &&
     190        1260 :                sts[0]->hTcxEnc->transform_type[1] != sts[1]->hTcxEnc->transform_type[1] ) ||
     191      164026 :              sts[0]->hTcxCfg->fIsTNSAllowed != sts[1]->hTcxCfg->fIsTNSAllowed )
     192             :         {
     193        1256 :             individual_decision[0] = individual_decision[1] = 1;
     194             :         }
     195      164026 :         else if ( bWhitenedDomain )
     196             :         {
     197       82013 :             nSubframes = ( sts[0]->hTcxEnc->tcxMode == TCX_20 ) ? 1 : NB_DIV;
     198      165789 :             for ( k = 0; k < nSubframes; k++ )
     199             :             {
     200       83776 :                 if ( sts[0]->hTcxEnc->bTnsOnWhithenedSpectra[k] != sts[1]->hTcxEnc->bTnsOnWhithenedSpectra[k] )
     201             :                 {
     202         441 :                     individual_decision[k] = 1;
     203             :                 }
     204             :             }
     205             :         }
     206             : 
     207             :         /* framing equal, check for similar filters, if very similar (also indicator for and M signal),
     208             :          * use at least the same decision, maybe use the same filter
     209             :          */
     210             :         {
     211             :             int16_t isTCX10;
     212      165282 :             isTCX10 = ( sts[0]->hTcxEnc->tcxMode == TCX_20 ) ? 0 : 1;
     213             : 
     214      165282 :             nSubframes = ( sts[0]->hTcxEnc->tcxMode == TCX_20 ) ? 1 : NB_DIV;
     215             : 
     216      334692 :             for ( k = 0; k < nSubframes; k++ )
     217             :             {
     218      169410 :                 if ( sts[0]->hTcxCfg->fIsTNSAllowed && individual_decision[k] != 1 && ( !bWhitenedDomain || sts[0]->hTcxEnc->bTnsOnWhithenedSpectra[k] ) )
     219             :                 {
     220      164739 :                     float maxPredGain = -1.0f;
     221      164739 :                     sts[0]->hTcxCfg->pCurrentTnsConfig = &sts[0]->hTcxCfg->tnsConfig[sts[0]->hTcxEnc->transform_type[k] == TCX_20][( k == 0 ) && ( sts[0]->last_core == ACELP_CORE )];
     222      164739 :                     sts[1]->hTcxCfg->pCurrentTnsConfig = &sts[1]->hTcxCfg->tnsConfig[sts[1]->hTcxEnc->transform_type[k] == TCX_20][( k == 0 ) && ( sts[1]->last_core == ACELP_CORE )];
     223             : 
     224             : #ifdef DEBUGGING
     225             :                     assert( sts[0]->hTcxCfg->pCurrentTnsConfig->nMaxFilters == sts[1]->hTcxCfg->pCurrentTnsConfig->nMaxFilters );
     226             : #endif
     227      472698 :                     for ( iFilter = sts[0]->hTcxCfg->pCurrentTnsConfig->nMaxFilters - 1; iFilter >= 0; iFilter-- )
     228             :                     {
     229             :                         STnsFilter *pFilter[2];
     230             :                         struct TnsParameters const *pTnsParameters[2];
     231      307959 :                         pFilter[0] = sts[0]->hTcxEnc->tnsData[k].filter + iFilter;
     232      307959 :                         pTnsParameters[0] = sts[0]->hTcxCfg->pCurrentTnsConfig->pTnsParameters + iFilter;
     233      307959 :                         pFilter[1] = sts[1]->hTcxEnc->tnsData[k].filter + iFilter;
     234      307959 :                         pTnsParameters[1] = sts[1]->hTcxCfg->pCurrentTnsConfig->pTnsParameters + iFilter;
     235             : 
     236             : #ifdef DEBUGGING
     237             :                         assert( pTnsParameters[0]->startLineFrequency == pTnsParameters[1]->startLineFrequency );
     238             :                         assert( pTnsParameters[0]->nSubdivisions == pTnsParameters[1]->nSubdivisions );
     239             : #endif
     240             :                         /* if prediction gain and avgSqrCoef are both close we are pretty sure the filters are quite similar, use the avg of
     241             :                          * both filters for the decision
     242             :                          */
     243      307959 :                         meanPredictionGain = ( pFilter[0]->predictionGain + pFilter[1]->predictionGain ) * 0.5f;
     244      307959 :                         maxPredictionGain = max( maxPredictionGain, meanPredictionGain );
     245             : 
     246      307959 :                         if ( ( pFilter[0]->predictionGain > pTnsParameters[0]->minPredictionGain ) && ( sts[0]->element_brate < IVAS_80k ) &&
     247        9024 :                              ( pFilter[1]->predictionGain > pTnsParameters[1]->minPredictionGain ) && ( sts[0]->hTcxEnc->tnsData[k].nFilters == sts[1]->hTcxEnc->tnsData[k].nFilters ) )
     248             :                         {
     249        4825 :                             pFilter[0]->predictionGain = pFilter[1]->predictionGain = meanPredictionGain; /* more TNS filter sync at 48kbps */
     250             :                         }
     251      307959 :                         if ( ( fabs( pFilter[0]->predictionGain - pFilter[1]->predictionGain ) < SIMILAR_TNS_THRESHOLD * meanPredictionGain ) &&
     252      203119 :                              ( sts[0]->hTcxEnc->tnsData[k].nFilters == sts[1]->hTcxEnc->tnsData[k].nFilters ) )
     253      203119 :                         {
     254      203119 :                             float maxAvgSqrCoef = max( pFilter[0]->avgSqrCoef, pFilter[1]->avgSqrCoef );
     255      203119 :                             float meanLtpGain = ( sts[0]->hTcxEnc->tcxltp_gain + sts[1]->hTcxEnc->tcxltp_gain ) * 0.5f;
     256      203119 :                             maxPredGain = max( maxPredGain, meanPredictionGain );
     257      203119 :                             if ( ( meanPredictionGain > pTnsParameters[0]->minPredictionGain ) || ( maxAvgSqrCoef > pTnsParameters[0]->minAvgSqrCoef ) )
     258             :                             {
     259        7125 :                                 if ( sts[0]->hTcxEnc->tnsData[k].nFilters > 0 || sts[1]->hTcxEnc->tnsData[k].nFilters > 0 || isTCX10 || meanLtpGain < 0.6f )
     260             :                                 {
     261        6451 :                                     ++sts[0]->hTcxEnc->tnsData[k].nFilters;
     262        6451 :                                     pFilter[0]->filterType = TNS_FILTER_ON;
     263        6451 :                                     ++sts[1]->hTcxEnc->tnsData[k].nFilters;
     264        6451 :                                     pFilter[1]->filterType = TNS_FILTER_ON;
     265             :                                 }
     266             :                                 else
     267             :                                 {
     268         674 :                                     const float maxEnergyChange = ( GetTCXMaxenergyChange( sts[0]->hTranDet, isTCX10, NSUBBLOCKS, 3 ) + GetTCXMaxenergyChange( sts[1]->hTranDet, isTCX10, NSUBBLOCKS, 3 ) ) * 0.5f;
     269             : 
     270         674 :                                     if ( maxEnergyChange >= pTnsParameters[0]->minEnergyChange )
     271             :                                     {
     272         664 :                                         ++sts[0]->hTcxEnc->tnsData[k].nFilters;
     273         664 :                                         pFilter[0]->filterType = TNS_FILTER_ON;
     274         664 :                                         ++sts[1]->hTcxEnc->tnsData[k].nFilters;
     275         664 :                                         pFilter[1]->filterType = TNS_FILTER_ON;
     276             :                                     }
     277             :                                     else
     278             :                                     {
     279          10 :                                         pFilter[0]->filterType = TNS_FILTER_OFF;
     280          10 :                                         pFilter[1]->filterType = TNS_FILTER_OFF;
     281             :                                     }
     282             :                                 }
     283             :                             }
     284      195994 :                             else if ( sts[0]->hTcxEnc->tnsData[k].nFilters > 0 && sts[1]->hTcxEnc->tnsData[k].nFilters > 0 ) /* If a previous filter is turned on */
     285             :                             {
     286         203 :                                 pFilter[0]->filterType = TNS_FILTER_ON_ZERO;
     287         203 :                                 pFilter[1]->filterType = TNS_FILTER_ON_ZERO;
     288         203 :                                 ++sts[0]->hTcxEnc->tnsData[k].nFilters;
     289         203 :                                 ++sts[1]->hTcxEnc->tnsData[k].nFilters;
     290             :                             }
     291      195791 :                             else if ( sts[0]->hTcxEnc->tnsData[k].nFilters != sts[1]->hTcxEnc->tnsData[k].nFilters ) /* sanity check */
     292             :                             {
     293           0 :                                 assert( 0 );
     294             :                             }
     295             :                             else
     296             :                             {
     297      195791 :                                 pFilter[0]->filterType = TNS_FILTER_OFF;
     298      195791 :                                 pFilter[1]->filterType = TNS_FILTER_OFF;
     299             :                             }
     300      203119 :                             if ( ( pFilter[0]->filterType == TNS_FILTER_ON ) && ( pFilter[1]->filterType == TNS_FILTER_ON ) && ( sts[0]->element_brate < IVAS_80k ) )
     301             :                             {
     302        6000 :                                 int16_t tmpIntValue = 0;
     303             :                                 int16_t tmpCoeff[TNS_MAX_FILTER_ORDER];
     304        6000 :                                 int16_t i, maxOrder = max( pFilter[0]->order, pFilter[1]->order );
     305             : 
     306        6000 :                                 set_s( tmpCoeff, 0, TNS_MAX_FILTER_ORDER );
     307       45463 :                                 for ( i = 0; i < maxOrder; i++ )
     308             :                                 {
     309       39463 :                                     tmpIntValue = (int16_t) max( tmpIntValue, abs( pFilter[0]->coefIndex[i] - pFilter[1]->coefIndex[i] ) );
     310             :                                 }
     311        6000 :                                 if ( tmpIntValue == 1 ) /* the TNS coefficients are sufficiently similar to equalize the two filters */
     312             :                                 {
     313       27535 :                                     for ( i = maxOrder - 1; i >= 0; i-- )
     314             :                                     {
     315       23931 :                                         tmpCoeff[i] = ( abs( pFilter[0]->coefIndex[i] ) < abs( pFilter[1]->coefIndex[i] ) ? pFilter[0]->coefIndex[i] : pFilter[1]->coefIndex[i] );
     316       23931 :                                         if ( ( tmpIntValue > 0 ) && ( tmpCoeff[i] == 0 ) )
     317             :                                         {
     318        5723 :                                             maxOrder--;
     319             :                                         }
     320             :                                         else
     321             :                                         {
     322       18208 :                                             tmpIntValue = 0;
     323             :                                         }
     324             :                                     }
     325             :                                     /* make sure that maxOrder is non zero and not all coefficients are zero (could happen in rare cases) */
     326        3604 :                                     if ( maxOrder > 0 )
     327             :                                     {
     328       32436 :                                         for ( i = TNS_MAX_FILTER_ORDER - 1; i >= 0; i-- )
     329             :                                         {
     330       28832 :                                             pFilter[0]->coefIndex[i] = pFilter[1]->coefIndex[i] = tmpCoeff[i];
     331             :                                         }
     332             : 
     333        3604 :                                         pFilter[0]->order = pFilter[1]->order = maxOrder;
     334             :                                     }
     335             :                                 }
     336             :                             }
     337             :                         }
     338             :                         else
     339             :                         {
     340      104840 :                             individual_decision[k] = 1;
     341             :                         }
     342             :                     }
     343             : 
     344      164739 :                     if ( individual_decision[k] == 0 )
     345             :                     {
     346       80736 :                         sts[0]->hTcxEnc->fUseTns[k] = ( sts[0]->hTcxEnc->tnsData[k].nFilters > 0 ) ? 1 : 0;
     347       80736 :                         sts[1]->hTcxEnc->fUseTns[k] = ( sts[1]->hTcxEnc->tnsData[k].nFilters > 0 ) ? 1 : 0;
     348             :                     }
     349             :                     else
     350             :                     {
     351       84003 :                         sts[0]->hTcxEnc->tnsData[k].nFilters = 0;
     352       84003 :                         sts[1]->hTcxEnc->tnsData[k].nFilters = 0;
     353       84003 :                         sts[0]->hTcxEnc->fUseTns[k] = 0;
     354       84003 :                         sts[1]->hTcxEnc->fUseTns[k] = 0;
     355      244554 :                         for ( iFilter = sts[0]->hTcxCfg->pCurrentTnsConfig->nMaxFilters - 1; iFilter >= 0; iFilter-- )
     356             :                         {
     357      160551 :                             sts[0]->hTcxEnc->tnsData[k].filter[iFilter].filterType = TNS_FILTER_OFF;
     358      160551 :                             sts[1]->hTcxEnc->tnsData[k].filter[iFilter].filterType = TNS_FILTER_OFF;
     359             :                         }
     360             :                     }
     361             : 
     362      164739 :                     if ( !bWhitenedDomain && individual_decision[k] == 0 && maxPredGain < TNS_GAIN_THRESHOLD_FOR_WHITE && sts[0]->hTcxEnc->transform_type[k] != TCX_5 )
     363             :                     {
     364       39649 :                         sts[0]->hTcxEnc->bTnsOnWhithenedSpectra[k] = 1;
     365       39649 :                         sts[1]->hTcxEnc->bTnsOnWhithenedSpectra[k] = 1;
     366       39649 :                         sts[0]->hTcxEnc->tnsData[k].nFilters = 0;
     367       39649 :                         sts[1]->hTcxEnc->tnsData[k].nFilters = 0;
     368       39649 :                         sts[0]->hTcxEnc->fUseTns[k] = 0;
     369       39649 :                         sts[1]->hTcxEnc->fUseTns[k] = 0;
     370      112057 :                         for ( iFilter = sts[0]->hTcxCfg->pCurrentTnsConfig->nMaxFilters - 1; iFilter >= 0; iFilter-- )
     371             :                         {
     372       72408 :                             ClearTnsFilterCoefficients( sts[0]->hTcxEnc->tnsData[k].filter + iFilter );
     373       72408 :                             ClearTnsFilterCoefficients( sts[1]->hTcxEnc->tnsData[k].filter + iFilter );
     374             :                         }
     375             :                     }
     376      164739 :                     maxPredictionGain = max( maxPredictionGain, maxPredGain );
     377             :                 }
     378             :             }
     379             :         }
     380             :     }
     381             : 
     382             :     /* individual decision for each channel */
     383     2117694 :     for ( ch = 0; ch < CPE_CHANNELS; ch++ )
     384             :     {
     385     1411796 :         if ( sts[ch]->mct_chan_mode == MCT_CHAN_MODE_IGNORE )
     386             :         {
     387      126223 :             continue;
     388             :         }
     389             : 
     390             :         int16_t isTCX10;
     391     1285573 :         isTCX10 = ( sts[ch]->hTcxEnc->tcxMode == TCX_20 ) ? 0 : 1;
     392             : 
     393     1285573 :         nSubframes = ( sts[ch]->hTcxEnc->tcxMode == TCX_20 ) ? 1 : NB_DIV;
     394             : 
     395     2600768 :         for ( k = 0; k < nSubframes; k++ )
     396             :         {
     397     1315195 :             if ( sts[ch]->hTcxCfg->fIsTNSAllowed && ( individual_decision[k] || mct_on ) &&
     398      567793 :                  ( !bWhitenedDomain || sts[ch]->hTcxEnc->bTnsOnWhithenedSpectra[k] ) )
     399             :             {
     400     1131395 :                 float maxPredGain = -1.0f;
     401             : 
     402     1131395 :                 sts[ch]->hTcxCfg->pCurrentTnsConfig = &sts[ch]->hTcxCfg->tnsConfig[sts[ch]->hTcxEnc->transform_type[k] == TCX_20][( k == 0 ) && ( sts[ch]->last_core == ACELP_CORE )];
     403             : 
     404     3301325 :                 for ( iFilter = sts[ch]->hTcxCfg->pCurrentTnsConfig->nMaxFilters - 1; iFilter >= 0; iFilter-- )
     405             :                 {
     406             :                     STnsFilter *pFilter;
     407             :                     const struct TnsParameters *pTnsParameters;
     408     2169930 :                     pFilter = sts[ch]->hTcxEnc->tnsData[k].filter + iFilter;
     409     2169930 :                     pTnsParameters = sts[ch]->hTcxCfg->pCurrentTnsConfig->pTnsParameters + iFilter;
     410     2169930 :                     maxPredGain = max( maxPredGain, pFilter->predictionGain );
     411             : 
     412     2169930 :                     if ( ( pFilter->predictionGain > pTnsParameters->minPredictionGain ) || ( pFilter->avgSqrCoef > pTnsParameters->minAvgSqrCoef ) )
     413             :                     {
     414      134280 :                         if ( sts[ch]->hTcxEnc->tnsData[k].nFilters > 0 || isTCX10 || sts[ch]->hTcxEnc->tcxltp_gain < 0.6f )
     415             :                         {
     416      114899 :                             ++sts[ch]->hTcxEnc->tnsData[k].nFilters;
     417      114899 :                             pFilter->filterType = TNS_FILTER_ON;
     418             :                         }
     419             :                         else
     420             :                         {
     421       19381 :                             const float maxEnergyChange = GetTCXMaxenergyChange( sts[ch]->hTranDet, isTCX10, NSUBBLOCKS, 3 );
     422             : 
     423       19381 :                             if ( maxEnergyChange >= pTnsParameters->minEnergyChange )
     424             :                             {
     425       18203 :                                 ++sts[ch]->hTcxEnc->tnsData[k].nFilters;
     426       18203 :                                 pFilter->filterType = TNS_FILTER_ON;
     427             :                             }
     428             :                             else
     429             :                             {
     430        1178 :                                 pFilter->filterType = TNS_FILTER_OFF;
     431             :                             }
     432             :                         }
     433             :                     }
     434     2035650 :                     else if ( sts[ch]->hTcxEnc->tnsData[k].nFilters > 0 ) /* If a previous filter is turned on */
     435             :                     {
     436       12832 :                         pFilter->filterType = TNS_FILTER_ON_ZERO;
     437       12832 :                         ++sts[ch]->hTcxEnc->tnsData[k].nFilters;
     438             :                     }
     439             :                     else
     440             :                     {
     441     2022818 :                         pFilter->filterType = TNS_FILTER_OFF;
     442             :                     }
     443             :                 }
     444             : 
     445     1131395 :                 sts[ch]->hTcxEnc->fUseTns[k] = ( sts[ch]->hTcxEnc->tnsData[k].nFilters > 0 ) ? 1 : 0;
     446             : 
     447     1131395 :                 if ( !bWhitenedDomain && maxPredGain < TNS_GAIN_THRESHOLD_FOR_WHITE && sts[ch]->hTcxEnc->transform_type[k] != TCX_5 )
     448             :                 {
     449      560254 :                     sts[ch]->hTcxEnc->fUseTns[k] = 0;
     450      560254 :                     sts[ch]->hTcxEnc->bTnsOnWhithenedSpectra[k] = 1;
     451      560254 :                     sts[ch]->hTcxEnc->tnsData[k].nFilters = 0;
     452     1633868 :                     for ( iFilter = sts[ch]->hTcxCfg->pCurrentTnsConfig->nMaxFilters - 1; iFilter >= 0; iFilter-- )
     453             :                     {
     454     1073614 :                         ClearTnsFilterCoefficients( sts[ch]->hTcxEnc->tnsData[k].filter + iFilter );
     455     1073614 :                         sts[ch]->hTcxEnc->tnsData[k].filter[iFilter].filterType = TNS_FILTER_OFF;
     456             :                     }
     457             :                 }
     458     1131395 :                 maxPredictionGain = max( maxPredictionGain, maxPredGain );
     459             :             }
     460             :         }
     461             :     }
     462             : 
     463             : 
     464             :     /* we have the decision, set filter data accordingly */
     465     2117694 :     for ( ch = 0; ch < CPE_CHANNELS; ch++ )
     466             :     {
     467     1411796 :         if ( sts[ch]->mct_chan_mode == MCT_CHAN_MODE_IGNORE )
     468             :         {
     469      126223 :             continue;
     470             :         }
     471             : 
     472     1285573 :         nSubframes = ( sts[ch]->hTcxEnc->tcxMode == TCX_20 ) ? 1 : NB_DIV;
     473             : 
     474     2600768 :         for ( k = 0; k < nSubframes; k++ )
     475             :         {
     476     1315195 :             if ( sts[ch]->hTcxCfg->fIsTNSAllowed && ( !bWhitenedDomain || sts[ch]->hTcxEnc->bTnsOnWhithenedSpectra[k] ) )
     477             :             {
     478     1292867 :                 sts[ch]->hTcxCfg->pCurrentTnsConfig = &sts[ch]->hTcxCfg->tnsConfig[sts[ch]->hTcxEnc->transform_type[k] == TCX_20][( k == 0 ) && ( sts[ch]->last_core == ACELP_CORE )];
     479             : 
     480     3757613 :                 for ( iFilter = sts[ch]->hTcxCfg->pCurrentTnsConfig->nMaxFilters - 1; iFilter >= 0; iFilter-- )
     481             :                 {
     482             :                     STnsFilter *pFilter;
     483     2464746 :                     pFilter = sts[ch]->hTcxEnc->tnsData[k].filter + iFilter;
     484     2464746 :                     switch ( pFilter->filterType )
     485             :                     {
     486     2370728 :                         case TNS_FILTER_OFF:
     487     2370728 :                             ClearTnsFilterCoefficients( sts[ch]->hTcxEnc->tnsData[k].filter + iFilter );
     488     2370728 :                             break;
     489        9782 :                         case TNS_FILTER_ON_ZERO:
     490             :                             /* Since TNS filter of order 0 is not allowed we have to signal in the stream filter of order 1 with the 0th coefficient equal to 0 */
     491        9782 :                             ClearTnsFilterCoefficients( pFilter );
     492        9782 :                             pFilter->order = 1;
     493        9782 :                             break;
     494             :                     }
     495     2464746 :                 }
     496             :             }
     497             :         }
     498             :     }
     499             : 
     500             :     /* Apply filters, loop over channels */
     501     2117694 :     for ( ch = 0; ch < CPE_CHANNELS; ch++ )
     502             :     {
     503     1411796 :         st = sts[ch];
     504     1411796 :         if ( st->mct_chan_mode == MCT_CHAN_MODE_IGNORE )
     505             :         {
     506      126223 :             continue;
     507             :         }
     508             : 
     509     1285573 :         nSubframes = ( st->hTcxEnc->tcxMode == TCX_20 ) ? 1 : NB_DIV;
     510             : 
     511     2600768 :         for ( k = 0; k < nSubframes; k++ )
     512             :         {
     513     1315195 :             if ( bWhitenedDomain && ( ch > 0 ) && /* test for identical TNS filter data in both channels */
     514      296440 :                  sts[0]->hTcxCfg->fIsTNSAllowed && sts[0]->hTcxEnc->fUseTns[k] &&
     515       32636 :                  sts[1]->hTcxCfg->fIsTNSAllowed && sts[1]->hTcxEnc->fUseTns[k] )
     516             :             {
     517       56500 :                 int16_t equalFilterData = ( sts[0]->hTcxCfg->pCurrentTnsConfig->nMaxFilters == sts[1]->hTcxCfg->pCurrentTnsConfig->nMaxFilters &&
     518       18824 :                                             sts[0]->hTcxEnc->bTnsOnWhithenedSpectra[k] == sts[1]->hTcxEnc->bTnsOnWhithenedSpectra[k] &&
     519       16542 :                                             sts[0]->hTcxEnc->tnsData[k].nFilters == sts[1]->hTcxEnc->tnsData[k].nFilters )
     520             :                                               ? 1
     521       37662 :                                               : 0;
     522       18838 :                 if ( equalFilterData )
     523             :                 {
     524       31141 :                     for ( iFilter = st->hTcxCfg->pCurrentTnsConfig->nMaxFilters - 1; iFilter >= 0; iFilter-- )
     525             :                     {
     526       26831 :                         const int16_t *pDataCh0 = (const int16_t *) &sts[0]->hTcxEnc->tnsData[k].filter[iFilter];
     527       26831 :                         const int16_t *pDataCh1 = (const int16_t *) &sts[1]->hTcxEnc->tnsData[k].filter[iFilter];
     528       26831 :                         int16_t i = 2 + TNS_MAX_FILTER_ORDER; /* excl. informative float data. Portable? */
     529             : 
     530      226721 :                         while ( ( i >= 0 ) && ( pDataCh0[i] == pDataCh1[i] ) )
     531             :                         {
     532      199890 :                             i--;
     533             :                         }
     534       26831 :                         if ( i >= 0 )
     535             :                         {
     536       10842 :                             equalFilterData = 0;
     537       10842 :                             break;
     538             :                         }
     539             :                     }
     540       15152 :                     if ( equalFilterData )
     541             :                     {
     542        4310 :                         st->hTcxEnc->tnsData[k].nFilters *= -1; /* signals common TNS */
     543             :                     }
     544             :                 }
     545             :             }
     546     1315195 :             if ( st->hTcxCfg->fIsTNSAllowed && ( !bWhitenedDomain || st->hTcxEnc->bTnsOnWhithenedSpectra[k] ) )
     547             :             {
     548     1292867 :                 L_spec = st->hTcxCfg->pCurrentTnsConfig->iFilterBorders[0];
     549     1292867 :                 spectrum = st->hTcxEnc->spectrum[k];
     550             :                 /* If TNS should be used then get the residual after applying it inplace in the spectrum */
     551     1292867 :                 if ( st->hTcxEnc->fUseTns[k] )
     552             :                 {
     553       72785 :                     st->hTcxCfg->pCurrentTnsConfig = &st->hTcxCfg->tnsConfig[st->hTcxEnc->transform_type[k] == TCX_20][( k == 0 ) && ( st->last_core == ACELP_CORE )];
     554             : 
     555       72785 :                     ApplyTnsFilter( st->hTcxCfg->pCurrentTnsConfig, &st->hTcxEnc->tnsData[k], spectrum, 1 );
     556             :                 }
     557             : 
     558     1292867 :                 if ( st->hTcxEnc->transform_type[k] == TCX_5 )
     559             :                 {
     560       15305 :                     tcx5TnsUngrouping( L_frame >> 2, L_spec >> 1, st->hTcxEnc->spectrum[k], ENC );
     561             :                 }
     562             : 
     563     1292867 :                 st->hTcxEnc->tnsData[k].tnsOnWhitenedSpectra = st->hTcxEnc->bTnsOnWhithenedSpectra[k];
     564             : 
     565     1292867 :                 EncodeTnsData( st->hTcxCfg->pCurrentTnsConfig, &st->hTcxEnc->tnsData[k], param_core[ch] + k * NPRM_DIV + 1 + NOISE_FILL_RANGES + LTPSIZE, tnsSize[ch] + k, tnsBits[ch] + k );
     566             :             }
     567             : 
     568     1315195 :             if ( st->hTcxEnc->transform_type[k] == TCX_5 )
     569             :             {
     570       30610 :                 tcx5SpectrumInterleaving( st->hTcxCfg->tcx5SizeFB, st->hTcxEnc->spectrum[k] );
     571       30610 :                 tcx5SpectrumInterleaving( st->hTcxCfg->tcx5SizeFB, mdst_spectrum[ch][k] );
     572             :             }
     573             :         }
     574             :     }
     575             : 
     576      705898 :     return;
     577             : }
     578             : 
     579             : 
     580             : /*-------------------------------------------------------------------*
     581             :  * TNSAnalysis()
     582             :  *
     583             :  *
     584             :  *-------------------------------------------------------------------*/
     585             : 
     586      237660 : void TNSAnalysis(
     587             :     TCX_CONFIG_HANDLE hTcxCfg,    /* i  : configuration of TCX                                                                    */
     588             :     const int16_t L_frame,        /* i  : frame length                                                                            */
     589             :     int16_t L_spec,               /* i  : length of the spectrum                                                                  */
     590             :     const int16_t transform_type, /* i  : transform type for the frame/subframe - TCX20 | TCX10 | TCX 5 (meaning 2 x TCX 5)       */
     591             :     const int16_t isAfterACELP,   /* i  : Flag indicating if the last frame was ACELP. For the second TCX subframe it should be 0 */
     592             :     float spectrum[],             /* i  : MDCT spectrum of the subframe                                                           */
     593             :     TRAN_DET_HANDLE hTranDet,     /* i  : handle transient detection                                                              */
     594             :     const float ltp_gain,         /* i  : ltp gain                                                                                */
     595             :     STnsData *pTnsData,           /* o  : TNS data                                                                                */
     596             :     int16_t *pfUseTns,            /* o  : Flag indicating if TNS is used                                                          */
     597             :     float *predictionGain         /* o  : TNS prediction gain                                                                     */
     598             : )
     599             : {
     600             :     float buff[8]; /* Buffer for the rearrangement of LF TCX5 */
     601             : 
     602             :     /* Init TNS */
     603      237660 :     *pfUseTns = 0;
     604             : 
     605      237660 :     if ( hTcxCfg->fIsTNSAllowed )
     606             :     {
     607      161953 :         hTcxCfg->pCurrentTnsConfig = &hTcxCfg->tnsConfig[transform_type == TCX_20][isAfterACELP];
     608      161953 :         L_spec = hTcxCfg->pCurrentTnsConfig->iFilterBorders[0];
     609             : 
     610             :         /*-----------------------------------------------------------*
     611             :          * Temporal Noise Shaping analysis                           *
     612             :          *-----------------------------------------------------------*/
     613             : 
     614      161953 :         if ( transform_type == TCX_5 )
     615             :         {
     616             :             /* rearrange LF sub-window lines prior to TNS analysis & filtering */
     617        2231 :             if ( L_spec < L_frame / 2 )
     618             :             {
     619        2163 :                 mvr2r( spectrum + 8, spectrum + 16, L_spec / 2 - 8 );
     620        2163 :                 mvr2r( spectrum + L_frame / 4, spectrum + 8, 8 );
     621        2163 :                 mvr2r( spectrum + L_frame / 4 + 8, spectrum + L_spec / 2 + 8, L_spec / 2 - 8 );
     622             :             }
     623             :             else
     624             :             {
     625          68 :                 mvr2r( spectrum + L_frame / 4, buff, 8 );
     626          68 :                 mvr2r( spectrum + 8, spectrum + 16, L_frame / 4 - 8 );
     627          68 :                 mvr2r( buff, spectrum + 8, 8 );
     628             :             }
     629             :         }
     630             : 
     631      161953 :         *pfUseTns = DetectTnsFilt( hTcxCfg->pCurrentTnsConfig, spectrum, hTranDet, transform_type != TCX_20, ltp_gain, pTnsData, predictionGain );
     632             : 
     633             : 
     634             :         /* If TNS should be used then get the residual after applying it inplace in the spectrum */
     635      161953 :         if ( *pfUseTns )
     636             :         {
     637       17665 :             ApplyTnsFilter( hTcxCfg->pCurrentTnsConfig, pTnsData, spectrum, 1 );
     638             :         }
     639             : 
     640      161953 :         if ( transform_type == TCX_5 )
     641             :         {
     642             :             /* undo rearrangement of LF sub-window lines prior to TNS analysis */
     643        2231 :             if ( L_spec < L_frame / 2 )
     644             :             {
     645        2163 :                 mvr2r( spectrum + L_spec / 2 + 8, spectrum + L_frame / 4 + 8, L_spec / 2 - 8 );
     646        2163 :                 mvr2r( spectrum + 8, spectrum + L_frame / 4, 8 );
     647        2163 :                 mvr2r( spectrum + 16, spectrum + 8, L_spec / 2 - 8 );
     648        2163 :                 set_zero( spectrum + L_spec / 2, L_frame / 4 - L_spec / 2 );
     649        2163 :                 set_zero( spectrum + L_frame / 4 + L_spec / 2, L_frame / 4 - L_spec / 2 );
     650             :             }
     651             :             else
     652             :             {
     653          68 :                 mvr2r( spectrum + 8, buff, 8 );
     654          68 :                 mvr2r( spectrum + 16, spectrum + 8, L_frame / 4 - 8 );
     655          68 :                 mvr2r( buff, spectrum + L_frame / 4, 8 );
     656             :             }
     657             :         }
     658             :     }
     659             : 
     660      237660 :     return;
     661             : }
     662             : 
     663             : 
     664             : /*-------------------------------------------------------------------*
     665             :  * ShapeSpectrum()
     666             :  *
     667             :  *
     668             :  *-------------------------------------------------------------------*/
     669             : 
     670     1471780 : void ShapeSpectrum(
     671             :     TCX_CONFIG_HANDLE hTcxCfg,  /* i  : configuration of TCX                */
     672             :     const float A[],            /* i  : quantized coefficients NxAz_q[M+1]  */
     673             :     float gainlpc[],            /* o  : MDCT gains for the previous frame   */
     674             :     const int16_t L_frame_glob, /* i  : frame length                        */
     675             :     int16_t L_spec,             /* i  : length of the spectrum              */
     676             :     float spectrum[],           /* i/o: MDCT spectrum                       */
     677             :     const int16_t fUseTns,      /* i  : Flag indicating if TNS is used      */
     678             :     Encoder_State *st,          /* i/o: encoder state structure             */
     679             :     float *scf                  /* i  : scale factors                       */
     680             : )
     681             : {
     682     1471780 :     TCX_ENC_HANDLE hTcxEnc = st->hTcxEnc;
     683             :     int16_t i, sf_width, L_frame, tcx_offset;
     684             :     float Ap[M + 2];
     685             :     float tmp, gamma1;
     686     1471780 :     float max_low_pre = 0.f, max_high_pre = 0.f;
     687             :     float sns_int_scf[FDNS_NPTS];
     688     1471780 :     int32_t total_brate = ( st->element_mode == IVAS_CPE_MDCT ? st->element_brate : st->total_brate );
     689             :     /*-----------------------------------------------------------*
     690             :      * Init                                                      *
     691             :      *-----------------------------------------------------------*/
     692             : 
     693             :     /* Init lengths */
     694     1471780 :     L_frame = L_frame_glob;
     695     1471780 :     tcx_offset = hTcxCfg->tcx_offset;
     696             : 
     697     1471780 :     gamma1 = st->gamma;
     698     1471780 :     if ( st->enableTcxLpc )
     699             :     {
     700       17457 :         gamma1 = 1.0f;
     701             :     }
     702             : 
     703     1471780 :     if ( st->element_mode != IVAS_CPE_MDCT ) /* in MDCT, this is already done outside the function */
     704             :     {
     705      237935 :         if ( st->last_core == ACELP_CORE )
     706             :         {
     707        7988 :             L_frame += tcx_offset;
     708        7988 :             L_spec += hTcxCfg->tcx_coded_lines >> 2;
     709        7988 :             if ( hTcxCfg->lfacNext < 0 )
     710             :             {
     711        7988 :                 L_frame -= hTcxCfg->lfacNext;
     712             :             }
     713             :         }
     714             :     }
     715             : 
     716     1471780 :     tcxGetNoiseFillingTilt( A, L_frame, ( total_brate >= ACELP_13k20 && !st->rf_mode ), &st->hTcxEnc->noiseTiltFactor );
     717             : 
     718             :     /* Calculate Spectrum Flatness Measure for the TCX Concealment */
     719     1471780 :     if ( st->enablePlcWaveadjust )
     720             :     {
     721           0 :         hTcxCfg->SFM2 = SFM_Cal( spectrum, min( 200, L_frame ) );
     722             :     }
     723             : 
     724     1471780 :     if ( ( total_brate <= ACELP_13k20 && st->bwidth == SWB ) )
     725             :     {
     726       31258 :         max_low_pre = 0.f;
     727     8173914 :         for ( i = 0; i < L_frame; i++ )
     728             :         {
     729     8142656 :             tmp = fabsf( spectrum[i] );
     730     8142656 :             if ( tmp > max_low_pre )
     731             :             {
     732      138748 :                 max_low_pre = tmp;
     733             :             }
     734             :         }
     735             : 
     736       31258 :         max_high_pre = 0.f;
     737    12245242 :         for ( i = 0; i < L_spec - L_frame; i++ )
     738             :         {
     739    12213984 :             tmp = fabsf( spectrum[L_frame + i] );
     740    12213984 :             if ( tmp > max_high_pre )
     741             :             {
     742        2462 :                 max_high_pre = tmp;
     743             :             }
     744             :         }
     745             :     }
     746             : 
     747     1471780 :     if ( st->element_mode == IVAS_CPE_MDCT )
     748             :     {
     749     1233845 :         sns_interpolate_scalefactors( &sns_int_scf[0], scf, ENC );
     750     1233845 :         sns_shape_spectrum( spectrum, st->hTcxCfg->psychParamsCurrent, &sns_int_scf[0], L_frame );
     751     1233845 :         v_multc( spectrum + L_frame, sns_int_scf[hTcxCfg->psychParamsCurrent->nBands - 1], spectrum + L_frame, L_spec - L_frame );
     752             :     }
     753             :     else
     754             :     {
     755             :         /*-----------------------------------------------------------*
     756             :          * Pre-shaping in frequency domain using weighted LPC (Wz)   *
     757             :          *-----------------------------------------------------------*/
     758             : 
     759      237935 :         weight_a( A, Ap, gamma1, M );
     760             : 
     761      237935 :         lpc2mdct( Ap, M, gainlpc, FDNS_NPTS, 0 );
     762             : 
     763      237935 :         mdct_preShaping( spectrum, L_frame, gainlpc );
     764             : 
     765      237935 :         v_multc( spectrum + L_frame, 1.f / gainlpc[FDNS_NPTS - 1], spectrum + L_frame, L_spec - L_frame );
     766             :     }
     767             : 
     768             :     /* reduce the peaks in the IGF region, to make life of the core-coder easier... */
     769     1471780 :     if ( total_brate <= ACELP_13k20 && st->bwidth == SWB )
     770             :     {
     771             :         int16_t dist_low, dist_high;
     772             :         float max_fac;
     773             :         float max_low, max_low1, max_low2, max_high;
     774             : 
     775       31258 :         if ( hTcxEnc->tcx_lpc_shaped_ari )
     776             :         {
     777       13364 :             max_fac = 1.5f;
     778             :         }
     779             :         else
     780             :         {
     781       17894 :             max_fac = 3.f;
     782             :         }
     783             : 
     784       31258 :         sf_width = L_frame / 2;
     785             : 
     786       31258 :         max_low2 = 0.f;
     787       31258 :         dist_low = 0;
     788     4102586 :         for ( i = 0; i < sf_width; i++ )
     789             :         {
     790     4071328 :             tmp = fabsf( spectrum[L_frame - 1 - i] );
     791     4071328 :             if ( tmp > max_low2 )
     792             :             {
     793      188749 :                 max_low2 = tmp;
     794      188749 :                 dist_low = i;
     795             :             }
     796             :         }
     797             : 
     798       31258 :         max_low1 = 0.f;
     799     4102586 :         for ( i = 0; i < L_frame - sf_width; i++ )
     800             :         {
     801     4071328 :             tmp = fabsf( spectrum[L_frame - sf_width - 1 - i] );
     802     4071328 :             if ( tmp > max_low1 )
     803             :             {
     804      287064 :                 max_low1 = tmp;
     805             :             }
     806     4071328 :             if ( tmp > max_low2 )
     807             :             {
     808      558548 :                 dist_low = sf_width + i;
     809             :             }
     810             :         }
     811             : 
     812       31258 :         max_low = max( max_low1, max_low2 );
     813             : 
     814       31258 :         max_high = 0.f;
     815       31258 :         dist_high = 0;
     816    12245242 :         for ( i = 0; i < L_spec - L_frame; i++ )
     817             :         {
     818    12213984 :             tmp = fabsf( spectrum[L_frame + i] );
     819    12213984 :             if ( tmp > max_high )
     820             :             {
     821        2462 :                 max_high = tmp;
     822        2462 :                 dist_high = i;
     823             :             }
     824             :         }
     825             : 
     826       31258 :         if ( ( 4.f * dist_high * max_high > dist_low * max_low ) && ( 16.f * max_low_pre > max_high_pre ) && ( max_high > max_fac * max_low2 ) )
     827             :         {
     828         597 :             tmp = max_fac * max_low2 / max_high;
     829         597 :             v_multc( spectrum + L_frame, tmp, spectrum + L_frame, L_spec - L_frame );
     830             :         }
     831             :     }
     832             : 
     833     1471780 :     if ( st->element_mode != IVAS_CPE_MDCT && st->tcxonly && st->hTcxEnc->tcxltp && ( st->hTcxEnc->tcxltp_gain > 0.0f ) && !fUseTns )
     834             :     {
     835        3732 :         PsychAdaptLowFreqEmph( spectrum, gainlpc );
     836             :     }
     837             : 
     838     1471780 :     return;
     839             : }
     840             : 
     841             : 
     842             : /*-------------------------------------------------------------------*
     843             :  * GetTransWidth()
     844             :  *
     845             :  *
     846             :  *-------------------------------------------------------------------*/
     847             : 
     848     1073088 : static int16_t GetTransWidth(
     849             :     const int16_t tcxonly,
     850             :     const int16_t tcx10,
     851             :     const float tcxltp_gain,
     852             :     const int16_t hm_active )
     853             : {
     854     1073088 :     int16_t noiseTransWidth = MIN_NOISE_FILLING_HOLE;
     855             : 
     856     1073088 :     if ( tcxonly )
     857             :     {
     858      815633 :         noiseTransWidth = HOLE_SIZE_FROM_LTP( max( tcxltp_gain, 0.3125f * hm_active ) );
     859             : 
     860      815633 :         if ( tcx10 )
     861             :         {
     862       35389 :             noiseTransWidth = 3; /* minimum transition for noise filling in TCX-10 */
     863             :         }
     864             :     }
     865             : 
     866     1073088 :     return noiseTransWidth;
     867             : }
     868             : 
     869             : 
     870             : /*-----------------------------------------------------------*
     871             :  * EstimateTCXNoiseLevel()
     872             :  *
     873             :  * Estimate and quantize noise factor                        *
     874             :  *-----------------------------------------------------------*/
     875             : 
     876      237935 : static void EstimateTCXNoiseLevel(
     877             :     Encoder_State *st,                /* i  : encoder state handle                            */
     878             :     const float x_orig[],             /* i  : shaped MDCT spectrum                            */
     879             :     float spectrum[],                 /* i/o: quantized MDCT spectrum                         */
     880             :     const float gain_tcx,             /* i  : global gain                                     */
     881             :     const int16_t L_frame,            /* i  : frame length                                    */
     882             :     const int16_t noiseFillingBorder, /* i  : noise filling border                            */
     883             :     const int16_t hm_active,          /* i  : flag indicating if the harmonic model is active */
     884             :     float *fac_ns,                    /* o  : noise filling level                             */
     885             :     int16_t *fac_ns_q                 /* o  : quantized noise filling level                   */
     886             : )
     887             : {
     888             :     int16_t maxNfCalcBw, iStart, noiseTransWidth;
     889      237935 :     TCX_ENC_HANDLE hTcxEnc = st->hTcxEnc;
     890             : 
     891      237935 :     maxNfCalcBw = min( noiseFillingBorder, (int16_t) ( hTcxEnc->measuredBwRatio * (float) L_frame + 0.5f ) );
     892             : 
     893      237935 :     if ( st->total_brate >= HQ_96k )
     894             :     {
     895       18143 :         *fac_ns = 0.0f;
     896       18143 :         *fac_ns_q = 0;
     897             :     }
     898             :     else
     899             :     {
     900      219792 :         const int16_t minLevel = ( hTcxEnc->tcx_lpc_shaped_ari && st->element_mode > IVAS_SCE ? 0 : 1 );
     901      219792 :         iStart = L_frame / ( ( st->total_brate >= ACELP_13k20 && !st->rf_mode ) ? 6 : 8 ); /* noise filling start bin*/
     902      219792 :         noiseTransWidth = GetTransWidth( st->tcxonly, ( L_frame == st->L_frame >> 1 ), st->hTcxEnc->tcxltp_gain, ( st->hTcxCfg->ctx_hm && st->last_core != ACELP_CORE && hm_active ) );
     903      219792 :         tcx_noise_factor( x_orig, spectrum, iStart, maxNfCalcBw, noiseTransWidth, L_frame, gain_tcx, hTcxEnc->noiseTiltFactor, fac_ns, fac_ns_q, st->element_mode );
     904             : 
     905             :         /* hysteresis for very tonal passages (more stationary noise filling level) */
     906      219792 :         if ( *fac_ns_q == minLevel )
     907             :         {
     908       15204 :             hTcxEnc->noiseLevelMemory_cnt = (int16_t) min( INT16_MAX, 1 + abs( hTcxEnc->noiseLevelMemory_cnt ) ); /* update counter */
     909             :         }
     910             :         else
     911             :         {
     912      204588 :             if ( ( *fac_ns_q == minLevel + 1 ) && ( abs( hTcxEnc->noiseLevelMemory_cnt ) > 5 ) )
     913             :             {
     914         775 :                 *fac_ns_q = minLevel; /* reduce noise filling level by one step */
     915         775 :                 *fac_ns = minLevel * 0.75f / ( 1 << NBITS_NOISE_FILL_LEVEL );
     916             : 
     917             :                 /* signal that noise level is changed by inverting sign of level memory */
     918         775 :                 hTcxEnc->noiseLevelMemory_cnt = ( hTcxEnc->noiseLevelMemory_cnt < 0 ) ? 5 : -1 - hTcxEnc->noiseLevelMemory_cnt;
     919             :             }
     920             :             else
     921             :             {
     922      203813 :                 hTcxEnc->noiseLevelMemory_cnt = 0; /* reset memory since level is too different */
     923             :             }
     924             :         }
     925             :     } /* bitrate */
     926             : 
     927      237935 :     return;
     928             : }
     929             : 
     930             : 
     931             : /*-----------------------------------------------------------*
     932             :  * EstimateStereoTCXNoiseLevel()
     933             :  *
     934             :  * Estimate and quantize stereo noise factors
     935             :  *-----------------------------------------------------------*/
     936             : 
     937      352949 : void EstimateStereoTCXNoiseLevel(
     938             :     Encoder_State **sts,                     /* i  : state handle                                    */
     939             :     float *q_spectrum[CPE_CHANNELS][NB_DIV], /* i  : quantized MDCT spectrum                         */
     940             :     float gain_tcx[][NB_DIV],                /* i  : global gain                                     */
     941             :     int16_t L_frame[][NB_DIV],               /* i  : frame length                                    */
     942             :     int16_t noiseFillingBorder[][NB_DIV],    /* i  : noise filling border                            */
     943             :     int16_t hm_active[][NB_DIV],             /* i  : flag indicating if the harmonic model is active */
     944             :     const int16_t ignore_chan[],             /* i  : flag indicating whether the channel should be ignored */
     945             :     float fac_ns[][NB_DIV],                  /* o  : noise filling level                             */
     946             :     int16_t param_core[][NB_DIV * NPRM_DIV], /* o  : quantized noise filling level                   */
     947             :     const int16_t MCT_flag                   /* i  : hMCT handle allocated (1) or not (0)            */
     948             : )
     949             : {
     950             :     int16_t ch, n;
     951             :     int16_t nSubframes, maxNfCalcBw, iStart, noiseTransWidth;
     952             :     float smooth_gain;
     953             :     float combined_q_spectrum[N_MAX];
     954             :     int16_t *fac_ns_q;
     955             :     int32_t total_brate;
     956             : 
     957     1058847 :     for ( ch = 0; ch < CPE_CHANNELS; ch++ )
     958             :     {
     959      705898 :         Encoder_State *st = sts[ch];
     960      705898 :         TCX_ENC_HANDLE hTcxEnc = st->hTcxEnc;
     961             : 
     962      705898 :         nSubframes = ( st->hTcxEnc->tcxMode == TCX_20 ) ? 1 : NB_DIV;
     963             : 
     964      705898 :         if ( ignore_chan[ch] )
     965             :         {
     966       67249 :             continue;
     967             :         }
     968      638649 :         total_brate = ( st->element_mode == IVAS_CPE_MDCT && !MCT_flag ) ? st->element_brate : st->total_brate;
     969             : 
     970     1292109 :         for ( n = 0; n < nSubframes; n++ )
     971             :         {
     972      653460 :             fac_ns_q = param_core[ch] + n * NPRM_DIV + 1;
     973      653460 :             maxNfCalcBw = min( noiseFillingBorder[ch][n], (int16_t) ( hTcxEnc->measuredBwRatio * (float) L_frame[ch][n] + 0.5f ) );
     974      653460 :             if ( ( total_brate >= HQ_96k && ( st->element_mode <= IVAS_SCE || st->bwidth < SWB ) ) || total_brate > IVAS_192k )
     975             :             {
     976       19488 :                 fac_ns[ch][n] = 0.0f;
     977       19488 :                 *fac_ns_q = 0;
     978             :             }
     979             :             else
     980             :             {
     981      633972 :                 iStart = L_frame[ch][n] / ( ( total_brate >= ACELP_13k20 && !st->rf_mode ) ? 6 : 8 ); /* noise filling start bin*/
     982             : 
     983      633972 :                 if ( n == 0 )
     984             :                 {
     985      619612 :                     mvr2r( hTcxEnc->ltpGainMemory, &hTcxEnc->ltpGainMemory[1], N_LTP_GAIN_MEMS - 1 );
     986      619612 :                     hTcxEnc->ltpGainMemory[0] = st->hTcxEnc->tcxltp_gain;
     987             :                 }
     988             : 
     989      633972 :                 smooth_gain = dotp( hTcxEnc->ltpGainMemory, nf_tw_smoothing_coeffs, N_LTP_GAIN_MEMS );
     990             : 
     991      633972 :                 noiseTransWidth = GetTransWidth( st->tcxonly, ( L_frame[ch][n] == st->L_frame >> 1 ), smooth_gain, ( st->hTcxCfg->ctx_hm && st->last_core != ACELP_CORE && hm_active[ch][n] ) );
     992             : 
     993      633972 :                 mvr2r( q_spectrum[ch][n], combined_q_spectrum, L_frame[ch][n] );
     994      633972 :                 tcx_noise_factor( hTcxEnc->spectrum[n], combined_q_spectrum, iStart, maxNfCalcBw, noiseTransWidth, L_frame[ch][n], gain_tcx[ch][n], hTcxEnc->noiseTiltFactor, &fac_ns[ch][n], fac_ns_q, st->element_mode );
     995             : 
     996             :                 /* hysteresis for very tonal passages (more stationary noise filling level) */
     997      633972 :                 if ( *fac_ns_q == 1 )
     998             :                 {
     999       82124 :                     hTcxEnc->noiseLevelMemory_cnt = (int16_t) min( INT16_MAX, 1 + abs( hTcxEnc->noiseLevelMemory_cnt ) ); /* update counter */
    1000             :                 }
    1001             :                 else
    1002             :                 {
    1003      551848 :                     if ( ( *fac_ns_q == 2 ) && ( abs( hTcxEnc->noiseLevelMemory_cnt ) > 5 ) )
    1004             :                     {
    1005        6658 :                         *fac_ns_q = 1; /* reduce noise filling level by one step */
    1006        6658 :                         fac_ns[ch][n] = 0.75f / ( 1 << NBITS_NOISE_FILL_LEVEL );
    1007             : 
    1008             :                         /* signal that noise level is changed by inverting sign of level memory */
    1009        6658 :                         hTcxEnc->noiseLevelMemory_cnt = ( hTcxEnc->noiseLevelMemory_cnt < 0 ) ? 5 : -1 - hTcxEnc->noiseLevelMemory_cnt;
    1010             :                     }
    1011             :                     else
    1012             :                     {
    1013      545190 :                         hTcxEnc->noiseLevelMemory_cnt = 0; /* reset memory since level is too different */
    1014             :                     }
    1015             :                 }
    1016             :             } /* bitrate */
    1017             :         }
    1018             : #ifdef DEBUG_MODE_MDCT
    1019             :         dbgwrite( &smooth_gain, sizeof( float ), 1, 1, "./res/smooth_gain" );
    1020             :         dbgwrite( &st->hTcxEnc->tcxltp_gain, sizeof( float ), 1, 1, "./res/tcxltp_gain" );
    1021             :         dbgwrite( &noiseTransWidth, sizeof( int16_t ), 1, 1, "./res/noiseTrans" );
    1022             :         dbgwrite( &fac_ns[ch][0], sizeof( float ), 2, 1, "./res/fac_ns" );
    1023             : #endif
    1024             :     }
    1025             : 
    1026      352949 :     return;
    1027             : }
    1028             : 
    1029             : 
    1030             : /*-----------------------------------------------------------*
    1031             :  * DecideTonalSideInfo()
    1032             :  *
    1033             :  *
    1034             :  *-----------------------------------------------------------*/
    1035             : 
    1036           0 : static int16_t DecideTonalSideInfo(
    1037             :     const float spectrum[],
    1038             :     const int16_t L_frame_glob,
    1039             :     float SFM2 )
    1040             : {
    1041             :     float SFM, K, K2;
    1042             :     int16_t Tonal_SideInfo;
    1043             : 
    1044           0 :     SFM = SFM_Cal( spectrum, min( 200, L_frame_glob ) );
    1045             : 
    1046           0 :     if ( L_frame_glob <= 256 )
    1047             :     {
    1048           0 :         K = 0.4f;
    1049           0 :         K2 = 0.1f;
    1050             :     }
    1051           0 :     else if ( L_frame_glob == 320 || L_frame_glob == 512 )
    1052             :     {
    1053           0 :         K = 0.4f;
    1054           0 :         K2 = 0.1f;
    1055             :     }
    1056             :     else /*FrameSize_Core == 640*/
    1057             :     {
    1058           0 :         K = 0.35f;
    1059           0 :         K2 = 0.04f;
    1060             :     }
    1061             : 
    1062             : 
    1063           0 :     Tonal_SideInfo = 0;
    1064           0 :     if ( SFM < K )
    1065             :     {
    1066           0 :         Tonal_SideInfo = 1;
    1067             :     }
    1068             : 
    1069           0 :     if ( SFM2 < K2 )
    1070             :     {
    1071           0 :         Tonal_SideInfo = 1;
    1072             :     }
    1073             : 
    1074           0 :     return Tonal_SideInfo;
    1075             : }
    1076             : 
    1077             : /*-----------------------------------------------------------*
    1078             :  * QuantizeTCXSpectrum()
    1079             :  *
    1080             :  *
    1081             :  *-----------------------------------------------------------*/
    1082             : 
    1083      891395 : void QuantizeTCXSpectrum(
    1084             :     Encoder_State *st,            /* i  : state handle                            */
    1085             :     const int16_t frame_cnt,      /* i  : frame counter in the super_frame        */
    1086             :     const float *x_orig,          /* i  : shaped MDCT spectrum                    */
    1087             :     const float *gainlpc,         /* i  : FDNS gains                              */
    1088             :     const Word16 *Aqind,          /* i  : frame-independent quantized coefficients (M+1) */
    1089             :     const int16_t tnsSize,        /* i  : number of tns parameters put into prm   */
    1090             :     const int16_t nb_bits,        /* i  : bit budget                              */
    1091             :     const int16_t vad_hover_flag, /* i  : VAD hangover flag */
    1092             :     int16_t *pL_frameTCX,         /* o  : full frame length                       */
    1093             :     int16_t *pL_frame,            /* o  : frame length                            */
    1094             :     int16_t *pL_spec,             /* o  : length of the coded spectrum            */
    1095             :     int16_t *ptcx_offset,         /* o  : folding point offset relative to the end of the previous frame */
    1096             :     int16_t *pnoiseFillingBorder, /* o  : noise filling border                    */
    1097             :     float spectrum[],             /* o  : quantized MDCT spectrum                 */
    1098             :     CONTEXT_HM_CONFIG *hm_cfg,    /* o  : Context-based harmonic model configuration */
    1099             :     int16_t *hm_active,           /* o  : flag indicating if the harmonic model is active */
    1100             :     float lf_deemph_fact[],       /* o  : low frequency deemphasis factors        */
    1101             :     int16_t *nf_seed,             /* o  : noise filling random seed               */
    1102             :     float *ener,                  /* o  : energy of the quantized spectrum        */
    1103             :     float *gain_tcx,              /* o  : global gain                             */
    1104             :     int16_t prm[]                 /* o  : tcx parameters                          */
    1105             : )
    1106             : {
    1107      891395 :     TCX_ENC_HANDLE hTcxEnc = st->hTcxEnc;
    1108             :     int16_t i, L_frame, L_frameTCX, L_spec, tcx_offset;
    1109             :     int16_t noiseFillingBorder, LtpPitchLag, PeriodicityIndex;
    1110             :     float sqGain, gain_tcx_opt, RelativeScore;
    1111             :     int16_t lastnzCtxHm, lastnz;
    1112             :     int16_t stop;
    1113             :     int16_t nEncodedCtxHm, stopCtxHm, sqBitsCtxHm, Selector;
    1114             :     int16_t nEncoded, sqBits_noStop;
    1115             :     int16_t NumIndexBits, signaling_bits, sqTargetBits, sqBits, ctxHmBits, resQBits, resQTargetBits;
    1116             :     int16_t *prm_ltp, *prm_tns, *prm_hm, *prm_lastnz, *sqQ, *prm_target;
    1117             :     float att;
    1118             :     int32_t total_brate;
    1119             : 
    1120             :     /*-----------------------------------------------------------*
    1121             :      * Init                                                      *
    1122             :      *-----------------------------------------------------------*/
    1123             : 
    1124      891395 :     sqGain = 1.0f;
    1125      891395 :     resQTargetBits = 0;
    1126             : 
    1127      891395 :     NumIndexBits = 0;
    1128      891395 :     sqBits = 0;
    1129      891395 :     ctxHmBits = 0;
    1130      891395 :     resQBits = 0;
    1131      891395 :     prm_ltp = &prm[1 + NOISE_FILL_RANGES];
    1132      891395 :     prm_tns = prm_ltp + LTPSIZE;
    1133      891395 :     prm_hm = prm_tns + tnsSize;
    1134      891395 :     prm_lastnz = prm_hm + 2;
    1135      891395 :     sqQ = prm_hm + NPRM_CTX_HM;
    1136             : 
    1137      891395 :     total_brate = ( st->element_mode == IVAS_CPE_MDCT ) ? st->element_brate : st->total_brate;
    1138             : 
    1139             :     /*-----------------------------------------------------------*
    1140             :      * Init lengths                                              *
    1141             :      *-----------------------------------------------------------*/
    1142             : 
    1143      891395 :     L_frame = st->L_frame;
    1144      891395 :     L_frameTCX = hTcxEnc->L_frameTCX;
    1145      891395 :     L_spec = st->hTcxCfg->tcx_coded_lines;
    1146      891395 :     tcx_offset = st->hTcxCfg->tcx_offset;
    1147             : 
    1148      891395 :     if ( st->core == TCX_10_CORE )
    1149             :     {
    1150       33776 :         L_frame /= 2;
    1151       33776 :         L_frameTCX /= 2;
    1152       33776 :         L_spec /= 2;
    1153             :     }
    1154      857619 :     else if ( st->last_core == ACELP_CORE )
    1155             :     {
    1156        9376 :         st->hTcxCfg->last_aldo = 0;
    1157             : 
    1158        9376 :         L_frame += tcx_offset;
    1159        9376 :         L_frameTCX += st->hTcxCfg->tcx_offsetFB;
    1160        9376 :         L_spec += st->hTcxCfg->tcx_coded_lines >> 2;
    1161             : 
    1162        9376 :         if ( st->hTcxCfg->lfacNext < 0 )
    1163             :         {
    1164        9376 :             L_frame -= st->hTcxCfg->lfacNext;
    1165        9376 :             L_frameTCX -= st->hTcxCfg->lfacNextFB;
    1166        9376 :             tcx_offset = st->hTcxCfg->lfacNext;
    1167             :         }
    1168             :         else
    1169             :         {
    1170           0 :             tcx_offset = 0;
    1171             :         }
    1172        9376 :         hTcxEnc->noiseLevelMemory_cnt = 0;
    1173             :     }
    1174             : 
    1175      891395 :     *pL_frameTCX = L_frameTCX;
    1176      891395 :     *pL_frame = L_frame;
    1177      891395 :     *pL_spec = L_spec;
    1178      891395 :     *ptcx_offset = tcx_offset;
    1179             : 
    1180             :     /* target bitrate for SQ */
    1181      891395 :     sqTargetBits = nb_bits - NBITS_TCX_GAIN - NBITS_NOISE_FILL_LEVEL;
    1182             : 
    1183      891395 :     if ( st->enablePlcWaveadjust )
    1184             :     {
    1185           0 :         st->Tonal_SideInfo = DecideTonalSideInfo( x_orig, ( st->core == TCX_20_CORE ) ? st->L_frame : st->L_frame / 2, st->hTcxCfg->SFM2 );
    1186             :     }
    1187             : 
    1188             :     /* Start with the pre-shaped spectrum*/
    1189      891395 :     mvr2r( x_orig, spectrum, L_spec );
    1190             : 
    1191             :     /*-----------------------------------------------------------*
    1192             :      * Bandwidth Limitation                                      *
    1193             :      *-----------------------------------------------------------*/
    1194             : 
    1195      891395 :     noiseFillingBorder = L_spec;
    1196      891395 :     if ( st->igf )
    1197             :     {
    1198      611995 :         noiseFillingBorder = st->hIGFEnc->infoStartLine;
    1199             :     }
    1200      891395 :     *pnoiseFillingBorder = noiseFillingBorder;
    1201             : 
    1202      891395 :     if ( st->igf )
    1203             :     {
    1204    91785435 :         for ( i = st->hIGFEnc->infoStopLine; i < max( L_frame, L_frameTCX ); i++ )
    1205             :         {
    1206    91173440 :             spectrum[i] = 0.0f;
    1207             :         }
    1208             :     }
    1209             :     else
    1210             :     {
    1211    15957000 :         for ( i = noiseFillingBorder; i < max( L_frame, L_frameTCX ); i++ )
    1212             :         {
    1213    15677600 :             spectrum[i] = 0.0f;
    1214             :         }
    1215             :     }
    1216             : 
    1217             :     /*-----------------------------------------------------------*
    1218             :      * Quantization                                              *
    1219             :      *-----------------------------------------------------------*/
    1220             : 
    1221      891395 :     if ( !hTcxEnc->tcx_lpc_shaped_ari )
    1222             :     {
    1223             :         /* context based arithmetic coder */
    1224             : 
    1225             :         /* initialize signaling to default, i.e. context based AC is inactive */
    1226      873938 :         prm_hm[0] = 0;
    1227      873938 :         prm_hm[1] = -1;
    1228             : 
    1229             :         /* Fast estimation of the scalar quantizer step size */
    1230      873938 :         if ( st->hTcxCfg->ctx_hm && st->last_core != ACELP_CORE )
    1231             :         {
    1232      180775 :             LtpPitchLag = ( ( !st->tcxonly ) && ( hTcxEnc->tcxltp_pitch_int < st->L_frame ) ? ( ( 2 * st->L_frame * st->pit_res_max ) << kLtpHmFractionalResolution ) / ( hTcxEnc->tcxltp_pitch_int * st->pit_res_max + hTcxEnc->tcxltp_pitch_fr ) : -1 );
    1233             : 
    1234      180775 :             ++ctxHmBits;    /* ContextHM flag */
    1235      180775 :             --sqTargetBits; /* ContextHM flag */
    1236             : 
    1237      180775 :             PeriodicityIndex = SearchPeriodicityIndex( spectrum, NULL, L_spec, sqTargetBits, LtpPitchLag, hTcxEnc->tcxltp ? hTcxEnc->tcxltp_gain : -1.0f, &RelativeScore );
    1238             : 
    1239      180775 :             NumIndexBits = CountIndexBits( L_spec >= 256, PeriodicityIndex );
    1240             : 
    1241      180775 :             if ( st->element_mode > EVS_MONO )
    1242             :             {
    1243      180167 :                 ConfigureContextHm( L_spec, sqTargetBits - NumIndexBits, PeriodicityIndex, LtpPitchLag, hm_cfg );
    1244             :             }
    1245             :             else
    1246             :             {
    1247         608 :                 ConfigureContextHm( L_spec, sqTargetBits, PeriodicityIndex, LtpPitchLag, hm_cfg );
    1248             :             }
    1249             : 
    1250             :             /* Quantize original spectrum */
    1251      180775 :             sqGain = SQ_gain( spectrum, (int16_t) ( hTcxEnc->tcx_target_bits_fac * (float) sqTargetBits ), L_spec );
    1252             : 
    1253      180775 :             tcx_scalar_quantization( spectrum, sqQ, L_spec, sqGain, st->hTcxCfg->sq_rounding, hTcxEnc->memQuantZeros, st->tcxonly );
    1254             : 
    1255             :             /* Estimate original bitrate */
    1256      180775 :             stop = 0;
    1257      180775 :             if ( st->element_mode > EVS_MONO )
    1258             :             {
    1259      180167 :                 sqBits = RCcontextMapping_encode2_estimate_no_mem_s17_LCS( sqQ, L_spec, &lastnz, &nEncoded, sqTargetBits, &stop, 0, NULL );
    1260             :             }
    1261             :             else
    1262             :             {
    1263         608 :                 sqBits = ACcontextMapping_encode2_estimate_no_mem_s17_LC( sqQ, L_spec, &lastnz, &nEncoded, sqTargetBits, &stop, NULL );
    1264             :             }
    1265             : 
    1266             :             /* Estimate context mapped bitrate */
    1267      180775 :             stopCtxHm = 0;
    1268             : 
    1269             :             /* Context Mapping */
    1270      180775 :             if ( st->element_mode > EVS_MONO )
    1271             :             {
    1272      180167 :                 sqBitsCtxHm = RCcontextMapping_encode2_estimate_no_mem_s17_LCS( sqQ, L_spec, &lastnzCtxHm, &nEncodedCtxHm, sqTargetBits - NumIndexBits, &stopCtxHm, 0, hm_cfg );
    1273             :             }
    1274             :             else
    1275             :             {
    1276         608 :                 sqBitsCtxHm = ACcontextMapping_encode2_estimate_no_mem_s17_LC( sqQ, L_spec, &lastnzCtxHm, &nEncodedCtxHm, sqTargetBits - NumIndexBits, &stopCtxHm, hm_cfg );
    1277             :             }
    1278             : 
    1279             :             /* Decide whether or not to use context mapping */
    1280      180775 :             Selector = max( stop, sqBits ) - ( max( stopCtxHm, sqBitsCtxHm ) + NumIndexBits );
    1281             : 
    1282      180775 :             if ( Selector > 2 || ( abs( Selector ) <= 2 && kCtxHmOlRSThr < RelativeScore ) )
    1283             :             {
    1284             :                 /* CtxHm is likely better */
    1285       12775 :                 sqTargetBits -= NumIndexBits;
    1286       12775 :                 ctxHmBits += NumIndexBits;
    1287       12775 :                 prm_hm[0] = 1;
    1288       12775 :                 prm_hm[1] = PeriodicityIndex;
    1289       12775 :                 *prm_lastnz = lastnzCtxHm;
    1290       12775 :                 sqBits_noStop = sqBits = sqBitsCtxHm;
    1291       12775 :                 nEncoded = nEncodedCtxHm;
    1292       12775 :                 stop = stopCtxHm;
    1293             :             }
    1294             :             else
    1295             :             {
    1296             :                 /* Original is better or not much difference */
    1297      168000 :                 prm_hm[0] = 0;
    1298      168000 :                 prm_hm[1] = PeriodicityIndex;
    1299      168000 :                 *prm_lastnz = lastnz;
    1300      168000 :                 PeriodicityIndex = -1;
    1301             : 
    1302      168000 :                 sqBits_noStop = sqBits;
    1303             :             }
    1304             : 
    1305      180775 :             if ( stop != 0 )
    1306             :             {
    1307       66293 :                 sqBits = stop;
    1308             :             }
    1309             :         }
    1310             :         else
    1311             :         {
    1312             :             /* no context hm*/
    1313      693163 :             PeriodicityIndex = -1;
    1314             : 
    1315      693163 :             if ( st->element_mode == IVAS_CPE_MDCT )
    1316             :             {
    1317      653460 :                 sqGain = SQ_gain_estimate( spectrum, (int16_t) ( hTcxEnc->tcx_target_bits_fac * (float) sqTargetBits ), L_spec );
    1318             :             }
    1319             :             else
    1320             :             {
    1321       39703 :                 sqGain = SQ_gain( spectrum, (int16_t) ( hTcxEnc->tcx_target_bits_fac * (float) sqTargetBits ), L_spec );
    1322             :             }
    1323             : 
    1324             :             /* Quantize spectrum */
    1325      693163 :             tcx_scalar_quantization( spectrum, sqQ, L_spec, sqGain, st->hTcxCfg->sq_rounding, hTcxEnc->memQuantZeros, st->tcxonly );
    1326             : 
    1327             :             /* Estimate bitrate */
    1328      693163 :             stop = 0;
    1329      693163 :             if ( st->element_mode > EVS_MONO )
    1330             :             {
    1331      693125 :                 sqBits_noStop = sqBits = RCcontextMapping_encode2_estimate_no_mem_s17_LCS( sqQ, L_spec, prm_lastnz, &nEncoded, sqTargetBits, &stop, 0, NULL );
    1332             :             }
    1333             :             else
    1334             :             {
    1335          38 :                 sqBits_noStop = sqBits = ACcontextMapping_encode2_estimate_no_mem_s17_LC( sqQ, L_spec, prm_lastnz, &nEncoded, sqTargetBits, &stop, NULL );
    1336             :             }
    1337             : 
    1338      693163 :             if ( stop != 0 )
    1339             :             {
    1340      361084 :                 sqBits = stop;
    1341             :             }
    1342             :         } /* end of if (ctx_hm) */
    1343             : 
    1344             :         /* Adjust correction factor */
    1345      873938 :         if ( ( L_spec & ( L_spec - 1 ) ) == 0 )
    1346             :         {
    1347             :             /* power-of-2 */
    1348           0 :             hTcxEnc->tcx_target_bits_fac *= (float) sqTargetBits / (float) ( sqBits + 1 );
    1349             :         }
    1350             :         else
    1351             :         {
    1352      873938 :             hTcxEnc->tcx_target_bits_fac *= (float) sqTargetBits / (float) sqBits;
    1353             :         }
    1354             : 
    1355      873938 :         if ( hTcxEnc->tcx_target_bits_fac > 1.25 )
    1356             :         {
    1357       88117 :             hTcxEnc->tcx_target_bits_fac = 1.25;
    1358             :         }
    1359      873938 :         if ( hTcxEnc->tcx_target_bits_fac < 0.75 )
    1360             :         {
    1361       56721 :             hTcxEnc->tcx_target_bits_fac = 0.75;
    1362             :         }
    1363             : 
    1364             :         /* Refine quantizer step size with a rate-control-loop (optional) */
    1365      873938 :         sqBits = tcx_scalar_quantization_rateloop( spectrum, sqQ, L_spec, &sqGain, st->hTcxCfg->sq_rounding, hTcxEnc->memQuantZeros, prm_lastnz, /* lastnz */ sqTargetBits, &nEncoded, &stop, sqBits_noStop, sqBits, st->hTcxCfg->tcxRateLoopOpt, st->tcxonly, PeriodicityIndex >= 0 ? hm_cfg : NULL, ( st->element_mode == IVAS_CPE_MDCT ? 2 : 4 ), st->element_mode );
    1366             : 
    1367      873938 :         if ( ctxHmBits > 0 )
    1368             :         {
    1369             :             /* Mapping tool is enabled */
    1370             :             /* Truncate spectrum */
    1371      426314 :             for ( i = nEncoded; i < L_spec; i++ )
    1372             :             {
    1373      424194 :                 if ( st->element_mode > EVS_MONO )
    1374             :                 {
    1375      178655 :                     break;
    1376             :                 }
    1377             :                 else
    1378             :                 {
    1379      245539 :                     sqQ[i] = 0;
    1380             :                 }
    1381             :             }
    1382             : 
    1383      180775 :             if ( PeriodicityIndex >= 0 )
    1384             :             {
    1385             :                 /* Mapping is used */
    1386             :                 /* Estimate non-mapped bitrate */
    1387       12775 :                 stopCtxHm = 1;
    1388       12775 :                 if ( st->element_mode > EVS_MONO )
    1389             :                 {
    1390             :                     /* Fix: Use updated value for target bits (sqTargetBits + NumIndexBits) before computing non-mapped estimate */
    1391       12727 :                     sqBitsCtxHm = RCcontextMapping_encode2_estimate_no_mem_s17_LCS( sqQ, L_spec, &lastnz, &nEncodedCtxHm, sqTargetBits + NumIndexBits, &stopCtxHm, 0, NULL );
    1392             :                 }
    1393             :                 else
    1394             :                 {
    1395          48 :                     sqBitsCtxHm = ACcontextMapping_encode2_estimate_no_mem_s17_LC( sqQ, L_spec, &lastnz, &nEncodedCtxHm, sqTargetBits, &stopCtxHm, NULL );
    1396             :                 }
    1397             : 
    1398             :                 /* Decide whether or not to revert mapping */
    1399       12775 :                 Selector = sqBits - ( sqBitsCtxHm + NumIndexBits );
    1400             : 
    1401       12775 :                 if ( st->element_mode > EVS_MONO )
    1402             :                 {
    1403       12727 :                     if ( ( stopCtxHm == 0 && Selector > 0 ) || stop ) /* If overflow occured with mapped, select non-mapped */
    1404             :                     {
    1405             :                         /* Non-mapped is better */
    1406         647 :                         sqTargetBits += NumIndexBits;
    1407         647 :                         ctxHmBits -= NumIndexBits;
    1408         647 :                         prm_hm[0] = 0;
    1409         647 :                         *prm_lastnz = lastnz;
    1410         647 :                         PeriodicityIndex = -1;
    1411         647 :                         sqBits_noStop = sqBits = sqBitsCtxHm;
    1412         647 :                         nEncoded = nEncodedCtxHm;
    1413         647 :                         stop = stopCtxHm;
    1414             :                     }
    1415             :                 }
    1416             :                 else
    1417             :                 {
    1418          48 :                     if ( stopCtxHm == 0 && Selector > 0 )
    1419             :                     {
    1420             :                         /* Non-mapped is better */
    1421           0 :                         sqTargetBits += NumIndexBits;
    1422           0 :                         ctxHmBits -= NumIndexBits;
    1423           0 :                         prm_hm[0] = 0;
    1424           0 :                         *prm_lastnz = lastnz;
    1425           0 :                         PeriodicityIndex = -1;
    1426           0 :                         sqBits_noStop = sqBits = sqBitsCtxHm;
    1427           0 :                         nEncoded = nEncodedCtxHm;
    1428           0 :                         stop = stopCtxHm;
    1429             :                     }
    1430             :                 }
    1431             :             }
    1432             :             else
    1433             :             {
    1434             :                 /* Mapping is not used */
    1435      168000 :                 if ( st->element_mode > EVS_MONO )
    1436             :                 {
    1437             :                     /* Truncate Spectrum */
    1438    86860590 :                     for ( i = nEncoded; i < L_spec; i++ )
    1439             :                     {
    1440    86693150 :                         sqQ[i] = 0;
    1441             :                     }
    1442             :                 }
    1443             :                 /* Estimate mapped bitrate */
    1444      168000 :                 stopCtxHm = 1;
    1445      168000 :                 if ( st->element_mode > EVS_MONO )
    1446             :                 {
    1447      167440 :                     sqBitsCtxHm = RCcontextMapping_encode2_estimate_no_mem_s17_LCS( sqQ, L_spec, &lastnzCtxHm, &nEncodedCtxHm, sqTargetBits - NumIndexBits, &stopCtxHm, 0, hm_cfg );
    1448             :                 }
    1449             :                 else
    1450             :                 {
    1451         560 :                     sqBitsCtxHm = ACcontextMapping_encode2_estimate_no_mem_s17_LC( sqQ, L_spec, &lastnzCtxHm, &nEncodedCtxHm, sqTargetBits - NumIndexBits, &stopCtxHm, hm_cfg );
    1452             :                 }
    1453             : 
    1454             :                 /* Decide whether or not to use mapping */
    1455      168000 :                 Selector = sqBits - ( sqBitsCtxHm + NumIndexBits );
    1456             : 
    1457      168000 :                 if ( stopCtxHm == 0 && Selector > 0 )
    1458             :                 {
    1459             :                     /* Mapped is better */
    1460         814 :                     sqTargetBits -= NumIndexBits;
    1461         814 :                     ctxHmBits += NumIndexBits;
    1462         814 :                     prm_hm[0] = 1;
    1463         814 :                     *prm_lastnz = lastnzCtxHm;
    1464         814 :                     PeriodicityIndex = prm_hm[1];
    1465         814 :                     sqBits_noStop = sqBits = sqBitsCtxHm;
    1466         814 :                     nEncoded = nEncodedCtxHm;
    1467         814 :                     stop = stopCtxHm;
    1468             :                 }
    1469             :             }
    1470             :         }
    1471             : 
    1472             :         /* Limit low sqGain for avoiding saturation of the gain quantizer*/
    1473      873938 :         if ( st->hTcxCfg->tcxRateLoopOpt < 3 && sqGain < sqrt( (float) NORM_MDCT_FACTOR / (float) L_spec ) )
    1474             :         {
    1475        5981 :             sqGain = (float) sqrt( (float) NORM_MDCT_FACTOR / (float) L_spec );
    1476             : 
    1477        5981 :             tcx_scalar_quantization( spectrum, sqQ, L_spec, sqGain, st->hTcxCfg->sq_rounding, hTcxEnc->memQuantZeros, st->tcxonly );
    1478             : 
    1479        5981 :             stop = 1;
    1480        5981 :             if ( st->element_mode > EVS_MONO )
    1481             :             {
    1482             :                 /* Ensure non-mapped estimation is used for limiting low sqGain considering that this refinement occurs very rarely */
    1483        5981 :                 PeriodicityIndex = -1;
    1484        5981 :                 if ( prm_hm[0] == 1 )
    1485             :                 {
    1486           0 :                     prm_hm[0] = 0;
    1487           0 :                     sqTargetBits += NumIndexBits;
    1488           0 :                     ctxHmBits -= NumIndexBits;
    1489             :                 }
    1490        5981 :                 sqBits = RCcontextMapping_encode2_estimate_no_mem_s17_LCS( sqQ, L_spec, prm_lastnz, &nEncoded, sqTargetBits, &stop, 0, NULL );
    1491             :             }
    1492             :             else
    1493             :             {
    1494           0 :                 sqBits = ACcontextMapping_encode2_estimate_no_mem_s17_LC( sqQ, L_spec, prm_lastnz, &nEncoded, sqTargetBits, &stop, PeriodicityIndex >= 0 ? hm_cfg : NULL );
    1495             :             }
    1496             :         }
    1497             : 
    1498             :         /* Truncate spectrum (for CBR) */
    1499      873938 :         if ( stop )
    1500             :         {
    1501    66060807 :             for ( i = nEncoded; i < L_spec; i++ )
    1502             :             {
    1503    65933388 :                 sqQ[i] = 0;
    1504             :             }
    1505             :         }
    1506             : 
    1507             :         /* Save quantized Values */
    1508      873938 :         *nf_seed = 0;
    1509   709704098 :         for ( i = 0; i < L_spec; i++ )
    1510             :         {
    1511   708830160 :             spectrum[i] = (float) sqQ[i];
    1512             :             /* noise filling seed */
    1513   708830160 :             *nf_seed += (int16_t) ( abs( sqQ[i] ) * i * 2 );
    1514             :         }
    1515             :     }
    1516             :     else
    1517             :     {
    1518             :         /* low rates: envelope based arithmetic coder */
    1519             : 
    1520       17457 :         AdaptLowFreqEmph( spectrum, NULL, 0.f, 1, gainlpc, L_frame );
    1521             : 
    1522       17457 :         prm_target = sqQ;
    1523       17457 :         sqQ = prm_target + 1;
    1524             : 
    1525       17457 :         LtpPitchLag = ( ( hTcxEnc->tcxltp_pitch_int < st->L_frame ) ? ( ( 2 * st->L_frame * st->pit_res_max ) << kLtpHmFractionalResolution ) / ( st->hTcxEnc->tcxltp_pitch_int * st->pit_res_max + hTcxEnc->tcxltp_pitch_fr ) : -1 );
    1526             : 
    1527       17457 :         tcx_arith_encode_envelope( spectrum, hm_cfg->indexBuffer, L_frame, L_spec, st, Aqind, sqTargetBits, sqQ, st->last_core != ACELP_CORE, prm_hm, /* HM parameter area */ LtpPitchLag, &sqBits, &signaling_bits, ( st->bwidth > WB ) ? 1 : 0 );
    1528             : 
    1529       17457 :         sqTargetBits -= signaling_bits;
    1530       17457 :         *prm_target = sqTargetBits;
    1531             : 
    1532             :         /* Noise filling seed */
    1533       17457 :         *nf_seed = 0;
    1534     3654029 :         for ( i = 0; i < noiseFillingBorder; ++i )
    1535             :         {
    1536     3636572 :             *nf_seed += (int16_t) ( abs( (int16_t) spectrum[i] ) * i * 2 );
    1537             :         }
    1538             :     }
    1539             : 
    1540      891395 :     *hm_active = prm_hm[0];
    1541             : 
    1542             :     /*-----------------------------------------------------------*
    1543             :      * Compute optimal TCX gain.                                 *
    1544             :      *-----------------------------------------------------------*/
    1545             : 
    1546      891395 :     if ( lf_deemph_fact != NULL )
    1547             :     {
    1548             :         /* initialize LF deemphasis factors in lf_deemph_fact */
    1549   198906335 :         for ( i = 0; i < L_spec; i++ )
    1550             :         {
    1551   198668400 :             lf_deemph_fact[i] = 1.0f;
    1552             :         }
    1553             :     }
    1554             : 
    1555      891395 :     if ( !st->tcxonly )
    1556             :     {
    1557      128960 :         AdaptLowFreqDeemph( spectrum, hTcxEnc->tcx_lpc_shaped_ari, gainlpc, L_frame, lf_deemph_fact );
    1558             :     }
    1559             : 
    1560      891395 :     assert( x_orig != spectrum );
    1561      891395 :     gain_tcx_opt = get_gain( x_orig, spectrum, L_spec, ener );
    1562             : 
    1563      891395 :     if ( gain_tcx_opt <= 0.0f )
    1564             :     {
    1565        2689 :         gain_tcx_opt = sqGain;
    1566             :     }
    1567      891395 :     *gain_tcx = gain_tcx_opt;
    1568             : 
    1569      891395 :     if ( st->element_mode == IVAS_CPE_DFT || st->element_mode == IVAS_CPE_TD )
    1570             :     {
    1571       14475 :         calculate_hangover_attenuation_gain( st, &att, vad_hover_flag );
    1572       14475 :         *gain_tcx *= att;
    1573             :     }
    1574             : 
    1575             :     /*-----------------------------------------------------------*
    1576             :      * Quantize TCX gain                                         *
    1577             :      *-----------------------------------------------------------*/
    1578             : 
    1579             :     /*  gain quantization here in case of VBR unvoiced coding; fixes problems of uninitialized global gain values */
    1580      891395 :     if ( total_brate >= ACELP_13k20 && !st->rf_mode )
    1581             :     {
    1582      858266 :         tcx_QuantizeGain( L_spec, gain_tcx, &prm[0] );
    1583             :     }
    1584             : 
    1585             :     /*-----------------------------------------------------------*
    1586             :      * Residual Quantization                                     *
    1587             :      *-----------------------------------------------------------*/
    1588             : 
    1589      891395 :     if ( st->hTcxCfg->resq )
    1590             :     {
    1591      393200 :         resQTargetBits = sqTargetBits - sqBits;
    1592             : 
    1593      393200 :         if ( hTcxEnc->tcx_lpc_shaped_ari )
    1594             :         {
    1595             :             /* envelope based arithmetic coder */
    1596             :             int16_t *prm_resq;
    1597             : 
    1598       17457 :             prm_resq = sqQ + sqTargetBits - resQTargetBits;
    1599             : 
    1600       17457 :             resQBits = tcx_ari_res_Q_spec( x_orig, hm_cfg->indexBuffer, spectrum, L_spec, *gain_tcx, prm_resq, resQTargetBits, resQBits, st->hTcxCfg->sq_rounding, lf_deemph_fact );
    1601             : 
    1602             :             /* Transmit zeros when there bits remain after RESQ */
    1603       18647 :             for ( i = resQBits; i < resQTargetBits; ++i )
    1604             :             {
    1605        1190 :                 prm_resq[i] = 0;
    1606             :             }
    1607             :         }
    1608             :         else
    1609             :         {
    1610             :             /* context based arithmetic coder */
    1611      375743 :             resQBits = tcx_res_Q_gain( gain_tcx_opt, gain_tcx, sqQ + L_spec, resQTargetBits );
    1612             : 
    1613      375743 :             resQBits = tcx_res_Q_spec( x_orig, spectrum, L_spec, *gain_tcx, sqQ + L_spec, resQTargetBits, resQBits, st->hTcxCfg->sq_rounding, st->tcxonly ? NULL : lf_deemph_fact );
    1614             :         }
    1615             :     }
    1616             : 
    1617             :     /*-----------------------------------------------------------*
    1618             :      * ALFE tcx only bitrates                                    *
    1619             :      *-----------------------------------------------------------*/
    1620             : 
    1621      891395 :     if ( st->element_mode != IVAS_CPE_MDCT )
    1622             :     {
    1623      237935 :         if ( st->tcxonly )
    1624             :         {
    1625      108975 :             if ( hTcxEnc->tcxltp && ( hTcxEnc->tcxltp_gain > 0.0f ) && !hTcxEnc->fUseTns[frame_cnt] )
    1626             :             {
    1627        3732 :                 PsychAdaptLowFreqDeemph( spectrum, gainlpc, NULL );
    1628             :             }
    1629             :         }
    1630             :     }
    1631             : 
    1632             : #ifdef DEBUGGING
    1633             :     /*-----------------------------------------------------------*
    1634             :      * TCX SNR for Analysis purposes                             *
    1635             :      *-----------------------------------------------------------*/
    1636             :     {
    1637             :         float diff[N_MAX];
    1638             :         char name[50] = "TCX_output_chX  ";
    1639             : 
    1640             :         for ( i = 0; i < min( L_frame, L_spec ); i++ )
    1641             :         {
    1642             :             diff[i] = x_orig[i] - *gain_tcx * spectrum[i];
    1643             :         }
    1644             : 
    1645             :         if ( st->id_element == 0 )
    1646             :         {
    1647             :             name[13] = (char) ( st->idchan + '0' );
    1648             :         }
    1649             :         else
    1650             :         {
    1651             :             char name2[50] = "TCX_output.idX_chX  ";
    1652             :             name2[13] = (char) ( st->id_element + '0' );
    1653             :             name2[17] = (char) ( st->idchan + '0' );
    1654             :             strcpy( name, name2 );
    1655             :         }
    1656             : 
    1657             :         snr( x_orig, diff, min( L_frame, L_spec ), name );
    1658             :     }
    1659             : #endif
    1660             : 
    1661      891395 :     return;
    1662             : }
    1663             : 
    1664             : 
    1665             : /*-------------------------------------------------------------------*
    1666             :  * InternalTCXDecoder()
    1667             :  *
    1668             :  *
    1669             :  *-------------------------------------------------------------------*/
    1670             : 
    1671      237935 : void InternalTCXDecoder(
    1672             :     Encoder_State *st,                /* i/o: state handle                            */
    1673             :     const int16_t frame_cnt,          /* i  : frame counter in the super_frame        */
    1674             :     const int16_t L_frameTCX,         /* i  : full frame length                       */
    1675             :     const int16_t L_frame,            /* i  : frame length                            */
    1676             :     const int16_t L_spec,             /* i  : length of the coded spectrum            */
    1677             :     const int16_t tcx_offset,         /* i  : folding point offset relative to the end of the previous frame */
    1678             :     const int16_t noiseFillingBorder, /* i  : noise filling border                    */
    1679             :     const float *x_quant,             /* i  : quantized spectrum                      */
    1680             :     const float ener,                 /* i  : energy of the quantized spectrum        */
    1681             :     float lf_deemph_fact[],           /* i/o: low frequency deemphasis factors        */
    1682             :     const float fac_ns,               /* i  : noise filling level                     */
    1683             :     const int16_t nf_seed,            /* i  : noise filling random seed               */
    1684             :     const float *A,                   /* i  : LPC representation of the FDNS gains    */
    1685             :     float *gainlpc,                   /* i/o: FDNS gains                              */
    1686             :     const int16_t hm_active,          /* i  : flag indicating if the harmonic model is active */
    1687             :     float gain_tcx,                   /* i/o: global gain / quantized global gain             */
    1688             :     float spectrum[],                 /* o  : dequantized spectrum                    */
    1689             :     float synth[],                    /* o  : time domain signal                      */
    1690             :     int16_t *gain_tcx_q               /* o  : quantized global gain (at low bitrates) */
    1691             : )
    1692             : {
    1693      237935 :     TCX_ENC_HANDLE hTcxEnc = st->hTcxEnc;
    1694             :     int16_t i, iStart, noiseTransWidth;
    1695             :     int16_t tcx_last_overlap_mode, overlap;
    1696             :     int16_t nz;   /* non-zero length in ALDO window*/
    1697             :     int16_t aldo; /* ALDO flag in current frame*/
    1698             :     float xn_buf[L_MDCT_OVLP_MAX + L_FRAME_PLUS + L_MDCT_OVLP_MAX];
    1699             :     float Aq_old[M + 1];
    1700             :     float sns_interpolated_scalefactors[FDNS_NPTS];
    1701             : 
    1702      237935 :     mvr2r( x_quant, spectrum, max( L_frame, L_spec ) );
    1703             : 
    1704             :     /* Replication of ACELP formant enhancement for low rates */
    1705      237935 :     if ( st->total_brate < ACELP_13k20 || st->rf_mode )
    1706             :     {
    1707       33129 :         tcxFormantEnhancement( lf_deemph_fact, gainlpc, spectrum, L_frame );
    1708             :     }
    1709             : 
    1710             :     /*-----------------------------------------------------------*
    1711             :      * Noise Filling.                                            *
    1712             :      *-----------------------------------------------------------*/
    1713             : 
    1714      237935 :     if ( fac_ns > 0.0f )
    1715             :     {
    1716      219324 :         iStart = tcxGetNoiseFillingTilt( A, L_frame, ( st->total_brate >= ACELP_13k20 && !st->rf_mode ), &hTcxEnc->noiseTiltFactor );
    1717             : 
    1718      219324 :         noiseTransWidth = GetTransWidth( st->tcxonly, ( L_frame == st->L_frame >> 1 ), hTcxEnc->tcxltp_gain, ( st->hTcxCfg->ctx_hm && st->last_core != ACELP_CORE && hm_active ) );
    1719      219324 :         assert( st->element_mode != IVAS_CPE_MDCT );
    1720      219324 :         tcx_noise_filling( spectrum, nf_seed, iStart, noiseFillingBorder, noiseTransWidth, L_frame, hTcxEnc->noiseTiltFactor, fac_ns, NULL, st->element_mode );
    1721             :     }
    1722             : 
    1723      237935 :     if ( st->total_brate < ACELP_13k20 || st->rf_mode )
    1724             :     {
    1725             :         /* partially recompute global gain (energy part), taking noise filling and formant enhancement into account */
    1726       33129 :         float ener_nf = 1e-6f;
    1727    21344489 :         for ( i = 0; i < L_spec; i++ )
    1728             :         {
    1729    21311360 :             ener_nf += spectrum[i] * spectrum[i];
    1730             :         }
    1731       33129 :         gain_tcx *= (float) sqrt( ener / ener_nf );
    1732       33129 :         tcx_QuantizeGain( L_spec, &gain_tcx, gain_tcx_q );
    1733             :     }
    1734             : 
    1735             :     /*end of noise filling*/
    1736             : 
    1737             :     /*-----------------------------------------------------------*
    1738             :      * Noise shaping in frequency domain (1/Wz)                  *
    1739             :      *-----------------------------------------------------------*/
    1740             : 
    1741      237935 :     if ( st->element_mode == IVAS_CPE_MDCT )
    1742             :     {
    1743           0 :         sns_interpolate_scalefactors( sns_interpolated_scalefactors, A, DEC );
    1744           0 :         sns_shape_spectrum( spectrum, st->hTcxCfg->psychParamsCurrent, sns_interpolated_scalefactors, L_frame );
    1745             :     }
    1746             :     else
    1747             :     {
    1748      237935 :         mdct_noiseShaping( spectrum, L_frame, gainlpc, FDNS_NPTS );
    1749             :     }
    1750             : 
    1751             :     /*-----------------------------------------------------------*
    1752             :      * Apply gain                                                *
    1753             :      *-----------------------------------------------------------*/
    1754             : 
    1755      237935 :     if ( st->hTcxCfg->coder_type == INACTIVE )
    1756             :     {
    1757             : 
    1758       13536 :         gain_tcx *= st->hTcxCfg->na_scale;
    1759             :     }
    1760             : 
    1761      237935 :     v_multc( spectrum, gain_tcx, spectrum, L_spec );
    1762             : 
    1763      237935 :     tcx_last_overlap_mode = st->hTcxCfg->tcx_last_overlap_mode; /* backup last TCX overlap mode */
    1764             : 
    1765      237935 :     if ( ( L_frame == st->L_frame >> 1 ) && st->tcxonly )
    1766             :     {
    1767        4154 :         int16_t L = L_frame;
    1768             : 
    1769        4154 :         if ( ( st->hTcxCfg->fIsTNSAllowed && hTcxEnc->fUseTns[frame_cnt] != 0 ) || ( L_spec > L_frame ) )
    1770             :         {
    1771        4052 :             L = L_spec;
    1772             :         }
    1773             : 
    1774        4154 :         tcxInvertWindowGrouping( st->hTcxCfg, xn_buf, spectrum, L, hTcxEnc->fUseTns[frame_cnt], st->last_core, tcx_last_overlap_mode, frame_cnt, 0 );
    1775             :     }
    1776             : 
    1777             :     /*-----------------------------------------------------------*
    1778             :      * Temporal Noise Shaping Synthesis                          *
    1779             :      *-----------------------------------------------------------*/
    1780             : 
    1781      237935 :     if ( st->hTcxCfg->fIsTNSAllowed )
    1782             :     {
    1783      161953 :         SetTnsConfig( st->hTcxCfg, st->core == TCX_20_CORE, ( st->last_core == ACELP_CORE ) && ( frame_cnt == 0 ) );
    1784             : 
    1785             :         /* Apply TNS to get the reconstructed signal */
    1786      161953 :         if ( hTcxEnc->fUseTns[frame_cnt] != 0 )
    1787             :         {
    1788       17665 :             ApplyTnsFilter( st->hTcxCfg->pCurrentTnsConfig, &hTcxEnc->tnsData[frame_cnt], spectrum, 0 );
    1789             : 
    1790       17665 :             if ( ( L_frame == st->L_frame >> 1 ) && ( st->tcxonly ) )
    1791             :             {
    1792        2400 :                 if ( ( st->hTcxCfg->tcx_last_overlap_mode != FULL_OVERLAP ) ||
    1793        1185 :                      ( ( st->hTcxCfg->tcx_curr_overlap_mode == FULL_OVERLAP ) && ( frame_cnt == 0 ) && ( tcx_last_overlap_mode == 0 ) ) )
    1794             :                 {
    1795        1749 :                     const int16_t L_win = L_spec >> 1;
    1796             : 
    1797             :                     /* undo rearrangement of LF sub-window lines for TNS synthesis filter */
    1798        1749 :                     if ( L_frame > L_spec )
    1799             :                     {
    1800           0 :                         assert( 0 );
    1801             :                     }
    1802             :                     else
    1803             :                     {
    1804        1749 :                         mvr2r( spectrum + 8, xn_buf, L_win );
    1805        1749 :                         mvr2r( xn_buf, spectrum + L_win, 8 );
    1806        1749 :                         mvr2r( xn_buf + 8, spectrum + 8, L_win - 8 );
    1807             :                     }
    1808             :                 }
    1809             :             }
    1810             :         }
    1811             :     }
    1812             : 
    1813             :     /*-----------------------------------------------------------*
    1814             :      * Compute inverse MDCT of spectrum[].                        *
    1815             :      *-----------------------------------------------------------*/
    1816             : 
    1817      237935 :     lsp2a_stab( st->lsp_old, Aq_old, M );
    1818      237935 :     overlap = st->hTcxCfg->tcx_mdct_window_length;
    1819      237935 :     nz = NS2SA( st->sr_core, N_ZERO_MDCT_NS );
    1820      237935 :     aldo = 0;
    1821             : 
    1822      237935 :     if ( ( L_frame == st->L_frame >> 1 ) && ( st->tcxonly ) )
    1823             :     {
    1824        4154 :         if ( st->hTcxCfg->tcx_last_overlap_mode != FULL_OVERLAP )
    1825             :         {
    1826             :             /* minimum or half overlap, two transforms, grouping into one window */
    1827             :             float win[( L_FRAME_PLUS + L_MDCT_OVLP_MAX ) / 2];
    1828        1633 :             const int16_t L_win = L_frame >> 1;
    1829        1633 :             const int16_t L_spec_TCX5 = max( L_frame, L_spec ) >> 1;
    1830        1633 :             const int16_t L_ola = ( st->hTcxCfg->tcx_last_overlap_mode == MIN_OVERLAP ) ? st->hTcxCfg->tcx_mdct_window_min_length : st->hTcxCfg->tcx_mdct_window_half_length;
    1831             :             int16_t w;
    1832             : 
    1833        1633 :             set_f( win, 0, ( L_FRAME_PLUS + L_MDCT_OVLP_MAX ) / 2 );
    1834        1633 :             set_zero( xn_buf, tcx_offset + ( L_ola >> 1 ) ); /* zero left end of buffer */
    1835             : 
    1836        4899 :             for ( w = 0; w < 2; w++ )
    1837             :             {
    1838        3266 :                 if ( st->hTcxCfg->tcx_last_overlap_mode == MIN_OVERLAP )
    1839             :                 {
    1840        1540 :                     TCX_MDCT_Inverse( spectrum + w * L_spec_TCX5, win, L_ola, L_win - L_ola, L_ola, st->element_mode );
    1841             :                 }
    1842             :                 else
    1843             :                 {
    1844        1726 :                     TCX_MDCT_Inverse( spectrum + w * L_spec_TCX5, win, L_ola, L_win - L_ola, L_ola, st->element_mode );
    1845             :                 }
    1846             : 
    1847        3266 :                 tcx_windowing_synthesis_current_frame( win, st->hTcxCfg->tcx_aldo_window_2, st->hTcxCfg->tcx_mdct_window_half, st->hTcxCfg->tcx_mdct_window_minimum, L_ola, st->hTcxCfg->tcx_mdct_window_half_length, st->hTcxCfg->tcx_mdct_window_min_length, w == 0 && st->last_core == ACELP_CORE, ( w > 0 ) || ( w == 0 && tcx_last_overlap_mode == 2 ) ? MIN_OVERLAP : st->hTcxCfg->tcx_last_overlap_mode, st->hTcxEnc->acelp_zir, st->hTcxEnc->Txnq, NULL, Aq_old, st->hTcxCfg->tcx_mdct_window_trans, L_win, tcx_offset < 0 ? -tcx_offset : 0, ( w > 0 ) ? 1 : st->last_core, 0, 0 );
    1848             : 
    1849        3266 :                 if ( w > 0 )
    1850             :                 {
    1851        1633 :                     tcx_windowing_synthesis_past_frame( xn_buf + tcx_offset - ( L_ola >> 1 ) + w * L_win, st->hTcxCfg->tcx_aldo_window_1_trunc, st->hTcxCfg->tcx_mdct_window_half, st->hTcxCfg->tcx_mdct_window_minimum, L_ola, st->hTcxCfg->tcx_mdct_window_half_length, st->hTcxCfg->tcx_mdct_window_min_length, 2 );
    1852             :                 }
    1853             : 
    1854             :                 /* add part of current sub-window overlapping with previous window */
    1855        3266 :                 v_add( win, xn_buf + tcx_offset - ( L_ola >> 1 ) + w * L_win, xn_buf + tcx_offset - ( L_ola >> 1 ) + w * L_win, L_ola );
    1856             : 
    1857             :                 /* copy new sub-window region not overlapping with previous window */
    1858        3266 :                 mvr2r( win + L_ola, xn_buf + tcx_offset + ( L_ola >> 1 ) + w * L_win, L_win );
    1859             :             }
    1860             : 
    1861             :             /* To assure that no garbage values are copied to Txnq */
    1862        1633 :             set_zero( xn_buf + L_frame + tcx_offset + ( L_ola >> 1 ), overlap - tcx_offset - ( L_ola >> 1 ) );
    1863             :         }
    1864        2521 :         else if ( ( frame_cnt == 0 ) && ( st->hTcxCfg->tcx_curr_overlap_mode == FULL_OVERLAP ) )
    1865         598 :         {
    1866             :             /* special overlap attempt, two transforms, grouping into one window */
    1867             :             float win[( L_FRAME_PLUS + L_MDCT_OVLP_MAX ) / 2];
    1868         598 :             const int16_t L_win = L_frame >> 1;
    1869         598 :             const int16_t L_spec_TCX5 = max( L_frame, L_spec ) >> 1;
    1870         598 :             const int16_t L_ola = st->hTcxCfg->tcx_mdct_window_min_length;
    1871             :             int16_t w;
    1872             : 
    1873         598 :             set_f( win, 0, ( L_FRAME_PLUS + L_MDCT_OVLP_MAX ) / 2 );
    1874             : 
    1875             :             /* Resize overlap (affect only asymmetric window)*/
    1876         598 :             overlap = st->hTcxCfg->tcx_mdct_window_delay;
    1877             : 
    1878             :             /* 1st TCX-5 window, special MDCT with minimum overlap on right side */
    1879         598 :             TCX_MDCT_Inverse( spectrum, win + L_win, 0, L_win - ( L_ola >> 1 ), L_ola, st->element_mode );
    1880             : 
    1881             :             /* copy new sub-window region not overlapping with previous window */
    1882         598 :             mvr2r( win + L_win, xn_buf + ( overlap >> 1 ), L_win + ( L_ola >> 1 ) );
    1883             : 
    1884             :             /* 2nd TCX-5 window, regular MDCT with minimum overlap on both sides */
    1885         598 :             TCX_MDCT_Inverse( spectrum + L_spec_TCX5, win, L_ola, L_win - L_ola, L_ola, st->element_mode );
    1886             : 
    1887         598 :             tcx_windowing_synthesis_current_frame( win, st->hTcxCfg->tcx_aldo_window_2, st->hTcxCfg->tcx_mdct_window_half, st->hTcxCfg->tcx_mdct_window_minimum, L_ola, st->hTcxCfg->tcx_mdct_window_half_length, st->hTcxCfg->tcx_mdct_window_min_length, 0, /* left_rect */
    1888         598 :                                                    2, /* left_mode */ st->hTcxEnc->acelp_zir, st->hTcxEnc->Txnq, NULL, Aq_old, st->hTcxCfg->tcx_mdct_window_trans, L_win, tcx_offset < 0 ? -tcx_offset : 0, 1, /* not st->last_core */ 0, 0 );
    1889             : 
    1890         598 :             tcx_windowing_synthesis_past_frame( xn_buf + ( overlap >> 1 ) + L_win - ( L_ola >> 1 ), st->hTcxCfg->tcx_aldo_window_1_trunc, st->hTcxCfg->tcx_mdct_window_half, st->hTcxCfg->tcx_mdct_window_minimum, L_ola, st->hTcxCfg->tcx_mdct_window_half_length, st->hTcxCfg->tcx_mdct_window_min_length, 2 );
    1891             : 
    1892             :             /* add part of current sub-window overlapping with previous window */
    1893         598 :             v_add( win, xn_buf + ( overlap >> 1 ) + L_win - ( L_ola >> 1 ), xn_buf + ( overlap >> 1 ) + L_win - ( L_ola >> 1 ), L_ola );
    1894             : 
    1895             :             /* copy new sub-window region not overlapping with previous window */
    1896         598 :             mvr2r( win + L_ola, xn_buf + ( overlap >> 1 ) + L_win + ( L_ola >> 1 ), L_win );
    1897             : 
    1898             :             /* extra folding-out on left side of win, for perfect reconstruction */
    1899       83898 :             for ( w = ( overlap >> 1 ); w < overlap; w++ )
    1900             :             {
    1901       83300 :                 xn_buf[overlap - 1 - w] = -1.0f * xn_buf[w];
    1902             :             }
    1903             : 
    1904         598 :             tcx_windowing_synthesis_current_frame( xn_buf, st->hTcxCfg->tcx_aldo_window_2, st->hTcxCfg->tcx_mdct_window_half, st->hTcxCfg->tcx_mdct_window_minimum, overlap, /*st->hTcxCfg->tcx_mdct_window_length*/ st->hTcxCfg->tcx_mdct_window_half_length, st->hTcxCfg->tcx_mdct_window_min_length, st->last_core == ACELP_CORE, 0, /* left_mode */ st->hTcxEnc->acelp_zir, st->hTcxEnc->Txnq, NULL, Aq_old, st->hTcxCfg->tcx_mdct_window_trans, L_win, tcx_offset < 0 ? -tcx_offset : 0, st->last_core, 0, 0 );
    1905             :         }
    1906             :         else
    1907             :         {
    1908             :             /* default, i.e. maximum overlap, single transform, no grouping */
    1909        1923 :             TCX_MDCT_Inverse( spectrum, xn_buf, overlap, L_frame - overlap, overlap, st->element_mode );
    1910             : 
    1911        1923 :             tcx_windowing_synthesis_current_frame( xn_buf, st->hTcxCfg->tcx_aldo_window_2, st->hTcxCfg->tcx_mdct_window_half, st->hTcxCfg->tcx_mdct_window_minimum, overlap, /*st->hTcxCfg->tcx_mdct_window_length*/ st->hTcxCfg->tcx_mdct_window_half_length, st->hTcxCfg->tcx_mdct_window_min_length, st->last_core == ACELP_CORE, ( frame_cnt > 0 ) && ( tcx_last_overlap_mode == 0 ) && ( st->last_core != ACELP_CORE ) ? 2 : tcx_last_overlap_mode, st->hTcxEnc->acelp_zir, st->hTcxEnc->Txnq, NULL, Aq_old, st->hTcxCfg->tcx_mdct_window_trans, st->L_frame >> 2, tcx_offset < 0 ? -tcx_offset : 0, st->last_core, 0, 0 );
    1912             : 
    1913             :         } /* tcx_last_overlap_mode != FULL_OVERLAP */
    1914             :     }
    1915             :     else
    1916             :     {
    1917             :         /* frame is TCX-20 or not TCX-only */
    1918      233781 :         if ( st->hTcxCfg->tcx_last_overlap_mode != TRANSITION_OVERLAP )
    1919             :         {
    1920             :             float tmp[L_FRAME_PLUS];
    1921             : 
    1922      225793 :             edct( spectrum, xn_buf + overlap / 2 + nz, L_frame, st->element_mode );
    1923             : 
    1924      225793 :             v_multc( xn_buf + overlap / 2 + nz, (float) sqrt( (float) L_frame / NORM_MDCT_FACTOR ), tmp, L_frame );
    1925             : 
    1926      225793 :             window_ola( tmp, xn_buf, st->hTcxEnc->old_out, L_frame, st->hTcxCfg->tcx_last_overlap_mode, st->hTcxCfg->tcx_curr_overlap_mode, 0, 0, NULL );
    1927      225793 :             aldo = 1;
    1928             :         }
    1929             :         else
    1930             :         {
    1931        7988 :             TCX_MDCT_Inverse( spectrum, xn_buf, overlap, L_frame - overlap, overlap, st->element_mode );
    1932             : 
    1933             :             /* Windowing, overlap and add */
    1934             :             /* Window current frame */
    1935        7988 :             tcx_windowing_synthesis_current_frame( xn_buf, st->hTcxCfg->tcx_aldo_window_2, st->hTcxCfg->tcx_mdct_window_half, st->hTcxCfg->tcx_mdct_window_minimum, overlap, /*st->hTcxCfg->tcx_mdct_window_length*/ st->hTcxCfg->tcx_mdct_window_half_length, st->hTcxCfg->tcx_mdct_window_min_length, st->last_core == ACELP_CORE, st->hTcxCfg->tcx_last_overlap_mode, /*left mode*/ st->hTcxEnc->acelp_zir, st->hTcxEnc->Txnq, NULL, Aq_old, st->hTcxCfg->tcx_mdct_window_trans, st->L_frame >> 1, tcx_offset < 0 ? -tcx_offset : 0, st->last_core, 0, 0 );
    1936             :         }
    1937             :     } /* TCX-20/TCX-10 and TCX-only */
    1938             : 
    1939             :     /* Window and overlap-add past frame if past frame is TCX */
    1940      237935 :     if ( st->last_core > ACELP_CORE && ( ( ( L_frameTCX == hTcxEnc->L_frameTCX >> 1 ) && ( st->tcxonly ) ) || ( st->hTcxCfg->tcx_last_overlap_mode == TRANSITION_OVERLAP ) ) )
    1941             :     {
    1942        4154 :         if ( st->hTcxCfg->last_aldo )
    1943             :         {
    1944      462004 :             for ( i = 0; i < overlap - st->hTcxCfg->tcx_mdct_window_min_length; i++ )
    1945             :             {
    1946      460080 :                 xn_buf[i] += st->hTcxEnc->old_out[i + nz];
    1947             :             }
    1948             :             /* fade truncated ALDO window */
    1949       78604 :             for ( ; i < overlap; i++ )
    1950             :             {
    1951       76680 :                 xn_buf[i] += st->hTcxEnc->old_out[i + nz] * st->hTcxCfg->tcx_mdct_window_minimum[overlap - 1 - i];
    1952             :             }
    1953             :         }
    1954             :         else
    1955             :         {
    1956        2230 :             if ( frame_cnt > 0 && tcx_last_overlap_mode == 0 && st->hTcxCfg->tcx_curr_overlap_mode == FULL_OVERLAP && st->last_core != ACELP_CORE )
    1957             :             {
    1958         598 :                 tcx_last_overlap_mode = 2; /* use minimum overlap between the two TCX-10 windows */
    1959             :             }
    1960             : 
    1961        2230 :             tcx_windowing_synthesis_past_frame( st->hTcxEnc->Txnq, st->hTcxCfg->tcx_aldo_window_1_trunc, st->hTcxCfg->tcx_mdct_window_half, st->hTcxCfg->tcx_mdct_window_minimum, overlap, st->hTcxCfg->tcx_mdct_window_half_length, st->hTcxCfg->tcx_mdct_window_min_length, ( tcx_last_overlap_mode == 0 || st->hTcxCfg->tcx_last_overlap_mode == MIN_OVERLAP ) ? st->hTcxCfg->tcx_last_overlap_mode : tcx_last_overlap_mode );
    1962             : 
    1963      624670 :             for ( i = 0; i < overlap; i++ )
    1964             :             {
    1965      622440 :                 xn_buf[i] += st->hTcxEnc->Txnq[i];
    1966             :             }
    1967             :         }
    1968             :     }
    1969             : 
    1970      237935 :     if ( !aldo && ( ( ( L_frameTCX == hTcxEnc->L_frameTCX >> 1 ) && frame_cnt > 0 ) || L_frameTCX != ( hTcxEnc->L_frameTCX >> 1 ) ) )
    1971             :     {
    1972             :         /*Compute windowed synthesis in case of switching to ALDO windows in next frame*/
    1973       10065 :         mvr2r( xn_buf + L_frame - nz, st->hTcxEnc->old_out, nz + overlap );
    1974       10065 :         set_zero( st->hTcxEnc->old_out + nz + overlap, nz );
    1975             : 
    1976       10065 :         tcx_windowing_synthesis_past_frame( st->hTcxEnc->old_out + nz, st->hTcxCfg->tcx_aldo_window_1_trunc, st->hTcxCfg->tcx_mdct_window_half, st->hTcxCfg->tcx_mdct_window_minimum, overlap, st->hTcxCfg->tcx_mdct_window_half_length, st->hTcxCfg->tcx_mdct_window_min_length, st->hTcxCfg->tcx_curr_overlap_mode );
    1977             : 
    1978       10065 :         if ( st->hTcxCfg->tcx_curr_overlap_mode == FULL_OVERLAP )
    1979             :         {
    1980      867677 :             for ( i = 0; i < nz; i++ )
    1981             :             {
    1982      858708 :                 st->hTcxEnc->old_out[nz + overlap + i] = xn_buf[L_frame - 1 - i] * st->hTcxCfg->tcx_aldo_window_1_trunc[-1 - i];
    1983             :             }
    1984             :         }
    1985             :     }
    1986             : 
    1987      237935 :     st->hTcxCfg->last_aldo = aldo;
    1988             : 
    1989             :     /* Update Txnq */
    1990      237935 :     if ( !st->hTcxCfg->last_aldo )
    1991             :     {
    1992       12142 :         mvr2r( xn_buf + L_frame, st->hTcxEnc->Txnq, overlap );
    1993             :     }
    1994             : 
    1995             :     /* Output */
    1996      237935 :     mvr2r( xn_buf + ( overlap >> 1 ) - tcx_offset, synth, ( st->core == TCX_20_CORE ) ? st->L_frame : L_frame );
    1997             : 
    1998      237935 :     return;
    1999             : }
    2000             : 
    2001             : /*-------------------------------------------------------------------*
    2002             :  * QuantizeSpectrum()
    2003             :  *
    2004             :  *
    2005             :  *-------------------------------------------------------------------*/
    2006             : 
    2007      237935 : void QuantizeSpectrum(
    2008             :     Encoder_State *st,           /* i/o: encoder state structure                         */
    2009             :     const float A[],             /* i  : quantized coefficients NxAz_q[M+1]              */
    2010             :     const Word16 Aqind[],        /* i  : frame-independent quantized coefficients (M+1)  */
    2011             :     float gainlpc[],             /* i  : MDCT gains of the previous frame                */
    2012             :     float synth[],               /* o  : synthesis buffer                                */
    2013             :     const int16_t nb_bits,       /* i  : bit budget                                      */
    2014             :     const int16_t tnsSize,       /* i  : number of tns parameters put into prm           */
    2015             :     int16_t prm[],               /* o  : tcx parameters                                  */
    2016             :     const int16_t frame_cnt,     /* i  : frame counter in the super_frame                */
    2017             :     CONTEXT_HM_CONFIG *hm_cfg,   /* i  : HM configuration                             */
    2018             :     const int16_t vad_hover_flag /* i  : VAD hangover flag                            */
    2019             : )
    2020             : {
    2021             :     int16_t L_frameTCX;                                                     /* full frame length */
    2022             :     int16_t L_frame;                                                        /* frame length */
    2023             :     int16_t L_spec;                                                         /* length of the coded spectrum */
    2024             :     int16_t tcx_offset;                                                     /* folding point offset relative to the end of the previous frame */
    2025             :     int16_t noiseFillingBorder;                                             /* noise filling border */
    2026             :     float quantized_spectrum[N_MAX];                                        /* quantized MDCT spectrum */
    2027             :     float lf_deemph_fact[L_MDCT_OVLP_MAX + L_FRAME_PLUS + L_MDCT_OVLP_MAX]; /* low frequency deemphasis factors */
    2028             :     int16_t hm_active;                                                      /* flag indicating if the harmonic model is active */
    2029             :     float fac_ns;                                                           /* noise filling level */
    2030             :     int16_t nf_seed;                                                        /* noise filling random seed */
    2031             :     float ener;                                                             /* energy of the quantized spectrum */
    2032             :     float gain_tcx;                                                         /* global gain */
    2033      237935 :     TCX_ENC_HANDLE hTcxEnc = st->hTcxEnc;
    2034             : 
    2035             :     /*-----------------------------------------------------------*
    2036             :      * Quantize the MDCT spectrum                                *
    2037             :      *-----------------------------------------------------------*/
    2038             : 
    2039      237935 :     QuantizeTCXSpectrum( st, frame_cnt, hTcxEnc->spectrum[frame_cnt], gainlpc, Aqind, tnsSize, nb_bits, vad_hover_flag,
    2040             :                          &L_frameTCX, &L_frame, &L_spec, &tcx_offset, &noiseFillingBorder, quantized_spectrum, hm_cfg, &hm_active, lf_deemph_fact, &nf_seed, &ener, &gain_tcx, prm );
    2041             : 
    2042             :     /*-----------------------------------------------------------*
    2043             :      * Estimate and quantize noise factor                        *
    2044             :      *-----------------------------------------------------------*/
    2045             : 
    2046      237935 :     EstimateTCXNoiseLevel( st, hTcxEnc->spectrum[frame_cnt], quantized_spectrum, gain_tcx, L_frame, noiseFillingBorder, hm_active, &fac_ns, &prm[1] );
    2047             : 
    2048             :     /*-----------------------------------------------------------*
    2049             :      * Internal decoder                                          *
    2050             :      *-----------------------------------------------------------*/
    2051             : 
    2052      237935 :     InternalTCXDecoder( st, frame_cnt, L_frameTCX, L_frame, L_spec, tcx_offset, noiseFillingBorder, quantized_spectrum, ener, lf_deemph_fact, fac_ns, nf_seed, A, gainlpc, hm_active, gain_tcx, hTcxEnc->spectrum[frame_cnt], synth, &prm[0] );
    2053             : 
    2054             :     /* Update L_frame_past */
    2055      237935 :     st->L_frame_past = L_frame;
    2056             : 
    2057             :     /* Update overlap */
    2058      237935 :     if ( ( ( ( L_frameTCX == hTcxEnc->L_frameTCX >> 1 ) && frame_cnt > 0 ) || ( st->hTcxCfg->tcx_last_overlap_mode == TRANSITION_OVERLAP ) ) && ( st->hTcxCfg->tcx_curr_overlap_mode == FULL_OVERLAP ) )
    2059             :     {
    2060        8969 :         st->hTcxCfg->tcx_curr_overlap_mode = ALDO_WINDOW;
    2061             :     }
    2062             : 
    2063             : 
    2064      237935 :     return;
    2065             : }
    2066             : 
    2067             : 
    2068             : /*-------------------------------------------------------------------*
    2069             :  * coder_tcx()
    2070             :  *
    2071             :  *
    2072             :  *-------------------------------------------------------------------*/
    2073             : 
    2074         646 : void coder_tcx(
    2075             :     Encoder_State *st,          /* i/o: encoder state structure             */
    2076             :     TCX_CONFIG_HANDLE hTcxCfg,  /* i  : configuration of TCX                */
    2077             :     const float A[],            /* i  : quantized coefficients NxAz_q[M+1]  */
    2078             :     const Word16 Aqind[],       /* i  : frame-independent quantized coefficients (M+1) */
    2079             :     float synth[],              /* o  : decoded synthesis                   */
    2080             :     const int16_t L_frame_glob, /* i  : frame length                        */
    2081             :     const int16_t L_frameTCX_glob,
    2082             :     const int16_t L_spec,
    2083             :     int16_t nb_bits,  /* i  : bit budget                          */
    2084             :     float spectrum[], /* i/o: MDCT spectrum                       */
    2085             :     int16_t prm[],    /* o  : tcx parameters                      */
    2086             :     CONTEXT_HM_CONFIG *hm_cfg,
    2087             :     const int16_t vad_hover_flag /* i  : VAD hangover flag */
    2088             : )
    2089             : {
    2090             :     int16_t L_frame;
    2091         646 :     int16_t left_overlap = -1, right_overlap = -1;
    2092         646 :     int16_t tnsSize = 0; /* number of tns parameters put into prm */
    2093         646 :     int16_t tnsBits = 0; /* number of tns bits in the frame */
    2094         646 :     int16_t ltpBits = 0;
    2095             :     float gainlpc[FDNS_NPTS];
    2096             :     float buf[N_MAX + L_MDCT_OVLP_MAX];
    2097             :     float winMDST[N_MAX + L_MDCT_OVLP_MAX];
    2098             :     float *win;
    2099             :     float *powerSpec;
    2100         646 :     TCX_ENC_HANDLE hTcxEnc = st->hTcxEnc;
    2101             : 
    2102         646 :     powerSpec = win = buf; /* Share memory for windowed TD signal and for the power spectrum */
    2103             : 
    2104         646 :     L_frame = L_frameTCX_glob;
    2105             : 
    2106             :     /*-----------------------------------------------------------*
    2107             :      * Windowing and MDCT                                        *
    2108             :      *-----------------------------------------------------------*/
    2109             : 
    2110         646 :     if ( st->hTcxCfg->tcx_last_overlap_mode == TRANSITION_OVERLAP )
    2111             :     {
    2112          38 :         WindowSignal( hTcxCfg, hTcxCfg->tcx_offsetFB, hTcxCfg->tcx_last_overlap_mode, hTcxCfg->tcx_curr_overlap_mode, &left_overlap, &right_overlap, st->hTcxEnc->speech_TCX, &L_frame, win, 1, 1 );
    2113             : 
    2114             :         /* Compute MDCT for xn_buf[] */
    2115          38 :         TCX_MDCT( win, spectrum, left_overlap, L_frame - ( left_overlap + right_overlap ) / 2, right_overlap, st->element_mode );
    2116             :     }
    2117             :     else
    2118             :     {
    2119         608 :         wtda( st->hTcxEnc->new_speech_TCX, win, NULL, hTcxCfg->tcx_last_overlap_mode, hTcxCfg->tcx_curr_overlap_mode, L_frame );
    2120             : 
    2121         608 :         WindowSignal( hTcxCfg, hTcxCfg->tcx_offsetFB, hTcxCfg->tcx_last_overlap_mode == ALDO_WINDOW ? FULL_OVERLAP : hTcxCfg->tcx_last_overlap_mode, hTcxCfg->tcx_curr_overlap_mode == ALDO_WINDOW ? FULL_OVERLAP : hTcxCfg->tcx_curr_overlap_mode, &left_overlap, &right_overlap, st->hTcxEnc->speech_TCX, &L_frame, winMDST, 1, 1 );
    2122             : 
    2123         608 :         edct( win, spectrum, L_frame, st->element_mode );
    2124             : 
    2125         608 :         v_multc( spectrum, (float) sqrt( (float) NORM_MDCT_FACTOR / L_frame ), spectrum, L_frame );
    2126             :     }
    2127             : 
    2128             :     /*-----------------------------------------------------------*
    2129             :      * Attenuate upper end of NB spectrum,                       *
    2130             :      * to simulate ACELP behavior                                *
    2131             :      *-----------------------------------------------------------*/
    2132             : 
    2133         646 :     if ( st->narrowBand )
    2134             :     {
    2135           0 :         attenuateNbSpectrum( L_frame, spectrum );
    2136             :     }
    2137             : 
    2138             :     /*-----------------------------------------------------------*
    2139             :      * Compute noise-measure flags for spectrum filling          *
    2140             :      * and quantization (0: tonal, 1: noise-like).               *
    2141             :      * Detect low pass if present.                               *
    2142             :      *-----------------------------------------------------------*/
    2143             : 
    2144         646 :     AnalyzePowerSpectrum( st, L_frame * st->L_frame / hTcxEnc->L_frameTCX, L_frame, left_overlap, right_overlap, spectrum, ( st->hTcxCfg->tcx_last_overlap_mode == TRANSITION_OVERLAP ) ? win : winMDST, powerSpec );
    2145             : 
    2146         646 :     if ( hTcxCfg->fIsTNSAllowed )
    2147             :     {
    2148         371 :         SetTnsConfig( hTcxCfg, L_frame_glob == st->L_frame, st->last_core == ACELP_CORE );
    2149             : 
    2150         371 :         TNSAnalysis( hTcxCfg, L_frame, L_spec, TCX_20, st->last_core == ACELP_CORE, spectrum, NULL, -1, hTcxEnc->tnsData, hTcxEnc->fUseTns, &st->hIGFEnc->tns_predictionGain );
    2151             :     }
    2152             :     else
    2153             :     {
    2154         275 :         hTcxEnc->fUseTns[0] = hTcxEnc->fUseTns[1] = 0;
    2155             :     }
    2156             : 
    2157         646 :     if ( st->igf )
    2158             :     {
    2159         646 :         ProcessIGF( st, spectrum, spectrum, powerSpec, 1, 0, 0, vad_hover_flag );
    2160             :     }
    2161             : 
    2162         646 :     ShapeSpectrum( hTcxCfg, A, gainlpc, L_frame_glob, L_spec, spectrum, hTcxEnc->fUseTns[0], st, NULL );
    2163             : 
    2164         646 :     if ( st->igf )
    2165             :     {
    2166         646 :         nb_bits -= st->hIGFEnc->infoTotalBitsPerFrameWritten;
    2167             :     }
    2168             : 
    2169         646 :     if ( hTcxCfg->fIsTNSAllowed )
    2170             :     {
    2171         371 :         EncodeTnsData( hTcxCfg->pCurrentTnsConfig, hTcxEnc->tnsData, prm + 1 + NOISE_FILL_RANGES + LTPSIZE, &tnsSize, &tnsBits );
    2172             :     }
    2173             : 
    2174         646 :     QuantizeSpectrum( st, A, Aqind, gainlpc, synth, nb_bits - tnsBits - ltpBits, tnsSize, prm, 0, hm_cfg, vad_hover_flag );
    2175             : 
    2176         646 :     return;
    2177             : }
    2178             : 
    2179             : /*-------------------------------------------------------------------*
    2180             :  * coder_tcx_post()
    2181             :  *
    2182             :  *
    2183             :  *-------------------------------------------------------------------*/
    2184             : 
    2185      235858 : void coder_tcx_post(
    2186             :     Encoder_State *st, /* i/o: encoder memory state                        */
    2187             :     float *A,          /* o  : Quantized LPC coefficients                  */
    2188             :     const float *Ai    /* i  : Unquantized (interpolated) LPC coefficients */
    2189             : )
    2190             : {
    2191             :     float xn_buf[L_FRAME_MAX];
    2192             : 
    2193             :     /* TCX output */
    2194      235858 :     mvr2r( st->synth, xn_buf, st->L_frame );
    2195             : 
    2196             :     /*-----------------------------------------------------------*
    2197             :      * Memory update                                             *
    2198             :      *-----------------------------------------------------------*/
    2199             : 
    2200             :     /* Update LPDmem (Txnq,syn,syn_pe,old_exc,wsyn,Ai,Aq) */
    2201      235858 :     tcx_encoder_memory_update( st, xn_buf, Ai, A );
    2202             : 
    2203      235858 :     return;
    2204             : }

Generated by: LCOV version 1.14