added test with real sinusoidal model parameters
authordrowe67 <drowe67@01035d8c-6547-0410-b346-abe4f91aad63>
Sun, 23 Jul 2017 02:14:02 +0000 (02:14 +0000)
committerdrowe67 <drowe67@01035d8c-6547-0410-b346-abe4f91aad63>
Sun, 23 Jul 2017 02:14:02 +0000 (02:14 +0000)
git-svn-id: https://svn.code.sf.net/p/freetel/code@3328 01035d8c-6547-0410-b346-abe4f91aad63

codec2-dev/unittest/CMakeLists.txt
codec2-dev/unittest/tc2wideband.c

index 2cae7a66c862b37a1935d4d0dc40d286699325ca..a4bd8d53f6e39e1aa92f5c586b923a3088a22e49 100644 (file)
@@ -96,5 +96,5 @@ target_link_libraries(tsrc samplerate)
 add_executable(tlininterp tlininterp.c)
 add_executable(tdec tdec.c)
 
-add_executable(tc2wideband tc2wideband.c ../src/c2wideband.c)
+add_executable(tc2wideband tc2wideband.c ../src/c2wideband.c ../src/octave.c)
 target_link_libraries(tc2wideband codec2)
index d0e335fb05ed6cfe27260717f2d10e8d7a6f39c4..7b41cd039f3d1bf160466fb489c7c716ea4a30f9 100644 (file)
@@ -16,6 +16,8 @@
 #include "newamp1.h"
 #include "quantise.h"
 
+#define FRAMES 300
+
 float mean(float data[], int n);
 int unit_test();
 float std(float data[], int rows);
@@ -23,19 +25,15 @@ void diff_de(int rows, int cols, float D[rows][cols], float E[rows][cols], float
 void array_col_to_row(int rows, int cols, float data[rows][cols], int col, float res[]);
 void std_on_cols(int rows, int cols, float data[rows][cols], float res[]);
 float mean_std_diff_de(int rows, int cols, float D[rows][cols], float E[rows][cols]);
-void setup_map(WIDEBAND_MAP * wb_map, int Nt, int K);
-
-
 void test_wideband_enc_dec();
-void test_experiment_rate_K_dct2();
+void setup_map(WIDEBAND_MAP * wb_map, int Nt, int K);
+void test_with_real_data(int argc, char *argv[]);
 
 char *fn;
 
 void test(char * tfn) {
   fn = tfn;
-  printf("========================================\n");
   printf("test function: %s\n", fn);
-  printf("========================================\n");
 }
 
 void test_failed() {
@@ -89,9 +87,10 @@ int main(int argc, char *argv[]) {
   float E[rows][cols];
   float res_diff_de[rows][cols];
   float expect_diff_de[rows][cols];
+  int r,c;
 
-  for (int r = 0; r < rows; r++) {
-    for (int c = 0; c < cols; c++) {
+  for (r = 0; r < rows; r++) {
+    for (c = 0; c < cols; c++) {
       float d = rand();
       float e = rand();
       D[r][c] = d;
@@ -111,14 +110,14 @@ int main(int argc, char *argv[]) {
   float data[rows][cols];
   float res_data[rows];
   float expect_data[cols][rows];
-  for (int r = 0; r < rows; r++) {
-    for (int c = 0; c < cols; c++) {
+  for (r = 0; r < rows; r++) {
+    for (c = 0; c < cols; c++) {
       float d = rand();
       data[r][c] = d;
       expect_data[c][r] = d;
     }
   }
-  for (int c = 0; c < cols; c++) {
+  for (c = 0; c < cols; c++) {
 
     array_col_to_row(rows, cols, data, c, res_data);
     if (memcmp(res_data, expect_data[c], cols * sizeof (float)) != 0) {
@@ -175,14 +174,9 @@ int main(int argc, char *argv[]) {
     test_failed_f(res_msd, expected_msd);
   }
 
-  
-  
   test_wideband_enc_dec();
 
-  
-  test_experiment_rate_K_dct2();
-  
-
+  test_with_real_data(argc, argv);
 
   return 1;
 }
@@ -222,19 +216,19 @@ void test_wideband_enc_dec() {
   int qn;
   float rate_K_surface_block[rate_K_surface_size][K]; // rate K vecs for each frame, form a surface that makes pretty graphs   
   float rate_K_surface_block_[rate_K_surface_size][K];
+  int n,i;
 
-
-  for (int n = 0; n < n_block_frames; n++) {
+  for (n = 0; n < n_block_frames; n++) {
     model_block[n].L = 10;
     model_block[n].Wo = (float) rand() / RAND_MAX;
-    for (int i = 0; i < MAX_AMP + 1; i++) {
+    for (i = 0; i < MAX_AMP + 1; i++) {
       model_block[n].phi[i] = (float) rand() / RAND_MAX;
       model_block[n].A[i] = (float) rand() / RAND_MAX;
     }
     model_block[n].voiced = round((float) rand() / RAND_MAX);
   }
 
-  int n = 0;
+  n = 0;
 
   printf("setup complete. now calling the function\n");
 
@@ -247,30 +241,140 @@ void test_wideband_enc_dec() {
   printf("made it to the end\n");
 }
 
-void test_experiment_rate_K_dct2(){
 
-  test("experiment_rate_K_dct2");
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: test_with_real_data()
+  AUTHOR......: David Rowe
+  DATE CREATED: July 2017
+
+  Tests the wideband functions with real data derived from input
+  speech samples.  Test vectors are dumped to Octave vectors so they can
+  be verified against the Octave version of the wideband functions.
+
+  Supports rapid go/no-go testing of the C port when any canges are
+  made, and flushes out bugs in the C and octave version.
+
+\*---------------------------------------------------------------------------*/
+
+void test_with_real_data(int argc, char *argv[]) {
+    int Nt = C2WB_NT;
+    int Fs = C2WB_FS;
+    int K = C2WB_K;
+
+    C2CONST c2const = c2const_create(Fs);
+    int   n_samp = c2const.n_samp;
+    int   m_pitch = c2const.m_pitch;
+    short buf[n_samp];         /* input/output buffer                   */
+    float Sn[m_pitch];         /* float input speech samples            */
+    COMP  Sw[FFT_ENC];         /* DFT of Sn[]                           */
+    codec2_fft_cfg fft_fwd_cfg; /* fwd FFT states                        */
+    float w[m_pitch];          /* time domain hamming window            */
+    COMP  W[FFT_ENC];          /* DFT of w[]                            */
+    MODEL model[FRAMES];
+    void *nlp_states;
+    float pitch, prev_f0;
+    int   i,m,f;
+    
+    if (argc != 2) {
+        printf("usage: ./tnewamp1 RawFile\n");
+        exit(1);
+    }
+    nlp_states = nlp_create(&c2const);
+    prev_f0 = 1.0/P_MAX_S;
+    fft_fwd_cfg = codec2_fft_alloc(FFT_ENC, 0, NULL, NULL); 
+    make_analysis_window(&c2const,fft_fwd_cfg, w, W);
+
+    for(i=0; i<m_pitch; i++) {
+       Sn[i] = 1.0;
+    }
+
+    WIDEBAND_MAP wb_map;
+    setup_map(&wb_map, Nt, K);
+    int n_block_frames = C2WB_NT * C2WB_DEC;
 
-  const int frames = 5000;
-  
+    float model_octave[FRAMES][MAX_AMP+2];    // model params in matrix format, useful for C <-> Octave  
+    float rate_K_surface[FRAMES][K];          // rate K vecs for each frame, form a surface that makes pretty graphs
+    float rate_K_surface_[FRAMES][K];
+    MODEL model_block_[n_block_frames];
 
-  int Fs = C2WB_FS;
-  
-  //struct CODEC2 * codec2 = codec2_create(CODEC2_MODE_WB);
-  C2CONST c2const = c2const_create(Fs);
+    int Nblocks = FRAMES/n_block_frames;
+    float dct2_sd[Nblocks];
+    int qn;
 
-  MODEL model_frames[frames];
+    for(f=0; f<FRAMES; f++) {
+        for(m=0; m<MAX_AMP+2; m++) {
+            model_octave[f][m] = 0.0;
+        }
+    }
 
-  printf("setting up random frames: %d\n", frames);
-  for (int n = 0; n < frames; n++) {
-    model_frames[n].L = 10;
-    model_frames[n].Wo = (float) rand() / RAND_MAX;
-    for (int i = 0; i < MAX_AMP + 1; i++) {
-      model_frames[n].phi[i] = (float) rand() / RAND_MAX;
-      model_frames[n].A[i] = (float) rand() / RAND_MAX;
+    FILE *fin = fopen(argv[1], "rb");
+    if (fin == NULL) {
+        fprintf(stderr, "Problem opening %s\n", argv[1]);
+        exit(1);
     }
-    model_frames[n].voiced = round((float) rand() / RAND_MAX);
-  }
-  printf("starting experiment\n");
-  experiment_rate_K_dct2(&c2const, model_frames, frames);
-}
\ No newline at end of file
+
+    for(f=0; f<FRAMES; f++) {
+        assert(fread(buf,sizeof(short),n_samp,fin) == n_samp);
+
+        /* shift buffer of input samples, and insert new samples */
+
+       for(i=0; i<m_pitch-n_samp; i++) {
+           Sn[i] = Sn[i+n_samp];
+       }
+       for(i=0; i<n_samp; i++) {
+           Sn[i+m_pitch-n_samp] = buf[i];
+        }
+
+       /* Estimate Sinusoidal Model Parameters ----------------------*/
+
+       nlp(nlp_states, Sn, n_samp, &pitch, Sw, W, &prev_f0);
+       model[f].Wo = TWO_PI/pitch;
+
+       dft_speech(&c2const, fft_fwd_cfg, Sw, Sn, w);
+       two_stage_pitch_refinement(&c2const, &model[f], Sw);
+       estimate_amplitudes(&model[f], Sw, W, 1);
+        est_voicing_mbe(&c2const, &model[f], Sw, W);
+
+        fprintf(stderr,"f: %d Wo: %4.3f L: %d v: %d\n", f, model[f].Wo, model[f].L, model[f].voiced);
+
+        /* log some vectors for sinusoidal model */
+        model_octave[f][0] = model[f].Wo;
+        model_octave[f][1] = model[f].L;
+
+        for(m=1; m<=model[f].L; m++) {
+            model_octave[f][m+1] = model[f].A[m];
+        }        
+
+        /* once we have collected a block of samples process ----------*/
+
+        if (((f+1) % n_block_frames) == 0) {
+
+            /* wideband processing ----------------------------------------*/
+
+            int block_st = f-n_block_frames+1;
+            wideband_enc_dec(&c2const, n_block_frames, &model[block_st], &wb_map,
+                             model_block_, dct2_sd, &qn, 
+                             &rate_K_surface[block_st], 
+                             &rate_K_surface_[block_st]);
+
+            fprintf(stderr, "  Performed a wideband_enc_dec() call, qn: %d\n", qn);
+
+            /* todo: add a synthesis stage here to output decoded speech from model_block_ */
+        }
+    }
+
+    fclose(fin);
+
+    /* save vectors in Octave format */
+
+    FILE *fout = fopen("tc2wideband_out.txt","wt");
+    assert(fout != NULL);
+    fprintf(fout, "# Created by tc2wideband.c\n");
+    octave_save_float(fout, "rate_K_surface_c", (float*)rate_K_surface, FRAMES, K, K);
+    octave_save_float(fout, "model_c", (float*)model_octave, FRAMES, MAX_AMP+2, MAX_AMP+2);
+    fclose(fout);
+
+    printf("Done! Now run\n  octave:1> tc2wideband(\"../path/to/tc2wideband_out.txt\")\n");
+}