Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.xiph.org/xiph/opus.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJean-Marc Valin <jmvalin@amazon.com>2023-05-31 11:01:52 +0300
committerJean-Marc Valin <jmvalin@amazon.com>2023-06-16 20:02:22 +0300
commite57dfb824c223c607d576cf7374a2ee339064634 (patch)
tree3b8595146cddda49459bc9709d49154ec8d44043
parentef4f459ec3e0ce2e0587009ef71dfd9dd8cf3f93 (diff)
Move LPCNet PLC state to top-level decoder
So it can be used outside of the SILK PLC
-rw-r--r--silk/API.h4
-rw-r--r--silk/PLC.c22
-rw-r--r--silk/PLC.h3
-rw-r--r--silk/dec_API.c9
-rw-r--r--silk/decode_frame.c15
-rw-r--r--silk/main.h3
-rw-r--r--silk/structs.h3
-rw-r--r--src/opus_decoder.c25
8 files changed, 65 insertions, 19 deletions
diff --git a/silk/API.h b/silk/API.h
index 4d90ff9a..b5327ba1 100644
--- a/silk/API.h
+++ b/silk/API.h
@@ -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 */
);
diff --git a/silk/PLC.c b/silk/PLC.c
index 7aff66ee..ff1ca7eb 100644
--- a/silk/PLC.c
+++ b/silk/PLC.c
@@ -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. */
diff --git a/silk/PLC.h b/silk/PLC.h
index 6438f516..b59f7f00 100644
--- a/silk/PLC.h
+++ b/silk/PLC.h
@@ -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: