mirror of https://github.com/drowe67/codec2.git
files previously in misc, needed for ctests
parent
ccfd83c27a
commit
3532e024e2
|
@ -0,0 +1,54 @@
|
||||||
|
/*
|
||||||
|
mksine.c
|
||||||
|
David Rowe
|
||||||
|
10 Nov 2010
|
||||||
|
|
||||||
|
Creates a file of sine wave samples.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <math.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#define TWO_PI 6.283185307
|
||||||
|
#define FS 8000.0
|
||||||
|
|
||||||
|
int main(int argc, char *argv[]) {
|
||||||
|
FILE *f;
|
||||||
|
int i,n;
|
||||||
|
float freq, length;
|
||||||
|
short *buf;
|
||||||
|
float amp = 1E4;
|
||||||
|
|
||||||
|
if (argc < 4) {
|
||||||
|
printf("usage: %s outputFile frequencyHz lengthSecs [PeakAmp]\n", argv[0]);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strcmp(argv[1], "-") == 0) {
|
||||||
|
f = stdout;
|
||||||
|
} else if ( (f = fopen(argv[1],"wb")) == NULL ) {
|
||||||
|
fprintf(stderr, "Error opening output file: %s: %s.\n", argv[3], strerror(errno));
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
freq = atof(argv[2]);
|
||||||
|
length = atof(argv[3]);
|
||||||
|
if (argc == 5) amp = atof(argv[4]);
|
||||||
|
|
||||||
|
n = length*FS;
|
||||||
|
buf = (short*)malloc(sizeof(short)*n);
|
||||||
|
assert(buf != NULL);
|
||||||
|
|
||||||
|
for(i=0; i<n; i++)
|
||||||
|
buf[i] = amp*cos(freq*i*(TWO_PI/FS));
|
||||||
|
|
||||||
|
fwrite(buf, sizeof(short), n, f);
|
||||||
|
|
||||||
|
fclose(f);
|
||||||
|
free(buf);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -0,0 +1,302 @@
|
||||||
|
/*
|
||||||
|
vq_mbest.c
|
||||||
|
David Rowe Dec 2019
|
||||||
|
|
||||||
|
Utility to perform a mbest VQ search on vectors from stdin, sending
|
||||||
|
quantised vectors to stdout.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <getopt.h>
|
||||||
|
#include <math.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include "mbest.h"
|
||||||
|
|
||||||
|
#define MAX_K 20
|
||||||
|
#define MAX_ENTRIES 4096
|
||||||
|
#define MAX_STAGES 5
|
||||||
|
|
||||||
|
void quant_mbest(float vec_out[],
|
||||||
|
int indexes[],
|
||||||
|
float vec_in[],
|
||||||
|
int num_stages,
|
||||||
|
float vqw[], float vq[],
|
||||||
|
int m[], int k,
|
||||||
|
int mbest_survivors);
|
||||||
|
|
||||||
|
int verbose = 0;
|
||||||
|
|
||||||
|
int main(int argc, char *argv[]) {
|
||||||
|
float vq[MAX_STAGES*MAX_K*MAX_ENTRIES];
|
||||||
|
float vqw[MAX_STAGES*MAX_K*MAX_ENTRIES];
|
||||||
|
int m[MAX_STAGES];
|
||||||
|
int k=0, mbest_survivors=1, num_stages=0;
|
||||||
|
char fnames[256], fn[256], *comma, *p;
|
||||||
|
FILE *fq;
|
||||||
|
float lower = -1E32;
|
||||||
|
int st = -1;
|
||||||
|
int en = -1;
|
||||||
|
int num = INT_MAX;
|
||||||
|
int output_vec_usage = 0;
|
||||||
|
|
||||||
|
int o = 0; int opt_idx = 0;
|
||||||
|
while (o != -1) {
|
||||||
|
static struct option long_opts[] = {
|
||||||
|
{"k", required_argument, 0, 'k'},
|
||||||
|
{"quant", required_argument, 0, 'q'},
|
||||||
|
{"mbest", required_argument, 0, 'm'},
|
||||||
|
{"lower", required_argument, 0, 'l'},
|
||||||
|
{"verbose", required_argument, 0, 'v'},
|
||||||
|
{"st", required_argument, 0, 't'},
|
||||||
|
{"en", required_argument, 0, 'e'},
|
||||||
|
{"num", required_argument, 0, 'n'},
|
||||||
|
{"vec_usage", no_argument, 0, 'u'},
|
||||||
|
{0, 0, 0, 0}
|
||||||
|
};
|
||||||
|
|
||||||
|
o = getopt_long(argc,argv,"hk:q:m:vt:e:n:u",long_opts,&opt_idx);
|
||||||
|
switch (o) {
|
||||||
|
case 'k':
|
||||||
|
k = atoi(optarg);
|
||||||
|
assert(k <= MAX_K);
|
||||||
|
break;
|
||||||
|
case 'q':
|
||||||
|
/* load up list of comma delimited file names */
|
||||||
|
strcpy(fnames, optarg);
|
||||||
|
p = fnames;
|
||||||
|
num_stages = 0;
|
||||||
|
do {
|
||||||
|
assert(num_stages < MAX_STAGES);
|
||||||
|
strcpy(fn, p);
|
||||||
|
comma = strchr(fn, ',');
|
||||||
|
if (comma) {
|
||||||
|
*comma = 0;
|
||||||
|
p = comma+1;
|
||||||
|
}
|
||||||
|
/* load quantiser file */
|
||||||
|
fprintf(stderr, "stage: %d loading %s ... ", num_stages, fn);
|
||||||
|
fq=fopen(fn, "rb");
|
||||||
|
if (fq == NULL) {
|
||||||
|
fprintf(stderr, "Couldn't open: %s\n", fn);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
/* count how many entries m of dimension k are in this VQ file */
|
||||||
|
m[num_stages] = 0;
|
||||||
|
float dummy[k];
|
||||||
|
while (fread(dummy, sizeof(float), k, fq) == (size_t)k)
|
||||||
|
m[num_stages]++;
|
||||||
|
assert(m[num_stages] <= MAX_ENTRIES);
|
||||||
|
fprintf(stderr, "%d entries of vectors width %d\n", m[num_stages], k);
|
||||||
|
/* now load VQ into memory */
|
||||||
|
rewind(fq);
|
||||||
|
int rd = fread(&vq[num_stages*k*MAX_ENTRIES], sizeof(float), m[num_stages]*k, fq);
|
||||||
|
assert(rd == m[num_stages]*k);
|
||||||
|
num_stages++;
|
||||||
|
fclose(fq);
|
||||||
|
} while(comma);
|
||||||
|
break;
|
||||||
|
case 'm':
|
||||||
|
mbest_survivors = atoi(optarg);
|
||||||
|
fprintf(stderr, "mbest_survivors = %d\n", mbest_survivors);
|
||||||
|
break;
|
||||||
|
case 'n':
|
||||||
|
num = atoi(optarg);
|
||||||
|
break;
|
||||||
|
case 'l':
|
||||||
|
lower = atof(optarg);
|
||||||
|
break;
|
||||||
|
case 't':
|
||||||
|
st = atoi(optarg);
|
||||||
|
break;
|
||||||
|
case 'e':
|
||||||
|
en = atoi(optarg);
|
||||||
|
break;
|
||||||
|
case 'u':
|
||||||
|
output_vec_usage = 1;
|
||||||
|
break;
|
||||||
|
case 'v':
|
||||||
|
verbose = 1;
|
||||||
|
break;
|
||||||
|
help:
|
||||||
|
fprintf(stderr, "\n");
|
||||||
|
fprintf(stderr, "usage: %s -k dimension -q vq1.f32,vq2.f32,.... [Options]\n", argv[0]);
|
||||||
|
fprintf(stderr, "\n");
|
||||||
|
fprintf(stderr, "input vectors on stdin, output quantised vectors on stdout\n");
|
||||||
|
fprintf(stderr, "\n");
|
||||||
|
fprintf(stderr, "--lower lowermeanLimit Only count vectors with average above this level in distortion calculations\n");
|
||||||
|
fprintf(stderr, "--mbest N number of survivors at each stage, set to 0 for standard VQ search\n");
|
||||||
|
fprintf(stderr, "--st Kst start vector element for error calculation (default 0)\n");
|
||||||
|
fprintf(stderr, "--en Ken end vector element for error calculation (default K-1)\n");
|
||||||
|
fprintf(stderr, "--num numToProcess number of vectors to quantise (default to EOF)\n");
|
||||||
|
fprintf(stderr, "--vec_usage Output a record of how many times each vector is used\n");
|
||||||
|
fprintf(stderr, "-v Verbose\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((num_stages == 0) || (k == 0))
|
||||||
|
goto help;
|
||||||
|
|
||||||
|
/* default to measuring error on entire vector */
|
||||||
|
if (st == -1) st = 0;
|
||||||
|
if (en == -1) en = k-1;
|
||||||
|
|
||||||
|
float w[k];
|
||||||
|
for(int i=0; i<st; i++)
|
||||||
|
w[i] = 0.0;
|
||||||
|
for(int i=st; i<=en; i++)
|
||||||
|
w[i] = 1.0;
|
||||||
|
for(int i=en+1; i<k; i++)
|
||||||
|
w[i] = 0.0;
|
||||||
|
|
||||||
|
/* apply weighting to codebook (rather than in search) */
|
||||||
|
memcpy(vqw, vq, sizeof(vq));
|
||||||
|
for(int s=0; s<num_stages; s++) {
|
||||||
|
mbest_precompute_weight(&vqw[s*k*MAX_ENTRIES], w, k, m[s]);
|
||||||
|
}
|
||||||
|
|
||||||
|
int indexes[num_stages], nvecs = 0; int vec_usage[m[0]];
|
||||||
|
for(int i=0; i<m[0]; i++) vec_usage[i] = 0;
|
||||||
|
float target[k], quantised[k];
|
||||||
|
float sqe = 0.0;
|
||||||
|
while(fread(&target, sizeof(float), k, stdin) && (nvecs < num)) {
|
||||||
|
for(int i=0; i<k; i++)
|
||||||
|
target[i] *= w[i];
|
||||||
|
int dont_count = 0;
|
||||||
|
/* optional clamping to lower limit or mean */
|
||||||
|
float mean = 0.0;
|
||||||
|
for(int i=0; i<k; i++)
|
||||||
|
mean += target[i];
|
||||||
|
mean /= k;
|
||||||
|
float difference = mean - lower;
|
||||||
|
if (difference < 0.0) {
|
||||||
|
/* bring target up to lower clamping limit */
|
||||||
|
for(int i=0; i<k; i++)
|
||||||
|
target[i] += -difference;
|
||||||
|
dont_count = 1;
|
||||||
|
}
|
||||||
|
quant_mbest(quantised, indexes, target, num_stages, vqw, vq, m, k, mbest_survivors);
|
||||||
|
if (dont_count == 0) {
|
||||||
|
for(int i=st; i<=en; i++)
|
||||||
|
sqe += pow(target[i]-quantised[i], 2.0);
|
||||||
|
}
|
||||||
|
fwrite(&quantised, sizeof(float), k, stdout);
|
||||||
|
nvecs++;
|
||||||
|
// count number f time each vector is used (just for first stage)
|
||||||
|
vec_usage[indexes[0]]++;
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(stderr, "MSE: %4.2f\n", sqe/(nvecs*(en-st+1)));
|
||||||
|
|
||||||
|
if (output_vec_usage) {
|
||||||
|
for(int i=0; i<m[0]; i++)
|
||||||
|
fprintf(stderr, "%d\n", vec_usage[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// print vector debug function
|
||||||
|
|
||||||
|
void pv(char s[], float v[], int k) {
|
||||||
|
int i;
|
||||||
|
if (verbose) {
|
||||||
|
fprintf(stderr, "%s",s);
|
||||||
|
for(i=0; i<k; i++)
|
||||||
|
fprintf(stderr, "%4.2f ", v[i]);
|
||||||
|
fprintf(stderr, "\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// mbest algorithm version, backported from LPCNet/src
|
||||||
|
|
||||||
|
void quant_mbest(float vec_out[],
|
||||||
|
int indexes[],
|
||||||
|
float vec_in[],
|
||||||
|
int num_stages,
|
||||||
|
float vqw[], float vq[],
|
||||||
|
int m[], int k,
|
||||||
|
int mbest_survivors)
|
||||||
|
{
|
||||||
|
float err[k], se1;
|
||||||
|
int i,j,s,s1,ind;
|
||||||
|
|
||||||
|
struct MBEST *mbest_stage[num_stages];
|
||||||
|
int index[num_stages];
|
||||||
|
float target[k];
|
||||||
|
|
||||||
|
for(i=0; i<num_stages; i++) {
|
||||||
|
mbest_stage[i] = mbest_create(mbest_survivors);
|
||||||
|
index[i] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
se1 = 0.0;
|
||||||
|
for(i=0; i<k; i++) {
|
||||||
|
err[i] = vec_in[i];
|
||||||
|
se1 += err[i]*err[i];
|
||||||
|
}
|
||||||
|
se1 /= k;
|
||||||
|
|
||||||
|
/* now quantise err[] using multi-stage mbest search, preserving
|
||||||
|
mbest_survivors at each stage */
|
||||||
|
|
||||||
|
mbest_search(vqw, err, k, m[0], mbest_stage[0], index);
|
||||||
|
if (verbose) mbest_print("Stage 1:", mbest_stage[0]);
|
||||||
|
|
||||||
|
for(s=1; s<num_stages; s++) {
|
||||||
|
|
||||||
|
/* for each candidate in previous stage, try to find best vector in next stage */
|
||||||
|
for (j=0; j<mbest_survivors; j++) {
|
||||||
|
/* indexes that lead us this far */
|
||||||
|
for(s1=0; s1<s; s1++) {
|
||||||
|
index[s1+1] = mbest_stage[s-1]->list[j].index[s1];
|
||||||
|
}
|
||||||
|
/* target is residual err[] vector given path to this candidate */
|
||||||
|
for(i=0; i<k; i++)
|
||||||
|
target[i] = err[i];
|
||||||
|
for(s1=0; s1<s; s1++) {
|
||||||
|
ind = index[s-s1];
|
||||||
|
if (verbose) fprintf(stderr, " s: %d s1: %d s-s1: %d ind: %d\n", s,s1,s-s1,ind);
|
||||||
|
for(i=0; i<k; i++) {
|
||||||
|
target[i] -= vqw[s1*k*MAX_ENTRIES+ind*k+i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pv(" target: ", target, k);
|
||||||
|
mbest_search(&vqw[s*k*MAX_ENTRIES], target, k, m[s], mbest_stage[s], index);
|
||||||
|
}
|
||||||
|
char str[80]; sprintf(str,"Stage %d:", s+1);
|
||||||
|
if (verbose) mbest_print(str, mbest_stage[s]);
|
||||||
|
}
|
||||||
|
|
||||||
|
for(s=0; s<num_stages; s++) {
|
||||||
|
indexes[s] = mbest_stage[num_stages-1]->list[0].index[num_stages-1-s];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* OK put it all back together using best survivor */
|
||||||
|
for(i=0; i<k; i++)
|
||||||
|
vec_out[i] = 0.0;
|
||||||
|
for(s=0; s<num_stages; s++) {
|
||||||
|
int ind = indexes[s];
|
||||||
|
float se2 = 0.0;
|
||||||
|
for(i=0; i<k; i++) {
|
||||||
|
err[i] -= vqw[s*k*MAX_ENTRIES+ind*k+i];
|
||||||
|
vec_out[i] += vq[s*k*MAX_ENTRIES+ind*k+i];
|
||||||
|
se2 += err[i]*err[i];
|
||||||
|
}
|
||||||
|
se2 /= k;
|
||||||
|
pv(" err: ", err, k);
|
||||||
|
if (verbose) fprintf(stderr, " se2: %f\n", se2);
|
||||||
|
}
|
||||||
|
pv(" vec_out: ",vec_out, k);
|
||||||
|
|
||||||
|
pv("\n vec_in: ", vec_in, k);
|
||||||
|
pv(" vec_out: ", vec_out, k);
|
||||||
|
pv(" err: ", err, k);
|
||||||
|
if (verbose) fprintf(stderr, " se1: %f\n", se1);
|
||||||
|
|
||||||
|
for(i=0; i<num_stages; i++)
|
||||||
|
mbest_destroy(mbest_stage[i]);
|
||||||
|
}
|
Loading…
Reference in New Issue