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++)