Commit a76a0b23 authored by Jean-Marc Valin's avatar Jean-Marc Valin
Browse files

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).
parent 649d5cc2
......@@ -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");
}
......
......@@ -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 @@ 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 */
......
......@@ -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);
}
......
......@@ -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++)
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment