ref: 80ed1476636e8fd342346bda19e6cab66ff3f3d0
parent: bf2398b0490acfab8bbd8472c9d2fae6de96b61e
author: Jean-Marc Valin <[email protected]>
date: Thu Oct 15 17:45:32 EDT 2009
The number of channels is now set when creating the states rather than when creating the mode. This means that the same mode can be shared for mono and stereo.
--- a/libcelt/celt.c
+++ b/libcelt/celt.c
@@ -119,7 +119,7 @@
return CELT_INVALID_STATE;
}
-CELTEncoder *celt_encoder_create(const CELTMode *mode)
+CELTEncoder *celt_encoder_create(const CELTMode *mode, int channels, int *error)
{
int N, C;
CELTEncoder *st;
@@ -126,18 +126,26 @@
if (check_mode(mode) != CELT_OK)
return NULL;
+ if (channels < 0 || channels > 2)
+ {
+ celt_warning("Only mono and stereo supported");
+ if (error)
+ *error = CELT_BAD_ARG;
+ return NULL;
+ }
N = mode->mdctSize;
- C = mode->nbChannels;
+ C = channels;
st = celt_alloc(sizeof(CELTEncoder));
if (st==NULL)
- return NULL;
+ return NULL;
st->marker = ENCODERPARTIAL;
st->mode = mode;
st->frame_size = N;
st->block_size = N;
st->overlap = mode->overlap;
+ st->channels = channels;
st->VBR_rate = 0;
st->pitch_enabled = 1;
@@ -525,7 +533,7 @@
int shortBlocks=0;
int transient_time;
int transient_shift;
- const int C = MCHANNELS(st->mode);
+ const int C = CHANNELS(st->channels);
int mdct_weight_shift = 0;
int mdct_weight_pos=0;
int gain_id=0;
@@ -825,7 +833,7 @@
if (pcm==NULL)
return CELT_BAD_ARG;
- C = MCHANNELS(st->mode);
+ C = CHANNELS(st->channels);
N = st->block_size;
ALLOC(in, C*N, celt_int16_t);
@@ -860,7 +868,7 @@
if (pcm==NULL)
return CELT_BAD_ARG;
- C=MCHANNELS(st->mode);
+ C=CHANNELS(st->channels);
N=st->block_size;
ALLOC(in, C*N, celt_sig_t);
for (j=0;j<C*N;j++) {
@@ -946,7 +954,7 @@
case CELT_RESET_STATE:
{
const CELTMode *mode = st->mode;
- int C = mode->nbChannels;
+ int C = st->channels;
if (st->pitch_available > 0) st->pitch_available = 1;
@@ -1000,6 +1008,7 @@
int frame_size;
int block_size;
int overlap;
+ int channels;
ec_byte_buffer buf;
ec_enc enc;
@@ -1031,7 +1040,7 @@
return CELT_INVALID_STATE;
}
-CELTDecoder *celt_decoder_create(const CELTMode *mode)
+CELTDecoder *celt_decoder_create(const CELTMode *mode, int channels, int *error)
{
int N, C;
CELTDecoder *st;
@@ -1038,9 +1047,16 @@
if (check_mode(mode) != CELT_OK)
return NULL;
+ if (channels < 0 || channels > 2)
+ {
+ celt_warning("Only mono and stereo supported");
+ if (error)
+ *error = CELT_BAD_ARG;
+ return NULL;
+ }
N = mode->mdctSize;
- C = MCHANNELS(mode);
+ C = CHANNELS(channels);
st = celt_alloc(sizeof(CELTDecoder));
if (st==NULL)
@@ -1051,6 +1067,7 @@
st->frame_size = N;
st->block_size = N;
st->overlap = mode->overlap;
+ st->channels = channels;
st->decode_mem = celt_alloc((DECODE_BUFFER_SIZE+st->overlap)*C*sizeof(celt_sig_t));
st->out_mem = st->decode_mem+DECODE_BUFFER_SIZE-MAX_PERIOD;
@@ -1119,7 +1136,7 @@
celt_word16_t fade = Q15ONE;
int i, len;
VARDECL(celt_sig_t, freq);
- const int C = MCHANNELS(st->mode);
+ const int C = CHANNELS(st->channels);
int offset;
SAVE_STACK;
N = st->block_size;
@@ -1196,7 +1213,7 @@
int transient_time;
int transient_shift;
int mdct_weight_shift=0;
- const int C = MCHANNELS(st->mode);
+ const int C = CHANNELS(st->channels);
int mdct_weight_pos=0;
int gain_id=0;
SAVE_STACK;
@@ -1334,7 +1351,7 @@
if (pcm==NULL)
return CELT_BAD_ARG;
- C = MCHANNELS(st->mode);
+ C = CHANNELS(st->channels);
N = st->block_size;
ALLOC(out, C*N, celt_int16_t);
@@ -1362,7 +1379,7 @@
if (pcm==NULL)
return CELT_BAD_ARG;
- C = MCHANNELS(st->mode);
+ C = CHANNELS(st->channels);
N = st->block_size;
ALLOC(out, C*N, celt_sig_t);
@@ -1399,7 +1416,7 @@
case CELT_RESET_STATE:
{
const CELTMode *mode = st->mode;
- int C = mode->nbChannels;
+ int C = st->channels;
CELT_MEMSET(st->decode_mem, 0, (DECODE_BUFFER_SIZE+st->overlap)*C);
CELT_MEMSET(st->oldBandE, 0, C*mode->nbEBands);
--- a/libcelt/celt.h
+++ b/libcelt/celt.h
@@ -95,8 +95,6 @@
#define CELT_GET_FRAME_SIZE 1000
/** GET the lookahead used in the current mode */
#define CELT_GET_LOOKAHEAD 1001
-/** GET the number of channels used in the current mode */
-#define CELT_GET_NB_CHANNELS 1002
/** GET the sample rate used in the current mode */
#define CELT_GET_SAMPLE_RATE 1003
@@ -138,7 +136,7 @@
@param error Returned error code (if NULL, no error will be returned)
@return A newly created mode
*/
-EXPORT CELTMode *celt_mode_create(celt_int32_t Fs, int channels, int frame_size, int *error);
+EXPORT CELTMode *celt_mode_create(celt_int32_t Fs, int frame_size, int *error);
/** Destroys a mode struct. Only call this after all encoders and
decoders using this mode are destroyed as well.
@@ -159,7 +157,7 @@
* decoder)
@return Newly created encoder state.
*/
-EXPORT CELTEncoder *celt_encoder_create(const CELTMode *mode);
+EXPORT CELTEncoder *celt_encoder_create(const CELTMode *mode, int channels, int *error);
/** Destroys a an encoder state.
@param st Encoder state to be destroyed
@@ -227,7 +225,7 @@
stream (must be the same characteristics as used for the encoder)
@return Newly created decoder state.
*/
-EXPORT CELTDecoder *celt_decoder_create(const CELTMode *mode);
+EXPORT CELTDecoder *celt_decoder_create(const CELTMode *mode, int channels, int *error);
/** Destroys a a decoder state.
@param st Decoder state to be destroyed
--- a/libcelt/celt_header.h
+++ b/libcelt/celt_header.h
@@ -56,7 +56,7 @@
} CELTHeader;
/** Creates a basic header struct */
-EXPORT int celt_header_init(CELTHeader *header, const CELTMode *m);
+EXPORT int celt_header_init(CELTHeader *header, const CELTMode *m, int channels);
EXPORT int celt_header_to_packet(const CELTHeader *header, unsigned char *packet, celt_uint32_t size);
--- a/libcelt/dump_modes.c
+++ b/libcelt/dump_modes.c
@@ -92,9 +92,9 @@
fprintf(file, "\n");
- fprintf(file, "#ifndef DEF_ALLOC_VECTORS%d_%d_%d\n", mode->Fs, mode->mdctSize, mode->nbChannels);
- fprintf(file, "#define DEF_ALLOC_VECTORS%d_%d_%d\n", mode->Fs, mode->mdctSize, mode->nbChannels);
- fprintf (file, "static const celt_int16_t allocVectors%d_%d_%d[%d] = {\n", mode->Fs, mode->mdctSize, mode->nbChannels, mode->nbEBands*mode->nbAllocVectors);
+ fprintf(file, "#ifndef DEF_ALLOC_VECTORS%d_%d\n", mode->Fs, mode->mdctSize);
+ fprintf(file, "#define DEF_ALLOC_VECTORS%d_%d\n", mode->Fs, mode->mdctSize);
+ fprintf (file, "static const celt_int16_t allocVectors%d_%d[%d] = {\n", mode->Fs, mode->mdctSize, mode->nbEBands*mode->nbAllocVectors);
for (j=0;j<mode->nbAllocVectors;j++)
{
int k;
@@ -106,25 +106,25 @@
fprintf(file, "#endif\n");
fprintf(file, "\n");
- fprintf(file, "#ifndef DEF_ALLOC_CACHE%d_%d_%d\n", mode->Fs, mode->mdctSize, mode->nbChannels);
- fprintf(file, "#define DEF_ALLOC_CACHE%d_%d_%d\n", mode->Fs, mode->mdctSize, mode->nbChannels);
+ fprintf(file, "#ifndef DEF_ALLOC_CACHE%d_%d\n", mode->Fs, mode->mdctSize);
+ fprintf(file, "#define DEF_ALLOC_CACHE%d_%d\n", mode->Fs, mode->mdctSize);
for (j=0;j<mode->nbEBands;j++)
{
int k;
if (j==0 || (mode->bits[j] != mode->bits[j-1]))
{
- fprintf (file, "static const celt_int16_t allocCache_band%d_%d_%d_%d[MAX_PULSES] = {\n", j, mode->Fs, mode->mdctSize, mode->nbChannels);
+ fprintf (file, "static const celt_int16_t allocCache_band%d_%d_%d[MAX_PULSES] = {\n", j, mode->Fs, mode->mdctSize);
for (k=0;k<MAX_PULSES;k++)
fprintf (file, "%2d, ", mode->bits[j][k]);
fprintf (file, "};\n");
} else {
- fprintf (file, "#define allocCache_band%d_%d_%d_%d allocCache_band%d_%d_%d_%d\n", j, mode->Fs, mode->mdctSize, mode->nbChannels, j-1, mode->Fs, mode->mdctSize, mode->nbChannels);
+ fprintf (file, "#define allocCache_band%d_%d_%d allocCache_band%d_%d_%d\n", j, mode->Fs, mode->mdctSize, j-1, mode->Fs, mode->mdctSize);
}
}
- fprintf (file, "static const celt_int16_t *allocCache%d_%d_%d[%d] = {\n", mode->Fs, mode->mdctSize, mode->nbChannels, mode->nbEBands);
+ fprintf (file, "static const celt_int16_t *allocCache%d_%d[%d] = {\n", mode->Fs, mode->mdctSize, mode->nbEBands);
for (j=0;j<mode->nbEBands;j++)
{
- fprintf (file, "allocCache_band%d_%d_%d_%d, ", j, mode->Fs, mode->mdctSize, mode->nbChannels);
+ fprintf (file, "allocCache_band%d_%d_%d, ", j, mode->Fs, mode->mdctSize);
}
fprintf (file, "};\n");
fprintf(file, "#endif\n");
@@ -131,19 +131,18 @@
fprintf(file, "\n");
- fprintf(file, "static const CELTMode mode%d_%d_%d_%d = {\n", mode->Fs, mode->nbChannels, mode->mdctSize, mode->overlap);
+ fprintf(file, "static const CELTMode mode%d_%d_%d = {\n", mode->Fs, mode->mdctSize, mode->overlap);
fprintf(file, "0x%x,\t/* marker */\n", 0xa110ca7e);
fprintf(file, INT32 ",\t/* Fs */\n", mode->Fs);
fprintf(file, "%d,\t/* overlap */\n", mode->overlap);
fprintf(file, "%d,\t/* mdctSize */\n", mode->mdctSize);
- fprintf(file, "%d,\t/* nbChannels */\n", mode->nbChannels);
fprintf(file, "%d,\t/* nbEBands */\n", mode->nbEBands);
fprintf(file, "%d,\t/* pitchEnd */\n", mode->pitchEnd);
fprintf(file, "eBands%d_%d,\t/* eBands */\n", mode->Fs, mode->mdctSize);
fprintf(file, WORD16 ",\t/* ePredCoef */\n", mode->ePredCoef);
fprintf(file, "%d,\t/* nbAllocVectors */\n", mode->nbAllocVectors);
- fprintf(file, "allocVectors%d_%d_%d,\t/* allocVectors */\n", mode->Fs, mode->mdctSize, mode->nbChannels);
- fprintf(file, "allocCache%d_%d_%d,\t/* bits */\n", mode->Fs, mode->mdctSize, mode->nbChannels);
+ fprintf(file, "allocVectors%d_%d,\t/* allocVectors */\n", mode->Fs, mode->mdctSize);
+ fprintf(file, "allocCache%d_%d,\t/* bits */\n", mode->Fs, mode->mdctSize);
fprintf(file, "{%d, 0, 0},\t/* mdct */\n", 2*mode->mdctSize);
fprintf(file, "0,\t/* fft */\n");
fprintf(file, "window%d,\t/* window */\n", mode->overlap);
@@ -163,7 +162,7 @@
for (i=0;i<nb_modes;i++)
{
CELTMode *mode = modes[i];
- fprintf(file, "&mode%d_%d_%d_%d,\n", mode->Fs, mode->nbChannels, mode->mdctSize, mode->overlap);
+ fprintf(file, "&mode%d_%d_%d,\n", mode->Fs, mode->mdctSize, mode->overlap);
}
fprintf(file, "};\n");
}
@@ -178,10 +177,6 @@
for (i=0;i<nb_modes;i++)
{
CELTMode *mode = modes[i];
- if (channels==0)
- channels = mode->nbChannels;
- else if (channels != mode->nbChannels)
- channels = -1;
if (frame_size==0)
frame_size = mode->mdctSize;
else if (frame_size != mode->mdctSize)
@@ -212,20 +207,19 @@
int i, nb;
FILE *file;
CELTMode **m;
- if (argc%3 != 1)
+ if (argc%2 != 1)
{
- fprintf (stderr, "must have a multiple of 4 arguments\n");
+ fprintf (stderr, "must have a multiple of 2 arguments\n");
return 1;
}
- nb = (argc-1)/3;
+ nb = (argc-1)/2;
m = malloc(nb*sizeof(CELTMode*));
for (i=0;i<nb;i++)
{
- int Fs, ch, frame;
- Fs = atoi(argv[3*i+1]);
- ch = atoi(argv[3*i+2]);
- frame = atoi(argv[3*i+3]);
- m[i] = celt_mode_create(Fs, ch, frame, NULL);
+ int Fs, frame;
+ Fs = atoi(argv[2*i+1]);
+ frame = atoi(argv[2*i+2]);
+ m[i] = celt_mode_create(Fs, frame, NULL);
}
file = fopen("static_modes.c", "w");
dump_modes(file, m, nb);
--- a/libcelt/header.c
+++ b/libcelt/header.c
@@ -62,7 +62,7 @@
return ret;
}
-int celt_header_init(CELTHeader *header, const CELTMode *m)
+int celt_header_init(CELTHeader *header, const CELTMode *m, int channels)
{
if (check_mode(m) != CELT_OK)
@@ -76,7 +76,7 @@
celt_mode_info(m, CELT_GET_BITSTREAM_VERSION, &header->version_id);
header->header_size = 56;
header->sample_rate = m->Fs;
- header->nb_channels = m->nbChannels;
+ header->nb_channels = channels;
header->frame_size = m->mdctSize;
header->overlap = m->overlap;
header->bytes_per_packet = -1;
--- a/libcelt/modes.c
+++ b/libcelt/modes.c
@@ -65,9 +65,6 @@
case CELT_GET_LOOKAHEAD:
*value = mode->overlap;
break;
- case CELT_GET_NB_CHANNELS:
- *value = mode->nbChannels;
- break;
case CELT_GET_BITSTREAM_VERSION:
*value = CELT_BITSTREAM_VERSION;
break;
@@ -226,7 +223,7 @@
#endif /* STATIC_MODES */
-CELTMode *celt_mode_create(celt_int32_t Fs, int channels, int frame_size, int *error)
+CELTMode *celt_mode_create(celt_int32_t Fs, int frame_size, int *error)
{
int i;
#ifdef STDIN_TUNING
@@ -252,7 +249,6 @@
for (i=0;i<TOTAL_MODES;i++)
{
if (Fs == static_mode_list[i]->Fs &&
- channels == static_mode_list[i]->nbChannels &&
frame_size == static_mode_list[i]->mdctSize)
{
m = static_mode_list[i];
@@ -293,13 +289,6 @@
*error = CELT_BAD_ARG;
return NULL;
}
- if (channels < 0 || channels > 2)
- {
- celt_warning("Only mono and stereo supported");
- if (error)
- *error = CELT_BAD_ARG;
- return NULL;
- }
if (frame_size < 64 || frame_size > 1024 || frame_size%2!=0)
{
celt_warning("Only even frame sizes from 64 to 1024 are supported");
@@ -315,7 +304,6 @@
mode->marker_start = MODEPARTIAL;
mode->Fs = Fs;
mode->mdctSize = frame_size;
- mode->nbChannels = channels;
mode->ePredCoef = QCONST16(.8f,15);
if (frame_size > 640 && (frame_size%16)==0)
--- a/libcelt/modes.h
+++ b/libcelt/modes.h
@@ -81,8 +81,7 @@
celt_int32_t Fs;
int overlap;
int mdctSize;
- int nbChannels;
-
+
int nbEBands;
int pitchEnd;
--- a/libcelt/testcelt.c
+++ b/libcelt/testcelt.c
@@ -44,6 +44,7 @@
int main(int argc, char *argv[])
{
+ int err;
char *inFile, *outFile;
FILE *fin, *fout;
CELTMode *mode=NULL;
@@ -73,7 +74,7 @@
rate = atoi(argv[1]);
channels = atoi(argv[2]);
frame_size = atoi(argv[3]);
- mode = celt_mode_create(rate, channels, frame_size, NULL);
+ mode = celt_mode_create(rate, frame_size, NULL);
celt_mode_info(mode, CELT_GET_LOOKAHEAD, &skip);
if (mode == NULL)
@@ -105,8 +106,12 @@
return 1;
}
- enc = celt_encoder_create(mode);
- dec = celt_decoder_create(mode);
+ enc = celt_encoder_create(mode, channels, &err);
+ if (err != 0)
+ return 1;
+ dec = celt_decoder_create(mode, channels, &err);
+ if (err != 0)
+ return 1;
if (argc>7)
{
@@ -115,12 +120,11 @@
}
celt_mode_info(mode, CELT_GET_FRAME_SIZE, &frame_size);
- celt_mode_info(mode, CELT_GET_NB_CHANNELS, &channels);
in = (celt_int16_t*)malloc(frame_size*channels*sizeof(celt_int16_t));
out = (celt_int16_t*)malloc(frame_size*channels*sizeof(celt_int16_t));
while (!feof(fin))
{
- fread(in, sizeof(short), frame_size*channels, fin);
+ err = fread(in, sizeof(short), frame_size*channels, fin);
if (feof(fin))
break;
len = celt_encode(enc, in, in, data, bytes_per_packet);
--- a/tests/tandem-test.c
+++ b/tests/tandem-test.c
@@ -76,14 +76,14 @@
printf ("Testing asynchronous tandeming (%dHz, %dch, %d samples, %d - %d bytes).\n",
rate, channels, frame_size, bmin, bmax);
- mode = celt_mode_create(rate, channels, frame_size, NULL);
+ mode = celt_mode_create(rate, frame_size, NULL);
if (mode == NULL) {
fprintf(stderr, "Error: failed to create a mode\n");
exit(1);
}
- dec = celt_decoder_create(mode);
- enc = celt_encoder_create(mode);
+ dec = celt_decoder_create(mode, channels, NULL);
+ enc = celt_encoder_create(mode, channels, NULL);
for (j = 0; j < frame_size * channels; j++)
pcm[j] = 0;
--- a/tools/celtdec.c
+++ b/tools/celtdec.c
@@ -299,7 +299,7 @@
fprintf (stderr, "Unsupported number of channels: %d\n", header.nb_channels);
return NULL;
}
- *mode = celt_mode_create(header.sample_rate, header.nb_channels, header.frame_size, NULL);
+ *mode = celt_mode_create(header.sample_rate, header.frame_size, NULL);
if (*mode == NULL)
{
fprintf (stderr, "Mode initialization failed.\n");
@@ -313,7 +313,7 @@
*channels = header.nb_channels;
*overlap=header.overlap;
- st = celt_decoder_create(*mode);
+ st = celt_decoder_create(*mode, header.nb_channels, NULL);
if (!st)
{
fprintf (stderr, "Decoder initialization failed.\n");
--- a/tools/celtenc.c
+++ b/tools/celtenc.c
@@ -490,7 +490,7 @@
bitrate = ((rate/(float)frame_size)*8*bytes_per_packet)/1000.0;
}
- mode = celt_mode_create(rate, chan, frame_size, NULL);
+ mode = celt_mode_create(rate, frame_size, NULL);
if (!mode)
return 1;
@@ -501,7 +501,7 @@
celt_mode_info(mode, CELT_GET_FRAME_SIZE, &frame_size);
- celt_header_init(&header, mode);
+ celt_header_init(&header, mode, chan);
header.nb_channels = chan;
{
@@ -518,7 +518,7 @@
}
/*Initialize CELT encoder*/
- st = celt_encoder_create(mode);
+ st = celt_encoder_create(mode, chan, NULL);
if (with_vbr)
{