working on 16kHz support, number of samples/frame now a run time varialble, c2sim...
authordrowe67 <drowe67@01035d8c-6547-0410-b346-abe4f91aad63>
Tue, 30 May 2017 01:57:35 +0000 (01:57 +0000)
committerdrowe67 <drowe67@01035d8c-6547-0410-b346-abe4f91aad63>
Tue, 30 May 2017 01:57:35 +0000 (01:57 +0000)
git-svn-id: https://svn.code.sf.net/p/freetel/code@3146 01035d8c-6547-0410-b346-abe4f91aad63

codec2-dev/src/CMakeLists.txt
codec2-dev/src/c2sim.c
codec2-dev/src/codec2.c
codec2-dev/src/codec2_internal.h
codec2-dev/src/defines.h
codec2-dev/src/phase.c
codec2-dev/src/phase.h
codec2-dev/src/sine.c
codec2-dev/src/sine.h

index 2b64b40566a3c26971e08922425da7768778b8fd..7dc9e8c036944f723bce75c1cbaac8135a7ef908 100644 (file)
@@ -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)
index f77543d4a71e674e5ea226657bcb9a54752ea37c..3d28bd09012acc9b408138ed13ff756c656f04c8 100644 (file)
 #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<N_SAMP; i++) {
+    for(i=0; i<n_samp; i++) {
        Sn_[i] *= gain;
        if (Sn_[i] > 32767.0)
            buf[i] = 32767;
index 9d35a630cd4fbb811098fbb293697a86fb7d39cc..081322dbae345acf7fb604396f2b387b5ff44681 100644 (file)
@@ -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; i<M_PITCH; i++)
        c2->Sn[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; i<BPF_N+4*N_SAMP; i++)
+    for(i=0; i<BPF_N+4*c2->n_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; i<BPF_N; i++)
-        c2->bpf_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; i<BPF_N; i++)
-        c2->bpf_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; i<M; i++) {
-        analyse_one_frame(c2, &model, &speech[i*N_SAMP]);
+        analyse_one_frame(c2, &model, &speech[i*c2->n_samp]);
     }
 
     int K = 20;
@@ -1869,7 +1888,7 @@ void codec2_decode_700c(struct CODEC2 *c2, short speech[], const unsigned char *
 
 
    for(i=0; i<M; i++) {
-       synthesise_one_frame(c2, &speech[N_SAMP*i], &model[i], &HH[i][0]);
+       synthesise_one_frame(c2, &speech[c2->n_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; i<N_SAMP; i++) {
+    for(i=0; i<c2->n_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; i<M_PITCH-N_SAMP; i++)
-      c2->Sn[i] = c2->Sn[i+N_SAMP];
-    for(i=0; i<N_SAMP; i++)
-      c2->Sn[i+M_PITCH-N_SAMP] = speech[i];
+    for(i=0; i<M_PITCH-c2->n_samp; i++)
+      c2->Sn[i] = c2->Sn[i+c2->n_samp];
+    for(i=0; i<c2->n_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;
index 519e9b3346cdaa21e7e5f3c2e3df5cb129b8b9ac..489dda3e8cfb3131a1c8a5165a9aebfd4efba523 100644 (file)
 
 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           */
index ed9a0bbfdef1bd9d00e25361c028174337979cd4..7cafd63eec06a4fd7fdfb98622512e6a7cef77e9 100644 (file)
@@ -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                */
 
 \*---------------------------------------------------------------------------*/
 
+typedef struct {
+    int  Fs;
+    int  n_samp;
+} C2CONST;
+
 /* Structure to hold model parameters for one frame */
 
 typedef struct {
index f6e4f4be7f3f247307b0c55f3ff013cb7f0d9f5f..e486613d17ec174079f617b262c4ca9025eb1ba6 100644 (file)
@@ -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++) {
index a01a3d0af043f6102eac57535a54e60b28a10436..92909f079b0deccf6774ce9109615b033d01ed54 100644 (file)
@@ -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);
 
index 10c35e0a0a317c5d2b1b4d3e9c59fc452cb6c2a0..8e2fb20b99f0a1e01c494481cba7aa235ae6d517 100644 (file)
@@ -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<N_SAMP/2-TW; i++)
+  for(i=0; i<n_samp/2-TW; i++)
     Pn[i] = 0.0;
   win = 0.0;
-  for(i=N_SAMP/2-TW; i<N_SAMP/2+TW; win+=1.0/(2*TW), i++ )
+  for(i=n_samp/2-TW; i<n_samp/2+TW; win+=1.0/(2*TW), i++ )
     Pn[i] = win;
-  for(i=N_SAMP/2+TW; i<3*N_SAMP/2-TW; i++)
+  for(i=n_samp/2+TW; i<3*n_samp/2-TW; i++)
     Pn[i] = 1.0;
   win = 1.0;
-  for(i=3*N_SAMP/2-TW; i<3*N_SAMP/2+TW; win-=1.0/(2*TW), i++)
+  for(i=3*n_samp/2-TW; i<3*n_samp/2+TW; win-=1.0/(2*TW), i++)
     Pn[i] = win;
-  for(i=3*N_SAMP/2+TW; i<2*N_SAMP; i++)
+  for(i=3*n_samp/2+TW; i<2*n_samp; i++)
     Pn[i] = 0.0;
 }
 
@@ -570,6 +580,7 @@ void make_synthesis_window(float Pn[])
 \*---------------------------------------------------------------------------*/
 
 void synthesise(
+  int    n_samp,
   codec2_fftr_cfg fftr_inv_cfg,
   float  Sn_[],                /* time domain synthesised signal              */
   MODEL *model,                /* ptr to model parameters for this frame      */
@@ -577,16 +588,16 @@ void synthesise(
   int    shift          /* flag used to handle transition frames       */
 )
 {
-    int   i,l,j,b;     /* loop variables */
+    int   i,l,j,b;             /* loop variables */
     COMP  Sw_[FFT_DEC/2+1];    /* DFT of synthesised signal */
-    float sw_[FFT_DEC];        /* synthesised signal */
+    float sw_[FFT_DEC];                /* synthesised signal */
 
     if (shift) {
        /* Update memories */
-       for(i=0; i<N_SAMP-1; i++) {
-           Sn_[i] = Sn_[i+N_SAMP];
+       for(i=0; i<n_samp-1; i++) {
+           Sn_[i] = Sn_[i+n_samp];
        }
-       Sn_[N_SAMP-1] = 0.0;
+       Sn_[n_samp-1] = 0.0;
     }
 
     for(i=0; i<FFT_DEC/2+1; i++) {
@@ -594,26 +605,9 @@ void synthesise(
        Sw_[i].imag = 0.0;
     }
 
-    /*
-      Nov 2010 - found that synthesis using time domain cos() functions
-      gives better results for synthesis frames greater than 10ms.  Inverse
-      FFT synthesis using a 512 pt FFT works well for 10ms window.  I think
-      (but am not sure) that the problem is related to the quantisation of
-      the harmonic frequencies to the FFT bin size, e.g. there is a
-      8000/512 Hz step between FFT bins.  For some reason this makes
-      the speech from longer frame > 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; i<N_SAMP-1; i++,j++) {
-            Sw_[FFT_DEC-N_SAMP+1+i].real += 2.0*model->A[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<N_SAMP-1; i++) {
-        Sn_[i] += sw_[FFT_DEC-N_SAMP+1+i]*Pn[i] * FFTI_FACTOR;
+
+    #ifdef USE_KISS_FFT
+    #define    FFTI_FACTOR ((float)1.0)
+    #else
+    #define    FFTI_FACTOR ((float32_t)FFT_DEC)
+    #endif
+
+    for(i=0; i<n_samp-1; i++) {
+        Sn_[i] += sw_[FFT_DEC-n_samp+1+i]*Pn[i] * FFTI_FACTOR;
     }
 
     if (shift)
-        for(i=N_SAMP-1,j=0; i<2*N_SAMP; i++,j++)
+        for(i=n_samp-1,j=0; i<2*n_samp; i++,j++)
             Sn_[i] = sw_[j]*Pn[i] * FFTI_FACTOR;
     else
-        for(i=N_SAMP-1,j=0; i<2*N_SAMP; i++,j++)
+        for(i=n_samp-1,j=0; i<2*n_samp; i++,j++)
             Sn_[i] += sw_[j]*Pn[i] * FFTI_FACTOR;
 }
 
 
+/* todo: this should probably be in some states rather than a static */
 static unsigned long next = 1;
 
 int codec2_rand(void) {
index bbd24711990663dc6298f5f1c0b9a0b675460592..47a3475f550a1c0d27682ab72e0edaa7d5e09776 100644 (file)
 #include "comp.h"
 #include "codec2_fft.h"
 
-void make_analysis_window(codec2_fft_cfg fft_fwd_cfg, float w[], COMP W[]);
+C2CONST c2const_create(int Fs);
+
+void make_analysis_window(C2CONST *c2const, codec2_fft_cfg fft_fwd_cfg, float w[], COMP W[]);
 float hpf(float x, float states[]);
 void dft_speech(codec2_fft_cfg fft_fwd_cfg, COMP Sw[], float Sn[], float w[]);
 void two_stage_pitch_refinement(MODEL *model, COMP Sw[]);
 void estimate_amplitudes(MODEL *model, COMP Sw[], COMP W[], int est_phase);
 float est_voicing_mbe(MODEL *model, COMP Sw[], COMP W[]);
-void make_synthesis_window(float Pn[]);
-void synthesise(codec2_fftr_cfg fftr_inv_cfg, float Sn_[], MODEL *model, float Pn[], int shift);
+void make_synthesis_window(C2CONST *c2const, float Pn[]);
+void synthesise(int n_samp, codec2_fftr_cfg fftr_inv_cfg, float Sn_[], MODEL *model, float Pn[], int shift);
 
 #define CODEC2_RAND_MAX 32767
 int codec2_rand(void);