added 1400 bps mode using JVMs joint energy Wo quantiser. Fixed bug in modem where...
authordrowe67 <drowe67@01035d8c-6547-0410-b346-abe4f91aad63>
Fri, 11 May 2012 04:17:14 +0000 (04:17 +0000)
committerdrowe67 <drowe67@01035d8c-6547-0410-b346-abe4f91aad63>
Fri, 11 May 2012 04:17:14 +0000 (04:17 +0000)
git-svn-id: https://svn.code.sf.net/p/freetel/code@416 01035d8c-6547-0410-b346-abe4f91aad63

12 files changed:
codec2-dev/README
codec2-dev/README_fdmdv.txt
codec2-dev/octave/fdmdv.m
codec2-dev/src/c2dec.c
codec2-dev/src/c2enc.c
codec2-dev/src/c2sim.c
codec2-dev/src/codec2.c
codec2-dev/src/codec2.h
codec2-dev/src/fdmdv.c
codec2-dev/src/quantise.c
codec2-dev/src/quantise.h
codec2-dev/unittest/genlsp.c

index 1f5e0e215a056388e7bf4b40d51bc84f24ec1f84..3b78e41301b97547db9149301757e8df8ee37022 100644 (file)
@@ -69,3 +69,9 @@ Directories
   voicing  - hand-estimated voicing files, used for development
   wav      - speech files in wave file format
 
+TODO
+----
+
+[ ] Make sure we have separate state variables for enc and dec on
+    modes that use difference in time coding and have statesthat are
+    presevred from frame to frame.
\ No newline at end of file
index e67ce80d55fc21594f360e18767370c3d8761b30..9c61bc60aead81134a6a52d6829e97b3adce2237 100644 (file)
@@ -55,6 +55,8 @@ $ cd src
 
    $ sox -r 8000 -s -2 modem_sample_8kHz.raw -r 48000 modem_sample_48kHz.wav
 
+   For real time applications, the fdmdv.[ch] library includes functions to
+   convert between 48 and 8 kHz sample rates.
 
 References
 ----------
index 1a5ba6eece119d514b28bb6a34f1895f14f87ca8..303b172b41a89e48bb0289e7b089f633b65b95ad 100644 (file)
@@ -434,10 +434,10 @@ function [rx_bits sync_bit f_err] = qpsk_to_bits(prev_rx_symbols, rx_symbols, mo
 
     phase_difference(Nc+1) = rx_symbols(Nc+1) .* conj(prev_rx_symbols(Nc+1));
     if (real(phase_difference(Nc+1)) < 0)
-      sync_bit = 0;
+      sync_bit = 1;
       f_err = imag(phase_difference(Nc+1));
     else
-      sync_bit = 1;
+      sync_bit = 0;
       f_err = -imag(phase_difference(Nc+1));
     end
 
index e3d90fd56e70737cb28ebf897daa83d33b9486bf..ad26f3fa88fe95dcb99e229afec977016cb69f32 100644 (file)
@@ -44,7 +44,7 @@ int main(int argc, char *argv[])
     float          ber, r;
 
     if (argc < 4) {
-       printf("usage: c2dec 2500|1500|1125 InputBitFile OutputRawSpeechFile\n");
+       printf("usage: c2dec 2500|1500|1400|1125 InputBitFile OutputRawSpeechFile\n");
        printf("e.g    c2dec 1500 hts1a.c2 hts1a_1500.raw\n");
        exit(1);
     }
@@ -53,10 +53,12 @@ int main(int argc, char *argv[])
        mode = CODEC2_MODE_2500;
     else if (strcmp(argv[1],"1500") == 0)
        mode = CODEC2_MODE_1500;
+    else if (strcmp(argv[1],"1400") == 0)
+       mode = CODEC2_MODE_1400;
     else if (strcmp(argv[1],"1200") == 0)
        mode = CODEC2_MODE_1200;
     else {
-       fprintf(stderr, "Error in mode: %s.  Must be 2500 or 1500 or 1200\n", argv[1]);
+       fprintf(stderr, "Error in mode: %s.  Must be 2500, 1500, 1400 or 1200\n", argv[1]);
        exit(1);
     }
     
index 8a5fc961b0f1636cbf5ca057730a738a30626522..707ad2356743955e38b221fd8eaca0a5f184ae19 100644 (file)
@@ -44,7 +44,7 @@ int main(int argc, char *argv[])
     int            nsam, nbit, nbyte;
 
     if (argc != 4) {
-       printf("usage: c2enc 2500|1500|1200 InputRawspeechFile OutputBitFile\n");
+       printf("usage: c2enc 2500|1500|1400|1200 InputRawspeechFile OutputBitFile\n");
        printf("e.g    c2enc 1500 ../raw/hts1a.raw hts1a.c2\n");
        exit(1);
     }
@@ -53,10 +53,12 @@ int main(int argc, char *argv[])
        mode = CODEC2_MODE_2500;
     else if (strcmp(argv[1],"1500") == 0)
        mode = CODEC2_MODE_1500;
+    else if (strcmp(argv[1],"1400") == 0)
+       mode = CODEC2_MODE_1400;
     else if (strcmp(argv[1],"1200") == 0)
        mode = CODEC2_MODE_1200;
     else {
-       fprintf(stderr, "Error in mode: %s.  Must be 2500 or 1500 or 1200\n", argv[1]);
+       fprintf(stderr, "Error in mode: %s.  Must be 2500, 1500, 1400 or 1200\n", argv[1]);
        exit(1);
     }
 
index 9933797ba62396209d33e4caaf46a4542fba121d..2a06ed3108690e950a7283a08869bac778f8128a 100644 (file)
@@ -105,7 +105,7 @@ int main(int argc, char *argv[])
     float ak_interp[LPC_MAX];
     int   lsp_indexes[LPC_MAX];
     float lsps_[LPC_MAX];
-    float Woe[2], Woe_[2];
+    float Woe_[2];
 
     void *nlp_states;
     float hpf_states[2];
@@ -241,6 +241,14 @@ int main(int argc, char *argv[])
                    postfilt = 1;
                    decimate = 1;
                    dt = 1;
+               } else if(strcmp(optarg,"1400") == 0) {
+                   lpc_model = 1; order = 10;
+                   vector_quant_Wo_e = 1;
+                   lsp = 1; lspdt = 1;
+                   phase0 = 1;
+                   postfilt = 1;
+                   decimate = 1;
+                   dt = 1;
                 } else if(strcmp(optarg,"1200") == 0) {
                    lpc_model = 1; order = 10;
                    scalar_quant_Wo_e = 1;
@@ -548,19 +556,10 @@ int main(int argc, char *argv[])
 
                /* JVM's experimental joint Wo & LPC energy quantiser */
 
-               Woe[0] = log10((model.Wo/PI)*4000.0/50.0)/log10(2);
-               Woe[1] = 10.0*log10(1e-4+e);
-               ge_quantise(Woe, Woe_);
-
-               /*
-                 x = log2(4000*Wo/(PI*50));
-                 2^x = 4000*Wo/(PI*50)
-                 Wo = (2^x)*(PI*50)/4000;
-               */
+               printf("\nWo %f e %f\n", model.Wo, e);
+               quantise_WoE(&model, &e, Woe_);
+               printf("Wo %f e %f\n", model.Wo, e);
 
-               model.Wo = pow(2.0, Woe_[0])*(PI*50.0)/4000.0;
-               model.L  = PI/model.Wo; /* if we quantise Wo re-compute L */
-               e = pow(10.0, Woe_[1]/10.0);
            }
 
            aks_to_M2(ak, order, &model, e, &snr, 1); 
@@ -765,7 +764,7 @@ void print_help(const struct option* long_options, int num_opts, char* argv[])
                } else if (strcmp("dump_pitch_e", long_options[i].name) == 0) {
                        option_parameters = " <Dump File>";
                } else if (strcmp("rate", long_options[i].name) == 0) {
-                       option_parameters = " <2500|1500|1200>";
+                       option_parameters = " <2500|1500|1400|1200>";
                } else if (strcmp("dump", long_options[i].name) == 0) {
                        option_parameters = " <DumpFilePrefix>";
                } else {
index 984b81704ba7ddd11e2bbe9a560f4691fe228c2c..7e1e86cec4ead8ad9502e7596ed45093faef304d 100644 (file)
@@ -59,6 +59,9 @@ struct CODEC2 {
     MODEL  prev_model;          /* previous frame's model parameters         */
     float  prev_lsps_[LPC_ORD]; /* previous frame's LSPs                     */
     float  prev_energy;         /* previous frame's LPC energy               */
+
+    float  xq_enc[2];           /* joint pitch and energy VQ states          */
+    float  xq_dec[2];
 };
 
 /*---------------------------------------------------------------------------*\
@@ -74,6 +77,8 @@ void codec2_encode_2500(struct CODEC2 *c2, unsigned char * bits, short speech[])
 void codec2_decode_2500(struct CODEC2 *c2, short speech[], const unsigned char * bits);
 void codec2_encode_1500(struct CODEC2 *c2, unsigned char * bits, short speech[]);
 void codec2_decode_1500(struct CODEC2 *c2, short speech[], const unsigned char * bits);
+void codec2_encode_1400(struct CODEC2 *c2, unsigned char * bits, short speech[]);
+void codec2_decode_1400(struct CODEC2 *c2, short speech[], const unsigned char * bits);
 void codec2_encode_1200(struct CODEC2 *c2, unsigned char * bits, short speech[]);
 void codec2_decode_1200(struct CODEC2 *c2, short speech[], const unsigned char * bits);
 
@@ -109,6 +114,7 @@ struct CODEC2 *codec2_create(int mode)
     assert(
           (mode == CODEC2_MODE_2500) || 
           (mode == CODEC2_MODE_1500) || 
+          (mode == CODEC2_MODE_1400) || 
           (mode == CODEC2_MODE_1200)
           );
     c2->mode = mode;
@@ -141,6 +147,9 @@ struct CODEC2 *codec2_create(int mode)
        return NULL;
     }
 
+    c2->xq_enc[0] = c2->xq_enc[1] = 0.0;
+    c2->xq_dec[0] = c2->xq_dec[1] = 0.0;
+
     return c2;
 }
 
@@ -176,6 +185,8 @@ int codec2_bits_per_frame(struct CODEC2 *c2) {
        return 50;
     if  (c2->mode == CODEC2_MODE_1500)
        return 60;
+    if  (c2->mode == CODEC2_MODE_1400)
+       return 56;
     if  (c2->mode == CODEC2_MODE_1200)
        return 48;
 
@@ -198,6 +209,8 @@ int codec2_samples_per_frame(struct CODEC2 *c2) {
        return 160;
     if  (c2->mode == CODEC2_MODE_1500)
        return 320;
+    if  (c2->mode == CODEC2_MODE_1400)
+       return 320;
     if  (c2->mode == CODEC2_MODE_1200)
        return 320;
 
@@ -210,6 +223,7 @@ void codec2_encode(struct CODEC2 *c2, unsigned char *bits, short speech[])
     assert(
           (c2->mode == CODEC2_MODE_2500) || 
           (c2->mode == CODEC2_MODE_1500) || 
+          (c2->mode == CODEC2_MODE_1400) || 
           (c2->mode == CODEC2_MODE_1200)
           );
 
@@ -217,6 +231,8 @@ void codec2_encode(struct CODEC2 *c2, unsigned char *bits, short speech[])
        codec2_encode_2500(c2, bits, speech);
     if (c2->mode == CODEC2_MODE_1500)
        codec2_encode_1500(c2, bits, speech);
+    if (c2->mode == CODEC2_MODE_1400)
+       codec2_encode_1400(c2, bits, speech);
     if (c2->mode == CODEC2_MODE_1200)
        codec2_encode_1200(c2, bits, speech);
 }
@@ -227,6 +243,7 @@ void codec2_decode(struct CODEC2 *c2, short speech[], const unsigned char *bits)
     assert(
           (c2->mode == CODEC2_MODE_2500) || 
           (c2->mode == CODEC2_MODE_1500) || 
+          (c2->mode == CODEC2_MODE_1400) || 
           (c2->mode == CODEC2_MODE_1200)
           );
 
@@ -234,6 +251,8 @@ void codec2_decode(struct CODEC2 *c2, short speech[], const unsigned char *bits)
        codec2_decode_2500(c2, speech, bits);
     if (c2->mode == CODEC2_MODE_1500)
        codec2_decode_1500(c2, speech, bits);
+    if (c2->mode == CODEC2_MODE_1400)
+       codec2_decode_1400(c2, speech, bits);
     if (c2->mode == CODEC2_MODE_1200)
        codec2_decode_1200(c2, speech, bits);
 }
@@ -337,7 +356,7 @@ void codec2_decode_2500(struct CODEC2 *c2, short speech[], const unsigned char *
     int     i;
     unsigned int nbit = 0;
     MODEL   model_interp;
-    static  int frames;
+    //static  int frames;
 
     //fprintf(stderr,"frame: %d\n", frames+=2);
     assert(c2 != NULL);
@@ -426,15 +445,15 @@ void codec2_decode_2500(struct CODEC2 *c2, short speech[], const unsigned char *
   AUTHOR......: David Rowe                           
   DATE CREATED: Nov 14 2011 
 
-  Encodes 320 speech samples (40ms of speech) into 60 bits.  
+  Encodes 320 speech samples (40ms of speech) into 60 bits.
 
   The codec2 algorithm actually operates internally on 10ms (80
   sample) frames, so we run the encoding algorithm for times:
 
   frame 0: just send voicing bit
-  frame 1: scalar quantisation of LSPs and Wo and E
+  frame 1: scalar quantisation of LSPs, Wo and E
   frame 2: just send voicing bit
-  frame 3: delta-time quantisation Wo and E
+  frame 3: delta-time Wo and scalar E
 
   The bit allocation is:
 
@@ -551,9 +570,9 @@ void codec2_encode_1500(struct CODEC2 *c2, unsigned char * bits, short speech[])
                                                        
   FUNCTION....: codec2_decode_1500          
   AUTHOR......: David Rowe                           
-  DATE CREATED: 16 Nov 2011
+  DATE CREATED: 11 May 2012
 
-  Decodes frames of 56 bits into 320 samples (40ms) of speech.
+  Decodes frames of 60 bits into 320 samples (40ms) of speech.
 
 \*---------------------------------------------------------------------------*/
 
@@ -730,6 +749,300 @@ void codec2_decode_1500(struct CODEC2 *c2, short speech[], const unsigned char *
 
 }
 
+
+/*---------------------------------------------------------------------------*\
+                                                       
+  FUNCTION....: codec2_encode_1400          
+  AUTHOR......: David Rowe                           
+  DATE CREATED: May 11 2012
+
+  Encodes 320 speech samples (40ms of speech) into 56 bits.
+
+  The codec2 algorithm actually operates internally on 10ms (80
+  sample) frames, so we run the encoding algorithm for times:
+
+  frame 0: just send voicing bit
+  frame 1: scalar quantisation of LSPs, joint VQ of Wo and E
+  frame 2: just send voicing bit
+  frame 3: joint VQ of Wo and E
+
+  The bit allocation is:
+
+    Parameter                      frame 2  frame 4   Total
+    -------------------------------------------------------
+    Harmonic magnitudes (LSPs)     36        0        36
+    Energy+Wo                       8        8        16
+    Voicing (10ms update)           2        2         4
+    TOTAL                          46       10        56
+\*---------------------------------------------------------------------------*/
+
+void codec2_encode_1400(struct CODEC2 *c2, unsigned char * bits, short speech[])
+{
+    MODEL   model;
+    float   lsps[LPC_ORD], lsps_[LPC_ORD];
+    float   ak[LPC_ORD+1];
+    float   e;
+    int     voiced1, voiced2, voiced3, voiced4;
+    int     lsp_indexes[LPC_ORD];
+    int     WoE_index;
+    int     i;
+    unsigned int nbit = 0;
+    unsigned int nbit_tmp;
+    //static  int frames;
+
+    assert(c2 != NULL);
+
+    memset(bits, '\0',  ((codec2_bits_per_frame(c2) + 7) / 8));
+
+    /* frame 1: - we just want voicing -------------------------------- */
+
+    //fprintf(stderr,"frame: %d\n", ++frames);
+    analyse_one_frame(c2, &model, speech);
+    voiced1 = model.voiced;
+
+    /* frame 2: - full LSP, joint Wo & EE ----------------------------- */
+
+    //fprintf(stderr,"frame: %d\n", ++frames);
+    analyse_one_frame(c2, &model, &speech[N]);
+    voiced2 = model.voiced;
+    
+    e = speech_to_uq_lsps(lsps, ak, c2->Sn, c2->w, LPC_ORD);
+    encode_lsps_scalar(lsp_indexes, lsps, LPC_ORD);
+    WoE_index = encode_WoE(&model, e, c2->xq_enc);
+
+    for(i=0; i<LSP_SCALAR_INDEXES; i++) {
+       pack(bits, &nbit, lsp_indexes[i], lsp_bits(i));
+    }
+    pack(bits, &nbit, WoE_index, WO_E_BITS);
+    pack(bits, &nbit, voiced1, 1);
+    pack(bits, &nbit, voiced2, 1);
+
+    /* decode LSPs for testing */
+
+    decode_lsps_scalar(lsps_, lsp_indexes, LPC_ORD);
+    bw_expand_lsps(lsps_, LPC_ORD);
+    /*
+      fprintf(stderr,"\n  lsps_......: ");
+    for(i=0; i<LPC_ORD; i++)
+       fprintf(stderr,"%5.3f  ", lsps_[i]);
+    fprintf(stderr,"\n");
+    */
+
+    /* frame 3: - we just want voicing --------------------------------- */
+
+    //fprintf(stderr,"frame: %d\n", ++frames);
+    analyse_one_frame(c2, &model, &speech[2*N]);
+    voiced3 = model.voiced;
+
+    /* frame 4: - voicing and joint Wo & E ----------------------------  */
+
+    //fprintf(stderr,"frame: %d\n", ++frames);
+    analyse_one_frame(c2, &model, &speech[3*N]);
+    voiced4 = model.voiced;
+  
+    /* need to run this to get LPC energy */
+    e = speech_to_uq_lsps(lsps, ak, c2->Sn, c2->w, LPC_ORD);
+
+    WoE_index = encode_WoE(&model, e, c2->xq_enc);
+
+    //fprintf(stderr,"  e: %f code: %d dec: %f \n", e, energy_index, decode_energy(energy_index));
+
+    nbit_tmp = nbit;
+    pack(bits, &nbit, WoE_index, WO_E_BITS);
+    pack(bits, &nbit, voiced3, 1);
+    pack(bits, &nbit, voiced4, 1);
+    //fprintf(stderr,"          00 16 24 32 40 48 56\n"); 
+    //fprintf(stderr,"nbit = %d %02x %02x %02x %02x %02x %02x %02x %02x\n", nbit, 
+    //    bits[0], bits[1], bits[2], bits[3],
+    //    bits[4], bits[5], bits[6], bits[7]);
+
+    //fprintf(stderr,"  nbit_tmp: %d ", nbit_tmp);
+    // fprintf(stderr,"energy_index after: %d\n", energy_index);
+
+    assert(nbit == (unsigned)codec2_bits_per_frame(c2));
+    //if (frames == 36)
+    //exit(0);
+}
+
+
+/*---------------------------------------------------------------------------*\
+                                                       
+  FUNCTION....: codec2_decode_1400          
+  AUTHOR......: David Rowe                           
+  DATE CREATED: 11 May 2012
+
+  Decodes frames of 48 bits into 320 samples (40ms) of speech.
+
+\*---------------------------------------------------------------------------*/
+
+void codec2_decode_1400(struct CODEC2 *c2, short speech[], const unsigned char * bits)
+{
+    MODEL   model;
+    int     voiced1, voiced2, voiced3, voiced4;
+    int     lsp_indexes[LPC_ORD];
+    float   lsps_[LPC_ORD];
+    int     WoE_index;
+    float   energy;
+    float   snr;
+    float   ak[LPC_ORD+1];
+    float   ak_interp[LPC_ORD+1];
+    float   lsps_interp[LPC_ORD];
+    int     i;
+    unsigned int nbit = 0;
+    MODEL   model_interp;
+    static  int frames;
+    float   prev__Wo;
+
+    assert(c2 != NULL);
+
+    /* unpack frame 1 & 2 bit stream to integer codes */
+
+    for(i=0; i<LSP_SCALAR_INDEXES; i++) {
+       lsp_indexes[i] = unpack(bits, &nbit, lsp_bits(i));
+    }
+    WoE_index = unpack(bits, &nbit, WO_E_BITS);
+    voiced1 = unpack(bits, &nbit, 1);
+    voiced2 = unpack(bits, &nbit, 1);
+    /* decode codes to model parameters */
+
+    decode_WoE(&model, &energy, c2->xq_dec, WoE_index);
+    memset(&model.A, 0, (model.L+1)*sizeof(model.A[0]));
+
+    /* decode frame 2 LSPs and model amplitudes */
+
+    decode_lsps_scalar(lsps_, lsp_indexes, LPC_ORD);
+    check_lsp_order(lsps_, LPC_ORD);
+    bw_expand_lsps(lsps_, LPC_ORD);
+    lsp_to_lpc(lsps_, ak, LPC_ORD);
+    aks_to_M2(ak, LPC_ORD, &model, energy, &snr, 1); 
+    apply_lpc_correction(&model);
+
+    /* interpolate frame 1 model parameters from adjacent frames */
+
+    model.voiced = voiced2;
+    model_interp.voiced = voiced1;
+    model_interp.Wo = P_MAX/2;
+    memset(&model_interp.A, 0, MAX_AMP*sizeof(model_interp.A[0]));
+
+    interpolate_lsp(&model_interp, &c2->prev_model, &model,
+                   c2->prev_lsps_, c2->prev_energy, lsps_, energy, ak_interp,
+                   lsps_interp);
+    apply_lpc_correction(&model_interp);
+
+    frames += 2;
+    /* used for comparing to c2sim version 
+       fprintf(stderr,"frame: %d\n", frames);
+    fprintf(stderr,"  Wo: %1.5f  L: %d v1: %d prev_e: %f\n", 
+          model_interp.Wo, model_interp.L, model_interp.voiced, c2->prev_energy);
+    fprintf(stderr,"  lsps_interp: ");
+    for(i=0; i<LPC_ORD; i++)
+       fprintf(stderr,"%5.3f  ", lsps_interp[i]);
+    fprintf(stderr,"\n  A..........: ");
+    for(i=0; i<10; i++)
+       fprintf(stderr,"%5.3f  ",model_interp.A[i]);
+
+    fprintf(stderr,"\n  Wo: %1.5f  L: %d e: %3.2f v2: %d\n", 
+          model.Wo, model.L, energy, model.voiced);
+    fprintf(stderr,"  lsps_......: ");
+    for(i=0; i<LPC_ORD; i++)
+       fprintf(stderr,"%5.3f  ", lsps_[i]);
+    fprintf(stderr,"\n  A..........: ");
+    for(i=0; i<10; i++)
+       fprintf(stderr,"%5.3f  ",model.A[i]);
+    fprintf(stderr,"\n");
+    */
+
+    /* synthesise frame 1 and frame 2 10ms frames */
+
+    synthesise_one_frame(c2, speech, &model_interp, ak_interp);
+    //fprintf(stderr,"  buf[0] %d\n", speech[0]);
+    synthesise_one_frame(c2, &speech[N], &model, ak);
+    //fprintf(stderr,"  buf[0] %d\n", speech[N]);
+
+    /* update memories (decode states) for next time */
+
+    memcpy(&c2->prev_model, &model, sizeof(MODEL));
+    memcpy(c2->prev_lsps_, lsps_, sizeof(lsps_));
+    c2->prev_energy = energy;
+    prev__Wo = model.Wo;
+
+    /*--------------------------------------------------------------------*/
+
+    /* unpack frame 3 & 4 bit stream to integer codes */
+
+    WoE_index = unpack(bits, &nbit, WO_E_BITS);
+    voiced3 = unpack(bits, &nbit, 1);
+    voiced4 = unpack(bits, &nbit, 1);
+    assert(nbit == (unsigned)codec2_bits_per_frame(c2));
+
+    /* decode integer codes to model parameters */
+
+    memset(&model.A, 0, (model.L+1)*sizeof(model.A[0]));
+
+    /* decode frame 4  */
+
+    decode_WoE(&model, &energy, c2->xq_dec, WoE_index);
+    aks_to_M2(ak, LPC_ORD, &model, energy, &snr, 1); 
+    apply_lpc_correction(&model);
+
+    /* interpolate frame 3 model parameters from adjacent frames */
+
+    model.voiced = voiced4;
+    model_interp.voiced = voiced3;
+    model_interp.Wo = P_MAX/2;
+    memset(&model_interp.A, 0, MAX_AMP*sizeof(model_interp.A[0]));
+
+    interpolate_lsp(&model_interp, &c2->prev_model, &model,
+                   c2->prev_lsps_, c2->prev_energy, lsps_, energy, ak_interp,
+                   lsps_interp);
+    apply_lpc_correction(&model_interp);
+
+    frames +=2;
+    /* used for comparing to c2sim version:
+    fprintf(stderr,"frame: %d\n", frames);
+
+    fprintf(stderr,"  Wo: %1.5f  L: %d v1: %d prev_e: %f\n", 
+          model_interp.Wo, model_interp.L, model_interp.voiced, c2->prev_energy);
+    fprintf(stderr,"  lsps_interp: ");
+    for(i=0; i<LPC_ORD; i++)
+       fprintf(stderr,"%5.3f  ", lsps_interp[i]);
+    fprintf(stderr,"\n  A..........: ");
+    for(i=0; i<10; i++)
+       fprintf(stderr,"%5.3f  ",model_interp.A[i]);
+
+    fprintf(stderr,"\n  Wo: %1.5f  L: %d e_index: %d e: %3.2f v2: %d\n", 
+          model.Wo, model.L, energy_index, energy, model.voiced);
+    fprintf(stderr,"  lsps_......: ");
+    for(i=0; i<LPC_ORD; i++)
+       fprintf(stderr,"%5.3f  ", lsps_[i]);
+    fprintf(stderr,"\n  A..........: ");
+    for(i=0; i<10; i++)
+       fprintf(stderr,"%5.3f  ",model.A[i]);
+    fprintf(stderr,"\n");
+    */
+
+    /* synthesise frame 3 and frame 4 10ms frames */
+
+    synthesise_one_frame(c2, &speech[2*N], &model_interp, ak_interp);
+    //fprintf(stderr,"  buf[0] %d\n", speech[2*N]);
+    synthesise_one_frame(c2, &speech[3*N], &model, ak);
+    //fprintf(stderr,"  buf[0] %d\n", speech[3*N]);
+    if (frames == 44) {
+       //exit(0);
+    }
+
+    /* update memories (decode states) for next time */
+
+    memcpy(&c2->prev_model, &model, sizeof(MODEL));
+    memcpy(c2->prev_lsps_, lsps_, sizeof(lsps_));
+    c2->prev_energy = energy;
+
+}
+
+
 /*---------------------------------------------------------------------------*\
                                                        
   FUNCTION....: codec2_encode_1200          
index f45cf2ee5e78437c69b18791e8f32728747811d5..35c81c9d52c18981251c18accad67f6020343098 100644 (file)
@@ -34,7 +34,8 @@ extern "C" {
 
 #define CODEC2_MODE_2500 0
 #define CODEC2_MODE_1500 1
-#define CODEC2_MODE_1200 2
+#define CODEC2_MODE_1400 2
+#define CODEC2_MODE_1200 3
 
 struct CODEC2;
 
index bb78ffac4adf72d3faca1c2366da8ea72bc5f670..3e8e28a2fbfa7eb76c79edb24b8181a3f0579a05 100644 (file)
@@ -937,11 +937,11 @@ float qpsk_to_bits(int rx_bits[], int *sync_bit, COMP phase_difference[], COMP p
 
     phase_difference[NC] = cmult(rx_symbols[NC], cconj(prev_rx_symbols[NC]));
     if (phase_difference[NC].real < 0) {
-      *sync_bit = 0;
+      *sync_bit = 1;
       ferr = phase_difference[NC].imag;
     }
     else {
-      *sync_bit = 1;
+      *sync_bit = 0;
       ferr = -phase_difference[NC].imag;
     }
 
index ad7e40084b93b20de6fe330472809fcf0c671925..8762d0fef727dd563cd71c43908f1e66aa4fc33d 100644 (file)
@@ -1477,27 +1477,98 @@ void compute_weights2(const float *x, const float *xp, float *w, int ndim)
 
 /*---------------------------------------------------------------------------*\
                                                        
-  FUNCTION....: quantize_ge()       
+  FUNCTION....: quantise_WoE()      
   AUTHOR......: Jean-Marc Valin & David Rowe                         
   DATE CREATED: 29 Feb 2012
 
-  Experimental joint Wo and LPC energy vector quantiser developed my
-  Jean-Marc Valin.
+  Experimental joint Wo and LPC energy vector quantiser developed by
+  Jean-Marc Valin.  Exploits correlations between the difference in
+  the log pitch and log energy from frame to frame.  For example the
+  both the pitch and energy tend to only change by small amounts
+  during voiced speech, however it is important that these changes be
+  coded carefully.  During unvoiced speech they both change a lot but
+  the ear is less sensitve to errors so coarser quantisation is OK.
+
+  The ear is sensitive to log energy and loq pitch so we quantise in
+  thise domains.  That way the error measure used to quantise the
+  values is close to way the ear senses errors.
+  
+  See http://jmspeex.livejournal.com/10446.html
+
+\*---------------------------------------------------------------------------*/
+
+void quantise_WoE(MODEL *model, float *e, float xq[])
+{
+  int          i, n1;
+  float        x[2];
+  float        err[2];
+  float        w[2];
+  const float *codebook1 = ge_cb[0].cb;
+  int          nb_entries = ge_cb[0].m;
+  int          ndim = ge_cb[0].k;
+  float Wo_min = TWO_PI/P_MAX;
+  float Wo_max = TWO_PI/P_MIN;
+
+  x[0] = log10((model->Wo/PI)*4000.0/50.0)/log10(2);
+  x[1] = 10.0*log10(1e-4 + *e);
+
+  compute_weights2(x, xq, w, ndim);
+  for (i=0;i<ndim;i++)
+    err[i] = x[i]-ge_coeff[i]*xq[i];
+  n1 = find_nearest_weighted(codebook1, nb_entries, err, w, ndim);
+  
+  for (i=0;i<ndim;i++)
+  {
+    xq[i] = ge_coeff[i]*xq[i] + codebook1[ndim*n1+i];
+    err[i] -= codebook1[ndim*n1+i];
+  }
+
+  /*
+    x = log2(4000*Wo/(PI*50));
+    2^x = 4000*Wo/(PI*50)
+    Wo = (2^x)*(PI*50)/4000;
+  */
+  
+  model->Wo = pow(2.0, xq[0])*(PI*50.0)/4000.0;
+
+  /* bit errors can make us go out of range leading to all sorts of
+     probs like seg faults */
+
+  if (model->Wo > Wo_max) model->Wo = Wo_max;
+  if (model->Wo < Wo_min) model->Wo = Wo_min;
+
+  model->L  = PI/model->Wo; /* if we quantise Wo re-compute L */
+
+  *e = pow(10.0, xq[1]/10.0);
+}
+
+/*---------------------------------------------------------------------------*\
+                                                       
+  FUNCTION....: encode_WoE()        
+  AUTHOR......: Jean-Marc Valin & David Rowe                         
+  DATE CREATED: 11 May 2012
+
+  Joint Wo and LPC energy vector quantiser developed my Jean-Marc
+  Valin.  Returns index, and updated states xq[].
   
 \*---------------------------------------------------------------------------*/
 
-void ge_quantise(float *x, float *xq)
+int encode_WoE(MODEL *model, float e, float xq[])
 {
   int          i, n1;
+  float        x[2];
   float        err[2];
   float        w[2];
   const float *codebook1 = ge_cb[0].cb;
   int          nb_entries = ge_cb[0].m;
   int          ndim = ge_cb[0].k;
 
-  //printf("ndim %d nb_entries %d\n", ndim, nb_entries);
+  assert((1<<WO_E_BITS) == nb_entries);
+
+  x[0] = log10((model->Wo/PI)*4000.0/50.0)/log10(2);
+  x[1] = 10.0*log10(1e-4 + e);
+
   compute_weights2(x, xq, w, ndim);
-  //exit(0);
   for (i=0;i<ndim;i++)
     err[i] = x[i]-ge_coeff[i]*xq[i];
   n1 = find_nearest_weighted(codebook1, nb_entries, err, w, ndim);
@@ -1508,5 +1579,47 @@ void ge_quantise(float *x, float *xq)
     err[i] -= codebook1[ndim*n1+i];
   }
 
+  return n1;
+}
+
+
+/*---------------------------------------------------------------------------*\
+                                                       
+  FUNCTION....: decode_WoE()        
+  AUTHOR......: Jean-Marc Valin & David Rowe                         
+  DATE CREATED: 11 May 2012
+
+  Joint Wo and LPC energy vector quantiser developed my Jean-Marc
+  Valin.  Given index and states xq[], returns Wo & E, and updates
+  states xq[].
+  
+\*---------------------------------------------------------------------------*/
+
+void decode_WoE(MODEL *model, float *e, float xq[], int n1)
+{
+  int          i;
+  float        err[2];
+  const float *codebook1 = ge_cb[0].cb;
+  int          ndim = ge_cb[0].k;
+  float Wo_min = TWO_PI/P_MAX;
+  float Wo_max = TWO_PI/P_MIN;
+
+  for (i=0;i<ndim;i++)
+  {
+    xq[i] = ge_coeff[i]*xq[i] + codebook1[ndim*n1+i];
+    err[i] -= codebook1[ndim*n1+i];
+  }
+
+  model->Wo = pow(2.0, xq[0])*(PI*50.0)/4000.0;
+
+  /* bit errors can make us go out of range leading to all sorts of
+     probs like seg faults */
+
+  if (model->Wo > Wo_max) model->Wo = Wo_max;
+  if (model->Wo < Wo_min) model->Wo = Wo_min;
+
+  model->L  = PI/model->Wo; /* if we quantise Wo re-compute L */
+
+  *e = pow(10.0, xq[1]/10.0);
 }
 
index 8344a5f0096edcd8e2c3d0d05efb2d554f4d9da3..513e2c26e640beb57829f8ac1a58a92b8b4195da 100644 (file)
@@ -44,6 +44,8 @@
 #define LSPDT_LOW   1
 #define LSPDT_HIGH  2
 
+#define WO_E_BITS   8
+
 void quantise_init();
 float lpc_model_amplitudes(float Sn[], float w[], MODEL *model, int order,
                           int lsp,float ak[]);
@@ -77,7 +79,10 @@ void lspvq_quantise(float lsp[], float lsp_[], int order);
 void lspjnd_quantise(float lsp[], float lsp_[], int order);
 void lspdt_quantise(float lsps[], float lsps_[], float lsps__prev[], int mode);
 void lspjvm_quantise(float lsps[], float lsps_[], int order);
-void ge_quantise(float *x, float *xq);
+
+void quantise_WoE(MODEL *model, float *e, float xq[]);
+int  encode_WoE(MODEL *model, float e, float xq[]);
+void decode_WoE(MODEL *model, float *e, float xq[], int n1);
 
 int encode_energy(float e);
 float decode_energy(int index);
index dc60893041c2aa897c1f237c4dfcf0ec1b059ca4..8a05b7fc8d9e5319b6c3159179799e8558986ea7 100644 (file)
@@ -26,7 +26,7 @@
   along with this program; if not, see <http://www.gnu.org/licenses/>.
 */
 
-#define P      10      /* LP order                                     */
+#define P      12      /* LP order                                     */
 #define LSP_DELTA1 0.01 /* grid spacing for LSP root searches */
 #define NW     279     /* frame size in samples                        */
 #define        N       80      /* frame to frame shift                         */