LCOV - code coverage report
Current view: top level - lib_dec - er_util_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main -- dec/rend @ 633e3f2e309758d10805ef21e0436356fe719b7a Lines: 172 307 56.0 %
Date: 2025-08-23 01:22:27 Functions: 5 7 71.4 %

          Line data    Source code
       1             : /*====================================================================================
       2             :     EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0
       3             :   ====================================================================================*/
       4             : 
       5             : 
       6             : #include <stdint.h>
       7             : #include "options.h"
       8             : #include "prot_fx.h"
       9             : #include "basop_util.h"
      10             : #include <assert.h>
      11             : #include "ivas_prot_fx.h"
      12             : 
      13             : 
      14             : /*  static void setnoiseLevelMemory_fx()
      15             :  *
      16             :  *      Helper function - updates buffer for minimumStatistics_fx function
      17             :  */
      18      351787 : static void setnoiseLevelMemory_fx( Word16 f, Word16 *new_noiseEstimate_e, Word16 *noiseLevelMemory_e, Word16 *noiseLevelMemory, Word16 *currLevelIndex )
      19             : {
      20      351787 :     noiseLevelMemory[*currLevelIndex] = f;
      21      351787 :     move16();
      22      351787 :     noiseLevelMemory_e[*currLevelIndex] = *new_noiseEstimate_e;
      23      351787 :     move16();
      24      351787 : }
      25             : 
      26             : 
      27             : /* PLC: [Common: Fade-out]
      28             :  * PLC: and for PLC fade out */
      29             : 
      30      351787 : void minimumStatistics_fx(
      31             :     Word16 *noiseLevelMemory,       /* Qx, internal state */
      32             :     Word16 *noiseLevelIndex,        /* Q0, internal state */
      33             :     Word16 *currLevelIndex,         /* Q0, internal state (circular buffer) */
      34             :     Word16 *noiseEstimate,          /* Qx, previous estimate of background noise */
      35             :     Word16 *lastFrameLevel,         /* Qx, level of the last frame */
      36             :     Word16 currentFrameLevel,       /* Qx, level of the current frame */
      37             :     Word16 *noiseLevelMemory_e,     /* scaling factor for noiseLevelMemory  */
      38             :     Word16 const noiseEstimate_e,   /* exponent of noiseEstimate */
      39             :     Word16 *new_noiseEstimate_e,    /* new exponent of noise Estimate*/
      40             :     Word16 *const lastFrameLevel_e, /* exponent of lastFrameLevel    */
      41             :     Word16 currentFrameLevel_e )    /* exponent of currentFrameLevel */
      42             : {
      43             :     Word16 aOpt, aOpt_e;
      44             :     Word16 f, p, i;
      45             :     Word16 tmp, tmp2, tmp_e;
      46             :     Word32 tmp32;
      47             : #ifndef ISSUE_1866_replace_overflow_libdec
      48             : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
      49             :     Flag Overflow = 0;
      50             :     move16();
      51             : #endif
      52             : #endif
      53      351787 :     aOpt_e = 0;
      54      351787 :     move16();
      55             : 
      56             : 
      57             :     BASOP_SATURATE_WARNING_OFF_EVS
      58             : #ifdef ISSUE_1866_replace_overflow_libdec
      59      351787 :     IF( LT_16( shl_sat( currentFrameLevel, currentFrameLevel_e ), PLC_MIN_CNG_LEV ) )
      60             : #else
      61             :     IF( LT_16( shl_o( currentFrameLevel, currentFrameLevel_e, &Overflow ), PLC_MIN_CNG_LEV ) )
      62             : #endif
      63             :     {
      64             :         BASOP_SATURATE_WARNING_ON_EVS
      65       68001 :         currentFrameLevel = PLC_MIN_CNG_LEV; /*Q15*/
      66       68001 :         move16();
      67       68001 :         currentFrameLevel_e = 0;
      68       68001 :         move16();
      69             :     }
      70             :     BASOP_SATURATE_WARNING_ON_EVS
      71             : 
      72             :     /* compute optimal factor aOpt for recursive smoothing of frame minima */
      73      351787 :     tmp2 = BASOP_Util_Add_MantExp( *lastFrameLevel, *lastFrameLevel_e, negate( *noiseEstimate ), noiseEstimate_e, &tmp );
      74      351787 :     IF( tmp >= 0 )
      75             :     {
      76             :         /* aOpt = *noiseEstimate / *lastFrameLevel; */
      77      290119 :         aOpt = BASOP_Util_Divide1616_Scale( *noiseEstimate, *lastFrameLevel, &aOpt_e ); /*Q16-aOpt_e*/
      78      290119 :         aOpt_e = add( aOpt_e, sub( noiseEstimate_e, *lastFrameLevel_e ) );
      79             :     }
      80             :     ELSE
      81             :     {
      82             :         /* aOpt = *lastFrameLevel / *noiseEstimate; */
      83       61668 :         aOpt = BASOP_Util_Divide1616_Scale( *lastFrameLevel, *noiseEstimate, &aOpt_e ); /*Q16-aOpt_e*/
      84       61668 :         aOpt_e = add( aOpt_e, sub( *lastFrameLevel_e, noiseEstimate_e ) );
      85             :     }
      86      351787 :     aOpt = mult_r( aOpt, aOpt ); /* Q15 */
      87      351787 :     aOpt_e = shl( aOpt_e, 1 );
      88      351787 :     if ( aOpt == 0 )
      89             :     {
      90           0 :         aOpt_e = 0;
      91           0 :         move16();
      92             :     }
      93             : 
      94      351787 :     *lastFrameLevel = currentFrameLevel; /*Qx*/
      95      351787 :     move16();
      96      351787 :     *lastFrameLevel_e = currentFrameLevel_e;
      97      351787 :     move16();
      98             : 
      99             :     /* recursively compute smoothed frame minima using optimal factor aOpt */
     100      351787 :     tmp = *currLevelIndex;
     101      351787 :     move16();
     102      351787 :     if ( tmp == 0 )
     103             :     {
     104       13904 :         tmp = PLC_MIN_STAT_BUFF_SIZE; /*Q0*/
     105       13904 :         move16();
     106             :     }
     107             :     /*f = msu_r(L_mult(aOpt, noiseLevelMemory[sub(tmp, 1)]),  add(aOpt, 0x8000),  currentFrameLevel);*/
     108             :     /*f = (aOpt * noiseLevelMemory[tmp-1]) - (currentFrameLevel * (aOpt-1))*/
     109             :     /*tmp32*/ /*tmp*/
     110             : 
     111      351787 :     tmp32 = L_mult( aOpt, noiseLevelMemory[sub( tmp, 1 )] ); /*Q_tmp32 = aOpt_e + noiseLevelMemory_e[tmp - 1]*/
     112      351787 :     tmp_e = tmp;
     113      351787 :     move16();
     114             : 
     115             : 
     116      351787 :     tmp2 = BASOP_Util_Add_MantExp( aOpt, aOpt_e, negate( 32768 / 2 ), 1, &tmp );
     117      351787 :     tmp = mult_r( tmp, currentFrameLevel ); /*Q_tmp = tmp2 + currentFrameLevel_e*/
     118      351787 :     tmp2 = add( tmp2, currentFrameLevel_e );
     119             : 
     120      351787 :     if ( tmp == 0 )
     121             :     {
     122       73248 :         tmp2 = 0;
     123       73248 :         move16();
     124             :     }
     125             : 
     126      351787 :     *new_noiseEstimate_e = BASOP_Util_Add_MantExp( round_fx( tmp32 ), add( aOpt_e, noiseLevelMemory_e[sub( tmp_e, 1 )] ), negate( s_max( tmp, -32767 ) /*to avoid negate(-32768)*/ ), tmp2, &f );
     127      351787 :     move16();
     128             : 
     129      351787 :     assert( f >= 0 );
     130             : 
     131             :     /* if current frame min is a new local min, set index to current index */
     132      351787 :     p = *noiseLevelIndex; /*Q0*/
     133      351787 :     move16();
     134      351787 :     tmp2 = BASOP_Util_Add_MantExp( noiseLevelMemory[p], noiseLevelMemory_e[p], negate( f ), *new_noiseEstimate_e, &tmp );
     135      351787 :     IF( tmp >= 0 )
     136             :     {
     137             : 
     138             :         /*rescale noiseLevelMemory*/
     139             : 
     140       88371 :         setnoiseLevelMemory_fx( f, new_noiseEstimate_e, noiseLevelMemory_e, noiseLevelMemory, currLevelIndex );
     141       88371 :         p = *currLevelIndex; /*Q0*/
     142       88371 :         move16();
     143             :     }
     144             :     ELSE
     145             :     {
     146      263416 :         setnoiseLevelMemory_fx( f, new_noiseEstimate_e, noiseLevelMemory_e, noiseLevelMemory, currLevelIndex );
     147             : 
     148             :         /* current min is not a new min, so check if min must be re-searched */
     149      263416 :         IF( NE_16( p, *currLevelIndex ) )
     150             :         {
     151      250296 :             f = noiseLevelMemory[p]; /* min is still in memory, so return it Qx*/
     152      250296 :             move16();
     153      250296 :             *new_noiseEstimate_e = noiseLevelMemory_e[p];
     154      250296 :             move16();
     155             :         }
     156             :         ELSE
     157             :         {
     158             :             /* p == currLevelIndex; min was removed from memory, re-search min */
     159      669120 :             FOR( i = 0; i < PLC_MIN_STAT_BUFF_SIZE; i++ )
     160             :             {
     161      656000 :                 tmp2 = BASOP_Util_Add_MantExp( noiseLevelMemory[p], noiseLevelMemory_e[p], negate( noiseLevelMemory[i] ), noiseLevelMemory_e[i], &tmp );
     162      656000 :                 if ( tmp > 0 )
     163             :                 {
     164       45865 :                     p = i;
     165       45865 :                     move16();
     166             :                 }
     167             :             }
     168       13120 :             f = noiseLevelMemory[p]; /*Qx*/
     169       13120 :             move16();
     170       13120 :             *new_noiseEstimate_e = noiseLevelMemory_e[p];
     171       13120 :             move16();
     172             :         }
     173             :     }
     174             : 
     175             :     /* update local-minimum-value index and current circular-buffer index */
     176      351787 :     *noiseLevelIndex = p; /*Q0*/
     177      351787 :     move16();
     178      351787 :     p = add( *currLevelIndex, 1 );
     179      351787 :     *currLevelIndex = add( *currLevelIndex, 1 ); /*Q0*/
     180      351787 :     move16();
     181      351787 :     if ( EQ_16( *currLevelIndex, PLC_MIN_STAT_BUFF_SIZE ) )
     182             :     {
     183        5548 :         *currLevelIndex = 0;
     184        5548 :         move16();
     185             :     }
     186             : 
     187      351787 :     *noiseEstimate = f; /*Qx*/
     188      351787 :     move16();
     189      351787 : }
     190             : 
     191             : /*----------------------------------------------------------------------*
     192             :  * PLC: [ACELP: Fade-out]
     193             :  * PLC: getLevelSynDeemph_fx: derives on frame or subframe basis the level
     194             :  *      of LPC synthesis and deeemphasis based on the given input
     195             :  *----------------------------------------------------------------------*/
     196        4652 : Word16 getLevelSynDeemph_fx( /*10Q5*/
     197             :                              Word16 h1Init[],
     198             :                              /* i: input value or vector to be processed */ /* Q15 */
     199             :                              Word16 const A[],
     200             :                              /* i: LPC coefficients                      */ /* Qx  */
     201             :                              Word16 const lpcorder,
     202             :                              /* i: LPC order                             */ /* Q0  */
     203             :                              Word16 const lenLpcExc,
     204             :                              /* i: length of the LPC excitation buffer   */ /* Q0  */
     205             :                              Word16 const preemph_fac,
     206             :                              /* i: preemphasis factor                    */ /* Q15 */
     207             :                              Word16 const numLoops,
     208             :                              /* i: number of loops                       */ /* Q0  */
     209             :                              Word16 *Exp                                    /* o: exponent of return value Q15          */
     210             : )
     211             : {
     212             :     Word32 levelSynDeemphSub;
     213             :     Word32 levelSynDeemph;
     214             :     Word16 h1[L_FRAME_PLUS / 4]; /*Q15*/
     215             :     Word16 mem[M];
     216             :     Word16 tmp;
     217             :     Word16 loop;
     218             :     Word16 s16, tmp16, Hr16;
     219             :     Word16 Q_h1;
     220             : 
     221             : 
     222        4652 :     levelSynDeemphSub = L_deposit_l( 0 );
     223        4652 :     levelSynDeemph = L_deposit_l( 0 );
     224        4652 :     tmp = 0;
     225        4652 :     move16();
     226        4652 :     Q_h1 = 9; /*synthesis scaling for */
     227        4652 :     move16();
     228             : 
     229             :     /*calculate headroom for dotproduct*/
     230        4652 :     Hr16 = sub( 15, norm_s( lenLpcExc ) ); /*Q0*/
     231             : 
     232        4652 :     Q_h1 = s_max( sub( Q_h1, Hr16 ), 0 ); /*compensate synthesis scaling with Headroom as much as possible to retain as much precision as possible*/
     233             : 
     234             :     /*Factor to be multiplied in order to calculate dotproduct with headroom*/
     235        4652 :     tmp16 = shr( 32768 / 2, sub( Hr16, 1 ) ); /*Q15*/
     236             : 
     237             :     /*moved from inside loop, before synthesis*/
     238        4652 :     h1Init[0] = mult_r( h1Init[0], tmp16 ); /*Q15*/
     239        4652 :     move16();
     240             : 
     241        9304 :     FOR( loop = 0; loop < numLoops; loop++ )
     242             :     {
     243        4652 :         set16_fx( h1, 0, lenLpcExc );
     244        4652 :         set16_fx( mem, 0, lpcorder );
     245             : 
     246        4652 :         Copy( h1Init, h1, 1 ); /*Q15*/
     247             :         /*h1 will be scaled down, Q_h1 */
     248        4652 :         E_UTIL_synthesis( Q_h1, A, h1, h1, lenLpcExc, mem, 0, lpcorder );
     249        4652 :         deemph_fx( h1, preemph_fac, lenLpcExc, &tmp );
     250        4652 :         A += ( M + 1 );
     251             : 
     252             :         /* gain introduced by synthesis+deemphasis */
     253             :         /*levelSynDeemphSub = (float)sqrt(dot_product( h1, h1, lenLpcExc));*/
     254        4652 :         levelSynDeemphSub = Dot_product12_offs( h1, h1, lenLpcExc, &s16, 0 ); /*Q31 - s16*/
     255        4652 :         s16 = sub( shl( add( Q_h1, Hr16 ), 1 ), sub( 30, s16 ) );
     256             : 
     257        4652 :         levelSynDeemphSub = Sqrt32( levelSynDeemphSub, &s16 ); /*Q31 - s16*/
     258             : 
     259             :         /* mean of the above across all subframes  -- moved outta loop*/
     260             :         /*levelSynDeemph += (1.0/(float)numLoops) * levelSynDeemphSub;*/
     261        4652 :         tmp16 = 32767 /*1.0f Q15*/;
     262        4652 :         move16();
     263             : 
     264        4652 :         if ( GT_16( numLoops, 1 ) )
     265             :         {
     266           0 :             tmp16 = div_s( 1, numLoops ); /*Q15*/
     267             :         }
     268             : 
     269        4652 :         levelSynDeemph = L_add( levelSynDeemph, L_shl( Mpy_32_16_1( levelSynDeemphSub, tmp16 ), sub( s16, 10 ) ) ); /*10Q21*/
     270             :     }
     271        4652 :     s16 = norm_l( levelSynDeemph );
     272        4652 :     levelSynDeemph = L_shl( levelSynDeemph, s16 ); /*Q31*/
     273        4652 :     *Exp = sub( 10, s16 );                         /*Set exponent in order to transform returnvalue to Q15*/
     274        4652 :     move16();
     275             : 
     276        4652 :     return round_fx_sat( levelSynDeemph ); /*Q15*/
     277             : }
     278             : 
     279             : /* BASOP version: up to date with rev 7422 */
     280           0 : void genPlcFiltBWAdap_fx(
     281             :     const Word32 sr_core, /* i  : core sampling rate                                         Q0*/
     282             :     Word16 *lpFiltAdapt,  /* o  : filter coefficients for filtering codebooks in case of flc Q15*/
     283             :     const Word16 type,    /* i  : type of filter, either 0 : lowpass or 1 : highpass         Q0*/
     284             :     const Word16 alpha    /* i  : fade out factor [0 1) used decrease filter tilt            Q15*/
     285             : )
     286             : {
     287             :     Word16 a, b, exp;
     288             : 
     289             : 
     290           0 :     assert( type == 0 || type == 1 );
     291             : 
     292           0 :     IF( EQ_32( sr_core, INT_FS_16k ) )
     293             :     {
     294           0 :         IF( type == 0 )
     295             :         {
     296           0 :             *lpFiltAdapt++ = 7282 /*  0.4000f/(2.f*0.4000f+1.f) Q15*/;
     297           0 :             move16();
     298           0 :             *lpFiltAdapt++ = 18204 /*      1.f/(2.f*0.4000f+1.f) Q15*/;
     299           0 :             move16();
     300           0 :             *lpFiltAdapt = 7282 /*  0.4000f/(2.f*0.4000f+1.f) Q15*/;
     301           0 :             move16();
     302             :         }
     303             :         ELSE
     304             :         {
     305           0 :             a = mult_r( 13107 /*0.4000f Q15*/, alpha ); /*Q15*/
     306           0 :             exp = 0;
     307           0 :             move16();
     308           0 :             b = Inv16( add( a, 16384 /*0.5f Q15*/ ), &exp ); /*Q15 - exp*/
     309           0 :             b = shr( b, sub( 1, exp ) );                     /*Q15*/
     310           0 :             a = negate( mult_r( a, b ) );                    /*Q15*/
     311           0 :             *lpFiltAdapt++ = a;                              /*Q15*/
     312           0 :             move16();
     313           0 :             *lpFiltAdapt++ = b; /*Q15*/
     314           0 :             move16();
     315           0 :             *lpFiltAdapt = a; /*Q15*/
     316           0 :             move16();
     317             :         }
     318             :     }
     319             :     ELSE /*sr_core = INT_FS_12k8 */
     320             :     {
     321           0 :         IF( type == 0 )
     322             :         {
     323           0 :             *lpFiltAdapt++ = 5899 /*  0.2813f/(2.f*0.2813f+1.f) Q15*/;
     324           0 :             move16();
     325           0 :             *lpFiltAdapt++ = 20970 /*      1.f/(2.f*0.2813f+1.f) Q15*/;
     326           0 :             move16();
     327           0 :             *lpFiltAdapt = 5899 /*  0.2813f/(2.f*0.2813f+1.f) Q15*/;
     328           0 :             move16();
     329             :         }
     330             :         ELSE
     331             :         {
     332           0 :             a = mult_r( 9218 /*0.2813f Q15*/, alpha ); /*Q15*/
     333           0 :             exp = 0;
     334           0 :             move16();
     335           0 :             b = Inv16( add( a, 16384 /*0.5f Q15*/ ), &exp ); /*Q15 - exp*/
     336           0 :             b = shr( b, sub( 1, exp ) );                     /*Q15*/
     337           0 :             a = negate( mult_r( a, b ) );                    /*Q15*/
     338           0 :             *lpFiltAdapt++ = a;                              /*Q15*/
     339           0 :             move16();
     340           0 :             *lpFiltAdapt++ = b; /*Q15*/
     341           0 :             move16();
     342           0 :             *lpFiltAdapt = a; /*Q15*/
     343           0 :             move16();
     344             :         }
     345             :     }
     346           0 : }
     347             : 
     348             : 
     349             : /*-----------------------------------------------------------------*
     350             :  * PLC: [ACELP: general]
     351             :  * PLC: high pass filtering
     352             :  *-----------------------------------------------------------------*/
     353             : /*VERSIONINFO: This port is up to date with trunk rev. 32434*/
     354        2360 : void highPassFiltering_fx(
     355             :     const Word16 last_good,  /* i:   short  last classification type                            Q0*/
     356             :     const Word16 L_buffer,   /* i:   int    buffer length                                       Q0*/
     357             :     Word16 exc2[],           /* i/o: Qx     unvoiced excitation before the high pass filtering  */
     358             :     const Word16 hp_filt[],  /* i:   Q15    high pass filter coefficients                       */
     359             :     const Word16 l_fir_fer ) /* i:        high pass filter length                               Q0*/
     360             : 
     361             : {
     362             :     Word16 i; /*int*/
     363             : 
     364        2360 :     IF( GT_16( last_good, UNVOICED_TRANSITION ) )
     365             :     {
     366     2593440 :         FOR( i = 0; i < L_buffer; i++ )
     367             :         {
     368     2591080 :             exc2[i] = round_fx( L_sub( Dot_product( &exc2[i], hp_filt, l_fir_fer ), 1 ) ); /*Qx*/
     369     2591080 :             move16();
     370             :         }
     371             :     }
     372        2360 : }
     373             : 
     374             : /*----------------------------------------------------------------------------------*
     375             :  * PLC: [Common: mode decision]
     376             :  * PLC: Decide which Concealment to use. Update pitch lags if needed
     377             :  *----------------------------------------------------------------------------------*/
     378       13326 : Word16 GetPLCModeDecision_ivas_fx(
     379             :     Decoder_State *st /* i/o:    decoder memory state pointer */
     380             : )
     381             : {
     382             :     Word16 /*int*/ core;
     383       13326 :     Word16 numIndices = 0;
     384             :     TCX_DEC_HANDLE hTcxDec;
     385             : 
     386       13326 :     hTcxDec = st->hTcxDec;
     387             : 
     388       13326 :     IF( EQ_16( st->flagGuidedAcelp, 1 ) )
     389             :     {
     390           0 :         st->old_pitch_buf_fx[( st->nb_subfr * 2 )] = L_deposit_h( st->guidedT0 ); /*Q16*/
     391           0 :         move32();
     392           0 :         st->old_pitch_buf_fx[( ( st->nb_subfr * 2 ) + 1 )] = L_deposit_h( st->guidedT0 ); /*Q16*/
     393           0 :         move32();
     394           0 :         st->mem_pitch_gain[0] = st->mem_pitch_gain[1] = 16384 /*1.f Q14*/; /*Q14*/
     395           0 :         move16();
     396           0 :         move16();
     397             :     }
     398       13326 :     st->plc_use_future_lag = 0;
     399       13326 :     move16();
     400       13326 :     test();
     401       13326 :     test();
     402       13326 :     if ( ( st->last_core > ACELP_CORE && hTcxDec->tcxltp_last_gain_unmodified != 0 ) || ( EQ_16( st->flagGuidedAcelp, 1 ) ) )
     403             :     {
     404             :         /* no updates needed here, because already updated in last good frame */
     405       10580 :         st->plc_use_future_lag = 1;
     406       10580 :         move16();
     407             :     }
     408             : 
     409       13326 :     IF( EQ_16( st->last_core, -1 ) )
     410             :     {
     411           0 :         core = TCX_20_CORE;
     412           0 :         move16();
     413           0 :         st->last_core = ACELP_CORE;
     414           0 :         move16();
     415           0 :         if ( st->Opt_AMR_WB )
     416             :         {
     417           0 :             core = ACELP_CORE;
     418           0 :             move16();
     419             :         }
     420           0 :         st->tonal_mdct_plc_active = 0;
     421           0 :         move16();
     422             :     }
     423             :     ELSE
     424             :     {
     425       13326 :         core = ACELP_CORE;
     426       13326 :         move16();
     427       13326 :         if ( GT_16( st->nbLostCmpt, 1 ) )
     428             :         {
     429        6193 :             core = st->last_core_bfi; /*Q0*/
     430        6193 :             move16();
     431             :         }
     432       13326 :         IF( EQ_16( st->nbLostCmpt, 1 ) )
     433             :         {
     434        7133 :             st->tonal_mdct_plc_active = 0;
     435        7133 :             move16();
     436        7133 :             test();
     437        7133 :             test();
     438        7133 :             test();
     439        7133 :             IF( !( st->rf_flag && st->use_partial_copy && ( EQ_16( st->rf_frame_type, RF_TCXTD1 ) || EQ_16( st->rf_frame_type, RF_TCXTD2 ) ) ) )
     440             :             {
     441        7133 :                 test();
     442        7133 :                 test();
     443        7133 :                 test();
     444        7133 :                 test();
     445        7133 :                 test();
     446        7133 :                 test();
     447        7133 :                 test();
     448        7133 :                 IF( ( st->hTonalMDCTConc != NULL && EQ_16( st->last_core, TCX_20_CORE ) ) && ( EQ_16( st->second_last_core, TCX_20_CORE ) ) && ( ( LE_32( st->old_fpitch, L_deposit_h( shr( st->L_frame, 1 ) ) ) ) || ( LE_16( hTcxDec->tcxltp_last_gain_unmodified, 13107 /*0.4f Q15*/ ) ) )
     449             :                     /* it is fine to call the detection even if no ltp information
     450             :                        is available, meaning that st->old_fpitch ==
     451             :                        st->tcxltp_second_last_pitch == st->L_frame */
     452             :                     && ( EQ_32( st->old_fpitch, hTcxDec->tcxltp_second_last_pitch ) ) && !st->last_tns_active && !st->second_last_tns_active )
     453        1673 :                 {
     454             :                     Word32 pitch;
     455             : 
     456        1673 :                     pitch = L_deposit_h( 0 );
     457        1673 :                     if ( hTcxDec->tcxltp_last_gain_unmodified > 0 )
     458             :                     {
     459         436 :                         pitch = L_add( st->old_fpitch, 0 ); /*Q16*/
     460             :                     }
     461             : 
     462        1673 :                     TonalMDCTConceal_Detect_ivas_fx( st->hTonalMDCTConc, pitch, &numIndices, ( EQ_16( st->element_mode, IVAS_CPE_MDCT ) ? &( st->hTcxCfg->psychParamsTCX20 ) : st->hTcxCfg->psychParamsCurrent ), st->element_mode );
     463             : 
     464        1673 :                     test();
     465        1673 :                     test();
     466        1673 :                     test();
     467        1673 :                     test();
     468        1673 :                     test();
     469        1673 :                     test();
     470        1673 :                     test();
     471        1673 :                     IF( ( GT_16( numIndices, 10 ) ) || ( ( GT_16( numIndices, 5 ) ) && ( LT_32( L_abs( L_sub( hTcxDec->tcxltp_third_last_pitch, hTcxDec->tcxltp_second_last_pitch ) ), 32768l /*0.5f Q16*/ ) ) ) || ( ( numIndices > 0 ) && ( ( LE_16( st->last_good, UNVOICED_TRANSITION ) ) || ( LE_16( hTcxDec->tcxltp_last_gain_unmodified, 13107 /*0.4f Q15*/ ) ) ) && ( LT_32( L_abs( L_sub( hTcxDec->tcxltp_third_last_pitch, hTcxDec->tcxltp_second_last_pitch ) ), 32768l /*0.5f Q16*/ ) ) ) )
     472             :                     {
     473         369 :                         core = TCX_20_CORE;
     474         369 :                         move16();
     475         369 :                         st->tonal_mdct_plc_active = 1;
     476         369 :                         move16();
     477             :                     }
     478        1304 :                     ELSE IF( LE_16( st->last_good, UNVOICED_TRANSITION ) || LE_16( hTcxDec->tcxltp_last_gain_unmodified, 13107 /*0.4f Q15*/ ) )
     479             :                     {
     480        1195 :                         core = TCX_20_CORE;
     481        1195 :                         move16();
     482             :                     }
     483             :                 }
     484        5460 :                 ELSE IF( st->last_core != ACELP_CORE )
     485             :                 {
     486        5460 :                     test();
     487        5460 :                     if ( LE_16( st->last_good, UNVOICED_TRANSITION ) || LE_16( hTcxDec->tcxltp_last_gain_unmodified, 13107 /*0.4f Q15*/ ) )
     488             :                     {
     489        3178 :                         core = st->last_core;
     490        3178 :                         move16();
     491             :                     }
     492             :                 }
     493             :             }
     494             :         }
     495             :     }
     496       13326 :     return core; /*Q0*/
     497             : }
     498             : 
     499           0 : Word16 GetPLCModeDecision_fx(
     500             :     Decoder_State *st /* i/o:    decoder memory state pointer */
     501             : )
     502             : {
     503             :     Word16 /*int*/ core;
     504             :     Word16 numIndices;
     505             :     TCX_DEC_HANDLE hTcxDec;
     506             : 
     507           0 :     numIndices = 0;
     508           0 :     move16();
     509             : 
     510           0 :     hTcxDec = st->hTcxDec;
     511             : 
     512             : 
     513           0 :     IF( EQ_16( st->flagGuidedAcelp, 1 ) )
     514             :     {
     515           0 :         st->old_pitch_buf_fx[( st->nb_subfr * 2 )] = L_deposit_h( st->guidedT0 ); /*Q16*/
     516           0 :         move32();
     517           0 :         st->old_pitch_buf_fx[( ( st->nb_subfr * 2 ) + 1 )] = L_deposit_h( st->guidedT0 ); /*Q16*/
     518           0 :         move32();
     519           0 :         st->mem_pitch_gain[0] = st->mem_pitch_gain[1] = 16384 /*1.f Q14*/; /*Q14*/
     520           0 :         move16();
     521           0 :         move16();
     522             :     }
     523           0 :     st->plc_use_future_lag = 0;
     524           0 :     move16();
     525           0 :     test();
     526           0 :     test();
     527           0 :     if ( ( st->last_core > ACELP_CORE && hTcxDec->tcxltp_last_gain_unmodified != 0 ) || ( EQ_16( st->flagGuidedAcelp, 1 ) ) )
     528             :     {
     529             :         /* no updates needed here, because already updated in last good frame */
     530           0 :         st->plc_use_future_lag = 1;
     531           0 :         move16();
     532             :     }
     533             : 
     534           0 :     IF( EQ_16( st->last_core, -1 ) )
     535             :     {
     536           0 :         core = TCX_20_CORE;
     537           0 :         move16();
     538           0 :         st->last_core = ACELP_CORE;
     539           0 :         move16();
     540           0 :         if ( st->Opt_AMR_WB )
     541             :         {
     542           0 :             core = ACELP_CORE;
     543           0 :             move16();
     544             :         }
     545           0 :         st->tonal_mdct_plc_active = 0;
     546           0 :         move16();
     547             :     }
     548             :     ELSE
     549             :     {
     550           0 :         core = ACELP_CORE;
     551           0 :         move16();
     552           0 :         if ( GT_16( st->nbLostCmpt, 1 ) )
     553             :         {
     554           0 :             core = st->last_core_bfi;
     555           0 :             move16();
     556             :         }
     557             : 
     558           0 :         IF( EQ_16( st->nbLostCmpt, 1 ) )
     559             :         {
     560           0 :             st->tonal_mdct_plc_active = 0;
     561           0 :             move16();
     562           0 :             test();
     563           0 :             test();
     564           0 :             test();
     565           0 :             IF( !( st->rf_flag && st->use_partial_copy && ( EQ_16( st->rf_frame_type, RF_TCXTD1 ) || EQ_16( st->rf_frame_type, RF_TCXTD2 ) ) ) )
     566             :             {
     567           0 :                 test();
     568           0 :                 test();
     569           0 :                 test();
     570           0 :                 test();
     571           0 :                 test();
     572           0 :                 test();
     573           0 :                 IF( ( st->hTonalMDCTConc != NULL && EQ_16( st->last_core, TCX_20_CORE ) ) && ( EQ_16( st->second_last_core, TCX_20_CORE ) ) && ( ( LE_32( st->old_fpitch, L_deposit_h( shr( st->L_frame, 1 ) ) ) ) || ( LE_16( hTcxDec->tcxltp_last_gain_unmodified, 13107 /*0.4f Q15*/ ) ) )
     574             :                     /* it is fine to call the detection even if no ltp information
     575             :                        is available, meaning that st->old_fpitch ==
     576             :                        st->tcxltp_second_last_pitch == st->L_frame */
     577             :                     && ( EQ_32( st->old_fpitch, hTcxDec->tcxltp_second_last_pitch ) ) && !st->last_tns_active && !st->second_last_tns_active )
     578           0 :                 {
     579             :                     Word32 pitch;
     580             : 
     581             : 
     582           0 :                     pitch = L_deposit_h( 0 );
     583           0 :                     if ( hTcxDec->tcxltp_last_gain_unmodified > 0 )
     584             :                     {
     585           0 :                         pitch = L_add( st->old_fpitch, 0 ); /*Q16*/
     586             :                     }
     587             : 
     588           0 :                     TonalMDCTConceal_Detect( st->hTonalMDCTConc, pitch, &numIndices, st->element_mode );
     589             : 
     590           0 :                     test();
     591           0 :                     test();
     592           0 :                     test();
     593           0 :                     test();
     594           0 :                     test();
     595           0 :                     test();
     596           0 :                     test();
     597           0 :                     IF( ( GT_16( numIndices, 10 ) ) || ( ( GT_16( numIndices, 5 ) ) && ( LT_32( L_abs( L_sub( hTcxDec->tcxltp_third_last_pitch, hTcxDec->tcxltp_second_last_pitch ) ), 32768l /*0.5f Q16*/ ) ) ) || ( ( numIndices > 0 ) && ( ( LE_16( st->last_good, UNVOICED_TRANSITION ) ) || ( LE_16( hTcxDec->tcxltp_last_gain_unmodified, 13107 /*0.4f Q15*/ ) ) ) && ( LT_32( L_abs( L_sub( hTcxDec->tcxltp_third_last_pitch, hTcxDec->tcxltp_second_last_pitch ) ), 32768l /*0.5f Q16*/ ) ) ) )
     598             :                     {
     599           0 :                         core = TCX_20_CORE;
     600           0 :                         move16();
     601           0 :                         st->tonal_mdct_plc_active = 1;
     602           0 :                         move16();
     603             :                     }
     604           0 :                     ELSE IF( LE_16( st->last_good, UNVOICED_TRANSITION ) || LE_16( hTcxDec->tcxltp_last_gain_unmodified, 13107 /*0.4f Q15*/ ) )
     605             :                     {
     606           0 :                         core = TCX_20_CORE;
     607           0 :                         move16();
     608             :                     }
     609             :                 }
     610           0 :                 ELSE IF( st->last_core != ACELP_CORE )
     611             :                 {
     612           0 :                     test();
     613           0 :                     if ( LE_16( st->last_good, UNVOICED_TRANSITION ) || LE_16( hTcxDec->tcxltp_last_gain_unmodified, 13107 /*0.4f Q15*/ ) )
     614             :                     {
     615           0 :                         core = st->last_core;
     616           0 :                         move16();
     617             :                     }
     618             :                 }
     619             :             }
     620             :         }
     621             :     }
     622           0 :     return core;
     623             : }

Generated by: LCOV version 1.14