ref: 71d5edcffbf520792a4e11959945735a0f9822e7
parent: 112b160a28787285a193bcc61161367449c859db
author: Jean-Marc Valin <jmvalin@amazon.com>
date: Mon May 15 11:08:08 EDT 2023
Directly include LPCNet state in SILK structs Makes shallow copy of decoder possible again
--- a/silk/PLC.c
+++ b/silk/PLC.c
@@ -65,12 +65,7 @@
psDec->sPLC.subfr_length = 20;
psDec->sPLC.nb_subfr = 2;
#ifdef NEURAL_PLC
- if( psDec->sPLC.lpcnet != NULL ) {
- lpcnet_plc_init( psDec->sPLC.lpcnet, LPCNET_PLC_CODEC );
- } else {
- /* FIXME: This is leaking memory. The right fix is for the LPCNet state to be part of the PLC struct itself. */
- psDec->sPLC.lpcnet = lpcnet_plc_create(LPCNET_PLC_CODEC);
- }
+ lpcnet_plc_init( &psDec->sPLC.lpcnet, LPCNET_PLC_CODEC );
#endif
}
@@ -105,7 +100,7 @@
int k;
psDec->sPLC.pre_filled = 0;
for( k = 0; k < psDec->nb_subfr; k += 2 ) {
- lpcnet_plc_update( psDec->sPLC.lpcnet, frame + k * psDec->subfr_length );
+ lpcnet_plc_update( &psDec->sPLC.lpcnet, frame + k * psDec->subfr_length );
}
}
#endif
@@ -396,7 +391,7 @@
if ( psDec->sPLC.fs_kHz == 16 ) {
psDec->sPLC.pre_filled = 1;
for( k = 0; k < psDec->nb_subfr; k += 2 ) {
- lpcnet_plc_conceal(psDec->sPLC.lpcnet, frame + k * psDec->subfr_length );
+ lpcnet_plc_conceal( &psDec->sPLC.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. */
--- a/silk/structs.h
+++ b/silk/structs.h
@@ -36,6 +36,7 @@
#ifdef NEURAL_PLC
#include "lpcnet.h"
+#include "lpcnet/src/lpcnet_private.h"
#endif
#ifdef ENABLE_NEURAL_FEC
@@ -260,7 +261,7 @@
opus_int subfr_length;
#ifdef NEURAL_PLC
/* FIXME: We should include the state struct directly to preserve the state shadow copy property. */
- LPCNetPLCState *lpcnet;
+ LPCNetPLCState lpcnet;
int pre_filled;
#endif
} silk_PLC_struct;
--- a/src/opus_decoder.c
+++ b/src/opus_decoder.c
@@ -654,7 +654,7 @@
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(&silk_dec->sPLC.lpcnet);
features_per_frame = frame_size/(st->Fs/100);
needed_feature_frames = features_per_frame;
if (!silk_dec->sPLC.pre_filled) needed_feature_frames+=2;
@@ -661,9 +661,9 @@
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(&silk_dec->sPLC.lpcnet, dred->fec_features+feature_offset*DRED_NUM_FEATURES);
} else {
- lpcnet_plc_fec_add(silk_dec->sPLC.lpcnet, NULL);
+ lpcnet_plc_fec_add(&silk_dec->sPLC.lpcnet, NULL);
}
}
--
⑨