shithub: opus

Download patch

ref: 0eb9f0bd389557670caf240618c35a2d5f2c3dad
parent: 3883f3d372f08562958845bb93ca7e4ef22d80a2
author: Jean-Marc Valin <jmvalin@amazon.com>
date: Sun Feb 20 21:34:44 EST 2022

Updating the DC tracker even during packet loss

Makes the offset signal more continuous

--- a/dnn/lpcnet_plc.c
+++ b/dnn/lpcnet_plc.c
@@ -93,6 +93,8 @@
   float plc_features[2*NB_BANDS+NB_FEATURES+1];
   short lp[FRAME_SIZE]={0};
   if (st->remove_dc) {
+    st->dc_mem += st->syn_dc;
+    st->syn_dc = 0;
     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);
@@ -203,6 +205,7 @@
   st->blend = 1;
   if (st->remove_dc) {
     for (i=0;i<FRAME_SIZE;i++) {
+      st->syn_dc += DC_CONST*(pcm[i] - st->syn_dc);
       pcm[i] += (int)floor(.5 + st->dc_mem);
     }
   }
@@ -227,8 +230,12 @@
   short pcm_save[FRAME_SIZE];
   float plc_features[2*NB_BANDS+NB_FEATURES+1];
   short lp[FRAME_SIZE]={0};
+  double mem_bak;
   process_queued_update(st);
   if (st->remove_dc) {
+    st->dc_mem += st->syn_dc;
+    st->syn_dc = 0;
+    mem_bak = st->dc_mem;
     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);
@@ -248,7 +255,21 @@
     compute_plc_pred(&st->plc_net, st->features, zeros);
     copy = st->lpcnet;
     lpcnet_synthesize_impl(&st->lpcnet, st->features, &st->pcm[FRAME_SIZE-TRAINING_OFFSET], TRAINING_OFFSET, 0);
-    {
+    /* Undo initial DC offset removal so that we can take into accound the last 5ms of synthesis. */
+    if (st->remove_dc) {
+      for (i=0;i<FRAME_SIZE;i++) pcm[i] += lp[i];
+      st->dc_mem = mem_bak;
+      for (i=0;i<TRAINING_OFFSET;i++) st->syn_dc += DC_CONST*(st->pcm[FRAME_SIZE-TRAINING_OFFSET+i] - st->syn_dc);
+      st->dc_mem += st->syn_dc;
+      st->syn_dc = 0;
+      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];
+      }
+      RNN_COPY(pcm_save, pcm, FRAME_SIZE);
+    }
+    {
       short rev[FRAME_SIZE];
       for (i=0;i<FRAME_SIZE;i++) rev[i] = pcm[FRAME_SIZE-i-1];
       clear_state(st);
@@ -330,6 +351,11 @@
 
   if (st->remove_dc) {
     int dc = (int)floor(.5 + st->dc_mem);
+    if (st->loss_count == 0) {
+        for (i=FRAME_SIZE-TRAINING_OFFSET;i<FRAME_SIZE;i++) st->syn_dc += DC_CONST*(pcm[i] - st->syn_dc);
+    } else {
+        for (i=0;i<FRAME_SIZE;i++) st->syn_dc += DC_CONST*(pcm[i] - st->syn_dc);
+    }
     for (i=0;i<TRAINING_OFFSET;i++) pcm[i] += st->dc_buf[i];
     for (;i<FRAME_SIZE;i++) pcm[i] += dc;
     for (i=0;i<TRAINING_OFFSET;i++) st->dc_buf[i] = dc;
--- a/dnn/lpcnet_private.h
+++ b/dnn/lpcnet_private.h
@@ -80,6 +80,7 @@
   PLCNetState plc_net;
   int enable_blending;
   double dc_mem;
+  double syn_dc;
   int remove_dc;
 
   short dc_buf[TRAINING_OFFSET];
--