mirror of
https://github.com/xiph/opus.git
synced 2025-05-16 00:18:29 +00:00
Add LPCNet decoder object
This commit is contained in:
parent
fe608dfc51
commit
54b057c9cd
7 changed files with 144 additions and 39 deletions
|
@ -22,14 +22,14 @@ endif
|
||||||
|
|
||||||
all: dump_data test_lpcnet test_vec
|
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_deps := $(dump_data_objs:.o=.d)
|
||||||
dump_data: $(dump_data_objs)
|
dump_data: $(dump_data_objs)
|
||||||
gcc -o $@ $(CFLAGS) $(dump_data_objs) -lm
|
gcc -o $@ $(CFLAGS) $(dump_data_objs) -lm
|
||||||
|
|
||||||
-include $dump_data_deps(_deps)
|
-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_deps := $(test_lpcnet_objs:.o=.d)
|
||||||
test_lpcnet: $(test_lpcnet_objs)
|
test_lpcnet: $(test_lpcnet_objs)
|
||||||
gcc -o $@ $(CFLAGS) $(test_lpcnet_objs) -lm
|
gcc -o $@ $(CFLAGS) $(test_lpcnet_objs) -lm
|
||||||
|
|
65
dnn/common.c
Normal file
65
dnn/common.c
Normal file
|
@ -0,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);
|
||||||
|
}
|
55
dnn/lpcnet.c
55
dnn/lpcnet.c
|
@ -89,11 +89,24 @@ void run_sample_network(NNetState *net, float *pdf, const float *condition, cons
|
||||||
compute_mdense(&dual_fc, pdf, net->gru_b_state);
|
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_create()
|
||||||
{
|
{
|
||||||
LPCNetState *lpcnet;
|
LPCNetState *lpcnet;
|
||||||
lpcnet = (LPCNetState *)calloc(sizeof(LPCNetState), 1);
|
lpcnet = (LPCNetState *)calloc(lpcnet_get_size(), 1);
|
||||||
lpcnet->last_exc = 128;
|
lpcnet_init(lpcnet);
|
||||||
return lpcnet;
|
return lpcnet;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -153,6 +166,40 @@ void lpcnet_synthesize(LPCNetState *lpcnet, short *output, const float *features
|
||||||
start = 0;
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
19
dnn/lpcnet.h
19
dnn/lpcnet.h
|
@ -32,8 +32,23 @@
|
||||||
|
|
||||||
typedef struct LPCNetState LPCNetState;
|
typedef struct LPCNetState LPCNetState;
|
||||||
|
|
||||||
|
typedef struct LPCNetDecState LPCNetDecState;
|
||||||
|
|
||||||
typedef struct LPCNetEncState LPCNetEncState;
|
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_get_size();
|
||||||
|
|
||||||
int lpcnet_encoder_init(LPCNetEncState *st);
|
int lpcnet_encoder_init(LPCNetEncState *st);
|
||||||
|
@ -46,6 +61,10 @@ int lpcnet_encode(LPCNetEncState *st, const short *pcm, unsigned char *buf);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int lpcnet_get_size();
|
||||||
|
|
||||||
|
int lpcnet_init(LPCNetState *lpcnet);
|
||||||
|
|
||||||
LPCNetState *lpcnet_create();
|
LPCNetState *lpcnet_create();
|
||||||
|
|
||||||
void lpcnet_destroy(LPCNetState *lpcnet);
|
void lpcnet_destroy(LPCNetState *lpcnet);
|
||||||
|
|
|
@ -50,7 +50,7 @@ typedef struct {
|
||||||
const unsigned char *chars;
|
const unsigned char *chars;
|
||||||
} unpacker;
|
} 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->byte_pos = 0;
|
||||||
bits->bit_pos = 0;
|
bits->bit_pos = 0;
|
||||||
bits->max_bytes = size;
|
bits->max_bytes = size;
|
||||||
|
@ -78,7 +78,7 @@ unsigned int bits_unpack(unpacker *bits, int nb_bits) {
|
||||||
return d;
|
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 c0_id;
|
||||||
int main_pitch;
|
int main_pitch;
|
||||||
|
|
|
@ -398,35 +398,6 @@ int double_interp_search(const float features[4][NB_TOTAL_FEATURES], const float
|
||||||
return best_id - (best_id >= FORBIDDEN_INTERP);
|
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) {
|
void perform_interp_relaxation(float features[4][NB_TOTAL_FEATURES], const float *mem) {
|
||||||
int id0, id1;
|
int id0, id1;
|
||||||
|
|
|
@ -33,7 +33,10 @@ struct LPCNetState {
|
||||||
float deemph_mem;
|
float deemph_mem;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct LPCNetDecState {
|
||||||
|
LPCNetState lpcnet_state;
|
||||||
|
float vq_mem[NB_BANDS];
|
||||||
|
};
|
||||||
|
|
||||||
struct LPCNetEncState{
|
struct LPCNetEncState{
|
||||||
float analysis_mem[OVERLAP_SIZE];
|
float analysis_mem[OVERLAP_SIZE];
|
||||||
|
@ -70,6 +73,6 @@ void process_superframe(LPCNetEncState *st, unsigned char *buf, FILE *ffeat, int
|
||||||
|
|
||||||
void compute_frame_features(LPCNetEncState *st, const float *in);
|
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
|
#endif
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue