From ac7c48b4dee99d4c772f133d70d8d1b38262fcd2 Mon Sep 17 00:00:00 2001 From: Author Name Date: Fri, 7 Jul 2023 12:20:59 +0930 Subject: shallow zip-file copy from codec2 e9d726bf20 --- misc/16_8_short.c | 47 ++++++ misc/CMakeLists.txt | 35 +++++ misc/de.c | 59 +++++++ misc/extract.c | 117 ++++++++++++++ misc/ge_train.c | 306 +++++++++++++++++++++++++++++++++++++ misc/genlsp.c | 183 ++++++++++++++++++++++ misc/mksine.c | 54 +++++++ misc/pre.c | 59 +++++++ misc/raw2h.c | 45 ++++++ misc/speexnoisesup.c | 58 +++++++ misc/tcodec2.c | 220 ++++++++++++++++++++++++++ misc/tdec.c | 141 +++++++++++++++++ misc/timpulse.c | 128 ++++++++++++++++ misc/tinterp.c | 151 ++++++++++++++++++ misc/tlininterp.c | 153 +++++++++++++++++++ misc/tnlp.c | 164 ++++++++++++++++++++ misc/tprede.c | 53 +++++++ misc/tquant.c | 214 ++++++++++++++++++++++++++ misc/tsrc.c | 109 +++++++++++++ misc/vq_binary_switch.c | 296 +++++++++++++++++++++++++++++++++++ misc/vq_mbest.c | 302 ++++++++++++++++++++++++++++++++++++ misc/vqtrain.c | 399 ++++++++++++++++++++++++++++++++++++++++++++++++ 22 files changed, 3293 insertions(+) create mode 100644 misc/16_8_short.c create mode 100644 misc/CMakeLists.txt create mode 100644 misc/de.c create mode 100644 misc/extract.c create mode 100644 misc/ge_train.c create mode 100644 misc/genlsp.c create mode 100644 misc/mksine.c create mode 100644 misc/pre.c create mode 100644 misc/raw2h.c create mode 100644 misc/speexnoisesup.c create mode 100644 misc/tcodec2.c create mode 100644 misc/tdec.c create mode 100644 misc/timpulse.c create mode 100644 misc/tinterp.c create mode 100644 misc/tlininterp.c create mode 100644 misc/tnlp.c create mode 100644 misc/tprede.c create mode 100644 misc/tquant.c create mode 100644 misc/tsrc.c create mode 100644 misc/vq_binary_switch.c create mode 100644 misc/vq_mbest.c create mode 100644 misc/vqtrain.c (limited to 'misc') diff --git a/misc/16_8_short.c b/misc/16_8_short.c new file mode 100644 index 0000000..a23722c --- /dev/null +++ b/misc/16_8_short.c @@ -0,0 +1,47 @@ +/* + 16_8_short.c + David Rowe + October 2018 + + Utility for resampling raw files from 16 to 8 kHz. +*/ + +#include +#include +#include +#include +#include "codec2_fdmdv.h" + +#define N8 160 /* procssing buffer size at 8 kHz */ +#define N16 (N8*FDMDV_OS) + +int main(int argc, char *argv[]) { + short in16k_short[FDMDV_OS_TAPS_16K + N16]; + FILE *f16; + short out8k_short[N16]; + FILE *f8; + int i; + + if (argc != 3) { + fprintf(stderr, "usage: %s 16kHz.raw 8kHz.raw\n", argv[0]); + exit(1); + } + f16 = fopen(argv[1], "rb"); + assert(f16 != NULL); + f8 = fopen(argv[2], "wb"); + assert(f8 != NULL); + + /* clear filter memories */ + + for(i=0; i +#include +#include +#include +#include +#include +#include "lpc.h" + +#define N 80 + +int main(int argc, char *argv[]) { + FILE *fin, *fout; + short buf[N]; + float Sn[N], Sn_de[N]; + float de_mem = 0.0; + int i; + + if (argc != 3) { + printf("usage: de InputRawSpeechFile OutputRawSpeechFile\n"); + printf("e.g de input.raw output.raw"); + exit(1); + } + + if (strcmp(argv[1], "-") == 0) fin = stdin; + else if ( (fin = fopen(argv[1],"rb")) == NULL ) { + fprintf(stderr, "Error opening input speech file: %s: %s.\n", + argv[1], strerror(errno)); + exit(1); + } + + if (strcmp(argv[2], "-") == 0) fout = stdout; + else if ( (fout = fopen(argv[2],"wb")) == NULL ) { + fprintf(stderr, "Error opening output speech file: %s: %s.\n", + argv[2], strerror(errno)); + exit(1); + } + + while(fread(buf, sizeof(short), N, fin) == N) { + for(i=0; i +#include +#include +#include + +#define NB_FEATURES 55 /* number of cols per row */ + +int main(int argc, char *argv[]) { + FILE *fin, *fout; + int st = 0; + int en = 17; + int stride = NB_FEATURES; + float gain = 1.0; + int frame_delay = 1; + float pred = 0.0; + int removemean = 0; + float lower = -1E32; + + static struct option long_options[] = { + {"startcol", required_argument, 0, 's'}, + {"endcol", required_argument, 0, 'e'}, + {"stride", required_argument, 0, 't'}, + {"gain", required_argument, 0, 'g'}, + {"pred", required_argument, 0, 'p'}, + {"delay", required_argument, 0, 'd'}, + {"removemean", no_argument, 0, 'm'}, + {"lower", required_argument, 0, 'l'}, + {0, 0, 0, 0} + }; + + int opt_index = 0; + int c; + + while ((c = getopt_long (argc, argv, "s:e:t:g:p:d:ml:", long_options, &opt_index)) != -1) { + switch (c) { + case 's': + st = atoi(optarg); + break; + case 'e': + en = atoi(optarg); + break; + case 't': + stride = atoi(optarg); + break; + case 'g': + gain = atof(optarg); + break; + case 'p': + pred = atof(optarg); + break; + case 'd': + frame_delay = atoi(optarg); + break; + case 'm': + removemean = 1; + break; + case 'l': + lower = atof(optarg); + break; + default: + helpmsg: + fprintf(stderr, "usage: %s -s startCol -e endCol [-t strideCol -g gain -p predCoeff -d framesDelay --removemean --lower] input.f32 output.f32\n", argv[0]); + exit(1); + } + } + if ( (argc - optind) < 2) { + fprintf(stderr, "Too few arguments\n"); + goto helpmsg; + } + + fin = fopen(argv[optind],"rb"); assert(fin != NULL); + fout = fopen(argv[optind+1],"wb"); assert(fout != NULL); + printf("extracting from %d to %d inclusive (stride %d) ... gain = %f pred = %f frame_delay = %d\n", + st, en, stride, gain, pred, frame_delay); + + float features[stride], features_prev[frame_delay][stride], delta[stride]; + int i,f,wr=0; + + for (f=0; f lower) { + fwrite(&delta[st], sizeof(float), en-st+1, fout); + wr++; + } + for (f=frame_delay-1; f>0; f--) + for(i=0; i quantized + + The first column is the log2 of the pitch compared to the lowest freq, + so log2(wo/pi*4000/50) where wo is the frequency your patch outputs. The + second column is the energy in dB, so 10*log10(1e-4+E) +*/ + +/* + Copyright (C) 2012 Jean-Marc Valin + + All rights reserved. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 2.1, as + published by the Free Software Foundation. This program is + distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program; if not, see . +*/ + +#include + +#include +#include +#include + +#define MIN(a,b) ((a)<(b)?(a):(b)) +//#define COEF 0.0 + +static float COEF[2] = {0.8, 0.9}; +//static float COEF[2] = {0.0, 0.}; + +#define MAX_ENTRIES 16384 + +void compute_weights2(const float *x, const float *xp, float *w, int ndim) +{ + w[0] = 30; + w[1] = 1; + if (x[1]<0) + { + w[0] *= .6; + w[1] *= .3; + } + if (x[1]<-10) + { + w[0] *= .3; + w[1] *= .3; + } + /* Higher weight if pitch is stable */ + if (fabs(x[0]-xp[0])<.2) + { + w[0] *= 2; + w[1] *= 1.5; + } else if (fabs(x[0]-xp[0])>.5) /* Lower if not stable */ + { + w[0] *= .5; + } + + /* Lower weight for low energy */ + if (x[1] < xp[1]-10) + { + w[1] *= .5; + } + if (x[1] < xp[1]-20) + { + w[1] *= .5; + } + + //w[0] = 30; + //w[1] = 1; + + /* Square the weights because it's applied on the squared error */ + w[0] *= w[0]; + w[1] *= w[1]; + +} + +int find_nearest_weighted(const float *codebook, int nb_entries, float *x, const float *w, int ndim) +{ + int i, j; + float min_dist = 1e15; + int nearest = 0; + + for (i=0;i. +*/ + +#define P 12 /* LP order */ +#define LSP_DELTA1 0.01 /* grid spacing for LSP root searches */ +#define NW 279 /* frame size in samples */ +#define N 80 /* frame to frame shift */ +#define THRESH 40.0 /* threshold energy/sample for frame inclusion */ +#define PI 3.141592654 /* mathematical constant */ + +#include +#include +#include +#include +#include "lpc.h" /* LPC analysis functions */ +#include "lsp.h" /* LSP encode/decode functions */ + +int switch_present(sw,argc,argv) + char sw[]; /* switch in string form */ + int argc; /* number of command line arguments */ + char *argv[]; /* array of command line arguments in string form */ +{ + int i; /* loop variable */ + + for(i=1; i THRESH) { + af++; + printf("Active Frame: %ld unstables: %d\n",af, unstables); + + find_aks(Sn, ak, NW, P, &Eres); + roots = lpc_to_lsp(ak, P , lsp, 5, LSP_DELTA1); + if (roots == P) { + if (lspd) { + if (log) { + fprintf(flsp,"%f ",log10(lsp[0])); + for(i=1; i +#include +#include +#include +#include +#include + +#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 +#include +#include +#include +#include +#include +#include "lpc.h" + +#define N 80 + +int main(int argc, char*argv[]) { + FILE *fin, *fout; + short buf[N]; + float Sn[N], Sn_pre[N]; + float pre_mem = 0.0; + int i; + + if (argc != 3) { + printf("usage: pre InputRawSpeechFile OutputRawSpeechFile\n"); + printf("e.g pre input.raw output.raw\n"); + exit(1); + } + + if (strcmp(argv[1], "-") == 0) fin = stdin; + else if ( (fin = fopen(argv[1],"rb")) == NULL ) { + fprintf(stderr, "Error opening input speech file: %s: %s.\n", + argv[1], strerror(errno)); + exit(1); + } + + if (strcmp(argv[2], "-") == 0) fout = stdout; + else if ( (fout = fopen(argv[2],"wb")) == NULL ) { + fprintf(stderr, "Error opening output speech file: %s: %s.\n", + argv[2], strerror(errno)); + exit(1); + } + + while(fread(buf, sizeof(short), N, fin) == N) { + for(i=0; i +#include +#include +#include + +int main(int argc, char *argv[]) { + FILE *fraw, *fheader; + int i, samples, ret; + short sam; + + if (argc != 5) { + printf("usage: %s inputRawFile outputHeaderFile arrayName samples\n", argv[0]); + exit(1); + } + + fraw = fopen(argv[1] ,"rb"); + assert(fraw != NULL); + fheader = fopen(argv[2],"wt"); + assert(fheader != NULL); + samples = atoi(argv[4]); + + fprintf(fheader, "short %s[] = {\n", argv[3]); + for(i=0; i +#include +#include +#include +#include +#include + +#define N 80 +#define FS 8000 + +int main(int argc, char *argv[]) { + FILE *fin, *fout; + short buf[N]; + SpeexPreprocessState *st; + + if (argc < 2) { + printf("usage: %s InFile OutFile\n", argv[0]); + exit(0); + } + + if (strcmp(argv[1], "-") == 0) fin = stdin; + else if ( (fin = fopen(argv[1],"rb")) == NULL ) { + fprintf(stderr, "Error opening %s\n", argv[1]); + exit(1); + } + + if (strcmp(argv[2], "-") == 0) fout = stdout; + else if ((fout = fopen(argv[2],"wb")) == NULL) { + fprintf(stderr, "Error opening %s\n", argv[2]); + exit(1); + } + + st = speex_preprocess_state_init(N, FS); + + while(fread(buf, sizeof(short), N, fin) == N) { + speex_preprocess_run(st, buf); + fwrite(buf, sizeof(short), N, fout); + if (fout == stdout) fflush(stdout); + } + + speex_preprocess_state_destroy(st); + + fclose(fin); + fclose(fout); + + return 0; +} diff --git a/misc/tcodec2.c b/misc/tcodec2.c new file mode 100644 index 0000000..ecb81d7 --- /dev/null +++ b/misc/tcodec2.c @@ -0,0 +1,220 @@ +/*---------------------------------------------------------------------------*\ + + FILE........: tcodec2.c + AUTHOR......: David Rowe + DATE CREATED: 24/8/10 + + Test program for codec2.c functions. + +\*---------------------------------------------------------------------------*/ + +/* + Copyright (C) 2010 David Rowe + + All rights reserved. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 2.1, as + published by the Free Software Foundation. This program is + distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program; if not, see . +*/ + +#include +#include +#include +#include +#include +#include "defines.h" +#include "comp.h" +#include "codec2.h" +#include "quantise.h" +#include "interp.h" + +/* CODEC2 struct copies from codec2.c to help with testing */ + +struct CODEC2 { + int mode; + float w[M]; /* time domain hamming window */ + COMP W[FFT_ENC]; /* DFT of w[] */ + float Pn[2*N]; /* trapezoidal synthesis window */ + float Sn[M]; /* input speech */ + float hpf_states[2]; /* high pass filter states */ + void *nlp; /* pitch predictor states */ + float Sn_[2*N]; /* synthesised output speech */ + float ex_phase; /* excitation model phase track */ + float bg_est; /* background noise estimate for post filter */ + float prev_Wo; /* previous frame's pitch estimate */ + MODEL prev_model; /* previous frame's model parameters */ + float prev_lsps_[LPC_ORD]; /* previous frame's LSPs */ + float prev_energy; /* previous frame's LPC energy */ +}; + +void analyse_one_frame(struct CODEC2 *c2, MODEL *model, short speech[]); +void synthesise_one_frame(struct CODEC2 *c2, short speech[], MODEL *model, float ak[]); + +int test1() +{ + FILE *fin, *fout; + short buf[N]; + struct CODEC2 *c2; + MODEL model; + float ak[LPC_ORD+1]; + float lsps[LPC_ORD]; + + c2 = codec2_create(CODEC2_MODE_2400); + + fin = fopen("../raw/hts1a.raw", "rb"); + assert(fin != NULL); + fout = fopen("hts1a_test.raw", "wb"); + assert(fout != NULL); + + while(fread(buf, sizeof(short), N, fin) == N) { + analyse_one_frame(c2, &model, buf); + speech_to_uq_lsps(lsps, ak, c2->Sn, c2->w, LPC_ORD); + synthesise_one_frame(c2, buf, &model, ak); + fwrite(buf, sizeof(short), N, fout); + } + + codec2_destroy(c2); + + fclose(fin); + fclose(fout); + + return 0; +} + +int test2() +{ + FILE *fin, *fout; + short buf[2*N]; + struct CODEC2 *c2; + MODEL model, model_interp; + float ak[LPC_ORD+1]; + int voiced1, voiced2; + int lsp_indexes[LPC_ORD]; + int energy_index; + int Wo_index; + char *bits; + int nbit; + int i; + float lsps[LPC_ORD]; + float e; + + c2 = codec2_create(CODEC2_MODE_2400); + bits = (char*)malloc(codec2_bits_per_frame(c2)); + assert(bits != NULL); + fin = fopen("../raw/hts1a.raw", "rb"); + assert(fin != NULL); + fout = fopen("hts1a_test.raw", "wb"); + assert(fout != NULL); + + while(fread(buf, sizeof(short), 2*N, fin) == 2*N) { + /* first 10ms analysis frame - we just want voicing */ + + analyse_one_frame(c2, &model, buf); + voiced1 = model.voiced; + + /* second 10ms analysis frame */ + + analyse_one_frame(c2, &model, &buf[N]); + voiced2 = model.voiced; + + Wo_index = encode_Wo(model.Wo); + e = speech_to_uq_lsps(lsps, ak, c2->Sn, c2->w, LPC_ORD); + encode_lsps_scalar(lsp_indexes, lsps, LPC_ORD); + energy_index = encode_energy(e); + nbit = 0; + pack((unsigned char*)bits, (unsigned *)&nbit, Wo_index, WO_BITS); + for(i=0; iprev_model, &model); + + synthesise_one_frame(c2, buf, &model_interp, ak); + synthesise_one_frame(c2, &buf[N], &model, ak); + + memcpy(&c2->prev_model, &model, sizeof(MODEL)); + fwrite(buf, sizeof(short), 2*N, fout); + } + + free(bits); + codec2_destroy(c2); + + fclose(fin); + fclose(fout); + + return 0; +} + +int test3() +{ + FILE *fin, *fout, *fbits; + short buf1[2*N]; + short buf2[2*N]; + char *bits; + struct CODEC2 *c2; + + c2 = codec2_create(CODEC2_MODE_2400); + int numBits = codec2_bits_per_frame(c2); + int numBytes = (numBits+7)>>3; + + bits = (char*)malloc(numBytes); + + fin = fopen("../raw/hts1a.raw", "rb"); + assert(fin != NULL); + fout = fopen("hts1a_test.raw", "wb"); + assert(fout != NULL); + fbits = fopen("hts1a_test3.bit", "wb"); + assert(fout != NULL); + + while(fread(buf1, sizeof(short), 2*N, fin) == 2*N) { + codec2_encode(c2, (void*)bits, buf1); + fwrite(bits, sizeof(char), numBytes, fbits); + codec2_decode(c2, buf2, (void*)bits); + fwrite(buf2, sizeof(short), numBytes, fout); + } + + free(bits); + codec2_destroy(c2); + + fclose(fin); + fclose(fout); + fclose(fbits); + + return 0; +} + +int main() { + test3(); + return 0; +} diff --git a/misc/tdec.c b/misc/tdec.c new file mode 100644 index 0000000..501edc6 --- /dev/null +++ b/misc/tdec.c @@ -0,0 +1,141 @@ +/* + tdec.c + David Rowe + Jan 2017 + + Trivial non filtered decimator for high ration sample rate conversion. + + build: gcc tdec.c -o tdec -Wall -O2 + +*/ + +#include +#include +#include +#include +#include +#include + +#define SIGNED_16BIT 0 +#define SIGNED_8BIT 1 +#define UNSIGNED_8BIT 2 + +void freq_shift_complex_buf(short buf[], int n, int lo_i[], int lo_q[]); + +void display_help(void) { + fprintf(stderr, "\nusage: tdec inputRawFile OutputRawFile DecimationRatio [-c]\n"); + fprintf(stderr, "\nUse - for stdin/stdout\n\n"); + fprintf(stderr, "-c complex signed 16 bit input and output\n"); + fprintf(stderr, "-d complex signed 8 bit input (e.g. HackRF), complex signed 16 bit output\n"); + fprintf(stderr, "-e complex unsigned 8 bit input (e.g. RTL-SDR), complex signed 16 bit output\n"); + fprintf(stderr, "-f -Fs/4 freq shift\n\n"); +} + +int main(int argc, char *argv[]) { + FILE *fin, *fout; + short dec; + int lo_i[3], lo_q[3]; + + if (argc < 3) { + display_help(); + exit(1); + } + + if (strcmp(argv[1], "-") == 0) + fin = stdin; + else + fin = fopen(argv[1], "rb"); + assert(fin != NULL); + + if (strcmp(argv[2], "-") == 0) + fout = stdout; + else + fout = fopen(argv[2], "wb"); + assert(fout != NULL); + + dec = atoi(argv[3]); + + int channels = 1; + int freq_shift = 0; + lo_i[0] = -1; lo_i[1] = 0; + lo_q[0] = 0; lo_q[1] = -1; + int opt; + int format = SIGNED_16BIT; + while ((opt = getopt(argc, argv, "cdef")) != -1) { + switch (opt) { + case 'c': channels = 2; break; + case 'd': channels = 2; format = SIGNED_8BIT; break; + case 'e': channels = 2; format = UNSIGNED_8BIT; break; + case 'f': freq_shift = 1; break; + default: + display_help(); + exit(1); + } + } + + if (format == SIGNED_16BIT) { + short buf[dec*channels]; + while(fread(buf, sizeof(short)*channels, dec, fin) == dec) { + if (freq_shift) + freq_shift_complex_buf(buf, dec*channels, lo_i, lo_q); + fwrite(buf, sizeof(short), channels, fout); + } + } + else { + uint8_t inbuf[dec*channels]; + short outbuf[dec*channels]; + short sam, i; + + while(fread(inbuf, sizeof(uint8_t)*channels, dec, fin) == dec) { + for (i=0; i +#include +#include +#include +#include + +#define FS 8000 + +int main(int argc, char *argv[]) { + short buf[FS] = {0}; + float f0 = 60.0; + float n0 = 0.0; + int Nsecs = 1; + int randf0 = 0; + int filter = 0; + int rande = 0; + + int o = 0; + int opt_idx = 0; + while( o != -1 ) { + static struct option long_opts[] = { + {"help", no_argument, 0, 'h'}, + {"n0", required_argument, 0, 'n'}, + {"f0", required_argument, 0, 'f'}, + {"secs", required_argument, 0, 's'}, + {"randf0", no_argument, 0, 'r'}, + {"rande", required_argument, 0, 'e'}, + {"filter", no_argument, 0, 'i'}, + {0, 0, 0, 0} + }; + + o = getopt_long(argc,argv,"hn:f:s:r",long_opts,&opt_idx); + + switch(o) { + case 'n': + n0 = atof(optarg); + break; + case 'f': + f0 = atof(optarg); + break; + case 's': + Nsecs = atoi(optarg); + break; + case 'r': + randf0 = 1; + break; + case 'i': + filter = 1; + break; + case 'e': + rande = atoi(optarg); + break; + case '?': + case 'h': + fprintf(stderr, + "usage: %s\n" + "[--f0 f0Hz] fixed F0\n" + "[--n0 samples] time offset\n" + "[--secs Nsecs] number of seconds to generate\n" + "[--randf0] choose a random F0 every second\n" + "[--rande Ndiscrete] choose a random frame energy every second, Ndiscrete values\n" + "\n", argv[0]); + exit(1); + break; + } + } + + int t = 0; + float A = 100.0; + + /* optionally filter with 2nd order system */ + float alpha = 0.25*M_PI, gamma=0.99; + float a[2] = {-2.0*gamma*cos(alpha), gamma*gamma}; + float mem[2] = {0}; + + for (int j=0; j. +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "defines.h" +#include "sine.h" +#include "interp.h" + +void make_amp(MODEL *model, float f0, float cdB, float mdBHz) +{ + int i; + float mdBrad = mdBHz*FS/TWO_PI; + + model->Wo = f0*TWO_PI/FS; + model->L = PI/model->Wo; + for(i=0; i<=model->L; i++) + model->A[i] = pow(10.0,(cdB + (float)i*model->Wo*mdBrad)/20.0); + model->voiced = 1; +} + +void write_amp(char file[], MODEL *model) +{ + FILE *f; + int i; + + f = fopen(file,"wt"); + for(i=1; i<=model->L; i++) + fprintf(f, "%f\t%f\n", model->Wo*i, model->A[i]); + fclose(f); +} + +const char *get_next_float(const char *s, float *num) +{ + const char *p = s; + char tmp[MAX_STR]; + + while(*p && !isspace(*p)) + p++; + assert((p-s) < (int)(sizeof(tmp)-1)); + memcpy(tmp, s, p-s); + tmp[p-s] = 0; + *num = atof(tmp); + + return p+1; +} + +const char *get_next_int(const char *s, int *num) +{ + const char *p = s; + char tmp[MAX_STR]; + + while(*p && !isspace(*p)) + p++; + assert((p-s) < (int)(sizeof(tmp)-1)); + memcpy(tmp, s, p-s); + tmp[p-s] = 0; + *num = atoi(tmp); + + return p+1; +} + +void load_amp(MODEL *model, const char * file, int frame) +{ + FILE *f; + int i; + char s[1024]; + const char *ps; + + f = fopen(file,"rt"); + assert(f); + + for(i=0; iWo); + ps = get_next_int(ps, &model->L); + for(i=1; i<=model->L; i++) + ps = get_next_float(ps, &model->A[i]); + + fclose(f); +} + +void load_or_make_amp(MODEL *model, + const char * filename, int frame, + float f0, float cdB, float mdBHz) +{ + struct stat buf; + int rc = stat(filename, &buf); + if (rc || !S_ISREG(buf.st_mode) || ((buf.st_mode & S_IRUSR) != S_IRUSR)) + { + make_amp(model, f0, cdB, mdBHz); + } + else + { + load_amp(model, filename, frame); + } +} +int main() { + MODEL prev, next, interp; + + load_or_make_amp(&prev, + "../src/hts1a_model.txt", 32, + 50.0, 60.0, 6E-3); + load_or_make_amp(&next, + "../src/hts1a_model.txt", 34, + 50.0, 40.0, 6E-3); + + interp.voiced = 1; + interpolate(&interp, &prev, &next); + + write_amp("tinterp_prev.txt", &prev); + write_amp("tinterp_interp.txt", &interp); + write_amp("tinterp_next.txt", &next); + + return 0; +} diff --git a/misc/tlininterp.c b/misc/tlininterp.c new file mode 100644 index 0000000..7db6791 --- /dev/null +++ b/misc/tlininterp.c @@ -0,0 +1,153 @@ +/* + tlininterp.c + David Rowe + Jan 2017 + + Fast linear interpolator for high oversampling rates. Upsample + with a decent filter first such that the signal is "low pass" wrt + to the input sample rate. + + build: gcc tlininterp.c -o tlininterp -Wall -O2 + +*/ + +#include +#include +#include +#include +#include +#include + +#define NBUF 1000 +#define SIGNED_16BIT 0 +#define SIGNED_8BIT 1 + +void display_help(void) { + fprintf(stderr, "\nusage: tlininterp inputRawFile OutputRawFile OverSampleRatio [-c]\n"); + fprintf(stderr, "\nUse - for stdin/stdout\n\n"); + fprintf(stderr, "-c complex signed 16 bit input and output\n"); + fprintf(stderr, "-d complex signed 16 bit input, complex signed 8 bit output\n"); + fprintf(stderr, "-f +Fs/4 freq shift\n\n"); +} + +int main(int argc, char *argv[]) { + FILE *fin, *fout; + short left[2], right[2], out[2*NBUF], i; + float oversample, t; + int8_t out_s8[2*NBUF]; + int lo_i[3], lo_q[3]; + + if (argc < 3) { + display_help(); + exit(1); + } + + if (strcmp(argv[1], "-") == 0) + fin = stdin; + else + fin = fopen(argv[1], "rb"); + assert(fin != NULL); + + if (strcmp(argv[2], "-") == 0) + fout = stdout; + else + fout = fopen(argv[2], "wb"); + assert(fout != NULL); + + oversample = atof(argv[3]); + if (oversample <= 1) { + display_help(); + exit(1); + } + + int channels = 1; + int freq_shift = 0; + lo_i[0] = -1; lo_i[1] = 0; + lo_q[0] = 0; lo_q[1] = -1; + int format = SIGNED_16BIT; + int opt; + while ((opt = getopt(argc, argv, "cdf")) != -1) { + switch (opt) { + case 'c': channels = 2; break; + case 'd': channels = 2; format = SIGNED_8BIT; break; + case 'f': freq_shift = 1; break; + default: + display_help(); + exit(1); + } + } + + for (i=0; i> 8; + } + fwrite(&out_s8, sizeof(int8_t)*channels, NBUF, fout); + } + j = 0; + } + + t += 1.0/oversample; + } + + t -= 1.0; + for (i=0; i> 8; + } + fwrite(&out_s8, sizeof(int8_t)*channels, j, fout); + } + + fclose(fout); + fclose(fin); + + return 0; +} diff --git a/misc/tnlp.c b/misc/tnlp.c new file mode 100644 index 0000000..35e2ea4 --- /dev/null +++ b/misc/tnlp.c @@ -0,0 +1,164 @@ +/*---------------------------------------------------------------------------*\ + + FILE........: tnlp.c + AUTHOR......: David Rowe + DATE CREATED: 23/3/93 + + Test program for non linear pitch estimation functions. + +\*---------------------------------------------------------------------------*/ + +/* + Copyright (C) 2009 David Rowe + + All rights reserved. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 2.1, as + published by the Free Software Foundation. This program is + distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program; if not, see . +*/ + + +#include +#include +#include +#include + +#include "defines.h" +#include "dump.h" +#include "sine.h" +#include "nlp.h" +#include "kiss_fft.h" + +int frames; + +/*---------------------------------------------------------------------------*\ + + switch_present() + + Searches the command line arguments for a "switch". If the switch is + found, returns the command line argument where it ws found, else returns + NULL. + +\*---------------------------------------------------------------------------*/ + +int switch_present(sw,argc,argv) + char sw[]; /* switch in string form */ + int argc; /* number of command line arguments */ + char *argv[]; /* array of command line arguments in string form */ +{ + int i; /* loop variable */ + + for(i=1; i +#include +#include +#include +#include "lpc.h" + +#define N 10 +#define F 10 + +int main() { + FILE *fprede; + float Sn[N], Sn_pre[N], Sn_de[N]; + float pre_mem = 0.0, de_mem = 0.0; + int i, f; + + fprede = fopen("prede.txt", "wt"); + assert(fprede != NULL); + + for(i=0; i. +*/ + +#include +#include +#include +#include +#include + +#include "defines.h" +#include "dump.h" +#include "quantise.h" + +int test_Wo_quant(); +int test_lsp_quant(); +int test_lsp(int lsp_number, int levels, float max_error_hz); +int test_energy_quant(int levels, float max_error_dB); + +int main() { + quantise_init(); + test_Wo_quant(); + test_lsp_quant(); + test_energy_quant(E_LEVELS, 0.5*(E_MAX_DB - E_MIN_DB)/E_LEVELS); + + return 0; +} + +int test_lsp_quant() { + test_lsp( 1, 16, 12.5); + test_lsp( 2, 16, 12.5); + test_lsp( 3, 16, 25); + test_lsp( 4, 16, 50); + test_lsp( 5, 16, 50); + test_lsp( 6, 16, 50); + test_lsp( 7, 16, 50); + test_lsp( 8, 8, 50); + test_lsp( 9, 8, 50); + test_lsp(10, 4, 100); + + return 0; +} + +int test_energy_quant(int levels, float max_error_dB) { + FILE *fe; + float e,e_dec, error, low_e, high_e; + int index, index_in, index_out, i; + + /* check 1:1 match between input and output levels */ + + for(i=0; i max_error_dB) { + printf("error: %f %f\n", error, max_error_dB); + exit(0); + } + } + + fclose(fe); + return 0; +} + +int test_lsp(int lsp_number, int levels, float max_error_hz) { + float lsp[LPC_ORD]; + int indexes_in[LPC_ORD]; + int indexes_out[LPC_ORD]; + int indexes[LPC_ORD]; + int i; + float lowf, highf, f, error; + char s[MAX_STR]; + FILE *flsp; + float max_error_rads; + + lsp_number--; + max_error_rads = max_error_hz*TWO_PI/FS; + + for(i=0; i max_error_rads) { + printf("%d error: %f %f\n", lsp_number+1, error, max_error_rads); + exit(0); + } + } + + fclose(flsp); + + printf("OK\n"); + + return 0; +} + +int test_Wo_quant() { + int c; + FILE *f; + float Wo,Wo_dec, error, step_size; + int index, index_in, index_out; + + /* output Wo quant curve for plotting */ + + f = fopen("quant_pitch.txt","wt"); + + for(Wo=0.9*(TWO_PI/P_MAX); Wo<=1.1*(TWO_PI/P_MIN); Wo += 0.001) { + index = encode_Wo(Wo, WO_BITS); + fprintf(f, "%f %d\n", Wo, index); + } + + fclose(f); + + /* check for all Wo codes we get 1:1 match between encoder + and decoder Wo levels */ + + for(c=0; c (step_size/2.0)) { + printf("error: %f step_size/2: %f\n", error, step_size/2.0); + exit(0); + } + fprintf(f,"%f\n",error); + } + printf("OK\n"); + + fclose(f); + return 0; +} diff --git a/misc/tsrc.c b/misc/tsrc.c new file mode 100644 index 0000000..6791b51 --- /dev/null +++ b/misc/tsrc.c @@ -0,0 +1,109 @@ +/* + tsrc.c + David Rowe + Sat Nov 3 2012 + + Unit test for libresample code. + + build: gcc tsrc.c -o tsrc -lm -lsamplerate + + */ + +#include +#include +#include +#include +#include +#include +#include + +#define N 10000 /* processing buffer size */ + +void display_help(void) { + fprintf(stderr, "\nusage: tsrc inputRawFile OutputRawFile OutSampleRatio [-l] [-c]\n"); + fprintf(stderr, "\nUse - for stdin/stdout\n\n"); + fprintf(stderr, "-l fast linear resampler\n"); + fprintf(stderr, "-c complex (two channel) resampling\n\n"); +} + +int main(int argc, char *argv[]) { + FILE *fin, *fout; + short in_short[N], out_short[N]; + float in[N], out[N]; + SRC_STATE *src; + SRC_DATA data; + int error, nin, nremaining, i; + + if (argc < 3) { + display_help(); + exit(1); + } + + if (strcmp(argv[1], "-") == 0) + fin = stdin; + else + fin = fopen(argv[1], "rb"); + assert(fin != NULL); + + if (strcmp(argv[2], "-") == 0) + fout = stdout; + else + fout = fopen(argv[2], "wb"); + assert(fout != NULL); + + data.data_in = in; + data.data_out = out; + data.end_of_input = 0; + data.src_ratio = atof(argv[3]); + + int channels = 1; + int resampler = SRC_SINC_FASTEST; + int opt; + while ((opt = getopt(argc, argv, "lc")) != -1) { + switch (opt) { + case 'l': resampler = SRC_LINEAR; break; + case 'c': channels = 2; break; + default: + display_help(); + exit(1); + } + } + + data.input_frames = N/channels; + data.output_frames = N/channels; + + src = src_new(resampler, channels, &error); + assert(src != NULL); + + int total_in = 0; + int total_out = 0; + + nin = data.input_frames; + nremaining = 0; + while(fread(&in_short[nremaining*channels], sizeof(short)*channels, nin, fin) == nin) { + src_short_to_float_array(in_short, in, N); + error = src_process(src, &data); + assert(error == 0); + src_float_to_short_array(out, out_short, data.output_frames_gen*channels); + + fwrite(out_short, sizeof(short), data.output_frames_gen*channels, fout); + if (fout == stdout) fflush(stdout); + + nremaining = data.input_frames - data.input_frames_used; + nin = data.input_frames_used; + //fprintf(stderr, "input frames: %d output_frames %d nremaining: %d\n", + // (int)data.input_frames_used, (int)data.output_frames_gen, nremaining); + for(i=0; i +#include +#include +#include +#include +#include +#include +#include "mbest.h" + +#define MAX_DIM 20 +#define MAX_ENTRIES 4096 + +// equation (33) of [1], total cost of all hamming distance 1 vectors of vq index k +float cost_of_distance_one(float *vq, int n, int dim, float *prob, int k, int st, int en, int verbose) { + int log2N = log2(n); + float c = 0.0; + for (int b=0; b best_delta) { + best_delta = fabs(delta); + best_j = j; + } + } + // unswitch + swap(vq, dim, prob, A[i], j); + } + } //next j + + // printf("best_delta: %f best_j: %d\n", best_delta, best_j); + if (best_delta == 0.0) { + // Hmm, no improvement, lets try the next vector in the sorted cost list + if (i == n-1) finished = 1; else i++; + } else { + // OK keep the switch that minimised the distortion + swap(vq, dim, prob, A[i], best_j); + switches++; + + // save results + FILE *fq=fopen(argv[dx+1], "wb"); + if (fq == NULL) { + fprintf(stderr, "Couldn't open: %s\n", argv[dx+1]); + exit(1); + } + int nwr = fwrite(vq, sizeof(float), n*dim, fq); + assert(nwr == n*dim); + fclose(fq); + + // set up for next iteration + iteration++; + float distortion = distortion_of_current_mapping(vq, n, dim, prob, st, en); + fprintf(stderr, "it: %3d dist: %f %3.2f i: %3d sw: %3d\n", iteration, distortion, + distortion/distortion0, i, switches); + if (iteration >= max_iter) finished = 1; + i = 0; + } + } + + return 0; +} + diff --git a/misc/vq_mbest.c b/misc/vq_mbest.c new file mode 100644 index 0000000..a247f61 --- /dev/null +++ b/misc/vq_mbest.c @@ -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 +#include +#include +#include +#include +#include +#include +#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; ilist[j].index[s1]; + } + /* target is residual err[] vector given path to this candidate */ + for(i=0; ilist[0].index[num_stages-1-s]; + } + + /* OK put it all back together using best survivor */ + for(i=0; i. +*/ + +/*-----------------------------------------------------------------------*\ + + INCLUDES + +\*-----------------------------------------------------------------------*/ + +#include +#include +#include +#include +#include +#include +#include +#include + +/*-----------------------------------------------------------------------*\ + + DEFINES + +\*-----------------------------------------------------------------------*/ + +#define DELTAQ 0.005 /* quitting distortion */ +#define MAX_STR 80 /* maximum string length */ + +/*-----------------------------------------------------------------------*\ + + FUNCTION PROTOTYPES + +\*-----------------------------------------------------------------------*/ + +void zero(float v[], int k); +void acc(float v1[], float v2[], int k); +void norm(float v[], int k, long n); +long quantise(float cb[], float vec[], int k, int m, int st, int en, float *beste, float *se); + +/*-----------------------------------------------------------------------* \ + + MAIN + +\*-----------------------------------------------------------------------*/ + +int main(int argc, char *argv[]) { + long k,m; /* dimension and codebook size */ + float *vec; /* current vector */ + float *cb; /* vector codebook */ + float *cent; /* centroids for each codebook entry */ + long *n; /* number of vectors in this interval */ + long J; /* number of vectors in training set */ + long i,j; + long ind; /* index of current vector */ + float e; /* squared error for current vector */ + float se; /* squared error for this iteration */ + float var,var_1; /* current and previous iterations distortion */ + float delta; /* improvement in distortion */ + long noutliers[3];/* number of vectors quantisers with > 3*sd */ + FILE *ftrain; /* file containing training set */ + FILE *fvq; /* file containing vector quantiser */ + int ret; + float deltaq_stop = DELTAQ; + FILE *fres = NULL; + int st = -1; + int en = -1; + int init_rand = 0; + + int o = 0; + int opt_idx = 0; + while( o != -1 ) { + static struct option long_opts[] = { + {"help", no_argument, 0, 'h'}, + {"residual", required_argument, 0, 'r'}, + {"stop", required_argument, 0, 's'}, + {"st", required_argument, 0, 't'}, + {"en", required_argument, 0, 'e'}, + {"rand", no_argument, 0, 'i'}, + {0, 0, 0, 0} + }; + + o = getopt_long(argc,argv,"hr:s:t:e:",long_opts,&opt_idx); + + switch(o) { + case 'r': + fres = fopen(optarg,"wb"); assert(fres != NULL); + //fprintf(stderr, "writing res to : %s \n", optarg); + break; + case 's': + deltaq_stop = atof(optarg); + //fprintf(stderr, "deltaq_stop :%f\n", deltaq_stop); + break; + case 't': + st = atoi(optarg); + break; + case 'e': + en = atoi(optarg); + break; + case 'i': + init_rand = 1; + break; + case 'h': + case '?': + goto helpmsg; + break; + } + } + int dx = optind; + + if ((argc - dx) < 4) { + fprintf(stderr, "Too few arguments\n"); + helpmsg: + fprintf(stderr, "usage: %s [Options] TrainFile.f32 K(dimension) M(codebook size) VQFile.f32\n", argv[0]); + fprintf(stderr, " -r --residual VQResidualErrorFile.f32\n"); + fprintf(stderr, " -s --stop StopDelta\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, " --rand use random sampling for initial VQ population\n"); + exit(1); + } + + /* Open training file */ + ftrain = fopen(argv[dx],"rb"); + if (ftrain == NULL) { + printf("Error opening training database file: %s\n",argv[dx]); + exit(1); + } + + /* determine k and m, and allocate arrays */ + k = atol(argv[dx+1]); + m = atol(argv[dx+2]); + + /* default to measuring error on entire vector */ + if (st == -1) st = 0; + if (en == -1) en = k-1; + + printf("vector dimension K=%ld codebook size M=%ld ", k, m); + vec = (float*)malloc(sizeof(float)*k); + cb = (float*)malloc(sizeof(float)*k*m); + cent = (float*)malloc(sizeof(float)*k*m); + n = (long*)malloc(sizeof(long)*m); + if (vec == NULL || cb == NULL || cent == NULL || n == NULL) { + printf("Error in malloc.\n"); + exit(1); + } + + /* determine size of training set */ + J = 0; zero(cent, k); + while(fread(vec, sizeof(float), k, ftrain) == (size_t)k) { + J++; + acc(cent, vec, k); + } + printf("J=%ld vectors in training set\n", J); + + /* Lets measure 0 bit VQ (i.e. mean of training set) as starting point */ + norm(cent, k, J); + memcpy(cb, cent, k*sizeof(float)); + se = 0.0; + rewind(ftrain); + for(i=0; i 1.0) noutliers[0]++; + if (sqrt(e/(en-st+1)) > 2.0) noutliers[1]++; + if (sqrt(e/(en-st+1)) > 3.0) noutliers[2]++; + } + var = se/(J*(en-st+1)); + delta = (var_1-var)/var; + int n_min = J; + int n_max = 0; + for(i=0; i n_max) n_max = n[i]; + } + printf("\r It: %2ld, var: %5f sd: %f outliers > 1/2/3 dB = %3.2f/%3.2f/%3.2f Delta = %5.4f %d %d\n", j, var, sqrt(var), + (float)noutliers[0]/J, (float)noutliers[1]/J, (float)noutliers[2]/J, delta, n_min, n_max); + j++; + + /* determine new codebook from centroids */ + if (delta > deltaq_stop) + for(i=0; i deltaq_stop); + + /* save VQ to disk */ + fvq = fopen(argv[dx+3],"wt"); + if (fvq == NULL) { + printf("Error opening VQ file: %s\n",argv[dx+3]); + exit(1); + } + + fwrite(cb, sizeof(float), m*k, fvq); + + /* optionally output residual error for next stage VQ */ + if (fres != NULL) { + float res[k]; + rewind(ftrain); + for(j=0; j