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

Generated by: LCOV version 1.14