first pass at adding index optimised direct VQ

pull/42/head
David Rowe 2021-12-31 10:37:23 +10:30
parent 0dc5935bbf
commit 72d21386c6
7 changed files with 61 additions and 18 deletions

File diff suppressed because one or more lines are too long

View File

@ -12,6 +12,7 @@ set(lpcnet_freedv_srcs
lpcnet_dump.c
4stage_pred_vq.c
4stage_direct_split_vq.c
4stage_direct_split_indopt_vq.c
lpcnet.c
lpcnet_freedv.c
nnet.c

View File

@ -61,7 +61,7 @@ int main(int argc, char **argv) {
int *m = pred_m;
float *vq = pred_vq;
int logmag = 0;
int direct_split = 0;
int vq_type = LPCNET_PRED;
fin = stdin;
fout = stdout;
@ -77,7 +77,8 @@ int main(int argc, char **argv) {
{"numstages", required_argument, 0, 'n'},
{"pitchquant", required_argument, 0, 'o'},
{"pred", required_argument, 0, 'p'},
{"directsplit", no_argument, 0, 's'},
{"split", no_argument, 0, 's'},
{"indexopt", no_argument, 0, 'x'},
{"verbose", no_argument, 0, 'v'},
{0, 0, 0, 0}
};
@ -85,7 +86,7 @@ int main(int argc, char **argv) {
int c;
int opt_index = 0;
while ((c = getopt_long (argc, argv, "b:d:n:o:p:svi:u:r:", long_options, &opt_index)) != -1) {
while ((c = getopt_long (argc, argv, "b:d:n:o:p:sxvi:u:r:", long_options, &opt_index)) != -1) {
switch (c) {
case 'i':
if ((fin = fopen(optarg, "rb")) == NULL) {
@ -124,8 +125,14 @@ int main(int argc, char **argv) {
nnet_read(optarg);
break;
case 's':
direct_split = 1; m = direct_split_m; vq = direct_split_vq; pred = 0.0; logmag = 1; weight = 1.0;
fprintf(stderr, "split VQ\n");
vq_type = LPCNET_DIRECT_SPLIT;
m = direct_split_m; vq = direct_split_vq; pred = 0.0; logmag = 1; weight = 1.0;
fprintf(stderr, "direct split VQ\n");
break;
case 'x':
vq_type = LPCNET_DIRECT_SPLIT_INDEX_OPT;
m = direct_split_indopt_m; vq = direct_split_indopt_vq; pred = 0.0; logmag = 1; weight = 1.0;
fprintf(stderr, "index optimised direct split VQ\n");
break;
case 'v':
lpcnet_verbose = 1;
@ -142,7 +149,7 @@ int main(int argc, char **argv) {
}
}
LPCNetFreeDV *lf = lpcnet_freedv_create(direct_split);
LPCNetFreeDV *lf = lpcnet_freedv_create(vq_type);
lpcnet_open_test_file(lf->net, "test_lpcnet_statesq.f32");
LPCNET_QUANT *q = lf->q;

View File

@ -56,7 +56,7 @@ int main(int argc, char **argv) {
int *m = pred_m;
float *vq = pred_vq;
int logmag = 0;
int direct_split = 0;
int vq_type = LPCNET_PRED;
fin = stdin;
fout = stdout;
@ -70,7 +70,8 @@ int main(int argc, char **argv) {
{"numstages", required_argument, 0, 'n'},
{"pitchquant", required_argument, 0, 'o'},
{"pred", required_argument, 0, 'p'},
{"directsplit", no_argument, 0, 's'},
{"split", no_argument, 0, 's'},
{"indexopt", no_argument, 0, 'x'},
{"verbose", no_argument, 0, 'v'},
{0, 0, 0, 0}
};
@ -78,7 +79,7 @@ int main(int argc, char **argv) {
int c;
int opt_index = 0;
while ((c = getopt_long (argc, argv, "d:n:o:p:svi:u:", long_options, &opt_index)) != -1) {
while ((c = getopt_long (argc, argv, "d:n:o:p:sxvi:u:", long_options, &opt_index)) != -1) {
switch (c) {
case 'i':
if ((fin = fopen(optarg, "rb")) == NULL) {
@ -109,9 +110,14 @@ int main(int argc, char **argv) {
fprintf(stderr, "pred = %f\n", pred);
break;
case 's':
direct_split = 1;
vq_type = LPCNET_DIRECT_SPLIT;
m = direct_split_m; vq = direct_split_vq; pred = 0.0; logmag = 1; weight = 1.0;
fprintf(stderr, "split VQ\n");
fprintf(stderr, "direct split VQ\n");
break;
case 'x':
vq_type = LPCNET_DIRECT_SPLIT_INDEX_OPT;
m = direct_split_indopt_m; vq = direct_split_indopt_vq; pred = 0.0; logmag = 1; weight = 1.0;
fprintf(stderr, "index optimised direct split VQ\n");
break;
case 'v':
lpcnet_verbose = 1;
@ -120,13 +126,15 @@ int main(int argc, char **argv) {
fprintf(stderr,"usage: %s [Options]:\n [-d --decimation 1/2/3...]\n", argv[0]);
fprintf(stderr," [-i --infile]\n [-u --outfile]\n");
fprintf(stderr," [-n --numstages]\n [-o --pitchbits nBits]\n");
fprintf(stderr," [-p --pred predCoff] [-s --split]\n");
fprintf(stderr," [-p --pred predCoff] Predictive quantiser prediction coeff\n");
fprintf(stderr," [-s --directsplit] Use direct split quaniser\n");
fprintf(stderr," [-x --indexopt] Use index optimised direct split quantiser\n");
fprintf(stderr," [-v --verbose]\n");
exit(1);
}
}
LPCNetFreeDV *lf = lpcnet_freedv_create(direct_split);
LPCNetFreeDV *lf = lpcnet_freedv_create(vq_type);
LPCNET_QUANT *q = lf->q;
q->weight = weight; q->pred = pred; q->mbest = mbest_survivors;

View File

@ -12,9 +12,14 @@
extern "C" {
#endif
// possible vq_type values in lpcnet_freedv_create()
#define LPCNET_PRED 0
#define LPCNET_DIRECT_SPLIT 1
#define LPCNET_DIRECT_SPLIT_INDEX_OPT 2
typedef struct LPCNetFreeDV LPCNetFreeDV;
LPCNetFreeDV* lpcnet_freedv_create(int direct_split);
LPCNetFreeDV* lpcnet_freedv_create(int vq_type);
void lpcnet_freedv_destroy(LPCNetFreeDV *lf);
void lpcnet_enc(LPCNetFreeDV *lf, short *pcm, char *frame);
void lpcnet_dec(LPCNetFreeDV *lf, char *frame, short* pcm);

View File

@ -30,13 +30,24 @@ int lpcnet_verbose = 0;
static int quantise(const float * cb, float vec[], float w[], int k, int m, float *se);
LPCNET_QUANT *lpcnet_quant_create(int direct_split) {
LPCNET_QUANT *lpcnet_quant_create(int vq_type) {
assert((vq_type == LPCNET_PRED) || (vq_type == LPCNET_DIRECT_SPLIT) ||
(vq_type == LPCNET_DIRECT_SPLIT_INDEX_OPT));
LPCNET_QUANT *q = (LPCNET_QUANT*)malloc(sizeof(LPCNET_QUANT));
if (q == NULL) return NULL;
if (direct_split) {
if ((vq_type == LPCNET_DIRECT_SPLIT) || (vq_type == LPCNET_DIRECT_SPLIT_INDEX_OPT)) {
q->weight = 1.0; q->pred = 0.0;
q->mbest = DEFAULT_MBEST; q->pitch_bits = DEFAULT_PITCH_BITS; q->dec = DEFAULT_DEC;
q->num_stages = direct_split_num_stages; q->vq = direct_split_vq; q->m = direct_split_m; q->logmag = 1;
q->logmag = 1;
if (vq_type == LPCNET_DIRECT_SPLIT) {
q->num_stages = direct_split_num_stages;
q->m = direct_split_m;
q->vq = direct_split_vq;
} else {
q->num_stages = direct_split_indopt_num_stages;
q->m = direct_split_indopt_m;
q->vq = direct_split_indopt_vq;
}
}
else {
q->weight = DEFAULT_WEIGHT; q->pred = DEFAULT_PRED;

View File

@ -8,6 +8,8 @@
#ifndef __LPCNET_QUANT__
#define __LPCNET_QUANT__
#include "lpcnet_freedv.h"
#define NB_FEATURES 55 /* length of feature vector (only a subset used) */
#define NB_BANDS 18 /* number of bands quantised */
#define MAX_ENTRIES 4096 /* max number of vectors per stage */
@ -32,13 +34,16 @@ typedef struct {
float features_lin[2][NB_FEATURES]; /* adjacent frames features for linear interpolation */
} LPCNET_QUANT;
// Two sorts of VQs available
// VQs available
extern int pred_num_stages;
extern float pred_vq[MAX_STAGES*NB_BANDS*MAX_ENTRIES];
extern int pred_m[MAX_STAGES];
extern int direct_split_num_stages;
extern float direct_split_vq[MAX_STAGES*NB_BANDS*MAX_ENTRIES];
extern int direct_split_m[MAX_STAGES];
extern int direct_split_indopt_num_stages;
extern float direct_split_indopt_vq[MAX_STAGES*NB_BANDS*MAX_ENTRIES];
extern int direct_split_indopt_m[MAX_STAGES];
LPCNET_QUANT *lpcnet_quant_create(int direct_split);
void lpcnet_quant_destroy(LPCNET_QUANT *q);