LSP interpolation to get from 10ms to 20ms frames investigated, does a better job...
authordrowe67 <drowe67@01035d8c-6547-0410-b346-abe4f91aad63>
Wed, 10 Nov 2010 06:09:01 +0000 (06:09 +0000)
committerdrowe67 <drowe67@01035d8c-6547-0410-b346-abe4f91aad63>
Wed, 10 Nov 2010 06:09:01 +0000 (06:09 +0000)
git-svn-id: https://svn.code.sf.net/p/freetel/code@215 01035d8c-6547-0410-b346-abe4f91aad63

codec2/src/c2sim.c
codec2/src/interp.c
codec2/src/interp.h

index a89e823bafbfac487b9d1429b507b49951b01955..42a665c2eee93433418160d24363bf8d183ccc3f 100644 (file)
@@ -117,6 +117,11 @@ int main(int argc, char *argv[])
 
   MODEL prev_model, interp_model;
   int decimate;
+  float lsps[LPC_ORD];
+  float prev_lsps[LPC_ORD];
+  float e, prev_e;
+  int lpc_correction;
+  float ak_interp[LPC_MAX];
 
   void *nlp_states;
 
@@ -136,6 +141,10 @@ int main(int argc, char *argv[])
   for(i=1; i<=MAX_AMP; i++) {
       ex_phase[i] = 0.0;
   }
+  for(i=0; i<LPC_ORD; i++) {
+      prev_lsps[i] = i*PI/(LPC_ORD+1);
+  }
+  prev_e = 1;
 
   nlp_states = nlp_create();
 
@@ -287,13 +296,10 @@ int main(int argc, char *argv[])
            fscanf(fvoicing,"%d\n",&model.voiced);
        }
     }
+
     /* optional LPC model amplitudes */
 
     if (lpc_model) {
-       int lpc_correction;
-       float e;
-       float lsps[LPC_ORD];
        int   lsp_indexes[LPC_ORD];
 
        e = speech_to_uq_lsps(lsps, ak, Sn, w, order);
@@ -331,31 +337,27 @@ int main(int argc, char *argv[])
            printf("needs --phase0 to resample phase for interpolated Wo\n");
            exit(0);
        }
+       if (!lpc_model) {
+           printf("needs --lpc 10 to resample amplitudes\n");
+           exit(0);
+       }
 
        /* odd frame - interpolate */
 
        if (frames%2) {
 
-           #ifdef TEST
-           model.voiced = 1;
-           prev_model.voiced = 1;
-           if (fabs(prev_model.Wo - model.Wo) < 0.1*model.Wo) {
-               interp_model.voiced = 1;
-               interpolate(&interp_model, &prev_model, &model);
-               for(i=0; i<=interp_model.L; i++) {
-                   interp_model.phi[i] = phi1[i];
-               }
-               printf("interp\n");
-           }
-           else
-               interp_model = tmp_model;
-           #endif
-
            interp_model.voiced = voiced1;
+
+           #ifdef LOG_LIN_INTERP
            interpolate(&interp_model, &prev_model, &model);
+           #else
+           interpolate_lsp(&interp_model, &prev_model, &model,
+                           prev_lsps, prev_e, lsps, e, ak_interp);
+           apply_lpc_correction(&interp_model, lpc_correction);
+           #endif
            
            if (phase0)
-               phase_synth_zero_order(&interp_model, ak, ex_phase);    
+               phase_synth_zero_order(&interp_model, ak_interp, ex_phase);     
            if (postfilt)
                postfilter(&interp_model, &bg_est);
            synth_one_frame(buf, &interp_model, Sn_, Pn);
@@ -369,6 +371,9 @@ int main(int argc, char *argv[])
            if (fout != NULL) fwrite(buf,sizeof(short),N,fout);
 
            prev_model = model;
+           for(i=0; i<LPC_ORD; i++)
+               prev_lsps[i] = lsps[i];
+           prev_e = e;
        }
        else {
            voiced1 = model.voiced;
index 0889fc63ef2981f0ef837b5dda739df57ebd40cc..dbdb5bf5d4bff11082be2cedbf65db80a75b68c0 100644 (file)
@@ -31,6 +31,8 @@
 
 #include "defines.h"
 #include "interp.h"
+#include "lsp.h"
+#include "quantise.h"
 
 float sample_log_amp(MODEL *model, float w);
 
@@ -47,6 +49,12 @@ float sample_log_amp(MODEL *model, float w);
 
   This version can interpolate the amplitudes between two frames of
   different Wo and L.
+
+  This version works by log linear interpolation, but listening tests
+  showed it creates problems in background noise, e.g. hts2a and mmt1.
+  When this function is used (--dec mode) bg noise appears to be
+  amplitude modulated, and gets louder.  The interp_lsp() function
+  below seems to do a better job.
   
 \*---------------------------------------------------------------------------*/
 
@@ -120,3 +128,64 @@ float sample_log_amp(MODEL *model, float w)
     return log_amp;
 }
 
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: interp_lsp()        
+  AUTHOR......: David Rowe                           
+  DATE CREATED: 10 Nov 2010
+        
+  Given two frames decribed by model parameters 20ms apart, determines
+  the model parameters of the 10ms frame between them.  Assumes
+  voicing is available for middle (interpolated) frame.  Outputs are
+  amplitudes and Wo for the interpolated frame.
+
+  This version uses interpolation of LSPs, seems to do a better job
+  with bg noise.
+  
+\*---------------------------------------------------------------------------*/
+
+void interpolate_lsp(
+  MODEL *interp,    /* interpolated model params                     */
+  MODEL *prev,      /* previous frames model params                  */
+  MODEL *next,      /* next frames model params                      */
+  float *prev_lsps, /* previous frames LSPs                          */
+  float  prev_e,    /* previous frames LPC energy                    */
+  float *next_lsps, /* next frames LSPs                              */
+  float  next_e,    /* next frames LPC energy                        */
+  float *ak_interp  /* interpolated aks for this frame                */
+                    )
+{
+    int   l,i;
+    float lsps[LPC_ORD],e;
+    float snr;
+
+    /* Wo depends on voicing of this and adjacent frames */
+
+    if (interp->voiced) {
+       if (prev->voiced && next->voiced)
+           interp->Wo = (prev->Wo + next->Wo)/2.0;
+       if (!prev->voiced && next->voiced)
+           interp->Wo = next->Wo;
+       if (prev->voiced && !next->voiced)
+           interp->Wo = prev->Wo;
+    }
+    else {
+       interp->Wo = TWO_PI/P_MAX;
+    }
+    interp->L = PI/interp->Wo;
+
+    /* interpolate LSPs */
+
+    for(i=0; i<LPC_ORD; i++) {
+       lsps[i] = (prev_lsps[i] + next_lsps[i])/2.0;
+    }
+
+    /* Interpolate LPC energy in log domain */
+
+    e = pow(10.0, (log10(prev_e) + log10(next_e))/2.0);
+
+    /* convert back to amplitudes */
+
+    lsp_to_lpc(lsps, ak_interp, LPC_ORD);
+    aks_to_M2(ak_interp, LPC_ORD, interp, e, &snr, 0); 
+}
index 653b18325fad4dd9192a75e93aa41a17e2d167aa..3dd5f83714ef68c574c65b9bd12f4953820d9a55 100644 (file)
@@ -29,5 +29,9 @@
 #define __INTERP__
 
 void interpolate(MODEL *interp, MODEL *prev, MODEL *next);
+void interpolate_lsp(MODEL *interp, MODEL *prev, MODEL *next, 
+                    float *prev_lsps, float  prev_e,
+                    float *next_lsps, float  next_e,
+                    float *ak_interp);
 
 #endif