diff --git a/dnn/Makefile b/dnn/Makefile index 32f9aca31669f004e41399752b7c27735aec8995..4574e8bb22dd6e4095b18d05eb057d55c76c60b5 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 0000000000000000000000000000000000000000..43dd5d558a344193fb1ca4d298ed311a3e5be9f8 --- /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; +}