From 1547d0c04001a0ce95dc22e508223af9e94e7668 Mon Sep 17 00:00:00 2001 From: drowe67 Date: Tue, 30 May 2017 01:57:35 +0000 Subject: [PATCH] working on 16kHz support, number of samples/frame now a run time varialble, c2sim and c2enc/dec 1300 output bit exact git-svn-id: https://svn.code.sf.net/p/freetel/code@3146 01035d8c-6547-0410-b346-abe4f91aad63 --- codec2-dev/src/CMakeLists.txt | 2 +- codec2-dev/src/c2sim.c | 31 ++++--- codec2-dev/src/codec2.c | 133 ++++++++++++++++++------------- codec2-dev/src/codec2_internal.h | 16 ++-- codec2-dev/src/defines.h | 6 +- codec2-dev/src/phase.c | 3 +- codec2-dev/src/phase.h | 2 +- codec2-dev/src/sine.c | 91 +++++++++------------ codec2-dev/src/sine.h | 8 +- 9 files changed, 157 insertions(+), 135 deletions(-) diff --git a/codec2-dev/src/CMakeLists.txt b/codec2-dev/src/CMakeLists.txt index 2b64b405..7dc9e8c0 100644 --- a/codec2-dev/src/CMakeLists.txt +++ b/codec2-dev/src/CMakeLists.txt @@ -227,7 +227,7 @@ target_link_libraries(c2enc ${CMAKE_REQUIRED_LIBRARIES} codec2) add_executable(c2dec c2dec.c) target_link_libraries(c2dec ${CMAKE_REQUIRED_LIBRARIES} codec2) -add_executable(c2sim c2sim.c ampexp.c phaseexp.c) +add_executable(c2sim c2sim.c) target_link_libraries(c2sim ${CMAKE_REQUIRED_LIBRARIES} codec2) add_executable(fdmdv_get_test_bits fdmdv_get_test_bits.c fdmdv.c kiss_fft.c codec2_fft.c kiss_fftr.c) diff --git a/codec2-dev/src/c2sim.c b/codec2-dev/src/c2sim.c index f77543d4..3d28bd09 100644 --- a/codec2-dev/src/c2sim.c +++ b/codec2-dev/src/c2sim.c @@ -51,9 +51,10 @@ #include "bpf.h" #include "bpfb.h" -void synth_one_frame(codec2_fftr_cfg fftr_inv_cfg, short buf[], MODEL *model, float Sn_[], float Pn[], int prede, float *de_mem, float gain); +void synth_one_frame(int n_samp, codec2_fftr_cfg fftr_inv_cfg, short buf[], MODEL *model, float Sn_[], float Pn[], int prede, float *de_mem, float gain); void print_help(const struct option *long_options, int num_opts, char* argv[]); +#define N_SAMP n_samp /* quick fix for run time sample rate selection */ /*---------------------------------------------------------------------------*\ @@ -63,6 +64,8 @@ void print_help(const struct option *long_options, int num_opts, char* argv[]); int main(int argc, char *argv[]) { + C2CONST c2const = c2const_create(8000); + int n_samp = c2const.n_samp; FILE *fout = NULL; /* output speech file */ FILE *fin; /* input speech file */ short buf[N_SAMP]; /* input/output buffer */ @@ -135,8 +138,10 @@ int main(int argc, char *argv[]) #ifdef DUMP int dump; #endif + #if 0 struct PEXP *pexp = NULL; struct AEXP *aexp = NULL; + #endif float gain = 1.0; int bpf_en = 0; int bpfb_en = 0; @@ -410,13 +415,17 @@ int main(int argc, char *argv[]) fft_fwd_cfg = codec2_fft_alloc(FFT_ENC, 0, NULL, NULL); /* fwd FFT,used in several places */ fftr_fwd_cfg = codec2_fftr_alloc(FFT_ENC, 0, NULL, NULL); /* fwd FFT,used in several places */ fftr_inv_cfg = codec2_fftr_alloc(FFT_DEC, 1, NULL, NULL); /* inverse FFT, used just for synth */ - make_analysis_window(fft_fwd_cfg, w, W); - make_synthesis_window(Pn); + make_analysis_window(&c2const, fft_fwd_cfg, w, W); + make_synthesis_window(&c2const, Pn); quantise_init(); + + /* disabled for now while we convert to runtime n_samp */ + #if 0 if (phaseexp) pexp = phase_experiment_create(); if (ampexp) aexp = amp_experiment_create(); + #endif if (bpfb_en) bpf_en = 1; @@ -500,6 +509,7 @@ int main(int argc, char *argv[]) dump_Sn(Sn); dump_Sw(Sw); dump_model(&model); #endif + #if 0 if (ampexp) amp_experiment(aexp, &model, ampexp_arg); @@ -512,6 +522,7 @@ int main(int argc, char *argv[]) dump_phase_(&model.phi[0], model.L); #endif } + #endif if (hi) { int m; @@ -853,11 +864,11 @@ int main(int argc, char *argv[]) } else { sample_phase(&model_dec[i], H, Aw); } - phase_synth_zero_order(&model_dec[i], ex_phase, H); + phase_synth_zero_order(n_samp, &model_dec[i], ex_phase, H); } if (postfilt) postfilter(&model_dec[i], &bg_est); - synth_one_frame(fftr_inv_cfg, buf, &model_dec[i], Sn_, Pn, prede, &de_mem, gain); + synth_one_frame(n_samp, fftr_inv_cfg, buf, &model_dec[i], Sn_, Pn, prede, &de_mem, gain); if (fout != NULL) fwrite(buf,sizeof(short),N_SAMP,fout); } @@ -888,10 +899,12 @@ int main(int argc, char *argv[]) fprintf(stderr, "lspmelvq std = %3.1f Hz\n", sqrt(lspmelvq_mse/frames)); } + #if 0 if (phaseexp) phase_experiment_destroy(pexp); if (ampexp) amp_experiment_destroy(aexp); + #endif #ifdef DUMP if (dump) dump_off(); @@ -905,16 +918,16 @@ int main(int argc, char *argv[]) return 0; } -void synth_one_frame(codec2_fftr_cfg fftr_inv_cfg, short buf[], MODEL *model, float Sn_[], +void synth_one_frame(int n_samp, codec2_fftr_cfg fftr_inv_cfg, short buf[], MODEL *model, float Sn_[], float Pn[], int prede, float *de_mem, float gain) { int i; - synthesise(fftr_inv_cfg, Sn_, model, Pn, 1); + synthesise(n_samp, fftr_inv_cfg, Sn_, model, Pn, 1); if (prede) - de_emp(Sn_, Sn_, de_mem, N_SAMP); + de_emp(Sn_, Sn_, de_mem, n_samp); - for(i=0; i 32767.0) buf[i] = 32767; diff --git a/codec2-dev/src/codec2.c b/codec2-dev/src/codec2.c index 9d35a630..081322db 100644 --- a/codec2-dev/src/codec2.c +++ b/codec2-dev/src/codec2.c @@ -102,6 +102,8 @@ struct CODEC2 * codec2_create(int mode) { struct CODEC2 *c2; int i,l; + C2CONST c2const = c2const_create(8000); + int n_samp = c2const.n_samp; if (!((mode >= 0) && (mode <= CODEC2_MODE_700C))) { return NULL; @@ -112,15 +114,30 @@ struct CODEC2 * codec2_create(int mode) return NULL; c2->mode = mode; + + c2->Fs = c2const.Fs; + c2->n_samp = n_samp; + c2->Pn = (float*)malloc(2*n_samp*sizeof(float)); + if (c2->Pn == NULL) { + free(c2); + return NULL; + } + c2->Sn_ = (float*)malloc(2*n_samp*sizeof(float)); + if (c2->Sn_ == NULL) { + free(c2->Pn); + free(c2); + return NULL; + } + for(i=0; iSn[i] = 1.0; c2->hpf_states[0] = c2->hpf_states[1] = 0.0; - for(i=0; i<2*N_SAMP; i++) + for(i=0; i<2*n_samp; i++) c2->Sn_[i] = 0; c2->fft_fwd_cfg = codec2_fft_alloc(FFT_ENC, 0, NULL, NULL); c2->fftr_fwd_cfg = codec2_fftr_alloc(FFT_ENC, 0, NULL, NULL); - make_analysis_window(c2->fft_fwd_cfg, c2->w,c2->W); - make_synthesis_window(c2->Pn); + make_analysis_window(&c2const, c2->fft_fwd_cfg, c2->w,c2->W); + make_synthesis_window(&c2const, c2->Pn); c2->fftr_inv_cfg = codec2_fftr_alloc(FFT_DEC, 1, NULL, NULL); quantise_init(); c2->prev_Wo_enc = 0.0; @@ -140,6 +157,8 @@ struct CODEC2 * codec2_create(int mode) c2->nlp = nlp_create(M_PITCH); if (c2->nlp == NULL) { + free(c2->Sn_); + free(c2->Pn); free (c2); return NULL; } @@ -156,9 +175,9 @@ struct CODEC2 * codec2_create(int mode) c2->smoothing = 0; - c2->bpf_buf = (float*)malloc(sizeof(float)*(BPF_N+4*N_SAMP)); + c2->bpf_buf = (float*)malloc(sizeof(float)*(BPF_N+4*c2->n_samp)); assert(c2->bpf_buf != NULL); - for(i=0; in_samp; i++) c2->bpf_buf[i] = 0.0; c2->softdec = NULL; @@ -382,7 +401,7 @@ void codec2_encode_3200(struct CODEC2 *c2, unsigned char * bits, short speech[]) /* second 10ms analysis frame */ - analyse_one_frame(c2, &model, &speech[N_SAMP]); + analyse_one_frame(c2, &model, &speech[c2->n_samp]); pack(bits, &nbit, model.voiced, 1); Wo_index = encode_Wo(model.Wo, WO_BITS); pack(bits, &nbit, Wo_index, WO_BITS); @@ -468,7 +487,7 @@ void codec2_decode_3200(struct CODEC2 *c2, short speech[], const unsigned char * aks_to_M2(c2->fftr_fwd_cfg, &ak[i][0], LPC_ORD, &model[i], e[i], &snr, 0, 0, c2->lpc_pf, c2->bass_boost, c2->beta, c2->gamma, Aw); apply_lpc_correction(&model[i]); - synthesise_one_frame(c2, &speech[N_SAMP*i], &model[i], Aw); + synthesise_one_frame(c2, &speech[c2->n_samp*i], &model[i], Aw); } /* update memories for next frame ----------------------------*/ @@ -528,7 +547,7 @@ void codec2_encode_2400(struct CODEC2 *c2, unsigned char * bits, short speech[]) /* second 10ms analysis frame */ - analyse_one_frame(c2, &model, &speech[N_SAMP]); + analyse_one_frame(c2, &model, &speech[c2->n_samp]); pack(bits, &nbit, model.voiced, 1); e = speech_to_uq_lsps(lsps, ak, c2->Sn, c2->w, LPC_ORD); @@ -611,7 +630,7 @@ void codec2_decode_2400(struct CODEC2 *c2, short speech[], const unsigned char * aks_to_M2(c2->fftr_fwd_cfg, &ak[i][0], LPC_ORD, &model[i], e[i], &snr, 0, 0, c2->lpc_pf, c2->bass_boost, c2->beta, c2->gamma, Aw); apply_lpc_correction(&model[i]); - synthesise_one_frame(c2, &speech[N_SAMP*i], &model[i], Aw); + synthesise_one_frame(c2, &speech[c2->n_samp*i], &model[i], Aw); } /* update memories for next frame ----------------------------*/ @@ -673,7 +692,7 @@ void codec2_encode_1600(struct CODEC2 *c2, unsigned char * bits, short speech[]) /* frame 2: - voicing, scalar Wo & E -------------------------------*/ - analyse_one_frame(c2, &model, &speech[N_SAMP]); + analyse_one_frame(c2, &model, &speech[c2->n_samp]); pack(bits, &nbit, model.voiced, 1); Wo_index = encode_Wo(model.Wo, WO_BITS); @@ -686,12 +705,12 @@ void codec2_encode_1600(struct CODEC2 *c2, unsigned char * bits, short speech[]) /* frame 3: - voicing ---------------------------------------------*/ - analyse_one_frame(c2, &model, &speech[2*N_SAMP]); + analyse_one_frame(c2, &model, &speech[2*c2->n_samp]); pack(bits, &nbit, model.voiced, 1); /* frame 4: - voicing, scalar Wo & E, scalar LSPs ------------------*/ - analyse_one_frame(c2, &model, &speech[3*N_SAMP]); + analyse_one_frame(c2, &model, &speech[3*c2->n_samp]); pack(bits, &nbit, model.voiced, 1); Wo_index = encode_Wo(model.Wo, WO_BITS); @@ -795,7 +814,7 @@ void codec2_decode_1600(struct CODEC2 *c2, short speech[], const unsigned char * aks_to_M2(c2->fftr_fwd_cfg, &ak[i][0], LPC_ORD, &model[i], e[i], &snr, 0, 0, c2->lpc_pf, c2->bass_boost, c2->beta, c2->gamma, Aw); apply_lpc_correction(&model[i]); - synthesise_one_frame(c2, &speech[N_SAMP*i], &model[i], Aw); + synthesise_one_frame(c2, &speech[c2->n_samp*i], &model[i], Aw); } /* update memories for next frame ----------------------------*/ @@ -856,7 +875,7 @@ void codec2_encode_1400(struct CODEC2 *c2, unsigned char * bits, short speech[]) /* frame 2: - voicing, joint Wo & E -------------------------------*/ - analyse_one_frame(c2, &model, &speech[N_SAMP]); + analyse_one_frame(c2, &model, &speech[c2->n_samp]); pack(bits, &nbit, model.voiced, 1); /* need to run this just to get LPC energy */ @@ -867,12 +886,12 @@ void codec2_encode_1400(struct CODEC2 *c2, unsigned char * bits, short speech[]) /* frame 3: - voicing ---------------------------------------------*/ - analyse_one_frame(c2, &model, &speech[2*N_SAMP]); + analyse_one_frame(c2, &model, &speech[2*c2->n_samp]); pack(bits, &nbit, model.voiced, 1); /* frame 4: - voicing, joint Wo & E, scalar LSPs ------------------*/ - analyse_one_frame(c2, &model, &speech[3*N_SAMP]); + analyse_one_frame(c2, &model, &speech[3*c2->n_samp]); pack(bits, &nbit, model.voiced, 1); e = speech_to_uq_lsps(lsps, ak, c2->Sn, c2->w, LPC_ORD); @@ -965,7 +984,7 @@ void codec2_decode_1400(struct CODEC2 *c2, short speech[], const unsigned char * aks_to_M2(c2->fftr_fwd_cfg, &ak[i][0], LPC_ORD, &model[i], e[i], &snr, 0, 0, c2->lpc_pf, c2->bass_boost, c2->beta, c2->gamma, Aw); apply_lpc_correction(&model[i]); - synthesise_one_frame(c2, &speech[N_SAMP*i], &model[i], Aw); + synthesise_one_frame(c2, &speech[c2->n_samp*i], &model[i], Aw); } /* update memories for next frame ----------------------------*/ @@ -1030,17 +1049,17 @@ void codec2_encode_1300(struct CODEC2 *c2, unsigned char * bits, short speech[]) /* frame 2: - voicing ---------------------------------------------*/ - analyse_one_frame(c2, &model, &speech[N_SAMP]); + analyse_one_frame(c2, &model, &speech[c2->n_samp]); pack_natural_or_gray(bits, &nbit, model.voiced, 1, c2->gray); /* frame 3: - voicing ---------------------------------------------*/ - analyse_one_frame(c2, &model, &speech[2*N_SAMP]); + analyse_one_frame(c2, &model, &speech[2*c2->n_samp]); pack_natural_or_gray(bits, &nbit, model.voiced, 1, c2->gray); /* frame 4: - voicing, scalar Wo & E, scalar LSPs ------------------*/ - analyse_one_frame(c2, &model, &speech[3*N_SAMP]); + analyse_one_frame(c2, &model, &speech[3*c2->n_samp]); pack_natural_or_gray(bits, &nbit, model.voiced, 1, c2->gray); Wo_index = encode_Wo(model.Wo, WO_BITS); @@ -1148,7 +1167,7 @@ void codec2_decode_1300(struct CODEC2 *c2, short speech[], const unsigned char * aks_to_M2(c2->fftr_fwd_cfg, &ak[i][0], LPC_ORD, &model[i], e[i], &snr, 0, 0, c2->lpc_pf, c2->bass_boost, c2->beta, c2->gamma, Aw); apply_lpc_correction(&model[i]); - synthesise_one_frame(c2, &speech[N_SAMP*i], &model[i], Aw); + synthesise_one_frame(c2, &speech[c2->n_samp*i], &model[i], Aw); } /* for(i=0; i<4; i++) { @@ -1225,7 +1244,7 @@ void codec2_encode_1200(struct CODEC2 *c2, unsigned char * bits, short speech[]) /* frame 2: - voicing, joint Wo & E -------------------------------*/ - analyse_one_frame(c2, &model, &speech[N_SAMP]); + analyse_one_frame(c2, &model, &speech[c2->n_samp]); pack(bits, &nbit, model.voiced, 1); /* need to run this just to get LPC energy */ @@ -1236,12 +1255,12 @@ void codec2_encode_1200(struct CODEC2 *c2, unsigned char * bits, short speech[]) /* frame 3: - voicing ---------------------------------------------*/ - analyse_one_frame(c2, &model, &speech[2*N_SAMP]); + analyse_one_frame(c2, &model, &speech[2*c2->n_samp]); pack(bits, &nbit, model.voiced, 1); /* frame 4: - voicing, joint Wo & E, scalar LSPs ------------------*/ - analyse_one_frame(c2, &model, &speech[3*N_SAMP]); + analyse_one_frame(c2, &model, &speech[3*c2->n_samp]); pack(bits, &nbit, model.voiced, 1); e = speech_to_uq_lsps(lsps, ak, c2->Sn, c2->w, LPC_ORD); @@ -1335,7 +1354,7 @@ void codec2_decode_1200(struct CODEC2 *c2, short speech[], const unsigned char * aks_to_M2(c2->fftr_fwd_cfg, &ak[i][0], LPC_ORD, &model[i], e[i], &snr, 0, 0, c2->lpc_pf, c2->bass_boost, c2->beta, c2->gamma, Aw); apply_lpc_correction(&model[i]); - synthesise_one_frame(c2, &speech[N_SAMP*i], &model[i], Aw); + synthesise_one_frame(c2, &speech[c2->n_samp*i], &model[i], Aw); } /* update memories for next frame ----------------------------*/ @@ -1387,8 +1406,8 @@ void codec2_encode_700(struct CODEC2 *c2, unsigned char * bits, short speech[]) int indexes[LPC_ORD_LOW]; int Wo_index, e_index, i; unsigned int nbit = 0; - float bpf_out[4*N_SAMP]; - short bpf_speech[4*N_SAMP]; + float bpf_out[4*c2->n_samp]; + short bpf_speech[4*c2->n_samp]; int spare = 0; assert(c2 != NULL); @@ -1398,11 +1417,11 @@ void codec2_encode_700(struct CODEC2 *c2, unsigned char * bits, short speech[]) /* band pass filter */ for(i=0; ibpf_buf[i] = c2->bpf_buf[4*N_SAMP+i]; - for(i=0; i<4*N_SAMP; i++) + c2->bpf_buf[i] = c2->bpf_buf[4*c2->n_samp+i]; + for(i=0; i<4*c2->n_samp; i++) c2->bpf_buf[BPF_N+i] = speech[i]; - inverse_filter(&c2->bpf_buf[BPF_N], bpf, 4*N_SAMP, bpf_out, BPF_N-1); - for(i=0; i<4*N_SAMP; i++) + inverse_filter(&c2->bpf_buf[BPF_N], bpf, 4*c2->n_samp, bpf_out, BPF_N-1); + for(i=0; i<4*c2->n_samp; i++) bpf_speech[i] = bpf_out[i]; /* frame 1 --------------------------------------------------------*/ @@ -1411,15 +1430,15 @@ void codec2_encode_700(struct CODEC2 *c2, unsigned char * bits, short speech[]) /* frame 2 --------------------------------------------------------*/ - analyse_one_frame(c2, &model, &bpf_speech[N_SAMP]); + analyse_one_frame(c2, &model, &bpf_speech[c2->n_samp]); /* frame 3 --------------------------------------------------------*/ - analyse_one_frame(c2, &model, &bpf_speech[2*N_SAMP]); + analyse_one_frame(c2, &model, &bpf_speech[2*c2->n_samp]); /* frame 4: - voicing, scalar Wo & E, scalar LSPs -----------------*/ - analyse_one_frame(c2, &model, &bpf_speech[3*N_SAMP]); + analyse_one_frame(c2, &model, &bpf_speech[3*c2->n_samp]); pack(bits, &nbit, model.voiced, 1); Wo_index = encode_log_Wo(model.Wo, 5); pack_natural_or_gray(bits, &nbit, Wo_index, 5, c2->gray); @@ -1533,7 +1552,7 @@ void codec2_decode_700(struct CODEC2 *c2, short speech[], const unsigned char * aks_to_M2(c2->fftr_fwd_cfg, &ak[i][0], LPC_ORD_LOW, &model[i], e[i], &snr, 0, 0, c2->lpc_pf, c2->bass_boost, c2->beta, c2->gamma, Aw); apply_lpc_correction(&model[i]); - synthesise_one_frame(c2, &speech[N_SAMP*i], &model[i], Aw); + synthesise_one_frame(c2, &speech[c2->n_samp*i], &model[i], Aw); } #ifdef DUMP @@ -1599,8 +1618,8 @@ void codec2_encode_700b(struct CODEC2 *c2, unsigned char * bits, short speech[]) int indexes[3]; int Wo_index, e_index, i; unsigned int nbit = 0; - float bpf_out[4*N_SAMP]; - short bpf_speech[4*N_SAMP]; + float bpf_out[4*c2->n_samp]; + short bpf_speech[4*c2->n_samp]; int spare = 0; assert(c2 != NULL); @@ -1610,11 +1629,11 @@ void codec2_encode_700b(struct CODEC2 *c2, unsigned char * bits, short speech[]) /* band pass filter */ for(i=0; ibpf_buf[i] = c2->bpf_buf[4*N_SAMP+i]; - for(i=0; i<4*N_SAMP; i++) + c2->bpf_buf[i] = c2->bpf_buf[4*c2->n_samp+i]; + for(i=0; i<4*c2->n_samp; i++) c2->bpf_buf[BPF_N+i] = speech[i]; - inverse_filter(&c2->bpf_buf[BPF_N], bpfb, 4*N_SAMP, bpf_out, BPF_N-1); - for(i=0; i<4*N_SAMP; i++) + inverse_filter(&c2->bpf_buf[BPF_N], bpfb, 4*c2->n_samp, bpf_out, BPF_N-1); + for(i=0; i<4*c2->n_samp; i++) bpf_speech[i] = bpf_out[i]; /* frame 1 --------------------------------------------------------*/ @@ -1623,15 +1642,15 @@ void codec2_encode_700b(struct CODEC2 *c2, unsigned char * bits, short speech[]) /* frame 2 --------------------------------------------------------*/ - analyse_one_frame(c2, &model, &bpf_speech[N_SAMP]); + analyse_one_frame(c2, &model, &bpf_speech[c2->n_samp]); /* frame 3 --------------------------------------------------------*/ - analyse_one_frame(c2, &model, &bpf_speech[2*N_SAMP]); + analyse_one_frame(c2, &model, &bpf_speech[2*c2->n_samp]); /* frame 4: - voicing, scalar Wo & E, VQ mel LSPs -----------------*/ - analyse_one_frame(c2, &model, &bpf_speech[3*N_SAMP]); + analyse_one_frame(c2, &model, &bpf_speech[3*c2->n_samp]); pack(bits, &nbit, model.voiced, 1); Wo_index = encode_log_Wo(model.Wo, 5); pack_natural_or_gray(bits, &nbit, Wo_index, 5, c2->gray); @@ -1737,7 +1756,7 @@ void codec2_decode_700b(struct CODEC2 *c2, short speech[], const unsigned char * aks_to_M2(c2->fftr_fwd_cfg, &ak[i][0], LPC_ORD_LOW, &model[i], e[i], &snr, 0, 0, c2->lpc_pf, c2->bass_boost, c2->beta, c2->gamma, Aw); apply_lpc_correction(&model[i]); - synthesise_one_frame(c2, &speech[N_SAMP*i], &model[i], Aw); + synthesise_one_frame(c2, &speech[c2->n_samp*i], &model[i], Aw); } #ifdef DUMP @@ -1800,7 +1819,7 @@ void codec2_encode_700c(struct CODEC2 *c2, unsigned char * bits, short speech[]) memset(bits, '\0', ((codec2_bits_per_frame(c2) + 7) / 8)); for(i=0; in_samp]); } int K = 20; @@ -1869,7 +1888,7 @@ void codec2_decode_700c(struct CODEC2 *c2, short speech[], const unsigned char * for(i=0; in_samp*i], &model[i], &HH[i][0]); } } @@ -2009,12 +2028,12 @@ void synthesise_one_frame(struct CODEC2 *c2, short speech[], MODEL *model, COMP 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); + phase_synth_zero_order(c2->n_samp, model, &c2->ex_phase, H); } else { /* LPC based phase synthesis */ COMP H[MAX_AMP+1]; sample_phase(model, H, Aw); - phase_synth_zero_order(model, &c2->ex_phase, H); + phase_synth_zero_order(c2->n_samp, model, &c2->ex_phase, H); } PROFILE_SAMPLE_AND_LOG(pf_start, phase_start, " phase_synth"); @@ -2023,13 +2042,13 @@ void synthesise_one_frame(struct CODEC2 *c2, short speech[], MODEL *model, COMP PROFILE_SAMPLE_AND_LOG(synth_start, pf_start, " postfilter"); - synthesise(c2->fftr_inv_cfg, c2->Sn_, model, c2->Pn, 1); + synthesise(c2->n_samp, c2->fftr_inv_cfg, c2->Sn_, model, c2->Pn, 1); PROFILE_SAMPLE_AND_LOG2(synth_start, " synth"); - ear_protection(c2->Sn_, N_SAMP); + ear_protection(c2->Sn_, c2->n_samp); - for(i=0; in_samp; i++) { if (c2->Sn_[i] > 32767.0) speech[i] = 32767; else if (c2->Sn_[i] < -32767.0) @@ -2060,10 +2079,10 @@ void analyse_one_frame(struct CODEC2 *c2, MODEL *model, short speech[]) /* Read input speech */ - for(i=0; iSn[i] = c2->Sn[i+N_SAMP]; - for(i=0; iSn[i+M_PITCH-N_SAMP] = speech[i]; + for(i=0; in_samp; i++) + c2->Sn[i] = c2->Sn[i+c2->n_samp]; + for(i=0; in_samp; i++) + c2->Sn[i+M_PITCH-c2->n_samp] = speech[i]; PROFILE_SAMPLE(dft_start); dft_speech(c2->fft_fwd_cfg, Sw, c2->Sn, c2->w); @@ -2071,7 +2090,7 @@ void analyse_one_frame(struct CODEC2 *c2, MODEL *model, short speech[]) /* Estimate pitch */ - nlp(c2->nlp,c2->Sn,N_SAMP,P_MIN,P_MAX,&pitch,Sw, c2->W, &c2->prev_Wo_enc); + nlp(c2->nlp,c2->Sn,c2->n_samp,P_MIN,P_MAX,&pitch,Sw, c2->W, &c2->prev_Wo_enc); PROFILE_SAMPLE_AND_LOG(model_start, nlp_start, " nlp"); model->Wo = TWO_PI/pitch; diff --git a/codec2-dev/src/codec2_internal.h b/codec2-dev/src/codec2_internal.h index 519e9b33..489dda3e 100644 --- a/codec2-dev/src/codec2_internal.h +++ b/codec2-dev/src/codec2_internal.h @@ -34,19 +34,21 @@ struct CODEC2 { int mode; - codec2_fft_cfg fft_fwd_cfg; /* forward FFT config */ - codec2_fftr_cfg fftr_fwd_cfg; /* forward real FFT config */ - float w[M_PITCH]; /* time domain hamming window */ + int Fs; + int n_samp; + codec2_fft_cfg fft_fwd_cfg; /* forward FFT config */ + codec2_fftr_cfg fftr_fwd_cfg; /* forward real FFT config */ + float w[M_PITCH]; /* time domain hamming window */ COMP W[FFT_ENC]; /* DFT of w[] */ - float Pn[2*N_SAMP]; /* trapezoidal synthesis window */ + float *Pn; /* [2*n_samp] trapezoidal synthesis window */ float *bpf_buf; /* buffer for band pass filter */ - float Sn[M_PITCH]; /* input speech */ + float Sn[M_PITCH]; /* input speech */ float hpf_states[2]; /* high pass filter states */ void *nlp; /* pitch predictor states */ int gray; /* non-zero for gray encoding */ - codec2_fftr_cfg fftr_inv_cfg; /* inverse FFT config */ - float Sn_[2*N_SAMP]; /* synthesised output speech */ + codec2_fftr_cfg fftr_inv_cfg; /* inverse FFT config */ + float *Sn_; /* [2*n_samp] synthesised output speech */ float ex_phase; /* excitation model phase track */ float bg_est; /* background noise estimate for post filter */ float prev_Wo_enc; /* previous frame's pitch estimate */ diff --git a/codec2-dev/src/defines.h b/codec2-dev/src/defines.h index ed9a0bbf..7cafd63e 100644 --- a/codec2-dev/src/defines.h +++ b/codec2-dev/src/defines.h @@ -36,7 +36,6 @@ /* General defines */ -#define N_SAMP 80 /* number of samples per frame */ #define MAX_AMP 80 /* maximum number of harmonics */ #ifndef PI #define PI 3.141592654 /* mathematical constant */ @@ -65,6 +64,11 @@ \*---------------------------------------------------------------------------*/ +typedef struct { + int Fs; + int n_samp; +} C2CONST; + /* Structure to hold model parameters for one frame */ typedef struct { diff --git a/codec2-dev/src/phase.c b/codec2-dev/src/phase.c index f6e4f4be..e486613d 100644 --- a/codec2-dev/src/phase.c +++ b/codec2-dev/src/phase.c @@ -158,6 +158,7 @@ void sample_phase(MODEL *model, \*---------------------------------------------------------------------------*/ void phase_synth_zero_order( + int n_samp, MODEL *model, float *ex_phase, /* excitation phase of fundamental */ COMP H[] /* L synthesis filter freq domain samples */ @@ -178,7 +179,7 @@ void phase_synth_zero_order( ex_phase[0] += (*prev_Wo+model->Wo)*N_SAMP/2; */ - ex_phase[0] += (model->Wo)*N_SAMP; + ex_phase[0] += (model->Wo)*n_samp; ex_phase[0] -= TWO_PI*floorf(ex_phase[0]/TWO_PI + 0.5); for(m=1; m<=model->L; m++) { diff --git a/codec2-dev/src/phase.h b/codec2-dev/src/phase.h index a01a3d0a..92909f07 100644 --- a/codec2-dev/src/phase.h +++ b/codec2-dev/src/phase.h @@ -32,7 +32,7 @@ #include "comp.h" void sample_phase(MODEL *model, COMP filter_phase[], COMP A[]); -void phase_synth_zero_order(MODEL *model, float *ex_phase, COMP filter_phase[]); +void phase_synth_zero_order(int n_samp, MODEL *model, float *ex_phase, COMP filter_phase[]); void mag_to_phase(float phase[], float Gdbfk[], int Nfft, codec2_fft_cfg fwd_cfg, codec2_fft_cfg inv_cfg); diff --git a/codec2-dev/src/sine.c b/codec2-dev/src/sine.c index 10c35e0a..8e2fb20b 100644 --- a/codec2-dev/src/sine.c +++ b/codec2-dev/src/sine.c @@ -56,6 +56,15 @@ void hs_pitch_refinement(MODEL *model, COMP Sw[], float pmin, float pmax, \*---------------------------------------------------------------------------*/ +C2CONST c2const_create(int Fs) { + C2CONST c2const; + + assert((Fs == 8000) || (Fs = 16000)); + c2const.Fs = Fs; + c2const.n_samp = Fs*0.01; + return c2const; +} + /*---------------------------------------------------------------------------*\ FUNCTION....: make_analysis_window @@ -66,7 +75,7 @@ void hs_pitch_refinement(MODEL *model, COMP Sw[], float pmin, float pmax, \*---------------------------------------------------------------------------*/ -void make_analysis_window(codec2_fft_cfg fft_fwd_cfg, float w[], COMP W[]) +void make_analysis_window(C2CONST *c2const, codec2_fft_cfg fft_fwd_cfg, float w[], COMP W[]) { float m; COMP wshift[FFT_ENC]; @@ -535,25 +544,26 @@ float est_voicing_mbe( \*---------------------------------------------------------------------------*/ -void make_synthesis_window(float Pn[]) +void make_synthesis_window(C2CONST *c2const, float Pn[]) { int i; float win; + int n_samp = c2const->n_samp; /* Generate Parzen window in time domain */ win = 0.0; - for(i=0; i 10ms sound poor. The effect can also - be seen when synthesising test signals like single sine waves, some - sort of amplitude modulation at the frame rate. - - Another possibility is using a larger FFT size (1024 or 2048). - */ - -#define FFT_SYNTHESIS -#ifdef FFT_SYNTHESIS /* Now set up frequency domain synthesised speech */ + for(l=1; l<=model->L; l++) { - //for(l=model->L/2; l<=model->L; l++) { - //for(l=1; l<=model->L/4; l++) { b = (int)(l*model->Wo*FFT_DEC/TWO_PI + 0.5); if (b > ((FFT_DEC/2)-1)) { b = (FFT_DEC/2)-1; @@ -625,42 +619,29 @@ void synthesise( /* Perform inverse DFT */ codec2_fftri(fftr_inv_cfg, Sw_,sw_); -#else - /* - Direct time domain synthesis using the cos() function. Works - well at 10ms and 20ms frames rates. Note synthesis window is - still used to handle overlap-add between adjacent frames. This - could be simplified as we don't need to synthesise where Pn[] - is zero. - */ - for(l=1; l<=model->L; l++) { - for(i=0,j=-N_SAMP+1; iA[l]*cosf(j*model->Wo*l + model->phi[l]); - } - for(i=N_SAMP-1,j=0; i<2*N_SAMP; i++,j++) - Sw_[j].real += 2.0*model->A[l]*cosf(j*model->Wo*l + model->phi[l]); - } -#endif /* Overlap add to previous samples */ -#ifdef USE_KISS_FFT -#define FFTI_FACTOR ((float)1.0) -#else -#define FFTI_FACTOR ((float32_t)FFT_DEC) -#endif - for(i=0; i