diff options
Diffstat (limited to 'media/libopus/silk/PLC.c')
-rw-r--r-- | media/libopus/silk/PLC.c | 61 |
1 files changed, 54 insertions, 7 deletions
diff --git a/media/libopus/silk/PLC.c b/media/libopus/silk/PLC.c index 4667440db2..b35bf750a0 100644 --- a/media/libopus/silk/PLC.c +++ b/media/libopus/silk/PLC.c @@ -33,6 +33,10 @@ POSSIBILITY OF SUCH DAMAGE. #include "stack_alloc.h" #include "PLC.h" +#ifdef ENABLE_DEEP_PLC +#include "lpcnet.h" +#endif + #define NB_ATT 2 static const opus_int16 HARM_ATT_Q15[NB_ATT] = { 32440, 31130 }; /* 0.99, 0.95 */ static const opus_int16 PLC_RAND_ATTENUATE_V_Q15[NB_ATT] = { 31130, 26214 }; /* 0.95, 0.8 */ @@ -47,6 +51,9 @@ static OPUS_INLINE void silk_PLC_conceal( silk_decoder_state *psDec, /* I/O Decoder state */ silk_decoder_control *psDecCtrl, /* I/O Decoder control */ opus_int16 frame[], /* O LPC residual signal */ +#ifdef ENABLE_DEEP_PLC + LPCNetPLCState *lpcnet, +#endif int arch /* I Run-time architecture */ ); @@ -67,6 +74,9 @@ void silk_PLC( silk_decoder_control *psDecCtrl, /* I/O Decoder control */ opus_int16 frame[], /* I/O signal */ opus_int lost, /* I Loss flag */ +#ifdef ENABLE_DEEP_PLC + LPCNetPLCState *lpcnet, +#endif int arch /* I Run-time architecture */ ) { @@ -80,7 +90,11 @@ void silk_PLC( /****************************/ /* Generate Signal */ /****************************/ - silk_PLC_conceal( psDec, psDecCtrl, frame, arch ); + silk_PLC_conceal( psDec, psDecCtrl, frame, +#ifdef ENABLE_DEEP_PLC + lpcnet, +#endif + arch ); psDec->lossCnt++; } else { @@ -88,6 +102,14 @@ void silk_PLC( /* Update state */ /****************************/ silk_PLC_update( psDec, psDecCtrl ); +#ifdef ENABLE_DEEP_PLC + if ( lpcnet != NULL && psDec->sPLC.fs_kHz == 16 ) { + int k; + for( k = 0; k < psDec->nb_subfr; k += 2 ) { + lpcnet_plc_update( lpcnet, frame + k * psDec->subfr_length ); + } + } +#endif } } @@ -195,6 +217,9 @@ static OPUS_INLINE void silk_PLC_conceal( silk_decoder_state *psDec, /* I/O Decoder state */ silk_decoder_control *psDecCtrl, /* I/O Decoder control */ opus_int16 frame[], /* O LPC residual signal */ +#ifdef ENABLE_DEEP_PLC + LPCNetPLCState *lpcnet, +#endif int arch /* I Run-time architecture */ ) { @@ -371,6 +396,24 @@ static OPUS_INLINE void silk_PLC_conceal( /* Scale with Gain */ frame[ i ] = (opus_int16)silk_SAT16( silk_SAT16( silk_RSHIFT_ROUND( silk_SMULWW( sLPC_Q14_ptr[ MAX_LPC_ORDER + i ], prevGain_Q10[ 1 ] ), 8 ) ) ); } +#ifdef ENABLE_DEEP_PLC + if ( lpcnet != NULL && lpcnet->loaded && psDec->sPLC.fs_kHz == 16 ) { + int run_deep_plc = psDec->sPLC.enable_deep_plc || lpcnet->fec_fill_pos != 0; + if( run_deep_plc ) { + for( k = 0; k < psDec->nb_subfr; k += 2 ) { + lpcnet_plc_conceal( lpcnet, frame + k * psDec->subfr_length ); + } + /* We *should* be able to copy only from psDec->frame_length-MAX_LPC_ORDER, i.e. the last MAX_LPC_ORDER samples. */ + for( i = 0; i < psDec->frame_length; i++ ) { + sLPC_Q14_ptr[ MAX_LPC_ORDER + i ] = (int)floor(.5 + frame[ i ] * (float)(1 << 24) / prevGain_Q10[ 1 ] ); + } + } else { + for( k = 0; k < psDec->nb_subfr; k += 2 ) { + lpcnet_plc_update( lpcnet, frame + k * psDec->subfr_length ); + } + } + } +#endif /* Save LPC state */ silk_memcpy( psDec->sLPC_Q14_buf, &sLPC_Q14_ptr[ psDec->frame_length ], MAX_LPC_ORDER * sizeof( opus_int32 ) ); @@ -431,12 +474,16 @@ void silk_PLC_glue_frames( slope_Q16 = silk_DIV32_16( ( (opus_int32)1 << 16 ) - gain_Q16, length ); /* Make slope 4x steeper to avoid missing onsets after DTX */ slope_Q16 = silk_LSHIFT( slope_Q16, 2 ); - - for( i = 0; i < length; i++ ) { - frame[ i ] = silk_SMULWB( gain_Q16, frame[ i ] ); - gain_Q16 += slope_Q16; - if( gain_Q16 > (opus_int32)1 << 16 ) { - break; +#ifdef ENABLE_DEEP_PLC + if ( psDec->sPLC.fs_kHz != 16 ) +#endif + { + for( i = 0; i < length; i++ ) { + frame[ i ] = silk_SMULWB( gain_Q16, frame[ i ] ); + gain_Q16 += slope_Q16; + if( gain_Q16 > (opus_int32)1 << 16 ) { + break; + } } } } |