From d9e4b1d72c3cf5e6d3886b09b4a0387f3abf8ffe Mon Sep 17 00:00:00 2001 From: Jean-Marc Valin Date: Fri, 28 Jan 2011 22:24:40 -0500 Subject: [PATCH 1/5] Adding the auto-generated static modes for float and fixed --- libcelt/dump_modes.c | 4 +- libcelt/modes.h | 4 -- libcelt/static_modes_fixed.c | 128 +++++++++++++++++++++++++++++++++ libcelt/static_modes_float.c | 132 +++++++++++++++++++++++++++++++++++ 4 files changed, 262 insertions(+), 6 deletions(-) create mode 100644 libcelt/static_modes_fixed.c create mode 100644 libcelt/static_modes_float.c diff --git a/libcelt/dump_modes.c b/libcelt/dump_modes.c index 84b0b71a..b795b1ec 100644 --- a/libcelt/dump_modes.c +++ b/libcelt/dump_modes.c @@ -307,9 +307,9 @@ int main(int argc, char **argv) file = fopen(BASENAME ".c", "w"); dump_modes(file, m, nb); fclose(file); - file = fopen(BASENAME ".h", "w"); + /*file = fopen(BASENAME ".h", "w"); dump_header(file, m, nb); - fclose(file); + fclose(file);*/ for (i=0;i Date: Fri, 28 Jan 2011 22:42:09 -0500 Subject: [PATCH 2/5] Enabling the standard static mode by default --- libcelt/cwrs.c | 4 ++-- libcelt/kiss_fft.c | 4 ++-- libcelt/mdct.c | 4 ++-- libcelt/modes.c | 45 ++++++++++++++++++++++++++------------------- libcelt/rate.c | 4 ++-- libcelt/testcelt.c | 4 ++-- 6 files changed, 36 insertions(+), 29 deletions(-) diff --git a/libcelt/cwrs.c b/libcelt/cwrs.c index 843dcd51..452c4ea2 100644 --- a/libcelt/cwrs.c +++ b/libcelt/cwrs.c @@ -644,7 +644,7 @@ celt_uint32 icwrs(int _n,int _k,celt_uint32 *_nc,const int *_y, return i; } -#ifndef STATIC_MODES +#ifdef CUSTOM_MODES void get_required_bits(celt_int16 *_bits,int _n,int _maxk,int _frac){ int k; /*_maxk==0 => there's nothing to do.*/ @@ -665,7 +665,7 @@ void get_required_bits(celt_int16 *_bits,int _n,int _maxk,int _frac){ RESTORE_STACK; } } -#endif /* STATIC_MODES */ +#endif /* CUSTOM_MODES */ void encode_pulses(const int *_y,int _n,int _k,ec_enc *_enc){ celt_uint32 i; diff --git a/libcelt/kiss_fft.c b/libcelt/kiss_fft.c index 390456d5..ec18a69b 100644 --- a/libcelt/kiss_fft.c +++ b/libcelt/kiss_fft.c @@ -495,7 +495,7 @@ static void ki_work( } -#ifndef STATIC_MODES +#ifdef CUSTOM_MODES static void compute_bitrev_table( @@ -651,7 +651,7 @@ void kiss_fft_free(const kiss_fft_state *cfg) celt_free((kiss_fft_state*)cfg); } -#endif /* STATIC_MODES */ +#endif /* CUSTOM_MODES */ static void kiss_fft_stride(const kiss_fft_state *st,const kiss_fft_cpx *fin,kiss_fft_cpx *fout,int in_stride) { diff --git a/libcelt/mdct.c b/libcelt/mdct.c index daa9d6bf..9ca65cf9 100644 --- a/libcelt/mdct.c +++ b/libcelt/mdct.c @@ -61,7 +61,7 @@ #define M_PI 3.141592653 #endif -#ifndef STATIC_MODES +#ifdef CUSTOM_MODES void clt_mdct_init(mdct_lookup *l,int N, int maxshift) { @@ -104,7 +104,7 @@ void clt_mdct_clear(mdct_lookup *l) celt_free((kiss_twiddle_scalar*)l->trig); } -#endif /* STATIC_MODES */ +#endif /* CUSTOM_MODES */ void clt_mdct_forward(const mdct_lookup *l, kiss_fft_scalar *in, kiss_fft_scalar * restrict out, const celt_word16 *window, int overlap, int shift) { diff --git a/libcelt/modes.c b/libcelt/modes.c index 5f801ccc..35985b66 100644 --- a/libcelt/modes.c +++ b/libcelt/modes.c @@ -85,13 +85,11 @@ static const unsigned char band_allocation[] = { }; #endif -#ifdef STATIC_MODES #ifdef FIXED_POINT #include "static_modes_fixed.c" #else #include "static_modes_float.c" #endif -#endif #ifndef M_PI #define M_PI 3.141592653 @@ -117,7 +115,7 @@ int celt_mode_info(const CELTMode *mode, int request, celt_int32 *value) return CELT_OK; } -#ifndef STATIC_MODES +#ifdef CUSTOM_MODES /* Defining 25 critical bands for the full 0-20 kHz audio bandwidth Taken from http://ccrma.stanford.edu/~jos/bbt/Bark_Frequency_Scale.html */ @@ -253,24 +251,11 @@ static void compute_allocation_table(CELTMode *mode) mode->allocVectors = allocVectors; } -#endif /* STATIC_MODES */ +#endif /* CUSTOM_MODES */ CELTMode *celt_mode_create(celt_int32 Fs, int frame_size, int *error) { int i; -#ifdef STATIC_MODES - for (i=0;iFs && - frame_size == static_mode_list[i]->shortMdctSize*static_mode_list[i]->nbShortMdcts) - { - return (CELTMode*)static_mode_list[i]; - } - } - if (error) - *error = CELT_BAD_ARG; - return NULL; -#else int res; CELTMode *mode=NULL; celt_word16 *window; @@ -291,6 +276,20 @@ CELTMode *celt_mode_create(celt_int32 Fs, int frame_size, int *error) goto failure; #endif + for (i=0;iFs && + frame_size == static_mode_list[i]->shortMdctSize*static_mode_list[i]->nbShortMdcts) + { + return (CELTMode*)static_mode_list[i]; + } + } +#ifndef CUSTOM_MODES + if (error) + *error = CELT_BAD_ARG; + return NULL; +#else + /* The good thing here is that permutation of the arguments will automatically be invalid */ if (Fs < 8000 || Fs > 96000) @@ -415,14 +414,22 @@ failure: if (mode!=NULL) celt_mode_destroy(mode); return NULL; -#endif /* !STATIC_MODES */ +#endif /* !CUSTOM_MODES */ } void celt_mode_destroy(CELTMode *mode) { -#ifndef STATIC_MODES +#ifdef CUSTOM_MODES + int i; if (mode == NULL) return; + for (i=0;ieBands); celt_free((celt_int16*)mode->allocVectors); diff --git a/libcelt/rate.c b/libcelt/rate.c index 63cfd22a..c0c4ca76 100644 --- a/libcelt/rate.c +++ b/libcelt/rate.c @@ -52,7 +52,7 @@ static const unsigned char LOG2_FRAC_TABLE[24]={ 32,33,34,34,35,36,36,37,37 }; -#ifndef STATIC_MODES +#ifdef CUSTOM_MODES /*Determines if V(N,K) fits in a 32-bit unsigned integer. N and K are themselves limited to 15 bits.*/ @@ -143,7 +143,7 @@ void compute_pulse_cache(CELTMode *m, int LM) } } -#endif /* !STATIC_MODES */ +#endif /* !CUSTOM_MODES */ #define ALLOC_STEPS 6 diff --git a/libcelt/testcelt.c b/libcelt/testcelt.c index 187ea1a7..d14272f6 100644 --- a/libcelt/testcelt.c +++ b/libcelt/testcelt.c @@ -57,7 +57,7 @@ int main(int argc, char *argv[]) unsigned char data[MAX_PACKET]; int rate; int complexity; -#if !(defined (FIXED_POINT) && defined(STATIC_MODES)) +#if !(defined (FIXED_POINT) && !defined(CUSTOM_MODES)) int i; double rmsd = 0; #endif @@ -174,7 +174,7 @@ int main(int argc, char *argv[]) for (i=0;i Date: Fri, 28 Jan 2011 23:07:32 -0500 Subject: [PATCH 3/5] celt_encoder_create() now defaults to Opus standard mode The old constructor is renamed celt_encoder_create_custom(). Same for the decoder. --- libcelt/celt.c | 34 ++++++++++++++++++++++++++++++---- libcelt/celt.h | 30 ++++++++++++++++++++++++++---- libcelt/modes.c | 12 +++++++++--- libcelt/testcelt.c | 4 ++-- tests/tandem-test.c | 17 ++++++++++++++--- tools/celtdec.c | 2 +- tools/celtenc.c | 2 +- 7 files changed, 83 insertions(+), 18 deletions(-) diff --git a/libcelt/celt.c b/libcelt/celt.c index b8283845..66bf4018 100644 --- a/libcelt/celt.c +++ b/libcelt/celt.c @@ -127,14 +127,27 @@ int celt_encoder_get_size(const CELTMode *mode, int channels) return size; } -CELTEncoder *celt_encoder_create(const CELTMode *mode, int channels, int *error) +CELTEncoder *celt_encoder_create(int channels, int *error) { + CELTMode *mode = celt_mode_create(48000, 960, NULL); return celt_encoder_init( + (CELTEncoder *)celt_alloc(celt_encoder_get_size(mode, channels)), + channels, error); +} + +CELTEncoder *celt_encoder_create_custom(const CELTMode *mode, int channels, int *error) +{ + return celt_encoder_init_custom( (CELTEncoder *)celt_alloc(celt_encoder_get_size(mode, channels)), mode, channels, error); } -CELTEncoder *celt_encoder_init(CELTEncoder *st, const CELTMode *mode, int channels, int *error) +CELTEncoder *celt_encoder_init(CELTEncoder *st, int channels, int *error) +{ + return celt_encoder_init_custom(st, celt_mode_create(48000, 960, NULL), channels, error); +} + +CELTEncoder *celt_encoder_init_custom(CELTEncoder *st, const CELTMode *mode, int channels, int *error) { if (channels < 0 || channels > 2) { @@ -1672,14 +1685,27 @@ int celt_decoder_get_size(const CELTMode *mode, int channels) return size; } -CELTDecoder *celt_decoder_create(const CELTMode *mode, int channels, int *error) +CELTDecoder *celt_decoder_create(int channels, int *error) { + const CELTMode *mode = celt_mode_create(48000, 960, NULL); return celt_decoder_init( + (CELTDecoder *)celt_alloc(celt_decoder_get_size(mode, channels)), + channels, error); +} + +CELTDecoder *celt_decoder_create_custom(const CELTMode *mode, int channels, int *error) +{ + return celt_decoder_init_custom( (CELTDecoder *)celt_alloc(celt_decoder_get_size(mode, channels)), mode, channels, error); } -CELTDecoder *celt_decoder_init(CELTDecoder *st, const CELTMode *mode, int channels, int *error) +CELTDecoder *celt_decoder_init(CELTDecoder *st, int channels, int *error) +{ + return celt_decoder_init_custom(st, celt_mode_create(48000, 960, NULL), channels, error); +} + +CELTDecoder *celt_decoder_init_custom(CELTDecoder *st, const CELTMode *mode, int channels, int *error) { if (channels < 0 || channels > 2) { diff --git a/libcelt/celt.h b/libcelt/celt.h index fddef5aa..a8270d31 100644 --- a/libcelt/celt.h +++ b/libcelt/celt.h @@ -163,6 +163,14 @@ EXPORT int celt_encoder_get_size(const CELTMode *mode, int channels); /** Creates a new encoder state. Each stream needs its own encoder state (can't be shared across simultaneous streams). + @param channels Number of channels + @param error Returns an error code + @return Newly created encoder state. +*/ +EXPORT CELTEncoder *celt_encoder_create(int channels, int *error); + +/** Creates a new encoder state. Each stream needs its own encoder + state (can't be shared across simultaneous streams). @param mode Contains all the information about the characteristics of * the stream (must be the same characteristics as used for the * decoder) @@ -170,9 +178,11 @@ EXPORT int celt_encoder_get_size(const CELTMode *mode, int channels); @param error Returns an error code @return Newly created encoder state. */ -EXPORT CELTEncoder *celt_encoder_create(const CELTMode *mode, int channels, int *error); +EXPORT CELTEncoder *celt_encoder_create_custom(const CELTMode *mode, int channels, int *error); -EXPORT CELTEncoder *celt_encoder_init(CELTEncoder *st, const CELTMode *mode, int channels, int *error); +EXPORT CELTEncoder *celt_encoder_init(CELTEncoder *st, int channels, int *error); + +EXPORT CELTEncoder *celt_encoder_init_custom(CELTEncoder *st, const CELTMode *mode, int channels, int *error); /** Destroys a an encoder state. @param st Encoder state to be destroyed @@ -235,9 +245,21 @@ EXPORT int celt_decoder_get_size(const CELTMode *mode, int channels); @param error Returns an error code @return Newly created decoder state. */ -EXPORT CELTDecoder *celt_decoder_create(const CELTMode *mode, int channels, int *error); +EXPORT CELTDecoder *celt_decoder_create(int channels, int *error); -EXPORT CELTDecoder *celt_decoder_init(CELTDecoder *st, const CELTMode *mode, int channels, int *error); +/** Creates a new decoder state. Each stream needs its own decoder state (can't + be shared across simultaneous streams). + @param mode Contains all the information about the characteristics of the + stream (must be the same characteristics as used for the encoder) + @param channels Number of channels + @param error Returns an error code + @return Newly created decoder state. + */ +EXPORT CELTDecoder *celt_decoder_create_custom(const CELTMode *mode, int channels, int *error); + +EXPORT CELTDecoder *celt_decoder_init(CELTDecoder *st, int channels, int *error); + +EXPORT CELTDecoder *celt_decoder_init_custom(CELTDecoder *st, const CELTMode *mode, int channels, int *error); /** Destroys a a decoder state. @param st Decoder state to be destroyed diff --git a/libcelt/modes.c b/libcelt/modes.c index 35985b66..3f59284b 100644 --- a/libcelt/modes.c +++ b/libcelt/modes.c @@ -278,10 +278,16 @@ CELTMode *celt_mode_create(celt_int32 Fs, int frame_size, int *error) for (i=0;iFs && - frame_size == static_mode_list[i]->shortMdctSize*static_mode_list[i]->nbShortMdcts) + int j; + for (j=0;j<4;j++) { - return (CELTMode*)static_mode_list[i]; + if (Fs == static_mode_list[i]->Fs && + (frame_size<shortMdctSize*static_mode_list[i]->nbShortMdcts) + { + if (error) + *error = CELT_OK; + return (CELTMode*)static_mode_list[i]; + } } } #ifndef CUSTOM_MODES diff --git a/libcelt/testcelt.c b/libcelt/testcelt.c index d14272f6..4c45868c 100644 --- a/libcelt/testcelt.c +++ b/libcelt/testcelt.c @@ -107,13 +107,13 @@ int main(int argc, char *argv[]) return 1; } - enc = celt_encoder_create(mode, channels, &err); + enc = celt_encoder_create_custom(mode, channels, &err); if (err != 0) { fprintf(stderr, "Failed to create the encoder: %s\n", celt_strerror(err)); return 1; } - dec = celt_decoder_create(mode, channels, &err); + dec = celt_decoder_create_custom(mode, channels, &err); if (err != 0) { fprintf(stderr, "Failed to create the decoder: %s\n", celt_strerror(err)); diff --git a/tests/tandem-test.c b/tests/tandem-test.c index e1f21baf..e45f8f2c 100644 --- a/tests/tandem-test.c +++ b/tests/tandem-test.c @@ -85,12 +85,12 @@ int async_tandem(int rate, int frame_size, int channels, int bitrate_min, exit(1); } - dec = celt_decoder_create(mode, channels, &error); + dec = celt_decoder_create_custom(mode, channels, &error); if (error){ fprintf(stderr, "Error: celt_decoder_create returned %s\n", celt_strerror(error)); exit(1); } - enc = celt_encoder_create(mode, channels, &error); + enc = celt_encoder_create_custom(mode, channels, &error); if (error){ fprintf(stderr, "Error: celt_encoder_create returned %s\n", celt_strerror(error)); exit(1); @@ -167,7 +167,11 @@ int async_tandem(int rate, int frame_size, int channels, int bitrate_min, int main(int argc, char *argv[]) { +#ifdef CUSTOM_MODES int sizes[8]={960,480,240,120,512,256,128,64}; +#else + int sizes[4]={960,480,240,120}; +#endif unsigned int seed; int ch, n; @@ -184,6 +188,7 @@ int main(int argc, char *argv[]) srand(seed); printf("CELT codec tests. Random seed: %u (%.4X)\n", seed, rand() % 65536); +#ifdef CUSTOM_MODES for (n = 0; n < 8; n++) { for (ch = 1; ch <= 2; ch++) { async_tandem(48000, sizes[n], ch, 12000 * ch, 128000 * ch); @@ -192,6 +197,12 @@ int main(int argc, char *argv[]) async_tandem(16000, sizes[n], ch, 12000 * ch, 64000 * ch); } } - +#else + for (n = 0; n < 4; n++) { + for (ch = 1; ch <= 2; ch++) { + async_tandem(48000, sizes[n], ch, 12000 * ch, 128000 * ch); + } + } +#endif return 0; } diff --git a/tools/celtdec.c b/tools/celtdec.c index 23e1e1e3..c26fa686 100644 --- a/tools/celtdec.c +++ b/tools/celtdec.c @@ -315,7 +315,7 @@ static CELTDecoder *process_header(ogg_packet *op, celt_int32 enh_enabled, celt_ *channels = header.nb_channels; *overlap=header.overlap; - st = celt_decoder_create(*mode, header.nb_channels, NULL); + st = celt_decoder_create_custom(*mode, header.nb_channels, NULL); if (!st) { fprintf (stderr, "Decoder initialization failed.\n"); diff --git a/tools/celtenc.c b/tools/celtenc.c index 65d93116..458fe6fa 100644 --- a/tools/celtenc.c +++ b/tools/celtenc.c @@ -525,7 +525,7 @@ int main(int argc, char **argv) } /*Initialize CELT encoder*/ - st = celt_encoder_create(mode, chan, NULL); + st = celt_encoder_create_custom(mode, chan, NULL); if (!with_cbr) { From 913a1742b960b8cb705132d1ebfcf0718bb994e7 Mon Sep 17 00:00:00 2001 From: Jean-Marc Valin Date: Sat, 29 Jan 2011 10:00:20 -0500 Subject: [PATCH 4/5] Adding resampling support We use the MDCT as low-pass filter. --- libcelt/celt.c | 118 +++++++++++++++++++++++++++++++++++++++++-------- libcelt/celt.h | 8 ++-- 2 files changed, 103 insertions(+), 23 deletions(-) diff --git a/libcelt/celt.c b/libcelt/celt.c index 66bf4018..58d53eb1 100644 --- a/libcelt/celt.c +++ b/libcelt/celt.c @@ -63,6 +63,32 @@ static const unsigned char tapset_icdf[3]={2,1,0}; #define COMBFILTER_MAXPERIOD 1024 #define COMBFILTER_MINPERIOD 15 +static int resampling_factor(celt_int32 rate) +{ + int ret; + switch (rate) + { + case 48000: + ret = 1; + break; + case 24000: + ret = 2; + break; + case 16000: + ret = 3; + break; + case 12000: + ret = 4; + break; + case 8000: + ret = 6; + break; + default: + ret = 0; + } + return ret; +} + /** Encoder state @brief Encoder state */ @@ -73,6 +99,7 @@ struct CELTEncoder { int force_intra; int complexity; + int upsample; int start, end; celt_int32 vbr_rate_norm; /* Target number of 8th bits per frame */ @@ -127,12 +154,13 @@ int celt_encoder_get_size(const CELTMode *mode, int channels) return size; } -CELTEncoder *celt_encoder_create(int channels, int *error) +CELTEncoder *celt_encoder_create(int sampling_rate, int channels, int *error) { CELTMode *mode = celt_mode_create(48000, 960, NULL); - return celt_encoder_init( + CELTEncoder *st = celt_encoder_init( (CELTEncoder *)celt_alloc(celt_encoder_get_size(mode, channels)), - channels, error); + sampling_rate, channels, error); + return st; } CELTEncoder *celt_encoder_create_custom(const CELTMode *mode, int channels, int *error) @@ -142,9 +170,17 @@ CELTEncoder *celt_encoder_create_custom(const CELTMode *mode, int channels, int mode, channels, error); } -CELTEncoder *celt_encoder_init(CELTEncoder *st, int channels, int *error) +CELTEncoder *celt_encoder_init(CELTEncoder *st, int sampling_rate, int channels, int *error) { - return celt_encoder_init_custom(st, celt_mode_create(48000, 960, NULL), channels, error); + celt_encoder_init_custom(st, celt_mode_create(48000, 960, NULL), channels, error); + st->upsample = resampling_factor(sampling_rate); + if (st->upsample==0) + { + if (error) + *error = CELT_BAD_ARG; + return NULL; + } + return st; } CELTEncoder *celt_encoder_init_custom(CELTEncoder *st, const CELTMode *mode, int channels, int *error) @@ -169,6 +205,7 @@ CELTEncoder *celt_encoder_init_custom(CELTEncoder *st, const CELTMode *mode, int st->overlap = mode->overlap; st->channels = channels; + st->upsample = 1; st->start = 0; st->end = st->mode->effEBands; st->constrained_vbr = 1; @@ -385,10 +422,11 @@ static void compute_inv_mdcts(const CELTMode *mode, int shortBlocks, celt_sig *X } while (++cupsample; for (LM=0;LM<4;LM++) if (st->mode->shortMdctSize<overlap)+st->overlap; for (i=0;iupsample) + { + count=0; + pcmp+=C; + } else { + x = 0; + } /* Apply pre-emphasis */ - celt_sig tmp = MULT16_16(st->mode->preemph[2], SCALEIN(*pcmp)); + tmp = MULT16_16(st->mode->preemph[2], x); *inp = tmp + st->preemph_memE[c]; st->preemph_memE[c] = MULT16_32_Q15(st->mode->preemph[1], *inp) - MULT16_32_Q15(st->mode->preemph[0], tmp); silence = silence && *inp == 0; inp++; - pcmp+=C; } CELT_COPY(pre[c], prefilter_mem+c*COMBFILTER_MAXPERIOD, COMBFILTER_MAXPERIOD); CELT_COPY(pre[c]+COMBFILTER_MAXPERIOD, in+c*(N+st->overlap)+st->overlap, N); @@ -1082,6 +1137,17 @@ int celt_encode_with_ec_float(CELTEncoder * restrict st, const celt_sig * pcm, i /* Compute MDCTs */ compute_mdcts(st->mode, shortBlocks, in, freq, C, LM); + if (st->upsample != 1) + { + c=0; do + { + int bound = N/st->upsample; + for (i=0;iupsample; + for (;imode, freq, bandE, effEnd, C, M); @@ -1412,7 +1478,7 @@ int celt_encode_with_ec_float(CELTEncoder * restrict st, const celt_sig * pcm, i } while (++cmode->preemph, st->preemph_memD); + deemphasis(out_mem, (celt_word16*)pcm, N, C, st->upsample, st->mode->preemph, st->preemph_memD); st->prefilter_period_old = st->prefilter_period; st->prefilter_gain_old = st->prefilter_gain; st->prefilter_tapset_old = st->prefilter_tapset; @@ -1651,6 +1717,7 @@ struct CELTDecoder { int overlap; int channels; + int downsample; int start, end; /* Everything beyond this point gets cleared on a reset */ @@ -1685,12 +1752,12 @@ int celt_decoder_get_size(const CELTMode *mode, int channels) return size; } -CELTDecoder *celt_decoder_create(int channels, int *error) +CELTDecoder *celt_decoder_create(int sampling_rate, int channels, int *error) { const CELTMode *mode = celt_mode_create(48000, 960, NULL); return celt_decoder_init( (CELTDecoder *)celt_alloc(celt_decoder_get_size(mode, channels)), - channels, error); + sampling_rate, channels, error); } CELTDecoder *celt_decoder_create_custom(const CELTMode *mode, int channels, int *error) @@ -1700,9 +1767,17 @@ CELTDecoder *celt_decoder_create_custom(const CELTMode *mode, int channels, int mode, channels, error); } -CELTDecoder *celt_decoder_init(CELTDecoder *st, int channels, int *error) +CELTDecoder *celt_decoder_init(CELTDecoder *st, int sampling_rate, int channels, int *error) { - return celt_decoder_init_custom(st, celt_mode_create(48000, 960, NULL), channels, error); + celt_decoder_init_custom(st, celt_mode_create(48000, 960, NULL), channels, error); + st->downsample = resampling_factor(sampling_rate); + if (st->downsample==0) + { + if (error) + *error = CELT_BAD_ARG; + return NULL; + } + return st; } CELTDecoder *celt_decoder_init_custom(CELTDecoder *st, const CELTMode *mode, int channels, int *error) @@ -1727,6 +1802,7 @@ CELTDecoder *celt_decoder_init_custom(CELTDecoder *st, const CELTMode *mode, int st->overlap = mode->overlap; st->channels = channels; + st->downsample = 1; st->start = 0; st->end = st->mode->effEBands; @@ -1955,7 +2031,7 @@ static void celt_decode_lost(CELTDecoder * restrict st, celt_word16 * restrict p out_mem[c][MAX_PERIOD+i] = e[i]; } while (++cmode->preemph, st->preemph_memD); + deemphasis(out_syn, pcm, N, C, st->downsample, st->mode->preemph, st->preemph_memD); st->loss_count++; @@ -2015,6 +2091,7 @@ int celt_decode_with_ec_float(CELTDecoder * restrict st, const unsigned char *da if (pcm==NULL) return CELT_BAD_ARG; + frame_size *= st->downsample; for (LM=0;LM<4;LM++) if (st->mode->shortMdctSize<mode->eBands[st->start];i++) freq[c*N+i] = 0; while (++cmode->eBands[effEnd]; + if (st->downsample!=1) + bound = IMIN(bound, N/st->downsample); for (i=M*st->mode->eBands[effEnd];irng = dec->rng; - deemphasis(out_syn, pcm, N, C, st->mode->preemph, st->preemph_memD); + deemphasis(out_syn, pcm, N, C, st->downsample, st->mode->preemph, st->preemph_memD); st->loss_count = 0; RESTORE_STACK; if (ec_dec_tell(dec,0) > 8*len || ec_dec_get_error(dec)) diff --git a/libcelt/celt.h b/libcelt/celt.h index a8270d31..ba1318f0 100644 --- a/libcelt/celt.h +++ b/libcelt/celt.h @@ -167,7 +167,7 @@ EXPORT int celt_encoder_get_size(const CELTMode *mode, int channels); @param error Returns an error code @return Newly created encoder state. */ -EXPORT CELTEncoder *celt_encoder_create(int channels, int *error); +EXPORT CELTEncoder *celt_encoder_create(int sampling_rate, int channels, int *error); /** Creates a new encoder state. Each stream needs its own encoder state (can't be shared across simultaneous streams). @@ -180,7 +180,7 @@ EXPORT CELTEncoder *celt_encoder_create(int channels, int *error); */ EXPORT CELTEncoder *celt_encoder_create_custom(const CELTMode *mode, int channels, int *error); -EXPORT CELTEncoder *celt_encoder_init(CELTEncoder *st, int channels, int *error); +EXPORT CELTEncoder *celt_encoder_init(CELTEncoder *st, int sampling_rate, int channels, int *error); EXPORT CELTEncoder *celt_encoder_init_custom(CELTEncoder *st, const CELTMode *mode, int channels, int *error); @@ -245,7 +245,7 @@ EXPORT int celt_decoder_get_size(const CELTMode *mode, int channels); @param error Returns an error code @return Newly created decoder state. */ -EXPORT CELTDecoder *celt_decoder_create(int channels, int *error); +EXPORT CELTDecoder *celt_decoder_create(int sampling_rate, int channels, int *error); /** Creates a new decoder state. Each stream needs its own decoder state (can't be shared across simultaneous streams). @@ -257,7 +257,7 @@ EXPORT CELTDecoder *celt_decoder_create(int channels, int *error); */ EXPORT CELTDecoder *celt_decoder_create_custom(const CELTMode *mode, int channels, int *error); -EXPORT CELTDecoder *celt_decoder_init(CELTDecoder *st, int channels, int *error); +EXPORT CELTDecoder *celt_decoder_init(CELTDecoder *st, int sampling_rate, int channels, int *error); EXPORT CELTDecoder *celt_decoder_init_custom(CELTDecoder *st, const CELTMode *mode, int channels, int *error); From d6c3d3ceaeaa2909619866c33b72655cc4f48e66 Mon Sep 17 00:00:00 2001 From: Jean-Marc Valin Date: Sun, 30 Jan 2011 10:23:40 -0500 Subject: [PATCH 5/5] Error handling in _create() functions --- libcelt/celt.c | 43 ++++++++++++++++++++++++++++++------------- 1 file changed, 30 insertions(+), 13 deletions(-) diff --git a/libcelt/celt.c b/libcelt/celt.c index 58d53eb1..e82dafca 100644 --- a/libcelt/celt.c +++ b/libcelt/celt.c @@ -156,18 +156,26 @@ int celt_encoder_get_size(const CELTMode *mode, int channels) CELTEncoder *celt_encoder_create(int sampling_rate, int channels, int *error) { + CELTEncoder *st; CELTMode *mode = celt_mode_create(48000, 960, NULL); - CELTEncoder *st = celt_encoder_init( - (CELTEncoder *)celt_alloc(celt_encoder_get_size(mode, channels)), - sampling_rate, channels, error); + st = (CELTEncoder *)celt_alloc(celt_encoder_get_size(mode, channels)); + if (st!=NULL && celt_encoder_init(st, sampling_rate, channels, error)==NULL) + { + celt_encoder_destroy(st); + st = NULL; + } return st; } CELTEncoder *celt_encoder_create_custom(const CELTMode *mode, int channels, int *error) { - return celt_encoder_init_custom( - (CELTEncoder *)celt_alloc(celt_encoder_get_size(mode, channels)), - mode, channels, error); + CELTEncoder *st = (CELTEncoder *)celt_alloc(celt_encoder_get_size(mode, channels)); + if (st!=NULL && celt_encoder_init_custom(st, mode, channels, error)==NULL) + { + celt_encoder_destroy(st); + st = NULL; + } + return st; } CELTEncoder *celt_encoder_init(CELTEncoder *st, int sampling_rate, int channels, int *error) @@ -192,7 +200,7 @@ CELTEncoder *celt_encoder_init_custom(CELTEncoder *st, const CELTMode *mode, int return NULL; } - if (st==NULL) + if (st==NULL || mode==NULL) { if (error) *error = CELT_ALLOC_FAIL; @@ -1754,17 +1762,26 @@ int celt_decoder_get_size(const CELTMode *mode, int channels) CELTDecoder *celt_decoder_create(int sampling_rate, int channels, int *error) { + CELTDecoder *st; const CELTMode *mode = celt_mode_create(48000, 960, NULL); - return celt_decoder_init( - (CELTDecoder *)celt_alloc(celt_decoder_get_size(mode, channels)), - sampling_rate, channels, error); + st = (CELTDecoder *)celt_alloc(celt_decoder_get_size(mode, channels)); + if (st!=NULL && celt_decoder_init(st, sampling_rate, channels, error)==NULL) + { + celt_decoder_destroy(st); + st = NULL; + } + return st; } CELTDecoder *celt_decoder_create_custom(const CELTMode *mode, int channels, int *error) { - return celt_decoder_init_custom( - (CELTDecoder *)celt_alloc(celt_decoder_get_size(mode, channels)), - mode, channels, error); + CELTDecoder *st = (CELTDecoder *)celt_alloc(celt_decoder_get_size(mode, channels)); + if (st!=NULL && celt_decoder_init_custom(st, mode, channels, error)==NULL) + { + celt_decoder_destroy(st); + st = NULL; + } + return st; } CELTDecoder *celt_decoder_init(CELTDecoder *st, int sampling_rate, int channels, int *error)