shithub: opus

Download patch

ref: a76a0b23eb7001411c898fecee39744d605d9d09
parent: 649d5cc23bfd3ecd6198068e509fc2e882fa1488
author: Jean-Marc Valin <[email protected]>
date: Thu Jan 17 17:43:05 EST 2008

Further simplified the API by passing the rate directly to the
encode function. Also, trying to properly flush the bit packer
(still some problems left).

--- a/libcelt/celt.c
+++ b/libcelt/celt.c
@@ -55,7 +55,6 @@
    int channels;
    int Fs;
    
-   int bytesPerFrame;
    ec_byte_buffer buf;
    ec_enc         enc;
 
@@ -96,8 +95,7 @@
    N4 = (N-st->overlap)/2;
    ec_byte_writeinit(&st->buf);
    ec_enc_init(&st->enc,&st->buf);
-   st->bytesPerFrame = mode->defaultRate;
-   
+
    mdct_init(&st->mdct_lookup, 2*N);
    st->fft = spx_fft_init(MAX_PERIOD*C);
    
@@ -236,16 +234,8 @@
    }
 }
 
-int celt_encoder_set_output_size(CELTEncoder *st, int bytesPerFrame)
+int celt_encode(CELTEncoder *st, short *pcm, char *compressed, int nbCompressedBytes)
 {
-   if (bytesPerFrame<= 0)
-      return -1;
-   st->bytesPerFrame = bytesPerFrame;
-   return st->bytesPerFrame;
-}
-
-int celt_encode(CELTEncoder *st, short *pcm, char *compressed)
-{
    int i, c, N, B, C, N4;
    N = st->block_size;
    B = st->nb_blocks;
@@ -357,7 +347,7 @@
       sum += X[i]*X[i];
    printf ("%f\n", sum);*/
    /* Residual quantisation */
-   quant_bands(st->mode, X, P, mask, &st->alloc, st->bytesPerFrame*8, &st->enc);
+   quant_bands(st->mode, X, P, mask, &st->alloc, nbCompressedBytes*8, &st->enc);
    
    time_idct(X, N, B, C);
    if (C==2)
@@ -389,25 +379,51 @@
       }
    }
    
-   while (ec_enc_tell(&st->enc, 0) < st->bytesPerFrame*8)
-      ec_enc_bits(&st->enc, 1, 1);
+   while (ec_enc_tell(&st->enc, 0) < nbCompressedBytes*8)
+      ec_enc_uint(&st->enc, 1, 2);
    ec_enc_done(&st->enc);
-   int nbBytes = ec_byte_bytes(&st->buf);
-   char *data = ec_byte_get_buffer(&st->buf);
-   for (i=0;i<nbBytes;i++)
-      compressed[i] = data[i];
-   /* Fill the last byte with the right pattern so the decoder doesn't get confused
-      if the encoder didn't return enough bytes */
-   /* FIXME: This isn't quite what the decoder expects, but it's the best we can do for now */
-   for (;i<st->bytesPerFrame;i++)
-      compressed[i] = 0x00;
-   //printf ("%d\n", *nbBytes);
-   
+   {
+      unsigned char *data;
+      int nbBytes = ec_byte_bytes(&st->buf);
+      //printf ("%d\n", *nbBytes);
+      data = ec_byte_get_buffer(&st->buf);
+      for (i=0;i<nbBytes;i++)
+         compressed[i] = data[i];
+      /* Fill the last byte with the right pattern so the decoder doesn't get confused
+         if the encoder didn't return enough bytes */
+      /* FIXME: This isn't quite what the decoder expects, but it's the best we can do for now */
+      if (nbBytes < nbCompressedBytes)
+      {
+         //fprintf (stderr, "smaller: %d\n", compressed[nbBytes-1]);
+         if (compressed[nbBytes-1] == 0x00)
+         {
+            compressed[i++] = 0x80;
+            //fprintf (stderr, "put 0x00\n");
+         } else if (compressed[nbBytes-1] == 0x80)
+         {
+            int k = nbBytes-1;
+            while (compressed[k-1] == 0x80)
+            {
+               k--;
+            }
+            if (compressed[k-1] == 0x00)
+            {
+               compressed[i++] = 0x80;
+               //fprintf (stderr, "special 0x00\n");
+            }
+         }
+         for (;i<nbCompressedBytes;i++)
+            compressed[i] = 0x00;
+      } else if (nbBytes < nbCompressedBytes)
+      {
+         //fprintf (stderr, "ERROR: too many bits\n");
+      }
+   }   
    /* Reset the packing for the next encoding */
    ec_byte_reset(&st->buf);
    ec_enc_init(&st->enc,&st->buf);
 
-   return st->bytesPerFrame;
+   return nbCompressedBytes;
 }
 
 char *celt_encoder_get_bytes(CELTEncoder *st, int *nbBytes)
@@ -640,6 +656,7 @@
          }
       }
    }
+   
    return 0;
    //printf ("\n");
 }
--- a/libcelt/celt.h
+++ b/libcelt/celt.h
@@ -32,6 +32,12 @@
 #ifndef CELT_H
 #define CELT_H
 
+#define CELT_BAD_ARG -1
+#define CELT_INVALID_MODE -2
+#define CELT_INTERNAL_ERROR -3
+#define CELT_CORRUPTED_DATA -4
+
+
 typedef struct CELTEncoder CELTEncoder;
 typedef struct CELTDecoder CELTDecoder;
 
@@ -49,9 +55,7 @@
 
 void celt_encoder_destroy(CELTEncoder *st);
 
-int celt_encoder_set_output_size(CELTEncoder *st, int bytesPerFrame);
-
-int celt_encode(CELTEncoder *st, short *pcm, char *compressed);
+int celt_encode(CELTEncoder *st, short *pcm, char *compressed, int nbCompressedBytes);
 
 /* Decoder stuff */
 
--- a/libcelt/testcelt.c
+++ b/libcelt/testcelt.c
@@ -55,13 +55,13 @@
    /* Use mode4 for stereo and don't forget to change the value of CHANNEL above */
    enc = celt_encoder_new(celt_mode0);
    dec = celt_decoder_new(celt_mode0);
-   //celt_encoder_set_output_size(enc, 48);
    
    while (!feof(fin))
    {
       fread(in, sizeof(short), FRAME_SIZE*CHANNELS, fin);
-      len = celt_encode(enc, in, data);
-      printf ("%d\n", len);
+      len = celt_encode(enc, in, data, 32);
+      //printf ("\n");
+      //printf ("%d\n", len);
 #if 1
       /* this is to simulate packet loss */
       if (rand()%100==-1)
@@ -68,6 +68,7 @@
          celt_decode(dec, NULL, len, in);
       else
          celt_decode(dec, data, len, in);
+      //printf ("\n");
 #endif
       fwrite(in, sizeof(short), FRAME_SIZE*CHANNELS, fout);
    }
--- a/libcelt/vq.c
+++ b/libcelt/vq.c
@@ -187,7 +187,7 @@
    //   printf ("%d ", iy[0][i]);
    pulse2comb(N, K, comb, signs, iy[0]); 
    ec_enc_uint64(enc,icwrs64(N, K, comb, signs),ncwrs64(N, K));
-   
+   //printf ("%llu ", icwrs64(N, K, comb, signs));
    /* Recompute the gain in one pass to reduce the encoder-decoder mismatch
       due to the recursive computation used in quantisation */
    if (1) {
@@ -232,6 +232,7 @@
    float g;
 
    id = ec_dec_uint64(dec, ncwrs64(N, K));
+   //printf ("%llu ", id);
    cwrsi64(N, K, id, comb, signs);
    comb2pulse(N, K, iy, comb, signs);
    //for (i=0;i<N;i++)