diff --git a/libcelt/celt.c b/libcelt/celt.c index ca40eb6e..395da318 100644 --- a/libcelt/celt.c +++ b/libcelt/celt.c @@ -119,25 +119,33 @@ static int check_encoder(const CELTEncoder *st) 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; 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 celt_encode_float(CELTEncoder * restrict st, const celt_sig_t * pcm, celt_si 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 @@ int celt_encode_float(CELTEncoder * restrict st, const float * pcm, float * opti 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 @@ int celt_encode(CELTEncoder * restrict st, const celt_int16_t * pcm, celt_int16_ 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;jmode; - int C = mode->nbChannels; + int C = st->channels; if (st->pitch_available > 0) st->pitch_available = 1; @@ -1000,6 +1008,7 @@ struct CELTDecoder { int frame_size; int block_size; int overlap; + int channels; ec_byte_buffer buf; ec_enc enc; @@ -1031,16 +1040,23 @@ int check_decoder(const CELTDecoder *st) 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; 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 @@ CELTDecoder *celt_decoder_create(const CELTMode *mode) 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 @@ static void celt_decode_lost(CELTDecoder * restrict st, celt_word16_t * restrict 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 celt_decode_float(CELTDecoder * restrict st, const unsigned char *data, int 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 @@ int celt_decode_float(CELTDecoder * restrict st, const unsigned char *data, int 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 @@ int celt_decode(CELTDecoder * restrict st, const unsigned char *data, int len, c 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 @@ int celt_decoder_ctl(CELTDecoder * restrict st, int request, ...) 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); diff --git a/libcelt/celt.h b/libcelt/celt.h index 47e58a77..a0d7d601 100644 --- a/libcelt/celt.h +++ b/libcelt/celt.h @@ -95,8 +95,6 @@ extern "C" { #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 @@ typedef struct CELTMode CELTMode; @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 @@ EXPORT int celt_mode_info(const CELTMode *mode, int request, celt_int32_t *value * 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 @@ EXPORT int celt_encoder_ctl(CELTEncoder * st, int request, ...); 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 diff --git a/libcelt/celt_header.h b/libcelt/celt_header.h index 78a528e3..a4a0c8ea 100644 --- a/libcelt/celt_header.h +++ b/libcelt/celt_header.h @@ -56,7 +56,7 @@ typedef struct { } 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); diff --git a/libcelt/dump_modes.c b/libcelt/dump_modes.c index 66dc2823..eb6e0375 100644 --- a/libcelt/dump_modes.c +++ b/libcelt/dump_modes.c @@ -92,9 +92,9 @@ void dump_modes(FILE *file, CELTMode **modes, int nb_modes) 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;jnbAllocVectors;j++) { int k; @@ -106,44 +106,43 @@ void dump_modes(FILE *file, CELTMode **modes, int nb_modes) 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;jnbEBands;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;kbits[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;jnbEBands;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"); 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 @@ void dump_modes(FILE *file, CELTMode **modes, int nb_modes) for (i=0;iFs, 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 @@ void dump_header(FILE *file, CELTMode **modes, int nb_modes) for (i=0;inbChannels; - 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 main(int argc, char **argv) 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;iversion_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; diff --git a/libcelt/modes.c b/libcelt/modes.c index 056d67aa..7c5508e5 100644 --- a/libcelt/modes.c +++ b/libcelt/modes.c @@ -65,9 +65,6 @@ int celt_mode_info(const CELTMode *mode, int request, celt_int32_t *value) 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 @@ static void compute_allocation_table(CELTMode *mode, int res) #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 @@ CELTMode *celt_mode_create(celt_int32_t Fs, int channels, int frame_size, int *e for (i=0;iFs && - channels == static_mode_list[i]->nbChannels && frame_size == static_mode_list[i]->mdctSize) { m = static_mode_list[i]; @@ -293,13 +289,6 @@ CELTMode *celt_mode_create(celt_int32_t Fs, int channels, int frame_size, int *e *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 @@ CELTMode *celt_mode_create(celt_int32_t Fs, int channels, int frame_size, int *e 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) diff --git a/libcelt/modes.h b/libcelt/modes.h index b6036b66..3a30c1a8 100644 --- a/libcelt/modes.h +++ b/libcelt/modes.h @@ -81,8 +81,7 @@ struct CELTMode { celt_int32_t Fs; int overlap; int mdctSize; - int nbChannels; - + int nbEBands; int pitchEnd; diff --git a/libcelt/testcelt.c b/libcelt/testcelt.c index d02c61d1..88d0608e 100644 --- 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 @@ int main(int argc, char *argv[]) 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 @@ int main(int argc, char *argv[]) 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 @@ int main(int argc, char *argv[]) } 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); diff --git a/tests/tandem-test.c b/tests/tandem-test.c index 77ea730b..50713c57 100644 --- a/tests/tandem-test.c +++ b/tests/tandem-test.c @@ -76,14 +76,14 @@ int async_tandem(int rate, int frame_size, int channels, int bitrate_min, 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; diff --git a/tools/celtdec.c b/tools/celtdec.c index be3da697..83edaddb 100644 --- a/tools/celtdec.c +++ b/tools/celtdec.c @@ -299,7 +299,7 @@ static CELTDecoder *process_header(ogg_packet *op, celt_int32_t enh_enabled, cel 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 @@ static CELTDecoder *process_header(ogg_packet *op, celt_int32_t enh_enabled, cel *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"); diff --git a/tools/celtenc.c b/tools/celtenc.c index e451c17f..cad89db3 100644 --- a/tools/celtenc.c +++ b/tools/celtenc.c @@ -490,7 +490,7 @@ int main(int argc, char **argv) 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 @@ int main(int argc, char **argv) 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 @@ int main(int argc, char **argv) } /*Initialize CELT encoder*/ - st = celt_encoder_create(mode); + st = celt_encoder_create(mode, chan, NULL); if (with_vbr) {