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

Generated by: LCOV version 1.14