exposed lpc post filter to codec2.h interface so we can play with it in real time...
authordrowe67 <drowe67@01035d8c-6547-0410-b346-abe4f91aad63>
Sun, 25 Nov 2012 01:39:12 +0000 (01:39 +0000)
committerdrowe67 <drowe67@01035d8c-6547-0410-b346-abe4f91aad63>
Sun, 25 Nov 2012 01:39:12 +0000 (01:39 +0000)
git-svn-id: https://svn.code.sf.net/p/freetel/code@1061 01035d8c-6547-0410-b346-abe4f91aad63

codec2-dev/src/c2sim.c
codec2-dev/src/codec2.c
codec2-dev/src/codec2.h
codec2-dev/src/codec2_internal.h
codec2-dev/src/interp.c
codec2-dev/src/quantise.c
codec2-dev/src/quantise.h

index 6aef4ef2e1d69d07faef7320decd9a858dfd43d1..d47f0bbd42b999cfc27fc47aa1c46c1447c7f1b9 100644 (file)
@@ -692,7 +692,7 @@ int main(int argc, char *argv[])
 
            }
 
-           aks_to_M2(fft_fwd_cfg, ak, order, &model, e, &snr, 1, simlpcpf, lpcpf); 
+           aks_to_M2(fft_fwd_cfg, ak, order, &model, e, &snr, 1, simlpcpf, lpcpf, 1, LPCPF_BETA, LPCPF_GAMMA); 
            apply_lpc_correction(&model);
 
             #ifdef DUMP
index 631a1bc34a93fbd81042f1e402ddc632ac20f64a..f1517a60c2d2dea7afd5a21690413b3551d2c331 100644 (file)
@@ -131,6 +131,8 @@ struct CODEC2 * CODEC2_WIN32SUPPORT codec2_create(int mode)
        return NULL;
     }
 
+    c2->lpc_pf = 1; c2->bass_boost = 1; c2->beta = LPCPF_BETA; c2->gamma = LPCPF_GAMMA;
+
     c2->xq_enc[0] = c2->xq_enc[1] = 0.0;
     c2->xq_dec[0] = c2->xq_dec[1] = 0.0;
 
@@ -374,7 +376,8 @@ void codec2_decode_3200(struct CODEC2 *c2, short speech[], const unsigned char *
     interpolate_lsp_ver2(&lsps[0][0], c2->prev_lsps_dec, &lsps[1][0], 0.5);
     for(i=0; i<2; i++) {
        lsp_to_lpc(&lsps[i][0], &ak[i][0], LPC_ORD);
-       aks_to_M2(c2->fft_fwd_cfg, &ak[i][0], LPC_ORD, &model[i], e[i], &snr, 0, 0, 1); 
+       aks_to_M2(c2->fft_fwd_cfg, &ak[i][0], LPC_ORD, &model[i], e[i], &snr, 0, 0, 
+                  c2->lpc_pf, c2->bass_boost, c2->beta, c2->gamma); 
        apply_lpc_correction(&model[i]);
     }
 
@@ -519,7 +522,8 @@ void codec2_decode_2400(struct CODEC2 *c2, short speech[], const unsigned char *
     interpolate_lsp_ver2(&lsps[0][0], c2->prev_lsps_dec, &lsps[1][0], 0.5);
     for(i=0; i<2; i++) {
        lsp_to_lpc(&lsps[i][0], &ak[i][0], LPC_ORD);
-       aks_to_M2(c2->fft_fwd_cfg, &ak[i][0], LPC_ORD, &model[i], e[i], &snr, 0, 0, 1); 
+       aks_to_M2(c2->fft_fwd_cfg, &ak[i][0], LPC_ORD, &model[i], e[i], &snr, 0, 0, 
+                  c2->lpc_pf, c2->bass_boost, c2->beta, c2->gamma); 
        apply_lpc_correction(&model[i]);
     }
 
@@ -691,7 +695,8 @@ void codec2_decode_1400(struct CODEC2 *c2, short speech[], const unsigned char *
     }
     for(i=0; i<4; i++) {
        lsp_to_lpc(&lsps[i][0], &ak[i][0], LPC_ORD);
-       aks_to_M2(c2->fft_fwd_cfg, &ak[i][0], LPC_ORD, &model[i], e[i], &snr, 0, 0, 1); 
+       aks_to_M2(c2->fft_fwd_cfg, &ak[i][0], LPC_ORD, &model[i], e[i], &snr, 0, 0,
+                  c2->lpc_pf, c2->bass_boost, c2->beta, c2->gamma); 
        apply_lpc_correction(&model[i]);
     }
 
@@ -868,7 +873,8 @@ void codec2_decode_1200(struct CODEC2 *c2, short speech[], const unsigned char *
     }
     for(i=0; i<4; i++) {
        lsp_to_lpc(&lsps[i][0], &ak[i][0], LPC_ORD);
-       aks_to_M2(c2->fft_fwd_cfg, &ak[i][0], LPC_ORD, &model[i], e[i], &snr, 0, 0, 1); 
+       aks_to_M2(c2->fft_fwd_cfg, &ak[i][0], LPC_ORD, &model[i], e[i], &snr, 0, 0,
+                  c2->lpc_pf, c2->bass_boost, c2->beta, c2->gamma); 
        apply_lpc_correction(&model[i]);
     }
 
@@ -998,3 +1004,14 @@ void ear_protection(float in_out[], int n) {
             in_out[i] *= gain;
     }
 }
+
+int CODEC2_WIN32SUPPORT codec2_set_lpc_post_filter(struct CODEC2 *c2, int enable, int bass_boost, float beta, float gamma)
+{
+    assert((beta >= 0.0) && (beta <= 1.0));
+    assert((gamma >= 0.0) && (gamma <= 1.0));
+    c2->lpc_pf = enable;
+    c2->bass_boost = bass_boost;
+    c2->beta = beta;
+    c2->gamma = gamma;
+}
+
index 9741449c1a1530e835a23b4a767646ef0f585cbf..b97fc0dfa1234e17c7ed431094ffe5361cf7065e 100644 (file)
@@ -59,6 +59,7 @@ void CODEC2_WIN32SUPPORT codec2_encode(struct CODEC2 *codec2_state, unsigned cha
 void CODEC2_WIN32SUPPORT codec2_decode(struct CODEC2 *codec2_state, short speech_out[], const unsigned char *bits);
 int  CODEC2_WIN32SUPPORT codec2_samples_per_frame(struct CODEC2 *codec2_state);
 int  CODEC2_WIN32SUPPORT codec2_bits_per_frame(struct CODEC2 *codec2_state);
+int  CODEC2_WIN32SUPPORT codec2_set_lpc_post_filter(struct CODEC2 *codec2_state, int enable, int bass_boost, float beta, float gamma);
 
 #endif
 
index b006d03515287f6059856eb8755bdd8ef781ea41..5c6d279c807fe30f710517b9796151596a44fa4c 100644 (file)
@@ -47,6 +47,11 @@ struct CODEC2 {
     MODEL         prev_model_dec;          /* previous frame's model parameters         */
     float         prev_lsps_dec[LPC_ORD];  /* previous frame's LSPs                     */
     float         prev_e_dec;              /* previous frame's LPC energy               */
+    
+    int           lpc_pf;                  /* LPC post filter on                        */
+    int           bass_boost;              /* LPC post filter bass boost                */
+    float         beta;                    /* LPC post filter parameters                */
+    float         gamma;
 
     float         xq_enc[2];               /* joint pitch and energy VQ states          */
     float         xq_dec[2];
index ebb579ab51a3bdcc9b4c9f12a3a511c92c2d260c..a8d818fa4279eebd19ee07b9dbc6800f1f5bfe2a 100644 (file)
@@ -201,7 +201,7 @@ void interpolate_lsp(
     /* convert back to amplitudes */
 
     lsp_to_lpc(lsps_interp, ak_interp, LPC_ORD);
-    aks_to_M2(fft_fwd_cfg, ak_interp, LPC_ORD, interp, e, &snr, 0, 0, 1); 
+    aks_to_M2(fft_fwd_cfg, ak_interp, LPC_ORD, interp, e, &snr, 0, 0, 1, 1, LPCPF_BETA, LPCPF_GAMMA); 
     //printf("  interp: ak[1]: %f A[1] %f\n", ak_interp[1], interp->A[1]);
 }
 
index 47601ac7d3c4e66592c291242c688d4d60f22905..1153943b9fe6a21f42d2f06f3db33001eea3142c 100644 (file)
@@ -901,10 +901,8 @@ float lpc_model_amplitudes(
 
 \*---------------------------------------------------------------------------*/
 
-#define LPCPF_GAMMA 0.5
-#define LPCPF_BETA  0.2
-
-void lpc_post_filter(kiss_fft_cfg fft_fwd_cfg, MODEL *model, COMP Pw[], float ak[], int order, int dump)
+void lpc_post_filter(kiss_fft_cfg fft_fwd_cfg, MODEL *model, COMP Pw[], float ak[], 
+                     int order, int dump, float beta, float gamma, int bass_boost)
 {
     int   i;
     COMP  x[FFT_ENC];   /* input to FFTs                */
@@ -945,7 +943,7 @@ void lpc_post_filter(kiss_fft_cfg fft_fwd_cfg, MODEL *model, COMP Pw[], float ak
     }
     
     for(i=0; i<=order; i++)
-       x[i].real = ak[i] * pow(LPCPF_GAMMA, (float)i);
+       x[i].real = ak[i] * pow(gamma, (float)i);
     kiss_fft(fft_fwd_cfg, (kiss_fft_cpx *)x, (kiss_fft_cpx *)Ww);
 
     for(i=0; i<FFT_ENC/2; i++) {
@@ -985,7 +983,7 @@ void lpc_post_filter(kiss_fft_cfg fft_fwd_cfg, MODEL *model, COMP Pw[], float ak
 
     e_after = 1E-4;
     for(i=0; i<FFT_ENC/2; i++) {
-       Pfw[i] = pow(Rw[i], LPCPF_BETA);
+       Pfw[i] = pow(Rw[i], beta);
        Pw[i].real *= Pfw[i] * Pfw[i];
        e_after += Pw[i].real;
     }
@@ -997,13 +995,13 @@ void lpc_post_filter(kiss_fft_cfg fft_fwd_cfg, MODEL *model, COMP Pw[], float ak
        Pw[i].real *= gain;
     }
 
-    /* add 3dB to first 1 kHz to account for LP effect of PF */
+    if (bass_boost) {
+        /* add 3dB to first 1 kHz to account for LP effect of PF */
 
-    for(i=0; i<FFT_ENC/8; i++) {
-       Pw[i].real *= 1.4*1.4;
+        for(i=0; i<FFT_ENC/8; i++) {
+            Pw[i].real *= 1.4*1.4;
+        }    
     }
-    
-
 }
 
 
@@ -1026,7 +1024,10 @@ void aks_to_M2(
   float        *snr,        /* signal to noise ratio for this frame in dB */
   int           dump,        /* true to dump sample to dump file */
   int           sim_pf,      /* true to simulate a post filter */
-  int           pf           /* true to post filter */
+  int           pf,          /* true to LPC post filter */
+  int           bass_boost,  /* enable LPC filter 0-1khz 3dB boost */
+  float         beta,
+  float         gamma        /* LPC post filter parameters */
 )
 {
   COMP pw[FFT_ENC];    /* input to FFT for power spectrum */
@@ -1057,7 +1058,7 @@ void aks_to_M2(
     Pw[i].real = E/(Pw[i].real*Pw[i].real + Pw[i].imag*Pw[i].imag);
 
   if (pf)
-      lpc_post_filter(fft_fwd_cfg, model, Pw, ak, order, dump);
+      lpc_post_filter(fft_fwd_cfg, model, Pw, ak, order, dump, beta, gamma, bass_boost);
 
   #ifdef DUMP
   if (dump) 
index ccf7a31c7151dc69abe1dfb194e615fb9667988e..1f5f9ee788d7890254e74ae7d1bff85c267ccdef 100644 (file)
 
 #define WO_E_BITS   8
 
+#define LPCPF_GAMMA 0.5
+#define LPCPF_BETA  0.2
+
 void quantise_init();
 float lpc_model_amplitudes(float Sn[], float w[], MODEL *model, int order,
                           int lsp,float ak[]);
 void aks_to_M2(kiss_fft_cfg fft_fwd_cfg, float ak[], int order, MODEL *model, 
-              float E, float *snr, int dump, int sim_pf, int pf);
+              float E, float *snr, int dump, int sim_pf, 
+               int pf, int bass_boost, float beta, float gamma);
 
 int   encode_Wo(float Wo);
 float decode_Wo(int index);