shithub: opus

Download patch

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);
          }
 
       }
--