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

Generated by: LCOV version 1.14