LCOV - code coverage report
Current view: top level - lib_dec - tonalMDCTconcealment.c (source / functions) Hit Total Coverage
Test: Coverage on main -- merged total coverage @ 9b04ec3cb36f5e8dc438cf854fa3e349998fa1e9 Lines: 441 447 98.7 %
Date: 2025-10-31 05:45:46 Functions: 14 14 100.0 %

          Line data    Source code
       1             : /******************************************************************************************************
       2             : 
       3             :    (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB,
       4             :    Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
       5             :    Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
       6             :    Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
       7             :    contributors to this repository. All Rights Reserved.
       8             : 
       9             :    This software is protected by copyright law and by international treaties.
      10             :    The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB,
      11             :    Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
      12             :    Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
      13             :    Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
      14             :    contributors to this repository retain full ownership rights in their respective contributions in
      15             :    the software. This notice grants no license of any kind, including but not limited to patent
      16             :    license, nor is any license granted by implication, estoppel or otherwise.
      17             : 
      18             :    Contributors are required to enter into the IVAS codec Public Collaboration agreement before making
      19             :    contributions.
      20             : 
      21             :    This software is provided "AS IS", without any express or implied warranties. The software is in the
      22             :    development stage. It is intended exclusively for experts who have experience with such software and
      23             :    solely for the purpose of inspection. All implied warranties of non-infringement, merchantability
      24             :    and fitness for a particular purpose are hereby disclaimed and excluded.
      25             : 
      26             :    Any dispute, controversy or claim arising under or in relation to providing this software shall be
      27             :    submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in
      28             :    accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and
      29             :    the United Nations Convention on Contracts on the International Sales of Goods.
      30             : 
      31             : *******************************************************************************************************/
      32             : 
      33             : /*====================================================================================
      34             :     EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0
      35             :   ====================================================================================*/
      36             : 
      37             : #define _USE_MATH_DEFINES
      38             : 
      39             : #include <assert.h>
      40             : #include <stdint.h>
      41             : #include "options.h"
      42             : #ifdef DEBUGGING
      43             : #include "debug.h"
      44             : #endif
      45             : #include <math.h>
      46             : #include "prot.h"
      47             : #include "ivas_prot.h"
      48             : #include "wmc_auto.h"
      49             : 
      50             : 
      51             : /*******************************************************/
      52             : /*-------------- public functions -------------------- */
      53             : /*******************************************************/
      54             : 
      55     1244037 : ivas_error TonalMDCTConceal_Init(
      56             :     TonalMDCTConcealPtr hTonalMDCTConc,
      57             :     const uint16_t nSamples,
      58             :     const uint16_t nSamplesCore,
      59             :     const uint16_t nScaleFactors,
      60             :     TCX_CONFIG_HANDLE hTcxCfg )
      61             : {
      62     1244037 :     if ( nSamples > L_FRAME_MAX || nScaleFactors > FDNS_NPTS )
      63             :     {
      64           0 :         assert( nSamples <= L_FRAME_MAX );
      65           0 :         assert( nScaleFactors <= FDNS_NPTS );
      66           0 :         return ( IVAS_ERROR( IVAS_ERR_INTERNAL, "TonalMDCT FEC: Number of samples larger than max. block size\n" ) );
      67             :     }
      68     1244037 :     assert( ( hTonalMDCTConc->nScaleFactors == nScaleFactors ) || ( hTonalMDCTConc->nSamples != nSamples ) ); /* If nSamples doesn't change then also nScaleFactors must stay the same */
      69             : 
      70     1244037 :     hTonalMDCTConc->tcx_cfg = hTcxCfg;
      71     1244037 :     hTonalMDCTConc->lastBlockData.spectralData = hTonalMDCTConc->spectralDataBuffers[0];
      72     1244037 :     hTonalMDCTConc->secondLastBlockData.spectralData = hTonalMDCTConc->spectralDataBuffers[1];
      73     1244037 :     hTonalMDCTConc->secondLastPowerSpectrum = hTonalMDCTConc->secondLastBlockData.spectralData;
      74     1244037 :     hTonalMDCTConc->lastBlockData.scaleFactors = hTonalMDCTConc->scaleFactorsBuffers[0];
      75     1244037 :     hTonalMDCTConc->secondLastBlockData.scaleFactors = hTonalMDCTConc->scaleFactorsBuffers[1];
      76     1244037 :     hTonalMDCTConc->lastBlockData.blockIsValid = 0;
      77     1244037 :     hTonalMDCTConc->secondLastBlockData.blockIsValid = 0;
      78     1244037 :     hTonalMDCTConc->nSamples = 0;
      79     1244037 :     hTonalMDCTConc->nScaleFactors = 0;
      80             : 
      81     1244037 :     hTonalMDCTConc->lastBlockData.blockIsConcealed = 0;
      82     1244037 :     hTonalMDCTConc->secondLastBlockData.blockIsConcealed = 0;
      83     1244037 :     hTonalMDCTConc->pTCI = (TonalComponentsInfo *) hTonalMDCTConc->timeDataBuffer;
      84             : 
      85     1244037 :     hTonalMDCTConc->lastPitchLag = 0;
      86             : 
      87     1244037 :     if ( hTonalMDCTConc->nSamples != nSamples )
      88             :     {
      89     1244037 :         hTonalMDCTConc->secondLastBlockData.blockIsValid = 0;
      90     1244037 :         hTonalMDCTConc->lastBlockData.blockIsValid = 0;
      91             :     }
      92     1244037 :     hTonalMDCTConc->nSamples = nSamples;
      93     1244037 :     hTonalMDCTConc->nSamplesCore = nSamplesCore;
      94     1244037 :     hTonalMDCTConc->nScaleFactors = nScaleFactors;
      95             : 
      96     1244037 :     set_zero( hTonalMDCTConc->scaleFactorsBackground, FDNS_NPTS );
      97     1244037 :     hTonalMDCTConc->scf_fadeout = 1.0f;
      98     1244037 :     PsychoacousticParameters_Init( INT_FS_16k, L_FRAME16k, 64, 1, 1, &hTonalMDCTConc->psychParamsTCX20 );
      99     1244037 :     PsychoacousticParameters_Init( INT_FS_16k, L_FRAME16k / 2, 64, 0, 1, &hTonalMDCTConc->psychParamsTCX10 );
     100     1244037 :     hTonalMDCTConc->psychParams = NULL;
     101             : 
     102     1244037 :     hTonalMDCTConc->last_block_nrg = 0.0f;
     103     1244037 :     hTonalMDCTConc->curr_noise_nrg = 0.0f;
     104     1244037 :     hTonalMDCTConc->faded_signal_nrg = 0.0f;
     105             : 
     106             :     /* Offset the pointer to the end of buffer, so that pTCI is not destroyed when
     107             :        new time samples are stored in lastPcmOut */
     108             :     /* just the second half of the second last pcm output is needed */
     109     1244037 :     hTonalMDCTConc->secondLastPcmOut = &hTonalMDCTConc->timeDataBuffer[( 3 * L_FRAME_MAX ) / 2 - ( 3 * min( L_FRAME_MAX, nSamples ) ) / 2];
     110     1244037 :     hTonalMDCTConc->lastPcmOut = &hTonalMDCTConc->timeDataBuffer[( 3 * L_FRAME_MAX ) / 2 - min( L_FRAME_MAX, nSamples )];
     111             : 
     112             :     /* If the second last frame was lost and concealed with tonal PLC, we
     113             :        reuse saved TonalComponentsInfo and don't update pcm buffers */
     114     1244037 :     assert( sizeof( *hTonalMDCTConc->pTCI ) <= ( hTonalMDCTConc->lastPcmOut - hTonalMDCTConc->timeDataBuffer ) * sizeof( hTonalMDCTConc->timeDataBuffer[0] ) );
     115             : 
     116     1244037 :     return IVAS_ERR_OK;
     117             : }
     118             : 
     119             : 
     120    47740195 : void TonalMDCTConceal_SaveFreqSignal(
     121             :     TonalMDCTConcealPtr hTonalMDCTConc,
     122             :     const float *mdctSpectrum,
     123             :     const uint16_t nNewSamples,
     124             :     const uint16_t nNewSamplesCore,
     125             :     const float *scaleFactors,
     126             :     const int16_t infoIGFStartLine )
     127             : {
     128             :     float *temp;
     129             :     uint16_t nOldSamples;
     130             : 
     131    47740195 :     assert( nNewSamples > 0 && nNewSamples <= 2 * L_FRAME_MAX );
     132             : 
     133             :     /* Avoid overwriting hTonalMDCTConc->secondLastPowerSpectrum stored in spectralData,
     134             :        because it is needed if the second last and the current frame are lost
     135             :        and concealed using the Tonal MDCT PLC */
     136    47740195 :     if ( !hTonalMDCTConc->lastBlockData.tonalConcealmentActive || ( hTonalMDCTConc->lastBlockData.nSamples != nNewSamples ) )
     137             :     {
     138    47682015 :         if ( nNewSamples <= L_FRAME_MAX )
     139             :         {
     140             :             /* Shift the buffers */
     141    47434750 :             temp = hTonalMDCTConc->secondLastBlockData.spectralData; /* Save the pointer */
     142    47434750 :             hTonalMDCTConc->secondLastBlockData.spectralData = hTonalMDCTConc->lastBlockData.spectralData;
     143    47434750 :             hTonalMDCTConc->lastBlockData.spectralData = temp;
     144    47434750 :             temp = hTonalMDCTConc->secondLastBlockData.scaleFactors;
     145    47434750 :             hTonalMDCTConc->secondLastBlockData.scaleFactors = hTonalMDCTConc->lastBlockData.scaleFactors;
     146    47434750 :             hTonalMDCTConc->lastBlockData.scaleFactors = temp;
     147             :         }
     148             :         else
     149             :         {
     150             :             /* Order the buffers so that even transition frame can fit in if written into the first buffer */
     151      247265 :             hTonalMDCTConc->lastBlockData.spectralData = hTonalMDCTConc->spectralDataBuffers[0];
     152      247265 :             hTonalMDCTConc->secondLastBlockData.spectralData = hTonalMDCTConc->spectralDataBuffers[1];
     153      247265 :             hTonalMDCTConc->lastBlockData.scaleFactors = hTonalMDCTConc->scaleFactorsBuffers[0];
     154      247265 :             hTonalMDCTConc->secondLastBlockData.scaleFactors = hTonalMDCTConc->scaleFactorsBuffers[1];
     155             :         }
     156    47682015 :         nOldSamples = hTonalMDCTConc->lastBlockData.nSamples;
     157    47682015 :         hTonalMDCTConc->lastBlockData.nSamples = nNewSamples;
     158    47682015 :         hTonalMDCTConc->secondLastBlockData.nSamples = nOldSamples;
     159    47682015 :         nOldSamples = hTonalMDCTConc->lastBlockData.nSamplesCore;
     160    47682015 :         hTonalMDCTConc->lastBlockData.nSamplesCore = nNewSamplesCore;
     161    47682015 :         hTonalMDCTConc->secondLastBlockData.nSamplesCore = nOldSamples;
     162             :     }
     163             : 
     164    47740195 :     if ( ( nNewSamples > 0 ) && ( nNewSamples <= 2 * L_FRAME_MAX ) )
     165             :     {
     166             :         /* Store new data */
     167             :         int16_t i;
     168             : 
     169    47740195 :         hTonalMDCTConc->last_block_nrg = 0.0f;
     170 21912033151 :         for ( i = 0; i < infoIGFStartLine; i++ )
     171             :         {
     172 21864292956 :             hTonalMDCTConc->lastBlockData.spectralData[i] = mdctSpectrum[i];
     173 21864292956 :             hTonalMDCTConc->last_block_nrg += mdctSpectrum[i] * mdctSpectrum[i];
     174             :         }
     175 15854106959 :         for ( ; i < nNewSamples; i++ )
     176             :         {
     177 15806366764 :             hTonalMDCTConc->lastBlockData.spectralData[i] = mdctSpectrum[i];
     178             :         }
     179             : 
     180    47740195 :         mvr2r( scaleFactors, hTonalMDCTConc->lastBlockData.scaleFactors, hTonalMDCTConc->nScaleFactors );
     181             :     }
     182             : 
     183    47740195 :     return;
     184             : }
     185             : 
     186             : 
     187    55244255 : void TonalMDCTConceal_UpdateState(
     188             :     TonalMDCTConcealPtr hTonalMDCTConc,
     189             :     const int16_t nNewSamples,
     190             :     const float pitchLag,
     191             :     const int16_t badBlock,
     192             :     const int16_t tonalConcealmentActive )
     193             : {
     194             :     int16_t newBlockIsValid;
     195             : 
     196    55244255 :     assert( !( !badBlock && tonalConcealmentActive ) );
     197             : 
     198    55244255 :     if ( badBlock )
     199             :     {
     200     2497771 :         newBlockIsValid = hTonalMDCTConc->lastBlockData.blockIsValid;
     201             :     }
     202             :     else
     203             :     {
     204    52746484 :         newBlockIsValid = ( nNewSamples <= 2 * L_FRAME_MAX ) && ( nNewSamples > 0 );
     205             :     }
     206             : 
     207             :     /* Shift old state */
     208    55244255 :     hTonalMDCTConc->secondLastBlockData.blockIsConcealed = hTonalMDCTConc->lastBlockData.blockIsConcealed;
     209    55244255 :     hTonalMDCTConc->secondLastBlockData.blockIsValid = hTonalMDCTConc->lastBlockData.blockIsValid;
     210    55244255 :     hTonalMDCTConc->secondLastBlockData.tonalConcealmentActive = hTonalMDCTConc->lastBlockData.tonalConcealmentActive;
     211             : 
     212             :     /* Store new state */
     213    55244255 :     hTonalMDCTConc->lastBlockData.blockIsConcealed = badBlock;
     214    55244255 :     hTonalMDCTConc->lastBlockData.blockIsValid = newBlockIsValid;
     215    55244255 :     hTonalMDCTConc->lastBlockData.tonalConcealmentActive = tonalConcealmentActive;
     216    55244255 :     hTonalMDCTConc->lastPitchLag = pitchLag;
     217             : 
     218    55244255 :     return;
     219             : }
     220             : 
     221             : 
     222      246090 : static void FindPhases(
     223             :     const TonalMDCTConcealPtr hTonalMDCTConc,
     224             :     const float secondLastMDCT[],
     225             :     const float secondLastMDST[] )
     226             : {
     227             :     int16_t i;
     228             :     int16_t l;
     229             :     float *pCurrentPhase;
     230             : 
     231      246090 :     pCurrentPhase = hTonalMDCTConc->pTCI->phase_currentFramePredicted;
     232             :     /* for each index/index group */
     233      622546 :     for ( i = 0; i < hTonalMDCTConc->pTCI->numIndexes; i++ )
     234             :     {
     235     2990899 :         for ( l = hTonalMDCTConc->pTCI->lowerIndex[i]; l <= hTonalMDCTConc->pTCI->upperIndex[i]; l++ )
     236             :         {
     237     2614443 :             *pCurrentPhase++ = (float) atan2( secondLastMDST[l], secondLastMDCT[l] );
     238             :         }
     239             :     }
     240             : 
     241      246090 :     return;
     242             : }
     243             : 
     244             : #define CNST_bandwidth 7.0f
     245             : #define CNST_m         (float) cos( EVS_PI / CNST_bandwidth )
     246             : #define CNST_s         (float) cos( ( 3 * EVS_PI ) / CNST_bandwidth )
     247             : #define CNST_n         (float) sin( EVS_PI / CNST_bandwidth )
     248             : #define CNST_j         (float) sin( ( 3 * EVS_PI ) / CNST_bandwidth )
     249             : #define CNST_G         (float) ( 1.0 / ( 2 * 1.36 ) )
     250             : #define CNST_maxRatio  44.8f /* Maximum ratio |ODFT[k-1]|/|ODFT[k+1]| is 16.5 dB, that is maximum ratio (for fractional = 0) is (cos(EVS_PI/bandwidth)/cos(3PI/bandwidth))^1.36 */
     251             : 
     252             : 
     253      246090 : static void FindPhaseDifferences(
     254             :     TonalMDCTConcealPtr const hTonalMDCTConc,
     255             :     float powerSpectrum[] )
     256             : {
     257             :     int16_t i, k;
     258             :     float odft_left, odft_right;
     259             :     float *phaseDiff;
     260             :     float fractional;
     261             :     float Q, a;
     262             : 
     263      246090 :     phaseDiff = hTonalMDCTConc->pTCI->phaseDiff;
     264      622546 :     for ( i = 0; i < hTonalMDCTConc->pTCI->numIndexes; i++ )
     265             :     {
     266      376456 :         k = hTonalMDCTConc->pTCI->indexOfTonalPeak[i];
     267      376456 :         odft_left = powerSpectrum[k - 1];
     268      376456 :         odft_right = powerSpectrum[k + 1];
     269      376456 :         if ( odft_left >= CNST_maxRatio * odft_right )
     270             :         {
     271        2718 :             a = (float) tan( 0.0f * EVS_PI / CNST_bandwidth );
     272             :         }
     273             :         else
     274             :         {
     275      373738 :             if ( odft_right >= CNST_maxRatio * odft_left )
     276             :             {
     277        3350 :                 a = (float) tan( 2.0f * EVS_PI / CNST_bandwidth );
     278             :             }
     279             :             else
     280             :             {
     281      370388 :                 Q = (float) pow( odft_left / odft_right, CNST_G );
     282      370388 :                 a = ( CNST_m - Q * CNST_s ) / ( CNST_n + Q * CNST_j );
     283             :             }
     284             :         }
     285      376456 :         fractional = (float) atan( a ) * ( CNST_bandwidth / 2.0f );
     286      376456 :         assert( ( fractional >= 0 ) && ( fractional <= EVS_PI + 1.192092896e-07F ) );
     287      376456 :         phaseDiff[i] = fractional + EVS_PI * ( k % 4 );
     288             :     }
     289             : 
     290      246090 :     return;
     291             : }
     292             : 
     293      246090 : static void CalcPowerSpec(
     294             :     const float *mdctSpec,
     295             :     const float *mdstSpec,
     296             :     const int16_t nSamples,
     297             :     float floorPowerSpectrum,
     298             :     float *powerSpec )
     299             : {
     300             :     int16_t k;
     301             :     float x;
     302             : 
     303   129088402 :     for ( k = 1; k <= nSamples - 2; k++ )
     304             :     {
     305   128842312 :         x = mdctSpec[k] * mdctSpec[k] + mdstSpec[k] * mdstSpec[k];
     306   128842312 :         powerSpec[k] = max( floorPowerSpectrum, x );
     307             :     }
     308      246090 :     powerSpec[0] = 0.5f * powerSpec[1];
     309      246090 :     powerSpec[nSamples - 1] = 0.5f * powerSpec[nSamples - 2];
     310             : 
     311      246090 :     return;
     312             : }
     313             : 
     314      246090 : static void CalcPowerSpecAndDetectTonalComponents(
     315             :     const TonalMDCTConcealPtr hTonalMDCTConc,
     316             :     float secondLastMDST[],
     317             :     float secondLastMDCT[],
     318             :     const float pitchLag,
     319             :     const PsychoacousticParameters *psychParamsCurrent )
     320             : {
     321             :     int16_t i, nSamples;
     322             :     float floorPowerSpectrum;         /* Minimum significant value of a spectral line in the power spectrum */
     323             :     float powerSpectrum[L_FRAME_MAX]; /* 32 bits are required */
     324             :     float invScaleFactors[FDNS_NPTS];
     325             :     int16_t nBands;
     326             : 
     327      246090 :     nSamples = hTonalMDCTConc->nNonZeroSamples;
     328             : 
     329             :     /* It is taken into account that the MDCT is not normalized. */
     330      246090 :     floorPowerSpectrum = hTonalMDCTConc->nSamples * hTonalMDCTConc->nSamples / 400.0f;
     331      246090 :     CalcPowerSpec( secondLastMDCT, secondLastMDST, nSamples, floorPowerSpectrum, powerSpectrum );
     332             : 
     333             :     /* This setting to minimal level is required because the power spectrum is used in the threshold adaptation using the pitch up to hTonalMDCTConc->nSamples. */
     334      246090 :     set_f( powerSpectrum + nSamples, floorPowerSpectrum, hTonalMDCTConc->nSamples - nSamples );
     335             :     /* this setting to zero is needed since the FDNS needs to be called
     336             :        with hTonalMDCTConc->nSamplesCore; it relevant only for nb; it has no effect
     337             :        to the output, but memory checker may complain otherwise due to the
     338             :        usage of uninitialized values */
     339             : 
     340      246090 :     if ( hTonalMDCTConc->nSamplesCore > hTonalMDCTConc->nSamples )
     341             :     {
     342        2645 :         set_zero( powerSpectrum + hTonalMDCTConc->nSamples, hTonalMDCTConc->nSamplesCore - hTonalMDCTConc->nSamples );
     343             :     }
     344             : 
     345      246090 :     DetectTonalComponents( hTonalMDCTConc->pTCI->indexOfTonalPeak, hTonalMDCTConc->pTCI->lowerIndex, hTonalMDCTConc->pTCI->upperIndex, &hTonalMDCTConc->pTCI->numIndexes, hTonalMDCTConc->lastPitchLag, pitchLag,
     346      246090 :                            hTonalMDCTConc->lastBlockData.spectralData, hTonalMDCTConc->lastBlockData.scaleFactors, powerSpectrum, nSamples, hTonalMDCTConc->nSamplesCore, floorPowerSpectrum, psychParamsCurrent );
     347             : 
     348      246090 :     FindPhases( hTonalMDCTConc, secondLastMDCT, secondLastMDST );
     349             : 
     350      246090 :     FindPhaseDifferences( hTonalMDCTConc, powerSpectrum );
     351             : 
     352      246090 :     if ( hTonalMDCTConc->pTCI->numIndexes > 0 )
     353             :     {
     354       90218 :         hTonalMDCTConc->secondLastPowerSpectrum = hTonalMDCTConc->secondLastBlockData.spectralData;
     355             : 
     356    46577176 :         for ( i = 0; i < nSamples; i++ )
     357             :         {
     358    46486958 :             powerSpectrum[i] = (float) sqrt( powerSpectrum[i] );
     359             :         }
     360             : 
     361     5864170 :         for ( i = 0; i < hTonalMDCTConc->nScaleFactors; i++ )
     362             :         {
     363     5773952 :             invScaleFactors[i] = 1.0f / hTonalMDCTConc->secondLastBlockData.scaleFactors[i];
     364             :         }
     365             : 
     366       90218 :         if ( psychParamsCurrent == NULL )
     367             :         {
     368       35450 :             nBands = FDNS_NPTS;
     369       35450 :             mdct_noiseShaping( powerSpectrum, hTonalMDCTConc->nSamplesCore, invScaleFactors, nBands );
     370             :         }
     371             :         else
     372             :         {
     373       54768 :             sns_shape_spectrum( powerSpectrum, psychParamsCurrent, invScaleFactors, hTonalMDCTConc->nSamplesCore );
     374       54768 :             nBands = psychParamsCurrent->nBands;
     375             :         }
     376             : 
     377       90218 :         v_multc( powerSpectrum + hTonalMDCTConc->nSamplesCore, invScaleFactors[nBands - 1], powerSpectrum + hTonalMDCTConc->nSamplesCore, hTonalMDCTConc->nSamples - hTonalMDCTConc->nSamplesCore );
     378       90218 :         mvr2r( powerSpectrum, hTonalMDCTConc->secondLastPowerSpectrum, hTonalMDCTConc->nSamples ); /* 16 bits are now enough for storing the power spectrum */
     379             :     }
     380             : 
     381      246090 :     return;
     382             : }
     383             : 
     384             : 
     385      492180 : static void CalcMDXT(
     386             :     const TonalMDCTConcealPtr hTonalMDCTConc,
     387             :     const char type,
     388             :     const float *timeSignal,
     389             :     float *mdxtOutput )
     390             : {
     391             :     float windowedTimeSignal[L_FRAME_PLUS + 2 * L_MDCT_OVLP_MAX];
     392             :     int16_t left_overlap, right_overlap;
     393             :     int16_t L_frame;
     394             : 
     395      492180 :     L_frame = hTonalMDCTConc->nSamples;
     396      492180 :     WindowSignal( hTonalMDCTConc->tcx_cfg, hTonalMDCTConc->tcx_cfg->tcx_offsetFB, FULL_OVERLAP, FULL_OVERLAP, &left_overlap, &right_overlap, timeSignal, &L_frame, windowedTimeSignal, 1, 1 );
     397             : 
     398      492180 :     if ( type == 'S' )
     399             :     {
     400      246090 :         TCX_MDST( windowedTimeSignal, mdxtOutput, left_overlap, L_frame - ( left_overlap + right_overlap ) / 2, right_overlap, EVS_MONO );
     401             :     }
     402             :     else
     403             :     {
     404      246090 :         TCX_MDCT( windowedTimeSignal, mdxtOutput, left_overlap, L_frame - ( left_overlap + right_overlap ) / 2, right_overlap, EVS_MONO );
     405             :     }
     406             : 
     407      492180 :     return;
     408             : }
     409             : 
     410             : 
     411      351949 : void TonalMDCTConceal_Detect(
     412             :     const TonalMDCTConcealPtr hTonalMDCTConc,
     413             :     const float pitchLag,
     414             :     int16_t *numIndices,
     415             :     const PsychoacousticParameters *psychParamsCurrent )
     416             : {
     417             :     float secondLastMDST[L_FRAME_MAX]; /* 32 bits are required */
     418             :     float secondLastMDCT[L_FRAME_MAX]; /* 32 bits are required */
     419      351949 :     float *powerSpectrum = secondLastMDST;
     420             :     int16_t i, nSamples;
     421             :     int16_t nBands;
     422             : 
     423      351949 :     nSamples = hTonalMDCTConc->nSamples;
     424      351949 :     if ( hTonalMDCTConc->lastBlockData.blockIsValid && hTonalMDCTConc->secondLastBlockData.blockIsValid && ( hTonalMDCTConc->lastBlockData.nSamples == nSamples ) && ( hTonalMDCTConc->secondLastBlockData.nSamples == nSamples ) && ( !hTonalMDCTConc->secondLastBlockData.blockIsConcealed || hTonalMDCTConc->secondLastBlockData.tonalConcealmentActive || ( pitchLag != 0 ) ) )
     425             :     {
     426             :         /* Safety if the second last frame was concealed and tonal concealment was inactive */
     427             : 
     428      256284 :         if ( !hTonalMDCTConc->lastBlockData.blockIsConcealed )
     429             :         {
     430      256284 :             if ( !hTonalMDCTConc->secondLastBlockData.tonalConcealmentActive )
     431             :             {
     432      246090 :                 CalcMDXT( hTonalMDCTConc, 'S', hTonalMDCTConc->secondLastPcmOut, secondLastMDST );
     433      246090 :                 CalcMDXT( hTonalMDCTConc, 'C', hTonalMDCTConc->secondLastPcmOut, secondLastMDCT );
     434      246090 :                 hTonalMDCTConc->nNonZeroSamples = 0;
     435   177876330 :                 for ( i = 0; i < hTonalMDCTConc->nSamples; i++ )
     436             :                 {
     437   177630240 :                     if ( hTonalMDCTConc->secondLastBlockData.spectralData[i] != 0 )
     438             :                     {
     439   114014932 :                         hTonalMDCTConc->nNonZeroSamples = i;
     440             :                     }
     441             :                 }
     442             :                 /* 23 is the maximum length of the MA filter in getEnvelope */
     443      246090 :                 hTonalMDCTConc->nNonZeroSamples = min( hTonalMDCTConc->nSamples, hTonalMDCTConc->nNonZeroSamples + 23 );
     444      246090 :                 CalcPowerSpecAndDetectTonalComponents( hTonalMDCTConc, secondLastMDST, secondLastMDCT, pitchLag, psychParamsCurrent );
     445             :             }
     446             :             else
     447             :             {
     448             :                 /* If the second last frame was also lost, it is expected that pastTimeSignal could hold a bit different signal (e.g. including fade-out) from the one stored in TonalMDCTConceal_SaveTimeSignal. */
     449             :                 /* That is why we reuse the already stored information about the concealed spectrum in the second last frame */
     450       10194 :                 nSamples = hTonalMDCTConc->nNonZeroSamples;
     451       10194 :                 mvr2r( hTonalMDCTConc->secondLastPowerSpectrum, powerSpectrum, nSamples ); /* Convert from 16 bits to 32 bits */
     452       10194 :                 if ( psychParamsCurrent == NULL )
     453             :                 {
     454        2701 :                     nBands = FDNS_NPTS;
     455        2701 :                     mdct_noiseShaping( powerSpectrum, hTonalMDCTConc->nSamplesCore, hTonalMDCTConc->secondLastBlockData.scaleFactors, nBands );
     456             :                 }
     457             :                 else
     458             :                 {
     459        7493 :                     sns_shape_spectrum( powerSpectrum, psychParamsCurrent, hTonalMDCTConc->secondLastBlockData.scaleFactors, hTonalMDCTConc->nSamplesCore );
     460        7493 :                     nBands = psychParamsCurrent->nBands;
     461             :                 }
     462             : 
     463       10194 :                 v_multc( powerSpectrum + hTonalMDCTConc->nSamplesCore, hTonalMDCTConc->secondLastBlockData.scaleFactors[nBands - 1], powerSpectrum + hTonalMDCTConc->nSamplesCore, nSamples - hTonalMDCTConc->nSamplesCore );
     464       10194 :                 v_mult( powerSpectrum, powerSpectrum, powerSpectrum, nSamples );
     465             : 
     466       10194 :                 RefineTonalComponents( hTonalMDCTConc->pTCI->indexOfTonalPeak, hTonalMDCTConc->pTCI->lowerIndex, hTonalMDCTConc->pTCI->upperIndex, hTonalMDCTConc->pTCI->phaseDiff,
     467       10194 :                                        hTonalMDCTConc->pTCI->phase_currentFramePredicted, &hTonalMDCTConc->pTCI->numIndexes, hTonalMDCTConc->lastPitchLag, pitchLag,
     468       10194 :                                        hTonalMDCTConc->lastBlockData.spectralData, hTonalMDCTConc->lastBlockData.scaleFactors, powerSpectrum,
     469       10194 :                                        nSamples, hTonalMDCTConc->nSamplesCore, hTonalMDCTConc->nSamples * hTonalMDCTConc->nSamples / 400.0f /* floorPowerSpectrum */, psychParamsCurrent );
     470             :             }
     471             :         }
     472             :     }
     473             :     else
     474             :     {
     475       95665 :         hTonalMDCTConc->pTCI->numIndexes = 0;
     476             :     }
     477             : 
     478      351949 :     *numIndices = hTonalMDCTConc->pTCI->numIndexes;
     479             : 
     480      351949 :     return;
     481             : }
     482             : 
     483             : 
     484     1795648 : void TonalMDCTConceal_InsertNoise(
     485             :     const TonalMDCTConcealPtr hTonalMDCTConc, /*IN */
     486             :     float *mdctSpectrum,                      /*OUT*/
     487             :     const int16_t tonalConcealmentActive,
     488             :     int16_t *pSeed,
     489             :     const float tiltCompFactor,
     490             :     const float crossfadeGain,
     491             :     const float concealment_noise[L_FRAME48k],
     492             :     const float cngLevelBackgroundTrace_bfi,
     493             :     const int16_t crossOverFreq )
     494             : {
     495             :     int16_t i, l;
     496             :     float x, y;
     497             :     Word16 rnd;
     498             :     float g, nrgNoiseInLastFrame, nrgWhiteNoise, tiltFactor, tilt;
     499             :     float last_block_nrg_correct;
     500             : 
     501     1795648 :     push_wmops( "InsertNoise" );
     502             : 
     503     1795648 :     g = 1.0f - crossfadeGain;
     504     1795648 :     if ( !hTonalMDCTConc->lastBlockData.blockIsConcealed )
     505             :     {
     506      745932 :         rnd = 1977;
     507             :     }
     508             :     else
     509             :     {
     510     1049716 :         rnd = *pSeed;
     511             :     }
     512             : 
     513             :     /* based on what is done in tcx_noise_filling() */
     514             :     /* always initialize these to avoid compiler warnings */
     515     1795648 :     tiltFactor = (float) pow( max( 0.375f, tiltCompFactor ), 1.0f / hTonalMDCTConc->lastBlockData.nSamples );
     516     1795648 :     tilt = 1.0f;
     517     1795648 :     nrgNoiseInLastFrame = 0.0f;
     518     1795648 :     nrgWhiteNoise = 0.0f;
     519     1795648 :     hTonalMDCTConc->faded_signal_nrg = 0.0f;
     520     1795648 :     last_block_nrg_correct = 0.0f;
     521             : 
     522     1795648 :     if ( !hTonalMDCTConc->lastBlockData.blockIsValid )
     523             :     {
     524             :         /* may just become active if the very first frame is lost */
     525           0 :         set_f( mdctSpectrum, 0.0f, hTonalMDCTConc->nSamples );
     526             :     }
     527     1795648 :     else if ( concealment_noise != NULL )
     528             :     {
     529      480455 :         if ( !tonalConcealmentActive )
     530             :         {
     531             :             /* if fadeout has not started yet, only apply sign scrambling */
     532      441626 :             if ( crossfadeGain == 1.0f )
     533             :             {
     534    78056144 :                 for ( i = 0; i < crossOverFreq; i++ )
     535             :                 {
     536    77860524 :                     if ( concealment_noise[i] > 0 )
     537             :                     {
     538    40486106 :                         mdctSpectrum[i] = hTonalMDCTConc->lastBlockData.spectralData[i];
     539             :                     }
     540             :                     else
     541             :                     {
     542    37374418 :                         mdctSpectrum[i] = -hTonalMDCTConc->lastBlockData.spectralData[i];
     543             :                     }
     544             :                 }
     545             : 
     546    50916456 :                 for ( l = crossOverFreq; l < hTonalMDCTConc->lastBlockData.nSamples; l++ )
     547             :                 {
     548    50720836 :                     mdctSpectrum[l] = 0.0f;
     549             :                 }
     550             :             }
     551             :             /* actual fadeout is done in this case */
     552             :             else
     553             :             {
     554      246006 :                 g *= (float) sqrt( cngLevelBackgroundTrace_bfi / hTonalMDCTConc->curr_noise_nrg );
     555             : 
     556    97073942 :                 for ( i = 0; i < crossOverFreq; i++ )
     557             :                 {
     558    96827936 :                     x = hTonalMDCTConc->lastBlockData.spectralData[i];
     559    96827936 :                     y = concealment_noise[i];
     560             : 
     561    96827936 :                     if ( y > 0 )
     562             :                     {
     563    12836787 :                         mdctSpectrum[i] = g * y + crossfadeGain * x;
     564             :                     }
     565             :                     else
     566             :                     {
     567    83991149 :                         mdctSpectrum[i] = g * y - crossfadeGain * x;
     568             :                     }
     569             : 
     570    96827936 :                     hTonalMDCTConc->faded_signal_nrg += mdctSpectrum[i] * mdctSpectrum[i];
     571             :                 }
     572    60613350 :                 for ( l = crossOverFreq; l < hTonalMDCTConc->lastBlockData.nSamples; l++ )
     573             :                 {
     574    60367344 :                     mdctSpectrum[l] = 0.0f;
     575             :                 }
     576             :             }
     577             :         }
     578             :         else
     579             :         {
     580       38829 :             assert( hTonalMDCTConc->pTCI->numIndexes > 0 );
     581             : 
     582             :             /* initialize bins of tonal components with zero: basically not
     583             :             necessary, but currently the whole spectrum is rescaled in
     584             :             mdct_noiseShaping() and then there would be a processing of
     585             :             uninitialized values */
     586      211272 :             for ( i = 0; i < hTonalMDCTConc->pTCI->numIndexes; i++ )
     587             :             {
     588     1376794 :                 for ( l = hTonalMDCTConc->pTCI->lowerIndex[i]; l <= hTonalMDCTConc->pTCI->upperIndex[i]; l++ )
     589             :                 {
     590     1204351 :                     mdctSpectrum[l] = 0;
     591     1204351 :                     if ( l < crossOverFreq )
     592             :                     {
     593     1162823 :                         last_block_nrg_correct += hTonalMDCTConc->lastBlockData.spectralData[l] * hTonalMDCTConc->lastBlockData.spectralData[l];
     594     1162823 :                         hTonalMDCTConc->curr_noise_nrg -= concealment_noise[l] * concealment_noise[l];
     595             :                     }
     596             :                 }
     597             :             }
     598             : 
     599             :             /* if fadeout has not started yet, only apply sign scrambling */
     600       38829 :             if ( crossfadeGain == 1.0f )
     601             :             {
     602     1283085 :                 for ( l = 0; l < hTonalMDCTConc->pTCI->lowerIndex[0]; l++ )
     603             :                 {
     604     1266328 :                     if ( concealment_noise[l] > 0 )
     605             :                     {
     606      629677 :                         mdctSpectrum[l] = hTonalMDCTConc->lastBlockData.spectralData[l];
     607             :                     }
     608             :                     else
     609             :                     {
     610      636651 :                         mdctSpectrum[l] = -hTonalMDCTConc->lastBlockData.spectralData[l];
     611             :                     }
     612             :                 }
     613       72810 :                 for ( i = 1; i < hTonalMDCTConc->pTCI->numIndexes; i++ )
     614             :                 {
     615     1325698 :                     for ( l = hTonalMDCTConc->pTCI->upperIndex[i - 1] + 1; l < hTonalMDCTConc->pTCI->lowerIndex[i]; l++ )
     616             :                     {
     617     1269645 :                         if ( concealment_noise[l] > 0 )
     618             :                         {
     619      664648 :                             mdctSpectrum[l] = hTonalMDCTConc->lastBlockData.spectralData[l];
     620             :                         }
     621             :                         else
     622             :                         {
     623      604997 :                             mdctSpectrum[l] = -hTonalMDCTConc->lastBlockData.spectralData[l];
     624             :                         }
     625             :                     }
     626             :                 }
     627             : 
     628     3635993 :                 for ( l = hTonalMDCTConc->pTCI->upperIndex[hTonalMDCTConc->pTCI->numIndexes - 1] + 1; l < crossOverFreq; l++ )
     629             :                 {
     630     3619236 :                     if ( concealment_noise[l] > 0 )
     631             :                     {
     632     1902569 :                         mdctSpectrum[l] = hTonalMDCTConc->lastBlockData.spectralData[l];
     633             :                     }
     634             :                     else
     635             :                     {
     636     1716667 :                         mdctSpectrum[l] = -hTonalMDCTConc->lastBlockData.spectralData[l];
     637             :                     }
     638             :                 }
     639             : 
     640     4506997 :                 for ( l = crossOverFreq; l < hTonalMDCTConc->lastBlockData.nSamples; l++ )
     641             :                 {
     642     4490240 :                     mdctSpectrum[l] = hTonalMDCTConc->lastBlockData.spectralData[l];
     643             :                 }
     644             :             }
     645             :             /* actual fadeout is done in this case */
     646             :             else
     647             :             {
     648       22072 :                 g *= (float) sqrt( cngLevelBackgroundTrace_bfi / hTonalMDCTConc->curr_noise_nrg );
     649             : 
     650     2211948 :                 for ( l = 0; l < hTonalMDCTConc->pTCI->lowerIndex[0]; l++ )
     651             :                 {
     652     2189876 :                     x = hTonalMDCTConc->lastBlockData.spectralData[l];
     653     2189876 :                     y = concealment_noise[l];
     654             : 
     655     2189876 :                     if ( y > 0 )
     656             :                     {
     657      418664 :                         mdctSpectrum[l] = g * y + crossfadeGain * x;
     658             :                     }
     659             :                     else
     660             :                     {
     661     1771212 :                         mdctSpectrum[l] = g * y - crossfadeGain * x;
     662             :                     }
     663     2189876 :                     hTonalMDCTConc->faded_signal_nrg += mdctSpectrum[l] * mdctSpectrum[l];
     664             :                 }
     665       99633 :                 for ( i = 1; i < hTonalMDCTConc->pTCI->numIndexes; i++ )
     666             :                 {
     667     1905542 :                     for ( l = hTonalMDCTConc->pTCI->upperIndex[i - 1] + 1; l < hTonalMDCTConc->pTCI->lowerIndex[i]; l++ )
     668             :                     {
     669     1827981 :                         x = hTonalMDCTConc->lastBlockData.spectralData[l];
     670     1827981 :                         y = concealment_noise[l];
     671             : 
     672     1827981 :                         if ( y > 0 )
     673             :                         {
     674      473585 :                             mdctSpectrum[l] = g * y + crossfadeGain * x;
     675             :                         }
     676             :                         else
     677             :                         {
     678     1354396 :                             mdctSpectrum[l] = g * y - crossfadeGain * x;
     679             :                         }
     680     1827981 :                         hTonalMDCTConc->faded_signal_nrg += mdctSpectrum[l] * mdctSpectrum[l];
     681             :                     }
     682             :                 }
     683             : 
     684     3885314 :                 for ( l = hTonalMDCTConc->pTCI->upperIndex[hTonalMDCTConc->pTCI->numIndexes - 1] + 1; l < crossOverFreq; l++ )
     685             :                 {
     686     3863242 :                     x = hTonalMDCTConc->lastBlockData.spectralData[l];
     687     3863242 :                     y = concealment_noise[l];
     688             : 
     689     3863242 :                     if ( y > 0 )
     690             :                     {
     691      895544 :                         mdctSpectrum[l] = g * y + crossfadeGain * x;
     692             :                     }
     693             :                     else
     694             :                     {
     695     2967698 :                         mdctSpectrum[l] = g * y - crossfadeGain * x;
     696             :                     }
     697     3863242 :                     hTonalMDCTConc->faded_signal_nrg += mdctSpectrum[l] * mdctSpectrum[l];
     698             :                 }
     699             : 
     700     5563208 :                 for ( l = crossOverFreq; l < hTonalMDCTConc->lastBlockData.nSamples; l++ )
     701             :                 {
     702     5541136 :                     mdctSpectrum[l] = 0.0f;
     703             :                 }
     704             :             }
     705             :         }
     706             : 
     707      480455 :         if ( hTonalMDCTConc->faded_signal_nrg > 0.0f && hTonalMDCTConc->curr_noise_nrg > MDCT_ST_PLC_FADEOUT_MIN_NOISE_NRG )
     708             :         {
     709             :             float nrg_corr_factor;
     710             : 
     711       81469 :             nrg_corr_factor = sqrtf( ( hTonalMDCTConc->last_block_nrg - last_block_nrg_correct ) / hTonalMDCTConc->faded_signal_nrg );
     712       81469 :             v_multc( mdctSpectrum, nrg_corr_factor, mdctSpectrum, crossOverFreq );
     713             :         }
     714             :     }
     715             :     else
     716             :     {
     717     1315193 :         if ( !tonalConcealmentActive )
     718             :         {
     719   550065883 :             for ( i = 0; i < crossOverFreq; i++ )
     720             :             {
     721   548868016 :                 x = hTonalMDCTConc->lastBlockData.spectralData[i];
     722   548868016 :                 nrgNoiseInLastFrame += x * x;
     723   548868016 :                 rnd = own_random( &rnd );
     724   548868016 :                 mdctSpectrum[i] = tilt * rnd;
     725   548868016 :                 tilt *= tiltFactor;
     726   548868016 :                 nrgWhiteNoise += mdctSpectrum[i] * mdctSpectrum[i];
     727             :             }
     728     1197867 :             if ( nrgWhiteNoise > 0 )
     729             :             {
     730     1197867 :                 g *= (float) sqrt( nrgNoiseInLastFrame / nrgWhiteNoise );
     731             :             }
     732   550065883 :             for ( i = 0; i < crossOverFreq; i++ )
     733             :             {
     734   548868016 :                 x = hTonalMDCTConc->lastBlockData.spectralData[i];
     735   548868016 :                 y = mdctSpectrum[i];
     736             : 
     737   548868016 :                 if ( y > 0 )
     738             :                 {
     739   273006195 :                     mdctSpectrum[i] = g * y + crossfadeGain * x;
     740             :                 }
     741             :                 else
     742             :                 {
     743   275861821 :                     mdctSpectrum[i] = g * y - crossfadeGain * x;
     744             :                 }
     745             :             }
     746             : 
     747   260603131 :             for ( l = crossOverFreq; l < hTonalMDCTConc->lastBlockData.nSamples; l++ )
     748             :             {
     749   259405264 :                 mdctSpectrum[l] = hTonalMDCTConc->lastBlockData.spectralData[l];
     750             :             }
     751             :         }
     752             :         else
     753             :         {
     754      117326 :             assert( hTonalMDCTConc->pTCI->numIndexes > 0 );
     755     9902266 :             for ( l = 0; l < hTonalMDCTConc->pTCI->lowerIndex[0]; l++ )
     756             :             {
     757     9784940 :                 x = hTonalMDCTConc->lastBlockData.spectralData[l];
     758     9784940 :                 rnd = own_random( &rnd );
     759     9784940 :                 mdctSpectrum[l] = tilt * rnd;
     760     9784940 :                 tilt *= tiltFactor;
     761     9784940 :                 nrgNoiseInLastFrame += x * x;
     762     9784940 :                 nrgWhiteNoise += mdctSpectrum[l] * mdctSpectrum[l];
     763             :             }
     764             : 
     765      513873 :             for ( i = 1; i < hTonalMDCTConc->pTCI->numIndexes; i++ )
     766             :             {
     767      396547 :                 tilt *= (float) pow( tiltFactor, hTonalMDCTConc->pTCI->upperIndex[i - 1] - hTonalMDCTConc->pTCI->lowerIndex[i - 1] + 1 );
     768     8751266 :                 for ( l = hTonalMDCTConc->pTCI->upperIndex[i - 1] + 1; l < hTonalMDCTConc->pTCI->lowerIndex[i]; l++ )
     769             :                 {
     770     8354719 :                     x = hTonalMDCTConc->lastBlockData.spectralData[l];
     771     8354719 :                     rnd = own_random( &rnd );
     772     8354719 :                     mdctSpectrum[l] = tilt * rnd;
     773     8354719 :                     tilt *= tiltFactor;
     774     8354719 :                     nrgNoiseInLastFrame += x * x;
     775     8354719 :                     nrgWhiteNoise += mdctSpectrum[l] * mdctSpectrum[l];
     776             :                 }
     777             :             }
     778      117326 :             tilt *= (float) pow( tiltFactor, hTonalMDCTConc->pTCI->upperIndex[hTonalMDCTConc->pTCI->numIndexes - 1] - hTonalMDCTConc->pTCI->lowerIndex[hTonalMDCTConc->pTCI->numIndexes - 1] + 1 );
     779             : 
     780    26457589 :             for ( l = hTonalMDCTConc->pTCI->upperIndex[hTonalMDCTConc->pTCI->numIndexes - 1] + 1; l < crossOverFreq; l++ )
     781             :             {
     782    26340263 :                 x = hTonalMDCTConc->lastBlockData.spectralData[l];
     783    26340263 :                 rnd = own_random( &rnd );
     784    26340263 :                 mdctSpectrum[l] = tilt * rnd;
     785    26340263 :                 tilt *= tiltFactor;
     786    26340263 :                 nrgNoiseInLastFrame += x * x;
     787    26340263 :                 nrgWhiteNoise += mdctSpectrum[l] * mdctSpectrum[l];
     788             :             }
     789      117326 :             if ( nrgWhiteNoise > 0 )
     790             :             {
     791      117326 :                 g *= (float) sqrt( nrgNoiseInLastFrame / nrgWhiteNoise );
     792             :             }
     793     9902266 :             for ( l = 0; l < hTonalMDCTConc->pTCI->lowerIndex[0]; l++ )
     794             :             {
     795     9784940 :                 x = hTonalMDCTConc->lastBlockData.spectralData[l];
     796     9784940 :                 y = mdctSpectrum[l];
     797             : 
     798     9784940 :                 if ( y > 0 )
     799             :                 {
     800     4982909 :                     mdctSpectrum[l] = g * y + crossfadeGain * x;
     801             :                 }
     802             :                 else
     803             :                 {
     804     4802031 :                     mdctSpectrum[l] = g * y - crossfadeGain * x;
     805             :                 }
     806             :             }
     807      513873 :             for ( i = 1; i < hTonalMDCTConc->pTCI->numIndexes; i++ )
     808             :             {
     809     8751266 :                 for ( l = hTonalMDCTConc->pTCI->upperIndex[i - 1] + 1; l < hTonalMDCTConc->pTCI->lowerIndex[i]; l++ )
     810             :                 {
     811     8354719 :                     x = hTonalMDCTConc->lastBlockData.spectralData[l];
     812     8354719 :                     y = mdctSpectrum[l];
     813             : 
     814     8354719 :                     if ( y > 0 )
     815             :                     {
     816     4273880 :                         mdctSpectrum[l] = g * y + crossfadeGain * x;
     817             :                     }
     818             :                     else
     819             :                     {
     820     4080839 :                         mdctSpectrum[l] = g * y - crossfadeGain * x;
     821             :                     }
     822             :                 }
     823             :             }
     824             :             /* initialize bins of tonal components with zero: basically not
     825             :                necessary, but currently the whole spectrum is rescaled in
     826             :                mdct_noiseShaping() and then there would be a processing of
     827             :                uninitialized values */
     828      631199 :             for ( i = 0; i < hTonalMDCTConc->pTCI->numIndexes; i++ )
     829             :             {
     830     4053501 :                 for ( l = hTonalMDCTConc->pTCI->lowerIndex[i]; l <= hTonalMDCTConc->pTCI->upperIndex[i]; l++ )
     831             :                 {
     832     3539628 :                     mdctSpectrum[l] = 0;
     833             :                 }
     834             :             }
     835    26457589 :             for ( l = hTonalMDCTConc->pTCI->upperIndex[hTonalMDCTConc->pTCI->numIndexes - 1] + 1; l < crossOverFreq; l++ )
     836             :             {
     837    26340263 :                 x = hTonalMDCTConc->lastBlockData.spectralData[l];
     838    26340263 :                 y = mdctSpectrum[l];
     839             : 
     840    26340263 :                 if ( y > 0 )
     841             :                 {
     842    12976771 :                     mdctSpectrum[l] = g * y + crossfadeGain * x;
     843             :                 }
     844             :                 else
     845             :                 {
     846    13363492 :                     mdctSpectrum[l] = g * y - crossfadeGain * x;
     847             :                 }
     848             :             }
     849             : 
     850    29397954 :             for ( l = crossOverFreq; l < hTonalMDCTConc->lastBlockData.nSamples; l++ )
     851             :             {
     852    29280628 :                 mdctSpectrum[l] = hTonalMDCTConc->lastBlockData.spectralData[l];
     853             :             }
     854             :         }
     855             :     }
     856             : 
     857     1795648 :     *pSeed = rnd;
     858             : 
     859     1795648 :     pop_wmops();
     860             : 
     861     1795648 :     return;
     862             : }
     863             : 
     864             : 
     865      156155 : void TonalMDCTConceal_Apply(
     866             :     TonalMDCTConcealPtr hTonalMDCTConc, /*IN */
     867             :     float *mdctSpectrum,                /*OUT */
     868             :     const PsychoacousticParameters *psychParamsCurrent )
     869             : {
     870             :     int16_t i, l;
     871             :     float *phaseDiff, *pCurrentPhase;
     872             :     float phaseToAdd;
     873             :     float powerSpectrum[L_FRAME_MAX];
     874             :     int16_t nSamples;
     875             :     int16_t nBands;
     876             : 
     877      156155 :     if ( hTonalMDCTConc->lastBlockData.blockIsValid & hTonalMDCTConc->secondLastBlockData.blockIsValid )
     878             :     {
     879      156155 :         assert( hTonalMDCTConc->pTCI->numIndexes > 0 );
     880             : 
     881      156155 :         nSamples = hTonalMDCTConc->nNonZeroSamples;
     882      156155 :         assert( hTonalMDCTConc->pTCI->upperIndex[hTonalMDCTConc->pTCI->numIndexes - 1] < nSamples );
     883      156155 :         mvr2r( hTonalMDCTConc->secondLastPowerSpectrum, powerSpectrum, nSamples ); /* Convert from 16 bits to 32 bits */
     884      156155 :         if ( psychParamsCurrent == NULL )
     885             :         {
     886       55943 :             nBands = FDNS_NPTS;
     887       55943 :             mdct_noiseShaping( powerSpectrum, hTonalMDCTConc->nSamplesCore, hTonalMDCTConc->secondLastBlockData.scaleFactors, nBands );
     888             :         }
     889             :         else
     890             :         {
     891      100212 :             sns_shape_spectrum( powerSpectrum, psychParamsCurrent, hTonalMDCTConc->secondLastBlockData.scaleFactors, hTonalMDCTConc->nSamplesCore );
     892      100212 :             nBands = psychParamsCurrent->nBands;
     893             :         }
     894             : 
     895      156155 :         v_multc( powerSpectrum + hTonalMDCTConc->nSamplesCore, hTonalMDCTConc->secondLastBlockData.scaleFactors[nBands - 1], powerSpectrum + hTonalMDCTConc->nSamplesCore, nSamples - hTonalMDCTConc->nSamplesCore );
     896             : 
     897      156155 :         phaseDiff = hTonalMDCTConc->pTCI->phaseDiff; /* if multiple frame loss occurs use the phase from the last frame and continue rotating */
     898      156155 :         pCurrentPhase = hTonalMDCTConc->pTCI->phase_currentFramePredicted;
     899             : 
     900      156155 :         if ( !hTonalMDCTConc->lastBlockData.blockIsConcealed )
     901             :         {
     902       60049 :             if ( hTonalMDCTConc->secondLastBlockData.tonalConcealmentActive )
     903             :             {
     904        3998 :                 hTonalMDCTConc->nFramesLost += 1;
     905             :             }
     906             :             else
     907             :             {
     908       56051 :                 hTonalMDCTConc->nFramesLost = 1.5;
     909             :             }
     910             :         }
     911             : 
     912             :         /* for each index group */
     913      842471 :         for ( i = 0; i < hTonalMDCTConc->pTCI->numIndexes; i++ )
     914             :         {
     915      686316 :             phaseToAdd = hTonalMDCTConc->nFramesLost * phaseDiff[i];
     916             : 
     917             :             /* Move phaseToAdd to range -EVS_PI..EVS_PI */
     918     8484252 :             while ( phaseToAdd > EVS_PI )
     919             :             {
     920     7797936 :                 phaseToAdd -= PI2;
     921             :             }
     922             : 
     923      686316 :             while ( phaseToAdd < -EVS_PI )
     924             :             {
     925             :                 /* should never occur in flt - kept for safety reasons */
     926           0 :                 phaseToAdd += PI2;
     927             :             }
     928             : 
     929     5430295 :             for ( l = hTonalMDCTConc->pTCI->lowerIndex[i]; l <= hTonalMDCTConc->pTCI->upperIndex[i]; l++ )
     930             :             {
     931     4743979 :                 const float currentPhase = ( *pCurrentPhase++ ) + phaseToAdd; /* *pCurrentPhase and phaseToAdd are in range -EVS_PI..EVS_PI */
     932     4743979 :                 mdctSpectrum[l] = (float) cos( currentPhase ) * powerSpectrum[l];
     933             :             }
     934             :         }
     935             :     }
     936             : 
     937      156155 :     hTonalMDCTConc->nFramesLost++;
     938             : 
     939      156155 :     return;
     940             : }
     941             : 
     942             : 
     943    51954186 : void TonalMDCTConceal_SaveTimeSignal(
     944             :     TonalMDCTConcealPtr hTonalMDCTConc,
     945             :     float *timeSignal,
     946             :     const int16_t nNewSamples )
     947             : {
     948    51954186 :     if ( nNewSamples == hTonalMDCTConc->nSamples )
     949             :     {
     950    50913499 :         assert( nNewSamples <= L_FRAME_MAX );
     951             : 
     952    50913499 :         if ( !hTonalMDCTConc->secondLastBlockData.tonalConcealmentActive )
     953             :         {
     954    50854747 :             mvr2r( hTonalMDCTConc->lastPcmOut + hTonalMDCTConc->nSamples / 2, hTonalMDCTConc->secondLastPcmOut, hTonalMDCTConc->nSamples / 2 );
     955             :         }
     956             : 
     957    50913499 :         mvr2r( timeSignal, hTonalMDCTConc->lastPcmOut, hTonalMDCTConc->nSamples );
     958             :     }
     959             : 
     960    51954186 :     return;
     961             : }
     962             : 
     963      480455 : void TonalMdctConceal_create_concealment_noise(
     964             :     float concealment_noise[L_FRAME48k],
     965             :     CPE_DEC_HANDLE hCPE,
     966             :     const int16_t L_frameTCX,
     967             :     const int16_t L_frame,
     968             :     const int16_t idchan,
     969             :     const int16_t subframe_idx,
     970             :     const int16_t core,
     971             :     const float crossfade_gain,
     972             :     const TONALMDCTCONC_NOISE_GEN_MODE noise_gen_mode )
     973             : {
     974             :     STEREO_MDCT_DEC_DATA_HANDLE hStereoMdct;
     975             :     TonalMDCTConcealPtr hTonalMDCTConc;
     976             :     Decoder_State *st;
     977             :     HANDLE_FD_CNG_COM hFdCngCom;
     978             :     int16_t *rnd_c, *rnd;
     979             :     int16_t crossOverFreq, i, save_rnd_c, max_noise_line;
     980             :     float c, c_inv;
     981             :     float noise_shape_buffer[L_FRAME48k];
     982             :     int16_t inc, start_idx, stop_idx;
     983             :     float *cngNoiseLevelPtr;
     984             :     float last_scf;
     985             : 
     986      480455 :     push_wmops( "create_conc_noise" );
     987             : 
     988      480455 :     hStereoMdct = hCPE->hStereoMdct;
     989      480455 :     st = hCPE->hCoreCoder[idchan];
     990      480455 :     hTonalMDCTConc = st->hTonalMDCTConc;
     991      480455 :     hFdCngCom = st->hFdCngDec->hFdCngCom;
     992      480455 :     rnd = &hStereoMdct->noise_seeds_channels[idchan];
     993      480455 :     rnd_c = &hStereoMdct->noise_seed_common;
     994             : 
     995             :     /* determine start bin for IGF */
     996      480455 :     if ( st->igf == 0 )
     997             :     {
     998      188442 :         if ( st->narrowBand == 0 )
     999             :         {
    1000             :             /* minimum needed for output with sampling rates lower then the
    1001             :                nominal sampling rate */
    1002      188442 :             crossOverFreq = min( L_frameTCX, L_frame );
    1003             :         }
    1004             :         else
    1005             :         {
    1006           0 :             crossOverFreq = L_frameTCX;
    1007             :         }
    1008             :     }
    1009             :     else
    1010             :     {
    1011      292013 :         crossOverFreq = min( st->hIGFDec->infoIGFStartLine, L_frameTCX );
    1012             :     }
    1013             : 
    1014             :     /* for tonal mdct concealment with tonal components above the crossover frequency, conditionally raise the frequency index until which noise is generated */
    1015      480455 :     max_noise_line = crossOverFreq;
    1016      480455 :     if ( st->tonal_mdct_plc_active )
    1017             :     {
    1018       38829 :         max_noise_line = max( max_noise_line, hTonalMDCTConc->pTCI->upperIndex[hTonalMDCTConc->pTCI->numIndexes - 1] + 1 );
    1019             :     }
    1020             : 
    1021             :     /* first lost frame is handled separately */
    1022      480455 :     if ( !hTonalMDCTConc->lastBlockData.blockIsConcealed )
    1023             :     {
    1024      212377 :         *rnd = 1977 + idchan;
    1025             :         /* will be set twice when looping over two channels, but does not matter */
    1026      212377 :         *rnd_c = 1979;
    1027             :     }
    1028             : 
    1029      480455 :     if ( crossfade_gain == 1.0f )
    1030             :     {
    1031             :         /* In first frame, noise is weighted with zero anyway, we only need the random numbers for the sign scrambling */
    1032    84736741 :         for ( i = 0; i < max_noise_line; i++ )
    1033             :         {
    1034    84524364 :             *rnd = own_random( rnd );
    1035    84524364 :             concealment_noise[i] = *rnd;
    1036             :         }
    1037             : 
    1038      212377 :         pop_wmops();
    1039             : 
    1040      212377 :         return;
    1041             :     }
    1042             : 
    1043      268078 :     save_rnd_c = *rnd_c;
    1044             : 
    1045      268078 :     c = sqrtf( hStereoMdct->lastCoh );
    1046      268078 :     c_inv = sqrtf( 1 - hStereoMdct->lastCoh );
    1047             : 
    1048             :     /* pre-compute the noise shape for later weighting of the noise spectra */
    1049      268078 :     cngNoiseLevelPtr = &hFdCngCom->cngNoiseLevel[0];
    1050      268078 :     inc = ( st->core > TCX_20_CORE ) ? 2 : 1;
    1051      268078 :     start_idx = hFdCngCom->startBand / inc;
    1052      268078 :     stop_idx = hFdCngCom->stopFFTbin / inc;
    1053             : 
    1054      797038 :     for ( i = 0; i < start_idx; i++ )
    1055             :     {
    1056      528960 :         noise_shape_buffer[i] = 0.0f;
    1057             :     }
    1058    84372718 :     for ( ; i < stop_idx; i++, cngNoiseLevelPtr += inc )
    1059             :     {
    1060    84104640 :         noise_shape_buffer[i] = sqrtf( *( cngNoiseLevelPtr ) );
    1061             :     }
    1062             : 
    1063      268078 :     last_scf = sqrtf( *( cngNoiseLevelPtr - inc ) );
    1064             : 
    1065    21039233 :     for ( ; i < max_noise_line; i++ )
    1066             :     {
    1067    20771155 :         noise_shape_buffer[i] = last_scf;
    1068             :     }
    1069             : 
    1070             :     /* fill the noise vector */
    1071      268078 :     hTonalMDCTConc->curr_noise_nrg = MDCT_ST_PLC_FADEOUT_MIN_NOISE_NRG;
    1072      268078 :     if ( noise_gen_mode == EQUAL_CORES || ( ( noise_gen_mode == TCX20_IN_0_TCX10_IN_1 && idchan == 0 ) || ( noise_gen_mode == TCX10_IN_0_TCX20_IN_1 && idchan == 1 ) ) )
    1073             :     {
    1074             :         /* current channel is TCX20 -> generate noise for "full-length" spectrum */
    1075   105454058 :         for ( i = 0; i < max_noise_line; i++ )
    1076             :         {
    1077   105186595 :             *rnd = own_random( rnd );
    1078   105186595 :             *rnd_c = own_random( rnd_c );
    1079             : 
    1080   105186595 :             concealment_noise[i] = ( c_inv * *rnd + c * *rnd_c ) * noise_shape_buffer[i];
    1081   105186595 :             hTonalMDCTConc->curr_noise_nrg += concealment_noise[i] * concealment_noise[i];
    1082             :         }
    1083             :     }
    1084             :     else /* ( ( noise_gen_mode == TCX10_IN_0_TCX20_IN_1 && idchan == 0 ) || ( noise_gen_mode == TCX20_IN_0_TCX10_IN_1 && idchan == 1 ) )  */
    1085             :     {
    1086             :         /* current channel is TCX10 and the other is TCX20 -> generate noise for "half-length" spectrum, but "increment" mid seed twice, to have the same seed in mid as the other (TCX20) channel for next frame */
    1087      218775 :         for ( i = 0; i < max_noise_line; i++ )
    1088             :         {
    1089      218160 :             *rnd = own_random( rnd );
    1090      218160 :             *rnd_c = own_random( rnd_c );
    1091             : 
    1092      218160 :             concealment_noise[i] = ( c_inv * *rnd + c * *rnd_c ) * noise_shape_buffer[i];
    1093      218160 :             hTonalMDCTConc->curr_noise_nrg += concealment_noise[i] * concealment_noise[i];
    1094             : 
    1095      218160 :             *rnd_c = own_random( rnd_c );
    1096             :         }
    1097             :     }
    1098             : 
    1099      268078 :     if ( st->tonal_mdct_plc_active )
    1100             :     {
    1101      292433 :         for ( i = crossOverFreq; i < max( crossOverFreq, hTonalMDCTConc->pTCI->lowerIndex[hTonalMDCTConc->pTCI->numIndexes - 1] ); ++i )
    1102             :         {
    1103      270361 :             concealment_noise[i] *= 0.0f;
    1104             :         }
    1105             :     }
    1106             : 
    1107             :     /* restore common seed
    1108             :          - after finishing the first channel
    1109             :          - after a first subframe if the current channel is TCX10 */
    1110      268078 :     if ( ( idchan == 0 && ( core == TCX_20 || ( core == TCX_10 && subframe_idx == 1 ) ) ) || ( core == TCX_10 && subframe_idx == 0 ) )
    1111             :     {
    1112      133575 :         *rnd_c = save_rnd_c;
    1113             :     }
    1114             : 
    1115      268078 :     st->seed_tcx_plc = *rnd;
    1116             : 
    1117      268078 :     pop_wmops();
    1118             : 
    1119      268078 :     return;
    1120             : }
    1121             : 
    1122      296611 : void TonalMdctConceal_whiten_noise_shape(
    1123             :     Decoder_State *st,
    1124             :     const int16_t L_frame,
    1125             :     const TONALMDCTCONC_NOISE_SHAPE_WHITENING_MODE whitening_mode )
    1126             : {
    1127             :     int16_t inc, start_idx, stop_idx;
    1128             :     float *noiseLevelPtr, *scfs_bg, *scfs_for_shaping;
    1129             :     HANDLE_FD_CNG_COM hFdCngCom;
    1130             :     float whitenend_noise_shape[L_FRAME16k];
    1131             :     float scfs_int[FDNS_NPTS];
    1132             :     const PsychoacousticParameters *psychParams;
    1133             : 
    1134      296611 :     push_wmops( "apply_sns_on_noise_shape" );
    1135             : 
    1136      296611 :     scfs_bg = &st->hTonalMDCTConc->scaleFactorsBackground[0];
    1137      296611 :     psychParams = st->hTonalMDCTConc->psychParams;
    1138      296611 :     hFdCngCom = st->hFdCngDec->hFdCngCom;
    1139             : 
    1140      296611 :     inc = ( ( whitening_mode == ON_FIRST_LOST_FRAME ? st->core : st->last_core ) > TCX_20_CORE ) ? 2 : 1;
    1141      296611 :     start_idx = hFdCngCom->startBand / inc;
    1142      296611 :     stop_idx = L_frame / inc;
    1143      296611 :     noiseLevelPtr = hFdCngCom->cngNoiseLevel;
    1144             : 
    1145      296611 :     set_zero( whitenend_noise_shape, start_idx );
    1146    93532621 :     for ( int16_t j = start_idx; j < stop_idx; j++, noiseLevelPtr += inc )
    1147             :     {
    1148    93236010 :         whitenend_noise_shape[j] = *noiseLevelPtr;
    1149             :     }
    1150             : 
    1151      296611 :     if ( whitening_mode == ON_FIRST_LOST_FRAME )
    1152             :     {
    1153             :         float scf[SNS_NPTS];
    1154             : 
    1155       92461 :         sns_compute_scf( whitenend_noise_shape, psychParams, L_frame, scf );
    1156       92461 :         sns_interpolate_scalefactors( scfs_int, scf, ENC );
    1157       92461 :         sns_interpolate_scalefactors( scfs_bg, scf, DEC );
    1158       92461 :         scfs_for_shaping = &scfs_int[0];
    1159             :     }
    1160             :     else /* whitening_mode == ON_FIRST_GOOD_FRAME */
    1161             :     {
    1162      204150 :         scfs_for_shaping = &scfs_bg[0];
    1163             :     }
    1164             : 
    1165      296611 :     if ( sum_f( scfs_for_shaping, FDNS_NPTS ) > 0.0f )
    1166             :     {
    1167      183585 :         sns_shape_spectrum( whitenend_noise_shape, psychParams, scfs_for_shaping, L_frame );
    1168      183585 :         mvr2r( whitenend_noise_shape + start_idx, hFdCngCom->cngNoiseLevel, stop_idx - start_idx );
    1169             :     }
    1170             :     else
    1171             :     {
    1172      113026 :         set_zero( hFdCngCom->cngNoiseLevel, stop_idx - start_idx );
    1173             :     }
    1174             : 
    1175      296611 :     pop_wmops();
    1176      296611 : }

Generated by: LCOV version 1.14