shithub: opus

Download patch

ref: 78e682950bf51634e239f23c19cf98307ba7b923
parent: 527841d03e74ea37987bca77e195fa93bbbde51f
author: Jean-Marc Valin <jmvalin@amazon.com>
date: Tue Feb 15 21:08:34 EST 2022

Handle DC offset

Remove DC, conceal, add it back at the end

--- a/dnn/lpcnet_plc.c
+++ b/dnn/lpcnet_plc.c
@@ -45,6 +45,8 @@
   st->blend = 0;
   st->loss_count = 0;
   st->enable_blending = 1;
+  st->dc_mem = 0;
+  st->remove_dc = 1;
 }
 
 LPCNET_EXPORT LPCNetPLCState *lpcnet_plc_create() {
@@ -75,6 +77,8 @@
   RNN_CLEAR(st->lpcnet.nnet.gru_b_state, GRU_B_STATE_SIZE);
 }
 
+#define DC_CONST 0.003
+
 #if 1
 
 /* In this causal version of the code, the DNN model implemented by compute_plc_pred()
@@ -85,6 +89,14 @@
   float x[FRAME_SIZE];
   short output[FRAME_SIZE];
   float plc_features[2*NB_BANDS+NB_FEATURES+1];
+  short lp[FRAME_SIZE]={0};
+  if (st->remove_dc) {
+    for (i=0;i<FRAME_SIZE;i++) {
+      lp[i] = (int)floor(.5 + st->dc_mem);
+      st->dc_mem += DC_CONST*(pcm[i] - st->dc_mem);
+      pcm[i] -= lp[i];
+    }
+  }
   for (i=0;i<FRAME_SIZE;i++) x[i] = pcm[i];
   burg_cepstral_analysis(plc_features, x);
   st->enc.pcount = 0;
@@ -143,11 +155,17 @@
     RNN_MOVE(st->pcm, &st->pcm[FRAME_SIZE], PLC_BUF_SIZE);
   }
   st->loss_count = 0;
+  if (st->remove_dc) {
+    for (i=0;i<FRAME_SIZE;i++) {
+      pcm[i] += lp[i];
+    }
+  }
   return 0;
 }
 
 static const float att_table[10] = {0, 0,  -.2, -.2,  -.4, -.4,  -.8, -.8, -1.6, -1.6};
 LPCNET_EXPORT int lpcnet_plc_conceal(LPCNetPLCState *st, short *pcm) {
+  int i;
   short output[FRAME_SIZE];
   float zeros[2*NB_BANDS+NB_FEATURES+1] = {0};
   st->enc.pcount = 0;
@@ -181,6 +199,11 @@
   }
   st->loss_count++;
   st->blend = 1;
+  if (st->remove_dc) {
+    for (i=0;i<FRAME_SIZE;i++) {
+      pcm[i] += (int)floor(.5 + st->dc_mem);
+    }
+  }
   return 0;
 }
 
@@ -194,6 +217,14 @@
   float x[FRAME_SIZE];
   short pcm_save[FRAME_SIZE];
   float plc_features[2*NB_BANDS+NB_FEATURES+1];
+  short lp[FRAME_SIZE]={0};
+  if (st->remove_dc) {
+    for (i=0;i<FRAME_SIZE;i++) {
+      lp[i] = (int)floor(.5 + st->dc_mem);
+      st->dc_mem += LP_CONST*(pcm[i] - st->dc_mem);
+      pcm[i] -= lp[i];
+    }
+  }
   RNN_COPY(pcm_save, pcm, FRAME_SIZE);
   for (i=0;i<FRAME_SIZE;i++) x[i] = pcm[i];
   burg_cepstral_analysis(plc_features, x);
@@ -246,6 +277,11 @@
   RNN_COPY(pcm, &st->pcm[TRAINING_OFFSET], FRAME_SIZE-TRAINING_OFFSET);
   RNN_COPY(st->pcm, pcm_save, FRAME_SIZE);
   st->loss_count = 0;
+  if (st->remove_dc) {
+    for (i=0;i<FRAME_SIZE;i++) {
+      pcm[i] += lp[i];
+    }
+  }
   return 0;
 }
 
@@ -277,7 +313,11 @@
   }
   RNN_COPY(st->pcm, &pcm[TRAINING_OFFSET], FRAME_SIZE-TRAINING_OFFSET);
 
-
+  if (st->remove_dc) {
+    for (i=0;i<FRAME_SIZE;i++) {
+      pcm[i] += (int)floor(.5 + st->dc_mem);
+    }
+  }
   st->loss_count++;
   return 0;
 }
--- a/dnn/lpcnet_private.h
+++ b/dnn/lpcnet_private.h
@@ -79,6 +79,8 @@
   int loss_count;
   PLCNetState plc_net;
   int enable_blending;
+  double dc_mem;
+  int remove_dc;
 };
 
 extern float ceps_codebook1[];
--