added 1600 bit/s Codec 2 mode with scaler Wo & E quantisers
authordrowe67 <drowe67@01035d8c-6547-0410-b346-abe4f91aad63>
Thu, 28 Feb 2013 07:57:53 +0000 (07:57 +0000)
committerdrowe67 <drowe67@01035d8c-6547-0410-b346-abe4f91aad63>
Thu, 28 Feb 2013 07:57:53 +0000 (07:57 +0000)
git-svn-id: https://svn.code.sf.net/p/freetel/code@1180 01035d8c-6547-0410-b346-abe4f91aad63

codec2-dev/src/c2dec.c
codec2-dev/src/c2enc.c
codec2-dev/src/codec2.c
codec2-dev/src/codec2.h
codec2-dev/src/fdmdv_demod.c

index 8b2f2eb67a047f2da756d820cbb8447fe1e50419..c1e1f467be651cab5c5cf85ac43cd1d9dd63e0ea 100644 (file)
@@ -52,10 +52,10 @@ int main(int argc, char *argv[])
     float          ber, r, burst_length, burst_period, burst_timer;
 
     if (argc < 4) {
-       printf("basic usage.................: c2dec 3200|2400|1400|1200 InputBitFile OutputRawSpeechFile\n");
-       printf("uniform errors usage........: c2dec 3200|2400|1400|1200 InputBitFile OutputRawSpeechFile uniformBER startBit endBit\n");
-       printf("uniform error on range usage: c2dec 3200|2400|1400|1200 InputBitFile OutputRawSpeechFile uniformBER\n");
-       printf("two state fading usage......: c2dec 3200|2400|1400|1200 InputBitFile OutputRawSpeechFile burstLength burstPeriod\n");
+       printf("basic usage.................: c2dec 3200|2400|1600|1400|1200 InputBitFile OutputRawSpeechFile\n");
+       printf("uniform errors usage........: c2dec 3200|2400|1600|1400|1200 InputBitFile OutputRawSpeechFile uniformBER startBit endBit\n");
+       printf("uniform error on range usage: c2dec 3200|2400|1600|1400|1200 InputBitFile OutputRawSpeechFile uniformBER\n");
+       printf("two state fading usage......: c2dec 3200|2400|1600|1400|1200 InputBitFile OutputRawSpeechFile burstLength burstPeriod\n");
        printf("e.g    c2dec 1400 hts1a.c2 hts1a_1400.raw\n");
        printf("e.g    c2dec 1400 hts1a.c2 hts1a_1400.raw 0.9\n");
        printf("e.g    c2dec 1400 hts1a.c2 hts1a_1400.raw 0.99 0.9\n");
@@ -66,12 +66,14 @@ int main(int argc, char *argv[])
        mode = CODEC2_MODE_3200;
     else if (strcmp(argv[1],"2400") == 0)
        mode = CODEC2_MODE_2400;
+    else if (strcmp(argv[1],"1600") == 0)
+       mode = CODEC2_MODE_1600;
     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 4800, 3200, 2400, 1400 or 1200\n", argv[1]);
+       fprintf(stderr, "Error in mode: %s.  Must be 3200, 2400, 1600, 1400 or 1200\n", argv[1]);
        exit(1);
     }
     bit_rate = atoi(argv[1]);
index d171c39a67b7fa06cfe567f2b003579304a2560d..88c2086442180a36320723b0ec35686c5ff84acf 100644 (file)
@@ -44,7 +44,7 @@ int main(int argc, char *argv[])
     int            nsam, nbit, nbyte;
  
     if (argc != 4) {
-       printf("usage: c2enc 3200|2400|1400|1200 InputRawspeechFile OutputBitFile\n");
+       printf("usage: c2enc 3200|2400|1600|1400|1200 InputRawspeechFile OutputBitFile\n");
        printf("e.g    c2enc 1400 ../raw/hts1a.raw hts1a.c2\n");
        exit(1);
     }
@@ -53,12 +53,14 @@ int main(int argc, char *argv[])
        mode = CODEC2_MODE_3200;
     else if (strcmp(argv[1],"2400") == 0)
        mode = CODEC2_MODE_2400;
+    else if (strcmp(argv[1],"1600") == 0)
+       mode = CODEC2_MODE_1600;
     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 3200, 2400, 1400 or 1200\n", argv[1]);
+       fprintf(stderr, "Error in mode: %s.  Must be 3200, 2400, 1600, 1400 or 1200\n", argv[1]);
        exit(1);
     }
 
index 7bf96b9f6a41e93e1368fa05dcb1a3e40a52cb6f..9a64c7e4c631d7866de2d6a804f029fe4082ca8a 100644 (file)
@@ -58,6 +58,8 @@ void codec2_encode_3200(struct CODEC2 *c2, unsigned char * bits, short speech[])
 void codec2_decode_3200(struct CODEC2 *c2, short speech[], const unsigned char * bits);
 void codec2_encode_2400(struct CODEC2 *c2, unsigned char * bits, short speech[]);
 void codec2_decode_2400(struct CODEC2 *c2, short speech[], const unsigned char * bits);
+void codec2_encode_1600(struct CODEC2 *c2, unsigned char * bits, short speech[]);
+void codec2_decode_1600(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[]);
@@ -96,6 +98,7 @@ struct CODEC2 * CODEC2_WIN32SUPPORT codec2_create(int mode)
     assert(
           (mode == CODEC2_MODE_3200) || 
           (mode == CODEC2_MODE_2400) || 
+          (mode == CODEC2_MODE_1600) || 
           (mode == CODEC2_MODE_1400) || 
           (mode == CODEC2_MODE_1200)
           );
@@ -173,6 +176,8 @@ int CODEC2_WIN32SUPPORT codec2_bits_per_frame(struct CODEC2 *c2) {
        return 64;
     if (c2->mode == CODEC2_MODE_2400)
        return 48;
+    if  (c2->mode == CODEC2_MODE_1600)
+       return 64;
     if  (c2->mode == CODEC2_MODE_1400)
        return 56;
     if  (c2->mode == CODEC2_MODE_1200)
@@ -197,6 +202,8 @@ int CODEC2_WIN32SUPPORT codec2_samples_per_frame(struct CODEC2 *c2) {
        return 160;
     if (c2->mode == CODEC2_MODE_2400)
        return 160;
+    if  (c2->mode == CODEC2_MODE_1600)
+       return 320;
     if  (c2->mode == CODEC2_MODE_1400)
        return 320;
     if  (c2->mode == CODEC2_MODE_1200)
@@ -211,6 +218,7 @@ void CODEC2_WIN32SUPPORT codec2_encode(struct CODEC2 *c2, unsigned char *bits, s
     assert(
           (c2->mode == CODEC2_MODE_3200) || 
           (c2->mode == CODEC2_MODE_2400) || 
+          (c2->mode == CODEC2_MODE_1600) || 
           (c2->mode == CODEC2_MODE_1400) || 
           (c2->mode == CODEC2_MODE_1200)
           );
@@ -219,6 +227,8 @@ void CODEC2_WIN32SUPPORT codec2_encode(struct CODEC2 *c2, unsigned char *bits, s
        codec2_encode_3200(c2, bits, speech);
     if (c2->mode == CODEC2_MODE_2400)
        codec2_encode_2400(c2, bits, speech);
+    if (c2->mode == CODEC2_MODE_1600)
+       codec2_encode_1600(c2, bits, speech);
     if (c2->mode == CODEC2_MODE_1400)
        codec2_encode_1400(c2, bits, speech);
     if (c2->mode == CODEC2_MODE_1200)
@@ -231,6 +241,7 @@ void CODEC2_WIN32SUPPORT codec2_decode(struct CODEC2 *c2, short speech[], const
     assert(
           (c2->mode == CODEC2_MODE_3200) || 
           (c2->mode == CODEC2_MODE_2400) || 
+          (c2->mode == CODEC2_MODE_1600) || 
           (c2->mode == CODEC2_MODE_1400) || 
           (c2->mode == CODEC2_MODE_1200)
           );
@@ -239,6 +250,8 @@ void CODEC2_WIN32SUPPORT codec2_decode(struct CODEC2 *c2, short speech[], const
        codec2_decode_3200(c2, speech, bits);
     if (c2->mode == CODEC2_MODE_2400)
        codec2_decode_2400(c2, speech, bits);
+    if (c2->mode == CODEC2_MODE_1600)
+       codec2_decode_1600(c2, speech, bits);
     if (c2->mode == CODEC2_MODE_1400)
        codec2_decode_1400(c2, speech, bits);
     if (c2->mode == CODEC2_MODE_1200)
@@ -541,6 +554,193 @@ void codec2_decode_2400(struct CODEC2 *c2, short speech[], const unsigned char *
 }
 
 
+/*---------------------------------------------------------------------------*\
+                                                       
+  FUNCTION....: codec2_encode_1600          
+  AUTHOR......: David Rowe                           
+  DATE CREATED: Feb 28 2013
+
+  Encodes 320 speech samples (40ms of speech) into 64 bits.
+
+  The codec2 algorithm actually operates internally on 10ms (80
+  sample) frames, so we run the encoding algorithm 4 times:
+
+  frame 0: voicing bit
+  frame 1: voicing bit, Wo and E
+  frame 2: voicing bit
+  frame 3: voicing bit, Wo and E, scalar LSPs
+
+  The bit allocation is:
+
+    Parameter                      frame 2  frame 4   Total
+    -------------------------------------------------------
+    Harmonic magnitudes (LSPs)      0       36        36
+    Pitch (Wo)                      7        7        14
+    Energy                          5        5        10
+    Voicing (10ms update)           2        2         4
+    TOTAL                          14       50        64
+\*---------------------------------------------------------------------------*/
+
+void codec2_encode_1600(struct CODEC2 *c2, unsigned char * bits, short speech[])
+{
+    MODEL   model;
+    float   lsps[LPC_ORD];
+    float   ak[LPC_ORD+1];
+    float   e;
+    int     lsp_indexes[LPC_ORD];
+    int     Wo_index, e_index;
+    int     i;
+    unsigned int nbit = 0;
+    
+    assert(c2 != NULL);
+
+    memset(bits, '\0',  ((codec2_bits_per_frame(c2) + 7) / 8));
+
+    /* frame 1: - voicing ---------------------------------------------*/
+
+    analyse_one_frame(c2, &model, speech);
+    pack(bits, &nbit, model.voiced, 1);
+    /* frame 2: - voicing, scalar Wo & E -------------------------------*/
+
+    analyse_one_frame(c2, &model, &speech[N]);
+    pack(bits, &nbit, model.voiced, 1);
+    Wo_index = encode_Wo(model.Wo);
+    pack(bits, &nbit, Wo_index, WO_BITS);
+
+    /* need to run this just to get LPC energy */
+    e = speech_to_uq_lsps(lsps, ak, c2->Sn, c2->w, LPC_ORD);
+    e_index = encode_energy(e);
+    pack(bits, &nbit, e_index, E_BITS);
+
+    /* frame 3: - voicing ---------------------------------------------*/
+
+    analyse_one_frame(c2, &model, &speech[2*N]);
+    pack(bits, &nbit, model.voiced, 1);
+
+    /* frame 4: - voicing, scalar Wo & E, scalar LSPs ------------------*/
+
+    analyse_one_frame(c2, &model, &speech[3*N]);
+    pack(bits, &nbit, model.voiced, 1);
+    Wo_index = encode_Wo(model.Wo);
+    pack(bits, &nbit, Wo_index, WO_BITS);
+
+    e = speech_to_uq_lsps(lsps, ak, c2->Sn, c2->w, LPC_ORD);
+    e_index = encode_energy(e);
+    pack(bits, &nbit, e_index, E_BITS);
+    encode_lsps_scalar(lsp_indexes, lsps, LPC_ORD);
+    for(i=0; i<LSP_SCALAR_INDEXES; i++) {
+       pack(bits, &nbit, lsp_indexes[i], lsp_bits(i));
+    }
+
+    assert(nbit == (unsigned)codec2_bits_per_frame(c2));
+}
+
+
+/*---------------------------------------------------------------------------*\
+                                                       
+  FUNCTION....: codec2_decode_1600          
+  AUTHOR......: David Rowe                           
+  DATE CREATED: 11 May 2012
+
+  Decodes frames of 64 bits into 320 samples (40ms) of speech.
+
+\*---------------------------------------------------------------------------*/
+
+void codec2_decode_1600(struct CODEC2 *c2, short speech[], const unsigned char * bits)
+{
+    MODEL   model[4];
+    int     lsp_indexes[LPC_ORD];
+    float   lsps[4][LPC_ORD];
+    int     Wo_index, e_index;
+    float   e[4];
+    float   snr;
+    float   ak[4][LPC_ORD+1];
+    int     i,j;
+    unsigned int nbit = 0;
+    float   weight;
+    
+    assert(c2 != NULL);
+
+    /* only need to zero these out due to (unused) snr calculation */
+
+    for(i=0; i<4; i++)
+       for(j=1; j<=MAX_AMP; j++)
+           model[i].A[j] = 0.0;
+
+    /* unpack bits from channel ------------------------------------*/
+
+    /* this will partially fill the model params for the 4 x 10ms
+       frames */
+
+    model[0].voiced = unpack(bits, &nbit, 1);
+    
+    model[1].voiced = unpack(bits, &nbit, 1);
+    Wo_index = unpack(bits, &nbit, WO_BITS);
+    model[1].Wo = decode_Wo(Wo_index);
+    model[1].L  = PI/model[1].Wo;
+
+    e_index = unpack(bits, &nbit, E_BITS);
+    e[1] = decode_energy(e_index);
+
+    model[2].voiced = unpack(bits, &nbit, 1);
+
+    model[3].voiced = unpack(bits, &nbit, 1);
+    Wo_index = unpack(bits, &nbit, WO_BITS);
+    model[3].Wo = decode_Wo(Wo_index);
+    model[3].L  = PI/model[3].Wo;
+
+    e_index = unpack(bits, &nbit, E_BITS);
+    e[3] = decode_energy(e_index);
+    for(i=0; i<LSP_SCALAR_INDEXES; i++) {
+       lsp_indexes[i] = unpack(bits, &nbit, lsp_bits(i));
+    }
+    decode_lsps_scalar(&lsps[3][0], lsp_indexes, LPC_ORD);
+    check_lsp_order(&lsps[3][0], LPC_ORD);
+    bw_expand_lsps(&lsps[3][0], LPC_ORD);
+    /* interpolate ------------------------------------------------*/
+
+    /* Wo and energy are sampled every 20ms, so we interpolate just 1
+       10ms frame between 20ms samples */
+
+    interp_Wo(&model[0], &c2->prev_model_dec, &model[1]);
+    e[0] = interp_energy(c2->prev_e_dec, e[1]);
+    interp_Wo(&model[2], &model[1], &model[3]);
+    e[2] = interp_energy(e[1], e[3]);
+    /* LSPs are sampled every 40ms so we interpolate the 3 frames in
+       between, then recover spectral amplitudes */
+
+    for(i=0, weight=0.25; i<3; i++, weight += 0.25) {
+       interpolate_lsp_ver2(&lsps[i][0], c2->prev_lsps_dec, &lsps[3][0], weight);
+    }
+    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,
+                  c2->lpc_pf, c2->bass_boost, c2->beta, c2->gamma); 
+       apply_lpc_correction(&model[i]);
+    }
+
+    /* synthesise ------------------------------------------------*/
+
+    for(i=0; i<4; i++)
+       synthesise_one_frame(c2, &speech[N*i], &model[i], &ak[i][0]);
+
+    /* update memories for next frame ----------------------------*/
+
+    c2->prev_model_dec = model[3];
+    c2->prev_e_dec = e[3];
+    for(i=0; i<LPC_ORD; i++)
+       c2->prev_lsps_dec[i] = lsps[3][i];
+
+}
+
 /*---------------------------------------------------------------------------*\
                                                        
   FUNCTION....: codec2_encode_1400          
index 8baa307eb620df81fdcf4064363ae87430de9b3d..2c25f66126767fceecd4e5e3457ca2d9260fecb5 100644 (file)
@@ -48,8 +48,9 @@
 
 #define CODEC2_MODE_3200 0
 #define CODEC2_MODE_2400 1
-#define CODEC2_MODE_1400 2
-#define CODEC2_MODE_1200 3
+#define CODEC2_MODE_1600 2
+#define CODEC2_MODE_1400 3
+#define CODEC2_MODE_1200 4
 
 struct CODEC2;
 
index 5013ab0b78029f5ede09dd0ae7f036a8efae0c98..5414b266fc1d87f81f2e3f1f5199e5c20d93f612 100644 (file)
@@ -102,7 +102,7 @@ int main(int argc, char *argv[])
     Nc = FDMDV_NC;
     fdmdv = fdmdv_create(Nc);
 
-    /* malloc some of the bigger variables to prevent out of stack problems */
+    /* malloc some of the larger variables to prevent out of stack problems */
 
     rx_fdm_log = (COMP*)malloc(sizeof(COMP)*FDMDV_MAX_SAMPLES_PER_FRAME*MAX_FRAMES);
     assert(rx_fdm_log != NULL);