LCOV - code coverage report
Current view: top level - lib_dec - tonalMDCTconcealment_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main enc/dec/rend @ 3b2f07138c61dcf997bbf4165d0882f794b2995f Lines: 1245 1722 72.3 %
Date: 2025-05-03 01:55:50 Functions: 17 21 81.0 %

          Line data    Source code
       1             : /*====================================================================================
       2             :     EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0
       3             :   ====================================================================================*/
       4             : 
       5             : #define _USE_MATH_DEFINES
       6             : 
       7             : #include <assert.h>
       8             : #include <stdint.h>
       9             : #include <math.h>
      10             : #include "options.h"
      11             : #include "basop_util.h"
      12             : #include "options.h"
      13             : #include "typedef.h"
      14             : #include "cnst.h"
      15             : #include "prot_fx.h"
      16             : #include "stat_com.h"
      17             : #include "ivas_prot_fx.h"
      18             : 
      19             : #define CROSSFADE_THRESHOLD ( 32762 ) // close to 1.0f in Q15 such that (x == 1.0f) is true
      20             : 
      21             : /************************************************************************************
      22             :  * local functions
      23             :  ************************************************************************************/
      24             : 
      25             : static void CalcMDXT( const TonalMDCTConcealPtr hTonalMDCTConc, const Word16 type, const Word16 *timeSignal, Word32 *mdxtOutput, Word16 *mdxtOutput_e );
      26             : static void CalcPowerSpec( const Word32 *mdctSpec, const Word16 mdctSpec_exp, const Word32 *mdstSpec, const Word16 mdstSpec_exp, const Word16 nSamples, const Word16 floorPowerSpectrum, Word32 *powerSpec, Word16 *powerSpec_exp );
      27             : static void CalcPowerSpecAndDetectTonalComponents( TonalMDCTConcealPtr const hTonalMDCTConc, Word32 secondLastMDST[], Word16 secondLastMDST_exp, Word32 secondLastMDCT[], Word16 secondLastMDCT_exp, Word32 const pitchLag, Word16 element_mode );
      28             : static void FindPhases( TonalMDCTConcealPtr const hTonalMDCTConc, Word32 secondLastMDCT[], Word32 secondLastMDST[], Word16 diff_exp );
      29             : static void FindPhaseDifferences( TonalMDCTConcealPtr const hTonalMDCTConc, Word32 powerSpectrum[] );
      30             : 
      31             : 
      32             : /*******************************************************/
      33             : /*-------------- public functions -------------------- */
      34             : /*******************************************************/
      35             : 
      36          35 : ivas_error TonalMDCTConceal_Init(
      37             :     TonalMDCTConcealPtr hTonalMDCTConc,
      38             :     const Word16 nSamples,
      39             :     const Word16 nSamplesCore,
      40             :     const Word16 nScaleFactors,
      41             :     TCX_CONFIG_HANDLE hTcxCfg /* TCX config */
      42             : )
      43             : {
      44          35 :     test();
      45          35 :     IF( GT_16( nSamples, L_FRAME_MAX ) || GT_16( nScaleFactors, FDNS_NPTS ) )
      46             :     {
      47           0 :         assert( nSamples <= L_FRAME_MAX );
      48           0 :         assert( nScaleFactors <= FDNS_NPTS );
      49           0 :         return ( IVAS_ERROR( IVAS_ERR_INTERNAL, "TonalMDCT FEC: Number of samples larger than max. block size\n" ) );
      50             :     }
      51          35 :     assert( ( hTonalMDCTConc->nScaleFactors == nScaleFactors ) || ( hTonalMDCTConc->nSamples != nSamples ) ); /* If nSamples doesn't change then also nScaleFactors must stay the same */
      52             : 
      53          35 :     hTonalMDCTConc->tcx_cfg = hTcxCfg;
      54             : 
      55          35 :     hTonalMDCTConc->lastBlockData.spectralData = hTonalMDCTConc->spectralDataBuffers[0];
      56          35 :     move16();
      57          35 :     hTonalMDCTConc->secondLastBlockData.spectralData = hTonalMDCTConc->spectralDataBuffers[1];
      58          35 :     move16();
      59          35 :     hTonalMDCTConc->secondLastPowerSpectrum = hTonalMDCTConc->secondLastBlockData.spectralData;
      60          35 :     move16();
      61             : 
      62          35 :     hTonalMDCTConc->lastBlockData.scaleFactors = hTonalMDCTConc->scaleFactorsBuffers[0];
      63          35 :     move16();
      64          35 :     hTonalMDCTConc->secondLastBlockData.scaleFactors = hTonalMDCTConc->scaleFactorsBuffers[1];
      65          35 :     move16();
      66          35 :     hTonalMDCTConc->lastBlockData.scaleFactors_exp = hTonalMDCTConc->scaleFactorsBuffers_exp[0];
      67          35 :     move16();
      68          35 :     hTonalMDCTConc->secondLastBlockData.scaleFactors_exp = hTonalMDCTConc->scaleFactorsBuffers_exp[1];
      69          35 :     move16();
      70             : 
      71          35 :     hTonalMDCTConc->lastBlockData.blockIsValid = 0;
      72          35 :     move16();
      73          35 :     hTonalMDCTConc->secondLastBlockData.blockIsValid = 0;
      74          35 :     move16();
      75          35 :     hTonalMDCTConc->nSamples = 0;
      76          35 :     move16();
      77          35 :     hTonalMDCTConc->nScaleFactors = 0;
      78          35 :     move16();
      79             : 
      80          35 :     hTonalMDCTConc->lastBlockData.blockIsConcealed = 0;
      81          35 :     move16();
      82          35 :     hTonalMDCTConc->secondLastBlockData.blockIsConcealed = 0;
      83          35 :     move16();
      84             : 
      85          35 :     hTonalMDCTConc->pTCI = (TonalComponentsInfo *) hTonalMDCTConc->timeDataBuffer;
      86          35 :     move16();
      87             : 
      88             : 
      89          35 :     hTonalMDCTConc->lastPitchLag = L_deposit_l( 0 );
      90             : 
      91          35 :     IF( NE_16( hTonalMDCTConc->nSamples, nSamples ) )
      92             :     {
      93          35 :         hTonalMDCTConc->secondLastBlockData.blockIsValid = 0;
      94          35 :         move16();
      95          35 :         hTonalMDCTConc->lastBlockData.blockIsValid = 0;
      96          35 :         move16();
      97             :     }
      98             : 
      99          35 :     hTonalMDCTConc->nSamples = nSamples;
     100          35 :     move16();
     101          35 :     hTonalMDCTConc->nSamplesCore = nSamplesCore;
     102          35 :     move16();
     103             : 
     104          35 :     hTonalMDCTConc->nScaleFactors = nScaleFactors;
     105          35 :     move16();
     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          35 :     move16();
     109          35 :     move16();
     110             :     /* just the second half of the second last pcm output is needed */
     111          35 :     hTonalMDCTConc->secondLastPcmOut = &hTonalMDCTConc->timeDataBuffer[sub( ( 3 * L_FRAME_MAX ) / 2, 3 * ( s_min( L_FRAME_MAX, nSamples ) ) / 2 )];
     112          35 :     hTonalMDCTConc->lastPcmOut = &hTonalMDCTConc->timeDataBuffer[sub( ( 3 * L_FRAME_MAX ) / 2, s_min( L_FRAME_MAX, nSamples ) )];
     113             : 
     114             :     /* If the second last frame was lost, we reuse saved TonalComponentsInfo and don't update pcm buffers */
     115          35 :     assert( sizeof( *hTonalMDCTConc->pTCI ) <= ( hTonalMDCTConc->lastPcmOut - hTonalMDCTConc->timeDataBuffer ) * sizeof( hTonalMDCTConc->timeDataBuffer[0] ) );
     116             : 
     117          35 :     return IVAS_ERR_OK;
     118             : }
     119       13011 : ivas_error TonalMDCTConceal_Init_ivas_fx(
     120             :     TonalMDCTConcealPtr hTonalMDCTConc,
     121             :     const UWord16 nSamples,
     122             :     const UWord16 nSamplesCore,
     123             :     const UWord16 nScaleFactors,
     124             :     TCX_CONFIG_HANDLE hTcxCfg )
     125             : {
     126       13011 :     test();
     127       13011 :     IF( GT_16( nSamples, L_FRAME_MAX ) || GT_16( nScaleFactors, FDNS_NPTS ) )
     128             :     {
     129           0 :         assert( LE_16( nSamples, L_FRAME_MAX ) );
     130           0 :         assert( LE_16( nScaleFactors, FDNS_NPTS ) );
     131           0 :         return ( IVAS_ERROR( IVAS_ERR_INTERNAL, "TonalMDCT FEC: Number of samples larger than max. block size\n" ) );
     132             :     }
     133       13011 :     assert( EQ_16( hTonalMDCTConc->nScaleFactors, nScaleFactors ) || NE_16( hTonalMDCTConc->nSamples, nSamples ) ); /* If nSamples doesn't change then also nScaleFactors must stay the same */
     134             : 
     135       13011 :     hTonalMDCTConc->tcx_cfg = hTcxCfg;
     136       13011 :     hTonalMDCTConc->lastBlockData.spectralData = hTonalMDCTConc->spectralDataBuffers[0];
     137       13011 :     set16_fx( hTonalMDCTConc->lastBlockData.spectralData, 0, L_FRAME_MAX );
     138       13011 :     move16();
     139       13011 :     hTonalMDCTConc->secondLastBlockData.spectralData = hTonalMDCTConc->spectralDataBuffers[1];
     140       13011 :     set16_fx( hTonalMDCTConc->secondLastBlockData.spectralData, 0, L_FRAME_MAX );
     141       13011 :     move16();
     142       13011 :     hTonalMDCTConc->secondLastPowerSpectrum = hTonalMDCTConc->secondLastBlockData.spectralData;
     143       13011 :     move16();
     144       13011 :     hTonalMDCTConc->secondLastPowerSpectrum_exp = hTonalMDCTConc->secondLastBlockData.spectralData_exp;
     145       13011 :     move16();
     146       13011 :     hTonalMDCTConc->lastBlockData.scaleFactors = hTonalMDCTConc->scaleFactorsBuffers[0];
     147       13011 :     set16_fx( hTonalMDCTConc->lastBlockData.scaleFactors, 0, FDNS_NPTS );
     148       13011 :     move16();
     149       13011 :     hTonalMDCTConc->secondLastBlockData.scaleFactors = hTonalMDCTConc->scaleFactorsBuffers[1];
     150       13011 :     set16_fx( hTonalMDCTConc->secondLastBlockData.scaleFactors, 0, FDNS_NPTS );
     151       13011 :     move16();
     152       13011 :     hTonalMDCTConc->lastBlockData.scaleFactors_exp = hTonalMDCTConc->scaleFactorsBuffers_exp[0];
     153       13011 :     move16();
     154       13011 :     hTonalMDCTConc->secondLastBlockData.scaleFactors_exp = hTonalMDCTConc->scaleFactorsBuffers_exp[1];
     155       13011 :     move16();
     156             : 
     157       13011 :     hTonalMDCTConc->lastBlockData.blockIsValid = 0;
     158       13011 :     move16();
     159       13011 :     hTonalMDCTConc->secondLastBlockData.blockIsValid = 0;
     160       13011 :     move16();
     161       13011 :     hTonalMDCTConc->nSamples = 0;
     162       13011 :     move16();
     163       13011 :     hTonalMDCTConc->nScaleFactors = 0;
     164       13011 :     move16();
     165             : 
     166       13011 :     hTonalMDCTConc->lastBlockData.blockIsConcealed = 0;
     167       13011 :     move16();
     168       13011 :     hTonalMDCTConc->secondLastBlockData.blockIsConcealed = 0;
     169       13011 :     move16();
     170       13011 :     hTonalMDCTConc->pTCI = (TonalComponentsInfo *) hTonalMDCTConc->timeDataBuffer;
     171             : 
     172       13011 :     move16();
     173       13011 :     hTonalMDCTConc->lastPitchLag = L_deposit_l( 0 );
     174             : 
     175       13011 :     IF( NE_16( hTonalMDCTConc->nSamples, nSamples ) )
     176             :     {
     177       13011 :         hTonalMDCTConc->secondLastBlockData.blockIsValid = 0;
     178       13011 :         move16();
     179       13011 :         hTonalMDCTConc->lastBlockData.blockIsValid = 0;
     180       13011 :         move16();
     181             :     }
     182       13011 :     hTonalMDCTConc->nSamples = nSamples;
     183       13011 :     move16();
     184       13011 :     hTonalMDCTConc->nSamplesCore = nSamplesCore;
     185       13011 :     move16();
     186       13011 :     hTonalMDCTConc->nScaleFactors = nScaleFactors;
     187       13011 :     move16();
     188             : 
     189       13011 :     set32_fx( hTonalMDCTConc->scaleFactorsBackground_fx, 0, FDNS_NPTS );
     190       13011 :     hTonalMDCTConc->scf_fadeout = 16384 /*1.000000 Q14*/;
     191       13011 :     PsychoacousticParameters_Init_fx( INT_FS_16k, L_FRAME16k, 64, 1, 1, &hTonalMDCTConc->psychParamsTCX20 );
     192       13011 :     PsychoacousticParameters_Init_fx( INT_FS_16k, L_FRAME16k / 2, 64, 0, 1, &hTonalMDCTConc->psychParamsTCX10 );
     193       13011 :     hTonalMDCTConc->psychParams = NULL;
     194             : 
     195       13011 :     hTonalMDCTConc->last_block_nrg = 0;
     196       13011 :     move16();
     197       13011 :     hTonalMDCTConc->last_block_nrg_exp = 0;
     198       13011 :     move16();
     199       13011 :     hTonalMDCTConc->curr_noise_nrg = 0;
     200       13011 :     move16();
     201       13011 :     hTonalMDCTConc->curr_noise_nrg_exp = 0;
     202       13011 :     move16();
     203       13011 :     hTonalMDCTConc->faded_signal_nrg = 0;
     204       13011 :     move16();
     205       13011 :     hTonalMDCTConc->faded_signal_nrg_exp = 0;
     206       13011 :     move16();
     207             : 
     208             :     /* Offset the pointer to the end of buffer, so that pTCI is not destroyed when
     209             :        new time samples are stored in lastPcmOut */
     210       13011 :     move16();
     211       13011 :     move16();
     212             :     /* just the second half of the second last pcm output is needed */
     213             : 
     214       13011 :     set16_fx( hTonalMDCTConc->timeDataBuffer, 0, ( 3 * L_FRAME_MAX ) / 2 );
     215       13011 :     hTonalMDCTConc->secondLastPcmOut = &hTonalMDCTConc->timeDataBuffer[( 3 * L_FRAME_MAX ) / 2 - ( 3 * min( L_FRAME_MAX, nSamples ) / 2 )];
     216       13011 :     hTonalMDCTConc->lastPcmOut = &hTonalMDCTConc->timeDataBuffer[( 3 * L_FRAME_MAX ) / 2 - min( L_FRAME_MAX, nSamples )];
     217             :     /* If the second last frame was lost, we reuse saved TonalComponentsInfo and don't update pcm buffers */
     218       13011 :     assert( sizeof( *hTonalMDCTConc->pTCI ) <= ( hTonalMDCTConc->lastPcmOut - hTonalMDCTConc->timeDataBuffer ) * sizeof( hTonalMDCTConc->timeDataBuffer[0] ) );
     219             : 
     220       13011 :     return IVAS_ERR_OK;
     221             : }
     222         638 : void TonalMDCTConceal_SaveFreqSignal(
     223             :     TonalMDCTConcealPtr hTonalMDCTConc,
     224             :     const Word32 *mdctSpectrum, // Q31-mdctSpectrum_exp
     225             :     const Word16 mdctSpectrum_exp,
     226             :     Word16 nNewSamples,         // Q0
     227             :     Word16 nNewSamplesCore,     // Q0
     228             :     const Word16 *scaleFactors, // Q31-scaleFactors_exp
     229             :     const Word16 *scaleFactors_exp,
     230             :     const Word16 gain_tcx_exp )
     231             : {
     232             :     Word16 *temp;
     233             :     Word16 nOldSamples, tmp_exp, s, i, max_exp;
     234             : 
     235             : 
     236         638 :     assert( nNewSamples > 0 && nNewSamples <= 2 * L_FRAME_MAX );
     237             : 
     238             :     /* Avoid overwriting hTonalMDCTConc->secondLastPowerSpectrum stored in spectralData,
     239             :        because it is needed if the second last and the current frame are lost
     240             :        and concealed using the Tonal MDCT PLC */
     241         638 :     test();
     242         638 :     IF( !hTonalMDCTConc->lastBlockData.tonalConcealmentActive || NE_16( hTonalMDCTConc->lastBlockData.nSamples, nNewSamples ) )
     243             :     {
     244         638 :         IF( LE_16( nNewSamples, L_FRAME_MAX ) )
     245             :         {
     246             :             /* Shift the buffers */
     247         615 :             temp = hTonalMDCTConc->secondLastBlockData.spectralData; /* Save the pointer */
     248         615 :             move16();
     249         615 :             hTonalMDCTConc->secondLastBlockData.spectralData = hTonalMDCTConc->lastBlockData.spectralData;
     250         615 :             move16();
     251         615 :             hTonalMDCTConc->lastBlockData.spectralData = temp;
     252         615 :             move16();
     253             : 
     254         615 :             tmp_exp = hTonalMDCTConc->secondLastBlockData.spectralData_exp; /* Save the pointer */
     255         615 :             move16();
     256         615 :             hTonalMDCTConc->secondLastBlockData.spectralData_exp = hTonalMDCTConc->lastBlockData.spectralData_exp;
     257         615 :             move16();
     258         615 :             hTonalMDCTConc->lastBlockData.spectralData_exp = tmp_exp;
     259         615 :             move16();
     260             : 
     261         615 :             tmp_exp = hTonalMDCTConc->secondLastBlockData.gain_tcx_exp; /* Save the pointer */
     262         615 :             move16();
     263         615 :             hTonalMDCTConc->secondLastBlockData.gain_tcx_exp = hTonalMDCTConc->lastBlockData.gain_tcx_exp;
     264         615 :             move16();
     265         615 :             hTonalMDCTConc->lastBlockData.gain_tcx_exp = tmp_exp;
     266         615 :             move16();
     267             : 
     268         615 :             tmp_exp = hTonalMDCTConc->secondLastBlockData.scaleFactors_max_e; /* Save the pointer */
     269         615 :             move16();
     270         615 :             hTonalMDCTConc->secondLastBlockData.scaleFactors_max_e = hTonalMDCTConc->lastBlockData.scaleFactors_max_e;
     271         615 :             move16();
     272         615 :             hTonalMDCTConc->lastBlockData.scaleFactors_max_e = tmp_exp;
     273         615 :             move16();
     274             : 
     275         615 :             temp = hTonalMDCTConc->secondLastBlockData.scaleFactors;
     276         615 :             move16();
     277         615 :             hTonalMDCTConc->secondLastBlockData.scaleFactors = hTonalMDCTConc->lastBlockData.scaleFactors;
     278         615 :             move16();
     279         615 :             hTonalMDCTConc->lastBlockData.scaleFactors = temp;
     280         615 :             move16();
     281             : 
     282         615 :             temp = hTonalMDCTConc->secondLastBlockData.scaleFactors_exp;
     283         615 :             move16();
     284         615 :             hTonalMDCTConc->secondLastBlockData.scaleFactors_exp = hTonalMDCTConc->lastBlockData.scaleFactors_exp;
     285         615 :             move16();
     286         615 :             hTonalMDCTConc->lastBlockData.scaleFactors_exp = temp;
     287         615 :             move16();
     288             :         }
     289             :         ELSE
     290             :         {
     291          23 :             hTonalMDCTConc->lastBlockData.spectralData = hTonalMDCTConc->spectralDataBuffers[0];
     292          23 :             move16();
     293          23 :             hTonalMDCTConc->secondLastBlockData.spectralData = hTonalMDCTConc->spectralDataBuffers[1];
     294          23 :             move16();
     295          23 :             hTonalMDCTConc->lastBlockData.scaleFactors = hTonalMDCTConc->scaleFactorsBuffers[0];
     296          23 :             move16();
     297          23 :             hTonalMDCTConc->secondLastBlockData.scaleFactors = hTonalMDCTConc->scaleFactorsBuffers[1];
     298          23 :             move16();
     299          23 :             hTonalMDCTConc->lastBlockData.scaleFactors_exp = hTonalMDCTConc->scaleFactorsBuffers_exp[0];
     300          23 :             move16();
     301          23 :             hTonalMDCTConc->secondLastBlockData.scaleFactors_exp = hTonalMDCTConc->scaleFactorsBuffers_exp[1];
     302          23 :             move16();
     303             :         }
     304             : 
     305         638 :         nOldSamples = hTonalMDCTConc->lastBlockData.nSamples;
     306         638 :         move16();
     307         638 :         hTonalMDCTConc->lastBlockData.nSamples = nNewSamples;
     308         638 :         move16();
     309         638 :         hTonalMDCTConc->secondLastBlockData.nSamples = nOldSamples;
     310         638 :         move16();
     311             : 
     312         638 :         nOldSamples = hTonalMDCTConc->lastBlockData.nSamplesCore;
     313         638 :         move16();
     314         638 :         hTonalMDCTConc->lastBlockData.nSamplesCore = nNewSamplesCore;
     315         638 :         move16();
     316         638 :         hTonalMDCTConc->secondLastBlockData.nSamplesCore = nOldSamples;
     317         638 :         move16();
     318             :     }
     319             : 
     320         638 :     test();
     321         638 :     IF( ( nNewSamples > 0 ) && ( LE_16( nNewSamples, 2 * L_FRAME_MAX ) ) )
     322             :     {
     323             :         /* Store new data */
     324         638 :         s = getScaleFactor32( mdctSpectrum, nNewSamples );
     325             : 
     326             :         /*Copy(scaleFactors_exp, hTonalMDCTConc->lastBlockData.scaleFactors_exp, hTonalMDCTConc->nScaleFactors);*/
     327         638 :         max_exp = 0;
     328       41470 :         FOR( i = 0; i < hTonalMDCTConc->nScaleFactors; i++ )
     329             :         {
     330       40832 :             hTonalMDCTConc->lastBlockData.scaleFactors_exp[i] = scaleFactors_exp[i];
     331       40832 :             move16();
     332       40832 :             max_exp = s_max( max_exp, scaleFactors_exp[i] );
     333             :         }
     334             : 
     335             :         /*s = sub(s, max_exp);*/
     336         638 :         hTonalMDCTConc->lastBlockData.scaleFactors_max_e = max_exp;
     337             : 
     338      536238 :         FOR( i = 0; i < nNewSamples; i++ )
     339             :         {
     340      535600 :             hTonalMDCTConc->lastBlockData.spectralData[i] = extract_h( L_shl( mdctSpectrum[i], s ) ); // Q31-(mdctSpectrum_exp-s)
     341      535600 :             move16();
     342             :         }
     343         638 :         hTonalMDCTConc->lastBlockData.spectralData_exp = sub( mdctSpectrum_exp, s );
     344         638 :         move16();
     345         638 :         hTonalMDCTConc->lastBlockData.gain_tcx_exp = gain_tcx_exp;
     346             : 
     347         638 :         Copy( scaleFactors, hTonalMDCTConc->lastBlockData.scaleFactors, hTonalMDCTConc->nScaleFactors );
     348             :     }
     349         638 :     return;
     350             : }
     351             : 
     352      771494 : void TonalMDCTConceal_SaveFreqSignal_ivas_fx(
     353             :     TonalMDCTConcealPtr hTonalMDCTConc,
     354             :     const Word32 *mdctSpectrum,     // Q31-mdctSpectrum_exp
     355             :     const Word16 mdctSpectrum_exp,  // Q0
     356             :     const Word16 nNewSamples,       // Q0
     357             :     const Word16 nNewSamplesCore,   // Q0
     358             :     const Word16 *scaleFactors,     // Q15 - *scaleFactors_exp
     359             :     const Word16 *scaleFactors_exp, // Q0
     360             :     const Word16 gain_tcx_exp,      // Q0
     361             :     const Word16 infoIGFStartLine ) // Q0
     362             : {
     363             :     Word16 *temp;
     364             :     Word16 nOldSamples, temp_exp, s, i, max_exp;
     365             : 
     366      771494 :     assert( nNewSamples > 0 && nNewSamples <= 2 * L_FRAME_MAX );
     367             : 
     368             :     /* Avoid overwriting hTonalMDCTConc->secondLastPowerSpectrum stored in spectralData,
     369             :        because it is needed if the second last and the current frame are lost
     370             :        and concealed using the Tonal MDCT PLC */
     371      771494 :     test();
     372      771494 :     IF( !hTonalMDCTConc->lastBlockData.tonalConcealmentActive || NE_16( hTonalMDCTConc->lastBlockData.nSamples, nNewSamples ) )
     373             :     {
     374      771168 :         IF( LE_16( nNewSamples, L_FRAME_MAX ) )
     375             :         {
     376             :             /* Shift the buffers */
     377      765334 :             temp = hTonalMDCTConc->secondLastBlockData.spectralData; /* Save the pointer */
     378      765334 :             move16();
     379      765334 :             hTonalMDCTConc->secondLastBlockData.spectralData = hTonalMDCTConc->lastBlockData.spectralData;
     380      765334 :             move16();
     381      765334 :             hTonalMDCTConc->lastBlockData.spectralData = temp;
     382      765334 :             move16();
     383             : 
     384      765334 :             temp_exp = hTonalMDCTConc->secondLastBlockData.spectralData_exp;
     385      765334 :             move16();
     386      765334 :             hTonalMDCTConc->secondLastBlockData.spectralData_exp = hTonalMDCTConc->lastBlockData.spectralData_exp;
     387      765334 :             move16();
     388      765334 :             hTonalMDCTConc->lastBlockData.spectralData_exp = temp_exp;
     389      765334 :             move16();
     390             : 
     391      765334 :             temp_exp = hTonalMDCTConc->secondLastBlockData.gain_tcx_exp; /* Save the pointer */
     392      765334 :             move16();
     393      765334 :             hTonalMDCTConc->secondLastBlockData.gain_tcx_exp = hTonalMDCTConc->lastBlockData.gain_tcx_exp;
     394      765334 :             move16();
     395      765334 :             hTonalMDCTConc->lastBlockData.gain_tcx_exp = temp_exp;
     396      765334 :             move16();
     397             : 
     398      765334 :             temp_exp = hTonalMDCTConc->secondLastBlockData.scaleFactors_max_e; /* Save the pointer */
     399      765334 :             move16();
     400      765334 :             hTonalMDCTConc->secondLastBlockData.scaleFactors_max_e = hTonalMDCTConc->lastBlockData.scaleFactors_max_e;
     401      765334 :             move16();
     402      765334 :             hTonalMDCTConc->lastBlockData.scaleFactors_max_e = temp_exp;
     403      765334 :             move16();
     404             : 
     405      765334 :             temp = hTonalMDCTConc->secondLastBlockData.scaleFactors;
     406      765334 :             move16();
     407      765334 :             hTonalMDCTConc->secondLastBlockData.scaleFactors = hTonalMDCTConc->lastBlockData.scaleFactors;
     408      765334 :             move16();
     409      765334 :             hTonalMDCTConc->lastBlockData.scaleFactors = temp;
     410      765334 :             move16();
     411             : 
     412      765334 :             temp = hTonalMDCTConc->secondLastBlockData.scaleFactors_exp;
     413      765334 :             move16();
     414      765334 :             hTonalMDCTConc->secondLastBlockData.scaleFactors_exp = hTonalMDCTConc->lastBlockData.scaleFactors_exp;
     415      765334 :             move16();
     416      765334 :             hTonalMDCTConc->lastBlockData.scaleFactors_exp = temp;
     417      765334 :             move16();
     418             :         }
     419             :         ELSE
     420             :         {
     421             :             /* Order the buffers so that even transition frame can fit in if written into the first buffer */
     422        5834 :             hTonalMDCTConc->lastBlockData.spectralData = hTonalMDCTConc->spectralDataBuffers[0];
     423        5834 :             move16();
     424        5834 :             hTonalMDCTConc->secondLastBlockData.spectralData = hTonalMDCTConc->spectralDataBuffers[1];
     425        5834 :             move16();
     426        5834 :             hTonalMDCTConc->lastBlockData.scaleFactors = hTonalMDCTConc->scaleFactorsBuffers[0];
     427        5834 :             move16();
     428        5834 :             hTonalMDCTConc->secondLastBlockData.scaleFactors = hTonalMDCTConc->scaleFactorsBuffers[1];
     429        5834 :             move16();
     430        5834 :             hTonalMDCTConc->lastBlockData.scaleFactors_exp = hTonalMDCTConc->scaleFactorsBuffers_exp[0];
     431        5834 :             move16();
     432        5834 :             hTonalMDCTConc->secondLastBlockData.scaleFactors_exp = hTonalMDCTConc->scaleFactorsBuffers_exp[1];
     433        5834 :             move16();
     434             :         }
     435      771168 :         nOldSamples = hTonalMDCTConc->lastBlockData.nSamples;
     436      771168 :         move16();
     437      771168 :         hTonalMDCTConc->lastBlockData.nSamples = nNewSamples;
     438      771168 :         move16();
     439      771168 :         hTonalMDCTConc->secondLastBlockData.nSamples = nOldSamples;
     440      771168 :         move16();
     441      771168 :         nOldSamples = (Word16) hTonalMDCTConc->lastBlockData.nSamplesCore;
     442      771168 :         move16();
     443      771168 :         hTonalMDCTConc->lastBlockData.nSamplesCore = (UWord16) nNewSamplesCore;
     444      771168 :         move16();
     445      771168 :         hTonalMDCTConc->secondLastBlockData.nSamplesCore = (UWord16) nOldSamples;
     446      771168 :         move16();
     447             :     }
     448             : 
     449      771494 :     test();
     450      771494 :     IF( ( nNewSamples > 0 ) && ( LE_16( nNewSamples, 2 * L_FRAME_MAX ) ) )
     451             :     {
     452             :         /* Store new data */
     453      771494 :         hTonalMDCTConc->last_block_nrg = 0;
     454      771494 :         move32();
     455             : 
     456   369098400 :         FOR( i = 0; i < infoIGFStartLine; i++ )
     457             :         {
     458   368326906 :             Word16 tmp = extract_h( mdctSpectrum[i] );
     459   368326906 :             hTonalMDCTConc->last_block_nrg = L_add( hTonalMDCTConc->last_block_nrg,
     460             :                                                     L_shr( L_mult0( tmp, tmp ), 16 ) ); // Q31-last_block_nrg_exp
     461   368326906 :             move32();
     462             :         }
     463      771494 :         hTonalMDCTConc->last_block_nrg_exp = sub( 31, sub( shl( sub( 15, mdctSpectrum_exp ), 1 ), 16 ) );
     464      771494 :         move16();
     465             : 
     466             :         /* Store new data */
     467      771494 :         s = getScaleFactor32( mdctSpectrum, nNewSamples );
     468             : 
     469      771494 :         max_exp = 0;
     470      771494 :         move16();
     471    50147110 :         FOR( i = 0; i < hTonalMDCTConc->nScaleFactors; i++ )
     472             :         {
     473    49375616 :             hTonalMDCTConc->lastBlockData.scaleFactors_exp[i] = scaleFactors_exp[i];
     474    49375616 :             move16();
     475    49375616 :             max_exp = s_max( max_exp, scaleFactors_exp[i] );
     476             :         }
     477             : 
     478             :         /*s = sub(s, max_exp);*/
     479      771494 :         hTonalMDCTConc->lastBlockData.scaleFactors_max_e = max_exp;
     480      771494 :         move16();
     481             : 
     482   639718374 :         FOR( i = 0; i < nNewSamples; i++ )
     483             :         {
     484   638946880 :             Word16 tmp = 0;
     485   638946880 :             if ( mdctSpectrum[i] != 0 )
     486             :             {
     487   457710947 :                 tmp = 1;
     488   457710947 :                 move16();
     489             :             }
     490   638946880 :             hTonalMDCTConc->lastBlockData.spectralData[i] = extract_h( L_shl( mdctSpectrum[i], s ) ); // 31 - mdctSpectrum_exp +s -16 = 15-(mdctSpectrum_exp -s)
     491   638946880 :             move16();
     492             : 
     493   638946880 :             test();
     494   638946880 :             if ( hTonalMDCTConc->lastBlockData.spectralData[i] == 0 && EQ_16( tmp, 1 ) )
     495             :             {
     496     5096198 :                 hTonalMDCTConc->lastBlockData.spectralData[i] = 1;
     497     5096198 :                 move16();
     498             :             }
     499             :         }
     500      771494 :         hTonalMDCTConc->lastBlockData.spectralData_exp = sub( mdctSpectrum_exp, s );
     501      771494 :         move16();
     502             : 
     503      771494 :         hTonalMDCTConc->lastBlockData.gain_tcx_exp = gain_tcx_exp;
     504      771494 :         move16();
     505      771494 :         Copy( scaleFactors, hTonalMDCTConc->lastBlockData.scaleFactors, hTonalMDCTConc->nScaleFactors );
     506             :     }
     507             : 
     508      771494 :     return;
     509             : }
     510             : 
     511             : 
     512      861023 : void TonalMDCTConceal_UpdateState(
     513             :     TonalMDCTConcealPtr hTonalMDCTConc,
     514             :     Word16 nNewSamples, // Q0
     515             :     Word32 pitchLag,    // Qx
     516             :     Word16 badBlock,    // Q0
     517             :     Word8 tonalConcealmentActive )
     518             : {
     519             :     Word8 newBlockIsValid;
     520             : 
     521      861023 :     assert( !( !badBlock && tonalConcealmentActive ) );
     522             : 
     523      861023 :     IF( badBlock )
     524             :     {
     525       12865 :         newBlockIsValid = (Word8) hTonalMDCTConc->lastBlockData.blockIsValid;
     526       12865 :         move16();
     527             :     }
     528             :     ELSE
     529             :     {
     530      848158 :         newBlockIsValid = 0;
     531      848158 :         move16();
     532      848158 :         test();
     533      848158 :         if ( ( LE_16( nNewSamples, 2 * L_FRAME_MAX ) ) && ( nNewSamples > 0 ) )
     534             :         {
     535      843026 :             newBlockIsValid = 1;
     536      843026 :             move16();
     537             :         }
     538             :     }
     539             : 
     540      861023 :     /* Shift old state */ move16();
     541      861023 :     move16();
     542      861023 :     move16();
     543      861023 :     hTonalMDCTConc->secondLastBlockData.blockIsConcealed = hTonalMDCTConc->lastBlockData.blockIsConcealed;
     544      861023 :     hTonalMDCTConc->secondLastBlockData.blockIsValid = hTonalMDCTConc->lastBlockData.blockIsValid;
     545      861023 :     hTonalMDCTConc->secondLastBlockData.tonalConcealmentActive = hTonalMDCTConc->lastBlockData.tonalConcealmentActive;
     546             : 
     547      861023 :     /* Store new state */ move16();
     548      861023 :     move16();
     549      861023 :     move16();
     550      861023 :     hTonalMDCTConc->lastBlockData.blockIsConcealed = badBlock;
     551      861023 :     hTonalMDCTConc->lastBlockData.blockIsValid = newBlockIsValid;
     552      861023 :     hTonalMDCTConc->lastBlockData.tonalConcealmentActive = tonalConcealmentActive;
     553             : 
     554      861023 :     hTonalMDCTConc->lastPitchLag = pitchLag;
     555      861023 :     move32();
     556             : 
     557      861023 :     return;
     558             : }
     559             : 
     560             : 
     561             : /* o: currenc phase   [-pi;pi]        2Q13 */
     562        1425 : static void FindPhases(
     563             :     TonalMDCTConcealPtr const hTonalMDCTConc, /* i: pointer to internal structure        */
     564             :     Word32 secondLastMDCT[],                  /* i: MDST spectrum data             Qx +31 -diff_exp     */
     565             :     Word32 secondLastMDST[],                  /* i: MDCT spectrum data             Qx      */
     566             :     Word16 diff_exp )                         /* i: exp_MDST - exp_MDCT                  */
     567             : {
     568             :     Word16 i;
     569             :     Word16 l;
     570             :     Word16 *pCurrentPhase;
     571             : 
     572             : 
     573        1425 :     pCurrentPhase = hTonalMDCTConc->pTCI->phase_currentFramePredicted;
     574             :     /* for each index/index group */
     575        4364 :     FOR( i = 0; i < hTonalMDCTConc->pTCI->numIndexes; i++ )
     576             :     {
     577       23463 :         FOR( l = hTonalMDCTConc->pTCI->lowerIndex[i]; l <= hTonalMDCTConc->pTCI->upperIndex[i]; l++ )
     578             :         {
     579             :             /* in contrast to the float code, the parameter secondLastMDST[l]
     580             :                needs not to be negated - due to a different implementation of
     581             :                the MDST */
     582       20524 :             *pCurrentPhase++ = BASOP_util_atan2( secondLastMDST[l], secondLastMDCT[l], diff_exp ); // Q13
     583       20524 :             move16();
     584             :         }
     585             :     }
     586             : 
     587        1425 :     return;
     588             : }
     589             : 
     590             : #define BANDWIDTH 7.0f
     591             : #define G         789516047l         /*1.0/(2*1.36) Q31*/
     592             : #define MAXRATIO  22938 /*44.8f Q9*/ /* Maximum ratio |ODFT[k-1]|/|ODFT[k+1]| is 16.5 dB, that is maximum ratio (for fractional = 0) is (cos(PI/bandwidth)/cos(3PI/bandwidth))^1.36 */
     593             : #define MM        1934815907         /* FL2WORD32(cos(EVS_PI/BANDWIDTH));  */
     594             : #define SS        29166              /* FL2WORD16(cos((3*EVS_PI)/BANDWIDTH)*4);  Q17*/
     595             : #define N         931758243          /* FL2WORD32(sin(EVS_PI/BANDWIDTH)); */
     596             : #define J         31946              /* FL2WORD16(sin((3*EVS_PI)/BANDWIDTH)); */
     597             : 
     598             : /* o: Phase difference [-pi;pi]         2Q13*/
     599        1425 : static void FindPhaseDifferences(
     600             :     TonalMDCTConcealPtr const hTonalMDCTConc, /* i: Pointer to internal structure        */
     601             :     Word32 powerSpectrum[] )                  /* i: Power spectrum data Qx                 */
     602             : {
     603             :     Word16 i, k;
     604             :     Word16 *phaseDiff;
     605             :     Word16 fractional, sf, sfn, sfd;
     606             :     Word16 divi, s, j;
     607             :     Word32 a, Q, L_tmp, m, n;
     608             : 
     609        1425 :     s = SS;
     610        1425 :     move16();
     611        1425 :     j = J;
     612        1425 :     move16();
     613             : 
     614        1425 :     phaseDiff = hTonalMDCTConc->pTCI->phaseDiff;
     615             : 
     616        4364 :     FOR( i = 0; i < hTonalMDCTConc->pTCI->numIndexes; i++ )
     617             :     {
     618        2939 :         m = MM;
     619        2939 :         move16();
     620        2939 :         n = N;
     621        2939 :         move16();
     622             : 
     623        2939 :         k = hTonalMDCTConc->pTCI->indexOfTonalPeak[i];
     624        2939 :         move16();
     625             : 
     626        2939 :         IF( GE_32( Mpy_32_16_1( powerSpectrum[k - 1], 512 /*1.0f Q9*/ ), Mpy_32_16_1( powerSpectrum[k + 1], MAXRATIO ) ) )
     627             :         {
     628          13 :             phaseDiff[i] = 0; /*(float)tan(0.0f*EVS_PI/bandwidth);*/
     629          13 :             move16();
     630          13 :             if ( s_and( k, 1 ) != 0 )
     631             :             {
     632           7 :                 phaseDiff[i] = -12868 /*-EVS_PI 3Q12*/;
     633           7 :                 move16();
     634             :             }
     635             :         }
     636             :         ELSE
     637             :         {
     638        2926 :             IF( GE_32( Mpy_32_16_1( powerSpectrum[k + 1], 512 /*1.0f Q9*/ ), Mpy_32_16_1( powerSpectrum[k - 1], MAXRATIO ) ) )
     639             :             {
     640          27 :                 phaseDiff[i] = 12868 /*EVS_PI 3Q12*/; /*(float)tan(2.0f*PI/bandwidth);*/
     641          27 :                 move16();
     642          27 :                 if ( s_and( k, 1 ) != 0 )
     643             :                 {
     644           9 :                     phaseDiff[i] = 0 /*0 Q13*/; /*2Q13*/
     645           9 :                     move16();
     646             :                 }
     647             :             }
     648             :             ELSE
     649             :             {
     650             :                 /*Q = (float)pow(odft_left/odft_right, G);
     651             :                   a = (m - Q * s) / (n + Q * j);
     652             :                   phaseDiff[i] = (float)atan(a) * (bandwidth/2.0f);*/
     653             :                 /*max divi=44.8 & sf=6*/
     654        2899 :                 divi = BASOP_Util_Divide3232_uu_1616_Scale( powerSpectrum[k - 1], powerSpectrum[k + 1], &sf );
     655        2899 :                 Q = BASOP_Util_fPow( L_deposit_h( divi ), sf, G, 0, &sf ); // Q31-sf
     656        2899 :                 L_tmp = Mpy_32_16_1( Q, s );
     657        2899 :                 sfn = sub( sf, 2 );
     658             : 
     659        2899 :                 if ( sfn > 0 )
     660             :                 {
     661         106 :                     m = L_shr( m, sfn );
     662             :                 }
     663        2899 :                 IF( sfn < 0 )
     664             :                 {
     665        2155 :                     L_tmp = L_shl( L_tmp, sfn );
     666        2155 :                     sfn = 0;
     667        2155 :                     move16();
     668             :                 }
     669             : 
     670        2899 :                 a = L_sub( m, L_tmp ); /*sf*/
     671             : 
     672        2899 :                 L_tmp = Mpy_32_16_1( Q, j );
     673        2899 :                 IF( sf >= 0 )
     674             :                 {
     675        2753 :                     L_tmp = L_shr( L_tmp, 1 );
     676        2753 :                     sfd = add( sf, 1 );
     677        2753 :                     n = L_shr( n, sfd );
     678             :                 }
     679             :                 ELSE
     680             :                 {
     681         146 :                     sfd = 0;
     682         146 :                     move16();
     683         146 :                     L_tmp = L_shl( L_tmp, sf );
     684             :                 }
     685             : 
     686        2899 :                 L_tmp = L_add( n, L_tmp );
     687        2899 :                 fractional = BASOP_util_atan2( a, L_tmp, sub( sfn, sfd ) ); /*2Q13*/
     688        2899 :                 L_tmp = L_mult( fractional, 28672 /*BANDWIDTH/2.0f Q13*/ ); /*2Q13*2Q13=4Q27*/
     689             : 
     690             :                 /* fractional is in the range 0..+pi */
     691             :                 /* we need to stay in the range -2pi..+2pi */
     692        2899 :                 if ( EQ_16( s_and( k, 3 ), 1 ) )
     693             :                 {
     694         632 :                     L_tmp = L_add( L_tmp, 421657440l /*+1*EVS_PI           Q27*/ );
     695             :                 }
     696        2899 :                 if ( EQ_16( s_and( k, 3 ), 2 ) )
     697             :                 {
     698         712 :                     L_tmp = L_sub( L_tmp, 843314880l /*+2*EVS_PI=-2*EVS_PI Q27*/ );
     699             :                 }
     700        2899 :                 if ( EQ_16( s_and( k, 3 ), 3 ) )
     701             :                 {
     702        1023 :                     L_tmp = L_sub( L_tmp, 421657440l /*+3*EVS_PI=-1*EVS_PI Q27*/ );
     703             :                 }
     704        2899 :                 phaseDiff[i] = round_fx( L_shl( L_tmp, 1 ) ); /*3Q12*/
     705        2899 :                 move16();
     706             :             }
     707             :         }
     708             :     }
     709        1425 : }
     710             : 
     711        1425 : static void ivas_CalcPowerSpecAndDetectTonalComponents_fx(
     712             :     TonalMDCTConcealPtr const hTonalMDCTConc,
     713             :     Word32 secondLastMDST[], // Q31 - secondLastMDST_exp
     714             :     Word16 secondLastMDST_exp,
     715             :     Word32 secondLastMDCT[], // Q31 - secondLastMDCT_exp
     716             :     Word16 secondLastMDCT_exp,
     717             :     Word32 const pitchLag, /*15Q16*/
     718             :     const PsychoacousticParameters *psychParamsCurrent,
     719             :     Word16 element_mode )
     720             : {
     721             :     Word16 nSamples;
     722             :     Word16 i;
     723             :     Word16 floorPowerSpectrum; /* Minimum significant value of a spectral line in the power spectrum */
     724             :     Word32 powerSpectrum[L_FRAME_MAX];
     725             :     Word16 invScaleFactors[FDNS_NPTS];
     726             :     Word16 invScaleFactors_exp[FDNS_NPTS];
     727             :     Word16 powerSpectrum_exp, tmp_exp, old_exp;
     728             : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
     729        1425 :     Flag Overflow = 0;
     730        1425 :     move32();
     731             : #endif
     732             : 
     733             :     Word16 nBands;
     734             :     Word32 invScaleFactors_fx[FDNS_NPTS];
     735             :     Word16 old_power_spectrum_q, power_spectrum_q;
     736             : 
     737        1425 :     set32_fx( powerSpectrum, 0, L_FRAME_MAX );
     738             : 
     739        1425 :     nSamples = hTonalMDCTConc->nNonZeroSamples;
     740        1425 :     move16();
     741             : 
     742             :     /* It is taken into account that the MDCT is not normalized. */
     743        1425 :     floorPowerSpectrum /*Q0*/ = extract_l( Mpy_32_32( L_mult0( hTonalMDCTConc->nSamples, hTonalMDCTConc->nSamples ), 5368709 ) ); /*1/400 = 5368709 Q31*/
     744        1425 :     powerSpectrum_exp = 0;
     745        1425 :     move16();
     746             : 
     747        1425 :     CalcPowerSpec( secondLastMDCT,
     748             :                    secondLastMDCT_exp,
     749             :                    secondLastMDST,
     750             :                    secondLastMDST_exp,
     751             :                    nSamples,
     752             :                    floorPowerSpectrum,
     753             :                    powerSpectrum,
     754             :                    &powerSpectrum_exp );
     755             : 
     756             :     /* This setting to minimal level is required because the power spectrum is used in the threshold adaptation using the pitch up to hTonalMDCTConc->nSamples. */
     757        1425 :     set32_fx( powerSpectrum + nSamples, floorPowerSpectrum, sub( hTonalMDCTConc->nSamples, nSamples ) );
     758             :     /* this setting to zero is needed since the FDNS needs to be called
     759             :        with hTonalMDCTConc->nSamplesCore; it relevant only for nb; it has no effect
     760             :        to the output, but memory checker may complain otherwise due to the
     761             :        usage of uninitialized values */
     762        1425 :     IF( GT_16( hTonalMDCTConc->nSamplesCore, hTonalMDCTConc->nSamples ) )
     763             :     {
     764          35 :         set32_fx( powerSpectrum + hTonalMDCTConc->nSamples, 0, sub( hTonalMDCTConc->nSamplesCore, hTonalMDCTConc->nSamples ) );
     765             :     }
     766             : 
     767        1425 :     ivas_DetectTonalComponents_fx( (Word16 *) hTonalMDCTConc->pTCI->indexOfTonalPeak,
     768        1425 :                                    (Word16 *) hTonalMDCTConc->pTCI->lowerIndex,
     769        1425 :                                    (Word16 *) hTonalMDCTConc->pTCI->upperIndex,
     770        1425 :                                    (Word16 *) &hTonalMDCTConc->pTCI->numIndexes,
     771             :                                    hTonalMDCTConc->lastPitchLag,
     772             :                                    pitchLag,
     773        1425 :                                    hTonalMDCTConc->lastBlockData.spectralData,
     774        1425 :                                    hTonalMDCTConc->lastBlockData.spectralData_exp,
     775        1425 :                                    hTonalMDCTConc->lastBlockData.scaleFactors,
     776        1425 :                                    hTonalMDCTConc->lastBlockData.scaleFactors_exp,
     777        1425 :                                    hTonalMDCTConc->lastBlockData.scaleFactors_max_e,
     778             :                                    powerSpectrum,
     779             :                                    powerSpectrum_exp,
     780             :                                    nSamples,
     781        1425 :                                    hTonalMDCTConc->nSamplesCore,
     782             :                                    floorPowerSpectrum, psychParamsCurrent, element_mode );
     783        1425 :     FindPhases( hTonalMDCTConc, secondLastMDCT, secondLastMDST, sub( secondLastMDST_exp, secondLastMDCT_exp ) );
     784             : 
     785        1425 :     FindPhaseDifferences( hTonalMDCTConc, powerSpectrum );
     786             : 
     787        1425 :     IF( hTonalMDCTConc->pTCI->numIndexes > 0 )
     788             :     {
     789         547 :         hTonalMDCTConc->secondLastPowerSpectrum = hTonalMDCTConc->secondLastBlockData.spectralData;
     790             : 
     791             :         /*sqrtFLOAT(powerSpectrum, powerSpectrum, nSamples);*/
     792         547 :         old_exp = powerSpectrum_exp;
     793         547 :         move16();
     794         547 :         powerSpectrum_exp = mult_r( sub( powerSpectrum_exp, 2 ), ( 1 << 14 ) ); /*remove 2 bits of headroom from CalcPowerSpec*/
     795      309863 :         FOR( i = 0; i < nSamples; i++ )
     796             :         {
     797      309316 :             tmp_exp = old_exp;
     798      309316 :             move16();
     799      309316 :             powerSpectrum[i] = Sqrt32( powerSpectrum[i], &tmp_exp );
     800      309316 :             move32();
     801      309316 :             powerSpectrum[i] = L_shr( powerSpectrum[i], sub( powerSpectrum_exp, tmp_exp ) ); // Q31-(powerSpectrum_exp-tmp_exp)
     802      309316 :             move32();
     803             :         }
     804             : 
     805       35555 :         FOR( i = 0; i < hTonalMDCTConc->nScaleFactors; i++ )
     806             :         {
     807       35008 :             invScaleFactors_exp[i] = hTonalMDCTConc->secondLastBlockData.scaleFactors_exp[i];
     808       35008 :             move16();
     809       35008 :             invScaleFactors[i] = Inv16( hTonalMDCTConc->secondLastBlockData.scaleFactors[i], &invScaleFactors_exp[i] ); // Q31-invScaleFactors_exp[i]
     810       35008 :             move16();
     811             :         }
     812             : 
     813         547 :         power_spectrum_q = sub( 31, powerSpectrum_exp );
     814         547 :         old_power_spectrum_q = power_spectrum_q;
     815         547 :         move16();
     816         547 :         Word16 length = 0;
     817         547 :         move16();
     818             :         /* here mdct_shaping() is intentionally used rather then mdct_shaping_16() */
     819         547 :         IF( psychParamsCurrent == NULL )
     820             :         {
     821         220 :             nBands = FDNS_NPTS;
     822         220 :             move16();
     823         220 :             mdct_shaping( powerSpectrum, hTonalMDCTConc->nSamplesCore, invScaleFactors, invScaleFactors_exp );
     824             :         }
     825             :         ELSE
     826             :         {
     827       21255 :             FOR( i = 0; i < FDNS_NPTS; i++ )
     828             :             {
     829       20928 :                 invScaleFactors_fx[i] = L_shl( invScaleFactors[i], add( 1, invScaleFactors_exp[i] ) ); // Q16
     830       20928 :                 move32();
     831             :             }
     832         327 :             sns_shape_spectrum_fx( powerSpectrum, &power_spectrum_q, psychParamsCurrent, invScaleFactors_fx, 16, hTonalMDCTConc->nSamplesCore, &length );
     833         327 :             power_spectrum_q = add( power_spectrum_q, 1 );
     834         327 :             nBands = psychParamsCurrent->nBands;
     835         327 :             move16();
     836             :         }
     837         547 :         IF( LT_16( old_power_spectrum_q, power_spectrum_q ) )
     838             :         {
     839         324 :             Scale_sig32( powerSpectrum, length, sub( old_power_spectrum_q, power_spectrum_q ) ); // Q(old_power_spectrum_q-power_spectrum_q)
     840             :         }
     841             :         ELSE
     842             :         {
     843         223 :             Scale_sig32( powerSpectrum + length, sub( nSamples, length ), sub( power_spectrum_q, old_power_spectrum_q ) ); // Q(power_spectrum_q - old_power_spectrum_q)
     844         223 :             powerSpectrum_exp = sub( 31, power_spectrum_q );
     845             :         }
     846         547 :         Scale_sig32( powerSpectrum, nSamples, -3 ); /*Adding guard bits*/ // Q(31 - powerSpectrum_exp )-3
     847         547 :         powerSpectrum_exp = add( powerSpectrum_exp, 3 );
     848       60146 :         FOR( i = hTonalMDCTConc->nSamplesCore; i < nSamples; i++ )
     849             :         {
     850       59599 :             powerSpectrum[i] = L_shl_sat( Mpy_32_16_1( powerSpectrum[i], invScaleFactors[nBands - 1] ), invScaleFactors_exp[nBands - 1] ); // Q(31 - powerSpectrum_exp)
     851       59599 :             move32();
     852             :         }
     853             : 
     854         547 :         Word16 shift = Find_Max_Norm32( powerSpectrum, nSamples );
     855         547 :         scale_sig32( powerSpectrum, nSamples, shift );
     856         547 :         powerSpectrum_exp = sub( powerSpectrum_exp, shift );
     857             : 
     858             :         /* 16 bits are now enough for storing the power spectrum */
     859      309863 :         FOR( i = 0; i < nSamples; i++ )
     860             :         {
     861      309316 :             hTonalMDCTConc->secondLastPowerSpectrum[i] = round_fx_o( powerSpectrum[i], &Overflow ); // Q31 - powerSpectrum_exp
     862      309316 :             move32();
     863             :         }
     864             : 
     865         547 :         hTonalMDCTConc->secondLastPowerSpectrum_exp = powerSpectrum_exp;
     866         547 :         move16();
     867             :     }
     868        1425 : }
     869             : 
     870           0 : static void CalcPowerSpecAndDetectTonalComponents(
     871             :     TonalMDCTConcealPtr const hTonalMDCTConc,
     872             :     Word32 secondLastMDST[], // Q31-secondLastMDST_exp
     873             :     Word16 secondLastMDST_exp,
     874             :     Word32 secondLastMDCT[], // Q31-secondLastMDCT_exp
     875             :     Word16 secondLastMDCT_exp,
     876             :     Word32 const pitchLag, /*15Q16*/
     877             :     Word16 element_mode
     878             : #ifdef IVAS_CODE_MDCT_GSHAPE
     879             :     ,
     880             :     const PsychoacousticParameters *psychParamsCurrent
     881             : #endif
     882             : )
     883             : {
     884             :     Word16 nSamples;
     885             :     Word16 i;
     886             :     Word16 floorPowerSpectrum; /* Minimum significant value of a spectral line in the power spectrum */
     887             :     Word32 powerSpectrum[L_FRAME_MAX];
     888             :     Word16 invScaleFactors[FDNS_NPTS];
     889             :     Word16 invScaleFactors_exp[FDNS_NPTS];
     890             :     Word16 powerSpectrum_exp, tmp_exp, old_exp;
     891             : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
     892           0 :     Flag Overflow = 0;
     893           0 :     move32();
     894             : #endif
     895             : 
     896             : 
     897           0 :     nSamples = hTonalMDCTConc->nNonZeroSamples;
     898           0 :     move16();
     899             : 
     900             :     /* It is taken into account that the MDCT is not normalized. */
     901           0 :     floorPowerSpectrum /*Q0*/ = extract_l( Mpy_32_16_1( L_mult0( hTonalMDCTConc->nSamples, hTonalMDCTConc->nSamples ), 82 ) ); /*1/400 = 82 Q15*/
     902           0 :     powerSpectrum_exp = 0;
     903           0 :     move16();
     904             : 
     905           0 :     CalcPowerSpec( secondLastMDCT,
     906             :                    secondLastMDCT_exp,
     907             :                    secondLastMDST,
     908             :                    secondLastMDST_exp,
     909             :                    nSamples,
     910             :                    floorPowerSpectrum,
     911             :                    powerSpectrum,
     912             :                    &powerSpectrum_exp );
     913             : 
     914             :     /* This setting to minimal level is required because the power spectrum is used in the threshold adaptation using the pitch up to hTonalMDCTConc->nSamples. */
     915           0 :     set32_fx( powerSpectrum + nSamples, floorPowerSpectrum, sub( hTonalMDCTConc->nSamples, nSamples ) );
     916             :     /* this setting to zero is needed since the FDNS needs to be called
     917             :        with hTonalMDCTConc->nSamplesCore; it relevant only for nb; it has no effect
     918             :        to the output, but memory checker may complain otherwise due to the
     919             :        usage of uninitialized values */
     920           0 :     IF( GT_16( hTonalMDCTConc->nSamplesCore, hTonalMDCTConc->nSamples ) )
     921             :     {
     922           0 :         set32_fx( powerSpectrum + hTonalMDCTConc->nSamples, 0, sub( hTonalMDCTConc->nSamplesCore, hTonalMDCTConc->nSamples ) );
     923             :     }
     924             : 
     925           0 :     DetectTonalComponents( (Word16 *) hTonalMDCTConc->pTCI->indexOfTonalPeak,
     926           0 :                            (Word16 *) hTonalMDCTConc->pTCI->lowerIndex,
     927           0 :                            (Word16 *) hTonalMDCTConc->pTCI->upperIndex,
     928           0 :                            (Word16 *) &hTonalMDCTConc->pTCI->numIndexes,
     929             :                            hTonalMDCTConc->lastPitchLag,
     930             :                            pitchLag,
     931           0 :                            hTonalMDCTConc->lastBlockData.spectralData,
     932           0 :                            add( hTonalMDCTConc->lastBlockData.spectralData_exp, hTonalMDCTConc->lastBlockData.gain_tcx_exp ),
     933           0 :                            hTonalMDCTConc->lastBlockData.scaleFactors,
     934           0 :                            hTonalMDCTConc->lastBlockData.scaleFactors_exp,
     935           0 :                            hTonalMDCTConc->lastBlockData.scaleFactors_max_e,
     936             :                            powerSpectrum,
     937             :                            nSamples,
     938           0 :                            hTonalMDCTConc->nSamplesCore,
     939             :                            floorPowerSpectrum, element_mode );
     940           0 :     FindPhases( hTonalMDCTConc, secondLastMDCT, secondLastMDST, sub( secondLastMDST_exp, secondLastMDCT_exp ) );
     941             : 
     942           0 :     FindPhaseDifferences( hTonalMDCTConc, powerSpectrum );
     943             : 
     944           0 :     IF( hTonalMDCTConc->pTCI->numIndexes > 0 )
     945             :     {
     946             : 
     947           0 :         hTonalMDCTConc->secondLastPowerSpectrum = hTonalMDCTConc->secondLastBlockData.spectralData;
     948             : 
     949             :         /*sqrtFLOAT(powerSpectrum, powerSpectrum, nSamples);*/
     950           0 :         old_exp = powerSpectrum_exp;
     951           0 :         move16();
     952           0 :         powerSpectrum_exp = mult_r( sub( powerSpectrum_exp, 2 ), 1 << 14 ); /*remove 2 bits of headroom from CalcPowerSpec*/
     953           0 :         FOR( i = 0; i < nSamples; i++ )
     954             :         {
     955           0 :             tmp_exp = old_exp;
     956           0 :             move16();
     957           0 :             powerSpectrum[i] = Sqrt32( powerSpectrum[i], &tmp_exp );                         // Q31- tmp_exp
     958           0 :             powerSpectrum[i] = L_shr( powerSpectrum[i], sub( powerSpectrum_exp, tmp_exp ) ); // Q31- tmp_exp
     959           0 :             move32();
     960             :         }
     961             : 
     962           0 :         FOR( i = 0; i < hTonalMDCTConc->nScaleFactors; i++ )
     963             :         {
     964           0 :             move16();
     965           0 :             move16();
     966           0 :             invScaleFactors_exp[i] = hTonalMDCTConc->secondLastBlockData.scaleFactors_exp[i];
     967           0 :             invScaleFactors[i] = Inv16( hTonalMDCTConc->secondLastBlockData.scaleFactors[i], &invScaleFactors_exp[i] ); // Q31 - invScaleFactors_exp[i]
     968             :         }
     969             : 
     970             : 
     971             :         /* here mdct_shaping() is intentionally used rather then mdct_shaping_16() */
     972             : #ifdef IVAS_CODE_MDCT_GSHAPE
     973             :         IF( psychParamsCurrent == NULL )
     974             : #endif
     975             :         {
     976           0 :             mdct_shaping( powerSpectrum, hTonalMDCTConc->nSamplesCore, invScaleFactors, invScaleFactors_exp );
     977             :         }
     978             : #ifdef IVAS_CODE_MDCT_GSHAPE
     979             :         ELSE
     980             :         {
     981             :             PMTE()
     982             :             sns_shape_spectrum( powerSpectrum, psychParamsCurrent, invScaleFactors, hTonalMDCTConc->nSamplesCore );
     983             :             nBands = psychParamsCurrent->nBands;
     984             :         }
     985             : #endif
     986           0 :         FOR( i = hTonalMDCTConc->nSamplesCore; i < nSamples; i++ )
     987             :         {
     988           0 :             powerSpectrum[i] = L_shl_sat( Mpy_32_16_1( powerSpectrum[i], invScaleFactors[FDNS_NPTS - 1] ), invScaleFactors_exp[FDNS_NPTS - 1] ); // powerSpectrum_exp+ 2*invScaleFactors_exp -15
     989           0 :             move32();
     990             :         }
     991             : 
     992             :         /* 16 bits are now enough for storing the power spectrum */
     993           0 :         FOR( i = 0; i < nSamples; i++ )
     994             :         {
     995           0 :             hTonalMDCTConc->secondLastPowerSpectrum[i] = round_fx_o( powerSpectrum[i], &Overflow ); // Q31-powerSpectrum_exp
     996           0 :             move32();
     997             :         }
     998             : 
     999           0 :         powerSpectrum_exp = sub( powerSpectrum_exp, hTonalMDCTConc->secondLastBlockData.gain_tcx_exp );
    1000           0 :         hTonalMDCTConc->secondLastPowerSpectrum_exp = powerSpectrum_exp;
    1001           0 :         move16();
    1002             :     }
    1003           0 : }
    1004             : 
    1005             : 
    1006        2850 : static void CalcMDXT(
    1007             :     const TonalMDCTConcealPtr hTonalMDCTConc,
    1008             :     const Word16 type,
    1009             :     const Word16 *timeSignal, // Qx
    1010             :     Word32 *mdxtOutput,       // Q31-mdxtOutput_e
    1011             :     Word16 *mdxtOutput_e )
    1012             : {
    1013             :     Word16 windowedTimeSignal[L_FRAME_PLUS + 2 * L_MDCT_OVLP_MAX];
    1014             :     Word16 left_overlap, right_overlap, L_frame;
    1015             : 
    1016        2850 :     L_frame = hTonalMDCTConc->nSamples;
    1017        2850 :     move16();
    1018             : 
    1019        2850 :     WindowSignal( hTonalMDCTConc->tcx_cfg, hTonalMDCTConc->tcx_cfg->tcx_offsetFB, FULL_OVERLAP,
    1020             :                   FULL_OVERLAP, &left_overlap, &right_overlap, timeSignal, &L_frame, windowedTimeSignal, 1, 1 );
    1021             : 
    1022        2850 :     IF( type == 0 )
    1023             :     {
    1024        1425 :         TCX_MDST( windowedTimeSignal, mdxtOutput, mdxtOutput_e, left_overlap,
    1025        1425 :                   sub( L_frame, shr( add( left_overlap, right_overlap ), 1 ) ), right_overlap, EVS_MONO );
    1026             :     }
    1027             :     ELSE
    1028             :     {
    1029        1425 :         TCX_MDCT( windowedTimeSignal, mdxtOutput, mdxtOutput_e, left_overlap,
    1030        1425 :                   sub( L_frame, shr( add( left_overlap, right_overlap ), 1 ) ), right_overlap, EVS_MONO );
    1031             :     }
    1032        2850 : }
    1033             : 
    1034           0 : void TonalMDCTConceal_Detect(
    1035             :     const TonalMDCTConcealPtr hTonalMDCTConc,
    1036             :     const Word32 pitchLag, /*15Q16*/
    1037             :     Word16 *numIndices,
    1038             :     Word16 element_mode
    1039             : #ifdef IVAS_CODE_MDCT_GSHAPE
    1040             :     ,
    1041             :     const PsychoacousticParameters *psychParamsCurrent
    1042             : #endif
    1043             : )
    1044             : {
    1045             :     Word32 secondLastMDST[L_FRAME_MAX];
    1046             :     Word32 secondLastMDCT[L_FRAME_MAX];
    1047             :     Word16 secondLastMDCT_exp;
    1048           0 :     Word32 *powerSpectrum = secondLastMDST;
    1049             :     Word16 i, powerSpectrum_exp, secondLastMDST_exp, s;
    1050             :     Word16 nSamples;
    1051             : 
    1052             : 
    1053           0 :     nSamples = hTonalMDCTConc->nSamples;
    1054           0 :     move16();
    1055           0 :     secondLastMDST_exp = 16; /*time signal Q-1*/
    1056           0 :     move16();
    1057           0 :     secondLastMDCT_exp = 16; /*time signal Q-1*/
    1058           0 :     move16();
    1059           0 :     test();
    1060           0 :     test();
    1061           0 :     test();
    1062           0 :     test();
    1063           0 :     test();
    1064           0 :     IF( hTonalMDCTConc->lastBlockData.blockIsValid && hTonalMDCTConc->secondLastBlockData.blockIsValid && ( EQ_16( hTonalMDCTConc->lastBlockData.nSamples, nSamples ) ) && ( EQ_16( hTonalMDCTConc->secondLastBlockData.nSamples, nSamples ) ) && ( !hTonalMDCTConc->secondLastBlockData.blockIsConcealed || hTonalMDCTConc->secondLastBlockData.tonalConcealmentActive || ( pitchLag != 0 ) ) )
    1065             :     {
    1066             :         /* Safety if the second last frame was concealed and tonal concealment was inactive */
    1067             : 
    1068           0 :         IF( hTonalMDCTConc->lastBlockData.blockIsConcealed == 0 )
    1069             :         {
    1070           0 :             IF( hTonalMDCTConc->secondLastBlockData.tonalConcealmentActive == 0 )
    1071             :             {
    1072           0 :                 CalcMDXT( hTonalMDCTConc, 0, hTonalMDCTConc->secondLastPcmOut, secondLastMDST, &secondLastMDST_exp );
    1073           0 :                 CalcMDXT( hTonalMDCTConc, 1, hTonalMDCTConc->secondLastPcmOut, secondLastMDCT, &secondLastMDCT_exp );
    1074           0 :                 hTonalMDCTConc->nNonZeroSamples = 0;
    1075           0 :                 move16();
    1076           0 :                 FOR( i = 0; i < hTonalMDCTConc->nSamples; i++ )
    1077             :                 {
    1078           0 :                     if ( hTonalMDCTConc->secondLastBlockData.spectralData[i] != 0 )
    1079             :                     {
    1080           0 :                         hTonalMDCTConc->nNonZeroSamples = i;
    1081           0 :                         move16();
    1082             :                     }
    1083             :                 }
    1084             : 
    1085             :                 /* 23 is the maximum length of the MA filter in getEnvelope */
    1086           0 :                 hTonalMDCTConc->nNonZeroSamples = s_min( hTonalMDCTConc->nSamples, add( hTonalMDCTConc->nNonZeroSamples, 23 ) );
    1087           0 :                 move16();
    1088           0 :                 nSamples = hTonalMDCTConc->nNonZeroSamples;
    1089           0 :                 move16();
    1090             : 
    1091           0 :                 s = getScaleFactor32( secondLastMDST, nSamples );
    1092             : 
    1093           0 :                 FOR( i = 0; i < nSamples; i++ )
    1094             :                 {
    1095           0 :                     secondLastMDST[i] = L_shl( secondLastMDST[i], s );
    1096           0 :                     move32();
    1097             :                 }
    1098           0 :                 secondLastMDST_exp = sub( secondLastMDST_exp, s );
    1099           0 :                 move16();
    1100           0 :                 s = getScaleFactor32( secondLastMDCT, nSamples );
    1101             : 
    1102           0 :                 FOR( i = 0; i < nSamples; i++ )
    1103             :                 {
    1104           0 :                     secondLastMDCT[i] = L_shl( secondLastMDCT[i], s );
    1105           0 :                     move32();
    1106             :                 }
    1107           0 :                 secondLastMDCT_exp = sub( secondLastMDCT_exp, s );
    1108           0 :                 move16();
    1109           0 :                 CalcPowerSpecAndDetectTonalComponents( hTonalMDCTConc, secondLastMDST, secondLastMDST_exp, secondLastMDCT, secondLastMDCT_exp, pitchLag, element_mode );
    1110             :             }
    1111             :             ELSE
    1112             :             {
    1113             :                 /* 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. */
    1114             :                 /* That is why we reuse the already stored information about the concealed spectrum in the second last frame */
    1115             : #ifdef IVAS_CODE_MDCT_GSHAPE
    1116             :                 IF( psychParamsCurrent == NULL )
    1117             : #endif
    1118             :                 {
    1119           0 :                     nSamples = hTonalMDCTConc->nNonZeroSamples;
    1120           0 :                     move16();
    1121           0 :                     mdct_shaping_16( hTonalMDCTConc->secondLastPowerSpectrum, hTonalMDCTConc->nSamplesCore, nSamples,
    1122           0 :                                      hTonalMDCTConc->secondLastBlockData.scaleFactors, hTonalMDCTConc->secondLastBlockData.scaleFactors_exp,
    1123           0 :                                      hTonalMDCTConc->secondLastBlockData.scaleFactors_max_e, powerSpectrum );
    1124             :                 }
    1125             : #ifdef IVAS_CODE_MDCT_GSHAPE
    1126             :                 ELSE
    1127             :                 {
    1128             :                     sns_shape_spectrum( powerSpectrum, psychParamsCurrent, hTonalMDCTConc->secondLastBlockData.scaleFactors, hTonalMDCTConc->nSamplesCore );
    1129             :                     nBands = psychParamsCurrent->nBands;
    1130             :                 }
    1131             : #endif
    1132           0 :                 powerSpectrum_exp = getScaleFactor32( powerSpectrum, nSamples );
    1133           0 :                 powerSpectrum_exp = sub( powerSpectrum_exp, 3 ); /*extra 3 bits of headroom for MA filter in getEnvelope*/
    1134             : 
    1135             :                 /* multFLOAT(powerSpectrum, powerSpectrum, powerSpectrum, nSamples); */
    1136           0 :                 FOR( i = 0; i < nSamples; i++ )
    1137             :                 {
    1138           0 :                     Word32 const t = L_shl( powerSpectrum[i], powerSpectrum_exp ); // Q(31-secondLastMDST_exp+powerSpectrum_exp)
    1139           0 :                     powerSpectrum[i] = Mpy_32_32( t, t );                          // Q2*(31-secondLastMDST_exp+powerSpectrum_exp) -31
    1140           0 :                     move32();
    1141             :                 }
    1142             : 
    1143           0 :                 RefineTonalComponents( (Word16 *) hTonalMDCTConc->pTCI->indexOfTonalPeak,
    1144           0 :                                        (Word16 *) hTonalMDCTConc->pTCI->lowerIndex,
    1145           0 :                                        (Word16 *) hTonalMDCTConc->pTCI->upperIndex,
    1146           0 :                                        hTonalMDCTConc->pTCI->phaseDiff,
    1147           0 :                                        hTonalMDCTConc->pTCI->phase_currentFramePredicted,
    1148           0 :                                        (Word16 *) &hTonalMDCTConc->pTCI->numIndexes,
    1149             :                                        hTonalMDCTConc->lastPitchLag,
    1150             :                                        pitchLag,
    1151           0 :                                        hTonalMDCTConc->lastBlockData.spectralData,
    1152           0 :                                        add( hTonalMDCTConc->lastBlockData.spectralData_exp, hTonalMDCTConc->lastBlockData.gain_tcx_exp ),
    1153           0 :                                        hTonalMDCTConc->lastBlockData.scaleFactors,
    1154           0 :                                        hTonalMDCTConc->lastBlockData.scaleFactors_exp,
    1155           0 :                                        hTonalMDCTConc->lastBlockData.scaleFactors_max_e,
    1156             :                                        powerSpectrum,
    1157             :                                        nSamples,
    1158           0 :                                        hTonalMDCTConc->nSamplesCore,
    1159           0 :                                        extract_l( Mpy_32_16_1( L_mult0( hTonalMDCTConc->nSamples, hTonalMDCTConc->nSamples ), 82 ) ), element_mode ); /* floorPowerSpectrum */
    1160             :             }
    1161             :         }
    1162             :     }
    1163             :     ELSE
    1164             :     {
    1165           0 :         hTonalMDCTConc->pTCI->numIndexes = 0;
    1166           0 :         move16();
    1167             :     }
    1168             : 
    1169           0 :     *numIndices = hTonalMDCTConc->pTCI->numIndexes;
    1170           0 :     move16();
    1171             : 
    1172             : 
    1173           0 :     return;
    1174             : }
    1175             : 
    1176        1601 : void TonalMDCTConceal_Detect_ivas_fx(
    1177             :     const TonalMDCTConcealPtr hTonalMDCTConc,
    1178             :     const Word32 pitchLag, /*15Q16*/
    1179             :     Word16 *numIndices,
    1180             :     const PsychoacousticParameters *psychParamsCurrent,
    1181             :     Word16 element_mode )
    1182             : {
    1183             :     Word32 secondLastMDST[L_FRAME_MAX];
    1184        1601 :     set32_fx( secondLastMDST, 0, L_FRAME_MAX );
    1185             :     Word32 secondLastMDCT[L_FRAME_MAX];
    1186             :     Word16 secondLastMDCT_exp;
    1187        1601 :     Word32 *powerSpectrum = secondLastMDST;
    1188             :     Word16 i, powerSpectrum_exp, secondLastMDST_exp, s;
    1189             :     Word16 nSamples;
    1190             :     // Word16 nBands;
    1191             :     Word32 sns_int_scf_fx[FDNS_NPTS];
    1192        1601 :     set32_fx( sns_int_scf_fx, 0, FDNS_NPTS );
    1193             : 
    1194        1601 :     nSamples = hTonalMDCTConc->nSamples;
    1195        1601 :     move16();
    1196        1601 :     secondLastMDST_exp = sub( 16, hTonalMDCTConc->q_lastPcmOut ); /*time signal Q-1 - hTonalMDCTConc->q_lastPcmOut*/
    1197        1601 :     move16();
    1198        1601 :     secondLastMDCT_exp = sub( 16, hTonalMDCTConc->q_lastPcmOut ); /*time signal Q-1 - hTonalMDCTConc->q_lastPcmOut*/
    1199        1601 :     move16();
    1200        1601 :     test();
    1201        1601 :     test();
    1202        1601 :     test();
    1203        1601 :     test();
    1204        1601 :     test();
    1205        1601 :     IF( hTonalMDCTConc->lastBlockData.blockIsValid && hTonalMDCTConc->secondLastBlockData.blockIsValid && ( EQ_16( hTonalMDCTConc->lastBlockData.nSamples, nSamples ) ) && ( EQ_16( hTonalMDCTConc->secondLastBlockData.nSamples, nSamples ) ) && ( !hTonalMDCTConc->secondLastBlockData.blockIsConcealed || hTonalMDCTConc->secondLastBlockData.tonalConcealmentActive || ( pitchLag != 0 ) ) )
    1206             :     {
    1207             :         /* Safety if the second last frame was concealed and tonal concealment was inactive */
    1208             : 
    1209        1425 :         IF( hTonalMDCTConc->lastBlockData.blockIsConcealed == 0 )
    1210             :         {
    1211        1425 :             IF( hTonalMDCTConc->secondLastBlockData.tonalConcealmentActive == 0 )
    1212             :             {
    1213        1425 :                 CalcMDXT( hTonalMDCTConc, 0, hTonalMDCTConc->secondLastPcmOut, secondLastMDST, &secondLastMDST_exp );
    1214        1425 :                 CalcMDXT( hTonalMDCTConc, 1, hTonalMDCTConc->secondLastPcmOut, secondLastMDCT, &secondLastMDCT_exp );
    1215        1425 :                 hTonalMDCTConc->nNonZeroSamples = 0;
    1216        1425 :                 move16();
    1217     1126225 :                 FOR( i = 0; i < hTonalMDCTConc->nSamples; i++ )
    1218             :                 {
    1219     1124800 :                     if ( hTonalMDCTConc->secondLastBlockData.spectralData[i] != 0 )
    1220             :                     {
    1221      683492 :                         hTonalMDCTConc->nNonZeroSamples = i;
    1222      683492 :                         move16();
    1223             :                     }
    1224             :                 }
    1225             : 
    1226             :                 /* 23 is the maximum length of the MA filter in getEnvelope */
    1227        1425 :                 hTonalMDCTConc->nNonZeroSamples = s_min( hTonalMDCTConc->nSamples, add( hTonalMDCTConc->nNonZeroSamples, 23 ) );
    1228        1425 :                 move16();
    1229        1425 :                 nSamples = hTonalMDCTConc->nNonZeroSamples;
    1230        1425 :                 move16();
    1231             : 
    1232        1425 :                 s = sub( getScaleFactor32( secondLastMDST, nSamples ), 1 );
    1233             : 
    1234      751351 :                 FOR( i = 0; i < nSamples; i++ )
    1235             :                 {
    1236      749926 :                     secondLastMDST[i] = L_shl( secondLastMDST[i], s );
    1237      749926 :                     move32();
    1238             :                 }
    1239        1425 :                 secondLastMDST_exp = sub( secondLastMDST_exp, s );
    1240        1425 :                 move16();
    1241        1425 :                 s = sub( getScaleFactor32( secondLastMDCT, nSamples ), 1 );
    1242             : 
    1243      751351 :                 FOR( i = 0; i < nSamples; i++ )
    1244             :                 {
    1245      749926 :                     secondLastMDCT[i] = L_shl( secondLastMDCT[i], s );
    1246      749926 :                     move32();
    1247             :                 }
    1248        1425 :                 secondLastMDCT_exp = sub( secondLastMDCT_exp, s );
    1249        1425 :                 move16();
    1250        1425 :                 ivas_CalcPowerSpecAndDetectTonalComponents_fx( hTonalMDCTConc, secondLastMDST, secondLastMDST_exp, secondLastMDCT, secondLastMDCT_exp, pitchLag, psychParamsCurrent, element_mode );
    1251             :             }
    1252             :             ELSE
    1253             :             {
    1254             :                 /* 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. */
    1255             :                 /* That is why we reuse the already stored information about the concealed spectrum in the second last frame */
    1256           0 :                 Word16 temp_power_spectrum_q = 0;
    1257           0 :                 nSamples = hTonalMDCTConc->nNonZeroSamples;
    1258           0 :                 move16();
    1259           0 :                 Copy_Scale_sig_16_32_DEPREC( hTonalMDCTConc->secondLastPowerSpectrum, powerSpectrum, nSamples, Q15 );
    1260           0 :                 temp_power_spectrum_q = add( Q15, sub( 15, hTonalMDCTConc->secondLastPowerSpectrum_exp ) );
    1261           0 :                 IF( psychParamsCurrent == NULL )
    1262             :                 {
    1263           0 :                     mdct_shaping_16( hTonalMDCTConc->secondLastPowerSpectrum, hTonalMDCTConc->nSamplesCore, nSamples,
    1264           0 :                                      hTonalMDCTConc->secondLastBlockData.scaleFactors, hTonalMDCTConc->secondLastBlockData.scaleFactors_exp,
    1265           0 :                                      hTonalMDCTConc->secondLastBlockData.scaleFactors_max_e, powerSpectrum );
    1266             : 
    1267           0 :                     powerSpectrum_exp = getScaleFactor32( powerSpectrum, nSamples );
    1268           0 :                     powerSpectrum_exp = sub( powerSpectrum_exp, 3 ); /*extra 3 bits of headroom for MA filter in getEnvelope*/
    1269             : 
    1270             :                     /* multFLOAT(powerSpectrum, powerSpectrum, powerSpectrum, nSamples); */
    1271           0 :                     FOR( i = 0; i < nSamples; i++ )
    1272             :                     {
    1273           0 :                         Word32 const t = L_shl( powerSpectrum[i], powerSpectrum_exp ); // Q(31-secondLastMDST_exp+powerSpectrum_exp)
    1274           0 :                         powerSpectrum[i] = Mpy_32_32( t, t );                          // Q(31-secondLastMDST_exp+powerSpectrum_exp)
    1275           0 :                         move32();
    1276             :                     }
    1277           0 :                     powerSpectrum_exp = 0;
    1278           0 :                     move16();
    1279             :                 }
    1280             :                 ELSE
    1281             :                 {
    1282           0 :                     FOR( i = 0; i < FDNS_NPTS; i++ )
    1283             :                     {
    1284           0 :                         sns_int_scf_fx[i] = L_shl( hTonalMDCTConc->secondLastBlockData.scaleFactors[i], add( 1, hTonalMDCTConc->secondLastBlockData.scaleFactors_exp[i] ) ); // Q16
    1285           0 :                         move32();
    1286             :                     }
    1287           0 :                     sns_shape_spectrum_fx( powerSpectrum, &temp_power_spectrum_q, psychParamsCurrent, sns_int_scf_fx, 16, hTonalMDCTConc->nSamplesCore, NULL );
    1288           0 :                     powerSpectrum_exp = sub( 31, temp_power_spectrum_q );
    1289             : 
    1290           0 :                     FOR( i = 0; i < nSamples; i++ )
    1291             :                     {
    1292           0 :                         Word32 const t = L_shl( powerSpectrum[i], -3 ); // Q31 - powerSpectrum_exp -3
    1293           0 :                         powerSpectrum[i] = Mpy_32_32( t, t );           // 2*(Q31 - powerSpectrum_exp -3)-31
    1294           0 :                         move32();
    1295             :                     }
    1296           0 :                     powerSpectrum_exp = sub( 31, sub( shl( sub( Q31 - 3, powerSpectrum_exp ), 1 ), 31 ) );
    1297             :                 }
    1298             : 
    1299           0 :                 ivas_RefineTonalComponents_fx( (Word16 *) hTonalMDCTConc->pTCI->indexOfTonalPeak,
    1300           0 :                                                (Word16 *) hTonalMDCTConc->pTCI->lowerIndex,
    1301           0 :                                                (Word16 *) hTonalMDCTConc->pTCI->upperIndex,
    1302           0 :                                                hTonalMDCTConc->pTCI->phaseDiff,
    1303           0 :                                                hTonalMDCTConc->pTCI->phase_currentFramePredicted,
    1304           0 :                                                (Word16 *) &hTonalMDCTConc->pTCI->numIndexes,
    1305             :                                                hTonalMDCTConc->lastPitchLag,
    1306             :                                                pitchLag,
    1307           0 :                                                hTonalMDCTConc->lastBlockData.spectralData,
    1308           0 :                                                add( hTonalMDCTConc->lastBlockData.spectralData_exp, hTonalMDCTConc->lastBlockData.gain_tcx_exp ),
    1309           0 :                                                hTonalMDCTConc->lastBlockData.scaleFactors,
    1310           0 :                                                hTonalMDCTConc->lastBlockData.scaleFactors_exp,
    1311           0 :                                                hTonalMDCTConc->lastBlockData.scaleFactors_max_e,
    1312             :                                                powerSpectrum,
    1313             :                                                powerSpectrum_exp,
    1314             :                                                nSamples,
    1315           0 :                                                hTonalMDCTConc->nSamplesCore,
    1316           0 :                                                extract_l( Mpy_32_16_1( L_mult0( hTonalMDCTConc->nSamples, hTonalMDCTConc->nSamples ), 82 ) ), element_mode, psychParamsCurrent ); /* floorPowerSpectrum */
    1317             :             }
    1318             :         }
    1319             :     }
    1320             :     ELSE
    1321             :     {
    1322         176 :         hTonalMDCTConc->pTCI->numIndexes = 0;
    1323         176 :         move16();
    1324             :     }
    1325             : 
    1326        1601 :     *numIndices = hTonalMDCTConc->pTCI->numIndexes;
    1327        1601 :     move16();
    1328             : 
    1329             : 
    1330        1601 :     return;
    1331             : }
    1332             : 
    1333        8487 : void TonalMDCTConceal_InsertNoise_ivas_fx(
    1334             :     const TonalMDCTConcealPtr hTonalMDCTConc, /*IN */
    1335             :     Word32 *mdctSpectrum,                     // Q31-mdctSpectrum_exp
    1336             :     Word16 *mdctSpectrum_exp,
    1337             :     const Word16 tonalConcealmentActive,
    1338             :     Word16 *pSeed,                              /*IN/OUT*/
    1339             :     const Word16 tiltCompFactor,                // Q15
    1340             :     const Word16 crossfadeGain_const,           // Q15
    1341             :     const Word32 concealment_noise[L_FRAME48k], // Q31-concealment_noise_e
    1342             :     const Word16 concealment_noise_e,
    1343             :     const Word32 cngLevelBackgroundTrace_bfi, // Q31-cngLevelBackgroundTrace_bfi_e
    1344             :     const Word16 cngLevelBackgroundTrace_bfi_e,
    1345             :     const Word16 crossOverFreq ) // Q0
    1346             : {
    1347             :     Word16 i, l, ld, fac;
    1348             :     Word16 rnd;
    1349             : 
    1350             :     Word16 tmp, g, tilt, exp_last, exp_noise, tiltFactor, crossfadeGain, e_crossfadeGain;
    1351             :     Word32 L_tmp, L_tmp1, L_tmp2, nrgNoiseInLastFrame, nrgWhiteNoise;
    1352             :     Word16 inv_exp, inv_samples, exp;
    1353             :     Word32 last_block_nrg_correct;
    1354             :     Word16 last_block_nrg_correct_e;
    1355             :     Word32 max_concealment_value;
    1356             :     Word16 max_spectral_value;
    1357             :     Word64 sum1, sum2;
    1358             :     Word16 num16, den16, exp1, exp2;
    1359             :     Word16 shift1, shift2;
    1360             : 
    1361        8487 :     crossfadeGain = crossfadeGain_const;
    1362        8487 :     move16();
    1363        8487 :     e_crossfadeGain = 0;
    1364        8487 :     move16();
    1365        8487 :     push_wmops( "InsertNoise" );
    1366             : 
    1367        8487 :     g = sub( MAX16B, crossfadeGain );
    1368             : 
    1369        8487 :     IF( !hTonalMDCTConc->lastBlockData.blockIsConcealed )
    1370             :     {
    1371        4616 :         rnd = 1977;
    1372        4616 :         move16();
    1373             :     }
    1374             :     ELSE
    1375             :     {
    1376        3871 :         rnd = *pSeed;
    1377        3871 :         move16();
    1378             :     }
    1379             : 
    1380             :     /* based on what is done in tcx_noise_filling() */
    1381             :     /* always initialize these to avoid compiler warnings */
    1382        8487 :     hTonalMDCTConc->faded_signal_nrg = L_deposit_h( 0 );
    1383        8487 :     move32();
    1384             : 
    1385        8487 :     L_tmp = 805306368l /*0.375f Q31*/;
    1386        8487 :     move32();
    1387        8487 :     inv_exp = 15;
    1388        8487 :     move16();
    1389        8487 :     inv_samples = Inv16( hTonalMDCTConc->lastBlockData.nSamples, &inv_exp );                                                                 // Q31-inv_exp
    1390        8487 :     tiltFactor = round_fx( BASOP_Util_fPow( L_max( L_tmp, L_deposit_h( tiltCompFactor ) ), 0, L_deposit_h( inv_samples ), inv_exp, &exp ) ); // Q15 - exp
    1391             :     BASOP_SATURATE_WARNING_OFF_EVS                                                                                                           /*next op may result in 32768*/
    1392        8487 :         tiltFactor = shl_sat( tiltFactor, exp );                                                                                             // Q15
    1393             :     BASOP_SATURATE_WARNING_ON_EVS
    1394        8487 :     tilt = MAX16B;
    1395        8487 :     move16();
    1396        8487 :     nrgNoiseInLastFrame = L_deposit_h( 0 );
    1397        8487 :     nrgWhiteNoise = L_deposit_h( 0 );
    1398        8487 :     last_block_nrg_correct = L_deposit_h( 0 );
    1399        8487 :     last_block_nrg_correct_e = 0;
    1400        8487 :     move16();
    1401        8487 :     exp_last = exp_noise = 0;
    1402        8487 :     move16();
    1403        8487 :     move16();
    1404             : 
    1405        8487 :     IF( !hTonalMDCTConc->lastBlockData.blockIsValid )
    1406             :     {
    1407             :         /* may just become active if the very first frame is lost */
    1408           0 :         set32_fx( mdctSpectrum, 0, hTonalMDCTConc->nSamples );
    1409             :     }
    1410        8487 :     ELSE IF( concealment_noise != NULL )
    1411             :     {
    1412        3093 :         IF( !tonalConcealmentActive )
    1413             :         {
    1414             :             /* if fadeout has not started yet, only apply sign scrambling */
    1415        3000 :             IF( GE_16( crossfadeGain_const, CROSSFADE_THRESHOLD ) )
    1416             :             {
    1417      573927 :                 FOR( i = 0; i < crossOverFreq; i++ )
    1418             :                 {
    1419      572456 :                     IF( concealment_noise[i] > 0 )
    1420             :                     {
    1421      298346 :                         mdctSpectrum[i] = L_shl( L_deposit_l( hTonalMDCTConc->lastBlockData.spectralData[i] ), 16 ); // Q31-spectralData_exp
    1422      298346 :                         move32();
    1423             :                     }
    1424             :                     ELSE
    1425             :                     {
    1426      274110 :                         mdctSpectrum[i] = L_negate( L_shl( L_deposit_l( hTonalMDCTConc->lastBlockData.spectralData[i] ), 16 ) ); // Q31-spectralData_exp
    1427      274110 :                         move32();
    1428             :                     }
    1429             :                 }
    1430             : 
    1431      371735 :                 FOR( l = crossOverFreq; l < hTonalMDCTConc->lastBlockData.nSamples; l++ )
    1432             :                 {
    1433      370264 :                     mdctSpectrum[l] = 0;
    1434      370264 :                     move32();
    1435             :                 }
    1436             : 
    1437        1471 :                 *mdctSpectrum_exp = hTonalMDCTConc->lastBlockData.spectralData_exp;
    1438        1471 :                 move16();
    1439             :             }
    1440             :             /* actual fadeout is done in this case */
    1441             :             ELSE
    1442             :             {
    1443             :                 Word32 num, den;
    1444             :                 Word16 exp_num, exp_den;
    1445             : 
    1446        1529 :                 exp_num = cngLevelBackgroundTrace_bfi_e;
    1447        1529 :                 move16();
    1448        1529 :                 exp_den = hTonalMDCTConc->curr_noise_nrg_exp;
    1449        1529 :                 move16();
    1450             : 
    1451        1529 :                 ld = norm_l( cngLevelBackgroundTrace_bfi );
    1452        1529 :                 num = L_shl( cngLevelBackgroundTrace_bfi, ld );
    1453        1529 :                 exp_num = sub( exp_num, ld );
    1454        1529 :                 ld = norm_l( hTonalMDCTConc->curr_noise_nrg );
    1455        1529 :                 den = L_shl( hTonalMDCTConc->curr_noise_nrg, ld ); // Q31- curr_noise_nrg_exp + ld
    1456        1529 :                 exp_den = sub( exp_den, ld );
    1457             : 
    1458        1529 :                 exp = sub( exp_num, exp_den );
    1459             : 
    1460        1529 :                 IF( GT_32( num, den ) )
    1461             :                 {
    1462        1489 :                     num = L_shr( num, 1 ); // Q31-exp -1
    1463        1489 :                     exp = add( exp, 1 );
    1464             :                 }
    1465        1529 :                 tmp = div_l( num, round_fx_sat( den ) );
    1466        1529 :                 tmp = Sqrt16( tmp, &exp );
    1467        1529 :                 g = mult_r( g, tmp ); // exponent of g = exp
    1468             : 
    1469        1529 :                 L_tmp = L_deposit_h( 0 );
    1470        1529 :                 exp = sub( hTonalMDCTConc->lastBlockData.spectralData_exp, add( concealment_noise_e, exp ) );
    1471        1529 :                 (void) maximum_abs_32_fx( concealment_noise, crossOverFreq, &max_concealment_value );
    1472        1529 :                 IF( GT_32( max_concealment_value, 0 ) )
    1473             :                 {
    1474         139 :                     IF( exp > 0 )
    1475             :                     {
    1476         121 :                         g = shr( g, exp ); // Q15-exp
    1477         121 :                         *mdctSpectrum_exp = hTonalMDCTConc->lastBlockData.spectralData_exp;
    1478         121 :                         move16();
    1479             :                     }
    1480             :                     ELSE
    1481             :                     {
    1482          18 :                         crossfadeGain = shl( crossfadeGain, exp ); // Q15 - e_crossfadeGain + exp
    1483          18 :                         e_crossfadeGain = sub( e_crossfadeGain, exp );
    1484          18 :                         *mdctSpectrum_exp = sub( hTonalMDCTConc->lastBlockData.spectralData_exp, exp );
    1485          18 :                         move16();
    1486             :                     }
    1487             :                     /*make a headroom for mdct_shaping*/
    1488         139 :                     exp = sub( *mdctSpectrum_exp, SPEC_EXP_DEC );
    1489             :                     /* assert(exp < 0);*/
    1490         139 :                     IF( exp < 0 )
    1491             :                     {
    1492         139 :                         *mdctSpectrum_exp = SPEC_EXP_DEC;
    1493         139 :                         move16();
    1494             :                     }
    1495             :                     ELSE
    1496             :                     {
    1497           0 :                         exp = 0;
    1498           0 :                         move16();
    1499             :                     }
    1500             :                 }
    1501             :                 ELSE
    1502             :                 {
    1503        1390 :                     (void) maximum_abs_16_fx( hTonalMDCTConc->lastBlockData.spectralData, crossOverFreq, &max_spectral_value );
    1504        1390 :                     exp = sub( norm_l( L_mult( max_spectral_value, crossfadeGain ) ), find_guarded_bits_fx( crossOverFreq ) );
    1505        1390 :                     *mdctSpectrum_exp = sub( hTonalMDCTConc->lastBlockData.spectralData_exp, exp );
    1506        1390 :                     move16();
    1507             :                 }
    1508             : 
    1509      584633 :                 FOR( i = 0; i < crossOverFreq; i++ )
    1510             :                 {
    1511      583104 :                     Word16 x = hTonalMDCTConc->lastBlockData.spectralData[i]; // Q15 - spectralData_exp
    1512      583104 :                     move16();
    1513      583104 :                     Word32 y = concealment_noise[i]; // Q31-concealment_noise_e
    1514      583104 :                     move32();
    1515             : 
    1516      583104 :                     IF( g > 0 )
    1517             :                     {
    1518      579936 :                         L_tmp = Mpy_32_16_1( y, g ); // Q31-concealment_noise_e- spectralData_exp
    1519             :                     }
    1520             : 
    1521      583104 :                     L_tmp2 = L_msu( L_tmp, crossfadeGain, x ); // Q15 - e_crossfadeGain + Q15 - spectralData_exp
    1522      583104 :                     IF( y > 0 )
    1523             :                     {
    1524       27948 :                         L_tmp2 = L_mac( L_tmp, crossfadeGain, x ); // Q15 - e_crossfadeGain + Q15 - spectralData_exp
    1525             :                     }
    1526      583104 :                     mdctSpectrum[i] = L_shl( L_tmp2, exp ); // Q15 - e_crossfadeGain + Q15 - spectralData_exp + exp
    1527      583104 :                     move32();
    1528             : 
    1529      583104 :                     hTonalMDCTConc->faded_signal_nrg = L_add( hTonalMDCTConc->faded_signal_nrg, Mpy_32_32( mdctSpectrum[i], mdctSpectrum[i] ) ); // Q31- faded_signal_nrg_exp
    1530      583104 :                     move32();
    1531             :                 }
    1532      402105 :                 FOR( i = crossOverFreq; i < hTonalMDCTConc->lastBlockData.nSamples; i++ )
    1533             :                 {
    1534      400576 :                     mdctSpectrum[i] = 0;
    1535      400576 :                     move32();
    1536             :                 }
    1537        1529 :                 *mdctSpectrum_exp = sub( add( e_crossfadeGain, hTonalMDCTConc->lastBlockData.spectralData_exp ), exp );
    1538        1529 :                 move16();
    1539        1529 :                 hTonalMDCTConc->faded_signal_nrg_exp = shl( *mdctSpectrum_exp, 1 );
    1540        1529 :                 move16();
    1541             :             }
    1542             :         }
    1543             :         ELSE
    1544             :         {
    1545          93 :             assert( hTonalMDCTConc->pTCI->numIndexes > 0 );
    1546             : 
    1547             :             /* initialize bins of tonal components with zero: basically not
    1548             :             necessary, but currently the whole spectrum is rescaled in
    1549             :             mdct_noiseShaping() and then there would be a processing of
    1550             :             uninitialized values */
    1551             : 
    1552          93 :             ld = sub( 14, norm_s( hTonalMDCTConc->lastBlockData.nSamples ) );
    1553          93 :             fac = shr( -32768, ld );
    1554             : 
    1555         754 :             FOR( i = 0; i < hTonalMDCTConc->pTCI->numIndexes; i++ )
    1556             :             {
    1557        5288 :                 FOR( l = hTonalMDCTConc->pTCI->lowerIndex[i]; l <= hTonalMDCTConc->pTCI->upperIndex[i]; l++ )
    1558             :                 {
    1559        4627 :                     mdctSpectrum[l] = L_deposit_h( 0 );
    1560        4627 :                     IF( LT_16( l, crossOverFreq ) )
    1561             :                     {
    1562        4564 :                         Word16 x = hTonalMDCTConc->lastBlockData.spectralData[l];
    1563        4564 :                         move16();
    1564        4564 :                         Word32 y = concealment_noise[l]; // concealment_noise_e
    1565        4564 :                         move32();
    1566        4564 :                         last_block_nrg_correct = L_add( last_block_nrg_correct, Mpy_32_16_1( L_msu( 0, x, fac ), x ) );                                                                                                   // exp = 2 * x_exp + ld
    1567        4564 :                         y = L_negate( Mpy_32_32( y, y ) );                                                                                                                                                                // Q31-2* concealment_noise_e
    1568        4564 :                         hTonalMDCTConc->curr_noise_nrg = BASOP_Util_Add_Mant32Exp( hTonalMDCTConc->curr_noise_nrg, hTonalMDCTConc->curr_noise_nrg_exp, y, 2 * concealment_noise_e, &hTonalMDCTConc->curr_noise_nrg_exp ); // Q31- hTonalMDCTConc->curr_noise_nrg_exp
    1569        4564 :                         move32();
    1570             :                     }
    1571             :                 }
    1572             :             }
    1573          93 :             last_block_nrg_correct_e = add( shl( hTonalMDCTConc->lastBlockData.spectralData_exp, 1 ), ld );
    1574             : 
    1575             :             /* if fadeout has not started yet, only apply sign scrambling */
    1576          93 :             IF( GE_16( crossfadeGain_const, CROSSFADE_THRESHOLD ) )
    1577             :             {
    1578        3868 :                 FOR( l = 0; l < hTonalMDCTConc->pTCI->lowerIndex[0]; l++ )
    1579             :                 {
    1580        3788 :                     IF( GT_32( concealment_noise[l], 0 ) )
    1581             :                     {
    1582        1788 :                         mdctSpectrum[l] = L_shl( L_deposit_l( hTonalMDCTConc->lastBlockData.spectralData[l] ), 16 ); // hTonalMDCTConc->lastBlockData.spectralData_exp
    1583        1788 :                         move32();
    1584             :                     }
    1585             :                     ELSE
    1586             :                     {
    1587        2000 :                         mdctSpectrum[l] = L_negate( L_shl( L_deposit_l( hTonalMDCTConc->lastBlockData.spectralData[l] ), 16 ) ); // hTonalMDCTConc->lastBlockData.spectralData_exp
    1588        2000 :                         move32();
    1589             :                     }
    1590             :                 }
    1591         585 :                 FOR( i = 1; i < hTonalMDCTConc->pTCI->numIndexes; i++ )
    1592             :                 {
    1593        7235 :                     FOR( l = hTonalMDCTConc->pTCI->upperIndex[i - 1] + 1; l < hTonalMDCTConc->pTCI->lowerIndex[i]; l++ )
    1594             :                     {
    1595        6730 :                         IF( concealment_noise[l] > 0 )
    1596             :                         {
    1597        3626 :                             mdctSpectrum[l] = L_shl( L_deposit_l( hTonalMDCTConc->lastBlockData.spectralData[l] ), 16 ); // hTonalMDCTConc->lastBlockData.spectralData_exp
    1598        3626 :                             move32();
    1599             :                         }
    1600             :                         ELSE
    1601             :                         {
    1602        3104 :                             mdctSpectrum[l] = L_negate( L_shl( L_deposit_l( hTonalMDCTConc->lastBlockData.spectralData[l] ), 16 ) ); // hTonalMDCTConc->lastBlockData.spectralData_exp
    1603        3104 :                             move32();
    1604             :                         }
    1605             :                     }
    1606             :                 }
    1607             : 
    1608       18488 :                 FOR( l = hTonalMDCTConc->pTCI->upperIndex[hTonalMDCTConc->pTCI->numIndexes - 1] + 1; l < crossOverFreq; l++ )
    1609             :                 {
    1610       18408 :                     IF( concealment_noise[l] > 0 )
    1611             :                     {
    1612        9487 :                         mdctSpectrum[l] = L_shl( L_deposit_l( hTonalMDCTConc->lastBlockData.spectralData[l] ), 16 ); // hTonalMDCTConc->lastBlockData.spectralData_exp
    1613        9487 :                         move32();
    1614             :                     }
    1615             :                     ELSE
    1616             :                     {
    1617        8921 :                         mdctSpectrum[l] = L_negate( L_shl( L_deposit_l( hTonalMDCTConc->lastBlockData.spectralData[l] ), 16 ) ); // hTonalMDCTConc->lastBlockData.spectralData_exp
    1618        8921 :                         move32();
    1619             :                     }
    1620             :                 }
    1621             : 
    1622       21592 :                 FOR( l = crossOverFreq; l < hTonalMDCTConc->lastBlockData.nSamples; l++ )
    1623             :                 {
    1624       21512 :                     mdctSpectrum[l] = L_shl( L_deposit_l( hTonalMDCTConc->lastBlockData.spectralData[l] ), 16 ); // hTonalMDCTConc->lastBlockData.spectralData_exp
    1625       21512 :                     move32();
    1626             :                 }
    1627             : 
    1628          80 :                 *mdctSpectrum_exp = hTonalMDCTConc->lastBlockData.spectralData_exp;
    1629          80 :                 move16();
    1630             :             }
    1631             :             /* actual fadeout is done in this case */
    1632             :             ELSE
    1633             :             {
    1634             :                 Word32 num, den;
    1635             :                 Word16 exp_num, exp_den;
    1636             : 
    1637          13 :                 exp_num = cngLevelBackgroundTrace_bfi_e;
    1638          13 :                 move16();
    1639          13 :                 exp_den = hTonalMDCTConc->curr_noise_nrg_exp;
    1640          13 :                 move16();
    1641             : 
    1642          13 :                 ld = norm_l( cngLevelBackgroundTrace_bfi );
    1643          13 :                 num = L_shl( cngLevelBackgroundTrace_bfi, ld ); // Q15 - exp_num + ld
    1644          13 :                 exp_num = sub( exp_num, ld );
    1645          13 :                 ld = norm_l( hTonalMDCTConc->curr_noise_nrg );
    1646          13 :                 den = L_shl( hTonalMDCTConc->curr_noise_nrg, ld ); // Q15 - exp_den + ld
    1647          13 :                 exp_den = sub( exp_den, ld );
    1648             : 
    1649          13 :                 exp = sub( exp_num, exp_den );
    1650             : 
    1651          13 :                 IF( GT_32( num, den ) )
    1652             :                 {
    1653          13 :                     num = L_shr( num, 1 ); // Q31- exp -1
    1654          13 :                     exp = add( exp, 1 );
    1655             :                 }
    1656          13 :                 tmp = div_l( num, round_fx( den ) );
    1657          13 :                 tmp = Sqrt16( tmp, &exp );
    1658          13 :                 g = mult_r( g, tmp ); // exponent of g = exp
    1659             : 
    1660          13 :                 L_tmp = L_deposit_h( 0 );
    1661          13 :                 exp = sub( hTonalMDCTConc->lastBlockData.spectralData_exp, add( concealment_noise_e, exp ) );
    1662             : 
    1663          13 :                 (void) maximum_abs_32_fx( concealment_noise, crossOverFreq, &max_concealment_value );
    1664          13 :                 IF( GT_32( max_concealment_value, 0 ) )
    1665             :                 {
    1666           0 :                     IF( GT_16( exp, 0 ) )
    1667             :                     {
    1668           0 :                         g = shr( g, exp ); // Q15- exp
    1669           0 :                         *mdctSpectrum_exp = hTonalMDCTConc->lastBlockData.spectralData_exp;
    1670           0 :                         move16();
    1671             :                     }
    1672             :                     ELSE
    1673             :                     {
    1674           0 :                         crossfadeGain = shl( crossfadeGain, exp ); // Q15 - e_crossfadeGain
    1675           0 :                         e_crossfadeGain = sub( e_crossfadeGain, exp );
    1676           0 :                         *mdctSpectrum_exp = add( e_crossfadeGain, hTonalMDCTConc->lastBlockData.spectralData_exp );
    1677           0 :                         move16();
    1678             :                     }
    1679             :                     /*make a headroom for mdct_shaping*/
    1680           0 :                     exp = sub( *mdctSpectrum_exp, SPEC_EXP_DEC );
    1681             :                     /* assert(exp < 0);*/
    1682           0 :                     IF( exp < 0 )
    1683             :                     {
    1684           0 :                         *mdctSpectrum_exp = SPEC_EXP_DEC;
    1685           0 :                         move16();
    1686             :                     }
    1687             :                     ELSE
    1688             :                     {
    1689           0 :                         exp = 0;
    1690           0 :                         move16();
    1691             :                     }
    1692             :                 }
    1693             :                 ELSE
    1694             :                 {
    1695          13 :                     (void) maximum_abs_16_fx( hTonalMDCTConc->lastBlockData.spectralData, crossOverFreq, &max_spectral_value );
    1696          13 :                     exp = sub( norm_l( L_mult( max_spectral_value, crossfadeGain ) ), find_guarded_bits_fx( crossOverFreq ) );
    1697          13 :                     *mdctSpectrum_exp = sub( hTonalMDCTConc->lastBlockData.spectralData_exp, exp );
    1698          13 :                     move16();
    1699             :                 }
    1700             : 
    1701        1054 :                 FOR( l = 0; l < hTonalMDCTConc->pTCI->lowerIndex[0]; l++ )
    1702             :                 {
    1703        1041 :                     Word16 x = hTonalMDCTConc->lastBlockData.spectralData[l]; // Q15 - spectralData_exp
    1704        1041 :                     move16();
    1705        1041 :                     Word32 y = concealment_noise[l]; // Q31-concealment_noise_e
    1706        1041 :                     move32();
    1707             : 
    1708        1041 :                     IF( g > 0 )
    1709             :                     {
    1710        1041 :                         L_tmp = Mpy_32_16_1( y, g ); // Q31-concealment_noise_e- spectralData_exp
    1711             :                     }
    1712             : 
    1713        1041 :                     L_tmp2 = L_msu( L_tmp, crossfadeGain, x ); // Q15 - e_crossfadeGain + Q15 - spectralData_exp
    1714        1041 :                     IF( y > 0 )
    1715             :                     {
    1716           0 :                         L_tmp2 = L_mac( L_tmp, crossfadeGain, x ); // Q15 - e_crossfadeGain + Q15 - spectralData_exp
    1717             :                     }
    1718        1041 :                     mdctSpectrum[l] = L_shl( L_tmp2, exp ); // Q15 - e_crossfadeGain + Q15 - spectralData_exp + exp
    1719        1041 :                     move32();
    1720             : 
    1721        1041 :                     hTonalMDCTConc->faded_signal_nrg = L_add( hTonalMDCTConc->faded_signal_nrg, Mpy_32_32( mdctSpectrum[l], mdctSpectrum[l] ) ); // Q31 - 2*mdctSpectrum_exp
    1722        1041 :                     move32();
    1723             :                 }
    1724             : 
    1725          76 :                 FOR( i = 1; i < hTonalMDCTConc->pTCI->numIndexes; i++ )
    1726             :                 {
    1727        1201 :                     FOR( l = hTonalMDCTConc->pTCI->upperIndex[i - 1] + 1; l < hTonalMDCTConc->pTCI->lowerIndex[i]; l++ )
    1728             :                     {
    1729        1138 :                         Word16 x = hTonalMDCTConc->lastBlockData.spectralData[l]; // Q15 - spectralData_exp
    1730        1138 :                         move16();
    1731        1138 :                         Word32 y = concealment_noise[l]; // Q31-concealment_noise_e
    1732        1138 :                         move32();
    1733             : 
    1734        1138 :                         L_tmp = Mpy_32_16_1( y, g );
    1735        1138 :                         L_tmp2 = L_msu( L_tmp, crossfadeGain, x ); // Q15 - e_crossfadeGain + Q15 - spectralData_exp
    1736        1138 :                         IF( y > 0 )
    1737             :                         {
    1738           0 :                             L_tmp2 = L_mac( L_tmp, crossfadeGain, x ); // Q15 - e_crossfadeGain + Q15 - spectralData_exp
    1739             :                         }
    1740        1138 :                         mdctSpectrum[l] = L_shl( L_tmp2, exp ); // Q15 - e_crossfadeGain + Q15 - spectralData_exp + exp
    1741        1138 :                         move32();
    1742             : 
    1743        1138 :                         hTonalMDCTConc->faded_signal_nrg = L_add( hTonalMDCTConc->faded_signal_nrg, Mpy_32_32( mdctSpectrum[l], mdctSpectrum[l] ) ); // Q31- 2*mdctSpectrum_exp
    1744             :                     }
    1745             :                 }
    1746             : 
    1747        2902 :                 FOR( l = hTonalMDCTConc->pTCI->upperIndex[hTonalMDCTConc->pTCI->numIndexes - 1] + 1; l < crossOverFreq; l++ )
    1748             :                 {
    1749        2889 :                     Word16 x = hTonalMDCTConc->lastBlockData.spectralData[l]; // Q15 - spectralData_exp
    1750        2889 :                     move16();
    1751        2889 :                     Word32 y = concealment_noise[l]; // Q31-concealment_noise_e
    1752        2889 :                     move32();
    1753             : 
    1754        2889 :                     L_tmp = Mpy_32_16_1( y, g );               // Q31-concealment_noise_e- spectralData_exp
    1755        2889 :                     L_tmp2 = L_msu( L_tmp, crossfadeGain, x ); // Q15 - e_crossfadeGain + Q15 - spectralData_exp
    1756        2889 :                     IF( y > 0 )
    1757             :                     {
    1758           0 :                         L_tmp2 = L_mac( L_tmp, crossfadeGain, x ); // Q15 - e_crossfadeGain + Q15 - spectralData_exp
    1759             :                     }
    1760        2889 :                     mdctSpectrum[l] = L_shl( L_tmp2, exp ); // Q15 - e_crossfadeGain + Q15 - spectralData_exp + exp
    1761        2889 :                     move32();
    1762             : 
    1763        2889 :                     hTonalMDCTConc->faded_signal_nrg = L_add( hTonalMDCTConc->faded_signal_nrg, Mpy_32_32( mdctSpectrum[l], mdctSpectrum[l] ) ); // Q31- 2*mdctSpectrum_exp
    1764        2889 :                     move32();
    1765             :                 }
    1766             : 
    1767        2093 :                 FOR( l = crossOverFreq; l < hTonalMDCTConc->lastBlockData.nSamples; l++ )
    1768             :                 {
    1769        2080 :                     mdctSpectrum[l] = L_deposit_h( 0 );
    1770        2080 :                     move32();
    1771             :                 }
    1772             : 
    1773          13 :                 hTonalMDCTConc->faded_signal_nrg_exp = shl( *mdctSpectrum_exp, 1 );
    1774          13 :                 move16();
    1775             :             }
    1776             :         }
    1777             : 
    1778             :         // Compare curr_noise_nrg with MDCT_ST_PLC_FADEOUT_MIN_NOISE_NRG
    1779             :         Flag flag;
    1780        3093 :         flag = EQ_16( hTonalMDCTConc->curr_noise_nrg_exp, 0 ) && GT_32( hTonalMDCTConc->curr_noise_nrg, MDCT_ST_PLC_FADEOUT_MIN_NOISE_NRG_Q31 );
    1781        3093 :         flag = flag || GT_16( hTonalMDCTConc->curr_noise_nrg_exp, 0 );
    1782        3093 :         test();
    1783        3093 :         IF( GT_32( hTonalMDCTConc->faded_signal_nrg, 0 ) && flag )
    1784             :         {
    1785             :             Word16 num_exp, den_exp;
    1786             :             Word32 num, den;
    1787             : 
    1788          73 :             num = BASOP_Util_Add_Mant32Exp( hTonalMDCTConc->last_block_nrg, hTonalMDCTConc->last_block_nrg_exp, L_negate( last_block_nrg_correct ), last_block_nrg_correct_e, &num_exp ); // Q31-num_exp
    1789             : 
    1790          73 :             den = hTonalMDCTConc->faded_signal_nrg; // Q31 - hTonalMDCTConc->faded_signal_nrg_exp
    1791          73 :             move32();
    1792          73 :             den_exp = hTonalMDCTConc->faded_signal_nrg_exp;
    1793          73 :             move16();
    1794             : 
    1795          73 :             ld = norm_l( num );
    1796          73 :             num = L_shl( num, ld ); // Q31-num_exp + ld
    1797          73 :             num_exp = sub( num_exp, ld );
    1798             : 
    1799          73 :             ld = norm_l( den );
    1800          73 :             den = L_shl( den, ld ); // Q31-den_exp + ld
    1801          73 :             den_exp = sub( den_exp, ld );
    1802             : 
    1803          73 :             exp = sub( num_exp, den_exp );
    1804             : 
    1805          73 :             IF( GT_32( num, den ) )
    1806             :             {
    1807          32 :                 num = L_shr( num, 1 ); // Q31- exp -1
    1808          32 :                 exp = add( exp, 1 );
    1809             :             }
    1810          73 :             tmp = div_l( num, extract_h( den ) );
    1811          73 :             tmp = Sqrt16( tmp, &exp );
    1812             : 
    1813       28105 :             FOR( i = 0; i < crossOverFreq; i++ )
    1814             :             {
    1815       28032 :                 mdctSpectrum[i] = Mpy_32_16_1( mdctSpectrum[i], tmp ); // Q31-(*mdctSpectrum_exp+exp)
    1816       28032 :                 move32();
    1817             :             }
    1818          73 :             *mdctSpectrum_exp = add( *mdctSpectrum_exp, exp );
    1819             :         }
    1820             :     }
    1821             :     ELSE{
    1822        5394 :         IF( tonalConcealmentActive == 0 ){
    1823        5050 :             sum1 = 0;
    1824        5050 :     sum2 = 0;
    1825        5050 :     move64();
    1826        5050 :     move64();
    1827     2340132 :     FOR( i = 0; i < crossOverFreq; i++ )
    1828             :     {
    1829             :         Word16 x;
    1830             :         /*x = hTonalMDCTConc->lastBlockData.spectralData[i];
    1831             :         nrgNoiseInLastFrame += x * x;*/
    1832     2335082 :         sum1 = W_mac0_16_16( sum1, hTonalMDCTConc->lastBlockData.spectralData[i], hTonalMDCTConc->lastBlockData.spectralData[i] ); // Q: 2*(15-hTonalMDCTConc->lastBlockData.spectralData_exp)
    1833             : 
    1834             :         /* rnd = own_random(&rnd); */
    1835     2335082 :         rnd = extract_l( L_mac0( 13849, rnd, 31821 ) ); /* Q0 */
    1836             : 
    1837             :         /* mdctSpectrum[i] = tilt * rnd; */
    1838     2335082 :         mdctSpectrum[i] = L_mult( tilt, rnd ); // Q16
    1839     2335082 :         move32();
    1840             : 
    1841             :         /* tilt *= tiltFactor; */
    1842     2335082 :         tilt = mult_r( tilt, tiltFactor ); /* Q15 */
    1843             : 
    1844             :         /* nrgWhiteNoise += mdctSpectrum[i] * mdctSpectrum[i]; */
    1845     2335082 :         x = round_fx( mdctSpectrum[i] );   // Q0
    1846     2335082 :         sum2 = W_mac0_16_16( sum2, x, x ); // Q0
    1847             :     }
    1848        5050 :     *mdctSpectrum_exp = 15;
    1849        5050 :     move16();
    1850             : 
    1851        5050 :     IF( sum1 /* nrgNoiseInLastFrame */ == 0 )
    1852             :     {
    1853           1 :         set32_fx( mdctSpectrum, 0, crossOverFreq );
    1854           1 :         *mdctSpectrum_exp = SPEC_EXP_DEC;
    1855           1 :         move16();
    1856             :     }
    1857             :     ELSE
    1858             :     {
    1859        5049 :         IF( g == 0 )
    1860             :         {
    1861        3959 :             *mdctSpectrum_exp = add( add( hTonalMDCTConc->lastBlockData.spectralData_exp, e_crossfadeGain ), 31 - SPEC_EXP_DEC );
    1862        3959 :             move16();
    1863     2028471 :             FOR( i = 0; i < crossOverFreq; i++ )
    1864             :             {
    1865             :                 /* mdctSpectrum[i] = g * mdctSpectrum[i] + crossfadeGain * hTonalMDCTConc->lastBlockData.spectralData[i]; */
    1866     2024512 :                 L_tmp = L_mult( crossfadeGain, hTonalMDCTConc->lastBlockData.spectralData[i] ); // exp: hTonalMDCTConc->lastBlockData.spectralData_exp+e_crossfadeGain
    1867     2024512 :                 if ( mdctSpectrum[i] <= 0 )
    1868             :                 {
    1869             :                     /* mdctSpectrum[i] = g * mdctSpectrum[i] - crossfadeGain * hTonalMDCTConc->lastBlockData.spectralData[i]; */
    1870     1013838 :                     L_tmp = L_negate( L_tmp ); // exp: hTonalMDCTConc->lastBlockData.spectralData_exp+e_crossfadeGain
    1871             :                 }
    1872             :                 /* headroom for mdct_shaping */
    1873     2024512 :                 mdctSpectrum[i] = L_shr( L_tmp, 31 - SPEC_EXP_DEC ); // *mdctSpectrum_exp
    1874     2024512 :                 move32();
    1875             :             }
    1876             :         }
    1877             :         ELSE
    1878             :         {
    1879        1090 :             IF( sum2 /* nrgWhiteNoise */ > 0 )
    1880             :             {
    1881        1090 :                 exp1 = sub( W_norm( sum1 ), 1 );
    1882        1090 :                 num16 = extract_h( W_extract_h( W_shl( sum1, exp1 ) ) ); // nrgNoiseInLastFrame -> Q: 2*(15-hTonalMDCTConc->lastBlockData.spectralData_exp)+exp1-48
    1883        1090 :                 exp2 = W_norm( sum2 );
    1884        1090 :                 den16 = extract_h( W_extract_h( W_shl( sum2, exp2 ) ) ); // nrgWhiteNoise -> Q: exp2-48
    1885             : 
    1886             :                 /* sqrt( nrgNoiseInLastFrame / nrgWhiteNoise ) */
    1887        1090 :                 tmp = div_s( num16, den16 );                                                                         // Q: 15+(2*(15-hTonalMDCTConc->lastBlockData.spectralData_exp)+exp1-48)-(exp2-48)
    1888        1090 :                 exp = sub( sub( shl( hTonalMDCTConc->lastBlockData.spectralData_exp, 1 ), 30 ), sub( exp1, exp2 ) ); // exp of tmp
    1889        1090 :                 tmp = Sqrt16( tmp, &exp );
    1890        1090 :                 g = mult_r( g, tmp ); // exponent of g = exp
    1891             :             }
    1892             : 
    1893        1090 :             exp1 = add( *mdctSpectrum_exp, exp );
    1894        1090 :             exp2 = add( hTonalMDCTConc->lastBlockData.spectralData_exp, e_crossfadeGain );
    1895        1090 :             exp = add( s_max( exp1, exp2 ), 1 );
    1896        1090 :             shift1 = sub( exp1, exp );
    1897        1090 :             shift2 = sub( exp2, exp );
    1898             : 
    1899      311340 :             FOR( i = 0; i < crossOverFreq; i++ )
    1900             :             {
    1901      310250 :                 L_tmp1 = L_shl( Mpy_32_16_1( mdctSpectrum[i], g ), shift1 );                                      // g * mdctSpectrum[i]
    1902      310250 :                 L_tmp2 = L_shl( L_mult( crossfadeGain, hTonalMDCTConc->lastBlockData.spectralData[i] ), shift2 ); // exp
    1903             : 
    1904             :                 /* mdctSpectrum[i] = g * mdctSpectrum[i] - crossfadeGain * hTonalMDCTConc->lastBlockData.spectralData[i]; */
    1905      310250 :                 L_tmp = L_sub( L_tmp1, L_tmp2 ); // exp
    1906      310250 :                 if ( mdctSpectrum[i] > 0 )
    1907             :                 {
    1908             :                     /* mdctSpectrum[i] = g * mdctSpectrum[i] + crossfadeGain * hTonalMDCTConc->lastBlockData.spectralData[i]; */
    1909      159166 :                     L_tmp = L_add( L_tmp1, L_tmp2 ); // exp
    1910             :                 }
    1911      310250 :                 mdctSpectrum[i] = L_shr( L_tmp, 31 - SPEC_EXP_DEC ); // exp+31-SPEC_EXP_DEC
    1912      310250 :                 move32();
    1913             :             }
    1914             :             /* headroom for mdct_shaping */
    1915        1090 :             *mdctSpectrum_exp = add( exp, 31 - SPEC_EXP_DEC );
    1916        1090 :             move16();
    1917             :         }
    1918             :     }
    1919        5050 :     exp = sub( hTonalMDCTConc->lastBlockData.spectralData_exp, *mdctSpectrum_exp );
    1920     1306368 :     FOR( i = crossOverFreq; i < hTonalMDCTConc->lastBlockData.nSamples; i++ )
    1921             :     {
    1922     1301318 :         mdctSpectrum[i] = L_shl( L_deposit_h( hTonalMDCTConc->lastBlockData.spectralData[i] ), exp ); // mdctSpectrum_exp
    1923     1301318 :         move32();
    1924             :     }
    1925             : }
    1926             : ELSE
    1927             : {
    1928         344 :     assert( hTonalMDCTConc->pTCI->numIndexes > 0 );
    1929        2743 :     FOR( l = hTonalMDCTConc->pTCI->lowerIndex[0]; l <= hTonalMDCTConc->pTCI->upperIndex[0]; l++ )
    1930             :     {
    1931        2399 :         mdctSpectrum[l] = L_deposit_l( 0 );
    1932             :     }
    1933             : 
    1934         344 :     ld = sub( 14, norm_s( hTonalMDCTConc->lastBlockData.nSamples ) );
    1935         344 :     fac = shr( -32768, ld );
    1936       24154 :     FOR( l = 0; l < hTonalMDCTConc->pTCI->lowerIndex[0]; l++ )
    1937             :     {
    1938       23810 :         Word16 x = hTonalMDCTConc->lastBlockData.spectralData[l]; // Q15 - spectralData_exp
    1939       23810 :         move16();
    1940             :         Word32 y;
    1941             : 
    1942       23810 :         rnd = extract_l( L_mac0( 13849, rnd, 31821 ) ); // Q0
    1943       23810 :         y = L_mult( tilt, rnd );                        // 15Q16
    1944             : 
    1945       23810 :         nrgNoiseInLastFrame = L_add( nrgNoiseInLastFrame, Mpy_32_16_1( L_msu( 0, x, fac ), x ) ); // Q(31 - x_exp - ld) + Q(15 - x_exp) - 15 = Q(31 - x_exp * 2 - ld)
    1946       23810 :         x = round_fx( y );                                                                        // 15Q16 -> Q15
    1947       23810 :         nrgWhiteNoise = L_add( nrgWhiteNoise, Mpy_32_16_1( L_msu( 0, x, fac ), x ) );             // Q(31 - (15 - 0) - ld) + Q(0) - 15 = Q(1 - ld)
    1948             : 
    1949       23810 :         mdctSpectrum[l] = y; /*  15Q16 L_deposit_l(y);*/
    1950       23810 :         move32();
    1951             : 
    1952       23810 :         tilt = mult_r( tilt, tiltFactor ); /* Q15 */
    1953             :     }
    1954             : 
    1955        1629 :     FOR( i = 1; i < hTonalMDCTConc->pTCI->numIndexes; i++ )
    1956             :     {
    1957        1285 :         tmp = round_fx( BASOP_Util_fPow( L_deposit_h( tiltFactor ), 0, L_deposit_h( (UWord16) L_add( L_sub( hTonalMDCTConc->pTCI->upperIndex[i - 1], hTonalMDCTConc->pTCI->lowerIndex[i - 1] ), 1 ) ), 15, &exp ) );
    1958        1285 :         tmp = shl_sat( tmp, exp );
    1959        1285 :         tilt = mult_r( tilt, tmp ); // Q15
    1960             : 
    1961       10250 :         FOR( l = hTonalMDCTConc->pTCI->lowerIndex[i]; l <= hTonalMDCTConc->pTCI->upperIndex[i]; l++ )
    1962             :         {
    1963        8965 :             mdctSpectrum[l] = L_deposit_l( 0 );
    1964        8965 :             move32();
    1965             :         }
    1966       20286 :         FOR( l = hTonalMDCTConc->pTCI->upperIndex[i - 1] + 1; l < hTonalMDCTConc->pTCI->lowerIndex[i]; l++ )
    1967             :         {
    1968       19001 :             Word16 x = hTonalMDCTConc->lastBlockData.spectralData[l]; // Q15 - spectralData_exp
    1969       19001 :             move16();
    1970             :             Word32 y;
    1971             : 
    1972       19001 :             rnd = extract_l( L_mac0( 13849, rnd, 31821 ) ); // Q0
    1973       19001 :             y = L_mult( tilt, rnd );                        // 15Q16
    1974             : 
    1975       19001 :             nrgNoiseInLastFrame = L_add( nrgNoiseInLastFrame, Mpy_32_16_1( L_msu( 0, x, fac ), x ) ); // Q(31 - hTonalMDCTConc->lastBlockData.spectralData_exp * 2 - ld)
    1976       19001 :             x = round_fx( y );                                                                        // Q15
    1977       19001 :             nrgWhiteNoise = L_add( nrgWhiteNoise, Mpy_32_16_1( L_msu( 0, x, fac ), x ) );             // Q(1 - ld)
    1978             : 
    1979       19001 :             mdctSpectrum[l] = y; /*  15Q16 L_deposit_l(y);*/
    1980       19001 :             move32();
    1981             : 
    1982       19001 :             tilt = mult_r( tilt, tiltFactor ); // Q15
    1983             :         }
    1984             :     }
    1985             : 
    1986         344 :     tmp = round_fx( BASOP_Util_fPow( L_deposit_h( tiltFactor ), 0,
    1987         344 :                                      L_deposit_h( extract_l( L_add( L_sub( hTonalMDCTConc->pTCI->upperIndex[hTonalMDCTConc->pTCI->numIndexes - 1], hTonalMDCTConc->pTCI->lowerIndex[hTonalMDCTConc->pTCI->numIndexes - 1] ), 1 ) ) ), 15, &exp ) );
    1988             :     BASOP_SATURATE_WARNING_OFF_EVS /*next op may result in 32768*/
    1989         344 :         tmp = shl_sat( tmp, exp );
    1990             :     BASOP_SATURATE_WARNING_ON_EVS
    1991         344 :     tilt = mult_r( tilt, tmp );
    1992             : 
    1993       97601 :     FOR( l = add( hTonalMDCTConc->pTCI->upperIndex[hTonalMDCTConc->pTCI->numIndexes - 1], 1 ); l < crossOverFreq; l++ )
    1994             :     {
    1995       97257 :         Word16 x = hTonalMDCTConc->lastBlockData.spectralData[l]; // Q15 - spectralData_exp
    1996       97257 :         move16();
    1997             :         Word32 y;
    1998       97257 :         rnd = extract_l( L_mac0( 13849, rnd, 31821 ) ); // Q0
    1999       97257 :         y = L_mult( tilt, rnd );                        // 15Q16
    2000             : 
    2001       97257 :         nrgNoiseInLastFrame = L_add( nrgNoiseInLastFrame, Mpy_32_16_1( L_msu( 0, x, fac ), x ) ); // Q(31 - hTonalMDCTConc->lastBlockData.spectralData_exp * 2 - ld)
    2002       97257 :         x = round_fx( y );                                                                        // Q15
    2003       97257 :         nrgWhiteNoise = L_add( nrgWhiteNoise, Mpy_32_16_1( L_msu( 0, x, fac ), x ) );             // Q(1 - ld)
    2004             : 
    2005       97257 :         mdctSpectrum[l] = y; /*  15Q16 L_deposit_l(y);*/
    2006       97257 :         move32();
    2007             : 
    2008       97257 :         tilt = mult_r( tilt, tiltFactor ); // Q15
    2009             :     }
    2010             : 
    2011         344 :     IF( EQ_32( nrgNoiseInLastFrame, 0 ) )
    2012             :     {
    2013           0 :         set32_fx( mdctSpectrum, 0, crossOverFreq );
    2014           0 :         *mdctSpectrum_exp = SPEC_EXP_DEC;
    2015           0 :         move16();
    2016             :     }
    2017             :     ELSE
    2018             :     {
    2019         344 :         exp_last = add( ld, shl( hTonalMDCTConc->lastBlockData.spectralData_exp, 1 ) );
    2020         344 :         exp_noise = add( ld, shl( 15, 1 ) );
    2021             : 
    2022         344 :         ld = norm_l( nrgNoiseInLastFrame );
    2023         344 :         nrgNoiseInLastFrame = L_shl( nrgNoiseInLastFrame, ld ); // Q31-exp_last+ld
    2024         344 :         exp_last = sub( exp_last, ld );
    2025         344 :         ld = norm_l( nrgWhiteNoise );
    2026         344 :         nrgWhiteNoise = L_shl( nrgWhiteNoise, ld ); // Q31 - exp_noise + ld
    2027         344 :         exp_noise = sub( exp_noise, ld );
    2028             : 
    2029         344 :         exp = sub( exp_last, exp_noise );
    2030             : 
    2031         344 :         IF( GT_32( nrgNoiseInLastFrame, nrgWhiteNoise ) )
    2032             :         {
    2033         189 :             nrgNoiseInLastFrame = L_shr( nrgNoiseInLastFrame, 1 ); // Q31 - Qexp -1
    2034         189 :             exp = add( exp, 1 );
    2035             :         }
    2036         344 :         tmp = div_l( nrgNoiseInLastFrame, extract_h( nrgWhiteNoise ) );
    2037         344 :         tmp = Sqrt16( tmp, &exp );
    2038         344 :         g = mult_r( g, tmp );
    2039             : 
    2040         344 :         L_tmp = L_deposit_h( 0 );
    2041         344 :         ld = sub( hTonalMDCTConc->lastBlockData.spectralData_exp, 15 );
    2042         344 :         exp = sub( ld, exp );
    2043         344 :         IF( exp > 0 )
    2044             :         {
    2045         344 :             g = shr( g, exp ); // Q15 - exp
    2046         344 :             *mdctSpectrum_exp = hTonalMDCTConc->lastBlockData.spectralData_exp;
    2047         344 :             move16();
    2048             :         }
    2049             :         ELSE
    2050             :         {
    2051           0 :             crossfadeGain = shl( crossfadeGain, exp );
    2052           0 :             e_crossfadeGain = sub( e_crossfadeGain, exp );
    2053           0 :             *mdctSpectrum_exp = add( e_crossfadeGain, hTonalMDCTConc->lastBlockData.spectralData_exp );
    2054           0 :             move16();
    2055             :         }
    2056             :         /*make a headroom for mdct_shaping*/
    2057         344 :         exp = sub( *mdctSpectrum_exp, SPEC_EXP_DEC );
    2058             : 
    2059         344 :         IF( exp < 0 )
    2060             :         {
    2061         344 :             *mdctSpectrum_exp = SPEC_EXP_DEC;
    2062         344 :             move16();
    2063             :         }
    2064             :         ELSE
    2065             :         {
    2066           0 :             exp = 0;
    2067           0 :             move16();
    2068             :         }
    2069             : 
    2070       24154 :         FOR( l = 0; l < hTonalMDCTConc->pTCI->lowerIndex[0]; l++ )
    2071             :         {
    2072       23810 :             Word16 const x = hTonalMDCTConc->lastBlockData.spectralData[l]; // Q15 - spectralData_exp
    2073       23810 :             move16();
    2074       23810 :             Word32 const y = mdctSpectrum[l]; // Q31-mdctSpectrum_exp
    2075       23810 :             move32();
    2076             : 
    2077       23810 :             IF( g > 0 )
    2078             :             {
    2079        4827 :                 L_tmp = Mpy_32_16_1( y, g ); // Q31-mdctSpectrum_exp- spectralData_exp
    2080             :             }
    2081             : 
    2082       23810 :             L_tmp2 = L_msu( L_tmp, crossfadeGain, x ); // Q15 - e_crossfadeGain + Q15 - spectralData_exp
    2083       23810 :             IF( y > 0 )
    2084             :             {
    2085       12162 :                 L_tmp2 = L_mac( L_tmp, crossfadeGain, x ); // Q15 - e_crossfadeGain + Q15 - spectralData_exp
    2086             :             }
    2087       23810 :             mdctSpectrum[l] = L_shl( L_tmp2, exp ); // Q15 - e_crossfadeGain + Q15 - spectralData_exp + exp
    2088       23810 :             move32();
    2089             :         }
    2090             : 
    2091        1629 :         FOR( i = 1; i < hTonalMDCTConc->pTCI->numIndexes; i++ )
    2092             :         {
    2093       20286 :             FOR( l = hTonalMDCTConc->pTCI->upperIndex[i - 1] + 1; l < hTonalMDCTConc->pTCI->lowerIndex[i]; l++ )
    2094             :             {
    2095       19001 :                 Word16 const x = hTonalMDCTConc->lastBlockData.spectralData[l]; // Q15 - spectralData_exp
    2096       19001 :                 move16();
    2097       19001 :                 Word32 const y = mdctSpectrum[l]; // Q31-mdctSpectrum_exp
    2098       19001 :                 move32();
    2099             : 
    2100       19001 :                 IF( g > 0 )
    2101             :                 {
    2102        3286 :                     L_tmp = Mpy_32_16_1( y, g ); // Q31-mdctSpectrum_exp- spectralData_exp
    2103             :                 }
    2104             : 
    2105       19001 :                 L_tmp2 = L_msu( L_tmp, crossfadeGain, x ); // Q15 - e_crossfadeGain + Q15 - spectralData_exp
    2106       19001 :                 IF( y > 0 )
    2107             :                 {
    2108       10687 :                     L_tmp2 = L_mac( L_tmp, crossfadeGain, x ); // Q15 - e_crossfadeGain + Q15 - spectralData_exp
    2109             :                 }
    2110       19001 :                 mdctSpectrum[l] = L_shl( L_tmp2, exp ); // Q15 - e_crossfadeGain + Q15 - spectralData_exp + exp
    2111       19001 :                 move32();
    2112             :             }
    2113             :         }
    2114             : 
    2115             :         /* initialize bins of tonal components with zero: basically not
    2116             :            necessary, but currently the whole spectrum is rescaled in
    2117             :            mdct_noiseShaping() and then there would be a processing of
    2118             :            uninitialized values */
    2119        1973 :         FOR( i = 0; i < hTonalMDCTConc->pTCI->numIndexes; i++ )
    2120             :         {
    2121       12993 :             FOR( l = hTonalMDCTConc->pTCI->lowerIndex[i]; l <= hTonalMDCTConc->pTCI->upperIndex[i]; l++ )
    2122             :             {
    2123       11364 :                 mdctSpectrum[l] = L_deposit_l( 0 );
    2124       11364 :                 move32();
    2125             :             }
    2126             :         }
    2127             : 
    2128       97601 :         FOR( l = add( hTonalMDCTConc->pTCI->upperIndex[hTonalMDCTConc->pTCI->numIndexes - 1], 1 ); l < crossOverFreq; l++ )
    2129             :         {
    2130       97257 :             Word16 const x = hTonalMDCTConc->lastBlockData.spectralData[l]; // Q15 - spectralData_exp
    2131       97257 :             move16();
    2132       97257 :             Word32 const y = mdctSpectrum[l]; // Q31-mdctSpectrum_exp
    2133       97257 :             move32();
    2134             : 
    2135       97257 :             IF( GT_16( g, 0 ) )
    2136             :             {
    2137       17188 :                 L_tmp = Mpy_32_16_1( y, g ); // Q31-mdctSpectrum_exp- spectralData_exp
    2138             :             }
    2139             : 
    2140       97257 :             L_tmp2 = L_msu( L_tmp, crossfadeGain, x ); // Q15 - e_crossfadeGain + Q15 - spectralData_exp
    2141       97257 :             IF( GT_32( y, 0 ) )
    2142             :             {
    2143       47852 :                 L_tmp2 = L_mac( L_tmp, crossfadeGain, x ); // Q15 - e_crossfadeGain + Q15 - spectralData_exp
    2144             :             }
    2145       97257 :             mdctSpectrum[l] = L_shl( L_tmp2, exp ); // Q15 - e_crossfadeGain + Q15 - spectralData_exp + exp
    2146       97257 :             move32();
    2147             :         }
    2148             :     }
    2149         344 :     exp = sub( hTonalMDCTConc->lastBlockData.spectralData_exp, sub( *mdctSpectrum_exp, 16 ) );
    2150      155152 :     FOR( l = crossOverFreq; l < hTonalMDCTConc->lastBlockData.nSamples; l++ )
    2151             :     {
    2152      154808 :         mdctSpectrum[l] = L_shl( L_deposit_l( hTonalMDCTConc->lastBlockData.spectralData[l] ), exp ); // Q15 - spectralData_exp
    2153      154808 :         move32();
    2154             :     }
    2155             : }
    2156             : }
    2157             : 
    2158        8487 : *pSeed = rnd;
    2159        8487 : move16();
    2160             : 
    2161        8487 : pop_wmops();
    2162             : 
    2163        8487 : return;
    2164             : }
    2165             : 
    2166             : 
    2167           0 : void TonalMDCTConceal_InsertNoise(
    2168             :     const TonalMDCTConcealPtr hTonalMDCTConc, /*IN */
    2169             :     Word32 *mdctSpectrum,                     // Q31- *mdctSpectrum_exp           /*OUT*/
    2170             :     Word16 *mdctSpectrum_exp,                 /*OUT*/
    2171             :     const Word16 tonalConcealmentActive,
    2172             :     Word16 *pSeed,               /*IN/OUT*/
    2173             :     const Word16 tiltCompFactor, // Q15
    2174             :     Word16 crossfadeGain,        // Q15
    2175             :     const Word16 crossOverFreq )
    2176             : {
    2177             :     Word16 i, ld, fac;
    2178             :     Word16 rnd, exp, exp_last, exp_noise, inv_samples, inv_exp;
    2179             :     Word16 g, tiltFactor, tilt, tmp;
    2180             :     Word32 nrgNoiseInLastFrame, nrgWhiteNoise, L_tmp, L_tmp2;
    2181             : 
    2182           0 :     g = sub( 32767 /*1.0f Q15*/, crossfadeGain );
    2183             : 
    2184           0 :     rnd = 1977;
    2185           0 :     move16();
    2186           0 :     if ( hTonalMDCTConc->lastBlockData.blockIsConcealed )
    2187             :     {
    2188           0 :         rnd = *pSeed;
    2189           0 :         move16();
    2190             :     }
    2191           0 :     IF( hTonalMDCTConc->lastBlockData.blockIsValid == 0 )
    2192             :     {
    2193             :         /* may just become active if the very first frame is lost */
    2194           0 :         set32_fx( mdctSpectrum, 0, hTonalMDCTConc->nSamples );
    2195           0 :         *mdctSpectrum_exp = SPEC_EXP_DEC;
    2196           0 :         move16();
    2197             :     }
    2198             :     ELSE
    2199             :     {
    2200           0 :         L_tmp = 805306368l /*0.375f Q31*/;
    2201           0 :         move32();
    2202           0 :         inv_exp = 15;
    2203           0 :         move16();
    2204           0 :         inv_samples = Inv16( hTonalMDCTConc->lastBlockData.nSamples, &inv_exp );
    2205           0 :         tiltFactor = round_fx( BASOP_Util_fPow( L_max( L_tmp, L_deposit_h( tiltCompFactor ) ), 0, L_deposit_h( inv_samples ), inv_exp, &exp ) );
    2206             :         BASOP_SATURATE_WARNING_OFF_EVS               /*next op may result in 32768*/
    2207           0 :             tiltFactor = shl_sat( tiltFactor, exp ); // Q15- 2*exp
    2208             :         BASOP_SATURATE_WARNING_ON_EVS
    2209             : 
    2210           0 :         tilt = 32767 /*1.0f Q15*/;
    2211           0 :         move16();
    2212             : 
    2213           0 :         nrgNoiseInLastFrame = L_deposit_h( 0 );
    2214           0 :         nrgWhiteNoise = L_deposit_h( 0 );
    2215           0 :         exp_last = exp_noise = 0;
    2216           0 :         move16();
    2217           0 :         move16();
    2218           0 :         IF( !tonalConcealmentActive )
    2219             :         {
    2220           0 :             ld = sub( 14, norm_s( hTonalMDCTConc->lastBlockData.nSamples ) );
    2221           0 :             fac = shr( -32768, ld );
    2222             : 
    2223           0 :             FOR( i = 0; i < crossOverFreq; i++ )
    2224             :             {
    2225           0 :                 Word16 x = hTonalMDCTConc->lastBlockData.spectralData[i]; // Q15 - spectralData_exp
    2226           0 :                 move16();
    2227             :                 Word32 y;
    2228           0 :                 rnd = extract_l( L_mac0( 13849, rnd, 31821 ) ); // Q0
    2229           0 :                 y = L_mult( tilt, rnd );                        /*  15Q16 */
    2230             : 
    2231           0 :                 nrgNoiseInLastFrame = L_add( nrgNoiseInLastFrame, Mpy_32_16_1( L_msu( 0, x, fac ), x ) ); // Q(31 - hTonalMDCTConc->lastBlockData.spectralData_exp * 2 - ld)
    2232           0 :                 x = round_fx( y );                                                                        // Q15
    2233           0 :                 nrgWhiteNoise = L_add( nrgWhiteNoise, Mpy_32_16_1( L_msu( 0, x, fac ), x ) );             // Q(1 - ld)
    2234             : 
    2235           0 :                 mdctSpectrum[i] = y; /*  15Q16 */
    2236           0 :                 move32();
    2237             : 
    2238           0 :                 tilt = mult_r( tilt, tiltFactor ); // Q15
    2239             :             }
    2240             : 
    2241           0 :             IF( nrgNoiseInLastFrame == 0 )
    2242             :             {
    2243           0 :                 set32_fx( mdctSpectrum, 0, crossOverFreq );
    2244           0 :                 *mdctSpectrum_exp = SPEC_EXP_DEC;
    2245           0 :                 move16();
    2246             :             }
    2247             :             ELSE
    2248             :             {
    2249           0 :                 exp_last = add( ld, shl( hTonalMDCTConc->lastBlockData.spectralData_exp, 1 ) );
    2250           0 :                 exp_noise = add( ld, 30 );
    2251             : 
    2252           0 :                 IF( nrgWhiteNoise > 0 )
    2253             :                 {
    2254           0 :                     ld = norm_l( nrgNoiseInLastFrame );
    2255           0 :                     nrgNoiseInLastFrame = L_shl( nrgNoiseInLastFrame, ld ); // Q31-exp_last + ld
    2256           0 :                     exp_last = sub( exp_last, ld );
    2257           0 :                     ld = norm_l( nrgWhiteNoise );
    2258           0 :                     nrgWhiteNoise = L_shl( nrgWhiteNoise, ld ); // Q31-exp_noise + ld
    2259           0 :                     exp_noise = sub( exp_noise, ld );
    2260             : 
    2261           0 :                     exp = sub( exp_last, exp_noise );
    2262             : 
    2263           0 :                     IF( GT_32( nrgNoiseInLastFrame, nrgWhiteNoise ) )
    2264             :                     {
    2265           0 :                         nrgNoiseInLastFrame = L_shr( nrgNoiseInLastFrame, 1 ); // Q31- exp - 1
    2266           0 :                         exp = add( exp, 1 );
    2267             :                     }
    2268           0 :                     tmp = div_l( nrgNoiseInLastFrame, round_fx( nrgWhiteNoise ) );
    2269           0 :                     tmp = Sqrt16( tmp, &exp );
    2270           0 :                     g = mult_r( g, tmp );
    2271             : 
    2272           0 :                     L_tmp = L_deposit_h( 0 );
    2273           0 :                     ld = sub( hTonalMDCTConc->lastBlockData.spectralData_exp, 15 );
    2274           0 :                     exp = sub( ld, exp );
    2275             : 
    2276           0 :                     IF( exp > 0 )
    2277             :                     {
    2278           0 :                         g = shr( g, exp );
    2279           0 :                         *mdctSpectrum_exp = hTonalMDCTConc->lastBlockData.spectralData_exp;
    2280           0 :                         move16();
    2281             :                     }
    2282             :                     ELSE
    2283             :                     {
    2284           0 :                         crossfadeGain = shl( crossfadeGain, exp );
    2285           0 :                         *mdctSpectrum_exp = sub( hTonalMDCTConc->lastBlockData.spectralData_exp, exp );
    2286             :                     }
    2287             :                     /*make a headroom for mdct_shaping*/
    2288           0 :                     exp = sub( *mdctSpectrum_exp, SPEC_EXP_DEC );
    2289             :                     /* assert(exp < 0);*/
    2290           0 :                     IF( exp < 0 )
    2291             :                     {
    2292           0 :                         *mdctSpectrum_exp = SPEC_EXP_DEC;
    2293           0 :                         move16();
    2294             :                     }
    2295             :                     ELSE
    2296             :                     {
    2297           0 :                         exp = 0;
    2298           0 :                         move16();
    2299             :                     }
    2300             :                 }
    2301             : 
    2302           0 :                 FOR( i = 0; i < crossOverFreq; i++ )
    2303             :                 {
    2304           0 :                     Word16 const x = hTonalMDCTConc->lastBlockData.spectralData[i];
    2305           0 :                     move16();
    2306           0 :                     Word32 const y = mdctSpectrum[i]; // Q31-mdctSpectrum_exp
    2307           0 :                     move32();
    2308             : 
    2309           0 :                     if ( g > 0 )
    2310             :                     {
    2311           0 :                         L_tmp = Mpy_32_16_1( y, g ); // Q31-mdctSpectrum_exp- spectralData_exp
    2312             :                     }
    2313             : 
    2314           0 :                     L_tmp2 = L_msu( L_tmp, crossfadeGain, x ); // Q15 - e_crossfadeGain + Q15 - spectralData_exp
    2315           0 :                     if ( y > 0 )
    2316             :                     {
    2317           0 :                         L_tmp2 = L_mac( L_tmp, crossfadeGain, x ); // Q15 - e_crossfadeGain + Q15 - spectralData_exp
    2318             :                     }
    2319           0 :                     mdctSpectrum[i] = L_shl( L_tmp2, exp ); // Q15 - e_crossfadeGain + Q15 - spectralData_exp + exp
    2320           0 :                     move32();
    2321             :                 }
    2322             :             }
    2323           0 :             exp = sub( hTonalMDCTConc->lastBlockData.spectralData_exp, sub( *mdctSpectrum_exp, 16 ) );
    2324           0 :             FOR( i = crossOverFreq; i < hTonalMDCTConc->lastBlockData.nSamples; i++ )
    2325             :             {
    2326           0 :                 mdctSpectrum[i] = L_shl( L_deposit_l( hTonalMDCTConc->lastBlockData.spectralData[i] ), exp ); // Q15 - spectralData_exp + exp
    2327           0 :                 move32();
    2328             :             }
    2329             :         }
    2330             :         ELSE
    2331             :         {
    2332             :             Word16 l;
    2333           0 :             assert( hTonalMDCTConc->pTCI->numIndexes > 0 );
    2334             : 
    2335           0 :             FOR( l = hTonalMDCTConc->pTCI->lowerIndex[0]; l <= hTonalMDCTConc->pTCI->upperIndex[0]; l++ )
    2336             :             {
    2337           0 :                 mdctSpectrum[l] = L_deposit_l( 0 );
    2338           0 :                 move32();
    2339             :             }
    2340             : 
    2341           0 :             ld = sub( 14, norm_s( hTonalMDCTConc->lastBlockData.nSamples ) );
    2342           0 :             fac = shr( -32768, ld );
    2343           0 :             FOR( l = 0; l < hTonalMDCTConc->pTCI->lowerIndex[0]; l++ )
    2344             :             {
    2345           0 :                 Word16 x = hTonalMDCTConc->lastBlockData.spectralData[l]; // Q15 - spectralData_exp
    2346           0 :                 move16();
    2347             :                 Word32 y;
    2348           0 :                 rnd = extract_l( L_mac0( 13849, rnd, 31821 ) ); // Q0
    2349           0 :                 y = L_mult( tilt, rnd );                        // 15Q16
    2350             : 
    2351           0 :                 nrgNoiseInLastFrame = L_add( nrgNoiseInLastFrame, Mpy_32_16_1( L_msu( 0, x, fac ), x ) ); // Q(31 - hTonalMDCTConc->lastBlockData.spectralData_exp * 2 - ld)
    2352           0 :                 x = round_fx( y );                                                                        // Q15
    2353           0 :                 nrgWhiteNoise = L_add( nrgWhiteNoise, Mpy_32_16_1( L_msu( 0, x, fac ), x ) );             // Q(1-ld)
    2354             : 
    2355           0 :                 mdctSpectrum[l] = y; /*  15Q16 L_deposit_l(y);*/
    2356           0 :                 move32();
    2357             : 
    2358           0 :                 tilt = mult_r( tilt, tiltFactor ); // Q15
    2359             :             }
    2360             : 
    2361           0 :             FOR( i = 1; i < hTonalMDCTConc->pTCI->numIndexes; i++ )
    2362             :             {
    2363             :                 /*tilt *= (float)pow(tiltFactor, hTonalMDCTConc->pTCI->upperIndex[i-1]-hTonalMDCTConc->pTCI->lowerIndex[i-1]+1);*/
    2364           0 :                 tmp = round_fx( BASOP_Util_fPow( L_deposit_h( tiltFactor ), 0, L_deposit_h( (UWord16) L_add( L_sub( hTonalMDCTConc->pTCI->upperIndex[i - 1], hTonalMDCTConc->pTCI->lowerIndex[i - 1] ), 1 ) ), 15, &exp ) );
    2365           0 :                 tmp = shl( tmp, exp );
    2366           0 :                 tilt = mult_r( tilt, tmp );
    2367             : 
    2368           0 :                 FOR( l = hTonalMDCTConc->pTCI->lowerIndex[i]; l <= hTonalMDCTConc->pTCI->upperIndex[i]; l++ )
    2369             :                 {
    2370           0 :                     mdctSpectrum[l] = L_deposit_l( 0 );
    2371           0 :                     move32();
    2372             :                 }
    2373             : 
    2374           0 :                 FOR( l = hTonalMDCTConc->pTCI->upperIndex[i - 1] + 1; l < hTonalMDCTConc->pTCI->lowerIndex[i]; l++ )
    2375             :                 {
    2376           0 :                     Word16 x = hTonalMDCTConc->lastBlockData.spectralData[l]; // Q15 - spectralData_exp
    2377           0 :                     move16();
    2378             :                     Word32 y;
    2379           0 :                     rnd = extract_l( L_mac0( 13849, rnd, 31821 ) ); // Q0
    2380           0 :                     y = L_mult( tilt, rnd );                        // 15Q16
    2381             : 
    2382           0 :                     nrgNoiseInLastFrame = L_add( nrgNoiseInLastFrame, Mpy_32_16_1( L_msu( 0, x, fac ), x ) ); // Q(31 - hTonalMDCTConc->lastBlockData.spectralData_exp * 2 - ld)
    2383           0 :                     x = round_fx( y );                                                                        // Q15
    2384           0 :                     nrgWhiteNoise = L_add( nrgWhiteNoise, Mpy_32_16_1( L_msu( 0, x, fac ), x ) );             // Q(1-ld)
    2385             : 
    2386           0 :                     mdctSpectrum[l] = y; /*  15Q16 L_deposit_l(y);*/
    2387           0 :                     move32();
    2388             : 
    2389           0 :                     tilt = mult_r( tilt, tiltFactor ); // Q15
    2390             :                 }
    2391             :             }
    2392             : 
    2393           0 :             tmp = round_fx( BASOP_Util_fPow( L_deposit_h( tiltFactor ), 0, L_deposit_h( (UWord16) L_add( L_sub( hTonalMDCTConc->pTCI->upperIndex[hTonalMDCTConc->pTCI->numIndexes - 1], hTonalMDCTConc->pTCI->lowerIndex[hTonalMDCTConc->pTCI->numIndexes - 1] ), 1 ) ), 15, &exp ) );
    2394             :             BASOP_SATURATE_WARNING_OFF_EVS /*next op may result in 32768*/
    2395           0 :                 tmp = shl_sat( tmp, exp ); // Q15 - 2*exp
    2396             :             BASOP_SATURATE_WARNING_ON_EVS
    2397           0 :             tilt = mult_r( tilt, tmp );
    2398             : 
    2399           0 :             FOR( l = add( hTonalMDCTConc->pTCI->upperIndex[hTonalMDCTConc->pTCI->numIndexes - 1], 1 ); l < crossOverFreq; l++ )
    2400             :             {
    2401           0 :                 Word16 x = hTonalMDCTConc->lastBlockData.spectralData[l]; // Q15 - spectralData_exp
    2402           0 :                 move16();
    2403             :                 Word32 y;
    2404           0 :                 rnd = extract_l( L_mac0( 13849, rnd, 31821 ) ); // Q0
    2405           0 :                 y = L_mult( tilt, rnd );                        // 15Q16
    2406             : 
    2407           0 :                 nrgNoiseInLastFrame = L_add( nrgNoiseInLastFrame, Mpy_32_16_1( L_msu( 0, x, fac ), x ) ); // Q(31 - hTonalMDCTConc->lastBlockData.spectralData_exp * 2 - ld)
    2408           0 :                 x = round_fx( y );                                                                        // Q15
    2409           0 :                 nrgWhiteNoise = L_add( nrgWhiteNoise, Mpy_32_16_1( L_msu( 0, x, fac ), x ) );             // Q(1-ld)
    2410             : 
    2411           0 :                 mdctSpectrum[l] = y; /*  15Q16 L_deposit_l(y);*/
    2412           0 :                 move32();
    2413             : 
    2414           0 :                 tilt = mult_r( tilt, tiltFactor ); // Q15
    2415             :             }
    2416             : 
    2417           0 :             IF( nrgNoiseInLastFrame == 0 )
    2418             :             {
    2419           0 :                 set32_fx( mdctSpectrum, 0, crossOverFreq );
    2420           0 :                 *mdctSpectrum_exp = SPEC_EXP_DEC;
    2421           0 :                 move16();
    2422             :             }
    2423             :             ELSE
    2424             :             {
    2425           0 :                 exp_last = add( ld, shl( hTonalMDCTConc->lastBlockData.spectralData_exp, 1 ) );
    2426           0 :                 exp_noise = add( ld, shl( 15, 1 ) );
    2427             : 
    2428           0 :                 ld = norm_l( nrgNoiseInLastFrame );
    2429           0 :                 nrgNoiseInLastFrame = L_shl( nrgNoiseInLastFrame, ld ); // Q31 - exp_last + ld
    2430           0 :                 exp_last = sub( exp_last, ld );
    2431           0 :                 ld = norm_l( nrgWhiteNoise );
    2432           0 :                 nrgWhiteNoise = L_shl( nrgWhiteNoise, ld ); // Q31 - exp_last + ld
    2433           0 :                 exp_noise = sub( exp_noise, ld );
    2434             : 
    2435           0 :                 exp = sub( exp_last, exp_noise );
    2436             : 
    2437           0 :                 IF( GT_32( nrgNoiseInLastFrame, nrgWhiteNoise ) )
    2438             :                 {
    2439           0 :                     nrgNoiseInLastFrame = L_shr( nrgNoiseInLastFrame, 1 ); // Q31 - exp -1
    2440           0 :                     exp = add( exp, 1 );
    2441             :                 }
    2442           0 :                 tmp = div_l( nrgNoiseInLastFrame, round_fx( nrgWhiteNoise ) );
    2443           0 :                 tmp = Sqrt16( tmp, &exp );
    2444           0 :                 g = mult_r( g, tmp );
    2445             : 
    2446           0 :                 L_tmp = L_deposit_h( 0 );
    2447           0 :                 ld = sub( hTonalMDCTConc->lastBlockData.spectralData_exp, 15 );
    2448           0 :                 exp = sub( ld, exp );
    2449           0 :                 IF( exp > 0 )
    2450             :                 {
    2451           0 :                     g = shr( g, exp );
    2452           0 :                     *mdctSpectrum_exp = hTonalMDCTConc->lastBlockData.spectralData_exp;
    2453           0 :                     move16();
    2454             :                 }
    2455             :                 ELSE
    2456             :                 {
    2457           0 :                     crossfadeGain = shl( crossfadeGain, exp );
    2458           0 :                     *mdctSpectrum_exp = sub( hTonalMDCTConc->lastBlockData.spectralData_exp, exp );
    2459             :                 }
    2460             :                 /*make a headroom for mdct_shaping*/
    2461           0 :                 exp = sub( *mdctSpectrum_exp, SPEC_EXP_DEC );
    2462             : 
    2463             : 
    2464           0 :                 IF( exp < 0 )
    2465             :                 {
    2466           0 :                     *mdctSpectrum_exp = SPEC_EXP_DEC;
    2467           0 :                     move16();
    2468             :                 }
    2469             :                 ELSE
    2470             :                 {
    2471           0 :                     exp = 0;
    2472           0 :                     move16();
    2473             :                 }
    2474             : 
    2475           0 :                 FOR( l = 0; l < hTonalMDCTConc->pTCI->lowerIndex[0]; l++ )
    2476             :                 {
    2477           0 :                     Word16 const x = hTonalMDCTConc->lastBlockData.spectralData[l]; // Q15 - spectralData_exp
    2478           0 :                     move16();
    2479           0 :                     Word32 const y = mdctSpectrum[l]; // Q31-mdctSpectrum_exp
    2480           0 :                     move32();
    2481             : 
    2482           0 :                     if ( g > 0 )
    2483             :                     {
    2484           0 :                         L_tmp = Mpy_32_16_1( y, g ); // Q31-mdctSpectrum_exp- spectralData_exp
    2485             :                     }
    2486             : 
    2487           0 :                     L_tmp2 = L_msu( L_tmp, crossfadeGain, x ); // Q15 - e_crossfadeGain + Q15 - spectralData_exp
    2488           0 :                     if ( y > 0 )
    2489             :                     {
    2490           0 :                         L_tmp2 = L_mac( L_tmp, crossfadeGain, x ); // Q15 - e_crossfadeGain + Q15 - spectralData_exp
    2491             :                     }
    2492           0 :                     mdctSpectrum[l] = L_shl( L_tmp2, exp ); // Q15 - e_crossfadeGain + Q15 - spectralData_exp + exp
    2493           0 :                     move32();
    2494             :                 }
    2495             : 
    2496           0 :                 FOR( i = 1; i < hTonalMDCTConc->pTCI->numIndexes; i++ )
    2497             :                 {
    2498           0 :                     FOR( l = hTonalMDCTConc->pTCI->upperIndex[i - 1] + 1; l < hTonalMDCTConc->pTCI->lowerIndex[i]; l++ )
    2499             :                     {
    2500           0 :                         Word16 const x = hTonalMDCTConc->lastBlockData.spectralData[l]; // Q15 - spectralData_exp
    2501           0 :                         move16();
    2502           0 :                         Word32 const y = mdctSpectrum[l]; // Q31-mdctSpectrum_exp
    2503           0 :                         move32();
    2504             : 
    2505           0 :                         if ( g > 0 )
    2506             :                         {
    2507           0 :                             L_tmp = Mpy_32_16_1( y, g ); // Q31-mdctSpectrum_exp- spectralData_exp
    2508             :                         }
    2509             : 
    2510           0 :                         L_tmp2 = L_msu( L_tmp, crossfadeGain, x ); // Q15 - e_crossfadeGain + Q15 - spectralData_exp
    2511           0 :                         if ( y > 0 )
    2512             :                         {
    2513           0 :                             L_tmp2 = L_mac( L_tmp, crossfadeGain, x ); // Q15 - e_crossfadeGain + Q15 - spectralData_exp
    2514             :                         }
    2515           0 :                         mdctSpectrum[l] = L_shl( L_tmp2, exp ); // Q15 - e_crossfadeGain + Q15 - spectralData_exp + exp
    2516           0 :                         move32();
    2517             :                     }
    2518             :                 }
    2519             : 
    2520             :                 /* initialize bins of tonal components with zero: basically not
    2521             :                    necessary, but currently the whole spectrum is rescaled in
    2522             :                    mdct_noiseShaping() and then there would be a processing of
    2523             :                    uninitialized values */
    2524           0 :                 FOR( i = 0; i < hTonalMDCTConc->pTCI->numIndexes; i++ )
    2525             :                 {
    2526           0 :                     FOR( l = hTonalMDCTConc->pTCI->lowerIndex[i]; l <= hTonalMDCTConc->pTCI->upperIndex[i]; l++ )
    2527             :                     {
    2528           0 :                         mdctSpectrum[l] = L_deposit_l( 0 );
    2529           0 :                         move32();
    2530             :                     }
    2531             :                 }
    2532             : 
    2533           0 :                 FOR( l = add( hTonalMDCTConc->pTCI->upperIndex[hTonalMDCTConc->pTCI->numIndexes - 1], 1 ); l < crossOverFreq; l++ )
    2534             :                 {
    2535           0 :                     Word16 const x = hTonalMDCTConc->lastBlockData.spectralData[l]; // Q15 - spectralData_exp
    2536           0 :                     move16();
    2537           0 :                     Word32 const y = mdctSpectrum[l]; // Q31-mdctSpectrum_exp
    2538           0 :                     move32();
    2539             : 
    2540           0 :                     if ( g > 0 )
    2541             :                     {
    2542           0 :                         L_tmp = Mpy_32_16_1( y, g ); // Q31-mdctSpectrum_exp- spectralData_exp
    2543             :                     }
    2544             : 
    2545           0 :                     L_tmp2 = L_msu( L_tmp, crossfadeGain, x ); // Q15 - e_crossfadeGain + Q15 - spectralData_exp
    2546           0 :                     if ( y > 0 )
    2547             :                     {
    2548           0 :                         L_tmp2 = L_mac( L_tmp, crossfadeGain, x ); // Q15 - e_crossfadeGain + Q15 - spectralData_exp
    2549             :                     }
    2550           0 :                     mdctSpectrum[l] = L_shl( L_tmp2, exp ); // Q15 - e_crossfadeGain + Q15 - spectralData_exp + exp
    2551           0 :                     move32();
    2552             :                 }
    2553             :             }
    2554           0 :             exp = sub( hTonalMDCTConc->lastBlockData.spectralData_exp, sub( *mdctSpectrum_exp, 16 ) );
    2555           0 :             FOR( l = crossOverFreq; l < hTonalMDCTConc->lastBlockData.nSamples; l++ )
    2556             :             {
    2557           0 :                 mdctSpectrum[l] = L_shl( L_deposit_l( hTonalMDCTConc->lastBlockData.spectralData[l] ), exp ); // Q15 - spectralData_exp + exp
    2558           0 :                 move32();
    2559             :             }
    2560             :         }
    2561             :     }
    2562             : 
    2563           0 :     *pSeed = rnd;
    2564           0 :     move16();
    2565             : 
    2566           0 :     return;
    2567             : }
    2568             : 
    2569           0 : void TonalMDCTConceal_Apply(
    2570             :     const TonalMDCTConcealPtr hTonalMDCTConc, /*IN */
    2571             :     Word32 *mdctSpectrum,                     // Q31-*mdctSpectrum_exp                 /*IN/OUT*/
    2572             :     Word16 *mdctSpectrum_exp                  /*IN */
    2573             : #ifdef IVAS_CODE_MDCT_GSHAPE
    2574             :     ,
    2575             :     const PsychoacousticParameters *psychParamsCurrent
    2576             : #endif
    2577             : )
    2578             : {
    2579             :     Word16 i, l, exp;
    2580             :     Word16 *phaseDiff, *pCurrentPhase;
    2581             :     Word32 phaseToAdd, currentPhase;
    2582             :     Word32 powerSpectrum[L_FRAME_MAX];
    2583             :     Word16 nSamples;
    2584             : 
    2585             : 
    2586           0 :     IF( s_and( hTonalMDCTConc->lastBlockData.blockIsValid, hTonalMDCTConc->secondLastBlockData.blockIsValid ) )
    2587             :     {
    2588           0 :         assert( hTonalMDCTConc->pTCI->numIndexes > 0 );
    2589             : 
    2590           0 :         nSamples = hTonalMDCTConc->nNonZeroSamples;
    2591           0 :         move16();
    2592           0 :         assert( hTonalMDCTConc->pTCI->upperIndex[hTonalMDCTConc->pTCI->numIndexes - 1] < nSamples );
    2593             : 
    2594             : #ifdef IVAS_CODE_MDCT_GSHAPE
    2595             :         IF( psychParamsCurrent == NULL )
    2596             : #endif
    2597             :         {
    2598             : 
    2599           0 :             mdct_shaping_16( hTonalMDCTConc->secondLastPowerSpectrum, hTonalMDCTConc->nSamplesCore, nSamples,
    2600           0 :                              hTonalMDCTConc->secondLastBlockData.scaleFactors, hTonalMDCTConc->secondLastBlockData.scaleFactors_exp,
    2601           0 :                              hTonalMDCTConc->secondLastBlockData.scaleFactors_max_e, powerSpectrum );
    2602             :         }
    2603             : #ifdef IVAS_CODE_MDCT_GSHAPE
    2604             :         ELSE
    2605             :         {
    2606             :             sns_shape_spectrum( powerSpectrum, psychParamsCurrent, hTonalMDCTConc->secondLastBlockData.scaleFactors, hTonalMDCTConc->nSamplesCore );
    2607             :             nBands = psychParamsCurrent->nBands;
    2608             :         }
    2609             : #endif
    2610           0 :         phaseDiff = hTonalMDCTConc->pTCI->phaseDiff; /* if multiple frame loss occurs use the phase from the last frame and continue rotating */
    2611           0 :         pCurrentPhase = hTonalMDCTConc->pTCI->phase_currentFramePredicted;
    2612             : 
    2613           0 :         exp = sub( *mdctSpectrum_exp, add( add( hTonalMDCTConc->secondLastPowerSpectrum_exp, add( hTonalMDCTConc->secondLastBlockData.gain_tcx_exp, 1 ) ), hTonalMDCTConc->secondLastBlockData.scaleFactors_max_e ) );
    2614             : 
    2615           0 :         IF( !hTonalMDCTConc->lastBlockData.blockIsConcealed )
    2616             :         {
    2617           0 :             if ( hTonalMDCTConc->secondLastBlockData.tonalConcealmentActive != 0 )
    2618             :             {
    2619           0 :                 hTonalMDCTConc->nFramesLost = add( hTonalMDCTConc->nFramesLost, 2 ); /*Q1*/
    2620           0 :                 move16();
    2621             :             }
    2622           0 :             if ( hTonalMDCTConc->secondLastBlockData.tonalConcealmentActive == 0 )
    2623             :             {
    2624           0 :                 hTonalMDCTConc->nFramesLost = 3; /*Q1*/
    2625           0 :                 move16();
    2626             :             }
    2627             :         }
    2628             :         /* for each index group */
    2629           0 :         FOR( i = 0; i < hTonalMDCTConc->pTCI->numIndexes; i++ )
    2630             :         {
    2631             :             /*phaseToAdd = hTonalMDCTConc->nFramesLost*phaseDiff[i];     */
    2632           0 :             phaseToAdd = L_mult0( hTonalMDCTConc->nFramesLost, phaseDiff[i] ); /*Q1*3Q12=2Q13*/
    2633             :             /* Move phaseToAdd to range -PI..PI */
    2634             : 
    2635           0 :             WHILE( GT_32( phaseToAdd, 25736l /*EVS_PI Q13*/ ) )
    2636             :             {
    2637           0 :                 phaseToAdd = L_sub( phaseToAdd, 51472l /*2*EVS_PI Q13*/ );
    2638             :             }
    2639           0 :             WHILE( LT_32( phaseToAdd, -25736l /*-EVS_PI Q13*/ ) )
    2640             :             {
    2641           0 :                 phaseToAdd = L_add( phaseToAdd, 51472l /*2*EVS_PI Q13*/ );
    2642             :             }
    2643             : 
    2644           0 :             FOR( l = hTonalMDCTConc->pTCI->lowerIndex[i]; l <= hTonalMDCTConc->pTCI->upperIndex[i]; l++ )
    2645             :             {
    2646             :                 /* *pCurrentPhase and phaseToAdd are in range -PI..PI */
    2647           0 :                 currentPhase = L_mac0( phaseToAdd, ( *pCurrentPhase++ ), 1 ); /*2Q13+2Q13=3Q13*/
    2648             : 
    2649           0 :                 if ( GT_32( currentPhase, 25736l /*EVS_PI Q13*/ ) )
    2650             :                 {
    2651           0 :                     currentPhase = L_sub( currentPhase, 51472l /*2*EVS_PI Q13*/ );
    2652             :                 }
    2653           0 :                 if ( LT_32( currentPhase, -25736l /*-EVS_PI Q13*/ ) )
    2654             :                 {
    2655           0 :                     currentPhase = L_add( currentPhase, 51472l /*2*EVS_PI Q13*/ );
    2656             :                 }
    2657             :                 /* getCosWord16 returns 1Q14*/
    2658           0 :                 mdctSpectrum[l] = Mpy_32_16_1( powerSpectrum[l], getCosWord16( extract_l( currentPhase ) ) );
    2659           0 :                 move32();
    2660           0 :                 mdctSpectrum[l] = L_shr( mdctSpectrum[l], exp );
    2661           0 :                 move32();
    2662             :             }
    2663             :         }
    2664             :     }
    2665             : 
    2666           0 :     hTonalMDCTConc->nFramesLost = add( hTonalMDCTConc->nFramesLost, 2 ); /*Q1*/
    2667           0 :     move16();
    2668             : 
    2669           0 :     return;
    2670             : }
    2671             : 
    2672         437 : void TonalMDCTConceal_Apply_ivas_fx(
    2673             :     TonalMDCTConcealPtr hTonalMDCTConc,   /*IN */
    2674             :     Word32 *mdctSpectrum,                 // Q31-*mdctSpectrum_exp              /*IN/OUT*/
    2675             :     Word16 mdctSpectrum_exp[L_FRAME_MAX], /*IN */
    2676             :     const PsychoacousticParameters *psychParamsCurrent )
    2677             : 
    2678             : {
    2679             :     Word16 i, l;
    2680             :     Word16 *phaseDiff, *pCurrentPhase;
    2681             :     Word32 phaseToAdd;
    2682             :     Word32 powerSpectrum[L_FRAME_MAX];
    2683             :     Word16 powerSpectrum_exp;
    2684             :     Word32 scaleFactors[FDNS_NPTS];
    2685             :     Word16 nSamples;
    2686             :     Word16 nBands;
    2687             : 
    2688         437 :     Word16 *tmp_secondLastPowerSpectrum = hTonalMDCTConc->secondLastPowerSpectrum;
    2689         437 :     Word16 tmp_secondLastPowerSpectrum_exp = hTonalMDCTConc->secondLastPowerSpectrum_exp;
    2690         437 :     move16();
    2691             : 
    2692         437 :     Word16 max_nSamples = s_max( hTonalMDCTConc->nNonZeroSamples, hTonalMDCTConc->nSamplesCore );
    2693             : 
    2694             :     // To avoid garbage values
    2695         437 :     set32_fx( powerSpectrum, 0, L_FRAME_MAX );
    2696             : 
    2697             :     /* Creating 32-bit scaleFactors with common exponent. */
    2698       28405 :     FOR( i = 0; i < FDNS_NPTS; i++ )
    2699             :     {
    2700       27968 :         scaleFactors[i] = L_shr( L_deposit_h( hTonalMDCTConc->secondLastBlockData.scaleFactors[i] ), sub( hTonalMDCTConc->secondLastBlockData.scaleFactors_max_e, hTonalMDCTConc->secondLastBlockData.scaleFactors_exp[i] ) ); // Q31- scaleFactors_max_e+scaleFactors_exp[i]
    2701       27968 :         move32();
    2702             :     }
    2703             : 
    2704         437 :     IF( s_and( hTonalMDCTConc->lastBlockData.blockIsValid, hTonalMDCTConc->secondLastBlockData.blockIsValid ) )
    2705             :     {
    2706         437 :         assert( hTonalMDCTConc->pTCI->numIndexes > 0 );
    2707             : 
    2708         437 :         nSamples = hTonalMDCTConc->nNonZeroSamples;
    2709         437 :         move16();
    2710         437 :         assert( hTonalMDCTConc->pTCI->upperIndex[hTonalMDCTConc->pTCI->numIndexes - 1] < nSamples );
    2711             : 
    2712      243524 :         FOR( i = 0; i < nSamples; i++ )
    2713             :         {
    2714      243087 :             powerSpectrum[i] = L_deposit_h( tmp_secondLastPowerSpectrum[i] ); // Q31 - secondLastPowerSpectrum_exp
    2715      243087 :             move16();
    2716             :         }
    2717         437 :         powerSpectrum_exp = tmp_secondLastPowerSpectrum_exp;
    2718         437 :         move16();
    2719             : 
    2720         437 :         Word16 exp1 = powerSpectrum_exp;
    2721         437 :         move16();
    2722             : 
    2723         437 :         IF( psychParamsCurrent == NULL )
    2724             :         {
    2725         182 :             nBands = FDNS_NPTS;
    2726         182 :             move16();
    2727         182 :             mdct_noiseShaping_ivas_fx( powerSpectrum, &powerSpectrum_exp, hTonalMDCTConc->nSamplesCore, hTonalMDCTConc->secondLastBlockData.scaleFactors,
    2728         182 :                                        hTonalMDCTConc->secondLastBlockData.scaleFactors_exp );
    2729             :         }
    2730             :         ELSE
    2731             :         {
    2732             :             Word16 q_ps, q_sf;
    2733         255 :             q_ps = sub( 31, powerSpectrum_exp );
    2734         255 :             q_sf = sub( 31, hTonalMDCTConc->secondLastBlockData.scaleFactors_max_e );
    2735             : 
    2736             :             /* adding guard bit */
    2737         255 :             q_ps = sub( q_ps, 1 );
    2738      143743 :             FOR( Word16 c = 0; c < hTonalMDCTConc->nSamplesCore; c++ )
    2739             :             {
    2740      143488 :                 powerSpectrum[c] = L_shr( powerSpectrum[c], 1 ); // q_ps -1
    2741      143488 :                 move32();
    2742             :             }
    2743             : 
    2744             :             /* adding guard bit */
    2745         255 :             q_sf = sub( q_sf, 1 );
    2746       16575 :             FOR( Word16 c = 0; c < FDNS_NPTS; c++ )
    2747             :             {
    2748       16320 :                 scaleFactors[c] = L_shr( scaleFactors[c], 1 ); // q_sf - 1
    2749       16320 :                 move32();
    2750             :             }
    2751             : 
    2752         255 :             sns_shape_spectrum_fx( powerSpectrum, &q_ps, psychParamsCurrent, scaleFactors, q_sf, hTonalMDCTConc->nSamplesCore, NULL );
    2753             : 
    2754         255 :             powerSpectrum_exp = sub( 31, add( q_ps, 1 ) );
    2755             : 
    2756         255 :             nBands = psychParamsCurrent->nBands;
    2757         255 :             move16();
    2758             :         }
    2759             : 
    2760         437 :         Word16 exp_left = powerSpectrum_exp;
    2761         437 :         move16();
    2762         437 :         Word16 exp_right = exp1;
    2763         437 :         move16();
    2764             : 
    2765       48890 :         FOR( Word16 c = hTonalMDCTConc->nSamplesCore; c < nSamples; c++ )
    2766             :         {
    2767       48453 :             powerSpectrum[c] = Mpy_32_16_1( powerSpectrum[c], hTonalMDCTConc->secondLastBlockData.scaleFactors[nBands - 1] ); // Q31 -(exp_right + scaleFactors_exp[])
    2768       48453 :             move32();
    2769             :         }
    2770         437 :         exp_right = add( exp_right, hTonalMDCTConc->secondLastBlockData.scaleFactors_exp[nBands - 1] );
    2771             : 
    2772         437 :         Word16 max_e = s_max( exp_right, exp_left );
    2773      252602 :         FOR( Word16 c = 0; c < max_nSamples; c++ )
    2774             :         {
    2775      252165 :             test();
    2776      252165 :             test();
    2777      252165 :             test();
    2778      252165 :             test();
    2779      252165 :             IF( GE_16( c, hTonalMDCTConc->nSamplesCore ) && LT_16( c, nSamples ) && GT_16( max_e, exp_right ) )
    2780             :             {
    2781       36746 :                 powerSpectrum[c] = L_shr( powerSpectrum[c], sub( max_e, exp_right ) ); // Q31-max_e
    2782       36746 :                 move32();
    2783             :             }
    2784      215419 :             ELSE IF( ( LT_16( c, hTonalMDCTConc->nSamplesCore ) || GT_16( c, nSamples ) ) && GT_16( max_e, exp_left ) )
    2785             :             {
    2786       29760 :                 powerSpectrum[c] = L_shr( powerSpectrum[c], sub( max_e, exp_left ) ); // Q31-max_e
    2787       29760 :                 move32();
    2788             :             }
    2789             :         }
    2790         437 :         powerSpectrum_exp = max_e;
    2791         437 :         move16();
    2792             : 
    2793         437 :         phaseDiff = hTonalMDCTConc->pTCI->phaseDiff; /* if multiple frame loss occurs use the phase from the last frame and continue rotating */
    2794         437 :         pCurrentPhase = hTonalMDCTConc->pTCI->phase_currentFramePredicted;
    2795             : 
    2796         437 :         IF( !hTonalMDCTConc->lastBlockData.blockIsConcealed )
    2797             :         {
    2798         335 :             if ( hTonalMDCTConc->secondLastBlockData.tonalConcealmentActive != 0 )
    2799             :             {
    2800           0 :                 hTonalMDCTConc->nFramesLost = add( hTonalMDCTConc->nFramesLost, 2 ); /*Q1*/
    2801           0 :                 move16();
    2802             :             }
    2803         335 :             if ( hTonalMDCTConc->secondLastBlockData.tonalConcealmentActive == 0 )
    2804             :             {
    2805         335 :                 hTonalMDCTConc->nFramesLost = 3; /*Q1*/
    2806         335 :                 move16();
    2807             :             }
    2808             :         }
    2809             : 
    2810             :         /* for each index group */
    2811        2727 :         FOR( i = 0; i < hTonalMDCTConc->pTCI->numIndexes; i++ )
    2812             :         {
    2813        2290 :             phaseToAdd = L_mult0( hTonalMDCTConc->nFramesLost, phaseDiff[i] ); /*Q1*3Q12=2Q13*/
    2814             : 
    2815             :             /* Move phaseToAdd to range -PI..PI */
    2816        3070 :             WHILE( GT_32( phaseToAdd, 25736l /*EVS_PI Q13*/ ) )
    2817             :             {
    2818         780 :                 phaseToAdd = L_sub( phaseToAdd, 51472l /*2*EVS_PI Q13*/ );
    2819             :             }
    2820        3853 :             WHILE( LT_32( phaseToAdd, -25736l /*-EVS_PI Q13*/ ) )
    2821             :             {
    2822        1563 :                 phaseToAdd = L_add( phaseToAdd, 51472l /*2*EVS_PI Q13*/ );
    2823             :             }
    2824             : 
    2825       18281 :             FOR( l = hTonalMDCTConc->pTCI->lowerIndex[i]; l <= hTonalMDCTConc->pTCI->upperIndex[i]; l++ )
    2826             :             {
    2827             :                 /* *pCurrentPhase and phaseToAdd are in range -PI..PI */
    2828       15991 :                 Word32 currentPhase = L_mac0( phaseToAdd, ( *pCurrentPhase++ ), 1 ); /*2Q13+2Q13=3Q13*/
    2829       15991 :                 IF( GT_32( currentPhase, 25736l /*EVS_PI Q13*/ ) )
    2830             :                 {
    2831        1766 :                     currentPhase = L_sub( currentPhase, 51472l /*2*EVS_PI Q13*/ );
    2832             :                 }
    2833       15991 :                 IF( LT_32( currentPhase, -25736l /*-EVS_PI Q13*/ ) )
    2834             :                 {
    2835        2448 :                     currentPhase = L_add( currentPhase, 51472l /*2*EVS_PI Q13*/ );
    2836             :                 }
    2837             : 
    2838             :                 /* getCosWord16 returns 1Q14*/
    2839       15991 :                 mdctSpectrum[l] = Mpy_32_16_1( powerSpectrum[l], getCosWord16( extract_l( currentPhase ) ) );
    2840       15991 :                 move32();
    2841       15991 :                 mdctSpectrum_exp[l] = add( powerSpectrum_exp, 1 ); // getCosWord16 returns Q14 (exp is 1)d
    2842       15991 :                 move16();
    2843             :             }
    2844             :         }
    2845             :     }
    2846             : 
    2847         437 :     hTonalMDCTConc->nFramesLost = add( hTonalMDCTConc->nFramesLost, 2 ); /*Q1*/
    2848         437 :     move16();
    2849             : 
    2850         437 :     return;
    2851             : }
    2852             : 
    2853         638 : void TonalMDCTConceal_SaveTimeSignal(
    2854             :     TonalMDCTConcealPtr hTonalMDCTConc,
    2855             :     Word16 *timeSignal, // Qx
    2856             :     Word16 nNewSamples
    2857             : 
    2858             : )
    2859             : {
    2860         638 :     IF( EQ_16( nNewSamples, hTonalMDCTConc->nSamples ) )
    2861             :     {
    2862         638 :         assert( nNewSamples <= L_FRAME_MAX );
    2863         638 :         IF( !hTonalMDCTConc->secondLastBlockData.tonalConcealmentActive )
    2864             :         {
    2865         638 :             Copy( hTonalMDCTConc->lastPcmOut + hTonalMDCTConc->nSamples / 2, hTonalMDCTConc->secondLastPcmOut, hTonalMDCTConc->nSamples / 2 );
    2866             :         }
    2867         638 :         Copy( timeSignal, hTonalMDCTConc->lastPcmOut, hTonalMDCTConc->nSamples );
    2868             :     }
    2869             : 
    2870         638 :     return;
    2871             : }
    2872      840446 : void TonalMDCTConceal_SaveTimeSignal_ivas_fx(
    2873             :     TonalMDCTConcealPtr hTonalMDCTConc,
    2874             :     Word16 *timeSignal, // q_timeSignal
    2875             :     Word16 q_timeSignal,
    2876             :     Word16 nNewSamples )
    2877             : {
    2878      840446 :     IF( EQ_16( nNewSamples, hTonalMDCTConc->nSamples ) )
    2879             :     {
    2880      826500 :         assert( nNewSamples <= L_FRAME_MAX );
    2881      826500 :         IF( !hTonalMDCTConc->secondLastBlockData.tonalConcealmentActive )
    2882             :         {
    2883             :             Word16 exp, len;
    2884      826170 :             len = shr( hTonalMDCTConc->nSamples, 1 );
    2885      826170 :             Copy( hTonalMDCTConc->lastPcmOut + len, hTonalMDCTConc->secondLastPcmOut, len );
    2886      826170 :             exp = sub( q_timeSignal, hTonalMDCTConc->q_lastPcmOut );
    2887      826170 :             IF( exp != 0 )
    2888             :             {
    2889        7882 :                 Scale_sig( hTonalMDCTConc->secondLastPcmOut, len, exp ); // q_timeSignal
    2890             :             }
    2891             :         }
    2892      826500 :         Copy( timeSignal, hTonalMDCTConc->lastPcmOut, hTonalMDCTConc->nSamples );
    2893      826500 :         hTonalMDCTConc->q_lastPcmOut = q_timeSignal;
    2894      826500 :         move16();
    2895             :     }
    2896             : 
    2897      840446 :     return;
    2898             : }
    2899        1425 : static void CalcPowerSpec(
    2900             :     const Word32 *mdctSpec,          /* i: MDCT spectrum Q31-mdctSpec_exp          */
    2901             :     const Word16 mdctSpec_exp,       /* i: exponent of MDCT spectrum               */
    2902             :     const Word32 *mdstSpec,          /* i: MDST spectrum Q31-mdstSpec_exp          */
    2903             :     const Word16 mdstSpec_exp,       /* i: exponent of MDST spectrum               */
    2904             :     const Word16 nSamples,           /* i: frame size                              */
    2905             :     const Word16 floorPowerSpectrum, /* i: lower limit for power spectrum bins Q0  */
    2906             :     Word32 *powerSpec,               /* o: power spectrum       Q31- powerSpec_exp                  */
    2907             :     Word16 *powerSpec_exp )          /* o: exponent of power spectrum              */
    2908             : {
    2909             :     Word16 k, s1, s2, tmp;
    2910             :     Word32 x, L_tmp, L_tmp_floor;
    2911             : 
    2912             : 
    2913        1425 :     k = s_max( mdctSpec_exp, mdstSpec_exp );
    2914        1425 :     *powerSpec_exp = add( add( k, k ), 3 ); /*extra 3 bits of headroom for MA filter in getEnvelope*/
    2915        1425 :     move16();
    2916        1425 :     s1 = sub( *powerSpec_exp, add( mdctSpec_exp, mdctSpec_exp ) );
    2917        1425 :     s2 = sub( *powerSpec_exp, add( mdstSpec_exp, mdstSpec_exp ) );
    2918             : 
    2919        1425 :     k = sub( 31, *powerSpec_exp );
    2920             :     /* If the signal is bellow floor, special care is needed for *powerSpec_exp */
    2921        1425 :     IF( LT_16( add( 16 - 3, norm_s( floorPowerSpectrum ) ), k ) ) /*extra 3 bits of headroom for MA filter in getEnvelope*/
    2922             :     {
    2923          69 :         k = sub( k, add( 16 - 3, norm_s( floorPowerSpectrum ) ) ); /*extra 3 bits of headroom for MA filter in getEnvelope*/
    2924          69 :         *powerSpec_exp = add( *powerSpec_exp, k );
    2925          69 :         s1 = add( s1, k );
    2926          69 :         s2 = add( s2, k );
    2927          69 :         k = add( 16 - 3, norm_s( floorPowerSpectrum ) );
    2928             :     }
    2929        1425 :     L_tmp_floor = L_shl( L_deposit_l( floorPowerSpectrum ), k );
    2930             : 
    2931        1425 :     tmp = sub( nSamples, 2 );
    2932      748501 :     FOR( k = 1; k <= tmp; k++ )
    2933             :     {
    2934      747076 :         x = Mpy_32_32( mdctSpec[k], mdctSpec[k] ); /*Q31,2*mdctSpec_exp*/
    2935             : 
    2936      747076 :         L_tmp = Mpy_32_32( mdstSpec[k], mdstSpec[k] );   /*Q31,2*mdstSpec_exp*/
    2937      747076 :         x = L_add( L_shr( x, s1 ), L_shr( L_tmp, s2 ) ); /*Q31,*powerSpec_exp*/
    2938             : 
    2939      747076 :         powerSpec[k] = L_max( L_tmp_floor, x );
    2940      747076 :         move32();
    2941             :     }
    2942             : 
    2943        1425 :     powerSpec[0] = L_shr( powerSpec[1], 1 );
    2944        1425 :     move32();
    2945        1425 :     powerSpec[nSamples - 1] = L_shr( powerSpec[nSamples - 2], 1 );
    2946        1425 :     move32();
    2947        1425 : }
    2948             : 
    2949             : 
    2950             : /*******************************************************/
    2951             : /*-------------- public functions -------------------- */
    2952             : /*******************************************************/
    2953             : 
    2954        3093 : void TonalMdctConceal_create_concealment_noise_ivas_fx(
    2955             :     Word32 concealment_noise[L_FRAME48k], // Q31-concealment_noise_exp
    2956             :     Word16 *concealment_noise_exp,
    2957             :     CPE_DEC_HANDLE hCPE,
    2958             :     const Word16 L_frameTCX,     // Q0
    2959             :     const Word16 L_frame,        // Q0
    2960             :     const Word16 idchan,         // Q0
    2961             :     const Word16 subframe_idx,   // Q0
    2962             :     const Word16 core,           // Q0
    2963             :     const Word16 crossfade_gain, // Q15
    2964             :     const TONALMDCTCONC_NOISE_GEN_MODE noise_gen_mode )
    2965             : {
    2966             :     STEREO_MDCT_DEC_DATA_HANDLE hStereoMdct;
    2967             :     TonalMDCTConcealPtr hTonalMDCTConc;
    2968             :     Decoder_State *st;
    2969             :     HANDLE_FD_CNG_COM hFdCngCom;
    2970             :     Word16 *rnd_c, *rnd;
    2971             :     Word16 crossOverFreq, i, save_rnd_c, max_noise_line;
    2972             :     Word16 c, c_inv, inc;
    2973             :     Word32 noise_shape_buffer[L_FRAME48k];
    2974             :     Word16 noise_shape_buffer_e[L_FRAME48k];
    2975        3093 :     Word16 start_idx, stop_idx, noise_shape_buffer_common_exp = MIN16B_FLT_FX, last_scf_e, temp_e;
    2976        3093 :     move16();
    2977             :     Word32 *cngNoiseLevelPtr;
    2978             :     Word32 last_scf;
    2979             : 
    2980             :     Word16 c_e, c_inv_e;
    2981             : 
    2982        3093 :     push_wmops( "create_conc_noise" );
    2983             : 
    2984        3093 :     hStereoMdct = hCPE->hStereoMdct;
    2985        3093 :     st = hCPE->hCoreCoder[idchan];
    2986        3093 :     hTonalMDCTConc = st->hTonalMDCTConc;
    2987        3093 :     hFdCngCom = st->hFdCngDec->hFdCngCom;
    2988        3093 :     rnd = &hStereoMdct->noise_seeds_channels[idchan];
    2989        3093 :     rnd_c = &hStereoMdct->noise_seed_common;
    2990             : 
    2991             :     /* determine start bin for IGF */
    2992        3093 :     IF( st->igf == 0 )
    2993             :     {
    2994        1096 :         IF( st->narrowBand == 0 )
    2995             :         {
    2996             :             /* minimum needed for output with sampling rates lower then the
    2997             :                nominal sampling rate */
    2998        1096 :             crossOverFreq = s_min( L_frameTCX, L_frame );
    2999             :         }
    3000             :         ELSE
    3001             :         {
    3002           0 :             crossOverFreq = L_frameTCX;
    3003           0 :             move16();
    3004             :         }
    3005             :     }
    3006             :     ELSE
    3007             :     {
    3008        1997 :         crossOverFreq = s_min( st->hIGFDec->infoIGFStartLine, L_frameTCX );
    3009             :     }
    3010             : 
    3011             :     /* for tonal mdct concealment with tonal components above the crossover frequency, conditionally raise the frequency index until which noise is generated */
    3012        3093 :     max_noise_line = crossOverFreq;
    3013        3093 :     move16();
    3014        3093 :     IF( st->tonal_mdct_plc_active )
    3015             :     {
    3016          93 :         max_noise_line = s_max( max_noise_line, extract_l( L_add( hTonalMDCTConc->pTCI->upperIndex[hTonalMDCTConc->pTCI->numIndexes - 1], 1 ) ) );
    3017             :     }
    3018             : 
    3019             :     /* first lost frame is handled separately */
    3020        3093 :     IF( !hTonalMDCTConc->lastBlockData.blockIsConcealed )
    3021             :     {
    3022        1551 :         *rnd = add( 1977, idchan ); // Q0
    3023        1551 :         move16();
    3024             :         /* will be set twice when looping over two channels, but does not matter */
    3025        1551 :         *rnd_c = 1979; // Q0
    3026        1551 :         move16();
    3027             :     }
    3028             : 
    3029        3093 :     IF( GT_16( crossfade_gain, 32734 ) )
    3030             :     /* Due to precision loss */ /* 0.999 in Q15*/
    3031             :     {
    3032             :         /* In first frame, noise is weighted with zero anyway, we only need the random numbers for the sign scrambling */
    3033      607028 :         FOR( i = 0; i < max_noise_line; i++ )
    3034             :         {
    3035      605477 :             *rnd = own_random( rnd );
    3036      605477 :             move16();
    3037      605477 :             concealment_noise[i] = *rnd; // Q31-concealment_noise_exp
    3038      605477 :             move32();
    3039             :         }
    3040        1551 :         *concealment_noise_exp = 31;
    3041        1551 :         move16();
    3042        1551 :         pop_wmops();
    3043             : 
    3044        1551 :         return;
    3045             :     }
    3046             : 
    3047        1542 :     save_rnd_c = *rnd_c; // Q0
    3048        1542 :     move16();
    3049             : 
    3050        1542 :     c_e = 1;
    3051        1542 :     move16();
    3052        1542 :     c_inv_e = 1;
    3053        1542 :     move16();
    3054             : 
    3055        1542 :     c = Sqrt16( hStereoMdct->lastCoh_fx, &c_e );                            // Q1 = 15 - c_e
    3056        1542 :     c_inv = Sqrt16( sub( ONE_IN_Q14, hStereoMdct->lastCoh_fx ), &c_inv_e ); // Q2 = 15 - c_inv_e
    3057             : 
    3058        1542 :     IF( NE_16( c_e, c_inv_e ) )
    3059             :     {
    3060         467 :         IF( LT_16( c_e, c_inv_e ) )
    3061             :         {
    3062         309 :             c = shr( c, sub( c_inv_e, c_e ) ); // Q0
    3063         309 :             c_e = c_inv_e;
    3064         309 :             move16();
    3065             :         }
    3066             :         ELSE
    3067             :         {
    3068         158 :             c_inv = shr( c_inv, sub( c_e, c_inv_e ) ); // Q0
    3069             :         }
    3070             :     }
    3071             : 
    3072             :     /* pre-compute the noise shape for later weighting of the noise spectra */
    3073        1542 :     cngNoiseLevelPtr = &hFdCngCom->cngNoiseLevel[0];
    3074        1542 :     last_scf_e = hFdCngCom->cngNoiseLevelExp;
    3075        1542 :     move16();
    3076             : 
    3077        1542 :     IF( GT_16( st->core, TCX_20_CORE ) )
    3078             :     {
    3079           8 :         inc = 2;
    3080             :     }
    3081             :     ELSE
    3082             :     {
    3083        1534 :         inc = 1;
    3084             :     }
    3085        1542 :     move16();
    3086        1542 :     start_idx = idiv1616( hFdCngCom->startBand, inc );
    3087        1542 :     stop_idx = idiv1616( hFdCngCom->stopFFTbin, inc );
    3088             : 
    3089        4618 :     FOR( i = 0; i < start_idx; i++ )
    3090             :     {
    3091        3076 :         noise_shape_buffer[i] = 0;
    3092        3076 :         move32();
    3093        3076 :         noise_shape_buffer_e[i] = 0;
    3094        3076 :         move16();
    3095             :     }
    3096      490626 :     FOR( ; i < stop_idx; ( i++, cngNoiseLevelPtr += inc ) )
    3097             :     {
    3098      489084 :         noise_shape_buffer_e[i] = hFdCngCom->cngNoiseLevelExp;
    3099      489084 :         move16();
    3100      489084 :         noise_shape_buffer[i] = Sqrt32( *( cngNoiseLevelPtr ), &noise_shape_buffer_e[i] ); // Q31-noise_shape_buffer_e[i]
    3101      489084 :         move32();
    3102      489084 :         noise_shape_buffer_common_exp = s_max( noise_shape_buffer_e[i], noise_shape_buffer_common_exp );
    3103             :     }
    3104             : 
    3105      493702 :     FOR( i = 0; i < stop_idx; i++ )
    3106             :     {
    3107      492160 :         IF( NE_16( noise_shape_buffer_common_exp, noise_shape_buffer_e[i] ) )
    3108             :         {
    3109             : 
    3110       42044 :             noise_shape_buffer[i] = L_shr( noise_shape_buffer[i], sub( noise_shape_buffer_common_exp, noise_shape_buffer_e[i] ) ); // Q31- (noise_shape_buffer_common_exp-noise_shape_buffer_e[i])
    3111       42044 :             move32();
    3112             :         }
    3113             :     }
    3114             : 
    3115        1542 :     last_scf = Sqrt32( *( cngNoiseLevelPtr - inc ), &last_scf_e ); // Q31-last_scf_e
    3116             : 
    3117        1542 :     IF( LT_16( noise_shape_buffer_common_exp, last_scf_e ) )
    3118             :     {
    3119           0 :         Scale_sig32( noise_shape_buffer, stop_idx, sub( noise_shape_buffer_common_exp, last_scf_e ) ); // Q31- (noise_shape_buffer_common_exp-last_scf_e)
    3120             : 
    3121           0 :         noise_shape_buffer_common_exp = last_scf_e;
    3122           0 :         move16();
    3123             :     }
    3124             :     ELSE
    3125             :     {
    3126        1542 :         last_scf = L_shl( last_scf, sub( last_scf_e, noise_shape_buffer_common_exp ) ); // Q31-(last_scf_e-noise_shape_buffer_common_exp)
    3127             :     }
    3128             : 
    3129       98086 :     FOR( ; i < max_noise_line; i++ )
    3130             :     {
    3131       96544 :         noise_shape_buffer[i] = last_scf; // Q31 - noise_shape_buffer_common_exp
    3132       96544 :         move32();
    3133             :     }
    3134             : 
    3135             :     /* fill the noise vector */
    3136        1542 :     hTonalMDCTConc->curr_noise_nrg = MDCT_ST_PLC_FADEOUT_MIN_NOISE_NRG_Q31; // Q31
    3137        1542 :     move32();
    3138        1542 :     hTonalMDCTConc->curr_noise_nrg_exp = 0;
    3139        1542 :     move16();
    3140        1542 :     *concealment_noise_exp = add( 16, add( noise_shape_buffer_common_exp, c_e ) );
    3141        1542 :     move16();
    3142        1542 :     temp_e = hTonalMDCTConc->curr_noise_nrg_exp;
    3143        1542 :     move16();
    3144             : 
    3145        1542 :     test();
    3146        1542 :     test();
    3147        1542 :     test();
    3148        1542 :     test();
    3149        1542 :     IF( EQ_16( noise_gen_mode, EQUAL_CORES ) || ( ( EQ_16( noise_gen_mode, TCX20_IN_0_TCX10_IN_1 ) && EQ_16( idchan, 0 ) ) || ( EQ_16( noise_gen_mode, TCX10_IN_0_TCX20_IN_1 ) && EQ_16( idchan, 1 ) ) ) )
    3150             :     {
    3151             :         /* current channel is TCX20 -> generate noise for "full-length" spectrum */
    3152             : 
    3153      590246 :         FOR( i = 0; i < max_noise_line; i++ )
    3154             :         {
    3155      588704 :             *rnd = own_random( rnd ); // Q0
    3156      588704 :             *rnd_c = own_random( rnd_c );
    3157             : 
    3158      588704 :             move16();
    3159      588704 :             move16();
    3160             : 
    3161      588704 :             concealment_noise[i] = Mpy_32_32( L_add( L_shr( L_mult( c_inv, *rnd ), 1 ), L_shr( L_mult( c, *rnd_c ), 1 ) ), noise_shape_buffer[i] ); // Q31 - *concealment_noise_exp
    3162      588704 :             move32();
    3163      588704 :             IF( concealment_noise[i] != 0 )
    3164             :             {
    3165       58234 :                 hTonalMDCTConc->curr_noise_nrg = BASOP_Util_Add_Mant32Exp( hTonalMDCTConc->curr_noise_nrg, hTonalMDCTConc->curr_noise_nrg_exp, Mpy_32_32( concealment_noise[i], concealment_noise[i] ), shl( *concealment_noise_exp, 1 ), &temp_e ); // Q31-temp_e
    3166             :             }
    3167      588704 :             hTonalMDCTConc->curr_noise_nrg_exp = temp_e;
    3168      588704 :             move16();
    3169             :         }
    3170             :     }
    3171             :     ELSE /* ( ( noise_gen_mode == TCX10_IN_0_TCX20_IN_1 && idchan == 0 ) || ( noise_gen_mode == TCX20_IN_0_TCX10_IN_1 && idchan == 1 ) )  */
    3172             :     {
    3173             :         /* 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 */
    3174           0 :         FOR( i = 0; i < max_noise_line; i++ )
    3175             :         {
    3176           0 :             *rnd = own_random( rnd );     // Q0
    3177           0 :             *rnd_c = own_random( rnd_c ); // Q0
    3178           0 :             move16();
    3179           0 :             move16();
    3180             : 
    3181           0 :             concealment_noise[i] = Mpy_32_32( L_add( L_shr( L_mult( c_inv, *rnd ), 1 ), L_shr( L_mult( c, *rnd_c ), 1 ) ), noise_shape_buffer[i] );
    3182           0 :             move32();
    3183           0 :             IF( concealment_noise[i] != 0 )
    3184             :             {
    3185           0 :                 hTonalMDCTConc->curr_noise_nrg = BASOP_Util_Add_Mant32Exp( hTonalMDCTConc->curr_noise_nrg, hTonalMDCTConc->curr_noise_nrg_exp, Mpy_32_32( concealment_noise[i], concealment_noise[i] ), shl( *concealment_noise_exp, 1 ), &temp_e ); // Q31-temp_e
    3186             :             }
    3187           0 :             hTonalMDCTConc->curr_noise_nrg_exp = temp_e;
    3188           0 :             move16();
    3189             : 
    3190           0 :             *rnd_c = own_random( rnd_c );
    3191           0 :             move16();
    3192             :         }
    3193             :     }
    3194             : 
    3195        1542 :     IF( st->tonal_mdct_plc_active )
    3196             :     {
    3197          13 :         FOR( i = crossOverFreq; i < s_max( crossOverFreq, hTonalMDCTConc->pTCI->lowerIndex[hTonalMDCTConc->pTCI->numIndexes - 1] ); ++i )
    3198             :         {
    3199           0 :             concealment_noise[i] = 0;
    3200           0 :             move32();
    3201             :         }
    3202             :     }
    3203             : 
    3204             :     /* restore common seed
    3205             :          - after finishing the first channel
    3206             :          - after a first subframe if the current channel is TCX10 */
    3207             : 
    3208        1542 :     test();
    3209        1542 :     test();
    3210        1542 :     test();
    3211        1542 :     test();
    3212        1542 :     test();
    3213        1542 :     IF( ( EQ_16( idchan, 0 ) && ( EQ_16( core, TCX_20 ) || ( EQ_16( core, TCX_10 ) && EQ_16( subframe_idx, 1 ) ) ) ) || ( EQ_16( core, TCX_10 ) && EQ_16( subframe_idx, 0 ) ) )
    3214             :     {
    3215         761 :         *rnd_c = save_rnd_c;
    3216         761 :         move16();
    3217             :     }
    3218             : 
    3219        1542 :     st->seed_tcx_plc = *rnd;
    3220        1542 :     move16();
    3221             : 
    3222        1542 :     pop_wmops();
    3223             : 
    3224        1542 :     return;
    3225             : }
    3226             : 
    3227             : 
    3228        1789 : void TonalMdctConceal_whiten_noise_shape_ivas_fx(
    3229             :     Decoder_State *st,
    3230             :     const Word16 L_frame,
    3231             :     const TONALMDCTCONC_NOISE_SHAPE_WHITENING_MODE whitening_mode )
    3232             : {
    3233             :     Word16 inc, start_idx, stop_idx, i;
    3234             :     Word32 *noiseLevelPtr, *scfs_bg, *scfs_for_shaping;
    3235             :     Word16 noiseLevelPtr_exp;
    3236             :     HANDLE_FD_CNG_COM hFdCngCom;
    3237             :     Word32 whitenend_noise_shape[L_FRAME16k];
    3238             :     Word16 q_wns;
    3239             :     Word32 scfs_int[FDNS_NPTS];
    3240             :     const PsychoacousticParameters *psychParams;
    3241             : 
    3242        1789 :     push_wmops( "apply_sns_on_noise_shape" );
    3243             : 
    3244        1789 :     scfs_bg = &st->hTonalMDCTConc->scaleFactorsBackground_fx[0];
    3245        1789 :     psychParams = st->hTonalMDCTConc->psychParams;
    3246        1789 :     hFdCngCom = st->hFdCngDec->hFdCngCom;
    3247             : 
    3248        1789 :     set32_fx( whitenend_noise_shape, 0, L_FRAME16k );
    3249             : 
    3250        1789 :     IF( EQ_32( whitening_mode, ON_FIRST_LOST_FRAME ) )
    3251             :     {
    3252         304 :         IF( GT_16( st->core, TCX_20_CORE ) )
    3253             :         {
    3254           6 :             inc = 2;
    3255           6 :             move16();
    3256             :         }
    3257             :         ELSE
    3258             :         {
    3259         298 :             inc = 1;
    3260         298 :             move16();
    3261             :         }
    3262             :     }
    3263             :     ELSE
    3264             :     {
    3265        1485 :         IF( GT_16( st->last_core, TCX_20_CORE ) )
    3266             :         {
    3267          19 :             inc = 2;
    3268          19 :             move16();
    3269             :         }
    3270             :         ELSE
    3271             :         {
    3272        1466 :             inc = 1;
    3273        1466 :             move16();
    3274             :         }
    3275             :     }
    3276        1789 :     start_idx = shr( hFdCngCom->startBand, sub( inc, 1 ) );
    3277        1789 :     stop_idx = shr( L_frame, sub( inc, 1 ) );
    3278        1789 :     noiseLevelPtr = hFdCngCom->cngNoiseLevel;
    3279        1789 :     noiseLevelPtr_exp = hFdCngCom->cngNoiseLevelExp;
    3280        1789 :     move16();
    3281             : 
    3282      566716 :     FOR( Word16 j = start_idx; j < stop_idx; j++ )
    3283             :     {
    3284      564927 :         whitenend_noise_shape[j] = L_shr( *noiseLevelPtr, 3 );
    3285      564927 :         move32();
    3286      564927 :         noiseLevelPtr += inc;
    3287             :     }
    3288             : 
    3289        1789 :     IF( EQ_32( whitening_mode, ON_FIRST_LOST_FRAME ) )
    3290             :     {
    3291             :         Word32 scf[SNS_NPTS];
    3292             : 
    3293         304 :         sns_compute_scf_fx( whitenend_noise_shape, psychParams, L_frame, scf, sub( sub( 31, noiseLevelPtr_exp ), 3 ) );
    3294             : 
    3295         304 :         sns_interpolate_scalefactors_fx( scfs_int, scf, ENC );
    3296         304 :         sns_interpolate_scalefactors_fx( scfs_bg, scf, DEC );
    3297             : 
    3298         304 :         scfs_for_shaping = &scfs_int[0]; // Q16
    3299             :     }
    3300             :     ELSE /* whitening_mode == ON_FIRST_GOOD_FRAME */
    3301             :     {
    3302        1485 :         scfs_for_shaping = &scfs_bg[0]; // Q16
    3303             :     }
    3304             : 
    3305        1789 :     IF( sum32_sat( scfs_for_shaping, FDNS_NPTS ) > 0 )
    3306             :     {
    3307         591 :         q_wns = sub( sub( 31, noiseLevelPtr_exp ), 3 );
    3308         591 :         sns_shape_spectrum_fx( whitenend_noise_shape, &q_wns, psychParams, scfs_for_shaping, Q16, L_frame, NULL );
    3309             : 
    3310         591 :         IF( GT_16( add( q_wns, 1 ), sub( 31, hFdCngCom->cngNoiseLevelExp ) ) )
    3311             :         {
    3312      152807 :             FOR( i = 0; i < sub( stop_idx, start_idx ); i++ )
    3313             :             {
    3314      152322 :                 hFdCngCom->cngNoiseLevel[i] = L_shr( whitenend_noise_shape[start_idx + i], sub( add( q_wns, hFdCngCom->cngNoiseLevelExp ), 30 ) ); //(q_wns + 1)
    3315      152322 :                 move32();
    3316             :             }
    3317             :         }
    3318             :         ELSE
    3319             :         {
    3320         106 :             Copy32( whitenend_noise_shape + start_idx, hFdCngCom->cngNoiseLevel, sub( stop_idx, start_idx ) );
    3321             : 
    3322         106 :             scale_sig32( hFdCngCom->cngNoiseLevel + sub( stop_idx, start_idx ), sub( FFTCLDFBLEN, sub( stop_idx, start_idx ) ), sub( add( q_wns, hFdCngCom->cngNoiseLevelExp ), 30 ) );
    3323             : 
    3324         106 :             hFdCngCom->cngNoiseLevelExp = sub( Q30, q_wns ); // Exponent = 31 - (q_wns + 1)
    3325         106 :             move16();
    3326             :         }
    3327             :     }
    3328             :     ELSE
    3329             :     {
    3330        1198 :         set32_fx( hFdCngCom->cngNoiseLevel, 0, sub( stop_idx, start_idx ) );
    3331             :     }
    3332             : 
    3333        1789 :     pop_wmops();
    3334        1789 : }

Generated by: LCOV version 1.14