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
--
⑨