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
|
||||
|
||||
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
|
||||
|
||||
-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
|
||||
|
|
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);
|
||||
}
|
||||
|
||||
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 @@ void lpcnet_synthesize(LPCNetState *lpcnet, short *output, const float *features
|
|||
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 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);
|
||||
|
@ -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();
|
||||
|
||||
void lpcnet_destroy(LPCNetState *lpcnet);
|
||||
|
|
|
@ -50,7 +50,7 @@ typedef struct {
|
|||
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 @@ unsigned int bits_unpack(unpacker *bits, int nb_bits) {
|
|||
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;
|
||||
|
|
|
@ -398,35 +398,6 @@ int double_interp_search(const float features[4][NB_TOTAL_FEATURES], const float
|
|||
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;
|
||||
|
|
|
@ -33,7 +33,10 @@ struct LPCNetState {
|
|||
float deemph_mem;
|
||||
};
|
||||
|
||||
|
||||
struct LPCNetDecState {
|
||||
LPCNetState lpcnet_state;
|
||||
float vq_mem[NB_BANDS];
|
||||
};
|
||||
|
||||
struct LPCNetEncState{
|
||||
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 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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue