diff --git a/Makefile.am b/Makefile.am index 67e8d256c7933eb95cd2dd52f4bed19bdfe48c1d..10e9c30426502410a59bbe5ff390ad328cf6720c 100644 --- a/Makefile.am +++ b/Makefile.am @@ -36,6 +36,13 @@ test_repacketizer_SOURCES = src/test_repacketizer.c test_repacketizer_LDADD = libopus.la -lm +if CUSTOM_MODES +pkginclude_HEADERS += libcelt/opus_custom.h +noinst_PROGRAMS += test_opus_custom +test_opus_custom_SOURCES = libcelt/test_opus_custom.c +test_opus_custom_LDADD = libopus.la -lm +endif + EXTRA_DIST = opus.pc.in opus-uninstalled.pc.in pkgconfigdir = $(libdir)/pkgconfig diff --git a/configure.ac b/configure.ac index 55a390729b510e3ca455b6a009a2d67afe15df3e..4f1982bed661c5f12ea823e2b486be6d1a9ec613 100644 --- a/configure.ac +++ b/configure.ac @@ -206,6 +206,7 @@ AC_DEFINE(OPUS_BUILD, [], [We're part of Opus]) fi AM_CONDITIONAL([FIXED_POINT], [test x$ac_enable_fixed = xyes]) +AM_CONDITIONAL([CUSTOM_MODES], [test x$ac_enable_custom_modes = xyes]) AC_OUTPUT([Makefile libcelt/Makefile opus.pc opus-uninstalled.pc]) diff --git a/doc/build_draft.sh b/doc/build_draft.sh index f5b1da10740324a3866c48222223a398df1fc301..276ef5abcd1cf29b4c9c6611ec82199358697350 100755 --- a/doc/build_draft.sh +++ b/doc/build_draft.sh @@ -23,8 +23,8 @@ for f in `cat "${toplevel}"/opus_sources.mk "${toplevel}"/celt_sources.mk \ cp -a "${toplevel}/${f}" "${destdir}/${f}" done cp -a "${toplevel}"/src/test_opus.c "${destdir}"/src/ -cp -a "${toplevel}"/src/test_opus_custom.c "${destdir}"/src/ -cp -a "${toplevel}"/src/opus_custom.h "${destdir}"/src/ +cp -a "${toplevel}"/libcelt/test_opus_custom.c "${destdir}"/libcelt/ +cp -a "${toplevel}"/libcelt/opus_custom.h "${destdir}"/libcelt/ cp -a "${toplevel}"/Makefile.draft "${destdir}"/Makefile cp -a "${toplevel}"/opus_sources.mk "${destdir}"/ cp -a "${toplevel}"/celt_sources.mk "${destdir}"/ diff --git a/libcelt/celt.c b/libcelt/celt.c index 19d020e674ed3442d17a5653b06c80dd67a5e3b8..00a775fdcea60cfbc3f1f7aa662964c199b09abf 100644 --- a/libcelt/celt.c +++ b/libcelt/celt.c @@ -184,11 +184,11 @@ struct CELTEncoder { int celt_encoder_get_size(int channels) { - CELTMode *mode = celt_mode_create(48000, 960, NULL); - return celt_encoder_get_size_custom(mode, channels); + CELTMode *mode = opus_custom_mode_create(48000, 960, NULL); + return opus_custom_encoder_get_size(mode, channels); } -int celt_encoder_get_size_custom(const CELTMode *mode, int channels) +int opus_custom_encoder_get_size(const CELTMode *mode, int channels) { int size = sizeof(struct CELTEncoder) + (2*channels*mode->overlap-1)*sizeof(celt_sig) @@ -197,26 +197,28 @@ int celt_encoder_get_size_custom(const CELTMode *mode, int channels) return size; } -CELTEncoder *celt_encoder_create_custom(const CELTMode *mode, int channels, int *error) +#ifdef CUSTOM_MODES +CELTEncoder *opus_custom_encoder_create(const CELTMode *mode, int channels, int *error) { int ret; - CELTEncoder *st = (CELTEncoder *)opus_alloc(celt_encoder_get_size_custom(mode, channels)); + CELTEncoder *st = (CELTEncoder *)opus_alloc(opus_custom_encoder_get_size(mode, channels)); /* init will handle the NULL case */ - ret = celt_encoder_init_custom(st, mode, channels); + ret = opus_custom_encoder_init(st, mode, channels); if (ret != OPUS_OK) { - celt_encoder_destroy(st); + opus_custom_encoder_destroy(st); st = NULL; - if (error) - *error = ret; } + if (error) + *error = ret; return st; } +#endif /* CUSTOM_MODES */ int celt_encoder_init(CELTEncoder *st, int sampling_rate, int channels) { int ret; - ret = celt_encoder_init_custom(st, celt_mode_create(48000, 960, NULL), channels); + ret = opus_custom_encoder_init(st, opus_custom_mode_create(48000, 960, NULL), channels); if (ret != OPUS_OK) return ret; st->upsample = resampling_factor(sampling_rate); @@ -226,7 +228,7 @@ int celt_encoder_init(CELTEncoder *st, int sampling_rate, int channels) return OPUS_OK; } -int celt_encoder_init_custom(CELTEncoder *st, const CELTMode *mode, int channels) +int opus_custom_encoder_init(CELTEncoder *st, const CELTMode *mode, int channels) { if (channels < 0 || channels > 2) return OPUS_BAD_ARG; @@ -234,7 +236,7 @@ int celt_encoder_init_custom(CELTEncoder *st, const CELTMode *mode, int channels if (st==NULL || mode==NULL) return OPUS_ALLOC_FAIL; - OPUS_CLEAR((char*)st, celt_encoder_get_size_custom(mode, channels)); + OPUS_CLEAR((char*)st, opus_custom_encoder_get_size(mode, channels)); st->mode = mode; st->overlap = mode->overlap; @@ -262,10 +264,12 @@ int celt_encoder_init_custom(CELTEncoder *st, const CELTMode *mode, int channels return OPUS_OK; } -void celt_encoder_destroy(CELTEncoder *st) +#ifdef CUSTOM_MODES +void opus_custom_encoder_destroy(CELTEncoder *st) { opus_free(st); } +#endif /* CUSTOM_MODES */ static inline opus_val16 SIG2WORD16(celt_sig x) { @@ -1647,15 +1651,16 @@ int celt_encode_with_ec(CELTEncoder * restrict st, const opus_val16 * pcm, int f } +#ifdef CUSTOM_MODES #ifdef FIXED_POINT -int celt_encode(CELTEncoder * restrict st, const opus_int16 * pcm, int frame_size, unsigned char *compressed, int nbCompressedBytes) +int opus_custom_encode(CELTEncoder * restrict st, const opus_int16 * pcm, int frame_size, unsigned char *compressed, int nbCompressedBytes) { return celt_encode_with_ec(st, pcm, frame_size, compressed, nbCompressedBytes, NULL); } #ifndef DISABLE_FLOAT_API -int celt_encode_float(CELTEncoder * restrict st, const float * pcm, int frame_size, unsigned char *compressed, int nbCompressedBytes) +int opus_custom_encode_float(CELTEncoder * restrict st, const float * pcm, int frame_size, unsigned char *compressed, int nbCompressedBytes) { int j, ret, C, N; VARDECL(opus_int16, in); @@ -1682,7 +1687,7 @@ int celt_encode_float(CELTEncoder * restrict st, const float * pcm, int frame_si #endif /* DISABLE_FLOAT_API */ #else -int celt_encode(CELTEncoder * restrict st, const opus_int16 * pcm, int frame_size, unsigned char *compressed, int nbCompressedBytes) +int opus_custom_encode(CELTEncoder * restrict st, const opus_int16 * pcm, int frame_size, unsigned char *compressed, int nbCompressedBytes) { int j, ret, C, N; VARDECL(celt_sig, in); @@ -1707,14 +1712,16 @@ int celt_encode(CELTEncoder * restrict st, const opus_int16 * pcm, int frame_siz return ret; } -int celt_encode_float(CELTEncoder * restrict st, const float * pcm, int frame_size, unsigned char *compressed, int nbCompressedBytes) +int opus_custom_encode_float(CELTEncoder * restrict st, const float * pcm, int frame_size, unsigned char *compressed, int nbCompressedBytes) { return celt_encode_with_ec(st, pcm, frame_size, compressed, nbCompressedBytes, NULL); } - #endif -int celt_encoder_ctl(CELTEncoder * restrict st, int request, ...) + +#endif /* CUSTOM_MODES */ + +int opus_custom_encoder_ctl(CELTEncoder * restrict st, int request, ...) { va_list ap; @@ -1794,7 +1801,7 @@ int celt_encoder_ctl(CELTEncoder * restrict st, int request, ...) case OPUS_RESET_STATE: { OPUS_CLEAR((char*)&st->ENCODER_RESET_START, - celt_encoder_get_size_custom(st->mode, st->channels)- + opus_custom_encoder_get_size(st->mode, st->channels)- ((char*)&st->ENCODER_RESET_START - (char*)st)); st->vbr_offset = 0; st->delayedIntra = 1; @@ -1891,11 +1898,11 @@ struct CELTDecoder { int celt_decoder_get_size(int channels) { - const CELTMode *mode = celt_mode_create(48000, 960, NULL); - return celt_decoder_get_size_custom(mode, channels); + const CELTMode *mode = opus_custom_mode_create(48000, 960, NULL); + return opus_custom_decoder_get_size(mode, channels); } -int celt_decoder_get_size_custom(const CELTMode *mode, int channels) +int opus_custom_decoder_get_size(const CELTMode *mode, int channels) { int size = sizeof(struct CELTDecoder) + (channels*(DECODE_BUFFER_SIZE+mode->overlap)-1)*sizeof(celt_sig) @@ -1904,25 +1911,27 @@ int celt_decoder_get_size_custom(const CELTMode *mode, int channels) return size; } -CELTDecoder *celt_decoder_create_custom(const CELTMode *mode, int channels, int *error) +#ifdef CUSTOM_MODES +CELTDecoder *opus_custom_decoder_create(const CELTMode *mode, int channels, int *error) { int ret; - CELTDecoder *st = (CELTDecoder *)opus_alloc(celt_decoder_get_size_custom(mode, channels)); - ret = celt_decoder_init_custom(st, mode, channels); + CELTDecoder *st = (CELTDecoder *)opus_alloc(opus_custom_decoder_get_size(mode, channels)); + ret = opus_custom_decoder_init(st, mode, channels); if (ret != OPUS_OK) { - celt_decoder_destroy(st); + opus_custom_decoder_destroy(st); st = NULL; - if (error) - *error = ret; } + if (error) + *error = ret; return st; } +#endif /* CUSTOM_MODES */ int celt_decoder_init(CELTDecoder *st, int sampling_rate, int channels) { int ret; - ret = celt_decoder_init_custom(st, celt_mode_create(48000, 960, NULL), channels); + ret = opus_custom_decoder_init(st, opus_custom_mode_create(48000, 960, NULL), channels); if (ret != OPUS_OK) return ret; st->downsample = resampling_factor(sampling_rate); @@ -1932,7 +1941,7 @@ int celt_decoder_init(CELTDecoder *st, int sampling_rate, int channels) return OPUS_OK; } -int celt_decoder_init_custom(CELTDecoder *st, const CELTMode *mode, int channels) +int opus_custom_decoder_init(CELTDecoder *st, const CELTMode *mode, int channels) { if (channels < 0 || channels > 2) return OPUS_BAD_ARG; @@ -1940,7 +1949,7 @@ int celt_decoder_init_custom(CELTDecoder *st, const CELTMode *mode, int channels if (st==NULL) return OPUS_ALLOC_FAIL; - OPUS_CLEAR((char*)st, celt_decoder_get_size_custom(mode, channels)); + OPUS_CLEAR((char*)st, opus_custom_decoder_get_size(mode, channels)); st->mode = mode; st->overlap = mode->overlap; @@ -1956,10 +1965,12 @@ int celt_decoder_init_custom(CELTDecoder *st, const CELTMode *mode, int channels return OPUS_OK; } -void celt_decoder_destroy(CELTDecoder *st) +#ifdef CUSTOM_MODES +void opus_custom_decoder_destroy(CELTDecoder *st) { opus_free(st); } +#endif /* CUSTOM_MODES */ static void celt_decode_lost(CELTDecoder * restrict st, opus_val16 * restrict pcm, int N, int LM) { @@ -2582,15 +2593,16 @@ int celt_decode_with_ec(CELTDecoder * restrict st, const unsigned char *data, in } +#ifdef CUSTOM_MODES #ifdef FIXED_POINT -int celt_decode(CELTDecoder * restrict st, const unsigned char *data, int len, opus_int16 * restrict pcm, int frame_size) +int opus_custom_decode(CELTDecoder * restrict st, const unsigned char *data, int len, opus_int16 * restrict pcm, int frame_size) { return celt_decode_with_ec(st, data, len, pcm, frame_size, NULL); } #ifndef DISABLE_FLOAT_API -int celt_decode_float(CELTDecoder * restrict st, const unsigned char *data, int len, float * restrict pcm, int frame_size) +int opus_custom_decode_float(CELTDecoder * restrict st, const unsigned char *data, int len, float * restrict pcm, int frame_size) { int j, ret, C, N; VARDECL(opus_int16, out); @@ -2615,12 +2627,12 @@ int celt_decode_float(CELTDecoder * restrict st, const unsigned char *data, int #else -int celt_decode_float(CELTDecoder * restrict st, const unsigned char *data, int len, float * restrict pcm, int frame_size) +int opus_custom_decode_float(CELTDecoder * restrict st, const unsigned char *data, int len, float * restrict pcm, int frame_size) { return celt_decode_with_ec(st, data, len, pcm, frame_size, NULL); } -int celt_decode(CELTDecoder * restrict st, const unsigned char *data, int len, opus_int16 * restrict pcm, int frame_size) +int opus_custom_decode(CELTDecoder * restrict st, const unsigned char *data, int len, opus_int16 * restrict pcm, int frame_size) { int j, ret, C, N; VARDECL(celt_sig, out); @@ -2644,9 +2656,10 @@ int celt_decode(CELTDecoder * restrict st, const unsigned char *data, int len, o } #endif +#endif /* CUSTOM_MODES */ -int celt_decoder_ctl(CELTDecoder * restrict st, int request, ...) +int opus_custom_decoder_ctl(CELTDecoder * restrict st, int request, ...) { va_list ap; @@ -2697,7 +2710,7 @@ int celt_decoder_ctl(CELTDecoder * restrict st, int request, ...) case OPUS_RESET_STATE: { OPUS_CLEAR((char*)&st->DECODER_RESET_START, - celt_decoder_get_size_custom(st->mode, st->channels)- + opus_custom_decoder_get_size(st->mode, st->channels)- ((char*)&st->DECODER_RESET_START - (char*)st)); } break; @@ -2738,20 +2751,3 @@ bad_request: return OPUS_UNIMPLEMENTED; } -const char *celt_strerror(int error) -{ - static const char *error_strings[8] = { - "success", - "invalid argument", - "buffer too small", - "internal error", - "corrupted stream", - "request not implemented", - "invalid state", - "memory allocation failed" - }; - if (error > 0 || error < -7) - return "unknown error"; - else - return error_strings[-error]; -} diff --git a/libcelt/celt.h b/libcelt/celt.h index 31cc0779a3366188aeded59fe02c36231a0fbb8c..e80eb76b89e41c71055e40a67313cdc47cff331a 100644 --- a/libcelt/celt.h +++ b/libcelt/celt.h @@ -37,19 +37,12 @@ #include "opus_types.h" #include "opus_defines.h" +#include "opus_custom.h" #ifdef __cplusplus extern "C" { #endif -#if defined(__GNUC__) && defined(CELT_BUILD) -#define CELT_EXPORT __attribute__ ((visibility ("default"))) -#elif defined(WIN32) -#define CELT_EXPORT __declspec(dllexport) -#else -#define CELT_EXPORT -#endif - #define _celt_check_mode_ptr_ptr(ptr) ((ptr) + ((ptr) - (const CELTMode**)(ptr))) /* Encoder/decoder Requests */ @@ -80,189 +73,35 @@ extern "C" { #define CELT_SET_END_BAND(x) CELT_SET_END_BAND_REQUEST, __opus_check_int(x) -/** Contains the state of an encoder. One encoder state is needed - for each stream. It is initialised once at the beginning of the - stream. Do *not* re-initialise the state for every frame. - @brief Encoder state - */ -typedef struct CELTEncoder CELTEncoder; - -/** State of the decoder. One decoder state is needed for each stream. - It is initialised once at the beginning of the stream. Do *not* - re-initialise the state for every frame */ -typedef struct CELTDecoder CELTDecoder; - -/** The mode contains all the information necessary to create an - encoder. Both the encoder and decoder need to be initialised - with exactly the same mode, otherwise the quality will be very - bad */ -typedef struct CELTMode CELTMode; /** \defgroup codec Encoding and decoding */ /* @{ */ /* Mode calls */ -/** Creates a new mode struct. This will be passed to an encoder or - decoder. The mode MUST NOT BE DESTROYED until the encoders and - decoders that use it are destroyed as well. - @param Fs Sampling rate (32000 to 96000 Hz) - @param frame_size Number of samples (per channel) to encode in each - packet (even values; 64 - 512) - @param error Returned error code (if NULL, no error will be returned) - @return A newly created mode -*/ -CELT_EXPORT CELTMode *celt_mode_create(opus_int32 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. - @param mode Mode to be destroyed -*/ -CELT_EXPORT void celt_mode_destroy(CELTMode *mode); /* Encoder stuff */ -CELT_EXPORT int celt_encoder_get_size(int channels); - -CELT_EXPORT int celt_encoder_get_size_custom(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 mode Contains all the information about the characteristics of - * the stream (must be the same characteristics as used for the - * decoder) - @param channels Number of channels - @param error Returns an error code - @return Newly created encoder state. -*/ -CELT_EXPORT CELTEncoder *celt_encoder_create_custom(const CELTMode *mode, int channels, int *error); +int celt_encoder_get_size(int channels); -CELT_EXPORT int celt_encoder_init(CELTEncoder *st, int sampling_rate, int channels); -CELT_EXPORT int celt_encoder_init_custom(CELTEncoder *st, const CELTMode *mode, int channels); +int celt_encoder_init(CELTEncoder *st, int sampling_rate, int channels); -/** Destroys a an encoder state. - @param st Encoder state to be destroyed - */ -CELT_EXPORT void celt_encoder_destroy(CELTEncoder *st); - -/** Encodes a frame of audio. - @param st Encoder state - @param pcm PCM audio in float format, with a normal range of +/-1.0. - * Samples with a range beyond +/-1.0 are supported but will - * be clipped by decoders using the integer API and should - * only be used if it is known that the far end supports - * extended dynmaic range. There must be exactly - * frame_size samples per channel. - @param compressed The compressed data is written here. This may not alias pcm or - * optional_synthesis. - @param nbCompressedBytes Maximum number of bytes to use for compressing the frame - * (can change from one frame to another) - @return Number of bytes written to "compressed". Will be the same as - * "nbCompressedBytes" unless the stream is VBR and will never be larger. - * If negative, an error has occurred (see error codes). It is IMPORTANT that - * the length returned be somehow transmitted to the decoder. Otherwise, no - * decoding is possible. -*/ -CELT_EXPORT int celt_encode_float(CELTEncoder *st, const float *pcm, int frame_size, unsigned char *compressed, int maxCompressedBytes); - -/** Encodes a frame of audio. - @param st Encoder state - @param pcm PCM audio in signed 16-bit format (native endian). There must be - * exactly frame_size samples per channel. - @param compressed The compressed data is written here. This may not alias pcm or - * optional_synthesis. - @param nbCompressedBytes Maximum number of bytes to use for compressing the frame - * (can change from one frame to another) - @return Number of bytes written to "compressed". Will be the same as - * "nbCompressedBytes" unless the stream is VBR and will never be larger. - * If negative, an error has occurred (see error codes). It is IMPORTANT that - * the length returned be somehow transmitted to the decoder. Otherwise, no - * decoding is possible. - */ -CELT_EXPORT int celt_encode(CELTEncoder *st, const opus_int16 *pcm, int frame_size, unsigned char *compressed, int maxCompressedBytes); -/** Query and set encoder parameters - @param st Encoder state - @param request Parameter to change or query - @param value Pointer to a 32-bit int value - @return Error code -*/ -CELT_EXPORT int celt_encoder_ctl(CELTEncoder * st, int request, ...); /* Decoder stuff */ -CELT_EXPORT int celt_decoder_get_size(int channels); +int celt_decoder_get_size(int channels); -CELT_EXPORT int celt_decoder_get_size_custom(const CELTMode *mode, int channels); -/** 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. - */ -CELT_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). - @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. - */ -CELT_EXPORT CELTDecoder *celt_decoder_create_custom(const CELTMode *mode, int channels, int *error); +int celt_decoder_init(CELTDecoder *st, int sampling_rate, int channels); -CELT_EXPORT int celt_decoder_init(CELTDecoder *st, int sampling_rate, int channels); - -CELT_EXPORT int celt_decoder_init_custom(CELTDecoder *st, const CELTMode *mode, int channels); - -/** Destroys a a decoder state. - @param st Decoder state to be destroyed - */ -CELT_EXPORT void celt_decoder_destroy(CELTDecoder *st); - -/** Decodes a frame of audio. - @param st Decoder state - @param data Compressed data produced by an encoder - @param len Number of bytes to read from "data". This MUST be exactly the number - of bytes returned by the encoder. Using a larger value WILL NOT WORK. - @param pcm One frame (frame_size samples per channel) of decoded PCM will be - returned here in float format. - @return Error code. - */ -CELT_EXPORT int celt_decode_float(CELTDecoder *st, const unsigned char *data, int len, float *pcm, int frame_size); - -/** Decodes a frame of audio. - @param st Decoder state - @param data Compressed data produced by an encoder - @param len Number of bytes to read from "data". This MUST be exactly the number - of bytes returned by the encoder. Using a larger value WILL NOT WORK. - @param pcm One frame (frame_size samples per channel) of decoded PCM will be - returned here in 16-bit PCM format (native endian). - @return Error code. - */ -CELT_EXPORT int celt_decode(CELTDecoder *st, const unsigned char *data, int len, opus_int16 *pcm, int frame_size); - -/** Query and set decoder parameters - @param st Decoder state - @param request Parameter to change or query - @param value Pointer to a 32-bit int value - @return Error code - */ -CELT_EXPORT int celt_decoder_ctl(CELTDecoder * st, int request, ...); - -/** Returns the English string that corresponds to an error code - * @param error Error code (negative for an error, 0 for success - * @return Constant string (must NOT be freed) - */ -CELT_EXPORT const char *celt_strerror(int error); /* @} */ +#define celt_encoder_ctl opus_custom_encoder_ctl +#define celt_decoder_ctl opus_custom_decoder_ctl + #ifdef __cplusplus } #endif diff --git a/libcelt/modes.c b/libcelt/modes.c index 247e1c2c436cba5d62bf5a1f07a45e0128459a25..3b64dd68a4532e2a5667f574261d0996b5d6416d 100644 --- a/libcelt/modes.c +++ b/libcelt/modes.c @@ -220,7 +220,7 @@ static void compute_allocation_table(CELTMode *mode) #endif /* CUSTOM_MODES */ -CELTMode *celt_mode_create(opus_int32 Fs, int frame_size, int *error) +CELTMode *opus_custom_mode_create(opus_int32 Fs, int frame_size, int *error) { int i; #ifdef CUSTOM_MODES @@ -392,12 +392,12 @@ failure: if (error) *error = OPUS_ALLOC_FAIL; if (mode!=NULL) - celt_mode_destroy(mode); + opus_custom_mode_destroy(mode); return NULL; #endif /* !CUSTOM_MODES */ } -void celt_mode_destroy(CELTMode *mode) +void opus_custom_mode_destroy(CELTMode *mode) { #ifdef CUSTOM_MODES int i; diff --git a/libcelt/opus_custom.h b/libcelt/opus_custom.h new file mode 100644 index 0000000000000000000000000000000000000000..973e3ffd1006c692480f51cdb9b6f42f49063e0b --- /dev/null +++ b/libcelt/opus_custom.h @@ -0,0 +1,210 @@ +/* Copyright (c) 2007-2008 CSIRO + Copyright (c) 2007-2009 Xiph.Org Foundation + Copyright (c) 2008 Gregory Maxwell + Written by Jean-Marc Valin and Gregory Maxwell */ +/** + @file celt.h + @brief Contains all the functions for encoding and decoding audio + */ + +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef OPUS_CUSTOM_H +#define OPUS_CUSTOM_H + + +#include "opus_defines.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** Contains the state of an encoder. One encoder state is needed + for each stream. It is initialised once at the beginning of the + stream. Do *not* re-initialise the state for every frame. + @brief Encoder state + */ +typedef struct CELTEncoder CELTEncoder; + +/** State of the decoder. One decoder state is needed for each stream. + It is initialised once at the beginning of the stream. Do *not* + re-initialise the state for every frame */ +typedef struct CELTDecoder CELTDecoder; + +/** The mode contains all the information necessary to create an + encoder. Both the encoder and decoder need to be initialised + with exactly the same mode, otherwise the quality will be very + bad */ +typedef struct CELTMode CELTMode; + +#define OpusCustomEncoder CELTEncoder +#define OpusCustomDecoder CELTDecoder +#define OpusCustomMode CELTMode + +/** Creates a new mode struct. This will be passed to an encoder or + decoder. The mode MUST NOT BE DESTROYED until the encoders and + decoders that use it are destroyed as well. + @param Fs Sampling rate (32000 to 96000 Hz) + @param frame_size Number of samples (per channel) to encode in each + packet (even values; 64 - 512) + @param error Returned error code (if NULL, no error will be returned) + @return A newly created mode +*/ +OPUS_EXPORT CELTMode *opus_custom_mode_create(opus_int32 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. + @param mode Mode to be destroyed +*/ +OPUS_EXPORT void opus_custom_mode_destroy(CELTMode *mode); + + + +/* Encoder */ + +OPUS_EXPORT int opus_custom_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 mode Contains all the information about the characteristics of + * the stream (must be the same characteristics as used for the + * decoder) + @param channels Number of channels + @param error Returns an error code + @return Newly created encoder state. +*/ +OPUS_EXPORT CELTEncoder *opus_custom_encoder_create(const CELTMode *mode, int channels, int *error); + +OPUS_EXPORT int opus_custom_encoder_init(CELTEncoder *st, const CELTMode *mode, int channels); + +/** Destroys a an encoder state. + @param st Encoder state to be destroyed + */ +OPUS_EXPORT void opus_custom_encoder_destroy(CELTEncoder *st); + +/** Encodes a frame of audio. + @param st Encoder state + @param pcm PCM audio in float format, with a normal range of +/-1.0. + * Samples with a range beyond +/-1.0 are supported but will + * be clipped by decoders using the integer API and should + * only be used if it is known that the far end supports + * extended dynmaic range. There must be exactly + * frame_size samples per channel. + @param compressed The compressed data is written here. This may not alias pcm or + * optional_synthesis. + @param nbCompressedBytes Maximum number of bytes to use for compressing the frame + * (can change from one frame to another) + @return Number of bytes written to "compressed". Will be the same as + * "nbCompressedBytes" unless the stream is VBR and will never be larger. + * If negative, an error has occurred (see error codes). It is IMPORTANT that + * the length returned be somehow transmitted to the decoder. Otherwise, no + * decoding is possible. +*/ +OPUS_EXPORT int opus_custom_encode_float(CELTEncoder *st, const float *pcm, int frame_size, unsigned char *compressed, int maxCompressedBytes); + +/** Encodes a frame of audio. + @param st Encoder state + @param pcm PCM audio in signed 16-bit format (native endian). There must be + * exactly frame_size samples per channel. + @param compressed The compressed data is written here. This may not alias pcm or + * optional_synthesis. + @param nbCompressedBytes Maximum number of bytes to use for compressing the frame + * (can change from one frame to another) + @return Number of bytes written to "compressed". Will be the same as + * "nbCompressedBytes" unless the stream is VBR and will never be larger. + * If negative, an error has occurred (see error codes). It is IMPORTANT that + * the length returned be somehow transmitted to the decoder. Otherwise, no + * decoding is possible. + */ +OPUS_EXPORT int opus_custom_encode(CELTEncoder *st, const opus_int16 *pcm, int frame_size, unsigned char *compressed, int maxCompressedBytes); + +/** Query and set encoder parameters + @param st Encoder state + @param request Parameter to change or query + @param value Pointer to a 32-bit int value + @return Error code +*/ +OPUS_EXPORT int opus_custom_encoder_ctl(CELTEncoder * restrict st, int request, ...); + + + +/* Decoder */ + +OPUS_EXPORT int opus_custom_decoder_get_size(const CELTMode *mode, int channels); + +/** 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. + */ +OPUS_EXPORT CELTDecoder *opus_custom_decoder_create(const CELTMode *mode, int channels, int *error); + +OPUS_EXPORT int opus_custom_decoder_init(CELTDecoder *st, const CELTMode *mode, int channels); + +/** Destroys a a decoder state. + @param st Decoder state to be destroyed + */ +OPUS_EXPORT void opus_custom_decoder_destroy(CELTDecoder *st); + +/** Decodes a frame of audio. + @param st Decoder state + @param data Compressed data produced by an encoder + @param len Number of bytes to read from "data". This MUST be exactly the number + of bytes returned by the encoder. Using a larger value WILL NOT WORK. + @param pcm One frame (frame_size samples per channel) of decoded PCM will be + returned here in float format. + @return Error code. + */ +OPUS_EXPORT int opus_custom_decode_float(CELTDecoder *st, const unsigned char *data, int len, float *pcm, int frame_size); + +/** Decodes a frame of audio. + @param st Decoder state + @param data Compressed data produced by an encoder + @param len Number of bytes to read from "data". This MUST be exactly the number + of bytes returned by the encoder. Using a larger value WILL NOT WORK. + @param pcm One frame (frame_size samples per channel) of decoded PCM will be + returned here in 16-bit PCM format (native endian). + @return Error code. + */ +OPUS_EXPORT int opus_custom_decode(CELTDecoder *st, const unsigned char *data, int len, opus_int16 *pcm, int frame_size); + +/** Query and set decoder parameters + @param st Decoder state + @param request Parameter to change or query + @param value Pointer to a 32-bit int value + @return Error code + */ +OPUS_EXPORT int opus_custom_decoder_ctl(CELTDecoder * restrict st, int request, ...); + + +#ifdef __cplusplus +} +#endif + +#endif /* OPUS_CUSTOM_H */ diff --git a/libcelt/opus_defines.h b/libcelt/opus_defines.h index 098562978d663bede62a9b70066b8e27de6d4626..a1abf298a68b234a840707843801006fd742c40f 100644 --- a/libcelt/opus_defines.h +++ b/libcelt/opus_defines.h @@ -150,6 +150,12 @@ extern "C" { #define OPUS_GET_FINAL_RANGE(x) OPUS_GET_FINAL_RANGE_REQUEST, __opus_check_uint_ptr(x) + +OPUS_EXPORT const char *opus_strerror(int error); + +OPUS_EXPORT const char *opus_get_version_string(void); + + #ifdef __cplusplus } #endif diff --git a/src/test_opus_custom.c b/libcelt/test_opus_custom.c similarity index 95% rename from src/test_opus_custom.c rename to libcelt/test_opus_custom.c index f5e61e8c28a6f2c79e484534973b1796aa37aa22..bb57f650da5abd53abf50a65cb5b1b212e1eaed7 100644 --- a/src/test_opus_custom.c +++ b/libcelt/test_opus_custom.c @@ -44,9 +44,9 @@ int main(int argc, char *argv[]) int err; char *inFile, *outFile; FILE *fin, *fout; - CELTMode *mode=NULL; - CELTEncoder *enc; - CELTDecoder *dec; + OpusCustomMode *mode=NULL; + OpusCustomEncoder *enc; + OpusCustomDecoder *dec; int len; opus_int32 frame_size, channels; int bytes_per_packet; @@ -62,7 +62,7 @@ int main(int argc, char *argv[]) opus_int16 *in, *out; if (argc != 9 && argc != 8 && argc != 7) { - fprintf (stderr, "Usage: testcelt <rate> <channels> <frame size> " + fprintf (stderr, "Usage: test_opus_custom <rate> <channels> <frame size> " " <bytes per packet> [<complexity> [packet loss rate]] " "<input> <output>\n"); return 1; @@ -113,12 +113,12 @@ int main(int argc, char *argv[]) fprintf(stderr, "Failed to create the decoder: %s\n", opus_strerror(err)); return 1; } - opus_custom_decoder_ctl(dec, CELT_GET_LOOKAHEAD(&skip)); + opus_custom_decoder_ctl(dec, OPUS_GET_LOOKAHEAD(&skip)); if (argc>7) { complexity=atoi(argv[5]); - opus_custom_encoder_ctl(enc,CELT_SET_COMPLEXITY(complexity)); + opus_custom_encoder_ctl(enc,OPUS_SET_COMPLEXITY(complexity)); } in = (opus_int16*)malloc(frame_size*channels*sizeof(opus_int16)); diff --git a/libcelt/testcelt.c b/libcelt/testcelt.c index 2afc75597932632577bbc8f311c4fb0da80faceb..c00b3951d318830c86c541e40b3f63d4dbb06439 100644 --- a/libcelt/testcelt.c +++ b/libcelt/testcelt.c @@ -101,13 +101,13 @@ int main(int argc, char *argv[]) return 1; } - enc = celt_encoder_create_custom(mode, channels, &err); + enc = opus_custom_encoder_create(mode, channels, &err); if (err != 0) { fprintf(stderr, "Failed to create the encoder: %s\n", celt_strerror(err)); return 1; } - dec = celt_decoder_create_custom(mode, channels, &err); + dec = opus_custom_decoder_create(mode, channels, &err); if (err != 0) { fprintf(stderr, "Failed to create the decoder: %s\n", celt_strerror(err)); diff --git a/src/opus.h b/src/opus.h index 7b5e629d7fa8a1b7a00292e3e3c954bf9723d1b2..08d706bfe8a60e4e56dfc95cade588451f4326b8 100644 --- a/src/opus.h +++ b/src/opus.h @@ -161,9 +161,6 @@ OPUS_EXPORT int opus_packet_get_nb_channels(const unsigned char *data); OPUS_EXPORT int opus_packet_get_nb_frames(const unsigned char packet[], int len); OPUS_EXPORT int opus_decoder_get_nb_samples(const OpusDecoder *dec, const unsigned char packet[], int len); -OPUS_EXPORT const char *opus_strerror(int error); - -OPUS_EXPORT const char *opus_get_version_string(void); /* Repacketizer */ typedef struct OpusRepacketizer OpusRepacketizer; diff --git a/src/opus_custom.h b/src/opus_custom.h deleted file mode 100644 index 19719f09be5367255a12c6503d021dc8b87a43ea..0000000000000000000000000000000000000000 --- a/src/opus_custom.h +++ /dev/null @@ -1,82 +0,0 @@ -/* Copyright (c) 2007-2008 CSIRO - Copyright (c) 2007-2009 Xiph.Org Foundation - Copyright (c) 2008 Gregory Maxwell - Written by Jean-Marc Valin and Gregory Maxwell */ -/** - @file celt.h - @brief Contains all the functions for encoding and decoding audio - */ - -/* - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR - CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#ifndef OPUS_CUSTOM_H -#define OPUS_CUSTOM_H - -#ifdef ENABLE_OPUS_CUSTOM - -#include "celt.h" -#include "opus.h" - -#ifdef __cplusplus -extern "C" { -#endif - - -#define OpusCustomEncoder CELTEncoder -#define OpusCustomDecoder CELTDecoder -#define OpusCustomMode CELTMode - - - -#define opus_custom_mode_create celt_mode_create -#define opus_custom_mode_destroy celt_mode_destroy - -#define opus_custom_encoder_get_size celt_encoder_get_size_custom -#define opus_custom_encoder_create celt_encoder_create_custom -#define opus_custom_encoder_init celt_encoder_init_custom - - -#define opus_custom_encoder_destroy celt_encoder_destroy - -#define opus_custom_encode_float celt_encode_float -#define opus_custom_encode celt_encode -#define opus_custom_encoder_ctl celt_encoder_ctl -#define opus_custom_decoder_get_size celt_decoder_get_size_custom -#define opus_custom_decoder_create celt_decoder_create_custom -#define opus_custom_decoder_init celt_decoder_init_custom -#define opus_custom_decoder_destroy celt_decoder_destroy -#define opus_custom_decode_float celt_decode_float -#define opus_custom_decode celt_decode -#define opus_custom_decoder_ctl celt_decoder_ctl - - -#ifdef __cplusplus -} -#endif - -#endif /* ENABLE_OPUS_CUSTOM */ - -#endif /* OPUS_CUSTOM_H */ diff --git a/src/opus_decoder.c b/src/opus_decoder.c index a7f0baab15a07af710dea6925647d7ab57b550dd..5266075f0c82b481f55a992d2216d64662d101a9 100644 --- a/src/opus_decoder.c +++ b/src/opus_decoder.c @@ -774,7 +774,7 @@ int opus_decoder_ctl(OpusDecoder *st, int request, ...) break; default: /*fprintf(stderr, "unknown opus_decoder_ctl() request: %d", request);*/ - ret = OPUS_BAD_ARG; + ret = OPUS_UNIMPLEMENTED; break; } diff --git a/src/opus_encoder.c b/src/opus_encoder.c index b9cf13aac92c95ba2808b32f1ec49a0d517c0e68..4f3d39f466d62eb6d84daa2993fb1fe25839767a 100644 --- a/src/opus_encoder.c +++ b/src/opus_encoder.c @@ -1014,7 +1014,7 @@ int opus_encoder_ctl(OpusEncoder *st, int request, ...) break; default: /* fprintf(stderr, "unknown opus_encoder_ctl() request: %d", request);*/ - ret = OPUS_BAD_ARG; + ret = OPUS_UNIMPLEMENTED; break; } va_end(ap);