From bb3f9fe5a4f28b174caa3dea722758eef872f9a7 Mon Sep 17 00:00:00 2001 From: drowe67 Date: Thu, 12 Jan 2017 06:49:21 +0000 Subject: [PATCH] debugging codec2.c mode git-svn-id: https://svn.code.sf.net/p/freetel/code@2961 01035d8c-6547-0410-b346-abe4f91aad63 --- codec2-dev/octave/tnewamp1.m | 33 +++-- codec2-dev/src/codec2.c | 236 ++++++++++++++++++++++++++----- codec2-dev/src/codec2.h | 17 +-- codec2-dev/src/codec2_internal.h | 10 ++ codec2-dev/src/newamp1.c | 24 +++- codec2-dev/src/newamp1.h | 1 + codec2-dev/src/phase.c | 13 +- codec2-dev/unittest/tnewamp1.c | 96 ++++++++----- 8 files changed, 339 insertions(+), 91 deletions(-) diff --git a/codec2-dev/octave/tnewamp1.m b/codec2-dev/octave/tnewamp1.m index 6adc9348..7e684709 100644 --- a/codec2-dev/octave/tnewamp1.m +++ b/codec2-dev/octave/tnewamp1.m @@ -101,6 +101,7 @@ function tnewamp1(input_prefix) left_vec = zeros(1,K); for f=1:M:frames + if voicing(f) index = encode_log_Wo(model(f,1), 6); if index == 0 @@ -111,39 +112,41 @@ function tnewamp1(input_prefix) model_(f,1) = 2*pi/100; end + Wo_right = model_(f,1); + voicing_right = voicing(f); + [Wo_ avoicing_] = interp_Wo_v(Wo_left, Wo_right, voicing_left, voicing_right); + if f > M - %Wo1 = model_(f-M,1); - Wo_right = model_(f,1); - voicing_right = voicing(f); - [Wo_ avoicing_] = interp_Wo_v(Wo_left, Wo_right, voicing_left, voicing_right); model_(f-M:f-1,1) = Wo_; voicing_(f-M:f-1) = avoicing_; model_(f-M:f-1,2) = floor(pi ./ model_(f-M:f-1,1)); % calculate L for each interpolated Wo + end - %left_vec = rate_K_surface_(f-M,:); - right_vec = rate_K_surface_(f,:); + right_vec = rate_K_surface_(f,:); + + if f > M sample_points = [f-M f]; resample_points = f-M:f-1; for k=1:K interpolated_surface_(resample_points,k) = interp_linear(sample_points, [left_vec(k) right_vec(k)], resample_points); end - + for k=f-M:f-1 model_(k,:) = resample_rate_L(model_(k,:), interpolated_surface_(k,:), sample_freqs_kHz); phase = determine_phase(model_, k, Nfft_phase); for m=1:model_(k,2) b = round(m*model_(k,1)*Nfft_phase/(2*pi)); % map harmonic centre to DFT bin H(k,m) = exp(-j*phase(b+1)); - end - + end end + end + + % update for next time - % update for next time - - Wo_left = Wo_right; - voicing_left = voicing_right; - left_vec = right_vec; - end + Wo_left = Wo_right; + voicing_left = voicing_right; + left_vec = right_vec; + end %model_(1,1:77) diff --git a/codec2-dev/src/codec2.c b/codec2-dev/src/codec2.c index 438c2cae..a6b57c8f 100644 --- a/codec2-dev/src/codec2.c +++ b/codec2-dev/src/codec2.c @@ -74,6 +74,8 @@ void codec2_encode_700(struct CODEC2 *c2, unsigned char * bits, short speech[]); void codec2_decode_700(struct CODEC2 *c2, short speech[], const unsigned char * bits); void codec2_encode_700b(struct CODEC2 *c2, unsigned char * bits, short speech[]); void codec2_decode_700b(struct CODEC2 *c2, short speech[], const unsigned char * bits); +void codec2_encode_700c(struct CODEC2 *c2, unsigned char * bits, short speech[]); +void codec2_decode_700c(struct CODEC2 *c2, short speech[], const unsigned char * bits); static void ear_protection(float in_out[], int n); /*---------------------------------------------------------------------------*\ @@ -101,17 +103,9 @@ struct CODEC2 * codec2_create(int mode) struct CODEC2 *c2; int i,l; - if ((mode != CODEC2_MODE_3200) && - (mode != CODEC2_MODE_2400) && - (mode != CODEC2_MODE_1600) && - (mode != CODEC2_MODE_1400) && - (mode != CODEC2_MODE_1300) && - (mode != CODEC2_MODE_1200) && - (mode != CODEC2_MODE_700) && - (mode != CODEC2_MODE_700B) - ) { + if (!((mode >= 0) && (mode <= CODEC2_MODE_700C))) { return NULL; - } + } c2 = (struct CODEC2*)malloc(sizeof(struct CODEC2)); if (c2 == NULL) @@ -169,6 +163,22 @@ struct CODEC2 * codec2_create(int mode) c2->softdec = NULL; + /* newamp1 initialisation */ + + if (c2->mode == CODEC2_MODE_700C) { + mel_sample_freqs_kHz(c2->rate_K_sample_freqs_kHz, NEWAMP1_K); + int k; + for(k=0; kprev_rate_K_vec_[k] = 0.0; + } + c2->Wo_left = 0.0; + c2->voicing_left = 0;; + c2->phase_fft_fwd_cfg = codec2_fft_alloc(NEWAMP1_PHASE_NFFT, 0, NULL, NULL); + c2->phase_fft_inv_cfg = codec2_fft_alloc(NEWAMP1_PHASE_NFFT, 1, NULL, NULL); + printf("c2->phase_fft_fwd_cfg: %x\n", c2->phase_fft_fwd_cfg); + printf("c2->phase_fft_inv_cfg: %x\n", c2->phase_fft_inv_cfg); + } + return c2; } @@ -190,6 +200,10 @@ void codec2_destroy(struct CODEC2 *c2) codec2_fft_free(c2->fft_fwd_cfg); codec2_fftr_free(c2->fftr_fwd_cfg); codec2_fftr_free(c2->fftr_inv_cfg); + if (c2->mode == CODEC2_MODE_700C) { + codec2_fft_free(c2->phase_fft_fwd_cfg); + codec2_fft_free(c2->phase_fft_inv_cfg); + } free(c2); } @@ -220,6 +234,8 @@ int codec2_bits_per_frame(struct CODEC2 *c2) { return 28; if (c2->mode == CODEC2_MODE_700B) return 28; + if (c2->mode == CODEC2_MODE_700C) + return 28; return 0; /* shouldn't get here */ } @@ -252,6 +268,8 @@ int codec2_samples_per_frame(struct CODEC2 *c2) { return 320; if (c2->mode == CODEC2_MODE_700B) return 320; + if (c2->mode == CODEC2_MODE_700C) + return 320; return 0; /* shouldnt get here */ } @@ -259,16 +277,7 @@ int codec2_samples_per_frame(struct CODEC2 *c2) { void codec2_encode(struct CODEC2 *c2, unsigned char *bits, short speech[]) { assert(c2 != NULL); - assert( - (c2->mode == CODEC2_MODE_3200) || - (c2->mode == CODEC2_MODE_2400) || - (c2->mode == CODEC2_MODE_1600) || - (c2->mode == CODEC2_MODE_1400) || - (c2->mode == CODEC2_MODE_1300) || - (c2->mode == CODEC2_MODE_1200) || - (c2->mode == CODEC2_MODE_700) || - (c2->mode == CODEC2_MODE_700B) - ); + assert((c2->mode >= CODEC2_MODE_3200) && (c2->mode <= CODEC2_MODE_700C)); if (c2->mode == CODEC2_MODE_3200) codec2_encode_3200(c2, bits, speech); @@ -287,6 +296,8 @@ void codec2_encode(struct CODEC2 *c2, unsigned char *bits, short speech[]) codec2_encode_700(c2, bits, speech); if (c2->mode == CODEC2_MODE_700B) codec2_encode_700b(c2, bits, speech); + if (c2->mode == CODEC2_MODE_700C) + codec2_encode_700c(c2, bits, speech); #endif } @@ -298,16 +309,7 @@ void codec2_decode(struct CODEC2 *c2, short speech[], const unsigned char *bits) void codec2_decode_ber(struct CODEC2 *c2, short speech[], const unsigned char *bits, float ber_est) { assert(c2 != NULL); - assert( - (c2->mode == CODEC2_MODE_3200) || - (c2->mode == CODEC2_MODE_2400) || - (c2->mode == CODEC2_MODE_1600) || - (c2->mode == CODEC2_MODE_1400) || - (c2->mode == CODEC2_MODE_1300) || - (c2->mode == CODEC2_MODE_1200) || - (c2->mode == CODEC2_MODE_700) || - (c2->mode == CODEC2_MODE_700B) - ); + assert((c2->mode >= CODEC2_MODE_3200) && (c2->mode <= CODEC2_MODE_700C)); if (c2->mode == CODEC2_MODE_3200) codec2_decode_3200(c2, speech, bits); @@ -326,6 +328,8 @@ void codec2_decode_ber(struct CODEC2 *c2, short speech[], const unsigned char *b codec2_decode_700(c2, speech, bits); if (c2->mode == CODEC2_MODE_700B) codec2_decode_700b(c2, speech, bits); + if (c2->mode == CODEC2_MODE_700C) + codec2_decode_700c(c2, speech, bits); #endif } @@ -1751,6 +1755,165 @@ void codec2_decode_700b(struct CODEC2 *c2, short speech[], const unsigned char * for(i=0; iprev_lsps_dec[i] = lsps[3][i]; } + + +/*---------------------------------------------------------------------------*\ + + FUNCTION....: codec2_encode_700c + AUTHOR......: David Rowe + DATE CREATED: Jan 2017 + + Version c of 700 bit/s codec that uses newamp1 fixed rate VQ of amplitudes. + + Encodes 320 speech samples (40ms of speech) into 28 bits. + + The codec2 algorithm actually operates internally on 10ms (80 + sample) frames, so we run the encoding algorithm four times: + + frame 0: nothing + frame 1: nothing + frame 2: nothing + frame 3: 18 bit 2 stage VQ (9 bits/stage), 4 bits energy, + 6 bit scalar Wo/voicing. No spare bits. + + Voicing is encoded using the 0 index of the Wo quantiser. + + The bit allocation is: + + Parameter frames 1-3 frame 4 Total + ----------------------------------------------------------- + Harmonic magnitudes (rate k VQ) 0 18 18 + Energy 0 4 4 + log Wo/voicing 0 6 6 + TOTAL 0 28 28 + +\*---------------------------------------------------------------------------*/ + +void codec2_encode_700c(struct CODEC2 *c2, unsigned char * bits, short speech[]) +{ + MODEL model; + int indexes[4], i, M=4; + unsigned int nbit = 0; + static int f = 0; + + assert(c2 != NULL); + + memset(bits, '\0', ((codec2_bits_per_frame(c2) + 7) / 8)); + + analyse_one_frame(c2, &model, speech); + fprintf(stderr,"f: %d Wo: %4.3f L: %d v: %d\n", f, model.Wo, model.L, model.voiced); + f++; + + int K = 20; + float rate_K_vec[K], mean; + float rate_K_vec_no_mean[K], rate_K_vec_no_mean_[K]; + + newamp1_model_to_indexes(indexes, + &model, + rate_K_vec, + c2->rate_K_sample_freqs_kHz, + K, + &mean, + rate_K_vec_no_mean, + rate_K_vec_no_mean_); + + for(i=0; i<5; i++) { + fprintf(stderr," %5.3f", rate_K_vec[i]); + } + fprintf(stderr,"\n"); + fprintf(stderr," %d %d %d %d\n", indexes[0], indexes[1], indexes[2], indexes[3]); + + for(i=1; iprev_rate_K_vec_, + &c2->Wo_left, + &c2->voicing_left, + c2->rate_K_sample_freqs_kHz, + NEWAMP1_K, + c2->phase_fft_fwd_cfg, + c2->phase_fft_inv_cfg, + indexes); + + fprintf(stderr,"f: %d\n", f); + fprintf(stderr," %d %d %d %d\n", indexes[0], indexes[1], indexes[2], indexes[3]); + for(i=0; i<4; i++) { + fprintf(stderr," Wo: %4.3f L: %d v: %d\n", model[i].Wo, model[i].L, model[i].voiced); + } + fprintf(stderr," rate_K_vec: "); + for(i=0; i<5; i++) { + fprintf(stderr,"%5.3f ", c2->prev_rate_K_vec_[i]); + } + fprintf(stderr,"\n"); + fprintf(stderr," H:\n"); + + for(int m=0; mex_phase, H); + if (c2->mode == CODEC2_MODE_700C) { + /* newamp1, we've already worked out rate L phase */ + COMP *H = Aw; + phase_synth_zero_order(model, &c2->ex_phase, H); + } else { + /* LPC based phase synthesis */ + COMP H[MAX_AMP]; + sample_phase(model, H, Aw); + phase_synth_zero_order(model, &c2->ex_phase, H); + } PROFILE_SAMPLE_AND_LOG(pf_start, phase_start, " phase_synth"); diff --git a/codec2-dev/src/codec2.h b/codec2-dev/src/codec2.h index 0e25850d..0e720f92 100644 --- a/codec2-dev/src/codec2.h +++ b/codec2-dev/src/codec2.h @@ -41,6 +41,7 @@ #define CODEC2_MODE_1200 5 #define CODEC2_MODE_700 6 #define CODEC2_MODE_700B 7 +#define CODEC2_MODE_700C 8 struct CODEC2; @@ -54,14 +55,14 @@ int codec2_bits_per_frame(struct CODEC2 *codec2_state); void codec2_set_lpc_post_filter(struct CODEC2 *codec2_state, int enable, int bass_boost, float beta, float gamma); int codec2_get_spare_bit_index(struct CODEC2 *codec2_state); -int codec2_rebuild_spare_bit(struct CODEC2 *codec2_state, int unpacked_bits[]); -void codec2_set_natural_or_gray(struct CODEC2 *codec2_state, int gray); -void codec2_set_softdec(struct CODEC2 *c2, float *softdec); -float codec2_get_energy(struct CODEC2 *codec2_state, const unsigned char *bits); - - -#endif - +int codec2_rebuild_spare_bit(struct CODEC2 *codec2_state, int unpacked_bits[]); +void codec2_set_natural_or_gray(struct CODEC2 *codec2_state, int gray); +void codec2_set_softdec(struct CODEC2 *c2, float *softdec); +float codec2_get_energy(struct CODEC2 *codec2_state, const unsigned char *bits); + + +#endif + #ifdef __cplusplus } #endif diff --git a/codec2-dev/src/codec2_internal.h b/codec2-dev/src/codec2_internal.h index 76c19f4d..519e9b33 100644 --- a/codec2-dev/src/codec2_internal.h +++ b/codec2-dev/src/codec2_internal.h @@ -30,6 +30,7 @@ #define __CODEC2_INTERNAL__ #include "codec2_fft.h" +#include "newamp1.h" struct CODEC2 { int mode; @@ -63,6 +64,15 @@ struct CODEC2 { int smoothing; /* enable smoothing for channels with errors */ float *softdec; /* optional soft decn bits from demod */ + + /* newamp1 states */ + + float rate_K_sample_freqs_kHz[NEWAMP1_K]; + float prev_rate_K_vec_[NEWAMP1_K]; + float Wo_left; + int voicing_left; + codec2_fft_cfg phase_fft_fwd_cfg; + codec2_fft_cfg phase_fft_inv_cfg; }; // test and debug diff --git a/codec2-dev/src/newamp1.c b/codec2-dev/src/newamp1.c index 6736adb5..f9c1da47 100644 --- a/codec2-dev/src/newamp1.c +++ b/codec2-dev/src/newamp1.c @@ -387,11 +387,21 @@ void determine_phase(COMP H[], MODEL *model, int Nfft, codec2_fft_cfg fwd_cfg, c interp_para(Gdbfk, &rate_L_sample_freqs_kHz[1], &AmdB[1], model->L, sample_freqs_kHz, Ns); + fprintf(stderr, " Gdbfk: "); + for(i=0; i<5; i++) + fprintf(stderr, "%5.3f ", Gdbfk[i]); + fprintf(stderr,"\n"); + mag_to_phase(phase, Gdbfk, Nfft, fwd_cfg, inv_cfg); + fprintf(stderr, " phase: "); + for(i=0; i<5; i++) + fprintf(stderr, "%5.3f ", phase[i]); + fprintf(stderr,"\n"); + for(m=1; m<=model->L; m++) { b = floorf(0.5+m*model->Wo*Nfft/(2.0*M_PI)); - H[m].real = cos(phase[b]); H[m].imag = -sin(phase[b]); + H[m].real = cosf(phase[b]); H[m].imag = -sinf(phase[b]); } } @@ -592,6 +602,18 @@ void newamp1_indexes_to_model(MODEL model_[], resample_rate_L(&model_[i], &interpolated_surface_[K*i], rate_K_sample_freqs_kHz, K); determine_phase(&H[(MAX_AMP+1)*i], &model_[i], NEWAMP1_PHASE_NFFT, fwd_cfg, inv_cfg); + + if (i == 0) { + int m; + fprintf(stderr, " Am: "); + for(m=1; m<=5; m++) + fprintf(stderr, "%5.3f ", model_[i].A[m]); + fprintf(stderr,"\n"); + fprintf(stderr, " H: "); + for(m=1; m<=5; m++) + fprintf(stderr, "(%5.3f %5.3f) ", H[(MAX_AMP+1)*i+m].real, H[(MAX_AMP+1)*i+m].imag); + fprintf(stderr,"\n"); + } } /* update memories for next time */ diff --git a/codec2-dev/src/newamp1.h b/codec2-dev/src/newamp1.h index a2609ddb..4b3d7fa4 100644 --- a/codec2-dev/src/newamp1.h +++ b/codec2-dev/src/newamp1.h @@ -32,6 +32,7 @@ #define NEWAMP1_N_INDEXES 4 /* Number of indexes to pack: vq1, vq2, energy, Wo */ #define NEWAMP1_PHASE_NFFT 128 /* size of FFT used for phase synthesis */ +#define NEWAMP1_K 20 /* rate K vector length */ #include "codec2_fft.h" #include "comp.h" diff --git a/codec2-dev/src/phase.c b/codec2-dev/src/phase.c index 4a4bee55..0488644e 100644 --- a/codec2-dev/src/phase.c +++ b/codec2-dev/src/phase.c @@ -264,16 +264,26 @@ void mag_to_phase(float phase[], /* Nfft/2+1 output phase samples in for(i=1; i= M) { + float a_interpolated_surface_[M][K]; + newamp1_indexes_to_model(model__, + (COMP*)HH, + (float*)a_interpolated_surface_, + prev_rate_K_vec_, + &Wo_left, + &voicing_left, + rate_K_sample_freqs_kHz, + K, + phase_fft_fwd_cfg, + phase_fft_inv_cfg, + &indexes[f][0]); + + fprintf(stderr,"f: %d\n", f); + fprintf(stderr," %d %d %d %d\n", indexes[f][0], indexes[f][1], indexes[f][2], indexes[f][3]); + for(i=0; i= M) { + for(i=0; i