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

Generated by: LCOV version 1.14