LCOV - code coverage report
Current view: top level - lib_dec - tonalMDCTconcealment_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main enc/dec/rend @ ca3146eb9de8185ed0247945c643267826a32a94 Lines: 1235 1712 72.1 %
Date: 2025-08-26 01:31:27 Functions: 17 21 81.0 %

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

Generated by: LCOV version 1.14