From 54bd6208a6ae905c7e319f3e6f8b469d704056cb Mon Sep 17 00:00:00 2001
From: Jean-Marc Valin <jmvalin@jmvalin.ca>
Date: Mon, 18 Mar 2019 16:17:57 -0400
Subject: [PATCH] Adding lpcnet_demo

---
 dnn/Makefile      |   9 +++-
 dnn/lpcnet_demo.c | 115 ++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 123 insertions(+), 1 deletion(-)
 create mode 100644 dnn/lpcnet_demo.c

diff --git a/dnn/Makefile b/dnn/Makefile
index 32f9aca31..4574e8bb2 100644
--- a/dnn/Makefile
+++ b/dnn/Makefile
@@ -20,7 +20,7 @@ ifneq ($(NEON),0)
 CFLAGS+=-mfpu=neon -march=armv8-a -mtune=cortex-a53
 endif
 
-all: dump_data test_lpcnet test_vec
+all: dump_data lpcnet_demo test_lpcnet test_vec
 
 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)
@@ -36,6 +36,13 @@ test_lpcnet: $(test_lpcnet_objs)
 
 -include $(test_lpcnet_deps)
 
+lpcnet_demo_objs := src/common.o src/lpcnet_demo.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 src/lpcnet_enc.o
+lpcnet_demo_deps := $(lpcnet_demo_objs:.o=.d)
+lpcnet_demo: $(lpcnet_demo_objs)
+	gcc -o $@ $(CFLAGS) $(lpcnet_demo_objs) -lm
+
+-include $(lpcnet_demo_deps)
+
 test_vec_objs := src/test_vec.o
 test_vec_deps := $(test_vec_objs:.o=.d)
 test_vec: $(test_vec_objs)
diff --git a/dnn/lpcnet_demo.c b/dnn/lpcnet_demo.c
new file mode 100644
index 000000000..43dd5d558
--- /dev/null
+++ b/dnn/lpcnet_demo.c
@@ -0,0 +1,115 @@
+/* Copyright (c) 2018 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.
+*/
+
+#include <math.h>
+#include <stdio.h>
+#include "arch.h"
+#include "lpcnet.h"
+#include "freq.h"
+
+#define MODE_ENCODE 0
+#define MODE_DECODE 1
+#define MODE_FEATURES 2
+#define MODE_SYNTHESIS 3
+
+int main(int argc, char **argv) {
+    int mode;
+    FILE *fin, *fout;
+    if (argc != 4)
+    {
+        fprintf(stderr, "usage: lpcnet_demo -encode <input.pcm> <compressed.lpcnet>\n");
+        fprintf(stderr, "       lpcnet_demo -decode <compressed.lpcnet> <output.pcm>\n");
+        fprintf(stderr, "       lpcnet_demo -features <input.pcm> <features.f32>\n");
+        fprintf(stderr, "       lpcnet_demo -synthesis <features.f32> <output.pcm>\n");
+        return 0;
+    }
+    if (strcmp(argv[1], "-encode") == 0) mode=MODE_ENCODE;
+    else if (strcmp(argv[1], "-decode") == 0) mode=MODE_DECODE;
+    else if (strcmp(argv[1], "-features") == 0) mode=MODE_FEATURES;
+    else if (strcmp(argv[1], "-synthesis") == 0) mode=MODE_SYNTHESIS;
+    else {
+        exit(1);
+    }
+    fin = fopen(argv[2], "rb");
+    if (fin == NULL) {
+	fprintf(stderr, "Can't open %s\n", argv[2]);
+	exit(1);
+    }
+
+    fout = fopen(argv[3], "wb");
+    if (fout == NULL) {
+	fprintf(stderr, "Can't open %s\n", argv[3]);
+	exit(1);
+    }
+
+    if (mode == MODE_ENCODE) {
+        LPCNetEncState *net;
+        net = lpcnet_encoder_create();
+        while (1) {
+            unsigned char buf[8];
+            short pcm[4*FRAME_SIZE];
+            fread(pcm, sizeof(pcm[0]), 4*FRAME_SIZE, fin);
+            if (feof(fin)) break;
+            lpcnet_encode(net, pcm, buf);
+            fwrite(buf, 1, 8, fout);
+        }
+        lpcnet_encoder_destroy(net);
+    } else if (mode == MODE_DECODE) {
+        LPCNetDecState *net;
+        net = lpcnet_decoder_create();
+        while (1) {
+            unsigned char buf[8];
+            short pcm[4*FRAME_SIZE];
+            fread(buf, sizeof(buf[0]), 8, fin);
+            if (feof(fin)) break;
+            lpcnet_decode(net, buf, pcm);
+            fwrite(pcm, sizeof(pcm[0]), 4*FRAME_SIZE, fout);
+        }
+        lpcnet_decoder_destroy(net);
+    } else if (mode == MODE_FEATURES) {
+        fprintf(stderr, "-features not yet implemented\n");
+    } else if (mode == MODE_SYNTHESIS) {
+        LPCNetState *net;
+        net = lpcnet_create();
+        while (1) {
+            float in_features[NB_TOTAL_FEATURES];
+            float features[NB_FEATURES];
+            short pcm[FRAME_SIZE];
+            fread(in_features, sizeof(features[0]), NB_TOTAL_FEATURES, fin);
+            if (feof(fin)) break;
+            RNN_COPY(features, in_features, NB_FEATURES);
+            RNN_CLEAR(&features[18], 18);
+            lpcnet_synthesize(net, pcm, features, FRAME_SIZE);
+            fwrite(pcm, sizeof(pcm[0]), FRAME_SIZE, fout);
+        }
+        lpcnet_destroy(net);
+    } else {
+        fprintf(stderr, "unknown action\n");
+    }
+    fclose(fin);
+    fclose(fout);
+    return 0;
+}
-- 
GitLab