diff options
author | Jean-Marc Valin <jmvalin@amazon.com> | 2023-05-31 11:01:52 +0300 |
---|---|---|
committer | Jean-Marc Valin <jmvalin@amazon.com> | 2023-06-16 20:02:22 +0300 |
commit | e57dfb824c223c607d576cf7374a2ee339064634 (patch) | |
tree | 3b8595146cddda49459bc9709d49154ec8d44043 | |
parent | ef4f459ec3e0ce2e0587009ef71dfd9dd8cf3f93 (diff) |
Move LPCNet PLC state to top-level decoder
So it can be used outside of the SILK PLC
-rw-r--r-- | silk/API.h | 4 | ||||
-rw-r--r-- | silk/PLC.c | 22 | ||||
-rw-r--r-- | silk/PLC.h | 3 | ||||
-rw-r--r-- | silk/dec_API.c | 9 | ||||
-rw-r--r-- | silk/decode_frame.c | 15 | ||||
-rw-r--r-- | silk/main.h | 3 | ||||
-rw-r--r-- | silk/structs.h | 3 | ||||
-rw-r--r-- | src/opus_decoder.c | 25 |
8 files changed, 65 insertions, 19 deletions
@@ -33,6 +33,7 @@ POSSIBILITY OF SUCH DAMAGE. #include "errors.h" #include "entenc.h" #include "entdec.h" +#include "lpcnet/src/lpcnet_private.h" #ifdef __cplusplus extern "C" @@ -113,6 +114,9 @@ opus_int silk_Decode( /* O Returns error co ec_dec *psRangeDec, /* I/O Compressor data structure */ opus_int16 *samplesOut, /* O Decoded output speech vector */ opus_int32 *nSamplesOut, /* O Number of samples decoded */ +#ifdef NEURAL_PLC + LPCNetPLCState *lpcnet, +#endif int arch /* I Run-time architecture */ ); @@ -51,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 NEURAL_PLC + LPCNetPLCState *lpcnet, +#endif int arch /* I Run-time architecture */ ); @@ -64,9 +67,6 @@ void silk_PLC_Reset( psDec->sPLC.prevGain_Q16[ 1 ] = SILK_FIX_CONST( 1, 16 ); psDec->sPLC.subfr_length = 20; psDec->sPLC.nb_subfr = 2; -#ifdef NEURAL_PLC - lpcnet_plc_init( &psDec->sPLC.lpcnet, LPCNET_PLC_CODEC ); -#endif } void silk_PLC( @@ -74,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 NEURAL_PLC + LPCNetPLCState *lpcnet, +#endif int arch /* I Run-time architecture */ ) { @@ -87,7 +90,11 @@ void silk_PLC( /****************************/ /* Generate Signal */ /****************************/ - silk_PLC_conceal( psDec, psDecCtrl, frame, arch ); + silk_PLC_conceal( psDec, psDecCtrl, frame, +#ifdef NEURAL_PLC + lpcnet, +#endif + arch ); psDec->lossCnt++; } else { @@ -99,7 +106,7 @@ void silk_PLC( if ( psDec->sPLC.fs_kHz == 16 ) { int k; for( k = 0; k < psDec->nb_subfr; k += 2 ) { - lpcnet_plc_update( &psDec->sPLC.lpcnet, frame + k * psDec->subfr_length ); + lpcnet_plc_update( lpcnet, frame + k * psDec->subfr_length ); } } #endif @@ -210,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 NEURAL_PLC + LPCNetPLCState *lpcnet, +#endif int arch /* I Run-time architecture */ ) { @@ -389,7 +399,7 @@ static OPUS_INLINE void silk_PLC_conceal( #ifdef NEURAL_PLC if ( psDec->sPLC.fs_kHz == 16 ) { for( k = 0; k < psDec->nb_subfr; k += 2 ) { - lpcnet_plc_conceal( &psDec->sPLC.lpcnet, frame + k * psDec->subfr_length ); + 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. */ @@ -49,6 +49,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 NEURAL_PLC + LPCNetPLCState *lpcnet, +#endif int arch /* I Run-time architecture */ ); diff --git a/silk/dec_API.c b/silk/dec_API.c index 7d5ca7fb..5d040409 100644 --- a/silk/dec_API.c +++ b/silk/dec_API.c @@ -86,6 +86,9 @@ opus_int silk_Decode( /* O Returns error co ec_dec *psRangeDec, /* I/O Compressor data structure */ opus_int16 *samplesOut, /* O Decoded output speech vector */ opus_int32 *nSamplesOut, /* O Number of samples decoded */ +#ifdef NEURAL_PLC + LPCNetPLCState *lpcnet, +#endif int arch /* I Run-time architecture */ ) { @@ -297,7 +300,11 @@ opus_int silk_Decode( /* O Returns error co } else { condCoding = CODE_CONDITIONALLY; } - ret += silk_decode_frame( &channel_state[ n ], psRangeDec, &samplesOut1_tmp[ n ][ 2 ], &nSamplesOutDec, lostFlag, condCoding, arch); + ret += silk_decode_frame( &channel_state[ n ], psRangeDec, &samplesOut1_tmp[ n ][ 2 ], &nSamplesOutDec, lostFlag, condCoding, +#ifdef NEURAL_PLC + lpcnet, +#endif + arch); } else { silk_memset( &samplesOut1_tmp[ n ][ 2 ], 0, nSamplesOutDec * sizeof( opus_int16 ) ); } diff --git a/silk/decode_frame.c b/silk/decode_frame.c index 4f36f854..952a807a 100644 --- a/silk/decode_frame.c +++ b/silk/decode_frame.c @@ -43,6 +43,9 @@ opus_int silk_decode_frame( opus_int32 *pN, /* O Pointer to size of output frame */ opus_int lostFlag, /* I 0: no loss, 1 loss, 2 decode fec */ opus_int condCoding, /* I The type of conditional coding to use */ +#ifdef NEURAL_PLC + LPCNetPLCState *lpcnet, +#endif int arch /* I Run-time architecture */ ) { @@ -87,7 +90,11 @@ opus_int silk_decode_frame( /********************************************************/ /* Update PLC state */ /********************************************************/ - silk_PLC( psDec, psDecCtrl, pOut, 0, arch ); + silk_PLC( psDec, psDecCtrl, pOut, 0, +#ifdef NEURAL_PLC + lpcnet, +#endif + arch ); psDec->lossCnt = 0; psDec->prevSignalType = psDec->indices.signalType; @@ -97,7 +104,11 @@ opus_int silk_decode_frame( psDec->first_frame_after_reset = 0; } else { /* Handle packet loss by extrapolation */ - silk_PLC( psDec, psDecCtrl, pOut, 1, arch ); + silk_PLC( psDec, psDecCtrl, pOut, 1, +#ifdef NEURAL_PLC + lpcnet, +#endif + arch ); } /*************************/ diff --git a/silk/main.h b/silk/main.h index a5f56875..5ff1980b 100644 --- a/silk/main.h +++ b/silk/main.h @@ -410,6 +410,9 @@ opus_int silk_decode_frame( opus_int32 *pN, /* O Pointer to size of output frame */ opus_int lostFlag, /* I 0: no loss, 1 loss, 2 decode fec */ opus_int condCoding, /* I The type of conditional coding to use */ +#ifdef NEURAL_PLC + LPCNetPLCState *lpcnet, +#endif int arch /* I Run-time architecture */ ); diff --git a/silk/structs.h b/silk/structs.h index 956d1975..6a0889ee 100644 --- a/silk/structs.h +++ b/silk/structs.h @@ -256,9 +256,6 @@ typedef struct { opus_int fs_kHz; opus_int nb_subfr; opus_int subfr_length; -#ifdef NEURAL_PLC - LPCNetPLCState lpcnet; -#endif } silk_PLC_struct; /* Struct for CNG */ diff --git a/src/opus_decoder.c b/src/opus_decoder.c index d2008d7c..178987d1 100644 --- a/src/opus_decoder.c +++ b/src/opus_decoder.c @@ -60,6 +60,9 @@ struct OpusDecoder { silk_DecControlStruct DecControl; int decode_gain; int arch; +#ifdef NEURAL_PLC + LPCNetPLCState lpcnet; +#endif /* Everything beyond this point gets cleared on a reset */ #define OPUS_DECODER_RESET_START stream_channels @@ -152,6 +155,9 @@ int opus_decoder_init(OpusDecoder *st, opus_int32 Fs, int channels) st->prev_mode = 0; st->frame_size = Fs/400; +#ifdef NEURAL_PLC + lpcnet_plc_init( &st->lpcnet, LPCNET_PLC_CODEC ); +#endif st->arch = opus_select_arch(); return OPUS_OK; } @@ -401,7 +407,11 @@ static int opus_decode_frame(OpusDecoder *st, const unsigned char *data, /* Call SILK decoder */ int first_frame = decoded_samples == 0; silk_ret = silk_Decode( silk_dec, &st->DecControl, - lost_flag, first_frame, &dec, pcm_ptr, &silk_frame_size, st->arch ); + lost_flag, first_frame, &dec, pcm_ptr, &silk_frame_size, +#ifdef NEURAL_PLC + &st->lpcnet, +#endif + st->arch ); if( silk_ret ) { if (lost_flag) { /* PLC failure should not be fatal */ @@ -652,19 +662,17 @@ int opus_decode_native(OpusDecoder *st, const unsigned char *data, if (dred != NULL && dred->process_stage == 2) { int features_per_frame; int needed_feature_frames; - silk_decoder_state *silk_dec; - silk_dec = (silk_decoder_state*)((char*)st+st->silk_dec_offset); - lpcnet_plc_fec_clear(&silk_dec->sPLC.lpcnet); + lpcnet_plc_fec_clear(&st->lpcnet); features_per_frame = frame_size/(st->Fs/100); needed_feature_frames = features_per_frame; /* if blend==0, the last PLC call was "update" and we need to feed two extra 10-ms frames. */ - if (silk_dec->sPLC.lpcnet.blend == 0) needed_feature_frames+=2; + if (st->lpcnet.blend == 0) needed_feature_frames+=2; for (i=0;i<needed_feature_frames;i++) { int feature_offset = (needed_feature_frames-i-1 + (dred_offset/(st->Fs/100)-1)*features_per_frame); if (feature_offset <= 4*dred->nb_latents-1) { - lpcnet_plc_fec_add(&silk_dec->sPLC.lpcnet, dred->fec_features+feature_offset*DRED_NUM_FEATURES); + lpcnet_plc_fec_add(&st->lpcnet, dred->fec_features+feature_offset*DRED_NUM_FEATURES); } else { - lpcnet_plc_fec_add(&silk_dec->sPLC.lpcnet, NULL); + lpcnet_plc_fec_add(&st->lpcnet, NULL); } } @@ -909,6 +917,9 @@ int opus_decoder_ctl(OpusDecoder *st, int request, ...) silk_InitDecoder( silk_dec ); st->stream_channels = st->channels; st->frame_size = st->Fs/400; +#ifdef NEURAL_PLC + lpcnet_plc_init( &st->lpcnet, LPCNET_PLC_CODEC ); +#endif } break; case OPUS_GET_SAMPLE_RATE_REQUEST: |