Further simplified the API by passing the rate directly to the
authorJean-Marc Valin <jean-marc.valin@usherbrooke.ca>
Thu, 17 Jan 2008 11:43:05 +0000 (22:43 +1100)
committerJean-Marc Valin <jean-marc.valin@usherbrooke.ca>
Thu, 17 Jan 2008 11:43:05 +0000 (22:43 +1100)
encode function. Also, trying to properly flush the bit packer
(still some problems left).

libcelt/celt.c
libcelt/celt.h
libcelt/testcelt.c
libcelt/vq.c

index e8930db..63b6565 100644 (file)
@@ -55,7 +55,6 @@ struct CELTEncoder {
    int channels;
    int Fs;
    
-   int bytesPerFrame;
    ec_byte_buffer buf;
    ec_enc         enc;
 
@@ -96,8 +95,7 @@ CELTEncoder *celt_encoder_new(const CELTMode *mode)
    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,15 +234,7 @@ static void compute_inv_mdcts(mdct_lookup *mdct_lookup, float *window, float *X,
    }
 }
 
-int celt_encoder_set_output_size(CELTEncoder *st, int bytesPerFrame)
-{
-   if (bytesPerFrame<= 0)
-      return -1;
-   st->bytesPerFrame = bytesPerFrame;
-   return st->bytesPerFrame;
-}
-
-int celt_encode(CELTEncoder *st, short *pcm, char *compressed)
+int celt_encode(CELTEncoder *st, short *pcm, char *compressed, int nbCompressedBytes)
 {
    int i, c, N, B, C, N4;
    N = st->block_size;
@@ -357,7 +347,7 @@ int celt_encode(CELTEncoder *st, short *pcm, char *compressed)
       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 @@ int celt_encode(CELTEncoder *st, short *pcm, char *compressed)
       }
    }
    
-   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 @@ int celt_decode(CELTDecoder *st, char *data, int len, short *pcm)
          }
       }
    }
+   
    return 0;
    //printf ("\n");
 }
index 490d4ad..2e7c873 100644 (file)
 #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 @@ CELTEncoder *celt_encoder_new(const CELTMode *mode);
 
 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 */
 
index ae950b3..6718d32 100644 (file)
@@ -55,19 +55,20 @@ int main(int argc, char *argv[])
    /* 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)
          celt_decode(dec, NULL, len, in);
       else
          celt_decode(dec, data, len, in);
+      //printf ("\n");
 #endif
       fwrite(in, sizeof(short), FRAME_SIZE*CHANNELS, fout);
    }
index e380900..c632946 100644 (file)
@@ -187,7 +187,7 @@ void alg_quant(float *x, float *W, int N, int K, float *p, float alpha, ec_enc *
    //   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 @@ void alg_unquant(float *x, int N, int K, float *p, float alpha, ec_dec *dec)
    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++)