shithub: opus

Download patch

ref: 54b057c9cd23f935338ca413d55b4d54b61bbbf8
parent: fe608dfc511ce5f9ea5ab9c698d2ff0aa320b427
author: Jean-Marc Valin <jmvalin@jmvalin.ca>
date: Mon Mar 18 10:13:07 EDT 2019

Add LPCNet decoder object

--- a/dnn/Makefile
+++ b/dnn/Makefile
@@ -22,7 +22,7 @@
 
 all: dump_data test_lpcnet test_vec
 
-dump_data_objs := src/dump_data.o src/freq.o src/kiss_fft.o src/pitch.o src/celt_lpc.o src/lpcnet_dec.o src/lpcnet_enc.o src/ceps_codebooks.o
+dump_data_objs := src/common.o src/dump_data.o src/freq.o src/kiss_fft.o src/pitch.o src/celt_lpc.o src/lpcnet_dec.o src/lpcnet_enc.o src/ceps_codebooks.o
 dump_data_deps := $(dump_data_objs:.o=.d)
 dump_data: $(dump_data_objs)
 	gcc -o $@ $(CFLAGS) $(dump_data_objs) -lm
@@ -29,7 +29,7 @@
 
 -include $dump_data_deps(_deps)
 
-test_lpcnet_objs := src/test_lpcnet.o src/lpcnet.o src/nnet.o src/nnet_data.o src/freq.o src/kiss_fft.o src/pitch.o src/celt_lpc.o
+test_lpcnet_objs := src/common.o src/test_lpcnet.o src/lpcnet.o src/nnet.o src/nnet_data.o src/freq.o src/kiss_fft.o src/pitch.o src/celt_lpc.o src/lpcnet_dec.o  src/ceps_codebooks.o
 test_lpcnet_deps := $(test_lpcnet_objs:.o=.d)
 test_lpcnet: $(test_lpcnet_objs)
 	gcc -o $@ $(CFLAGS) $(test_lpcnet_objs) -lm
--- /dev/null
+++ b/dnn/common.c
@@ -1,0 +1,65 @@
+
+/* Copyright (c) 2017-2019 Mozilla */
+/*
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions
+   are met:
+
+   - Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+
+   - Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR
+   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include "freq.h"
+#include "lpcnet_private.h"
+
+
+static void single_interp(float *x, const float *left, const float *right, int id)
+{
+    int i;
+    float ref[NB_BANDS];
+    float pred[3*NB_BANDS];
+    RNN_COPY(ref, x, NB_BANDS);
+    for (i=0;i<NB_BANDS;i++) pred[i] = .5*(left[i] + right[i]);
+    for (i=0;i<NB_BANDS;i++) pred[NB_BANDS+i] = left[i];
+    for (i=0;i<NB_BANDS;i++) pred[2*NB_BANDS+i] = right[i];
+    for (i=0;i<NB_BANDS;i++) {
+      x[i] = pred[id*NB_BANDS + i];
+    }
+    if (0) {
+        float err = 0;
+        for (i=0;i<NB_BANDS;i++) {
+            err += (x[i]-ref[i])*(x[i]-ref[i]);
+        }
+        printf("%f\n", sqrt(err/NB_BANDS));
+    }
+}
+
+void perform_double_interp(float features[4][NB_TOTAL_FEATURES], const float *mem, int best_id) {
+    int id0, id1;
+    best_id += (best_id >= FORBIDDEN_INTERP);
+    id0 = best_id / 3;
+    id1 = best_id % 3;
+    single_interp(features[0], mem, features[1], id0);
+    single_interp(features[2], features[1], features[3], id1);
+}
--- a/dnn/lpcnet.c
+++ b/dnn/lpcnet.c
@@ -89,11 +89,24 @@
     compute_mdense(&dual_fc, pdf, net->gru_b_state);
 }
 
+int lpcnet_get_size()
+{
+    return sizeof(LPCNetState);
+}
+
+int lpcnet_init(LPCNetState *lpcnet)
+{
+    memset(lpcnet, 0, lpcnet_get_size());
+    lpcnet->last_exc = 128;
+    return 0;
+}
+
+
 LPCNetState *lpcnet_create()
 {
     LPCNetState *lpcnet;
-    lpcnet = (LPCNetState *)calloc(sizeof(LPCNetState), 1);
-    lpcnet->last_exc = 128;
+    lpcnet = (LPCNetState *)calloc(lpcnet_get_size(), 1);
+    lpcnet_init(lpcnet);
     return lpcnet;
 }
 
@@ -153,6 +166,40 @@
     start = 0;
 }
 
-#if 1
 
-#endif
+int lpcnet_decoder_get_size()
+{
+  return sizeof(LPCNetDecState);
+}
+
+int lpcnet_decoder_init(LPCNetDecState *st)
+{
+  memset(st, 0, lpcnet_decoder_get_size());
+  lpcnet_init(&st->lpcnet_state);
+  return 0;
+}
+
+LPCNetDecState *lpcnet_decoder_create()
+{
+  LPCNetDecState *st;
+  st = malloc(lpcnet_decoder_get_size());
+  lpcnet_decoder_init(st);
+  return st;
+}
+
+void lpcnet_decoder_destroy(LPCNetDecState *st)
+{
+  free(st);
+}
+
+int lpcnet_decode(LPCNetDecState *st, const unsigned char *buf, short *pcm)
+{
+  int k;
+  float features[4][NB_TOTAL_FEATURES];
+  decode_packet(features, st->vq_mem, buf);
+  for (k=0;k<4;k++) {
+    lpcnet_synthesize(&st->lpcnet_state, &pcm[k*FRAME_SIZE], features[k], FRAME_SIZE);
+  }
+  return 0;
+}
+
--- a/dnn/lpcnet.h
+++ b/dnn/lpcnet.h
@@ -32,8 +32,23 @@
 
 typedef struct LPCNetState LPCNetState;
 
+typedef struct LPCNetDecState LPCNetDecState;
+
 typedef struct LPCNetEncState LPCNetEncState;
 
+
+int lpcnet_decoder_get_size();
+
+int lpcnet_decoder_init(LPCNetDecState *st);
+
+LPCNetDecState *lpcnet_decoder_create();
+
+void lpcnet_decoder_destroy(LPCNetDecState *st);
+
+int lpcnet_decode(LPCNetDecState *st, const unsigned char *buf, short *pcm);
+
+
+
 int lpcnet_encoder_get_size();
 
 int lpcnet_encoder_init(LPCNetEncState *st);
@@ -45,6 +60,10 @@
 int lpcnet_encode(LPCNetEncState *st, const short *pcm, unsigned char *buf);
 
 
+
+int lpcnet_get_size();
+
+int lpcnet_init(LPCNetState *lpcnet);
 
 LPCNetState *lpcnet_create();
 
--- a/dnn/lpcnet_dec.c
+++ b/dnn/lpcnet_dec.c
@@ -50,7 +50,7 @@
     const unsigned char *chars;
 } unpacker;
 
-void bits_unpacker_init(unpacker *bits, unsigned char *buf, int size) {
+void bits_unpacker_init(unpacker *bits, const unsigned char *buf, int size) {
   bits->byte_pos = 0;
   bits->bit_pos = 0;
   bits->max_bytes = size;
@@ -78,7 +78,7 @@
   return d;
 }
 
-void decode_packet(float features[4][NB_TOTAL_FEATURES], float *vq_mem, unsigned char buf[8])
+void decode_packet(float features[4][NB_TOTAL_FEATURES], float *vq_mem, const unsigned char buf[8])
 {
   int c0_id;
   int main_pitch;
--- a/dnn/lpcnet_enc.c
+++ b/dnn/lpcnet_enc.c
@@ -398,35 +398,6 @@
     return best_id - (best_id >= FORBIDDEN_INTERP);
 }
 
-static void single_interp(float *x, const float *left, const float *right, int id)
-{
-    int i;
-    float ref[NB_BANDS];
-    float pred[3*NB_BANDS];
-    RNN_COPY(ref, x, NB_BANDS);
-    for (i=0;i<NB_BANDS;i++) pred[i] = .5*(left[i] + right[i]);
-    for (i=0;i<NB_BANDS;i++) pred[NB_BANDS+i] = left[i];
-    for (i=0;i<NB_BANDS;i++) pred[2*NB_BANDS+i] = right[i];
-    for (i=0;i<NB_BANDS;i++) {
-      x[i] = pred[id*NB_BANDS + i];
-    }
-    if (0) {
-        float err = 0;
-        for (i=0;i<NB_BANDS;i++) {
-            err += (x[i]-ref[i])*(x[i]-ref[i]);
-        }
-        printf("%f\n", sqrt(err/NB_BANDS));
-    }
-}
-
-void perform_double_interp(float features[4][NB_TOTAL_FEATURES], const float *mem, int best_id) {
-    int id0, id1;
-    best_id += (best_id >= FORBIDDEN_INTERP);
-    id0 = best_id / 3;
-    id1 = best_id % 3;
-    single_interp(features[0], mem, features[1], id0);
-    single_interp(features[2], features[1], features[3], id1);
-}
 
 void perform_interp_relaxation(float features[4][NB_TOTAL_FEATURES], const float *mem) {
     int id0, id1;
--- a/dnn/lpcnet_private.h
+++ b/dnn/lpcnet_private.h
@@ -33,8 +33,11 @@
     float deemph_mem;
 };
 
+struct LPCNetDecState {
+    LPCNetState lpcnet_state;
+    float vq_mem[NB_BANDS];
+};
 
-
 struct LPCNetEncState{
   float analysis_mem[OVERLAP_SIZE];
   float mem_preemph;
@@ -70,6 +73,6 @@
 
 void compute_frame_features(LPCNetEncState *st, const float *in);
 
-void decode_packet(float features[4][NB_TOTAL_FEATURES], float *vq_mem, unsigned char buf[8]);
+void decode_packet(float features[4][NB_TOTAL_FEATURES], float *vq_mem, const unsigned char buf[8]);
 
 #endif
--