bunch of changes to support separate enc/dec at 1400. Builds but I haven't tested yet
authordrowe67 <drowe67@01035d8c-6547-0410-b346-abe4f91aad63>
Fri, 18 Nov 2011 00:39:28 +0000 (00:39 +0000)
committerdrowe67 <drowe67@01035d8c-6547-0410-b346-abe4f91aad63>
Fri, 18 Nov 2011 00:39:28 +0000 (00:39 +0000)
git-svn-id: https://svn.code.sf.net/p/freetel/code@307 01035d8c-6547-0410-b346-abe4f91aad63

codec2-dev/octave/pllsp.m
codec2-dev/src/c2dec.c
codec2-dev/src/c2demo.c
codec2-dev/src/c2enc.c
codec2-dev/src/c2sim.c
codec2-dev/src/codec2.c
codec2-dev/src/codec2.h
codec2-dev/src/quantise.c
codec2-dev/src/quantise.h

index 7602fa3b3a0d15517e7789eaeaf30aba2402f125..15da6748c27e7f27d1e4b5ce8fb3a5c6590570db 100644 (file)
@@ -31,12 +31,12 @@ function pllsp(rawfile,
 
   figure(1);
   clf;
-  subplot(211);
+  %subplot(211);
   sp = s((start_f-2)*80:(end_f-2)*80);
   plot(sp);
 
-  subplot(212);
-  plot(lpc10_snr((start_f+1):end_f)-lsp_snr((start_f+1):end_f));
+  %subplot(212);
+  %plot(lpc10_snr((start_f+1):end_f)-lsp_snr((start_f+1):end_f));
 
   figure(2);
   plot((4000/pi)*lsp((start_f+1):end_f,:));
index b866d04d60e31fa40cd1b402c520895f3d1df7cf..bf3499e4a15c8bb24cf065541ed641fbf4d9caab 100644 (file)
 
 int main(int argc, char *argv[])
 {
-    void *codec2;
-    FILE *fin;
-    FILE *fout;
-    short buf[CODEC2_SAMPLES_PER_FRAME];
-    unsigned char  bits[BITS_SIZE];
+    int            mode;
+    void          *codec2;
+    FILE          *fin;
+    FILE          *fout;
+    short         *buf;
+    unsigned char *bits;
+    int            nsam, nbit;
 
     if (argc != 3) {
-       printf("usage: %s InputBitFile OutputRawSpeechFile\n", argv[0]);
+       printf("usage: %s 2500|1400 InputBitFile OutputRawSpeechFile\n", argv[0]);
+       printf("e.g    %s 1400 hts1a.c2 hts1a_1400.raw\n", argv[0]);
        exit(1);
     }
 
-    if (strcmp(argv[1], "-")  == 0) fin = stdin;
+    if (strcmp(argv[1],"1400") == 0)
+       mode = CODEC2_MODE_2500;
+    else if (strcmp(argv[1],"2500") == 0)
+       mode = CODEC2_MODE_1400;
+    else {
+       fprintf(stderr, "Error in mode: %s.  Must be 2500 or 1400\n", argv[1]);
+       exit(1);
+    }
+
+    if (strcmp(argv[2], "-")  == 0) fin = stdin;
     else if ( (fin = fopen(argv[1],"rb")) == NULL ) {
        fprintf(stderr, "Error opening input bit file: %s: %s.\n",
          argv[1], strerror(errno));
        exit(1);
     }
 
-    if (strcmp(argv[2], "-") == 0) fout = stdout;
+    if (strcmp(argv[3], "-") == 0) fout = stdout;
     else if ( (fout = fopen(argv[2],"wb")) == NULL ) {
        fprintf(stderr, "Error opening output speech file: %s: %s.\n",
          argv[2], strerror(errno));
        exit(1);
     }
 
-    codec2 = codec2_create();
+    codec2 = codec2_create(mode);
+    nsam = codec2_samples_per_frame(codec2);
+    nbit = codec2_bits_per_frame(codec2);
+    buf = (short*)malloc(nsam*sizeof(short));
+    bits = (char*)malloc(nbit*sizeof(char));
 
-    while(fread(bits, sizeof(char), BITS_SIZE, fin) == BITS_SIZE) {
+    while(fread(bits, sizeof(char), nbit, fin) == nbit) {
        codec2_decode(codec2, buf, bits);
-       fwrite(buf, sizeof(short), CODEC2_SAMPLES_PER_FRAME, fout);
+       fwrite(buf, sizeof(short), nsam, fout);
        //if this is in a pipeline, we probably don't want the usual
         //buffering to occur
         if (fout == stdout) fflush(stdout);
         if (fin == stdin) fflush(stdin);
           
- }
   }
 
     codec2_destroy(codec2);
 
+    free(buf);
+    free(bits);
     fclose(fin);
     fclose(fout);
 
index efa8d6449aa114a3892ac6fcf0f5e345517337b5..36be594862330638a3945f9e76023ccbd3b7b63a 100644 (file)
 
 int main(int argc, char *argv[])
 {
-    void *codec2;
-    FILE *fin;
-    FILE *fout;
-    short buf[CODEC2_SAMPLES_PER_FRAME];
-    unsigned char  bits[BITS_SIZE];
+    struct CODEC2 *codec2;
+    FILE          *fin;
+    FILE          *fout;
+    short         *buf;
+    unsigned char *bits;
+    int            nsam, nbit;
 
     if (argc != 3) {
        printf("usage: %s InputRawSpeechFile OutputRawSpeechFile\n", argv[0]);
@@ -68,15 +69,20 @@ int main(int argc, char *argv[])
     /* Note only one set of Codec 2 states is required for an encoder
        and decoder pair. */
 
-    codec2 = codec2_create();
+    codec2 = codec2_create(CODEC2_MODE_1400);
+    nsam = codec2_samples_per_frame(codec2);
+    buf = (short*)malloc(nsam*sizeof(short));
+    nbit = codec2_bits_per_frame(codec2);
+    bits = (unsigned char*)malloc(nbit*sizeof(char));
 
-    while(fread(buf, sizeof(short), CODEC2_SAMPLES_PER_FRAME, fin) == 
-         CODEC2_SAMPLES_PER_FRAME) {
+    while(fread(buf, sizeof(short), nsam, fin) == nsam) {
        codec2_encode(codec2, bits, buf);
        codec2_decode(codec2, buf, bits);
-       fwrite(buf, sizeof(short), CODEC2_SAMPLES_PER_FRAME, fout);
+       fwrite(buf, sizeof(short), nsam, fout);
     }
 
+    free(buf);
+    free(bits);
     codec2_destroy(codec2);
 
     fclose(fin);
index 4d1d019dfc19e6af8f96b3e02d8bf58f25e06c1d..5ca503f8e108e5f6c2e6722dda23e547decbf35b 100644 (file)
 
 int main(int argc, char *argv[])
 {
-    void *codec2;
-    FILE *fin;
-    FILE *fout;
-    short buf[CODEC2_SAMPLES_PER_FRAME];
-    unsigned char  bits[BITS_SIZE];
+    int            mode;
+    void          *codec2;
+    FILE          *fin;
+    FILE          *fout;
+    short         *buf;
+    unsigned char *bits;
+    int            nsam, nbit;
 
     if (argc != 3) {
-       printf("usage: %s InputRawspeechFile OutputBitFile\n", argv[0]);
+       printf("usage: %s 2500|1400 InputRawspeechFile OutputBitFile\n", argv[0]);
+       printf("e.g    %s 1400 ../raw/hts1a.raw hts1a.c2\n", argv[0]);
        exit(1);
     }
  
-    if (strcmp(argv[1], "-")  == 0) fin = stdin;
+    if (strcmp(argv[1],"1400") == 0)
+       mode = CODEC2_MODE_2500;
+    else if (strcmp(argv[1],"2500") == 0)
+       mode = CODEC2_MODE_1400;
+    else {
+       fprintf(stderr, "Error in mode: %s.  Must be 2500 or 1400\n", argv[1]);
+       exit(1);
+    }
+
+    if (strcmp(argv[2], "-")  == 0) fin = stdin;
     else if ( (fin = fopen(argv[1],"rb")) == NULL ) {
        fprintf(stderr, "Error opening input bit file: %s: %s.\n",
          argv[1], strerror(errno));
        exit(1);
     }
 
-    if (strcmp(argv[2], "-") == 0) fout = stdout;
+    if (strcmp(argv[3], "-") == 0) fout = stdout;
     else if ( (fout = fopen(argv[2],"wb")) == NULL ) {
        fprintf(stderr, "Error opening output speech file: %s: %s.\n",
          argv[2], strerror(errno));
        exit(1);
     }
 
-    codec2 = codec2_create();
+    codec2 = codec2_create(mode);
+    nsam = codec2_samples_per_frame(codec2);
+    nbit = codec2_bits_per_frame(codec2);
+    buf = (short*)malloc(nsam*sizeof(short));
+    bits = (char*)malloc(nbit*sizeof(char));
 
-    while(fread(buf, sizeof(short), CODEC2_SAMPLES_PER_FRAME, fin) ==
-         CODEC2_SAMPLES_PER_FRAME) {
+    while(fread(buf, sizeof(short), nsam, fin) == nsam) {
        codec2_encode(codec2, bits, buf);
-       fwrite(bits, sizeof(char), BITS_SIZE, fout);
+       fwrite(bits, sizeof(char), nbit, fout);
        //if this is in a pipeline, we probably don't want the usual
         //buffering to occur
         if (fout == stdout) fflush(stdout);
@@ -76,6 +91,8 @@ int main(int argc, char *argv[])
 
     codec2_destroy(codec2);
 
+    free(buf);
+    free(bits);
     fclose(fin);
     fclose(fout);
 
index e1ee1b3c31370fa79fb20722755c99bc4fb6073b..a6eed4ae10d0d5ddc36702b631077bc5ac6b61c0 100644 (file)
@@ -353,8 +353,8 @@ int main(int argc, char *argv[])
            /* various LSP quantisation schemes */
 
            if (lsp) {
-               encode_lsps(lsp_indexes, lsps, LPC_ORD);
-               decode_lsps(lsps_, lsp_indexes, LPC_ORD);
+               encode_lsps_scalar(lsp_indexes, lsps, LPC_ORD);
+               decode_lsps_scalar(lsps_, lsp_indexes, LPC_ORD);
                bw_expand_lsps(lsps_, LPC_ORD);
                lsp_to_lpc(lsps_, ak, LPC_ORD);
            }
index 4b669153232beaae206aedf5e0a9d649a939ba26..48c0f27f2ef7e921638ca330da526260edce183f 100644 (file)
 #include "interp.h"
 #include "postfilter.h"
 #include "codec2.h"
-
-typedef struct {
-    float  w[M];              /* time domain hamming window                */
-    COMP   W[FFT_ENC];        /* DFT of w[]                                */
-    float  Pn[2*N];           /* trapezoidal synthesis window              */
-    float  Sn[M];              /* input speech                              */
-    float  hpf_states[2];      /* high pass filter states                   */
-    void  *nlp;                /* pitch predictor states                    */
-    float  Sn_[2*N];          /* synthesised output speech                 */
-    float  ex_phase;           /* excitation model phase track              */
-    float  bg_est;             /* background noise estimate for post filter */
-    float  prev_Wo;            /* previous frame's pitch estimate           */
-    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               */
-} CODEC2;
+#include "lsp.h"
+
+struct CODEC2 {
+    int    mode;
+    float  w[M];               /* time domain hamming window                */
+    COMP   W[FFT_ENC];         /* DFT of w[]                                */
+    float  Pn[2*N];            /* trapezoidal synthesis window              */
+    float  Sn[M];               /* input speech                              */
+    float  hpf_states[2];       /* high pass filter states                   */
+    void  *nlp;                 /* pitch predictor states                    */
+    float  Sn_[2*N];           /* synthesised output speech                 */
+    float  ex_phase;            /* excitation model phase track              */
+    float  bg_est;              /* background noise estimate for post filter */
+    float  prev_Wo;             /* previous frame's pitch estimate           */
+    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               */
+};
 
 /*---------------------------------------------------------------------------*\
                                                        
@@ -65,8 +67,13 @@ typedef struct {
 
 \*---------------------------------------------------------------------------*/
 
-void analyse_one_frame(CODEC2 *c2, MODEL *model, short speech[]);
-void synthesise_one_frame(CODEC2 *c2, short speech[], MODEL *model,float ak[]);
+void analyse_one_frame(struct CODEC2 *c2, MODEL *model, short speech[]);
+void synthesise_one_frame(struct CODEC2 *c2, short speech[], MODEL *model,
+                         float ak[]);
+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_1400(struct CODEC2 *c2, unsigned char * bits, short speech[]);
+void codec2_decode_1400(struct CODEC2 *c2, short speech[], const unsigned char * bits);
 
 /*---------------------------------------------------------------------------*\
                                                        
@@ -88,15 +95,17 @@ void synthesise_one_frame(CODEC2 *c2, short speech[], MODEL *model,float ak[]);
 
 \*---------------------------------------------------------------------------*/
 
-void *codec2_create()
+struct CODEC2 *codec2_create(int mode)
 {
-    CODEC2 *c2;
-    int     i,l;
+    struct CODEC2 *c2;
+    int            i,l;
 
-    c2 = (CODEC2*)malloc(sizeof(CODEC2));
+    c2 = (struct CODEC2*)malloc(sizeof(struct CODEC2));
     if (c2 == NULL)
        return NULL;
-
+    
+    assert((mode == CODEC2_MODE_2500) || (mode == CODEC2_MODE_1400));
+    c2->mode = mode;
     for(i=0; i<M; i++)
        c2->Sn[i] = 1.0;
     c2->hpf_states[0] = c2->hpf_states[1] = 0.0;
@@ -116,7 +125,7 @@ void *codec2_create()
     c2->prev_model.voiced = 0;
 
     for(i=0; i<LPC_ORD; i++) {
-      c2->prev_lsps[i] = i*PI/(LPC_ORD+1);
+      c2->prev_lsps_[i] = i*PI/(LPC_ORD+1);
     }
     c2->prev_energy = 1;
 
@@ -126,12 +135,12 @@ void *codec2_create()
        return NULL;
     }
 
-    return (void*)c2;
+    return c2;
 }
 
 /*---------------------------------------------------------------------------*\
                                                        
-  FUNCTION....: codec2_create       
+  FUNCTION....: codec2_destroy      
   AUTHOR......: David Rowe                           
   DATE CREATED: 21/8/2010 
 
@@ -139,23 +148,81 @@ void *codec2_create()
 
 \*---------------------------------------------------------------------------*/
 
-void codec2_destroy(void *codec2_state)
+void codec2_destroy(struct CODEC2 *c2)
 {
-    CODEC2 *c2;
-    
-    assert(codec2_state != NULL);
-    c2 = (CODEC2*)codec2_state;
+    assert(c2 != NULL);
     nlp_destroy(c2->nlp);
-    free(codec2_state);
+    free(c2);
+}
+
+/*---------------------------------------------------------------------------*\
+                                                       
+  FUNCTION....: codec2_bits_per_frame     
+  AUTHOR......: David Rowe                           
+  DATE CREATED: Nov 14 2011
+
+  Returns the number of bits per frame.
+
+\*---------------------------------------------------------------------------*/
+
+int codec2_bits_per_frame(struct CODEC2 *c2) {
+    if (c2->mode == CODEC2_MODE_2500)
+       return 50;
+    if  (c2->mode == CODEC2_MODE_1400)
+       return 56;
+
+    return 0; /* shouldn't get here */
 }
 
+
 /*---------------------------------------------------------------------------*\
                                                        
-  FUNCTION....: codec2_encode       
+  FUNCTION....: codec2_samples_per_frame     
+  AUTHOR......: David Rowe                           
+  DATE CREATED: Nov 14 2011
+
+  Returns the number of bits per frame.
+
+\*---------------------------------------------------------------------------*/
+
+int codec2_samples_per_frame(struct CODEC2 *c2) {
+    if (c2->mode == CODEC2_MODE_2500)
+       return 160;
+    if  (c2->mode == CODEC2_MODE_1400)
+       return 320;
+
+    return 0; /* shouldnt get here */
+}
+
+void codec2_encode(struct CODEC2 *c2, unsigned char *bits, short speech[])
+{
+    assert(c2 != NULL);
+    assert((c2->mode == CODEC2_MODE_2500) || (c2->mode == CODEC2_MODE_1400));
+
+    if (c2->mode == CODEC2_MODE_2500)
+       codec2_encode_2500(c2, bits, speech);
+    else
+       codec2_encode_1400(c2, bits, speech);
+}
+
+void codec2_decode(struct CODEC2 *c2, short speech[], const unsigned char *bits)
+{
+    assert(c2 != NULL);
+    assert((c2->mode == CODEC2_MODE_2500) || (c2->mode == CODEC2_MODE_1400));
+
+    if (c2->mode == CODEC2_MODE_2500)
+       codec2_decode_2500(c2, speech, bits);
+    else
+       codec2_decode_1400(c2, speech, bits);
+}
+
+/*---------------------------------------------------------------------------*\
+                                                       
+  FUNCTION....: codec2_encode_2500          
   AUTHOR......: David Rowe                           
   DATE CREATED: 21/8/2010 
 
-  Encodes 160 speech samples (20ms of speech) into 51 bits.  
+  Encodes 160 speech samples (20ms of speech) into 50 bits.  
 
   The codec2 algorithm actually operates internally on 10ms (80
   sample) frames, so we run the encoding algorithm twice.  On the
@@ -167,27 +234,29 @@ void codec2_destroy(void *codec2_state)
     Parameter                      bits/frame
     --------------------------------------
     Harmonic magnitudes (LSPs)     36
-    Low frequency LPC correction    1
     Energy                          5
     Wo (fundamental frequnecy)      7
     Voicing (10ms update)           2
-    TOTAL                          51
+    TOTAL                          50
  
 \*---------------------------------------------------------------------------*/
 
-void codec2_encode(void *codec2_state, unsigned char * bits, short speech[])
+void codec2_encode_2500(struct CODEC2 *c2, unsigned char * bits, short speech[])
 {
-    CODEC2 *c2;
     MODEL   model;
     int     voiced1, voiced2;
+    float   lsps[LPC_ORD];
+    float   ak[LPC_ORD+1];
+    float   e;
     int     lsp_indexes[LPC_ORD];
     int     energy_index;
     int     Wo_index;
     int     i;
     unsigned int nbit = 0;
 
-    assert(codec2_state != NULL);
-    c2 = (CODEC2*)codec2_state;
+    assert(c2 != NULL);
+
+    memset(bits, '\0', ((codec2_bits_per_frame(c2) + 7) / 8));
 
     /* first 10ms analysis frame - we just want voicing */
 
@@ -200,43 +269,42 @@ void codec2_encode(void *codec2_state, unsigned char * bits, short speech[])
     voiced2 = model.voiced;
     
     Wo_index = encode_Wo(model.Wo);
-    encode_amplitudes(lsp_indexes, 
-                     &energy_index,
-                     &model, 
-                      c2->Sn, 
-                      c2->w);   
-    memset(bits, '\0', ((CODEC2_BITS_PER_FRAME + 7) / 8));
+
+    e = speech_to_uq_lsps(lsps, ak, c2->Sn, c2->w, LPC_ORD);
+    encode_lsps_scalar(lsp_indexes, lsps, LPC_ORD);
+    energy_index = encode_energy(e);
+
     pack(bits, &nbit, Wo_index, WO_BITS);
-    for(i=0; i<LPC_ORD; i++) {
+    for(i=0; i<LSP_SCALAR_INDEXES; i++) {
        pack(bits, &nbit, lsp_indexes[i], lsp_bits(i));
     }
     pack(bits, &nbit, energy_index, E_BITS);
     pack(bits, &nbit, voiced1, 1);
     pack(bits, &nbit, voiced2, 1);
     
-    assert(nbit == CODEC2_BITS_PER_FRAME);
+    assert(nbit == codec2_bits_per_frame(c2));
 }
 
+
 /*---------------------------------------------------------------------------*\
                                                        
-  FUNCTION....: codec2_decode       
+  FUNCTION....: codec2_decode_2500          
   AUTHOR......: David Rowe                           
   DATE CREATED: 21/8/2010 
 
-  Decodes frames of 51 bits into 160 samples (20ms) of speech.
+  Decodes frames of 50 bits into 160 samples (20ms) of speech.
 
 \*---------------------------------------------------------------------------*/
 
-void codec2_decode(void *codec2_state, short speech[],
-                   const unsigned char * bits)
+void codec2_decode_2500(struct CODEC2 *c2, short speech[], const unsigned char * bits)
 {
-    CODEC2 *c2;
     MODEL   model;
     int     voiced1, voiced2;
     int     lsp_indexes[LPC_ORD];
-    float   lsps[LPC_ORD];
+    float   lsps_[LPC_ORD];
     int     energy_index;
     float   energy;
+    float   snr;
     int     Wo_index;
     float   ak[LPC_ORD+1];
     float   ak_interp[LPC_ORD+1];
@@ -244,44 +312,224 @@ void codec2_decode(void *codec2_state, short speech[],
     unsigned int nbit = 0;
     MODEL   model_interp;
 
-    assert(codec2_state != NULL);
-    c2 = (CODEC2*)codec2_state;
+    assert(c2 != NULL);
 
     /* unpack bit stream to integer codes */
 
     Wo_index = unpack(bits, &nbit, WO_BITS);
-    for(i=0; i<LPC_ORD; i++) {
+    for(i=0; i<LSP_SCALAR_INDEXES; i++) {
        lsp_indexes[i] = unpack(bits, &nbit, lsp_bits(i));
     }
     energy_index = unpack(bits, &nbit, E_BITS);
     voiced1 = unpack(bits, &nbit, 1);
     voiced2 = unpack(bits, &nbit, 1);
-    assert(nbit == CODEC2_BITS_PER_FRAME);
+    assert(nbit == codec2_bits_per_frame(c2));
 
     /* decode integer codes to model parameters */
 
     model.Wo = decode_Wo(Wo_index);
     model.L = PI/model.Wo;
     memset(&model.A, 0, (model.L+1)*sizeof(model.A[0]));
-    decode_amplitudes(&model, 
-                     ak,
-                     lsp_indexes,
-                     energy_index,
-                     lsps,
-                     &energy);
+
+    /* decode even frame LSPs and model amplitudes */
+
+    decode_lsps_scalar(lsps_, lsp_indexes, LPC_ORD);
+    bw_expand_lsps(lsps_, LPC_ORD);
+    lsp_to_lpc(lsps_, ak, LPC_ORD);
+    energy = decode_energy(energy_index);
+    aks_to_M2(ak, LPC_ORD, &model, energy, &snr, 1); 
+    apply_lpc_correction(&model);
+
+    /* interpolate odd frame 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 middle frame's model parameters for adjacent frames */
+    interpolate_lsp(&model_interp, &c2->prev_model, &model,
+                   c2->prev_lsps_, c2->prev_energy, lsps_, energy, ak_interp);
+    apply_lpc_correction(&model_interp);
+
+    /* synthesise two 10ms frames */
+
+    synthesise_one_frame(c2, speech, &model_interp, ak_interp);
+    synthesise_one_frame(c2, &speech[N], &model, ak);
+
+    /* 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_1400          
+  AUTHOR......: David Rowe                           
+  DATE CREATED: Nov 14 2011 
+
+  Encodes 320 speech samples (50ms 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: full quantisation of LSPs and Wo
+  frame 2: just send voicing bit
+  frame 3: delta-time quantisation of LSPs and Wo
+
+  The bit allocation is:
+
+    Parameter                      frame 2  frame 4   Total
+    -------------------------------------------------------
+    Harmonic magnitudes (LSPs)     25        7        32
+    Energy                          5        5        10
+    Wo (fundamental frequnecy)      7        3        10
+    Voicing (10ms update)           2        2         4
+    TOTAL                          39       17        56
+\*---------------------------------------------------------------------------*/
+
+void codec2_encode_1400(struct CODEC2 *c2, unsigned char * bits, short speech[])
+{
+    MODEL   model;
+    float   lsps[LPC_ORD], prev_lsps_[LPC_ORD];
+    float   ak[LPC_ORD+1];
+    float   e;
+    int     voiced1, voiced2, voiced3, voiced4;
+    int     lsp_indexes[LPC_ORD];
+    int     energy_index;
+    int     Wo_index, delta_Wo_index;
+    int     i;
+    unsigned int nbit = 0;
+    float   prev_Wo;
+
+    assert(c2 != NULL);
+
+    memset(bits, '\0', codec2_bits_per_frame(c2)/8);
+
+    /* frame 1: - we just want voicing -------------------------------- */
+
+    analyse_one_frame(c2, &model, speech);
+    voiced1 = model.voiced;
+
+    /* frame 2: - full LSP and Wo ------------------------------------- */
+
+    analyse_one_frame(c2, &model, &speech[N]);
+    voiced2 = model.voiced;
+    
+    Wo_index = encode_Wo(model.Wo);
+
+    e = speech_to_uq_lsps(lsps, ak, c2->Sn, c2->w, LPC_ORD);
+    encode_lsps_diff_freq_vq(lsp_indexes, lsps, LPC_ORD);
+    energy_index = encode_energy(e);
+
+    pack(bits, &nbit, Wo_index, WO_BITS);
+    for(i=0; i<LSP_DIFF_FREQ_INDEXES; i++) {
+       pack(bits, &nbit, lsp_indexes[i], lspd_bits(i));
+    }
+    pack(bits, &nbit, energy_index, E_BITS);
+    pack(bits, &nbit, voiced1, 1);
+    pack(bits, &nbit, voiced2, 1);
+
+    /* decode LSPs and Wo for use in frame 4 */
+
+    decode_lsps_diff_freq_vq(prev_lsps_, lsp_indexes, LPC_ORD);
+    prev_Wo = decode_Wo(Wo_index);
+
+    /* frame 3: - we just want voicing --------------------------------- */
+
+    analyse_one_frame(c2, &model, &speech[2*N]);
+    voiced3 = model.voiced;
+
+    /* frame 4: - delta-time and delta Wo -----------------------------  */
+
+    analyse_one_frame(c2, &model, &speech[3*N]);
+    voiced4 = model.voiced;
+    
+    delta_Wo_index =  encode_Wo_dt(model.Wo, prev_Wo);
+  
+    e = speech_to_uq_lsps(lsps, ak, c2->Sn, c2->w, LPC_ORD);
+    encode_lsps_diff_time_vq(lsp_indexes, lsps, prev_lsps_, LPC_ORD);
+    energy_index = encode_energy(e);
+
+    pack(bits, &nbit, delta_Wo_index, WO_DT_BITS);
+    pack(bits, &nbit, *lsp_indexes, LSP_DIFF_TIME_BITS);
+    pack(bits, &nbit, energy_index, E_BITS);
+    pack(bits, &nbit, voiced3, 1);
+    pack(bits, &nbit, voiced4, 1);
+    
+    assert(nbit == codec2_bits_per_frame(c2));
+}
+
+
+/*---------------------------------------------------------------------------*\
+                                                       
+  FUNCTION....: codec2_decode_1400          
+  AUTHOR......: David Rowe                           
+  DATE CREATED: 16 Nov 2011
+
+  Decodes frames of 56 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     energy_index;
+    float   energy;
+    float   snr;
+    int     Wo_index, delta_Wo_index;
+    float   ak[LPC_ORD+1];
+    float   ak_interp[LPC_ORD+1];
+    int     i;
+    unsigned int nbit = 0;
+    MODEL   model_interp;
+
+    assert(c2 != NULL);
+
+    /* unpack frame 1 & 2 bit stream to integer codes */
+
+    Wo_index = unpack(bits, &nbit, WO_BITS);
+    for(i=0; i<LSP_DIFF_FREQ_INDEXES; i++) {
+       lsp_indexes[i] = unpack(bits, &nbit, lspd_bits(i));
+    }
+    energy_index = unpack(bits, &nbit, E_BITS);
+    voiced1 = unpack(bits, &nbit, 1);
+    voiced2 = unpack(bits, &nbit, 1);
+    /* decode integer codes to model parameters */
+
+    model.Wo = decode_Wo(Wo_index);
+    model.L = PI/model.Wo;
+    memset(&model.A, 0, (model.L+1)*sizeof(model.A[0]));
+
+    /* decode frame 2 LSPs and model amplitudes */
+
+    decode_lsps_diff_freq_vq(lsps_, lsp_indexes, LPC_ORD);
+    bw_expand_lsps(lsps_, LPC_ORD);
+    lsp_to_lpc(lsps_, ak, LPC_ORD);
+    energy = decode_energy(energy_index);
+    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);
+                   c2->prev_lsps_, c2->prev_energy, lsps_, energy, ak_interp);
     apply_lpc_correction(&model_interp);
 
-    /* synthesis two 10ms frames */
+    /* synthesise frame 1 and frame 2 10ms frames */
 
     synthesise_one_frame(c2, speech, &model_interp, ak_interp);
     synthesise_one_frame(c2, &speech[N], &model, ak);
@@ -289,10 +537,54 @@ void codec2_decode(void *codec2_state, short speech[],
     /* update memories (decode states) for next time */
 
     memcpy(&c2->prev_model, &model, sizeof(MODEL));
-    memcpy(c2->prev_lsps, lsps, sizeof(lsps));
+    memcpy(c2->prev_lsps_, lsps_, sizeof(lsps_));
     c2->prev_energy = energy;
+
+    /*--------------------------------------------------------------------*/
+
+    /* unpack frame 3 & 4 bit stream to integer codes */
+
+    delta_Wo_index = unpack(bits, &nbit, WO_DT_BITS);
+    *lsp_indexes = unpack(bits, &nbit, LSP_DIFF_TIME_BITS);
+    energy_index = unpack(bits, &nbit, E_BITS);
+    voiced3 = unpack(bits, &nbit, 1);
+    voiced4 = unpack(bits, &nbit, 1);
+    assert(nbit == codec2_bits_per_frame(c2));
+
+    /* decode frame 4 LSPs and model amplitudes */
+
+    decode_lsps_diff_time_vq(lsps_, lsp_indexes, c2->prev_lsps_, LPC_ORD);
+    bw_expand_lsps(lsps_, LPC_ORD);
+    lsp_to_lpc(lsps_, ak, LPC_ORD);
+    energy = decode_energy(energy_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);
+    apply_lpc_correction(&model_interp);
+
+    /* synthesise frame 3 and frame 4 10ms frames */
+
+    synthesise_one_frame(c2, &speech[2*N], &model_interp, ak_interp);
+    synthesise_one_frame(c2, &speech[3*N], &model, ak);
+
+    /* 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....: synthesise_one_frame()      
@@ -303,7 +595,7 @@ void codec2_decode(void *codec2_state, short speech[],
 
 \*---------------------------------------------------------------------------*/
 
-void synthesise_one_frame(CODEC2 *c2, short speech[], MODEL *model, float ak[])
+void synthesise_one_frame(struct CODEC2 *c2, short speech[], MODEL *model, float ak[])
 {
     int     i;
 
@@ -333,7 +625,7 @@ void synthesise_one_frame(CODEC2 *c2, short speech[], MODEL *model, float ak[])
  
 \*---------------------------------------------------------------------------*/
 
-void analyse_one_frame(CODEC2 *c2, MODEL *model, short speech[])
+void analyse_one_frame(struct CODEC2 *c2, MODEL *model, short speech[])
 {
     COMP    Sw[FFT_ENC];
     COMP    Sw_[FFT_ENC];
index 946dedca5ef24349d63fbd00d846195d4bc6e93f..277b8e7a50a81535b963d6db2c324ebbb56f1df3 100644 (file)
 #ifndef __CODEC2__
 #define  __CODEC2__
 
-#define CODEC2_SAMPLES_PER_FRAME 160
-#define CODEC2_BITS_PER_FRAME     50
-
-void *codec2_create();
-void codec2_destroy(void *codec2_state);
-void codec2_encode(void *codec2_state, unsigned char * bits, short speech_in[]);
-void codec2_decode(void *codec2_state, short speech_out[],
-      const unsigned char * bits);
+#define CODEC2_MODE_2500 0
+#define CODEC2_MODE_1400 1
+
+struct CODEC2;
+
+struct CODEC2 *codec2_create(int mode);
+void codec2_destroy(struct CODEC2 *codec2_state);
+void codec2_encode(struct CODEC2 *codec2_state, unsigned char * bits, short speech_in[]);
+void codec2_decode(struct CODEC2 *codec2_state, short speech_out[], const unsigned char *bits);
+int  codec2_samples_per_frame(struct CODEC2 *codec2_state);
+int  codec2_bits_per_frame(struct CODEC2 *codec2_state);
 
 #endif
index b3da2a5932bb0e42e88271a5a0681f257879c579..551a7dec0c403f51594e1f252d1aa10e58aa23ba 100644 (file)
@@ -59,6 +59,10 @@ int lsp_bits(int i) {
     return lsp_cb[i].log2m;
 }
 
+int lspd_bits(int i) {
+    return lsp_cbd[i].log2m;
+}
+
 /*---------------------------------------------------------------------------*\
 
   quantise_init
@@ -130,7 +134,7 @@ void lspd_quantise(
   int   order
 ) 
 {
-    int   i,k,m,ncb, nlsp, index;
+    int   i,k,m,index;
     float lsp_hz[LPC_MAX];
     float lsp__hz[LPC_MAX];
     float dlsp[LPC_MAX];
@@ -779,16 +783,16 @@ float speech_to_uq_lsps(float lsp[],
 
 /*---------------------------------------------------------------------------*\
                                                        
-  FUNCTION....: encode_lsps()       
+  FUNCTION....: encode_lsps_scalar()        
   AUTHOR......: David Rowe                           
   DATE CREATED: 22/8/2010 
 
-  From a vector of unquantised (floating point) LSPs finds the quantised
-  LSP indexes.
+  Thirty-six bit sclar LSP quantiser. From a vector of unquantised
+  (floating point) LSPs finds the quantised LSP indexes.
 
 \*---------------------------------------------------------------------------*/
 
-void encode_lsps(int indexes[], float lsp[], int order)
+void encode_lsps_scalar(int indexes[], float lsp[], int order)
 {
     int    i,k,m;
     float  wt[1];
@@ -815,7 +819,7 @@ void encode_lsps(int indexes[], float lsp[], int order)
 
 /*---------------------------------------------------------------------------*\
                                                        
-  FUNCTION....: decode_lsps()       
+  FUNCTION....: decode_lsps_scalar()        
   AUTHOR......: David Rowe                           
   DATE CREATED: 22/8/2010 
 
@@ -824,7 +828,7 @@ void encode_lsps(int indexes[], float lsp[], int order)
 
 \*---------------------------------------------------------------------------*/
 
-void decode_lsps(float lsp[], int indexes[], int order)
+void decode_lsps_scalar(float lsp[], int indexes[], int order)
 {
     int    i,k;
     float  lsp_hz[LPC_MAX];
@@ -840,6 +844,190 @@ void decode_lsps(float lsp[], int indexes[], int order)
 
     for(i=0; i<order; i++)
        lsp[i] = (PI/4000.0)*lsp_hz[i];
+}
+
+
+/*---------------------------------------------------------------------------*\
+                                                       
+  FUNCTION....: encode_lsps_diff_freq_vq()          
+  AUTHOR......: David Rowe                           
+  DATE CREATED: 15 November 2011
+
+  Twenty-five bit LSP quantiser.  LSPs 1-4 are quantised with scalar
+  LSP differences (in frequency, i.e difference from the previous
+  LSP).  LSPs 5-10 are quantised with a VQ trained generated using
+  vqtrainjnd.c
+
+\*---------------------------------------------------------------------------*/
+
+void encode_lsps_diff_freq_vq(int indexes[], float lsp[], int order)
+{
+    int    i,k,m;
+    float  lsp_hz[LPC_MAX];
+    float lsp__hz[LPC_MAX];
+    float dlsp[LPC_MAX];
+    float dlsp_[LPC_MAX];
+    float wt[LPC_MAX];
+    const float * cb;
+    float se;
+
+    for(i=0; i<LPC_ORD; i++) {
+       wt[i] = 1.0;
+    }
+
+    /* convert from radians to Hz so we can use human readable
+       frequencies */
+
+    for(i=0; i<order; i++)
+       lsp_hz[i] = (4000.0/PI)*lsp[i];
+    
+    /* scalar quantisers for LSP differences 1..4 */
+
+    wt[0] = 1.0;
+    for(i=0; i<4; i++) {
+       if (i) 
+           dlsp[i] = lsp_hz[i] - lsp__hz[i-1];     
+       else
+           dlsp[0] = lsp_hz[0];
+
+       k = lsp_cbd[i].k;
+       m = lsp_cbd[i].m;
+       cb = lsp_cbd[i].cb;
+       indexes[i] = quantise(cb, &dlsp[i], wt, k, m, &se);
+       dlsp_[i] = cb[indexes[i]*k];
+
+       if (i) 
+           lsp__hz[i] = lsp__hz[i-1] + dlsp_[i];
+       else
+           lsp__hz[0] = dlsp_[0];
+    }
+
+    /* VQ LSPs 5,6,7,8,9,10 */
+
+    k = lsp_cbjnd[4].k;
+    m = lsp_cbjnd[4].m;
+    cb = lsp_cbjnd[4].cb;
+    indexes[4] = quantise(cb, &lsp_hz[4], &wt[4], k, m, &se);
+}
+
+
+/*---------------------------------------------------------------------------*\
+                                                       
+  FUNCTION....: decode_lsps_diff_freq_vq()          
+  AUTHOR......: David Rowe                           
+  DATE CREATED: 15 Nov 2011
+
+  From a vector of quantised LSP indexes, returns the quantised
+  (floating point) LSPs.
+
+\*---------------------------------------------------------------------------*/
+
+void decode_lsps_diff_freq_vq(float lsp_[], int indexes[], int order)
+{
+    int    i,k,m;
+    float  dlsp_[LPC_MAX];
+    float  lsp__hz[LPC_MAX];
+    const float * cb;
+
+    /* scalar LSP differences */
+
+    for(i=0; i<4; i++) {
+       cb = lsp_cbd[i].cb;
+       dlsp_[i] = cb[indexes[i]];
+       if (i) 
+           lsp__hz[i] = lsp__hz[i-1] + dlsp_[i];
+       else
+           lsp__hz[0] = dlsp_[0];
+    }
+
+    /* VQ */
+
+    k = lsp_cbjnd[4].k;
+    m = lsp_cbjnd[4].m;
+    cb = lsp_cbjnd[4].cb;
+    for(i=4; i<order; i++)
+       lsp__hz[i] = cb[indexes[4]*k+i-4];
+
+    /* convert back to radians */
+
+    for(i=0; i<order; i++)
+       lsp_[i] = (PI/4000.0)*lsp__hz[i];
+}
+
+
+/*---------------------------------------------------------------------------*\
+                                                       
+  FUNCTION....: encode_lsps_diff_time_vq()          
+  AUTHOR......: David Rowe                           
+  DATE CREATED: 15 November 2011
+
+  Seven bit LSP quantiser.  The difference in LSPs 1-4 from a previous
+  frame are quantised with a hand constructed Just Noticable Differnce
+  (JND) VQ.  LSPs 5-10 are just repeated from the last frame.
+
+\*---------------------------------------------------------------------------*/
+
+void encode_lsps_diff_time_vq(int indexes[], 
+                             float lsps[], 
+                             float lsps__prev[], 
+                             int order)
+{
+    int    i,k,m;
+    float  lsps_dt[LPC_ORD];
+    float  wt[LPC_MAX];
+    const  float * cb;
+    float  se;
+
+    for(i=0; i<LPC_ORD; i++) {
+       wt[i] = 1.0;
+    }
+
+    /* Determine difference in time and convert from radians to Hz so
+       we can use human readable frequencies */
+
+    for(i=0; i<LPC_ORD; i++) {
+       lsps_dt[i] = (4000/PI)*(lsps[i] - lsps__prev[i]);
+    }
+    
+    /* VQ LSP dTs 1 to 4 */
+
+    k = lsp_cbdt[0].k;
+    m = lsp_cbdt[0].m;
+    cb = lsp_cbdt[0].cb;
+    *indexes = quantise(cb, lsps_dt, wt, k, m, &se);
+}
+
+
+/*---------------------------------------------------------------------------*\
+                                                       
+  FUNCTION....: decode_lsps_diff_time_vq()          
+  AUTHOR......: David Rowe                           
+  DATE CREATED: 15 Nov 2011
+
+  From a quantised LSP indexes, returns the quantised
+  (floating point) LSPs.
+
+\*---------------------------------------------------------------------------*/
+
+void decode_lsps_diff_time_vq(
+                             float lsps_[], 
+                             int indexes[], 
+                             float lsps__prev[],
+                             int order)
+{
+    int    i,k,m;
+    const  float * cb;
+
+    for(i=0; i<order; i++)
+       lsps_[i] = lsps__prev[i];
+
+    k = lsp_cbdt[0].k;
+    m = lsp_cbdt[0].m;
+    cb = lsp_cbdt[0].cb;
+
+    for(i=0; i<4; i++) {
+       lsps_[i] += (PI/4000.0)*cb[*indexes*k + i];
+    }
 
 }
 
@@ -1021,34 +1209,6 @@ float decode_energy(int index)
     return e;
 }
 
-/*---------------------------------------------------------------------------*\
-                                                       
-  FUNCTION....: encode_amplitudes()         
-  AUTHOR......: David Rowe                           
-  DATE CREATED: 22/8/2010 
-
-  Time domain LPC is used model the amplitudes which are then
-  converted to LSPs and quantised.  So we don't actually encode the
-  amplitudes directly, rather we derive an equivalent representation
-  from the time domain speech.
-
-\*---------------------------------------------------------------------------*/
-
-void encode_amplitudes(int    lsp_indexes[], 
-                      int   *energy_index,
-                      MODEL *model, 
-                      float  Sn[], 
-                      float  w[])
-{
-    float lsps[LPC_ORD];
-    float ak[LPC_ORD+1];
-    float e;
-
-    e = speech_to_uq_lsps(lsps, ak, Sn, w, LPC_ORD);
-    encode_lsps(lsp_indexes, lsps, LPC_ORD);
-    *energy_index = encode_energy(e);
-}
-
 /*---------------------------------------------------------------------------*\
                                                        
   FUNCTION....: decode_amplitudes()         
@@ -1070,7 +1230,7 @@ float decode_amplitudes(MODEL *model,
 {
     float snr;
 
-    decode_lsps(lsps, lsp_indexes, LPC_ORD);
+    decode_lsps_scalar(lsps, lsp_indexes, LPC_ORD);
     bw_expand_lsps(lsps, LPC_ORD);
     lsp_to_lpc(lsps, ak, LPC_ORD);
     *e = decode_energy(energy_index);
index 259ea4b8112992be50f59e1c72d05a3857f68653..fc10c8740bf7d7a6af5fe4b361716401176143b9 100644 (file)
 #define E_MIN_DB   -10.0
 #define E_MAX_DB    40.0
 
+#define LSP_SCALAR_INDEXES    10
+#define LSP_DIFF_FREQ_INDEXES  5
+#define LSP_DIFF_TIME_BITS     7
+
 #define LSPDT_ALL   0
 #define LSPDT_LOW   1
 #define LSPDT_HIGH  2
@@ -47,11 +51,22 @@ void aks_to_M2(float ak[], int order, MODEL *model, float E, float *snr,
 
 int   encode_Wo(float Wo);
 float decode_Wo(int index);
-int encode_Wo_dt(float Wo, float prev_Wo);
+int   encode_Wo_dt(float Wo, float prev_Wo);
 float decode_Wo_dt(int index, float prev_Wo);
+void  encode_lsps_scalar(int indexes[], float lsp[], int order);
+void  decode_lsps_scalar(float lsp[], int indexes[], int order);
+void  encode_lsps_diff_freq_vq(int indexes[], float lsp[], int order);
+void  decode_lsps_diff_freq_vq(float lsp_[], int indexes[], int order);
+void encode_lsps_diff_time_vq(int indexes[], 
+                             float lsp[], 
+                             float lsp__prev[], 
+                             int order);
+void decode_lsps_diff_time_vq(
+                             float lsp_[], 
+                             int indexes[], 
+                             float lsp__prev[],
+                             int order);
 
-void encode_lsps(int indexes[], float lsp[], int order);
-void decode_lsps(float lsp[], int indexes[], int order);
 void lspd_quantise(float lsp[], float lsp_[], int order);
 void lspvq_quantise(float lsp[], float lsp_[], int order); 
 void lspjnd_quantise(float lsp[], float lsp_[], int order);
@@ -60,23 +75,11 @@ void lspdt_quantise(float lsps[], float lsps_[], float lsps__prev[], int mode);
 int encode_energy(float e);
 float decode_energy(int index);
 
-void encode_amplitudes(int    lsp_indexes[], 
-                      int   *energy_index,
-                      MODEL *model, 
-                      float  Sn[], 
-                      float  w[]);
-
-float decode_amplitudes(MODEL *model,
-                       float  ak[],
-                       int lsp_indexes[],
-                       int energy_index,
-                       float  lsps[],
-                       float *e);
-
 void pack(unsigned char * bits, unsigned int *nbit, int index, unsigned int index_bits);
 int  unpack(const unsigned char * bits, unsigned int *nbit, unsigned int index_bits);
 
 int lsp_bits(int i);
+int lspd_bits(int i);
 
 void apply_lpc_correction(MODEL *model);
 float speech_to_uq_lsps(float lsp[],
@@ -87,6 +90,5 @@ float speech_to_uq_lsps(float lsp[],
                        );
 void bw_expand_lsps(float lsp[], int order);
 void locate_lsps_jnd_steps(float lsp[], int order);
-void decode_lsps(float lsp[], int indexes[], int order);
 
 #endif