From 8447234f9b2ae6b024182c786e78be4b63971174 Mon Sep 17 00:00:00 2001 From: drowe67 Date: Fri, 11 May 2012 04:17:14 +0000 Subject: [PATCH] added 1400 bps mode using JVMs joint energy Wo quantiser. Fixed bug in modem where sync bit was decoded inverted. Can now do end-end enc-mod-demod-dec. yayyyyyyyyy git-svn-id: https://svn.code.sf.net/p/freetel/code@416 01035d8c-6547-0410-b346-abe4f91aad63 --- codec2-dev/README | 6 + codec2-dev/README_fdmdv.txt | 2 + codec2-dev/octave/fdmdv.m | 4 +- codec2-dev/src/c2dec.c | 6 +- codec2-dev/src/c2enc.c | 6 +- codec2-dev/src/c2sim.c | 27 ++- codec2-dev/src/codec2.c | 325 ++++++++++++++++++++++++++++++++++- codec2-dev/src/codec2.h | 3 +- codec2-dev/src/fdmdv.c | 4 +- codec2-dev/src/quantise.c | 125 +++++++++++++- codec2-dev/src/quantise.h | 7 +- codec2-dev/unittest/genlsp.c | 2 +- 12 files changed, 480 insertions(+), 37 deletions(-) diff --git a/codec2-dev/README b/codec2-dev/README index 1f5e0e21..3b78e413 100644 --- a/codec2-dev/README +++ b/codec2-dev/README @@ -69,3 +69,9 @@ Directories voicing - hand-estimated voicing files, used for development wav - speech files in wave file format +TODO +---- + +[ ] Make sure we have separate state variables for enc and dec on + modes that use difference in time coding and have statesthat are + presevred from frame to frame. \ No newline at end of file diff --git a/codec2-dev/README_fdmdv.txt b/codec2-dev/README_fdmdv.txt index e67ce80d..9c61bc60 100644 --- a/codec2-dev/README_fdmdv.txt +++ b/codec2-dev/README_fdmdv.txt @@ -55,6 +55,8 @@ $ cd src $ sox -r 8000 -s -2 modem_sample_8kHz.raw -r 48000 modem_sample_48kHz.wav + For real time applications, the fdmdv.[ch] library includes functions to + convert between 48 and 8 kHz sample rates. References ---------- diff --git a/codec2-dev/octave/fdmdv.m b/codec2-dev/octave/fdmdv.m index 1a5ba6ee..303b172b 100644 --- a/codec2-dev/octave/fdmdv.m +++ b/codec2-dev/octave/fdmdv.m @@ -434,10 +434,10 @@ function [rx_bits sync_bit f_err] = qpsk_to_bits(prev_rx_symbols, rx_symbols, mo phase_difference(Nc+1) = rx_symbols(Nc+1) .* conj(prev_rx_symbols(Nc+1)); if (real(phase_difference(Nc+1)) < 0) - sync_bit = 0; + sync_bit = 1; f_err = imag(phase_difference(Nc+1)); else - sync_bit = 1; + sync_bit = 0; f_err = -imag(phase_difference(Nc+1)); end diff --git a/codec2-dev/src/c2dec.c b/codec2-dev/src/c2dec.c index e3d90fd5..ad26f3fa 100644 --- a/codec2-dev/src/c2dec.c +++ b/codec2-dev/src/c2dec.c @@ -44,7 +44,7 @@ int main(int argc, char *argv[]) float ber, r; if (argc < 4) { - printf("usage: c2dec 2500|1500|1125 InputBitFile OutputRawSpeechFile\n"); + printf("usage: c2dec 2500|1500|1400|1125 InputBitFile OutputRawSpeechFile\n"); printf("e.g c2dec 1500 hts1a.c2 hts1a_1500.raw\n"); exit(1); } @@ -53,10 +53,12 @@ int main(int argc, char *argv[]) mode = CODEC2_MODE_2500; else if (strcmp(argv[1],"1500") == 0) mode = CODEC2_MODE_1500; + else if (strcmp(argv[1],"1400") == 0) + mode = CODEC2_MODE_1400; else if (strcmp(argv[1],"1200") == 0) mode = CODEC2_MODE_1200; else { - fprintf(stderr, "Error in mode: %s. Must be 2500 or 1500 or 1200\n", argv[1]); + fprintf(stderr, "Error in mode: %s. Must be 2500, 1500, 1400 or 1200\n", argv[1]); exit(1); } diff --git a/codec2-dev/src/c2enc.c b/codec2-dev/src/c2enc.c index 8a5fc961..707ad235 100644 --- a/codec2-dev/src/c2enc.c +++ b/codec2-dev/src/c2enc.c @@ -44,7 +44,7 @@ int main(int argc, char *argv[]) int nsam, nbit, nbyte; if (argc != 4) { - printf("usage: c2enc 2500|1500|1200 InputRawspeechFile OutputBitFile\n"); + printf("usage: c2enc 2500|1500|1400|1200 InputRawspeechFile OutputBitFile\n"); printf("e.g c2enc 1500 ../raw/hts1a.raw hts1a.c2\n"); exit(1); } @@ -53,10 +53,12 @@ int main(int argc, char *argv[]) mode = CODEC2_MODE_2500; else if (strcmp(argv[1],"1500") == 0) mode = CODEC2_MODE_1500; + else if (strcmp(argv[1],"1400") == 0) + mode = CODEC2_MODE_1400; else if (strcmp(argv[1],"1200") == 0) mode = CODEC2_MODE_1200; else { - fprintf(stderr, "Error in mode: %s. Must be 2500 or 1500 or 1200\n", argv[1]); + fprintf(stderr, "Error in mode: %s. Must be 2500, 1500, 1400 or 1200\n", argv[1]); exit(1); } diff --git a/codec2-dev/src/c2sim.c b/codec2-dev/src/c2sim.c index 9933797b..2a06ed31 100644 --- a/codec2-dev/src/c2sim.c +++ b/codec2-dev/src/c2sim.c @@ -105,7 +105,7 @@ int main(int argc, char *argv[]) float ak_interp[LPC_MAX]; int lsp_indexes[LPC_MAX]; float lsps_[LPC_MAX]; - float Woe[2], Woe_[2]; + float Woe_[2]; void *nlp_states; float hpf_states[2]; @@ -241,6 +241,14 @@ int main(int argc, char *argv[]) postfilt = 1; decimate = 1; dt = 1; + } else if(strcmp(optarg,"1400") == 0) { + lpc_model = 1; order = 10; + vector_quant_Wo_e = 1; + lsp = 1; lspdt = 1; + phase0 = 1; + postfilt = 1; + decimate = 1; + dt = 1; } else if(strcmp(optarg,"1200") == 0) { lpc_model = 1; order = 10; scalar_quant_Wo_e = 1; @@ -548,19 +556,10 @@ int main(int argc, char *argv[]) /* JVM's experimental joint Wo & LPC energy quantiser */ - Woe[0] = log10((model.Wo/PI)*4000.0/50.0)/log10(2); - Woe[1] = 10.0*log10(1e-4+e); - ge_quantise(Woe, Woe_); - - /* - x = log2(4000*Wo/(PI*50)); - 2^x = 4000*Wo/(PI*50) - Wo = (2^x)*(PI*50)/4000; - */ + printf("\nWo %f e %f\n", model.Wo, e); + quantise_WoE(&model, &e, Woe_); + printf("Wo %f e %f\n", model.Wo, e); - model.Wo = pow(2.0, Woe_[0])*(PI*50.0)/4000.0; - model.L = PI/model.Wo; /* if we quantise Wo re-compute L */ - e = pow(10.0, Woe_[1]/10.0); } aks_to_M2(ak, order, &model, e, &snr, 1); @@ -765,7 +764,7 @@ void print_help(const struct option* long_options, int num_opts, char* argv[]) } else if (strcmp("dump_pitch_e", long_options[i].name) == 0) { option_parameters = " "; } else if (strcmp("rate", long_options[i].name) == 0) { - option_parameters = " <2500|1500|1200>"; + option_parameters = " <2500|1500|1400|1200>"; } else if (strcmp("dump", long_options[i].name) == 0) { option_parameters = " "; } else { diff --git a/codec2-dev/src/codec2.c b/codec2-dev/src/codec2.c index 984b8170..7e1e86ce 100644 --- a/codec2-dev/src/codec2.c +++ b/codec2-dev/src/codec2.c @@ -59,6 +59,9 @@ struct CODEC2 { 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 */ + + float xq_enc[2]; /* joint pitch and energy VQ states */ + float xq_dec[2]; }; /*---------------------------------------------------------------------------*\ @@ -74,6 +77,8 @@ void codec2_encode_2500(struct CODEC2 *c2, unsigned char * bits, short speech[]) void codec2_decode_2500(struct CODEC2 *c2, short speech[], const unsigned char * bits); void codec2_encode_1500(struct CODEC2 *c2, unsigned char * bits, short speech[]); void codec2_decode_1500(struct CODEC2 *c2, short speech[], const unsigned char * bits); +void codec2_encode_1400(struct CODEC2 *c2, unsigned char * bits, short speech[]); +void codec2_decode_1400(struct CODEC2 *c2, short speech[], const unsigned char * bits); void codec2_encode_1200(struct CODEC2 *c2, unsigned char * bits, short speech[]); void codec2_decode_1200(struct CODEC2 *c2, short speech[], const unsigned char * bits); @@ -109,6 +114,7 @@ struct CODEC2 *codec2_create(int mode) assert( (mode == CODEC2_MODE_2500) || (mode == CODEC2_MODE_1500) || + (mode == CODEC2_MODE_1400) || (mode == CODEC2_MODE_1200) ); c2->mode = mode; @@ -141,6 +147,9 @@ struct CODEC2 *codec2_create(int mode) return NULL; } + c2->xq_enc[0] = c2->xq_enc[1] = 0.0; + c2->xq_dec[0] = c2->xq_dec[1] = 0.0; + return c2; } @@ -176,6 +185,8 @@ int codec2_bits_per_frame(struct CODEC2 *c2) { return 50; if (c2->mode == CODEC2_MODE_1500) return 60; + if (c2->mode == CODEC2_MODE_1400) + return 56; if (c2->mode == CODEC2_MODE_1200) return 48; @@ -198,6 +209,8 @@ int codec2_samples_per_frame(struct CODEC2 *c2) { return 160; if (c2->mode == CODEC2_MODE_1500) return 320; + if (c2->mode == CODEC2_MODE_1400) + return 320; if (c2->mode == CODEC2_MODE_1200) return 320; @@ -210,6 +223,7 @@ void codec2_encode(struct CODEC2 *c2, unsigned char *bits, short speech[]) assert( (c2->mode == CODEC2_MODE_2500) || (c2->mode == CODEC2_MODE_1500) || + (c2->mode == CODEC2_MODE_1400) || (c2->mode == CODEC2_MODE_1200) ); @@ -217,6 +231,8 @@ void codec2_encode(struct CODEC2 *c2, unsigned char *bits, short speech[]) codec2_encode_2500(c2, bits, speech); if (c2->mode == CODEC2_MODE_1500) codec2_encode_1500(c2, bits, speech); + if (c2->mode == CODEC2_MODE_1400) + codec2_encode_1400(c2, bits, speech); if (c2->mode == CODEC2_MODE_1200) codec2_encode_1200(c2, bits, speech); } @@ -227,6 +243,7 @@ void codec2_decode(struct CODEC2 *c2, short speech[], const unsigned char *bits) assert( (c2->mode == CODEC2_MODE_2500) || (c2->mode == CODEC2_MODE_1500) || + (c2->mode == CODEC2_MODE_1400) || (c2->mode == CODEC2_MODE_1200) ); @@ -234,6 +251,8 @@ void codec2_decode(struct CODEC2 *c2, short speech[], const unsigned char *bits) codec2_decode_2500(c2, speech, bits); if (c2->mode == CODEC2_MODE_1500) codec2_decode_1500(c2, speech, bits); + if (c2->mode == CODEC2_MODE_1400) + codec2_decode_1400(c2, speech, bits); if (c2->mode == CODEC2_MODE_1200) codec2_decode_1200(c2, speech, bits); } @@ -337,7 +356,7 @@ void codec2_decode_2500(struct CODEC2 *c2, short speech[], const unsigned char * int i; unsigned int nbit = 0; MODEL model_interp; - static int frames; + //static int frames; //fprintf(stderr,"frame: %d\n", frames+=2); assert(c2 != NULL); @@ -426,15 +445,15 @@ void codec2_decode_2500(struct CODEC2 *c2, short speech[], const unsigned char * AUTHOR......: David Rowe DATE CREATED: Nov 14 2011 - Encodes 320 speech samples (40ms of speech) into 60 bits. + Encodes 320 speech samples (40ms of speech) into 60 bits. The codec2 algorithm actually operates internally on 10ms (80 sample) frames, so we run the encoding algorithm for times: frame 0: just send voicing bit - frame 1: scalar quantisation of LSPs and Wo and E + frame 1: scalar quantisation of LSPs, Wo and E frame 2: just send voicing bit - frame 3: delta-time quantisation Wo and E + frame 3: delta-time Wo and scalar E The bit allocation is: @@ -551,9 +570,9 @@ void codec2_encode_1500(struct CODEC2 *c2, unsigned char * bits, short speech[]) FUNCTION....: codec2_decode_1500 AUTHOR......: David Rowe - DATE CREATED: 16 Nov 2011 + DATE CREATED: 11 May 2012 - Decodes frames of 56 bits into 320 samples (40ms) of speech. + Decodes frames of 60 bits into 320 samples (40ms) of speech. \*---------------------------------------------------------------------------*/ @@ -730,6 +749,300 @@ void codec2_decode_1500(struct CODEC2 *c2, short speech[], const unsigned char * } + +/*---------------------------------------------------------------------------*\ + + FUNCTION....: codec2_encode_1400 + AUTHOR......: David Rowe + DATE CREATED: May 11 2012 + + Encodes 320 speech samples (40ms of speech) into 56 bits. + + The codec2 algorithm actually operates internally on 10ms (80 + sample) frames, so we run the encoding algorithm for times: + + frame 0: just send voicing bit + frame 1: scalar quantisation of LSPs, joint VQ of Wo and E + frame 2: just send voicing bit + frame 3: joint VQ of Wo and E + + The bit allocation is: + + Parameter frame 2 frame 4 Total + ------------------------------------------------------- + Harmonic magnitudes (LSPs) 36 0 36 + Energy+Wo 8 8 16 + Voicing (10ms update) 2 2 4 + TOTAL 46 10 56 + +\*---------------------------------------------------------------------------*/ + +void codec2_encode_1400(struct CODEC2 *c2, unsigned char * bits, short speech[]) +{ + MODEL model; + float lsps[LPC_ORD], lsps_[LPC_ORD]; + float ak[LPC_ORD+1]; + float e; + int voiced1, voiced2, voiced3, voiced4; + int lsp_indexes[LPC_ORD]; + int WoE_index; + int i; + unsigned int nbit = 0; + unsigned int nbit_tmp; + //static int frames; + + assert(c2 != NULL); + + memset(bits, '\0', ((codec2_bits_per_frame(c2) + 7) / 8)); + + /* frame 1: - we just want voicing -------------------------------- */ + + //fprintf(stderr,"frame: %d\n", ++frames); + analyse_one_frame(c2, &model, speech); + voiced1 = model.voiced; + + /* frame 2: - full LSP, joint Wo & EE ----------------------------- */ + + //fprintf(stderr,"frame: %d\n", ++frames); + analyse_one_frame(c2, &model, &speech[N]); + voiced2 = model.voiced; + + e = speech_to_uq_lsps(lsps, ak, c2->Sn, c2->w, LPC_ORD); + encode_lsps_scalar(lsp_indexes, lsps, LPC_ORD); + WoE_index = encode_WoE(&model, e, c2->xq_enc); + + for(i=0; iSn, c2->w, LPC_ORD); + + WoE_index = encode_WoE(&model, e, c2->xq_enc); + + //fprintf(stderr," e: %f code: %d dec: %f \n", e, energy_index, decode_energy(energy_index)); + + nbit_tmp = nbit; + pack(bits, &nbit, WoE_index, WO_E_BITS); + pack(bits, &nbit, voiced3, 1); + pack(bits, &nbit, voiced4, 1); + //fprintf(stderr," 00 16 24 32 40 48 56\n"); + //fprintf(stderr,"nbit = %d %02x %02x %02x %02x %02x %02x %02x %02x\n", nbit, + // bits[0], bits[1], bits[2], bits[3], + // bits[4], bits[5], bits[6], bits[7]); + + //fprintf(stderr," nbit_tmp: %d ", nbit_tmp); + // fprintf(stderr,"energy_index after: %d\n", energy_index); + + assert(nbit == (unsigned)codec2_bits_per_frame(c2)); + //if (frames == 36) + //exit(0); +} + + +/*---------------------------------------------------------------------------*\ + + FUNCTION....: codec2_decode_1400 + AUTHOR......: David Rowe + DATE CREATED: 11 May 2012 + + Decodes frames of 48 bits into 320 samples (40ms) of speech. + +\*---------------------------------------------------------------------------*/ + +void codec2_decode_1400(struct CODEC2 *c2, short speech[], const unsigned char * bits) +{ + MODEL model; + int voiced1, voiced2, voiced3, voiced4; + int lsp_indexes[LPC_ORD]; + float lsps_[LPC_ORD]; + int WoE_index; + float energy; + float snr; + float ak[LPC_ORD+1]; + float ak_interp[LPC_ORD+1]; + float lsps_interp[LPC_ORD]; + int i; + unsigned int nbit = 0; + MODEL model_interp; + static int frames; + float prev__Wo; + + assert(c2 != NULL); + + /* unpack frame 1 & 2 bit stream to integer codes */ + + for(i=0; ixq_dec, WoE_index); + memset(&model.A, 0, (model.L+1)*sizeof(model.A[0])); + + /* decode frame 2 LSPs and model amplitudes */ + + decode_lsps_scalar(lsps_, lsp_indexes, LPC_ORD); + check_lsp_order(lsps_, LPC_ORD); + bw_expand_lsps(lsps_, LPC_ORD); + lsp_to_lpc(lsps_, ak, LPC_ORD); + aks_to_M2(ak, LPC_ORD, &model, energy, &snr, 1); + apply_lpc_correction(&model); + + /* interpolate frame 1 model parameters from adjacent frames */ + + model.voiced = voiced2; + model_interp.voiced = voiced1; + model_interp.Wo = P_MAX/2; + memset(&model_interp.A, 0, MAX_AMP*sizeof(model_interp.A[0])); + + interpolate_lsp(&model_interp, &c2->prev_model, &model, + c2->prev_lsps_, c2->prev_energy, lsps_, energy, ak_interp, + lsps_interp); + apply_lpc_correction(&model_interp); + + frames += 2; + /* used for comparing to c2sim version + fprintf(stderr,"frame: %d\n", frames); + fprintf(stderr," Wo: %1.5f L: %d v1: %d prev_e: %f\n", + model_interp.Wo, model_interp.L, model_interp.voiced, c2->prev_energy); + fprintf(stderr," lsps_interp: "); + for(i=0; iprev_model, &model, sizeof(MODEL)); + memcpy(c2->prev_lsps_, lsps_, sizeof(lsps_)); + c2->prev_energy = energy; + prev__Wo = model.Wo; + + /*--------------------------------------------------------------------*/ + + /* unpack frame 3 & 4 bit stream to integer codes */ + + WoE_index = unpack(bits, &nbit, WO_E_BITS); + voiced3 = unpack(bits, &nbit, 1); + voiced4 = unpack(bits, &nbit, 1); + assert(nbit == (unsigned)codec2_bits_per_frame(c2)); + + /* decode integer codes to model parameters */ + + memset(&model.A, 0, (model.L+1)*sizeof(model.A[0])); + + /* decode frame 4 */ + + decode_WoE(&model, &energy, c2->xq_dec, WoE_index); + aks_to_M2(ak, LPC_ORD, &model, energy, &snr, 1); + apply_lpc_correction(&model); + + /* interpolate frame 3 model parameters from adjacent frames */ + + model.voiced = voiced4; + model_interp.voiced = voiced3; + model_interp.Wo = P_MAX/2; + memset(&model_interp.A, 0, MAX_AMP*sizeof(model_interp.A[0])); + + interpolate_lsp(&model_interp, &c2->prev_model, &model, + c2->prev_lsps_, c2->prev_energy, lsps_, energy, ak_interp, + lsps_interp); + apply_lpc_correction(&model_interp); + + frames +=2; + /* used for comparing to c2sim version: + fprintf(stderr,"frame: %d\n", frames); + + fprintf(stderr," Wo: %1.5f L: %d v1: %d prev_e: %f\n", + model_interp.Wo, model_interp.L, model_interp.voiced, c2->prev_energy); + fprintf(stderr," lsps_interp: "); + for(i=0; iprev_model, &model, sizeof(MODEL)); + memcpy(c2->prev_lsps_, lsps_, sizeof(lsps_)); + c2->prev_energy = energy; + +} + + /*---------------------------------------------------------------------------*\ FUNCTION....: codec2_encode_1200 diff --git a/codec2-dev/src/codec2.h b/codec2-dev/src/codec2.h index f45cf2ee..35c81c9d 100644 --- a/codec2-dev/src/codec2.h +++ b/codec2-dev/src/codec2.h @@ -34,7 +34,8 @@ extern "C" { #define CODEC2_MODE_2500 0 #define CODEC2_MODE_1500 1 -#define CODEC2_MODE_1200 2 +#define CODEC2_MODE_1400 2 +#define CODEC2_MODE_1200 3 struct CODEC2; diff --git a/codec2-dev/src/fdmdv.c b/codec2-dev/src/fdmdv.c index bb78ffac..3e8e28a2 100644 --- a/codec2-dev/src/fdmdv.c +++ b/codec2-dev/src/fdmdv.c @@ -937,11 +937,11 @@ float qpsk_to_bits(int rx_bits[], int *sync_bit, COMP phase_difference[], COMP p phase_difference[NC] = cmult(rx_symbols[NC], cconj(prev_rx_symbols[NC])); if (phase_difference[NC].real < 0) { - *sync_bit = 0; + *sync_bit = 1; ferr = phase_difference[NC].imag; } else { - *sync_bit = 1; + *sync_bit = 0; ferr = -phase_difference[NC].imag; } diff --git a/codec2-dev/src/quantise.c b/codec2-dev/src/quantise.c index ad7e4008..8762d0fe 100644 --- a/codec2-dev/src/quantise.c +++ b/codec2-dev/src/quantise.c @@ -1477,27 +1477,98 @@ void compute_weights2(const float *x, const float *xp, float *w, int ndim) /*---------------------------------------------------------------------------*\ - FUNCTION....: quantize_ge() + FUNCTION....: quantise_WoE() AUTHOR......: Jean-Marc Valin & David Rowe DATE CREATED: 29 Feb 2012 - Experimental joint Wo and LPC energy vector quantiser developed my - Jean-Marc Valin. + Experimental joint Wo and LPC energy vector quantiser developed by + Jean-Marc Valin. Exploits correlations between the difference in + the log pitch and log energy from frame to frame. For example the + both the pitch and energy tend to only change by small amounts + during voiced speech, however it is important that these changes be + coded carefully. During unvoiced speech they both change a lot but + the ear is less sensitve to errors so coarser quantisation is OK. + + The ear is sensitive to log energy and loq pitch so we quantise in + thise domains. That way the error measure used to quantise the + values is close to way the ear senses errors. + + See http://jmspeex.livejournal.com/10446.html + +\*---------------------------------------------------------------------------*/ + +void quantise_WoE(MODEL *model, float *e, float xq[]) +{ + int i, n1; + float x[2]; + float err[2]; + float w[2]; + const float *codebook1 = ge_cb[0].cb; + int nb_entries = ge_cb[0].m; + int ndim = ge_cb[0].k; + float Wo_min = TWO_PI/P_MAX; + float Wo_max = TWO_PI/P_MIN; + + x[0] = log10((model->Wo/PI)*4000.0/50.0)/log10(2); + x[1] = 10.0*log10(1e-4 + *e); + + compute_weights2(x, xq, w, ndim); + for (i=0;iWo = pow(2.0, xq[0])*(PI*50.0)/4000.0; + + /* bit errors can make us go out of range leading to all sorts of + probs like seg faults */ + + if (model->Wo > Wo_max) model->Wo = Wo_max; + if (model->Wo < Wo_min) model->Wo = Wo_min; + + model->L = PI/model->Wo; /* if we quantise Wo re-compute L */ + + *e = pow(10.0, xq[1]/10.0); +} + +/*---------------------------------------------------------------------------*\ + + FUNCTION....: encode_WoE() + AUTHOR......: Jean-Marc Valin & David Rowe + DATE CREATED: 11 May 2012 + + Joint Wo and LPC energy vector quantiser developed my Jean-Marc + Valin. Returns index, and updated states xq[]. \*---------------------------------------------------------------------------*/ -void ge_quantise(float *x, float *xq) +int encode_WoE(MODEL *model, float e, float xq[]) { int i, n1; + float x[2]; float err[2]; float w[2]; const float *codebook1 = ge_cb[0].cb; int nb_entries = ge_cb[0].m; int ndim = ge_cb[0].k; - //printf("ndim %d nb_entries %d\n", ndim, nb_entries); + assert((1<Wo/PI)*4000.0/50.0)/log10(2); + x[1] = 10.0*log10(1e-4 + e); + compute_weights2(x, xq, w, ndim); - //exit(0); for (i=0;iWo = pow(2.0, xq[0])*(PI*50.0)/4000.0; + + /* bit errors can make us go out of range leading to all sorts of + probs like seg faults */ + + if (model->Wo > Wo_max) model->Wo = Wo_max; + if (model->Wo < Wo_min) model->Wo = Wo_min; + + model->L = PI/model->Wo; /* if we quantise Wo re-compute L */ + + *e = pow(10.0, xq[1]/10.0); } diff --git a/codec2-dev/src/quantise.h b/codec2-dev/src/quantise.h index 8344a5f0..513e2c26 100644 --- a/codec2-dev/src/quantise.h +++ b/codec2-dev/src/quantise.h @@ -44,6 +44,8 @@ #define LSPDT_LOW 1 #define LSPDT_HIGH 2 +#define WO_E_BITS 8 + void quantise_init(); float lpc_model_amplitudes(float Sn[], float w[], MODEL *model, int order, int lsp,float ak[]); @@ -77,7 +79,10 @@ void lspvq_quantise(float lsp[], float lsp_[], int order); void lspjnd_quantise(float lsp[], float lsp_[], int order); void lspdt_quantise(float lsps[], float lsps_[], float lsps__prev[], int mode); void lspjvm_quantise(float lsps[], float lsps_[], int order); -void ge_quantise(float *x, float *xq); + +void quantise_WoE(MODEL *model, float *e, float xq[]); +int encode_WoE(MODEL *model, float e, float xq[]); +void decode_WoE(MODEL *model, float *e, float xq[], int n1); int encode_energy(float e); float decode_energy(int index); diff --git a/codec2-dev/unittest/genlsp.c b/codec2-dev/unittest/genlsp.c index dc608930..8a05b7fc 100644 --- a/codec2-dev/unittest/genlsp.c +++ b/codec2-dev/unittest/genlsp.c @@ -26,7 +26,7 @@ along with this program; if not, see . */ -#define P 10 /* LP order */ +#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 */ -- 2.25.1