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

Generated by: LCOV version 1.14