From 62a9040cb8d2753db2df04c3067be02fb9ba0cac Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Sun, 10 Nov 2013 03:27:21 -0500 Subject: [PATCH] Add a Opus decoder JNI library. Write an audio depacketizer. Audio works! --- jni/Android.mk | 20 + jni/Application.mk | 10 + jni/libopus/inc/opus.h | 906 ++++++++++++++++++ jni/libopus/inc/opus_custom.h | 329 +++++++ jni/libopus/inc/opus_defines.h | 655 +++++++++++++ jni/libopus/inc/opus_multistream.h | 660 +++++++++++++ jni/libopus/inc/opus_types.h | 159 +++ jni/nv_opus_dec.c | 54 ++ jni/nv_opus_dec.h | 6 + jni/nv_opus_dec_jni.c | 61 ++ libs/armeabi-v7a/libnv_opus_dec.so | Bin 0 -> 148716 bytes src/com/limelight/nvstream/NvAudioStream.java | 150 ++- src/com/limelight/nvstream/NvConnection.java | 6 + .../av/audio/AvAudioDepacketizer.java | 59 ++ .../nvstream/av/audio/OpusDecoder.java | 14 + .../av/video/AvVideoDepacketizer.java | 2 +- 16 files changed, 3064 insertions(+), 27 deletions(-) create mode 100644 jni/Android.mk create mode 100644 jni/Application.mk create mode 100644 jni/libopus/inc/opus.h create mode 100644 jni/libopus/inc/opus_custom.h create mode 100644 jni/libopus/inc/opus_defines.h create mode 100644 jni/libopus/inc/opus_multistream.h create mode 100644 jni/libopus/inc/opus_types.h create mode 100644 jni/nv_opus_dec.c create mode 100644 jni/nv_opus_dec.h create mode 100644 jni/nv_opus_dec_jni.c create mode 100644 libs/armeabi-v7a/libnv_opus_dec.so create mode 100644 src/com/limelight/nvstream/av/audio/AvAudioDepacketizer.java create mode 100644 src/com/limelight/nvstream/av/audio/OpusDecoder.java diff --git a/jni/Android.mk b/jni/Android.mk new file mode 100644 index 00000000..2414454a --- /dev/null +++ b/jni/Android.mk @@ -0,0 +1,20 @@ +# Android.mk for Limelight's Opus decoder + +# This allows the the build system to find the source files +LOCAL_PATH := $(call my-dir) + +# This clears local variables for us +include $(CLEAR_VARS) + +# Declare our module name and source files +LOCAL_MODULE := nv_opus_dec +LOCAL_SRC_FILES := nv_opus_dec.c nv_opus_dec_jni.c + +# Set the local include path to the GMP directory for our architecture +LOCAL_C_INCLUDES := $(LOCAL_PATH)/libopus/inc + +# Link to libopus +LOCAL_LDLIBS := -L$(LOCAL_PATH)/libopus/$(TARGET_ARCH_ABI) -lopus + +# Build a shared library +include $(BUILD_SHARED_LIBRARY) diff --git a/jni/Application.mk b/jni/Application.mk new file mode 100644 index 00000000..af95f394 --- /dev/null +++ b/jni/Application.mk @@ -0,0 +1,10 @@ +# Application.mk for Limelight + +# Our minimum version is Android 4.1 +APP_PLATFORM := android-16 + +# We just build for ARMv7a for now +APP_ABI := armeabi-v7a # x86 + +# We want an optimized build +APP_OPTIM := release diff --git a/jni/libopus/inc/opus.h b/jni/libopus/inc/opus.h new file mode 100644 index 00000000..ce860388 --- /dev/null +++ b/jni/libopus/inc/opus.h @@ -0,0 +1,906 @@ +/* Copyright (c) 2010-2011 Xiph.Org Foundation, Skype Limited + Written by Jean-Marc Valin and Koen Vos */ +/* + 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 COPYRIGHT OWNER + 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. +*/ + +/** + * @file opus.h + * @brief Opus reference implementation API + */ + +#ifndef OPUS_H +#define OPUS_H + +#include "opus_types.h" +#include "opus_defines.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @mainpage Opus + * + * The Opus codec is designed for interactive speech and audio transmission over the Internet. + * It is designed by the IETF Codec Working Group and incorporates technology from + * Skype's SILK codec and Xiph.Org's CELT codec. + * + * The Opus codec is designed to handle a wide range of interactive audio applications, + * including Voice over IP, videoconferencing, in-game chat, and even remote live music + * performances. It can scale from low bit-rate narrowband speech to very high quality + * stereo music. Its main features are: + + * @li Sampling rates from 8 to 48 kHz + * @li Bit-rates from 6 kb/s to 510 kb/s + * @li Support for both constant bit-rate (CBR) and variable bit-rate (VBR) + * @li Audio bandwidth from narrowband to full-band + * @li Support for speech and music + * @li Support for mono and stereo + * @li Support for multichannel (up to 255 channels) + * @li Frame sizes from 2.5 ms to 60 ms + * @li Good loss robustness and packet loss concealment (PLC) + * @li Floating point and fixed-point implementation + * + * Documentation sections: + * @li @ref opus_encoder + * @li @ref opus_decoder + * @li @ref opus_repacketizer + * @li @ref opus_multistream + * @li @ref opus_libinfo + * @li @ref opus_custom + */ + +/** @defgroup opus_encoder Opus Encoder + * @{ + * + * @brief This page describes the process and functions used to encode Opus. + * + * Since Opus is a stateful codec, the encoding process starts with creating an encoder + * state. This can be done with: + * + * @code + * int error; + * OpusEncoder *enc; + * enc = opus_encoder_create(Fs, channels, application, &error); + * @endcode + * + * From this point, @c enc can be used for encoding an audio stream. An encoder state + * @b must @b not be used for more than one stream at the same time. Similarly, the encoder + * state @b must @b not be re-initialized for each frame. + * + * While opus_encoder_create() allocates memory for the state, it's also possible + * to initialize pre-allocated memory: + * + * @code + * int size; + * int error; + * OpusEncoder *enc; + * size = opus_encoder_get_size(channels); + * enc = malloc(size); + * error = opus_encoder_init(enc, Fs, channels, application); + * @endcode + * + * where opus_encoder_get_size() returns the required size for the encoder state. Note that + * future versions of this code may change the size, so no assuptions should be made about it. + * + * The encoder state is always continuous in memory and only a shallow copy is sufficient + * to copy it (e.g. memcpy()) + * + * It is possible to change some of the encoder's settings using the opus_encoder_ctl() + * interface. All these settings already default to the recommended value, so they should + * only be changed when necessary. The most common settings one may want to change are: + * + * @code + * opus_encoder_ctl(enc, OPUS_SET_BITRATE(bitrate)); + * opus_encoder_ctl(enc, OPUS_SET_COMPLEXITY(complexity)); + * opus_encoder_ctl(enc, OPUS_SET_SIGNAL(signal_type)); + * @endcode + * + * where + * + * @arg bitrate is in bits per second (b/s) + * @arg complexity is a value from 1 to 10, where 1 is the lowest complexity and 10 is the highest + * @arg signal_type is either OPUS_AUTO (default), OPUS_SIGNAL_VOICE, or OPUS_SIGNAL_MUSIC + * + * See @ref opus_encoderctls and @ref opus_genericctls for a complete list of parameters that can be set or queried. Most parameters can be set or changed at any time during a stream. + * + * To encode a frame, opus_encode() or opus_encode_float() must be called with exactly one frame (2.5, 5, 10, 20, 40 or 60 ms) of audio data: + * @code + * len = opus_encode(enc, audio_frame, frame_size, packet, max_packet); + * @endcode + * + * where + * + * + * opus_encode() and opus_encode_float() return the number of bytes actually written to the packet. + * The return value can be negative, which indicates that an error has occurred. If the return value + * is 1 byte, then the packet does not need to be transmitted (DTX). + * + * Once the encoder state if no longer needed, it can be destroyed with + * + * @code + * opus_encoder_destroy(enc); + * @endcode + * + * If the encoder was created with opus_encoder_init() rather than opus_encoder_create(), + * then no action is required aside from potentially freeing the memory that was manually + * allocated for it (calling free(enc) for the example above) + * + */ + +/** Opus encoder state. + * This contains the complete state of an Opus encoder. + * It is position independent and can be freely copied. + * @see opus_encoder_create,opus_encoder_init + */ +typedef struct OpusEncoder OpusEncoder; + +/** Gets the size of an OpusEncoder structure. + * @param[in] channels int: Number of channels. + * This must be 1 or 2. + * @returns The size in bytes. + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_encoder_get_size(int channels); + +/** + */ + +/** Allocates and initializes an encoder state. + * There are three coding modes: + * + * @ref OPUS_APPLICATION_VOIP gives best quality at a given bitrate for voice + * signals. It enhances the input signal by high-pass filtering and + * emphasizing formants and harmonics. Optionally it includes in-band + * forward error correction to protect against packet loss. Use this + * mode for typical VoIP applications. Because of the enhancement, + * even at high bitrates the output may sound different from the input. + * + * @ref OPUS_APPLICATION_AUDIO gives best quality at a given bitrate for most + * non-voice signals like music. Use this mode for music and mixed + * (music/voice) content, broadcast, and applications requiring less + * than 15 ms of coding delay. + * + * @ref OPUS_APPLICATION_RESTRICTED_LOWDELAY configures low-delay mode that + * disables the speech-optimized mode in exchange for slightly reduced delay. + * This mode can only be set on an newly initialized or freshly reset encoder + * because it changes the codec delay. + * + * This is useful when the caller knows that the speech-optimized modes will not be needed (use with caution). + * @param [in] Fs opus_int32: Sampling rate of input signal (Hz) + * This must be one of 8000, 12000, 16000, + * 24000, or 48000. + * @param [in] channels int: Number of channels (1 or 2) in input signal + * @param [in] application int: Coding mode (@ref OPUS_APPLICATION_VOIP/@ref OPUS_APPLICATION_AUDIO/@ref OPUS_APPLICATION_RESTRICTED_LOWDELAY) + * @param [out] error int*: @ref opus_errorcodes + * @note Regardless of the sampling rate and number channels selected, the Opus encoder + * can switch to a lower audio bandwidth or number of channels if the bitrate + * selected is too low. This also means that it is safe to always use 48 kHz stereo input + * and let the encoder optimize the encoding. + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT OpusEncoder *opus_encoder_create( + opus_int32 Fs, + int channels, + int application, + int *error +); + +/** Initializes a previously allocated encoder state + * The memory pointed to by st must be at least the size returned by opus_encoder_get_size(). + * This is intended for applications which use their own allocator instead of malloc. + * @see opus_encoder_create(),opus_encoder_get_size() + * To reset a previously initialized state, use the #OPUS_RESET_STATE CTL. + * @param [in] st OpusEncoder*: Encoder state + * @param [in] Fs opus_int32: Sampling rate of input signal (Hz) + * This must be one of 8000, 12000, 16000, + * 24000, or 48000. + * @param [in] channels int: Number of channels (1 or 2) in input signal + * @param [in] application int: Coding mode (OPUS_APPLICATION_VOIP/OPUS_APPLICATION_AUDIO/OPUS_APPLICATION_RESTRICTED_LOWDELAY) + * @retval #OPUS_OK Success or @ref opus_errorcodes + */ +OPUS_EXPORT int opus_encoder_init( + OpusEncoder *st, + opus_int32 Fs, + int channels, + int application +) OPUS_ARG_NONNULL(1); + +/** Encodes an Opus frame. + * @param [in] st OpusEncoder*: Encoder state + * @param [in] pcm opus_int16*: Input signal (interleaved if 2 channels). length is frame_size*channels*sizeof(opus_int16) + * @param [in] frame_size int: Number of samples per channel in the + * input signal. + * This must be an Opus frame size for + * the encoder's sampling rate. + * For example, at 48 kHz the permitted + * values are 120, 240, 480, 960, 1920, + * and 2880. + * Passing in a duration of less than + * 10 ms (480 samples at 48 kHz) will + * prevent the encoder from using the LPC + * or hybrid modes. + * @param [out] data unsigned char*: Output payload. + * This must contain storage for at + * least \a max_data_bytes. + * @param [in] max_data_bytes opus_int32: Size of the allocated + * memory for the output + * payload. This may be + * used to impose an upper limit on + * the instant bitrate, but should + * not be used as the only bitrate + * control. Use #OPUS_SET_BITRATE to + * control the bitrate. + * @returns The length of the encoded packet (in bytes) on success or a + * negative error code (see @ref opus_errorcodes) on failure. + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT opus_int32 opus_encode( + OpusEncoder *st, + const opus_int16 *pcm, + int frame_size, + unsigned char *data, + opus_int32 max_data_bytes +) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2) OPUS_ARG_NONNULL(4); + +/** Encodes an Opus frame from floating point input. + * @param [in] st OpusEncoder*: Encoder state + * @param [in] pcm float*: Input in float format (interleaved if 2 channels), 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 dynamic range. + * length is frame_size*channels*sizeof(float) + * @param [in] frame_size int: Number of samples per channel in the + * input signal. + * This must be an Opus frame size for + * the encoder's sampling rate. + * For example, at 48 kHz the permitted + * values are 120, 240, 480, 960, 1920, + * and 2880. + * Passing in a duration of less than + * 10 ms (480 samples at 48 kHz) will + * prevent the encoder from using the LPC + * or hybrid modes. + * @param [out] data unsigned char*: Output payload. + * This must contain storage for at + * least \a max_data_bytes. + * @param [in] max_data_bytes opus_int32: Size of the allocated + * memory for the output + * payload. This may be + * used to impose an upper limit on + * the instant bitrate, but should + * not be used as the only bitrate + * control. Use #OPUS_SET_BITRATE to + * control the bitrate. + * @returns The length of the encoded packet (in bytes) on success or a + * negative error code (see @ref opus_errorcodes) on failure. + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT opus_int32 opus_encode_float( + OpusEncoder *st, + const float *pcm, + int frame_size, + unsigned char *data, + opus_int32 max_data_bytes +) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2) OPUS_ARG_NONNULL(4); + +/** Frees an OpusEncoder allocated by opus_encoder_create(). + * @param[in] st OpusEncoder*: State to be freed. + */ +OPUS_EXPORT void opus_encoder_destroy(OpusEncoder *st); + +/** Perform a CTL function on an Opus encoder. + * + * Generally the request and subsequent arguments are generated + * by a convenience macro. + * @param st OpusEncoder*: Encoder state. + * @param request This and all remaining parameters should be replaced by one + * of the convenience macros in @ref opus_genericctls or + * @ref opus_encoderctls. + * @see opus_genericctls + * @see opus_encoderctls + */ +OPUS_EXPORT int opus_encoder_ctl(OpusEncoder *st, int request, ...) OPUS_ARG_NONNULL(1); +/**@}*/ + +/** @defgroup opus_decoder Opus Decoder + * @{ + * + * @brief This page describes the process and functions used to decode Opus. + * + * The decoding process also starts with creating a decoder + * state. This can be done with: + * @code + * int error; + * OpusDecoder *dec; + * dec = opus_decoder_create(Fs, channels, &error); + * @endcode + * where + * @li Fs is the sampling rate and must be 8000, 12000, 16000, 24000, or 48000 + * @li channels is the number of channels (1 or 2) + * @li error will hold the error code in case of failure (or #OPUS_OK on success) + * @li the return value is a newly created decoder state to be used for decoding + * + * While opus_decoder_create() allocates memory for the state, it's also possible + * to initialize pre-allocated memory: + * @code + * int size; + * int error; + * OpusDecoder *dec; + * size = opus_decoder_get_size(channels); + * dec = malloc(size); + * error = opus_decoder_init(dec, Fs, channels); + * @endcode + * where opus_decoder_get_size() returns the required size for the decoder state. Note that + * future versions of this code may change the size, so no assuptions should be made about it. + * + * The decoder state is always continuous in memory and only a shallow copy is sufficient + * to copy it (e.g. memcpy()) + * + * To decode a frame, opus_decode() or opus_decode_float() must be called with a packet of compressed audio data: + * @code + * frame_size = opus_decode(dec, packet, len, decoded, max_size, 0); + * @endcode + * where + * + * @li packet is the byte array containing the compressed data + * @li len is the exact number of bytes contained in the packet + * @li decoded is the decoded audio data in opus_int16 (or float for opus_decode_float()) + * @li max_size is the max duration of the frame in samples (per channel) that can fit into the decoded_frame array + * + * opus_decode() and opus_decode_float() return the number of samples (per channel) decoded from the packet. + * If that value is negative, then an error has occurred. This can occur if the packet is corrupted or if the audio + * buffer is too small to hold the decoded audio. + * + * Opus is a stateful codec with overlapping blocks and as a result Opus + * packets are not coded independently of each other. Packets must be + * passed into the decoder serially and in the correct order for a correct + * decode. Lost packets can be replaced with loss concealment by calling + * the decoder with a null pointer and zero length for the missing packet. + * + * A single codec state may only be accessed from a single thread at + * a time and any required locking must be performed by the caller. Separate + * streams must be decoded with separate decoder states and can be decoded + * in parallel unless the library was compiled with NONTHREADSAFE_PSEUDOSTACK + * defined. + * + */ + +/** Opus decoder state. + * This contains the complete state of an Opus decoder. + * It is position independent and can be freely copied. + * @see opus_decoder_create,opus_decoder_init + */ +typedef struct OpusDecoder OpusDecoder; + +/** Gets the size of an OpusDecoder structure. + * @param [in] channels int: Number of channels. + * This must be 1 or 2. + * @returns The size in bytes. + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_decoder_get_size(int channels); + +/** Allocates and initializes a decoder state. + * @param [in] Fs opus_int32: Sample rate to decode at (Hz). + * This must be one of 8000, 12000, 16000, + * 24000, or 48000. + * @param [in] channels int: Number of channels (1 or 2) to decode + * @param [out] error int*: #OPUS_OK Success or @ref opus_errorcodes + * + * Internally Opus stores data at 48000 Hz, so that should be the default + * value for Fs. However, the decoder can efficiently decode to buffers + * at 8, 12, 16, and 24 kHz so if for some reason the caller cannot use + * data at the full sample rate, or knows the compressed data doesn't + * use the full frequency range, it can request decoding at a reduced + * rate. Likewise, the decoder is capable of filling in either mono or + * interleaved stereo pcm buffers, at the caller's request. + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT OpusDecoder *opus_decoder_create( + opus_int32 Fs, + int channels, + int *error +); + +/** Initializes a previously allocated decoder state. + * The state must be at least the size returned by opus_decoder_get_size(). + * This is intended for applications which use their own allocator instead of malloc. @see opus_decoder_create,opus_decoder_get_size + * To reset a previously initialized state, use the #OPUS_RESET_STATE CTL. + * @param [in] st OpusDecoder*: Decoder state. + * @param [in] Fs opus_int32: Sampling rate to decode to (Hz). + * This must be one of 8000, 12000, 16000, + * 24000, or 48000. + * @param [in] channels int: Number of channels (1 or 2) to decode + * @retval #OPUS_OK Success or @ref opus_errorcodes + */ +OPUS_EXPORT int opus_decoder_init( + OpusDecoder *st, + opus_int32 Fs, + int channels +) OPUS_ARG_NONNULL(1); + +/** Decode an Opus packet. + * @param [in] st OpusDecoder*: Decoder state + * @param [in] data char*: Input payload. Use a NULL pointer to indicate packet loss + * @param [in] len opus_int32: Number of bytes in payload* + * @param [out] pcm opus_int16*: Output signal (interleaved if 2 channels). length + * is frame_size*channels*sizeof(opus_int16) + * @param [in] frame_size Number of samples per channel of available space in \a pcm. + * If this is less than the maximum packet duration (120ms; 5760 for 48kHz), this function will + * not be capable of decoding some packets. In the case of PLC (data==NULL) or FEC (decode_fec=1), + * then frame_size needs to be exactly the duration of audio that is missing, otherwise the + * decoder will not be in the optimal state to decode the next incoming packet. For the PLC and + * FEC cases, frame_size must be a multiple of 2.5 ms. + * @param [in] decode_fec int: Flag (0 or 1) to request that any in-band forward error correction data be + * decoded. If no such data is available, the frame is decoded as if it were lost. + * @returns Number of decoded samples or @ref opus_errorcodes + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_decode( + OpusDecoder *st, + const unsigned char *data, + opus_int32 len, + opus_int16 *pcm, + int frame_size, + int decode_fec +) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(4); + +/** Decode an Opus packet with floating point output. + * @param [in] st OpusDecoder*: Decoder state + * @param [in] data char*: Input payload. Use a NULL pointer to indicate packet loss + * @param [in] len opus_int32: Number of bytes in payload + * @param [out] pcm float*: Output signal (interleaved if 2 channels). length + * is frame_size*channels*sizeof(float) + * @param [in] frame_size Number of samples per channel of available space in \a pcm. + * If this is less than the maximum packet duration (120ms; 5760 for 48kHz), this function will + * not be capable of decoding some packets. In the case of PLC (data==NULL) or FEC (decode_fec=1), + * then frame_size needs to be exactly the duration of audio that is missing, otherwise the + * decoder will not be in the optimal state to decode the next incoming packet. For the PLC and + * FEC cases, frame_size must be a multiple of 2.5 ms. + * @param [in] decode_fec int: Flag (0 or 1) to request that any in-band forward error correction data be + * decoded. If no such data is available the frame is decoded as if it were lost. + * @returns Number of decoded samples or @ref opus_errorcodes + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_decode_float( + OpusDecoder *st, + const unsigned char *data, + opus_int32 len, + float *pcm, + int frame_size, + int decode_fec +) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(4); + +/** Perform a CTL function on an Opus decoder. + * + * Generally the request and subsequent arguments are generated + * by a convenience macro. + * @param st OpusDecoder*: Decoder state. + * @param request This and all remaining parameters should be replaced by one + * of the convenience macros in @ref opus_genericctls or + * @ref opus_decoderctls. + * @see opus_genericctls + * @see opus_decoderctls + */ +OPUS_EXPORT int opus_decoder_ctl(OpusDecoder *st, int request, ...) OPUS_ARG_NONNULL(1); + +/** Frees an OpusDecoder allocated by opus_decoder_create(). + * @param[in] st OpusDecoder*: State to be freed. + */ +OPUS_EXPORT void opus_decoder_destroy(OpusDecoder *st); + +/** Parse an opus packet into one or more frames. + * Opus_decode will perform this operation internally so most applications do + * not need to use this function. + * This function does not copy the frames, the returned pointers are pointers into + * the input packet. + * @param [in] data char*: Opus packet to be parsed + * @param [in] len opus_int32: size of data + * @param [out] out_toc char*: TOC pointer + * @param [out] frames char*[48] encapsulated frames + * @param [out] size opus_int16[48] sizes of the encapsulated frames + * @param [out] payload_offset int*: returns the position of the payload within the packet (in bytes) + * @returns number of frames + */ +OPUS_EXPORT int opus_packet_parse( + const unsigned char *data, + opus_int32 len, + unsigned char *out_toc, + const unsigned char *frames[48], + opus_int16 size[48], + int *payload_offset +) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(4); + +/** Gets the bandwidth of an Opus packet. + * @param [in] data char*: Opus packet + * @retval OPUS_BANDWIDTH_NARROWBAND Narrowband (4kHz bandpass) + * @retval OPUS_BANDWIDTH_MEDIUMBAND Mediumband (6kHz bandpass) + * @retval OPUS_BANDWIDTH_WIDEBAND Wideband (8kHz bandpass) + * @retval OPUS_BANDWIDTH_SUPERWIDEBAND Superwideband (12kHz bandpass) + * @retval OPUS_BANDWIDTH_FULLBAND Fullband (20kHz bandpass) + * @retval OPUS_INVALID_PACKET The compressed data passed is corrupted or of an unsupported type + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_packet_get_bandwidth(const unsigned char *data) OPUS_ARG_NONNULL(1); + +/** Gets the number of samples per frame from an Opus packet. + * @param [in] data char*: Opus packet. + * This must contain at least one byte of + * data. + * @param [in] Fs opus_int32: Sampling rate in Hz. + * This must be a multiple of 400, or + * inaccurate results will be returned. + * @returns Number of samples per frame. + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_packet_get_samples_per_frame(const unsigned char *data, opus_int32 Fs) OPUS_ARG_NONNULL(1); + +/** Gets the number of channels from an Opus packet. + * @param [in] data char*: Opus packet + * @returns Number of channels + * @retval OPUS_INVALID_PACKET The compressed data passed is corrupted or of an unsupported type + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_packet_get_nb_channels(const unsigned char *data) OPUS_ARG_NONNULL(1); + +/** Gets the number of frames in an Opus packet. + * @param [in] packet char*: Opus packet + * @param [in] len opus_int32: Length of packet + * @returns Number of frames + * @retval OPUS_BAD_ARG Insufficient data was passed to the function + * @retval OPUS_INVALID_PACKET The compressed data passed is corrupted or of an unsupported type + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_packet_get_nb_frames(const unsigned char packet[], opus_int32 len) OPUS_ARG_NONNULL(1); + +/** Gets the number of samples of an Opus packet. + * @param [in] packet char*: Opus packet + * @param [in] len opus_int32: Length of packet + * @param [in] Fs opus_int32: Sampling rate in Hz. + * This must be a multiple of 400, or + * inaccurate results will be returned. + * @returns Number of samples + * @retval OPUS_BAD_ARG Insufficient data was passed to the function + * @retval OPUS_INVALID_PACKET The compressed data passed is corrupted or of an unsupported type + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_packet_get_nb_samples(const unsigned char packet[], opus_int32 len, opus_int32 Fs) OPUS_ARG_NONNULL(1); + +/** Gets the number of samples of an Opus packet. + * @param [in] dec OpusDecoder*: Decoder state + * @param [in] packet char*: Opus packet + * @param [in] len opus_int32: Length of packet + * @returns Number of samples + * @retval OPUS_BAD_ARG Insufficient data was passed to the function + * @retval OPUS_INVALID_PACKET The compressed data passed is corrupted or of an unsupported type + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_decoder_get_nb_samples(const OpusDecoder *dec, const unsigned char packet[], opus_int32 len) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2); +/**@}*/ + +/** @defgroup opus_repacketizer Repacketizer + * @{ + * + * The repacketizer can be used to merge multiple Opus packets into a single + * packet or alternatively to split Opus packets that have previously been + * merged. Splitting valid Opus packets is always guaranteed to succeed, + * whereas merging valid packets only succeeds if all frames have the same + * mode, bandwidth, and frame size, and when the total duration of the merged + * packet is no more than 120 ms. + * The repacketizer currently only operates on elementary Opus + * streams. It will not manipualte multistream packets successfully, except in + * the degenerate case where they consist of data from a single stream. + * + * The repacketizing process starts with creating a repacketizer state, either + * by calling opus_repacketizer_create() or by allocating the memory yourself, + * e.g., + * @code + * OpusRepacketizer *rp; + * rp = (OpusRepacketizer*)malloc(opus_repacketizer_get_size()); + * if (rp != NULL) + * opus_repacketizer_init(rp); + * @endcode + * + * Then the application should submit packets with opus_repacketizer_cat(), + * extract new packets with opus_repacketizer_out() or + * opus_repacketizer_out_range(), and then reset the state for the next set of + * input packets via opus_repacketizer_init(). + * + * For example, to split a sequence of packets into individual frames: + * @code + * unsigned char *data; + * int len; + * while (get_next_packet(&data, &len)) + * { + * unsigned char out[1276]; + * opus_int32 out_len; + * int nb_frames; + * int err; + * int i; + * err = opus_repacketizer_cat(rp, data, len); + * if (err != OPUS_OK) + * { + * release_packet(data); + * return err; + * } + * nb_frames = opus_repacketizer_get_nb_frames(rp); + * for (i = 0; i < nb_frames; i++) + * { + * out_len = opus_repacketizer_out_range(rp, i, i+1, out, sizeof(out)); + * if (out_len < 0) + * { + * release_packet(data); + * return (int)out_len; + * } + * output_next_packet(out, out_len); + * } + * opus_repacketizer_init(rp); + * release_packet(data); + * } + * @endcode + * + * Alternatively, to combine a sequence of frames into packets that each + * contain up to TARGET_DURATION_MS milliseconds of data: + * @code + * // The maximum number of packets with duration TARGET_DURATION_MS occurs + * // when the frame size is 2.5 ms, for a total of (TARGET_DURATION_MS*2/5) + * // packets. + * unsigned char *data[(TARGET_DURATION_MS*2/5)+1]; + * opus_int32 len[(TARGET_DURATION_MS*2/5)+1]; + * int nb_packets; + * unsigned char out[1277*(TARGET_DURATION_MS*2/2)]; + * opus_int32 out_len; + * int prev_toc; + * nb_packets = 0; + * while (get_next_packet(data+nb_packets, len+nb_packets)) + * { + * int nb_frames; + * int err; + * nb_frames = opus_packet_get_nb_frames(data[nb_packets], len[nb_packets]); + * if (nb_frames < 1) + * { + * release_packets(data, nb_packets+1); + * return nb_frames; + * } + * nb_frames += opus_repacketizer_get_nb_frames(rp); + * // If adding the next packet would exceed our target, or it has an + * // incompatible TOC sequence, output the packets we already have before + * // submitting it. + * // N.B., The nb_packets > 0 check ensures we've submitted at least one + * // packet since the last call to opus_repacketizer_init(). Otherwise a + * // single packet longer than TARGET_DURATION_MS would cause us to try to + * // output an (invalid) empty packet. It also ensures that prev_toc has + * // been set to a valid value. Additionally, len[nb_packets] > 0 is + * // guaranteed by the call to opus_packet_get_nb_frames() above, so the + * // reference to data[nb_packets][0] should be valid. + * if (nb_packets > 0 && ( + * ((prev_toc & 0xFC) != (data[nb_packets][0] & 0xFC)) || + * opus_packet_get_samples_per_frame(data[nb_packets], 48000)*nb_frames > + * TARGET_DURATION_MS*48)) + * { + * out_len = opus_repacketizer_out(rp, out, sizeof(out)); + * if (out_len < 0) + * { + * release_packets(data, nb_packets+1); + * return (int)out_len; + * } + * output_next_packet(out, out_len); + * opus_repacketizer_init(rp); + * release_packets(data, nb_packets); + * data[0] = data[nb_packets]; + * len[0] = len[nb_packets]; + * nb_packets = 0; + * } + * err = opus_repacketizer_cat(rp, data[nb_packets], len[nb_packets]); + * if (err != OPUS_OK) + * { + * release_packets(data, nb_packets+1); + * return err; + * } + * prev_toc = data[nb_packets][0]; + * nb_packets++; + * } + * // Output the final, partial packet. + * if (nb_packets > 0) + * { + * out_len = opus_repacketizer_out(rp, out, sizeof(out)); + * release_packets(data, nb_packets); + * if (out_len < 0) + * return (int)out_len; + * output_next_packet(out, out_len); + * } + * @endcode + * + * An alternate way of merging packets is to simply call opus_repacketizer_cat() + * unconditionally until it fails. At that point, the merged packet can be + * obtained with opus_repacketizer_out() and the input packet for which + * opus_repacketizer_cat() needs to be re-added to a newly reinitialized + * repacketizer state. + */ + +typedef struct OpusRepacketizer OpusRepacketizer; + +/** Gets the size of an OpusRepacketizer structure. + * @returns The size in bytes. + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_repacketizer_get_size(void); + +/** (Re)initializes a previously allocated repacketizer state. + * The state must be at least the size returned by opus_repacketizer_get_size(). + * This can be used for applications which use their own allocator instead of + * malloc(). + * It must also be called to reset the queue of packets waiting to be + * repacketized, which is necessary if the maximum packet duration of 120 ms + * is reached or if you wish to submit packets with a different Opus + * configuration (coding mode, audio bandwidth, frame size, or channel count). + * Failure to do so will prevent a new packet from being added with + * opus_repacketizer_cat(). + * @see opus_repacketizer_create + * @see opus_repacketizer_get_size + * @see opus_repacketizer_cat + * @param rp OpusRepacketizer*: The repacketizer state to + * (re)initialize. + * @returns A pointer to the same repacketizer state that was passed in. + */ +OPUS_EXPORT OpusRepacketizer *opus_repacketizer_init(OpusRepacketizer *rp) OPUS_ARG_NONNULL(1); + +/** Allocates memory and initializes the new repacketizer with + * opus_repacketizer_init(). + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT OpusRepacketizer *opus_repacketizer_create(void); + +/** Frees an OpusRepacketizer allocated by + * opus_repacketizer_create(). + * @param[in] rp OpusRepacketizer*: State to be freed. + */ +OPUS_EXPORT void opus_repacketizer_destroy(OpusRepacketizer *rp); + +/** Add a packet to the current repacketizer state. + * This packet must match the configuration of any packets already submitted + * for repacketization since the last call to opus_repacketizer_init(). + * This means that it must have the same coding mode, audio bandwidth, frame + * size, and channel count. + * This can be checked in advance by examining the top 6 bits of the first + * byte of the packet, and ensuring they match the top 6 bits of the first + * byte of any previously submitted packet. + * The total duration of audio in the repacketizer state also must not exceed + * 120 ms, the maximum duration of a single packet, after adding this packet. + * + * The contents of the current repacketizer state can be extracted into new + * packets using opus_repacketizer_out() or opus_repacketizer_out_range(). + * + * In order to add a packet with a different configuration or to add more + * audio beyond 120 ms, you must clear the repacketizer state by calling + * opus_repacketizer_init(). + * If a packet is too large to add to the current repacketizer state, no part + * of it is added, even if it contains multiple frames, some of which might + * fit. + * If you wish to be able to add parts of such packets, you should first use + * another repacketizer to split the packet into pieces and add them + * individually. + * @see opus_repacketizer_out_range + * @see opus_repacketizer_out + * @see opus_repacketizer_init + * @param rp OpusRepacketizer*: The repacketizer state to which to + * add the packet. + * @param[in] data const unsigned char*: The packet data. + * The application must ensure + * this pointer remains valid + * until the next call to + * opus_repacketizer_init() or + * opus_repacketizer_destroy(). + * @param len opus_int32: The number of bytes in the packet data. + * @returns An error code indicating whether or not the operation succeeded. + * @retval #OPUS_OK The packet's contents have been added to the repacketizer + * state. + * @retval #OPUS_INVALID_PACKET The packet did not have a valid TOC sequence, + * the packet's TOC sequence was not compatible + * with previously submitted packets (because + * the coding mode, audio bandwidth, frame size, + * or channel count did not match), or adding + * this packet would increase the total amount of + * audio stored in the repacketizer state to more + * than 120 ms. + */ +OPUS_EXPORT int opus_repacketizer_cat(OpusRepacketizer *rp, const unsigned char *data, opus_int32 len) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2); + + +/** Construct a new packet from data previously submitted to the repacketizer + * state via opus_repacketizer_cat(). + * @param rp OpusRepacketizer*: The repacketizer state from which to + * construct the new packet. + * @param begin int: The index of the first frame in the current + * repacketizer state to include in the output. + * @param end int: One past the index of the last frame in the + * current repacketizer state to include in the + * output. + * @param[out] data const unsigned char*: The buffer in which to + * store the output packet. + * @param maxlen opus_int32: The maximum number of bytes to store in + * the output buffer. In order to guarantee + * success, this should be at least + * 1276 for a single frame, + * or for multiple frames, + * 1277*(end-begin). + * However, 1*(end-begin) plus + * the size of all packet data submitted to + * the repacketizer since the last call to + * opus_repacketizer_init() or + * opus_repacketizer_create() is also + * sufficient, and possibly much smaller. + * @returns The total size of the output packet on success, or an error code + * on failure. + * @retval #OPUS_BAD_ARG [begin,end) was an invalid range of + * frames (begin < 0, begin >= end, or end > + * opus_repacketizer_get_nb_frames()). + * @retval #OPUS_BUFFER_TOO_SMALL \a maxlen was insufficient to contain the + * complete output packet. + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT opus_int32 opus_repacketizer_out_range(OpusRepacketizer *rp, int begin, int end, unsigned char *data, opus_int32 maxlen) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(4); + +/** Return the total number of frames contained in packet data submitted to + * the repacketizer state so far via opus_repacketizer_cat() since the last + * call to opus_repacketizer_init() or opus_repacketizer_create(). + * This defines the valid range of packets that can be extracted with + * opus_repacketizer_out_range() or opus_repacketizer_out(). + * @param rp OpusRepacketizer*: The repacketizer state containing the + * frames. + * @returns The total number of frames contained in the packet data submitted + * to the repacketizer state. + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_repacketizer_get_nb_frames(OpusRepacketizer *rp) OPUS_ARG_NONNULL(1); + +/** Construct a new packet from data previously submitted to the repacketizer + * state via opus_repacketizer_cat(). + * This is a convenience routine that returns all the data submitted so far + * in a single packet. + * It is equivalent to calling + * @code + * opus_repacketizer_out_range(rp, 0, opus_repacketizer_get_nb_frames(rp), + * data, maxlen) + * @endcode + * @param rp OpusRepacketizer*: The repacketizer state from which to + * construct the new packet. + * @param[out] data const unsigned char*: The buffer in which to + * store the output packet. + * @param maxlen opus_int32: The maximum number of bytes to store in + * the output buffer. In order to guarantee + * success, this should be at least + * 1277*opus_repacketizer_get_nb_frames(rp). + * However, + * 1*opus_repacketizer_get_nb_frames(rp) + * plus the size of all packet data + * submitted to the repacketizer since the + * last call to opus_repacketizer_init() or + * opus_repacketizer_create() is also + * sufficient, and possibly much smaller. + * @returns The total size of the output packet on success, or an error code + * on failure. + * @retval #OPUS_BUFFER_TOO_SMALL \a maxlen was insufficient to contain the + * complete output packet. + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT opus_int32 opus_repacketizer_out(OpusRepacketizer *rp, unsigned char *data, opus_int32 maxlen) OPUS_ARG_NONNULL(1); + +/**@}*/ + +#ifdef __cplusplus +} +#endif + +#endif /* OPUS_H */ diff --git a/jni/libopus/inc/opus_custom.h b/jni/libopus/inc/opus_custom.h new file mode 100644 index 00000000..e7861d6f --- /dev/null +++ b/jni/libopus/inc/opus_custom.h @@ -0,0 +1,329 @@ +/* Copyright (c) 2007-2008 CSIRO + Copyright (c) 2007-2009 Xiph.Org Foundation + Copyright (c) 2008-2012 Gregory Maxwell + Written by Jean-Marc Valin and Gregory Maxwell */ +/* + 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 COPYRIGHT OWNER + 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. +*/ + +/** + @file opus_custom.h + @brief Opus-Custom reference implementation API + */ + +#ifndef OPUS_CUSTOM_H +#define OPUS_CUSTOM_H + +#include "opus_defines.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef CUSTOM_MODES +#define OPUS_CUSTOM_EXPORT OPUS_EXPORT +#define OPUS_CUSTOM_EXPORT_STATIC OPUS_EXPORT +#else +#define OPUS_CUSTOM_EXPORT +#ifdef CELT_C +#define OPUS_CUSTOM_EXPORT_STATIC static inline +#else +#define OPUS_CUSTOM_EXPORT_STATIC +#endif +#endif + +/** @defgroup opus_custom Opus Custom + * @{ + * Opus Custom is an optional part of the Opus specification and + * reference implementation which uses a distinct API from the regular + * API and supports frame sizes that are not normally supported.\ Use + * of Opus Custom is discouraged for all but very special applications + * for which a frame size different from 2.5, 5, 10, or 20 ms is needed + * (for either complexity or latency reasons) and where interoperability + * is less important. + * + * In addition to the interoperability limitations the use of Opus custom + * disables a substantial chunk of the codec and generally lowers the + * quality available at a given bitrate. Normally when an application needs + * a different frame size from the codec it should buffer to match the + * sizes but this adds a small amount of delay which may be important + * in some very low latency applications. Some transports (especially + * constant rate RF transports) may also work best with frames of + * particular durations. + * + * Libopus only supports custom modes if they are enabled at compile time. + * + * The Opus Custom API is similar to the regular API but the + * @ref opus_encoder_create and @ref opus_decoder_create calls take + * an additional mode parameter which is a structure produced by + * a call to @ref opus_custom_mode_create. Both the encoder and decoder + * must create a mode using the same sample rate (fs) and frame size + * (frame size) so these parameters must either be signaled out of band + * or fixed in a particular implementation. + * + * Similar to regular Opus the custom modes support on the fly frame size + * switching, but the sizes available depend on the particular frame size in + * use. For some initial frame sizes on a single on the fly size is available. + */ + +/** Contains the state of an encoder. One encoder state is needed + for each stream. It is initialized once at the beginning of the + stream. Do *not* re-initialize the state for every frame. + @brief Encoder state + */ +typedef struct OpusCustomEncoder OpusCustomEncoder; + +/** State of the decoder. One decoder state is needed for each stream. + It is initialized once at the beginning of the stream. Do *not* + re-initialize the state for every frame. + @brief Decoder state + */ +typedef struct OpusCustomDecoder OpusCustomDecoder; + +/** The mode contains all the information necessary to create an + encoder. Both the encoder and decoder need to be initialized + with exactly the same mode, otherwise the output will be + corrupted. + @brief Mode configuration + */ +typedef struct OpusCustomMode OpusCustomMode; + +/** 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 [in] Fs int: Sampling rate (8000 to 96000 Hz) + * @param [in] frame_size int: Number of samples (per channel) to encode in each + * packet (64 - 1024, prime factorization must contain zero or more 2s, 3s, or 5s and no other primes) + * @param [out] error int*: Returned error code (if NULL, no error will be returned) + * @return A newly created mode + */ +OPUS_CUSTOM_EXPORT OPUS_WARN_UNUSED_RESULT OpusCustomMode *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 [in] mode OpusCustomMode*: Mode to be freed. + */ +OPUS_CUSTOM_EXPORT void opus_custom_mode_destroy(OpusCustomMode *mode); + +/* Encoder */ +/** Gets the size of an OpusCustomEncoder structure. + * @param [in] mode OpusCustomMode *: Mode configuration + * @param [in] channels int: Number of channels + * @returns size + */ +OPUS_CUSTOM_EXPORT_STATIC OPUS_WARN_UNUSED_RESULT int opus_custom_encoder_get_size( + const OpusCustomMode *mode, + int channels +) OPUS_ARG_NONNULL(1); + +/** Creates a new encoder state. Each stream needs its own encoder + * state (can't be shared across simultaneous streams). + * @param [in] mode OpusCustomMode*: Contains all the information about the characteristics of + * the stream (must be the same characteristics as used for the + * decoder) + * @param [in] channels int: Number of channels + * @param [out] error int*: Returns an error code + * @return Newly created encoder state. +*/ +OPUS_CUSTOM_EXPORT OPUS_WARN_UNUSED_RESULT OpusCustomEncoder *opus_custom_encoder_create( + const OpusCustomMode *mode, + int channels, + int *error +) OPUS_ARG_NONNULL(1); + +/** Initializes a previously allocated encoder state + * The memory pointed to by st must be the size returned by opus_custom_encoder_get_size. + * This is intended for applications which use their own allocator instead of malloc. + * @see opus_custom_encoder_create(),opus_custom_encoder_get_size() + * To reset a previously initialized state use the OPUS_RESET_STATE CTL. + * @param [in] st OpusCustomEncoder*: Encoder state + * @param [in] mode OpusCustomMode *: Contains all the information about the characteristics of + * the stream (must be the same characteristics as used for the + * decoder) + * @param [in] channels int: Number of channels + * @return OPUS_OK Success or @ref opus_errorcodes + */ +OPUS_CUSTOM_EXPORT_STATIC int opus_custom_encoder_init( + OpusCustomEncoder *st, + const OpusCustomMode *mode, + int channels +) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2); + +/** Destroys a an encoder state. + * @param[in] st OpusCustomEncoder*: State to be freed. + */ +OPUS_CUSTOM_EXPORT void opus_custom_encoder_destroy(OpusCustomEncoder *st); + +/** Encodes a frame of audio. + * @param [in] st OpusCustomEncoder*: Encoder state + * @param [in] pcm float*: 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 dynamic range. There must be exactly + * frame_size samples per channel. + * @param [in] frame_size int: Number of samples per frame of input signal + * @param [out] compressed char *: The compressed data is written here. This may not alias pcm and must be at least maxCompressedBytes long. + * @param [in] maxCompressedBytes int: Maximum number of bytes to use for compressing the frame + * (can change from one frame to another) + * @return Number of bytes written to "compressed". + * 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_CUSTOM_EXPORT OPUS_WARN_UNUSED_RESULT int opus_custom_encode_float( + OpusCustomEncoder *st, + const float *pcm, + int frame_size, + unsigned char *compressed, + int maxCompressedBytes +) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2) OPUS_ARG_NONNULL(4); + +/** Encodes a frame of audio. + * @param [in] st OpusCustomEncoder*: Encoder state + * @param [in] pcm opus_int16*: PCM audio in signed 16-bit format (native endian). + * There must be exactly frame_size samples per channel. + * @param [in] frame_size int: Number of samples per frame of input signal + * @param [out] compressed char *: The compressed data is written here. This may not alias pcm and must be at least maxCompressedBytes long. + * @param [in] maxCompressedBytes int: Maximum number of bytes to use for compressing the frame + * (can change from one frame to another) + * @return Number of bytes written to "compressed". + * 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_CUSTOM_EXPORT OPUS_WARN_UNUSED_RESULT int opus_custom_encode( + OpusCustomEncoder *st, + const opus_int16 *pcm, + int frame_size, + unsigned char *compressed, + int maxCompressedBytes +) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2) OPUS_ARG_NONNULL(4); + +/** Perform a CTL function on an Opus custom encoder. + * + * Generally the request and subsequent arguments are generated + * by a convenience macro. + * @see opus_encoderctls + */ +OPUS_CUSTOM_EXPORT int opus_custom_encoder_ctl(OpusCustomEncoder * OPUS_RESTRICT st, int request, ...) OPUS_ARG_NONNULL(1); + +/* Decoder */ + +/** Gets the size of an OpusCustomDecoder structure. + * @param [in] mode OpusCustomMode *: Mode configuration + * @param [in] channels int: Number of channels + * @returns size + */ +OPUS_CUSTOM_EXPORT_STATIC OPUS_WARN_UNUSED_RESULT int opus_custom_decoder_get_size( + const OpusCustomMode *mode, + int channels +) OPUS_ARG_NONNULL(1); + +/** Creates a new decoder state. Each stream needs its own decoder state (can't + * be shared across simultaneous streams). + * @param [in] mode OpusCustomMode: Contains all the information about the characteristics of the + * stream (must be the same characteristics as used for the encoder) + * @param [in] channels int: Number of channels + * @param [out] error int*: Returns an error code + * @return Newly created decoder state. + */ +OPUS_CUSTOM_EXPORT OPUS_WARN_UNUSED_RESULT OpusCustomDecoder *opus_custom_decoder_create( + const OpusCustomMode *mode, + int channels, + int *error +) OPUS_ARG_NONNULL(1); + +/** Initializes a previously allocated decoder state + * The memory pointed to by st must be the size returned by opus_custom_decoder_get_size. + * This is intended for applications which use their own allocator instead of malloc. + * @see opus_custom_decoder_create(),opus_custom_decoder_get_size() + * To reset a previously initialized state use the OPUS_RESET_STATE CTL. + * @param [in] st OpusCustomDecoder*: Decoder state + * @param [in] mode OpusCustomMode *: Contains all the information about the characteristics of + * the stream (must be the same characteristics as used for the + * encoder) + * @param [in] channels int: Number of channels + * @return OPUS_OK Success or @ref opus_errorcodes + */ +OPUS_CUSTOM_EXPORT_STATIC int opus_custom_decoder_init( + OpusCustomDecoder *st, + const OpusCustomMode *mode, + int channels +) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2); + +/** Destroys a an decoder state. + * @param[in] st OpusCustomDecoder*: State to be freed. + */ +OPUS_CUSTOM_EXPORT void opus_custom_decoder_destroy(OpusCustomDecoder *st); + +/** Decode an opus custom frame with floating point output + * @param [in] st OpusCustomDecoder*: Decoder state + * @param [in] data char*: Input payload. Use a NULL pointer to indicate packet loss + * @param [in] len int: Number of bytes in payload + * @param [out] pcm float*: Output signal (interleaved if 2 channels). length + * is frame_size*channels*sizeof(float) + * @param [in] frame_size Number of samples per channel of available space in *pcm. + * @returns Number of decoded samples or @ref opus_errorcodes + */ +OPUS_CUSTOM_EXPORT OPUS_WARN_UNUSED_RESULT int opus_custom_decode_float( + OpusCustomDecoder *st, + const unsigned char *data, + int len, + float *pcm, + int frame_size +) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(4); + +/** Decode an opus custom frame + * @param [in] st OpusCustomDecoder*: Decoder state + * @param [in] data char*: Input payload. Use a NULL pointer to indicate packet loss + * @param [in] len int: Number of bytes in payload + * @param [out] pcm opus_int16*: Output signal (interleaved if 2 channels). length + * is frame_size*channels*sizeof(opus_int16) + * @param [in] frame_size Number of samples per channel of available space in *pcm. + * @returns Number of decoded samples or @ref opus_errorcodes + */ +OPUS_CUSTOM_EXPORT OPUS_WARN_UNUSED_RESULT int opus_custom_decode( + OpusCustomDecoder *st, + const unsigned char *data, + int len, + opus_int16 *pcm, + int frame_size +) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(4); + +/** Perform a CTL function on an Opus custom decoder. + * + * Generally the request and subsequent arguments are generated + * by a convenience macro. + * @see opus_genericctls + */ +OPUS_CUSTOM_EXPORT int opus_custom_decoder_ctl(OpusCustomDecoder * OPUS_RESTRICT st, int request, ...) OPUS_ARG_NONNULL(1); + +/**@}*/ + +#ifdef __cplusplus +} +#endif + +#endif /* OPUS_CUSTOM_H */ diff --git a/jni/libopus/inc/opus_defines.h b/jni/libopus/inc/opus_defines.h new file mode 100644 index 00000000..9fa3ccb5 --- /dev/null +++ b/jni/libopus/inc/opus_defines.h @@ -0,0 +1,655 @@ +/* Copyright (c) 2010-2011 Xiph.Org Foundation, Skype Limited + Written by Jean-Marc Valin and Koen Vos */ +/* + 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 COPYRIGHT OWNER + 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. +*/ + +/** + * @file opus_defines.h + * @brief Opus reference implementation constants + */ + +#ifndef OPUS_DEFINES_H +#define OPUS_DEFINES_H + +#include "opus_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** @defgroup opus_errorcodes Error codes + * @{ + */ +/** No error @hideinitializer*/ +#define OPUS_OK 0 +/** One or more invalid/out of range arguments @hideinitializer*/ +#define OPUS_BAD_ARG -1 +/** The mode struct passed is invalid @hideinitializer*/ +#define OPUS_BUFFER_TOO_SMALL -2 +/** An internal error was detected @hideinitializer*/ +#define OPUS_INTERNAL_ERROR -3 +/** The compressed data passed is corrupted @hideinitializer*/ +#define OPUS_INVALID_PACKET -4 +/** Invalid/unsupported request number @hideinitializer*/ +#define OPUS_UNIMPLEMENTED -5 +/** An encoder or decoder structure is invalid or already freed @hideinitializer*/ +#define OPUS_INVALID_STATE -6 +/** Memory allocation has failed @hideinitializer*/ +#define OPUS_ALLOC_FAIL -7 +/**@}*/ + +/** @cond OPUS_INTERNAL_DOC */ +/**Export control for opus functions */ + +#ifndef OPUS_EXPORT +# if defined(WIN32) +# ifdef OPUS_BUILD +# define OPUS_EXPORT __declspec(dllexport) +# else +# define OPUS_EXPORT +# endif +# elif defined(__GNUC__) && defined(OPUS_BUILD) +# define OPUS_EXPORT __attribute__ ((visibility ("default"))) +# else +# define OPUS_EXPORT +# endif +#endif + +# if !defined(OPUS_GNUC_PREREQ) +# if defined(__GNUC__)&&defined(__GNUC_MINOR__) +# define OPUS_GNUC_PREREQ(_maj,_min) \ + ((__GNUC__<<16)+__GNUC_MINOR__>=((_maj)<<16)+(_min)) +# else +# define OPUS_GNUC_PREREQ(_maj,_min) 0 +# endif +# endif + +#if (!defined(__STDC_VERSION__) || (__STDC_VERSION__ < 199901L) ) +# if OPUS_GNUC_PREREQ(3,0) +# define OPUS_RESTRICT __restrict__ +# elif (defined(_MSC_VER) && _MSC_VER >= 1400) +# define OPUS_RESTRICT __restrict +# else +# define OPUS_RESTRICT +# endif +#else +# define OPUS_RESTRICT restrict +#endif + +/**Warning attributes for opus functions + * NONNULL is not used in OPUS_BUILD to avoid the compiler optimizing out + * some paranoid null checks. */ +#if defined(__GNUC__) && OPUS_GNUC_PREREQ(3, 4) +# define OPUS_WARN_UNUSED_RESULT __attribute__ ((__warn_unused_result__)) +#else +# define OPUS_WARN_UNUSED_RESULT +#endif +#if !defined(OPUS_BUILD) && defined(__GNUC__) && OPUS_GNUC_PREREQ(3, 4) +# define OPUS_ARG_NONNULL(_x) __attribute__ ((__nonnull__(_x))) +#else +# define OPUS_ARG_NONNULL(_x) +#endif + +/** These are the actual Encoder CTL ID numbers. + * They should not be used directly by applications. + * In general, SETs should be even and GETs should be odd.*/ +#define OPUS_SET_APPLICATION_REQUEST 4000 +#define OPUS_GET_APPLICATION_REQUEST 4001 +#define OPUS_SET_BITRATE_REQUEST 4002 +#define OPUS_GET_BITRATE_REQUEST 4003 +#define OPUS_SET_MAX_BANDWIDTH_REQUEST 4004 +#define OPUS_GET_MAX_BANDWIDTH_REQUEST 4005 +#define OPUS_SET_VBR_REQUEST 4006 +#define OPUS_GET_VBR_REQUEST 4007 +#define OPUS_SET_BANDWIDTH_REQUEST 4008 +#define OPUS_GET_BANDWIDTH_REQUEST 4009 +#define OPUS_SET_COMPLEXITY_REQUEST 4010 +#define OPUS_GET_COMPLEXITY_REQUEST 4011 +#define OPUS_SET_INBAND_FEC_REQUEST 4012 +#define OPUS_GET_INBAND_FEC_REQUEST 4013 +#define OPUS_SET_PACKET_LOSS_PERC_REQUEST 4014 +#define OPUS_GET_PACKET_LOSS_PERC_REQUEST 4015 +#define OPUS_SET_DTX_REQUEST 4016 +#define OPUS_GET_DTX_REQUEST 4017 +#define OPUS_SET_VBR_CONSTRAINT_REQUEST 4020 +#define OPUS_GET_VBR_CONSTRAINT_REQUEST 4021 +#define OPUS_SET_FORCE_CHANNELS_REQUEST 4022 +#define OPUS_GET_FORCE_CHANNELS_REQUEST 4023 +#define OPUS_SET_SIGNAL_REQUEST 4024 +#define OPUS_GET_SIGNAL_REQUEST 4025 +#define OPUS_GET_LOOKAHEAD_REQUEST 4027 +/* #define OPUS_RESET_STATE 4028 */ +#define OPUS_GET_SAMPLE_RATE_REQUEST 4029 +#define OPUS_GET_FINAL_RANGE_REQUEST 4031 +#define OPUS_GET_PITCH_REQUEST 4033 +#define OPUS_SET_GAIN_REQUEST 4034 +#define OPUS_GET_GAIN_REQUEST 4045 /* Should have been 4035 */ +#define OPUS_SET_LSB_DEPTH_REQUEST 4036 +#define OPUS_GET_LSB_DEPTH_REQUEST 4037 + +#define OPUS_GET_LAST_PACKET_DURATION_REQUEST 4039 + +/* Don't use 4045, it's already taken by OPUS_GET_GAIN_REQUEST */ + +/* Macros to trigger compilation errors when the wrong types are provided to a CTL */ +#define __opus_check_int(x) (((void)((x) == (opus_int32)0)), (opus_int32)(x)) +#define __opus_check_int_ptr(ptr) ((ptr) + ((ptr) - (opus_int32*)(ptr))) +#define __opus_check_uint_ptr(ptr) ((ptr) + ((ptr) - (opus_uint32*)(ptr))) +/** @endcond */ + +/** @defgroup opus_ctlvalues Pre-defined values for CTL interface + * @see opus_genericctls, opus_encoderctls + * @{ + */ +/* Values for the various encoder CTLs */ +#define OPUS_AUTO -1000 /**opus_int32: Allowed values: 0-10, inclusive. + * + * @hideinitializer */ +#define OPUS_SET_COMPLEXITY(x) OPUS_SET_COMPLEXITY_REQUEST, __opus_check_int(x) +/** Gets the encoder's complexity configuration. + * @see OPUS_SET_COMPLEXITY + * @param[out] x opus_int32 *: Returns a value in the range 0-10, + * inclusive. + * @hideinitializer */ +#define OPUS_GET_COMPLEXITY(x) OPUS_GET_COMPLEXITY_REQUEST, __opus_check_int_ptr(x) + +/** Configures the bitrate in the encoder. + * Rates from 500 to 512000 bits per second are meaningful, as well as the + * special values #OPUS_AUTO and #OPUS_BITRATE_MAX. + * The value #OPUS_BITRATE_MAX can be used to cause the codec to use as much + * rate as it can, which is useful for controlling the rate by adjusting the + * output buffer size. + * @see OPUS_GET_BITRATE + * @param[in] x opus_int32: Bitrate in bits per second. The default + * is determined based on the number of + * channels and the input sampling rate. + * @hideinitializer */ +#define OPUS_SET_BITRATE(x) OPUS_SET_BITRATE_REQUEST, __opus_check_int(x) +/** Gets the encoder's bitrate configuration. + * @see OPUS_SET_BITRATE + * @param[out] x opus_int32 *: Returns the bitrate in bits per second. + * The default is determined based on the + * number of channels and the input + * sampling rate. + * @hideinitializer */ +#define OPUS_GET_BITRATE(x) OPUS_GET_BITRATE_REQUEST, __opus_check_int_ptr(x) + +/** Enables or disables variable bitrate (VBR) in the encoder. + * The configured bitrate may not be met exactly because frames must + * be an integer number of bytes in length. + * @warning Only the MDCT mode of Opus can provide hard CBR behavior. + * @see OPUS_GET_VBR + * @see OPUS_SET_VBR_CONSTRAINT + * @param[in] x opus_int32: Allowed values: + *
+ *
0
Hard CBR. For LPC/hybrid modes at very low bit-rate, this can + * cause noticeable quality degradation.
+ *
1
VBR (default). The exact type of VBR is controlled by + * #OPUS_SET_VBR_CONSTRAINT.
+ *
+ * @hideinitializer */ +#define OPUS_SET_VBR(x) OPUS_SET_VBR_REQUEST, __opus_check_int(x) +/** Determine if variable bitrate (VBR) is enabled in the encoder. + * @see OPUS_SET_VBR + * @see OPUS_GET_VBR_CONSTRAINT + * @param[out] x opus_int32 *: Returns one of the following values: + *
+ *
0
Hard CBR.
+ *
1
VBR (default). The exact type of VBR may be retrieved via + * #OPUS_GET_VBR_CONSTRAINT.
+ *
+ * @hideinitializer */ +#define OPUS_GET_VBR(x) OPUS_GET_VBR_REQUEST, __opus_check_int_ptr(x) + +/** Enables or disables constrained VBR in the encoder. + * This setting is ignored when the encoder is in CBR mode. + * @warning Only the MDCT mode of Opus currently heeds the constraint. + * Speech mode ignores it completely, hybrid mode may fail to obey it + * if the LPC layer uses more bitrate than the constraint would have + * permitted. + * @see OPUS_GET_VBR_CONSTRAINT + * @see OPUS_SET_VBR + * @param[in] x opus_int32: Allowed values: + *
+ *
0
Unconstrained VBR.
+ *
1
Constrained VBR (default). This creates a maximum of one + * frame of buffering delay assuming a transport with a + * serialization speed of the nominal bitrate.
+ *
+ * @hideinitializer */ +#define OPUS_SET_VBR_CONSTRAINT(x) OPUS_SET_VBR_CONSTRAINT_REQUEST, __opus_check_int(x) +/** Determine if constrained VBR is enabled in the encoder. + * @see OPUS_SET_VBR_CONSTRAINT + * @see OPUS_GET_VBR + * @param[out] x opus_int32 *: Returns one of the following values: + *
+ *
0
Unconstrained VBR.
+ *
1
Constrained VBR (default).
+ *
+ * @hideinitializer */ +#define OPUS_GET_VBR_CONSTRAINT(x) OPUS_GET_VBR_CONSTRAINT_REQUEST, __opus_check_int_ptr(x) + +/** Configures mono/stereo forcing in the encoder. + * This can force the encoder to produce packets encoded as either mono or + * stereo, regardless of the format of the input audio. This is useful when + * the caller knows that the input signal is currently a mono source embedded + * in a stereo stream. + * @see OPUS_GET_FORCE_CHANNELS + * @param[in] x opus_int32: Allowed values: + *
+ *
#OPUS_AUTO
Not forced (default)
+ *
1
Forced mono
+ *
2
Forced stereo
+ *
+ * @hideinitializer */ +#define OPUS_SET_FORCE_CHANNELS(x) OPUS_SET_FORCE_CHANNELS_REQUEST, __opus_check_int(x) +/** Gets the encoder's forced channel configuration. + * @see OPUS_SET_FORCE_CHANNELS + * @param[out] x opus_int32 *: + *
+ *
#OPUS_AUTO
Not forced (default)
+ *
1
Forced mono
+ *
2
Forced stereo
+ *
+ * @hideinitializer */ +#define OPUS_GET_FORCE_CHANNELS(x) OPUS_GET_FORCE_CHANNELS_REQUEST, __opus_check_int_ptr(x) + +/** Configures the maximum bandpass that the encoder will select automatically. + * Applications should normally use this instead of #OPUS_SET_BANDWIDTH + * (leaving that set to the default, #OPUS_AUTO). This allows the + * application to set an upper bound based on the type of input it is + * providing, but still gives the encoder the freedom to reduce the bandpass + * when the bitrate becomes too low, for better overall quality. + * @see OPUS_GET_MAX_BANDWIDTH + * @param[in] x opus_int32: Allowed values: + *
+ *
OPUS_BANDWIDTH_NARROWBAND
4 kHz passband
+ *
OPUS_BANDWIDTH_MEDIUMBAND
6 kHz passband
+ *
OPUS_BANDWIDTH_WIDEBAND
8 kHz passband
+ *
OPUS_BANDWIDTH_SUPERWIDEBAND
12 kHz passband
+ *
OPUS_BANDWIDTH_FULLBAND
20 kHz passband (default)
+ *
+ * @hideinitializer */ +#define OPUS_SET_MAX_BANDWIDTH(x) OPUS_SET_MAX_BANDWIDTH_REQUEST, __opus_check_int(x) + +/** Gets the encoder's configured maximum allowed bandpass. + * @see OPUS_SET_MAX_BANDWIDTH + * @param[out] x opus_int32 *: Allowed values: + *
+ *
#OPUS_BANDWIDTH_NARROWBAND
4 kHz passband
+ *
#OPUS_BANDWIDTH_MEDIUMBAND
6 kHz passband
+ *
#OPUS_BANDWIDTH_WIDEBAND
8 kHz passband
+ *
#OPUS_BANDWIDTH_SUPERWIDEBAND
12 kHz passband
+ *
#OPUS_BANDWIDTH_FULLBAND
20 kHz passband (default)
+ *
+ * @hideinitializer */ +#define OPUS_GET_MAX_BANDWIDTH(x) OPUS_GET_MAX_BANDWIDTH_REQUEST, __opus_check_int_ptr(x) + +/** Sets the encoder's bandpass to a specific value. + * This prevents the encoder from automatically selecting the bandpass based + * on the available bitrate. If an application knows the bandpass of the input + * audio it is providing, it should normally use #OPUS_SET_MAX_BANDWIDTH + * instead, which still gives the encoder the freedom to reduce the bandpass + * when the bitrate becomes too low, for better overall quality. + * @see OPUS_GET_BANDWIDTH + * @param[in] x opus_int32: Allowed values: + *
+ *
#OPUS_AUTO
(default)
+ *
#OPUS_BANDWIDTH_NARROWBAND
4 kHz passband
+ *
#OPUS_BANDWIDTH_MEDIUMBAND
6 kHz passband
+ *
#OPUS_BANDWIDTH_WIDEBAND
8 kHz passband
+ *
#OPUS_BANDWIDTH_SUPERWIDEBAND
12 kHz passband
+ *
#OPUS_BANDWIDTH_FULLBAND
20 kHz passband
+ *
+ * @hideinitializer */ +#define OPUS_SET_BANDWIDTH(x) OPUS_SET_BANDWIDTH_REQUEST, __opus_check_int(x) + +/** Configures the type of signal being encoded. + * This is a hint which helps the encoder's mode selection. + * @see OPUS_GET_SIGNAL + * @param[in] x opus_int32: Allowed values: + *
+ *
#OPUS_AUTO
(default)
+ *
#OPUS_SIGNAL_VOICE
Bias thresholds towards choosing LPC or Hybrid modes.
+ *
#OPUS_SIGNAL_MUSIC
Bias thresholds towards choosing MDCT modes.
+ *
+ * @hideinitializer */ +#define OPUS_SET_SIGNAL(x) OPUS_SET_SIGNAL_REQUEST, __opus_check_int(x) +/** Gets the encoder's configured signal type. + * @see OPUS_SET_SIGNAL + * @param[out] x opus_int32 *: Returns one of the following values: + *
+ *
#OPUS_AUTO
(default)
+ *
#OPUS_SIGNAL_VOICE
Bias thresholds towards choosing LPC or Hybrid modes.
+ *
#OPUS_SIGNAL_MUSIC
Bias thresholds towards choosing MDCT modes.
+ *
+ * @hideinitializer */ +#define OPUS_GET_SIGNAL(x) OPUS_GET_SIGNAL_REQUEST, __opus_check_int_ptr(x) + + +/** Configures the encoder's intended application. + * The initial value is a mandatory argument to the encoder_create function. + * @see OPUS_GET_APPLICATION + * @param[in] x opus_int32: Returns one of the following values: + *
+ *
#OPUS_APPLICATION_VOIP
+ *
Process signal for improved speech intelligibility.
+ *
#OPUS_APPLICATION_AUDIO
+ *
Favor faithfulness to the original input.
+ *
#OPUS_APPLICATION_RESTRICTED_LOWDELAY
+ *
Configure the minimum possible coding delay by disabling certain modes + * of operation.
+ *
+ * @hideinitializer */ +#define OPUS_SET_APPLICATION(x) OPUS_SET_APPLICATION_REQUEST, __opus_check_int(x) +/** Gets the encoder's configured application. + * @see OPUS_SET_APPLICATION + * @param[out] x opus_int32 *: Returns one of the following values: + *
+ *
#OPUS_APPLICATION_VOIP
+ *
Process signal for improved speech intelligibility.
+ *
#OPUS_APPLICATION_AUDIO
+ *
Favor faithfulness to the original input.
+ *
#OPUS_APPLICATION_RESTRICTED_LOWDELAY
+ *
Configure the minimum possible coding delay by disabling certain modes + * of operation.
+ *
+ * @hideinitializer */ +#define OPUS_GET_APPLICATION(x) OPUS_GET_APPLICATION_REQUEST, __opus_check_int_ptr(x) + +/** Gets the sampling rate the encoder or decoder was initialized with. + * This simply returns the Fs value passed to opus_encoder_init() + * or opus_decoder_init(). + * @param[out] x opus_int32 *: Sampling rate of encoder or decoder. + * @hideinitializer + */ +#define OPUS_GET_SAMPLE_RATE(x) OPUS_GET_SAMPLE_RATE_REQUEST, __opus_check_int_ptr(x) + +/** Gets the total samples of delay added by the entire codec. + * This can be queried by the encoder and then the provided number of samples can be + * skipped on from the start of the decoder's output to provide time aligned input + * and output. From the perspective of a decoding application the real data begins this many + * samples late. + * + * The decoder contribution to this delay is identical for all decoders, but the + * encoder portion of the delay may vary from implementation to implementation, + * version to version, or even depend on the encoder's initial configuration. + * Applications needing delay compensation should call this CTL rather than + * hard-coding a value. + * @param[out] x opus_int32 *: Number of lookahead samples + * @hideinitializer */ +#define OPUS_GET_LOOKAHEAD(x) OPUS_GET_LOOKAHEAD_REQUEST, __opus_check_int_ptr(x) + +/** Configures the encoder's use of inband forward error correction (FEC). + * @note This is only applicable to the LPC layer + * @see OPUS_GET_INBAND_FEC + * @param[in] x opus_int32: Allowed values: + *
+ *
0
Disable inband FEC (default).
+ *
1
Enable inband FEC.
+ *
+ * @hideinitializer */ +#define OPUS_SET_INBAND_FEC(x) OPUS_SET_INBAND_FEC_REQUEST, __opus_check_int(x) +/** Gets encoder's configured use of inband forward error correction. + * @see OPUS_SET_INBAND_FEC + * @param[out] x opus_int32 *: Returns one of the following values: + *
+ *
0
Inband FEC disabled (default).
+ *
1
Inband FEC enabled.
+ *
+ * @hideinitializer */ +#define OPUS_GET_INBAND_FEC(x) OPUS_GET_INBAND_FEC_REQUEST, __opus_check_int_ptr(x) + +/** Configures the encoder's expected packet loss percentage. + * Higher values with trigger progressively more loss resistant behavior in the encoder + * at the expense of quality at a given bitrate in the lossless case, but greater quality + * under loss. + * @see OPUS_GET_PACKET_LOSS_PERC + * @param[in] x opus_int32: Loss percentage in the range 0-100, inclusive (default: 0). + * @hideinitializer */ +#define OPUS_SET_PACKET_LOSS_PERC(x) OPUS_SET_PACKET_LOSS_PERC_REQUEST, __opus_check_int(x) +/** Gets the encoder's configured packet loss percentage. + * @see OPUS_SET_PACKET_LOSS_PERC + * @param[out] x opus_int32 *: Returns the configured loss percentage + * in the range 0-100, inclusive (default: 0). + * @hideinitializer */ +#define OPUS_GET_PACKET_LOSS_PERC(x) OPUS_GET_PACKET_LOSS_PERC_REQUEST, __opus_check_int_ptr(x) + +/** Configures the encoder's use of discontinuous transmission (DTX). + * @note This is only applicable to the LPC layer + * @see OPUS_GET_DTX + * @param[in] x opus_int32: Allowed values: + *
+ *
0
Disable DTX (default).
+ *
1
Enabled DTX.
+ *
+ * @hideinitializer */ +#define OPUS_SET_DTX(x) OPUS_SET_DTX_REQUEST, __opus_check_int(x) +/** Gets encoder's configured use of discontinuous transmission. + * @see OPUS_SET_DTX + * @param[out] x opus_int32 *: Returns one of the following values: + *
+ *
0
DTX disabled (default).
+ *
1
DTX enabled.
+ *
+ * @hideinitializer */ +#define OPUS_GET_DTX(x) OPUS_GET_DTX_REQUEST, __opus_check_int_ptr(x) +/** Configures the depth of signal being encoded. + * This is a hint which helps the encoder identify silence and near-silence. + * @see OPUS_GET_LSB_DEPTH + * @param[in] x opus_int32: Input precision in bits, between 8 and 24 + * (default: 24). + * @hideinitializer */ +#define OPUS_SET_LSB_DEPTH(x) OPUS_SET_LSB_DEPTH_REQUEST, __opus_check_int(x) +/** Gets the encoder's configured signal depth. + * @see OPUS_SET_LSB_DEPTH + * @param[out] x opus_int32 *: Input precision in bits, between 8 and + * 24 (default: 24). + * @hideinitializer */ +#define OPUS_GET_LSB_DEPTH(x) OPUS_GET_LSB_DEPTH_REQUEST, __opus_check_int_ptr(x) + +/** Gets the duration (in samples) of the last packet successfully decoded or concealed. + * @param[out] x opus_int32 *: Number of samples (at current sampling rate). + * @hideinitializer */ +#define OPUS_GET_LAST_PACKET_DURATION(x) OPUS_GET_LAST_PACKET_DURATION_REQUEST, __opus_check_int_ptr(x) +/**@}*/ + +/** @defgroup opus_genericctls Generic CTLs + * + * These macros are used with the \c opus_decoder_ctl and + * \c opus_encoder_ctl calls to generate a particular + * request. + * + * When called on an \c OpusDecoder they apply to that + * particular decoder instance. When called on an + * \c OpusEncoder they apply to the corresponding setting + * on that encoder instance, if present. + * + * Some usage examples: + * + * @code + * int ret; + * opus_int32 pitch; + * ret = opus_decoder_ctl(dec_ctx, OPUS_GET_PITCH(&pitch)); + * if (ret == OPUS_OK) return ret; + * + * opus_encoder_ctl(enc_ctx, OPUS_RESET_STATE); + * opus_decoder_ctl(dec_ctx, OPUS_RESET_STATE); + * + * opus_int32 enc_bw, dec_bw; + * opus_encoder_ctl(enc_ctx, OPUS_GET_BANDWIDTH(&enc_bw)); + * opus_decoder_ctl(dec_ctx, OPUS_GET_BANDWIDTH(&dec_bw)); + * if (enc_bw != dec_bw) { + * printf("packet bandwidth mismatch!\n"); + * } + * @endcode + * + * @see opus_encoder, opus_decoder_ctl, opus_encoder_ctl, opus_decoderctls, opus_encoderctls + * @{ + */ + +/** Resets the codec state to be equivalent to a freshly initialized state. + * This should be called when switching streams in order to prevent + * the back to back decoding from giving different results from + * one at a time decoding. + * @hideinitializer */ +#define OPUS_RESET_STATE 4028 + +/** Gets the final state of the codec's entropy coder. + * This is used for testing purposes, + * The encoder and decoder state should be identical after coding a payload + * (assuming no data corruption or software bugs) + * + * @param[out] x opus_uint32 *: Entropy coder state + * + * @hideinitializer */ +#define OPUS_GET_FINAL_RANGE(x) OPUS_GET_FINAL_RANGE_REQUEST, __opus_check_uint_ptr(x) + +/** Gets the pitch of the last decoded frame, if available. + * This can be used for any post-processing algorithm requiring the use of pitch, + * e.g. time stretching/shortening. If the last frame was not voiced, or if the + * pitch was not coded in the frame, then zero is returned. + * + * This CTL is only implemented for decoder instances. + * + * @param[out] x opus_int32 *: pitch period at 48 kHz (or 0 if not available) + * + * @hideinitializer */ +#define OPUS_GET_PITCH(x) OPUS_GET_PITCH_REQUEST, __opus_check_int_ptr(x) + +/** Gets the encoder's configured bandpass or the decoder's last bandpass. + * @see OPUS_SET_BANDWIDTH + * @param[out] x opus_int32 *: Returns one of the following values: + *
+ *
#OPUS_AUTO
(default)
+ *
#OPUS_BANDWIDTH_NARROWBAND
4 kHz passband
+ *
#OPUS_BANDWIDTH_MEDIUMBAND
6 kHz passband
+ *
#OPUS_BANDWIDTH_WIDEBAND
8 kHz passband
+ *
#OPUS_BANDWIDTH_SUPERWIDEBAND
12 kHz passband
+ *
#OPUS_BANDWIDTH_FULLBAND
20 kHz passband
+ *
+ * @hideinitializer */ +#define OPUS_GET_BANDWIDTH(x) OPUS_GET_BANDWIDTH_REQUEST, __opus_check_int_ptr(x) + +/**@}*/ + +/** @defgroup opus_decoderctls Decoder related CTLs + * @see opus_genericctls, opus_encoderctls, opus_decoder + * @{ + */ + +/** Configures decoder gain adjustment. + * Scales the decoded output by a factor specified in Q8 dB units. + * This has a maximum range of -32768 to 32767 inclusive, and returns + * OPUS_BAD_ARG otherwise. The default is zero indicating no adjustment. + * This setting survives decoder reset. + * + * gain = pow(10, x/(20.0*256)) + * + * @param[in] x opus_int32: Amount to scale PCM signal by in Q8 dB units. + * @hideinitializer */ +#define OPUS_SET_GAIN(x) OPUS_SET_GAIN_REQUEST, __opus_check_int(x) +/** Gets the decoder's configured gain adjustment. @see OPUS_SET_GAIN + * + * @param[out] x opus_int32 *: Amount to scale PCM signal by in Q8 dB units. + * @hideinitializer */ +#define OPUS_GET_GAIN(x) OPUS_GET_GAIN_REQUEST, __opus_check_int_ptr(x) + +/**@}*/ + +/** @defgroup opus_libinfo Opus library information functions + * @{ + */ + +/** Converts an opus error code into a human readable string. + * + * @param[in] error int: Error number + * @returns Error string + */ +OPUS_EXPORT const char *opus_strerror(int error); + +/** Gets the libopus version string. + * + * @returns Version string + */ +OPUS_EXPORT const char *opus_get_version_string(void); +/**@}*/ + +#ifdef __cplusplus +} +#endif + +#endif /* OPUS_DEFINES_H */ diff --git a/jni/libopus/inc/opus_multistream.h b/jni/libopus/inc/opus_multistream.h new file mode 100644 index 00000000..ae599793 --- /dev/null +++ b/jni/libopus/inc/opus_multistream.h @@ -0,0 +1,660 @@ +/* Copyright (c) 2011 Xiph.Org Foundation + Written by Jean-Marc Valin */ +/* + 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 COPYRIGHT OWNER + 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. +*/ + +/** + * @file opus_multistream.h + * @brief Opus reference implementation multistream API + */ + +#ifndef OPUS_MULTISTREAM_H +#define OPUS_MULTISTREAM_H + +#include "opus.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** @cond OPUS_INTERNAL_DOC */ + +/** Macros to trigger compilation errors when the wrong types are provided to a + * CTL. */ +/**@{*/ +#define __opus_check_encstate_ptr(ptr) ((ptr) + ((ptr) - (OpusEncoder**)(ptr))) +#define __opus_check_decstate_ptr(ptr) ((ptr) + ((ptr) - (OpusDecoder**)(ptr))) +/**@}*/ + +/** These are the actual encoder and decoder CTL ID numbers. + * They should not be used directly by applications. + * In general, SETs should be even and GETs should be odd.*/ +/**@{*/ +#define OPUS_MULTISTREAM_GET_ENCODER_STATE_REQUEST 5120 +#define OPUS_MULTISTREAM_GET_DECODER_STATE_REQUEST 5122 +/**@}*/ + +/** @endcond */ + +/** @defgroup opus_multistream_ctls Multistream specific encoder and decoder CTLs + * + * These are convenience macros that are specific to the + * opus_multistream_encoder_ctl() and opus_multistream_decoder_ctl() + * interface. + * The CTLs from @ref opus_genericctls, @ref opus_encoderctls, and + * @ref opus_decoderctls may be applied to a multistream encoder or decoder as + * well. + * In addition, you may retrieve the encoder or decoder state for an specific + * stream via #OPUS_MULTISTREAM_GET_ENCODER_STATE or + * #OPUS_MULTISTREAM_GET_DECODER_STATE and apply CTLs to it individually. + */ +/**@{*/ + +/** Gets the encoder state for an individual stream of a multistream encoder. + * @param[in] x opus_int32: The index of the stream whose encoder you + * wish to retrieve. + * This must be non-negative and less than + * the streams parameter used + * to initialize the encoder. + * @param[out] y OpusEncoder**: Returns a pointer to the given + * encoder state. + * @retval OPUS_BAD_ARG The index of the requested stream was out of range. + * @hideinitializer + */ +#define OPUS_MULTISTREAM_GET_ENCODER_STATE(x,y) OPUS_MULTISTREAM_GET_ENCODER_STATE_REQUEST, __opus_check_int(x), __opus_check_encstate_ptr(y) + +/** Gets the decoder state for an individual stream of a multistream decoder. + * @param[in] x opus_int32: The index of the stream whose decoder you + * wish to retrieve. + * This must be non-negative and less than + * the streams parameter used + * to initialize the decoder. + * @param[out] y OpusDecoder**: Returns a pointer to the given + * decoder state. + * @retval OPUS_BAD_ARG The index of the requested stream was out of range. + * @hideinitializer + */ +#define OPUS_MULTISTREAM_GET_DECODER_STATE(x,y) OPUS_MULTISTREAM_GET_DECODER_STATE_REQUEST, __opus_check_int(x), __opus_check_decstate_ptr(y) + +/**@}*/ + +/** @defgroup opus_multistream Opus Multistream API + * @{ + * + * The multistream API allows individual Opus streams to be combined into a + * single packet, enabling support for up to 255 channels. Unlike an + * elementary Opus stream, the encoder and decoder must negotiate the channel + * configuration before the decoder can successfully interpret the data in the + * packets produced by the encoder. Some basic information, such as packet + * duration, can be computed without any special negotiation. + * + * The format for multistream Opus packets is defined in the + * Ogg + * encapsulation specification and is based on the self-delimited Opus + * framing described in Appendix B of RFC 6716. + * Normal Opus packets are just a degenerate case of multistream Opus packets, + * and can be encoded or decoded with the multistream API by setting + * streams to 1 when initializing the encoder or + * decoder. + * + * Multistream Opus streams can contain up to 255 elementary Opus streams. + * These may be either "uncoupled" or "coupled", indicating that the decoder + * is configured to decode them to either 1 or 2 channels, respectively. + * The streams are ordered so that all coupled streams appear at the + * beginning. + * + * A mapping table defines which decoded channel i + * should be used for each input/output (I/O) channel j. This table is + * typically provided as an unsigned char array. + * Let i = mapping[j] be the index for I/O channel j. + * If i < 2*coupled_streams, then I/O channel j is + * encoded as the left channel of stream (i/2) if i + * is even, or as the right channel of stream (i/2) if + * i is odd. Otherwise, I/O channel j is encoded as + * mono in stream (i - coupled_streams), unless it has the special + * value 255, in which case it is omitted from the encoding entirely (the + * decoder will reproduce it as silence). Each value i must either + * be the special value 255 or be less than streams + coupled_streams. + * + * The output channels specified by the encoder + * should use the + * Vorbis + * channel ordering. A decoder may wish to apply an additional permutation + * to the mapping the encoder used to achieve a different output channel + * order (e.g. for outputing in WAV order). + * + * Each multistream packet contains an Opus packet for each stream, and all of + * the Opus packets in a single multistream packet must have the same + * duration. Therefore the duration of a multistream packet can be extracted + * from the TOC sequence of the first stream, which is located at the + * beginning of the packet, just like an elementary Opus stream: + * + * @code + * int nb_samples; + * int nb_frames; + * nb_frames = opus_packet_get_nb_frames(data, len); + * if (nb_frames < 1) + * return nb_frames; + * nb_samples = opus_packet_get_samples_per_frame(data, 48000) * nb_frames; + * @endcode + * + * The general encoding and decoding process proceeds exactly the same as in + * the normal @ref opus_encoder and @ref opus_decoder APIs. + * See their documentation for an overview of how to use the corresponding + * multistream functions. + */ + +/** Opus multistream encoder state. + * This contains the complete state of a multistream Opus encoder. + * It is position independent and can be freely copied. + * @see opus_multistream_encoder_create + * @see opus_multistream_encoder_init + */ +typedef struct OpusMSEncoder OpusMSEncoder; + +/** Opus multistream decoder state. + * This contains the complete state of a multistream Opus decoder. + * It is position independent and can be freely copied. + * @see opus_multistream_decoder_create + * @see opus_multistream_decoder_init + */ +typedef struct OpusMSDecoder OpusMSDecoder; + +/**\name Multistream encoder functions */ +/**@{*/ + +/** Gets the size of an OpusMSEncoder structure. + * @param streams int: The total number of streams to encode from the + * input. + * This must be no more than 255. + * @param coupled_streams int: Number of coupled (2 channel) streams + * to encode. + * This must be no larger than the total + * number of streams. + * Additionally, The total number of + * encoded channels (streams + + * coupled_streams) must be no + * more than 255. + * @returns The size in bytes on success, or a negative error code + * (see @ref opus_errorcodes) on error. + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT opus_int32 opus_multistream_encoder_get_size( + int streams, + int coupled_streams +); + +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT opus_int32 opus_multistream_surround_encoder_get_size( + int channels, + int mapping_family +); + + +/** Allocates and initializes a multistream encoder state. + * Call opus_multistream_encoder_destroy() to release + * this object when finished. + * @param Fs opus_int32: Sampling rate of the input signal (in Hz). + * This must be one of 8000, 12000, 16000, + * 24000, or 48000. + * @param channels int: Number of channels in the input signal. + * This must be at most 255. + * It may be greater than the number of + * coded channels (streams + + * coupled_streams). + * @param streams int: The total number of streams to encode from the + * input. + * This must be no more than the number of channels. + * @param coupled_streams int: Number of coupled (2 channel) streams + * to encode. + * This must be no larger than the total + * number of streams. + * Additionally, The total number of + * encoded channels (streams + + * coupled_streams) must be no + * more than the number of input channels. + * @param[in] mapping const unsigned char[channels]: Mapping from + * encoded channels to input channels, as described in + * @ref opus_multistream. As an extra constraint, the + * multistream encoder does not allow encoding coupled + * streams for which one channel is unused since this + * is never a good idea. + * @param application int: The target encoder application. + * This must be one of the following: + *
+ *
#OPUS_APPLICATION_VOIP
+ *
Process signal for improved speech intelligibility.
+ *
#OPUS_APPLICATION_AUDIO
+ *
Favor faithfulness to the original input.
+ *
#OPUS_APPLICATION_RESTRICTED_LOWDELAY
+ *
Configure the minimum possible coding delay by disabling certain modes + * of operation.
+ *
+ * @param[out] error int *: Returns #OPUS_OK on success, or an error + * code (see @ref opus_errorcodes) on + * failure. + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT OpusMSEncoder *opus_multistream_encoder_create( + opus_int32 Fs, + int channels, + int streams, + int coupled_streams, + const unsigned char *mapping, + int application, + int *error +) OPUS_ARG_NONNULL(5); + +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT OpusMSEncoder *opus_multistream_surround_encoder_create( + opus_int32 Fs, + int channels, + int mapping_family, + int *streams, + int *coupled_streams, + unsigned char *mapping, + int application, + int *error +) OPUS_ARG_NONNULL(5); + +/** Initialize a previously allocated multistream encoder state. + * The memory pointed to by \a st must be at least the size returned by + * opus_multistream_encoder_get_size(). + * This is intended for applications which use their own allocator instead of + * malloc. + * To reset a previously initialized state, use the #OPUS_RESET_STATE CTL. + * @see opus_multistream_encoder_create + * @see opus_multistream_encoder_get_size + * @param st OpusMSEncoder*: Multistream encoder state to initialize. + * @param Fs opus_int32: Sampling rate of the input signal (in Hz). + * This must be one of 8000, 12000, 16000, + * 24000, or 48000. + * @param channels int: Number of channels in the input signal. + * This must be at most 255. + * It may be greater than the number of + * coded channels (streams + + * coupled_streams). + * @param streams int: The total number of streams to encode from the + * input. + * This must be no more than the number of channels. + * @param coupled_streams int: Number of coupled (2 channel) streams + * to encode. + * This must be no larger than the total + * number of streams. + * Additionally, The total number of + * encoded channels (streams + + * coupled_streams) must be no + * more than the number of input channels. + * @param[in] mapping const unsigned char[channels]: Mapping from + * encoded channels to input channels, as described in + * @ref opus_multistream. As an extra constraint, the + * multistream encoder does not allow encoding coupled + * streams for which one channel is unused since this + * is never a good idea. + * @param application int: The target encoder application. + * This must be one of the following: + *
+ *
#OPUS_APPLICATION_VOIP
+ *
Process signal for improved speech intelligibility.
+ *
#OPUS_APPLICATION_AUDIO
+ *
Favor faithfulness to the original input.
+ *
#OPUS_APPLICATION_RESTRICTED_LOWDELAY
+ *
Configure the minimum possible coding delay by disabling certain modes + * of operation.
+ *
+ * @returns #OPUS_OK on success, or an error code (see @ref opus_errorcodes) + * on failure. + */ +OPUS_EXPORT int opus_multistream_encoder_init( + OpusMSEncoder *st, + opus_int32 Fs, + int channels, + int streams, + int coupled_streams, + const unsigned char *mapping, + int application +) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(6); + +OPUS_EXPORT int opus_multistream_surround_encoder_init( + OpusMSEncoder *st, + opus_int32 Fs, + int channels, + int mapping_family, + int *streams, + int *coupled_streams, + unsigned char *mapping, + int application +) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(6); + +/** Encodes a multistream Opus frame. + * @param st OpusMSEncoder*: Multistream encoder state. + * @param[in] pcm const opus_int16*: The input signal as interleaved + * samples. + * This must contain + * frame_size*channels + * samples. + * @param frame_size int: Number of samples per channel in the input + * signal. + * This must be an Opus frame size for the + * encoder's sampling rate. + * For example, at 48 kHz the permitted values + * are 120, 240, 480, 960, 1920, and 2880. + * Passing in a duration of less than 10 ms + * (480 samples at 48 kHz) will prevent the + * encoder from using the LPC or hybrid modes. + * @param[out] data unsigned char*: Output payload. + * This must contain storage for at + * least \a max_data_bytes. + * @param [in] max_data_bytes opus_int32: Size of the allocated + * memory for the output + * payload. This may be + * used to impose an upper limit on + * the instant bitrate, but should + * not be used as the only bitrate + * control. Use #OPUS_SET_BITRATE to + * control the bitrate. + * @returns The length of the encoded packet (in bytes) on success or a + * negative error code (see @ref opus_errorcodes) on failure. + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_multistream_encode( + OpusMSEncoder *st, + const opus_int16 *pcm, + int frame_size, + unsigned char *data, + opus_int32 max_data_bytes +) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2) OPUS_ARG_NONNULL(4); + +/** Encodes a multistream Opus frame from floating point input. + * @param st OpusMSEncoder*: Multistream encoder state. + * @param[in] pcm const float*: The input signal as interleaved + * samples 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 + * dynamic range. + * This must contain + * frame_size*channels + * samples. + * @param frame_size int: Number of samples per channel in the input + * signal. + * This must be an Opus frame size for the + * encoder's sampling rate. + * For example, at 48 kHz the permitted values + * are 120, 240, 480, 960, 1920, and 2880. + * Passing in a duration of less than 10 ms + * (480 samples at 48 kHz) will prevent the + * encoder from using the LPC or hybrid modes. + * @param[out] data unsigned char*: Output payload. + * This must contain storage for at + * least \a max_data_bytes. + * @param [in] max_data_bytes opus_int32: Size of the allocated + * memory for the output + * payload. This may be + * used to impose an upper limit on + * the instant bitrate, but should + * not be used as the only bitrate + * control. Use #OPUS_SET_BITRATE to + * control the bitrate. + * @returns The length of the encoded packet (in bytes) on success or a + * negative error code (see @ref opus_errorcodes) on failure. + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_multistream_encode_float( + OpusMSEncoder *st, + const float *pcm, + int frame_size, + unsigned char *data, + opus_int32 max_data_bytes +) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2) OPUS_ARG_NONNULL(4); + +/** Frees an OpusMSEncoder allocated by + * opus_multistream_encoder_create(). + * @param st OpusMSEncoder*: Multistream encoder state to be freed. + */ +OPUS_EXPORT void opus_multistream_encoder_destroy(OpusMSEncoder *st); + +/** Perform a CTL function on a multistream Opus encoder. + * + * Generally the request and subsequent arguments are generated by a + * convenience macro. + * @param st OpusMSEncoder*: Multistream encoder state. + * @param request This and all remaining parameters should be replaced by one + * of the convenience macros in @ref opus_genericctls, + * @ref opus_encoderctls, or @ref opus_multistream_ctls. + * @see opus_genericctls + * @see opus_encoderctls + * @see opus_multistream_ctls + */ +OPUS_EXPORT int opus_multistream_encoder_ctl(OpusMSEncoder *st, int request, ...) OPUS_ARG_NONNULL(1); + +/**@}*/ + +/**\name Multistream decoder functions */ +/**@{*/ + +/** Gets the size of an OpusMSDecoder structure. + * @param streams int: The total number of streams coded in the + * input. + * This must be no more than 255. + * @param coupled_streams int: Number streams to decode as coupled + * (2 channel) streams. + * This must be no larger than the total + * number of streams. + * Additionally, The total number of + * coded channels (streams + + * coupled_streams) must be no + * more than 255. + * @returns The size in bytes on success, or a negative error code + * (see @ref opus_errorcodes) on error. + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT opus_int32 opus_multistream_decoder_get_size( + int streams, + int coupled_streams +); + +/** Allocates and initializes a multistream decoder state. + * Call opus_multistream_decoder_destroy() to release + * this object when finished. + * @param Fs opus_int32: Sampling rate to decode at (in Hz). + * This must be one of 8000, 12000, 16000, + * 24000, or 48000. + * @param channels int: Number of channels to output. + * This must be at most 255. + * It may be different from the number of coded + * channels (streams + + * coupled_streams). + * @param streams int: The total number of streams coded in the + * input. + * This must be no more than 255. + * @param coupled_streams int: Number of streams to decode as coupled + * (2 channel) streams. + * This must be no larger than the total + * number of streams. + * Additionally, The total number of + * coded channels (streams + + * coupled_streams) must be no + * more than 255. + * @param[in] mapping const unsigned char[channels]: Mapping from + * coded channels to output channels, as described in + * @ref opus_multistream. + * @param[out] error int *: Returns #OPUS_OK on success, or an error + * code (see @ref opus_errorcodes) on + * failure. + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT OpusMSDecoder *opus_multistream_decoder_create( + opus_int32 Fs, + int channels, + int streams, + int coupled_streams, + const unsigned char *mapping, + int *error +) OPUS_ARG_NONNULL(5); + +/** Intialize a previously allocated decoder state object. + * The memory pointed to by \a st must be at least the size returned by + * opus_multistream_encoder_get_size(). + * This is intended for applications which use their own allocator instead of + * malloc. + * To reset a previously initialized state, use the #OPUS_RESET_STATE CTL. + * @see opus_multistream_decoder_create + * @see opus_multistream_deocder_get_size + * @param st OpusMSEncoder*: Multistream encoder state to initialize. + * @param Fs opus_int32: Sampling rate to decode at (in Hz). + * This must be one of 8000, 12000, 16000, + * 24000, or 48000. + * @param channels int: Number of channels to output. + * This must be at most 255. + * It may be different from the number of coded + * channels (streams + + * coupled_streams). + * @param streams int: The total number of streams coded in the + * input. + * This must be no more than 255. + * @param coupled_streams int: Number of streams to decode as coupled + * (2 channel) streams. + * This must be no larger than the total + * number of streams. + * Additionally, The total number of + * coded channels (streams + + * coupled_streams) must be no + * more than 255. + * @param[in] mapping const unsigned char[channels]: Mapping from + * coded channels to output channels, as described in + * @ref opus_multistream. + * @returns #OPUS_OK on success, or an error code (see @ref opus_errorcodes) + * on failure. + */ +OPUS_EXPORT int opus_multistream_decoder_init( + OpusMSDecoder *st, + opus_int32 Fs, + int channels, + int streams, + int coupled_streams, + const unsigned char *mapping +) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(6); + +/** Decode a multistream Opus packet. + * @param st OpusMSDecoder*: Multistream decoder state. + * @param[in] data const unsigned char*: Input payload. + * Use a NULL + * pointer to indicate packet + * loss. + * @param len opus_int32: Number of bytes in payload. + * @param[out] pcm opus_int16*: Output signal, with interleaved + * samples. + * This must contain room for + * frame_size*channels + * samples. + * @param frame_size int: The number of samples per channel of + * available space in \a pcm. + * If this is less than the maximum packet duration + * (120 ms; 5760 for 48kHz), this function will not be capable + * of decoding some packets. In the case of PLC (data==NULL) + * or FEC (decode_fec=1), then frame_size needs to be exactly + * the duration of audio that is missing, otherwise the + * decoder will not be in the optimal state to decode the + * next incoming packet. For the PLC and FEC cases, frame_size + * must be a multiple of 2.5 ms. + * @param decode_fec int: Flag (0 or 1) to request that any in-band + * forward error correction data be decoded. + * If no such data is available, the frame is + * decoded as if it were lost. + * @returns Number of samples decoded on success or a negative error code + * (see @ref opus_errorcodes) on failure. + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_multistream_decode( + OpusMSDecoder *st, + const unsigned char *data, + opus_int32 len, + opus_int16 *pcm, + int frame_size, + int decode_fec +) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(4); + +/** Decode a multistream Opus packet with floating point output. + * @param st OpusMSDecoder*: Multistream decoder state. + * @param[in] data const unsigned char*: Input payload. + * Use a NULL + * pointer to indicate packet + * loss. + * @param len opus_int32: Number of bytes in payload. + * @param[out] pcm opus_int16*: Output signal, with interleaved + * samples. + * This must contain room for + * frame_size*channels + * samples. + * @param frame_size int: The number of samples per channel of + * available space in \a pcm. + * If this is less than the maximum packet duration + * (120 ms; 5760 for 48kHz), this function will not be capable + * of decoding some packets. In the case of PLC (data==NULL) + * or FEC (decode_fec=1), then frame_size needs to be exactly + * the duration of audio that is missing, otherwise the + * decoder will not be in the optimal state to decode the + * next incoming packet. For the PLC and FEC cases, frame_size + * must be a multiple of 2.5 ms. + * @param decode_fec int: Flag (0 or 1) to request that any in-band + * forward error correction data be decoded. + * If no such data is available, the frame is + * decoded as if it were lost. + * @returns Number of samples decoded on success or a negative error code + * (see @ref opus_errorcodes) on failure. + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_multistream_decode_float( + OpusMSDecoder *st, + const unsigned char *data, + opus_int32 len, + float *pcm, + int frame_size, + int decode_fec +) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(4); + +/** Perform a CTL function on a multistream Opus decoder. + * + * Generally the request and subsequent arguments are generated by a + * convenience macro. + * @param st OpusMSDecoder*: Multistream decoder state. + * @param request This and all remaining parameters should be replaced by one + * of the convenience macros in @ref opus_genericctls, + * @ref opus_decoderctls, or @ref opus_multistream_ctls. + * @see opus_genericctls + * @see opus_decoderctls + * @see opus_multistream_ctls + */ +OPUS_EXPORT int opus_multistream_decoder_ctl(OpusMSDecoder *st, int request, ...) OPUS_ARG_NONNULL(1); + +/** Frees an OpusMSDecoder allocated by + * opus_multistream_decoder_create(). + * @param st OpusMSDecoder: Multistream decoder state to be freed. + */ +OPUS_EXPORT void opus_multistream_decoder_destroy(OpusMSDecoder *st); + +/**@}*/ + +/**@}*/ + +#ifdef __cplusplus +} +#endif + +#endif /* OPUS_MULTISTREAM_H */ diff --git a/jni/libopus/inc/opus_types.h b/jni/libopus/inc/opus_types.h new file mode 100644 index 00000000..b28e03ae --- /dev/null +++ b/jni/libopus/inc/opus_types.h @@ -0,0 +1,159 @@ +/* (C) COPYRIGHT 1994-2002 Xiph.Org Foundation */ +/* Modified by Jean-Marc Valin */ +/* + 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 COPYRIGHT OWNER + 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. +*/ +/* opus_types.h based on ogg_types.h from libogg */ + +/** + @file opus_types.h + @brief Opus reference implementation types +*/ +#ifndef OPUS_TYPES_H +#define OPUS_TYPES_H + +/* Use the real stdint.h if it's there (taken from Paul Hsieh's pstdint.h) */ +#if (defined(__STDC__) && __STDC__ && __STDC_VERSION__ >= 199901L) || (defined(__GNUC__) && (defined(_STDINT_H) || defined(_STDINT_H_)) || defined (HAVE_STDINT_H)) +#include + + typedef int16_t opus_int16; + typedef uint16_t opus_uint16; + typedef int32_t opus_int32; + typedef uint32_t opus_uint32; +#elif defined(_WIN32) + +# if defined(__CYGWIN__) +# include <_G_config.h> + typedef _G_int32_t opus_int32; + typedef _G_uint32_t opus_uint32; + typedef _G_int16 opus_int16; + typedef _G_uint16 opus_uint16; +# elif defined(__MINGW32__) + typedef short opus_int16; + typedef unsigned short opus_uint16; + typedef int opus_int32; + typedef unsigned int opus_uint32; +# elif defined(__MWERKS__) + typedef int opus_int32; + typedef unsigned int opus_uint32; + typedef short opus_int16; + typedef unsigned short opus_uint16; +# else + /* MSVC/Borland */ + typedef __int32 opus_int32; + typedef unsigned __int32 opus_uint32; + typedef __int16 opus_int16; + typedef unsigned __int16 opus_uint16; +# endif + +#elif defined(__MACOS__) + +# include + typedef SInt16 opus_int16; + typedef UInt16 opus_uint16; + typedef SInt32 opus_int32; + typedef UInt32 opus_uint32; + +#elif (defined(__APPLE__) && defined(__MACH__)) /* MacOS X Framework build */ + +# include + typedef int16_t opus_int16; + typedef u_int16_t opus_uint16; + typedef int32_t opus_int32; + typedef u_int32_t opus_uint32; + +#elif defined(__BEOS__) + + /* Be */ +# include + typedef int16 opus_int16; + typedef u_int16 opus_uint16; + typedef int32_t opus_int32; + typedef u_int32_t opus_uint32; + +#elif defined (__EMX__) + + /* OS/2 GCC */ + typedef short opus_int16; + typedef unsigned short opus_uint16; + typedef int opus_int32; + typedef unsigned int opus_uint32; + +#elif defined (DJGPP) + + /* DJGPP */ + typedef short opus_int16; + typedef unsigned short opus_uint16; + typedef int opus_int32; + typedef unsigned int opus_uint32; + +#elif defined(R5900) + + /* PS2 EE */ + typedef int opus_int32; + typedef unsigned opus_uint32; + typedef short opus_int16; + typedef unsigned short opus_uint16; + +#elif defined(__SYMBIAN32__) + + /* Symbian GCC */ + typedef signed short opus_int16; + typedef unsigned short opus_uint16; + typedef signed int opus_int32; + typedef unsigned int opus_uint32; + +#elif defined(CONFIG_TI_C54X) || defined (CONFIG_TI_C55X) + + typedef short opus_int16; + typedef unsigned short opus_uint16; + typedef long opus_int32; + typedef unsigned long opus_uint32; + +#elif defined(CONFIG_TI_C6X) + + typedef short opus_int16; + typedef unsigned short opus_uint16; + typedef int opus_int32; + typedef unsigned int opus_uint32; + +#else + + /* Give up, take a reasonable guess */ + typedef short opus_int16; + typedef unsigned short opus_uint16; + typedef int opus_int32; + typedef unsigned int opus_uint32; + +#endif + +#define opus_int int /* used for counters etc; at least 16 bits */ +#define opus_int64 long long +#define opus_int8 signed char + +#define opus_uint unsigned int /* used for counters etc; at least 16 bits */ +#define opus_uint64 unsigned long long +#define opus_uint8 unsigned char + +#endif /* OPUS_TYPES_H */ diff --git a/jni/nv_opus_dec.c b/jni/nv_opus_dec.c new file mode 100644 index 00000000..60425aec --- /dev/null +++ b/jni/nv_opus_dec.c @@ -0,0 +1,54 @@ +#include +#include +#include "nv_opus_dec.h" + +OpusDecoder* decoder; + +// This function must be called before +// any other decoding functions +int nv_opus_init(void) { + int err; + decoder = opus_decoder_create( + nv_opus_get_sample_rate(), + nv_opus_get_channel_count(), + &err); + return err; +} + +// This function must be called after +// decoding is finished +void nv_opus_destroy(void) { + if (decoder != NULL) { + opus_decoder_destroy(decoder); + } +} + +// The Opus stream is stereo +int nv_opus_get_channel_count(void) { + return 2; +} + +// This number assumes 2 channels at 48 KHz +int nv_opus_get_max_out_shorts(void) { + return 5760*2; +} + +// The Opus stream is 48 KHz +int nv_opus_get_sample_rate(void) { + return 48000; +} + +// outpcmdata must be 5760*2 shorts in length +// packets must be decoded in order +// a packet loss must call this function with NULL indata and 0 inlen +// returns the number of decoded samples +int nv_opus_decode(unsigned char* indata, int inlen, short* outpcmdata) { + int err; + + // Decoding to 16-bit PCM with FEC off + // Maximum length assuming 48KHz sample rate + err = opus_decode(decoder, indata, inlen, + outpcmdata, 5760, 0); + + return err; +} diff --git a/jni/nv_opus_dec.h b/jni/nv_opus_dec.h new file mode 100644 index 00000000..c5eb7f55 --- /dev/null +++ b/jni/nv_opus_dec.h @@ -0,0 +1,6 @@ +int nv_opus_init(void); +void nv_opus_destroy(void); +int nv_opus_get_channel_count(void); +int nv_opus_get_max_out_shorts(void); +int nv_opus_get_sample_rate(void); +int nv_opus_decode(unsigned char* indata, int inlen, short* outpcmdata); diff --git a/jni/nv_opus_dec_jni.c b/jni/nv_opus_dec_jni.c new file mode 100644 index 00000000..bb99568b --- /dev/null +++ b/jni/nv_opus_dec_jni.c @@ -0,0 +1,61 @@ +#include "nv_opus_dec.h" + +#include + +// This function must be called before +// any other decoding functions +JNIEXPORT jint JNICALL +Java_com_limelight_nvstream_av_audio_OpusDecoder_init(JNIEnv *env, jobject this) { + return nv_opus_init(); +} + +// This function must be called after +// decoding is finished +JNIEXPORT void JNICALL +Java_com_limelight_nvstream_av_audio_OpusDecoder_destroy(JNIEnv *env, jobject this) { + nv_opus_destroy(); +} + +// The Opus stream is stereo +JNIEXPORT jint JNICALL +Java_com_limelight_nvstream_av_audio_OpusDecoder_getChannelCount(JNIEnv *env, jobject this) { + return nv_opus_get_channel_count(); +} + +// This number assumes 2 channels at 48 KHz +JNIEXPORT jint JNICALL +Java_com_limelight_nvstream_av_audio_OpusDecoder_getMaxOutputShorts(JNIEnv *env, jobject this) { + return nv_opus_get_max_out_shorts(); +} + +// The Opus stream is 48 KHz +JNIEXPORT jint JNICALL +Java_com_limelight_nvstream_av_audio_OpusDecoder_getSampleRate(JNIEnv *env, jobject this) { + return nv_opus_get_sample_rate(); +} + +// outpcmdata must be 5760*2 shorts in length +// packets must be decoded in order +// a packet loss must call this function with NULL indata and 0 inlen +// returns the number of decoded samples +JNIEXPORT jint JNICALL +Java_com_limelight_nvstream_av_audio_OpusDecoder_decode( + JNIEnv *env, jobject this, // JNI parameters + jbyteArray indata, jint inoff, jint inlen, // Input parameters + jshortArray outpcmdata) // Output parameter +{ + jint ret; + jbyte* jni_input_data; + jshort* jni_pcm_data; + + jni_input_data = (*env)->GetByteArrayElements(env, indata, 0); + jni_pcm_data = (*env)->GetShortArrayElements(env, outpcmdata, 0); + + ret = nv_opus_decode(&jni_input_data[inoff], inlen, jni_pcm_data); + + // The input data isn't changed so it can be safely aborted + (*env)->ReleaseByteArrayElements(env, indata, jni_input_data, JNI_ABORT); + (*env)->ReleaseShortArrayElements(env, outpcmdata, jni_pcm_data, 0); + + return ret; +} diff --git a/libs/armeabi-v7a/libnv_opus_dec.so b/libs/armeabi-v7a/libnv_opus_dec.so new file mode 100644 index 0000000000000000000000000000000000000000..4f8be2974dcd277ee42fb4f04ea4696b1a0b65c9 GIT binary patch literal 148716 zcmcG%3w&JFb??8=Jgl)K?2#p7BPrn+ltgh18H1Cm#0dj7#t9~jAAq55EFsB{MA+jO zb#h5Fwq$G^3C38C4Vd`2(3TR~ibqmPAsJ(6D1}=S!-e|N^vsM;Wn_9|Qj$Or}D)f2y4JS2>>vlz`&N zKfxa%{N`L^8i*%Ar3;An&MA#0_;TP#D&&t{M~yE5w|vr=SWv%%xXwOR|GxoG1QtGO z{~h9{3iz*prvSGStNibXx6LyC8VLR;;4fB`{}g!d)u+lwfY(qiTByFw1UFQ`HvoUV z0=@_Mn-%a+fj3paA7R0^0Job`f7kjf1Hj*TgqwkzgZZAvczwVP74W^luUzO?_wo4w z@Us>0KLH=Dfd2#doeFqd*qB>CeX9K@fy;kdp9Js_^~>vX`5EPNfgfx!W;S(2kHx?Z zA3FuFsHksK=hide0pOv8F@wZv|0idZKLI?A`OXWm+`E4ZPw%EYkzu ztG}m!XVBgW>OT)${u95yDEM+?mJq3a0eA`Uv|zk<&Zz(EGvH8Fxi_^prV4n)Y{m@6 zpA78GF{Uf%|03YXmE;BRBH-**rTszUF9UuSxFIOt4BT@yav8vbz!CIyx%__M=RY_F zKMGv_6Fz?neCwBunMqpx9|nE`I2FJ@JEQ(Pz)!tznf74*77O`!MgMW&*MDW5q}NA) zCxcI!ep9vZ!Jn^B&Vbv1Q;(jS?;PMh;5coB-&cU&`gaBo;2z*ND#rhBz-iXMH7MT( zT>jH|{b#^g;HQ3OnTLb*xbKYe`+@u6pH|vx{J#d){-eLRd3*E+XTZ+@$12Ky3|#)x z_%8tq{|8B{zt@1*Lm$mg`rHE^g#YcJ{FlIzhc^Ov6gUgMyjNkorhz?J&qZQx3M@g8s`zr?Cf z*B=eQd*G-30RQvOfIkiVAmz6P<)1qPz7n`nf2Dvc<>v4sH*v~pF~(#~{xX?ktqWFO1B*Dvi{(Xnb(chAz!)f-lw>Rlx_cWhj`dc*pq z>sG8@yMEnijn;MCobKsfx)z*H=C51@cBf&}xwgBqLJ6tLD&|Waw{$S_%}aY$-rU`@ za`}q&OIO{(yt+GXUfOZX(vA&XD_1YQhUv~OO=zh<$bY$2nO6VhhLB-ai9WM@^8CMa zaCOJVYc{M;Z&<&uM92S^J{J1)ULb1zmzxJ4CvHl%~R z^^0@S^+yK@7JP-@xP(bI!yb#F{}cdqa5I&HkvYV}nysf8W4d?=;L z`M<07@1T+2>_Z52GJn=dbeQ_AIhUQ@|ALN{>$ zOIYv?H*5A4^D5;nUA=bcg6{Pz)~^1eljF`>EhQmp1zb0~Tj1{)_41C+udQF((W&l# zdqI~jEq8Jz=0V?QW}m7b;9Ra(p2Erg{EQF7|3hYWve(mT6!d+1=E=GhGYcwKwCrSh*+r-FyDFP^ zQ3=7Q)b?waE@xL+rycFIZNk^-i1Io_@@7P8b*EXjw)>1qo$Gr_t3uP*E)Z40?%6s9uO8k~C>sj3)T@lcz^XByO z)4`tgrf2QSRqL01SeO3jr*&8&1EU2!Ow4I0-Bh0B)<- zN)6t;`j%iu+CA5({e-x#?WJ z?qp_{xB%W-rG21OZ>841yUS<5r8lix#~?nlcCYF(Yo%kT$tHfwx|J87Y6F}&3HfN; zyjpDZA@xcHrLnr!mROSicP%^BU01-UU0tPIf4w%WTDP+66q|1F@hmN6P=GLigi%u&j<-_fz0YUpTe1O&C%8gyi)~zJ9e(i=;ouvJN0xmi=m35`5 zbb*TIbQ1e@!rq70tvr?9u&S#B1CB7v{-$cyO+>9g0 ze%D`;ptJfl1pTcev=jb_@cV>Lg8p=Vz|Ca7O6VYLAn42~|L7vZy#)PzmheSCWz4sU zG4IVr!Y;xfVG}{;*gFa3zdJ~Li?D+*K)8;e^UzYl#e~HK{c+SXn+fL=))M54%@FP( zl>fE{3As@w6V4`lG|0O|Q}RR)6iwlm=W zKfsA}T3gZaq>6MoDc}2t{hb$Ne!QYEOuCuSRFPMiys#3eNPnUtJ&kl-1^oFSeMt~c z58}&-X9Vezr^A@30j%gELLz`0h(ATZO>*+@3nx>h#PvkKSCRLJ73p$vAqm`UC;xQ5 z{sY35gas#axjU#xe~k2{gc~aI8iRBVF>YA@FU|k!39AXMgmVb`iJczF#9v`F? zeT^`au#JGr(EqFA|4V}O3gSM(Hwl*!mJ!Y(e1>o?q5RiNVhdqSkfFOH@x!qoek+Ji z1o1mT{B97xAH-%}sa;DDw*~RcAWjDHydX{m@uDDJ9K=h4xGRWP1aVIg?+s!nhz|wv zD?uFLZcF&bg19Y+X9jUHi020JydX{m@uDDJ9K=h4xIKuwf_Oy`_XKe|h;I$zOc3`4 z@wOoD58`YP4+gOl#191VgF*ao5Dx|M<3apHIsS5KzPTWNHi(}O;unMXP!PW!#BT(# z8^lM0_*f9X6~rfk_?;krH;CU4VslMt{74YTg19z_<3ZdI#FK-#If(5bZVBSnAf6V) zi6EX4#BD)5Gl-KxJUfWz2JyTgP6hFzAYL5AOMfr#W&&SQ;ZUM zM=_h&yNXdd?<+=WMcfO#h`Y}l=iceYPW;e&A_0BSZ4R7HAjMLJoLZmUQqD$=c_WA;AJ#GPWu zzSDhXbaZ4g^Ntwu%$@E5;23cDs{b~-X~pCfu}3~~;^`lyul&J90_4^jH7mN29-bhVViV{_#f_ym{iv zbLWItoIR&*jyW$f=U?7!$sB&yy=c#s=dZYooWt)PyJ!<5@3}H|cXZC!<5gxV`279o z`75T+`O=)j@0xX?^EXre1oiDXm(7_6h@4{L18Y%LhtWvtuX z7d1Zpax+*6o9pt}GgGUnA5*=dD+|Y1S1j2)9F7UOxHtwpE%3CQt%bbG5>7Fm=<~)J zr}!!IHSXVN+{7OGTv(($OnG#!>GPt-2_v4>nnT2FE6g)}-?tLZWAy#xLp~l(kvwmn z8T3;0DH^Np1Y;grIJ4-}uHD`j4I9S_*}JOZc3*UyKOe?n{JDvJQTnP5(S~_6&Pcv&p#Gnt-))5rd=#)_XBOXHaMj%XyF@%jDaSo9r_ z4-_Ky6ff+LJK*bNjp;FFc|7SM(Q96M&16fCE@@NH*%-ZD29InPxi^OuB3?}ryY%ec~0)DOc~ z6C&v?%sW-wL_P6Nmi2E-_j%$c$;P?BDhJOxaIBBoPTif<{dUj~=Wcj7Rm9Awt~I-k zh0MC*R?;zK$|B8Lp!>=?&B=!oTjGE6X(u0xJ60sVb7CBx7#oZcHv`c)a;9~FZ>u@? zjfg&HK^vQO`dTo5c(Sn-nuX1^d2qIp8jpEkx{R3gF4`|HhSvPJ_^|-D%PFsg)||+g z_x1JBA;*e2j)mT==4?L_iT|Ci2VxqVbrUaIx$T9T_>M{7hpfP(xdHEAe*-OY>LnGx-WEr&{b%j+M*21+=^bJ%+< z;z_~2Ig$9p6(xIN`M+LW2>Cq8+Pr;d_Q&)QC1CE32>0!Tzfd~u6b}$YMMhC^A1ALXgU-D?MIWlR&gYI~9UC}tsPRnt6W2P~GuTQrd zi&4j^1K-9tycl;b-)z$N6u_BrCgtxUU+tjlc4JFtPtYELT*@9mzsH{`&W&e|GGJpU zzNu*7h4WY!@n6_}hIQ}rK$3O3UUo=zd9S5DI$V3t!Q!Dr=IA+ooyGKNs_VuL6wV6T zVAC`bMuY=6ZdX}#P$qsyK7BZzT2^R_55gnY7Fn-6@_l3rYg2dOK;brPvx|;E_aIlf z9Y>+@QOjOX`1R=M)adkHSGb99;*0@rOo4tEFJs@^?l}33waE>~o&4tU$wKw-=%d>2 z1Kbn6i0|TJ8?qqWgzG;Wa~!|QY52cRp2ox<;^Qw^Ixq}Pi5pL@C$c48z?ZaL_KfTi z^&5j`L(?-y|CM%G=C66aLAnk7BRHCN^0#$lT}a1}6D@ z49@?_81SyA`hQP-gA7QL@%d(@AiA}z)w~|hN z2QnsGDUw4c-~7L~olL?lCNKK97p4Csx;`e|h*hcH&FF}4?evk!@Od!Y4Sf|qEG05mR!uWHe4qV*5KS+M5&8Sqja zWD}XDoV>;MKtcPF@EYsSJymboojhk4xgSTywmU_&ucjaA?LT8J(%?TMo+-4M9mm?t z1#gay&mJ@GeaEKMWZ%-rFI`y=lcJP zIxGKAbrJ)GFZ`eCu$C*%s1vgfNl&ou3yPL~`2^|nvC0Fk@#W(3!dN@!Md0a3{H~*8 zOy(GRs~EEn!p}Rs^JczevA~ez&ymbH+VB1TUE+ z`k(Qn^RO-JUm;xu&yA!1DsYmV*Cy#BIp7_Ge+8?2d{D0Z-;ghT^&GsIiN_1Rt+9zQ zgZA)vabxCZ|7M&4?={ILyd24FD}cQD1E}-g(&bkK2D$9%z4KtatARoL|yFG#z(-bideGxE#_nFRAB>SpNLN=tRr9T=2QPs z>dCfL`|`Ld6CPU_U+qIlr?^Tqp?*Bl>(-h9-*&4?_W69K^$@+kWlZ6h=!;F4_7>E> zTvz@51M_&S0;e14&tlB+(EkK<(tf3S_~1w0C+~6Q5l)&=RWdTcvim}W36xu*IA@bj zYz~vIqkVno6PxSLrA?0d)0xNLGlpm-yf0%6_J`jZBlPj!Jo<6u#}#!y8_K-M(9hQPu>M5je+gdI6lcakbH3RajtIN?5`ILKJq+$LMMOxDfFqi#qG@n(e588 z!zT618iO*;UvwzXU%0VuBO31z<7qBcjOW)0#$(RKXu>IeA>hCB**mpA#$_{e=GVD; zp7uXzAl(!}ekHpRdjLOVuW!eP;jvoIpjC;(-dUVgYr&^{{#ASNgU;l&)RVtU{AdMo zHP`Gsc{cxDb$|Kmk_^sE?DVSa!ydjq{A#_0@)+6|``^QtLA;${)xO8 zIOx1s%lR?_&&Pp7?YFrR(>q+7>~sGO{%@dMxLT}x38w|n9(|O(owa}$obAK|9zMp# zW~~`Mw9MbhcYeW}_Rv7#0q9Vh%X$xg8~-r#-@EvE_r>v?kK36iw&mOf?QSG@ua`;G zpwkDv=his+KGM%6klU>Gr0erNz*j(*jqw_9yz^8V^3q54P8MwOQ?X=vLM=oECqXk#^`Fvv+wrq3LGYhT*4b zvnU^8ovz1^+aA9PJ-NORix2o~ViNdttbt?ND|?vF7}|7RtTRojh_9g<-*d5AxX@?2 zQ{&x3zuNDs6VA)@|1!LKMB~s;@v-c-d-a}j@A5h{?Z&(|0m2bWZdE*;+TD}7fnk4td%eBVs7D!d(ur_ zCe`E(wl{fqG54};j53cl)_;Z>^lB&X^OB4);nS=07C43zo89r;F*Lv@#&+u0LmO!8 zW~_zz4VHO9d?T4c-ts@DPwDo3AJti|>102)eR&~lZ+5E^n+sM3y5yX^`Z+i~={}r5 zrWx;H;Bcbd?X?!<*OT`>`j&2FOxY`8`mJYe>n-_UjZ@qcukm%pgYbKb_Ezpzd{@rJ z;lxeu13BfPAHb!~c8Y`4O|xbR*0JvMvkGT1ADxRQ+D@nzUMwsA1tDfXpnykD4m^50u+j*qK%imwox^d2u1>^Is&zChks?Hy*@QO>-LeQ9`$ zel-5;6Zd(G?W+od%<%!ne~`Sz3E?p@KQp`2dk7lt3GkXCIm$>T7wfEdWN!{!=wEom z^2D;W6VAb~?Hq_wuDvK6-#c6d&xPZe;c@Vzd;{7GC6AF@KQ>CHfE+dMsWPt7T4Z%^ zhODulYM064{5WJ^^v?};E@NAmp#Oit%nJ+DL#cx*+U)Sn1MF$)FUUzme#t7HQvaW zl4I>{;rM3vVc@;MynrL%-z8Sv7tc1wbF@`@3H(tjnPS{5WBy*Cw*-e09j?i)D}=Lu z;R??ToPQvV92M&r;{o7I zmb!#Jgh90-9!r~aqQ<+Ay3)hl$guXWZ+_khV`oIY-;7r0xbIfpQ`7fF1N%dF5xgfD z^zS4^pE7Owp`qp_nw$qsE`%nc>-xHV-XB5NzhRtk%Jt_{P5O(|&G9Gc>j9r97mF6* zK&SfmhD!gCwQi<;nXkL)M|6|?m~@GMyRchCYw6Z=SkE%O|62SPFY&4PQambNm3|SA zt|z?+JmkZAO+24T7334O3~e&d*wBXfLBhj?YpAPvOP*wt%2rhWzOBeQR^dMl%QnS7 zvXQ>~?HVuUIC;s@3(QlptbO?@#Q2T#ffD@;+>T9?EGy%M>K@=P>@cTaM4i zfo$F+oOsSM&7a^6Dxr~ZF5ySxc|$vK>Low>{r5h&{K9{`^eNyO2Q2etHZ1o-ek&o7 z#4cD^)SbCWvJY|=!2ZG`O*RAD^gq5OS)~uGk(V4tkxVBDXh1%%@o<5)Lvqsjb8uA1BUS zd@5af8zH)~=Du$HI5H%ho(OPirHwx}YhK1_Zkl@){Lm)d=f&FlylI45^zvjvoOB5L zL3lqL^ueCnSe5Q`eST$3`CT*Ot# z>~!1ccP9PULO1!1zj@ZR#eekeVpo1~-|qVrvCdvOoF}5ct#x7z-wo*hEVOu*v#6EU zp0^14EUF7ZKhbH(r_&1DIxh&XcYQn-73J^N zK2%vpzLRKs$p@u+n%g(9eP8}1{u|~^gX#!$sIr~>x5@Y08~TS2xHI?r{|CRWQ!Glh z=zmOr!@r&}&vE90H|2L04>ZFkCYANx`@*b(jckn7`X#(ULxqyJrWaLwXsf14wSpN~oIP!7A#|SNi^9kn>rVwm`d^WmsRK4FPG!ZT% z=>Fq!!Zif$k4KoCe~*XFH6ou)9f9@d9>ALAvQm=+)}` z=*6qOJ|Co$PahLM$afjR?iU}ZZNm3^(mq~pUuwhqhmmIZSo}T>IsY2;b>Y1zYcmzT z8w1~teww`#z4IbGc<@|!FnrL}8RX!_9qu$69!$XZ$gj>*ABN{gz|+4=&^-qA^v*{0 zW`ol|pV!d^_KWNI6n_9s#|o&pgRQmI2g2(?^d=|=p4=wvH8VTJM$S| zH*>f4S{g>%5lFI`XD>yfO}b}Gkze{ zX*7m4p~Ia)xmCxVRwCyfV7-#z4!>Qw|GIk4=F};-KM?Np%SDUBSKkzupGI;sBPqG@ z^+M5VM_%B)@DMOpesjRjq@DZ_HqZ;ms+E21sMS6P{XEv!5w}s!zFoXj^@!08mW6*9 zTNe1b;-C07`>WoinF)n`~SBU zzVLe!-G;6!hBIz)DDe#bYiKOJjPFbH{krCBUiE&BE*mn>?qK|#rE#w-;y3N~1!FtK-b86#G)CC&!zOeOKW6v6 z3?7I7MRsiBHO5>hoOZDP?_}M!ho46Ww|BVnh-(>#HF{Eg^DcsMZ!Ds(s`u2^GWY9b z13oEQqTitD+(L$VNmm%?IF$HF{*gpqK7_3aXXoF81_}Itl3($5oAj>vgQCg)BWiA8 zu`1OaH>uuOu4RF}w>1XPi28Y@=n)E}|e zaJ3SLj(z~m#K)2$@$%Ksj{R{&JgPHCeuX){$AsN#=JFb4T7#!GPwr;4_L2B~p6+S1 z{*TzDH3+i?^7}})Y0m_o{cG@D36C4qH~6Xl9@4T2ehmZay>cjrZbaVY2d|~S$vNz; z+<M^WiU(c-hyv$?5whf>L8UIbS|lpWxh_<8GiGUpZ;n6+`e`Q(~YnEvWk}?L?<3;4m|> z+iQ02^KI&|`2+BGAA=8{R5@{V#@yzPVJ_A9DjN*6X?JwLj8AR1*8q*Op^*FY#3JMg z8;Uw%XS*Akzr{89&ZWzLZolHz*Oh$%ZQKuN9DJG&^_6u-yOV#MetmzJ z)6Y)?Idud}Jfit=X2^4QkvEeEjpIz`AJN2xCZr?8q6zOr zy)5)9uj`4cxuY1u2B(eu?}qtm{BWAsaUYusJ^XwAlvCUr4!gf~?qE$cC!K?0v= zQj9~mMeE|E3fMnKbcVTy_Pp)MqZp1{*&tuQcaA2%W{&@uw8?OX--FG|el5Ca-GAIC zUNhA;`O0g}?29UY?mL`s=}+hLa-WZyAG_$|7sTt$^4AWagFhHW^@;b~!|?0N;^A;hsTj(|{~a zHmp~Cz~emUua#^j-OosurbyRjb`DQg?CcyyKOgb!T==qfsMn38?>Q=7lkU0UtI#YC zjoNRM-#7nnz!6~4S>*-4oN-BCtu%J^SlascNYtst4;4l(U#CodzyIOa`L;I~T!fSE zisE_;n_`WIzHRhY99yulmhuM5EqrgathM+}c>8xunciXfA#A8W(0Zrf<7eUYIkqYPIMEz8#rTY4Hgv55bw31yY`ov zcrz4B+*^Epc$kmd;dZ;8x%meT&a}fTscL&QP+j0$BVK zadsXR9(oT`Rkw5aCi49^k@T&4FEMUh{UkQIk$Al)9BRm4Og-VII?qxk0>78b=2w(G zO<62H(JvcI-7i&?{lG8V#XZrMg4(M5@{01mqP&5zRi-)E?e}??P#%l_V7RTK-UI&l zXZ!VH&|-Q;*?oQ){M{~|zR#N)l&Qb(_~SSDWqN~senr`xei?7{x%XFFl{ZzCZ>2l~ z&6>e4?0*NbX;^j)_CjMzmbb1$_j%%t71WWubC!H)Ch5>7?Sq`xlCs8MI*(NvU zY<7{EVl1->KhB`nz<8sK5smK|?jerE8%i>pF45^-@_m$F>5yoxBU!{3Jyv!U=;J1>EWpuxZtycC~iHB!U_82<8H7;N2 z{37S@BdkMlTC&D#b(*|H68|1J$1+>6iFXZ;fllXvuXtDArEpdqj-cay1-{d$3lA0B zvfS}xn!MI5Ffu3`Nd1}Q9$!X;UtQ3L@QnhCziY`;nfO4uJq9e=i-#hlFV#LpSrquL zpiK3CgWXnTZpcSc+m14R9((Tv;nK$V3C$}(I~!eK!#m7Bfi9QL=HJ)Y&f#fx&8s&v z?->c*y@ID--}UDa&O%FD_l%2*%c+yFnHTj;hW^&TOVBEk`Wx;rN^g0tg?BAz5KVx; z=EA-SPT^6fu@IWRMd#G~Jn=XA?5*Iy8EDg%LNvo!4LU~9jUr|L)zb)WCs{j^=t zX~LhoBGJ=o-(DEQJn*#~nE_s7lC1ask{n8|BJn4^vxC0MV`yI+i(M!G)fo21%KpYM z&%ej!8Vjwoj?=)Wd`GNxkq@|)akO9jv40+Oc-z6cej0dyuo+5ucYB8-71n4LoVa zb~kM88ZPVje}hNG%i8Z3kRFTdfNTC8@K@e5$muWM9zAYTX7QFob)`qH1RkUN%pw1K zlEw@^59Nmwce)YINiFf6-ak=CHi3M+!cVrZV6D0Q0XkpbOP#sccFz(^-ku5KPZO8V z%&NZwxP^L85`){w0P$qt9}xTY?vPXDj63rBgIs*RcK^&fpZUe-UwU!g=S45+rkSEu z1{|Z zyRYZw+BMu`*Ld?N(>h9D$WHDM-y(anZTOvg(LK;m?u??Y5 z@or+@PD$5zV>H@9gnCV^*1xs#9QU;a0ptO+;-R3S!R=4zLSlf z!P~;8CcwqVBLN;}$M8J*3NuEzUF3{*ZItWXiR?+O3v|hAeA$s&zk8W$S@yJtXdQl! zHL$Wyab~*7+Xt_ddE*McmzxHESR>q*-FOxL;H=kdMZM-VA4TWrJH4zoZT>hf=I-{a zZ%_`ewC1b4<{gu~)=iVVuDU8O1b>H)X9{5l9%DUp9;>Upitpn#6~fbRcdc*Wm;7pP zp*E2juA6yPA%@?%Hr+d{`OW&~RfRU*%JYp>zP5eqFmHW$^VDD99^(b;g{um!2b#T} z3-@_@$BlDa(%dhxE)DH>6s*s6`#9_D)tvvR7p5KSQJhSlV><3|btfH)ZymlUY^rDd z`&EU6`{jbwcvWF;-ty6SLZeGwp(fGsfH<*_pGJ;U}13y z{rGjJ*ZJ*R@wdMI`F-B&XYKP^z`w=4s*tiQ&t7A(c6SV0)mIg!)y2K2)}Q{St*P_o zQU2$bZgmgl@GTs$yjd?XzuY{=+RB`X)98BYv~^fsl75y@Co!LTXMs=LDYo0to^Mc} zJ;7Sif3p?$tf?x?dhIWV*o$^}buU7rnZ1Qx=n`XJ)je2p%>-{6xY}l*(2|1wjHPd9 z8?2C5b=lrw+nV6Tr-%GKHf#?LhwYO7wW=5T-!5p~%k&a0VEk(Figig}VM%_XkKfGc zQSJ_sg_%<(dW%ReMwg6BU@PaN-fZ|O62FLWKfGFccci(C=O)ARJ`K>{Iw#xKM?LFv z?4NZX^^n#4`yb(KG7}nucbIQ|Kj`NEyY_}+Xs>g>^gBO?dPIC;!zb4FRu)42D+`k6 zu{+o&)7sPe-EEuDC&;w)_ex}1vG%xE(eJViqh^mU+sf|<%EwUt66JcsVcMNM{sjLm z^X2GV?X5UQ8l`*G&y%$Iy>4^-t6CSJz{P@I>s9G>2iKB zZ|U$m!B1-wN3ON^ku1-MZeg>ODw93V#P-CUOvBuEP1(ysat(Oq5 zH*Mm5Ll1mCpE;Q$5$eh}p!wF?JBM}O8?k#!xPbTM0B_kvlIMm4lS;fPJqVsvJKz!W zXF9wm{uK6jev&u(QS3 zD9T&fi1~eQ1^VO;@ew$;2w(QmDDRR?vLrKG1A5E8`441A`8sDvo-%3&ed1HtgUHic z+W3@lrTxcj_9V-HM4idtuKuf#1)a}UOmBw1t=|8H{j2#<*RZ^<<+ap0 zHdvFqnRS!AZLH-qXd5+O!R|CiM!(Pp4^4sxdJE&2yDyh~mx1pIdfe~%yfpQyLUQ^9 z&(izXOV~5!*L%q+VXrM;?}ez>p1Y&ab|B0iQ17k#VDyCqv)4C!J%y<3!IJHfz8OJ$!Q=v5|*I8NqHQ{@Q zeTQqieA`aD7&--8e197@$L0yQ`T5$jlki>~+hYd#8SX-~M%tU~{k2}h{$_76Hl2f{u?Lh z^j37b>`T3?!$19k=o>#!?@fl*_WpW!0X|~?lFo`j*M_=!Z^ra`Z^@LB49JeryhRV` zExY}@yitND!KHako!7Pry^`FmJ+Ej_vAk)77WV#f8=HIPhV*y6t?<%+B<{-Bzrc9( zgU{9P!)7j)xvXF;^nM)v)?F0*T8n;&q#U1*^xoORCY}o&G?%TcwdiK&o4sGy>hlga zl<0KptH}pf$xXw7abBGD=05(2m7Q0Z%({);vCX&7ky-z2Glsb@;61W`?u4F6+IK<6 zC}+ip`3q0yMaiOgYchL*=G-8Br(y$uZ@g}T_rb@U;;v872XyuIW|Hsz5`&)RU4>rd z?%~MynYZu`x1oQK_gTdM9b0xx+Q~QZCZ`{pr`P8D(ZptKZ}t)7O6#GuX@I}AE;Hcw zU)jHVP3~cBP4c_mdE9A8Uo_80zkfq^$}X=3x#%s^{}Rr7(9+-ML_^kBdt0sDi@kq& zAv9&1e+OqwurHWDDakT(pEiZL$GN9x{`P?hUMsTQGJk@nd#h-w-XMOlM!Q?~l&8tDdqzhhq7 z^Gm*Md}Zz(E^l655WY#_3vGO!%?{>$9f~~0Gkd*r?ty>dpDOr8cY0&F)1m+BC^*YU z!y%GA?*{or9|4d3(udNQ;>)T;#!Vnc`hA!1^gCP&TQiEDh$QbX;ZlvfqW2}oW5|!< z1Lt=iUYPX}*{qy5;>byyZ(Sk-Z)$IjV`C(yuva5DbCKBu-@nX!d6M^+@RaNU*?G@u zk3t?|ABJ{+d}6YNB^;YmosC94PzB}B4PwIZgz5Hf)EzbFXHv$$o zRhdo0n#&r>BGkD@ar!$xUM5porz*+^$=AH)GuaWOmH&RHzH`2|7%_k5akuRAvhZl* zydfMW+fH#eXZ7R4n|T?>DK27ev*FLh(zMK3ul_v#Js}Pv*^d?{ba$eo8&FL&?(+~sZ;#QWbOp)eV)Ggk({R3Km7A#V)t-! zzRtVg3!U`8b+{Ee-U&X<96%=%@S|Kh8s^_(cyZnr_5xoS&Rn{BLU?BR{5+4d^K84u zo1N4*9rt>XXS#F_&CfIVM&kGc@sG&%kj*hUb+0euhTmS1EJdguff4TVBh2> zsXu}58l&^^@5HwhLii@CY`&%8dtU9iD-Q8ym3?+@vc_9XTK#I@O{MTFAP;Ay(Ao5* zI_;EO=yavKNSpX}k9+GQi`9nlXVOO~xw+6r{PWz-{5#2=dEpUB_P7mS(tfoFx#50} z{h^k8(IiYeV{J!g>fL%4+fn|%Ehqhdvze=Yx8zUJ4eG1GzSmpy5c-KZPNPixDSs*Z zW>~gjBGKf%!#%L-`uWgq2DJO8)*y}CX5@#j@n)p)b7f2KU@Y*sVKQmn5j4->ZV8;! zkL&^U@6wE1yxX32vn-aapflh~~((mij`MoU0QvdQb z_Tg*PZy~(0?r^?~wpGk$aeI^3p5(iebd&e${fF}wYbZK{pI4RH%>66h^W?xS#~XPA zE$FLCKJ45BUL^Me>?G%9y)$NA9;xMbwQ6%;b%m4c2`fWi8GRpxPczZ^sDJ*-^*pL? zw<4K81*eQ#Yj1Y(^*4%-)Xx&|ifAqP4J+t;e<;4F5S_k#n0IVnN>Qg><@oZt7$cI~ z;_oeyU(cajyK&zUvk;e(sH;t)PJX!beeV@wkHNY=did-#<* zfx-P?#3s+K@h%cw8D|Fli~nYlHqKW=@I=%&yh{bQxyno2KeTYVezO8V*HA1cy&;PD@!ZW2DTzjb<@@Swt(I*Sn3NtknHlW>(t}x^uq1v>vYzChdv(uFj@Do zzHeYJI*9H+>>wXKi5hQ3yvFMyJdv$=l{ZJ|G2R|BKl!+A#+O}Sa_(bK8EFKrLWZ?hv!;3@g*@^mk#U|dr|t^GuPU#Dm%-&QxE$;U zueY)_-icI==YosA`Eb(k3pRTUJVI|}3U|2NN#i5jZH&9y;(LMYy(W$NO6UdnC=LjkB3#5I=TxhV)Rj z$=ib6uD3=Z^q};{EZ$7!Xs7$vP{P?CPB@R`a)NmWo^tj_!Sm{vc_BldL%m3LFMhY} zg|YGN?k?!}VgkB^!+c+%eM5d+_6>c5iQT8WO7k*%0sDZ_S(vk3D`(+14%K)sY7Fv| z3H>I;UEUM)T|1@Mb;#c`zvQFP_fyqtc+Z{Eev*PGo&C>J?_u)weVXR@c#<;o6mq~f zWi{R*>fTEEgT#BOGf4T81bdcU<85>Zw3pu0el$q?vCbBE_dQeHOqTEZ7`q{Rw`b?} zdfT$}pX6H{^0V~QN15!eboy@3WCp#*$(PSCihSrjjxl$8OORLOCoh@&JT{H?i*2^X zkBg?N z8%f;lsVoxjb$3ml;)?Elw9y&Osz%QFHb>w246<%9+C3QH^EhoC`mp#dP~G!Mx9YC= zLDoaxE^F$o0Y835od?MKSVjN+z~2k%WWKmBIz~9a zFS~<0&hFKcftKW6=D4VM-WYzzhPgctF7bqT?}q%iD)W%!Ahg3NzMJB^<;!Yh+l}OC zcOHI*L#zYeRE$LFSN%sdKDt_S{AMtY=KfvAss*2|m9+{?dEtldhp&6eh-7RzZclpM|>-T51?3u{h)iVgR2kb|2fXLW{Kb) z3?8aqx;o#K?8ZL|e(amtyC&38C$2d<#rlTJ+;i=2{5tn~Zv}0`)YBPKc{<~%4G-0i zOZPvYZt|M3uN&-LUj3!3(V@NWM|IxR9dXuq?8R)&_g@}^AI02O_$2uMigVxsV$s<` zXSJvI`ZNsf$Q0g1w*36heYGGx7tZk8jal{)bmyTgFuFCi3EPKuOWN@zrkuRwK)=y; zSH!|L+v!bn+2_o5caZ&UJaPan_Oow4HZI-cN{6+`K11F@_~6<(Ul^<3{SW1=n6!b1~n=4x=5h)mZGU?5mS=1K!nqLlI$&!H{u7>??!&r}+D@ zRmV8sX)N&7TGQ65xskVaTU~vh$(cWY2{IdrpY7|MD(?2qp`OD$%vWbjTpbydDaf0@9^(8u*^xdA;H->)J?-%G@ zt$0MfWZ(AS_a0<>=d@7XLi1GHz; zY}B`>(|kRDZLvSs6umXmG;zYT()Sp5#gMb?ZtMzpEO9&c98O-})Fu<`Wz5~zjo@?0 z;ddq+-cZN+?l4*7ZDWj$HnNHjOZIWLy|f2{Q}I^j(}K;f{a54ZZMFV&4PS@atg|)n zrpcDxBxd0Q@%Bd106V?n-9qCwaFUHy;{9v$lJ{+l{Q&v;CY$?mbU=+aM84W(!RZM4 z`jAuFAN{t_gS&!oiB_DI(eJ$d;clDrDR^t%l0(gtf4#$#KK>{=Sh4IA_DSsb!Qper zL+|^0z!r41-WTy(u}ArSs!{u;o!W&BAiM6`;wRAi@{?)4KU+e(EPZGA{iZDRqCdUg z0Uv*VmQ1}ye}l|Hv>Q9W-@m_4Ll>GNg@*C6GpV`}8-sZlrCxLy)-1TO94}ECe%Qmj~OSHgm=DkH9 z5#&g}ZSbtkH_EiT_X2bL!L0Pjpx0_skF|_Y_bJt({6T%kNSXNYDaIJm8kvD(>SKsL zROe;-5ZyFSy(vF)eA(6yfUjiuSQZ=@L+k9nTXzOL>9ll$yNG1zt+c*7*7%Rp_qE*T zw4y7XqJO@rBjYkIx;TnXFjMvpN9_H~gF71JOy>r^8F@i=)1IvG z+wDEbSg~A|y=J#}H{Zp~LpF5hIF9!kRk;_7yvcGk*F((HfX^$8D|$%B>UWl=C zxgmbHZ@=rjrn8guo6cf}&i{{#4|5;F z?<(Y+Fg8Y%Y5Bj6qu=1bH(0zGd_+%d(T8+aQ~P+`x!&z&iz~XSZ+)+y0sjc^6}HrI zCueg{jx2|4r8hIqPy98}y|&(A#nRYm^wVtf?Fl^L@88sG=Ke)%&mM%%yCFX}(Xacf zCvWxVw5Zq|-#Zcfe0|jn%|e{hw}thaD*VPZ-_p@GIyc@QeR#^b{$8!$@?Xq8gq-jV zBl4PtHt+$^>&3vb}7iN)sCM}&UHXZeGfNyyR_@wL*=|lDP zl+9X+mS!{GKXC8o%e4P(+6!)?$vXypF4ErV%T@Rp+2-?DGvTQD$(PWQ!e5nxM_ALR z$k!h8Anl?Z+`qv)Vfb-O`gT|QpZ16`?fw3FTXF%t{ol>F=_{O9(ckOQ-~Ri5aEv5& zPn5m~rwNh7)`>R+b-qR&%|YemvIu9%R%F|9t|<8Wo&DxKc!=+0JS($>dmQeHuu1sd z;iy}Ry`K_Gzvw-fNpj|fS9D$%?lIowL{q(P)Y>~7pN^iQ{b9eIlYf~wKAn0=>^leF zYTe-QKL&Z>1m7|N{}@<%;`QLHzMsR6l0En7+L9g@?ONCaTibX0yvaM+{OvpN-KFqZ zzzfw8^Uzb^VP&r<)K#D1{JUM#~~68Pcctdoh~!*?j+C*CV1`&{JUp$N8~XcpC3Dve&}eXjQS z_<0Dl|&Bb_OqlfEm_T}(EPt)q3LAN3&`>3y`7oc#>E`<(9gwT{rLh&R#K^ZY*Q zh|Bt9UA^Pxts}ZF3f}lOo_hwGy`C-U%de^b95MtR+S^(<<85m434+%KTc;Q`*bZF0{07ayRpS z*8|Gbz@slD_q|7Hk50@(J13OhIuuTHyLwAomFzk+HrbV{?}6^?oVU-Zzx}SP0-1)SP($6=DZ$a)vTmLs|3~wD0?S($G#oNZ2w>4~@)cnLh;x)Zh z9}B-r|2%;_TnTUKywQivVzPI8`hBzKSyTCtwEi6Ct7T8CeT=>Gw`{TC%psdhw&6wa zsMhTb@EzOB+UZ+lbWYM4D7=wuit0DJ*y5|j2O+z!u$kWlizS`=(HoBm4|u^fxx2Ba z?q+T8_I*sUAy*iF8;Wv$zod6z`YoGwY&?Cx4?Q{qSawqz-~S&1@ABC2N`6uM?a&oJD7KgEHua1h51emhb70=&UBXh(6`{bKf~E z9UL}y__%Wx^Zi(_Q12c0e_v1E-ix<=8AXP~TYDoG@BCir#8=R( zR(4Jy>p=S~>zygB{YJ)-zT_-(B$m9#x6cO0R$)6}wN=*0_`nf%HAPgY4K<~Y1v$ik>|Naqi`v$^`d-%_0`$qebeM2d+y&=wEH4+!_QNc zP4_zK%dqjp(l`edJv5rYswjWxqIq^Wen4qwM)|SuQBc^-sWV zp7=Or_-spk+D#LscX;zKq0g?F`0fSgdVS!jbH=mRJe${kwS;|mkUi^@>@ljldu%{= zY)kof3i#Ay=Sf#Qh8~e`pdWfxC%)*v{a-lK$vKlx$F;X=|ANJmL`lddNnBE5-p1L-c#;gW|I&M&R#L*4U- zusy^_{C@1K+!;SN4L<14z|&d2f8#xkf4)oN{{wg3<33K1KlFq5kPFtEbEALvP&=RB zSVMPQL_TZJH%Iu)(4oF91)Maz|3ml7->E%LKF_{5@?^7zFxMYKugiWt%5MfO$oD3C zbN64`n>(0r4*czJMqhXfddV;K1KwVBefnJ9pY|4ZtbN8k@H5ue-t1m}-j`kZ`Tq*q zJ`OD{;R`M&2)7cl;3RuH2d!nhZN^p$$DK#kzd!n<=#c@3#fEPp;(diw?yjR@d_A@3 zbbb5(6zyu$rM+5v!&}tXo-h@xvd4Af8@)R4%w!8F~0cX=b4}In-hogllyqXGede{A!iisb`$(=B4f$FZ8>ub z)%*DtEcK-C=Zr%0s^mSx7H0y{WxviHJ^U}n8%%a-@niMyw5rB zbI$v`)yLp{Fa77NsAx{Gh6S@Q{O`xXcW4pxAe?j?RhP)-<7wJr zVi76t56Jrx@DU$=W5!|RQ*_zvsis^B|4jw`44-DC7whv@RoYPBUHvCrWBfY*|w7bIYY?YKE-?h=i;$ceK5Cs zes}8l&Y9&{TcUx_$MIi+{y|fUzoM>lDWkf__%0kg!Z+D+CBNM9`l-5?XiI!VH0>zk zRsB|?k3HIF^Px=NZusxMJJ-0oRL4`)@m#ikUx^i*<;{Tj=oK_`;CKZlItYX z)j~IQU)r+Qp;e6YQTkKeXUMlydsp%Ji>WWinErzCm@Kp-i!4GrCwV^3?{RlSd{_q)A-+Ij^xD;UP&JD&bS@_=PuzA`pmSu0~zlj>5#2dXMy)(6n$pIJV9T% z`zgM@WLM@|csca>vffVXKxbuy&%(hw8tbA-eD~igX<5=vR??`a z349IrnR@@1@)ga%50J+-cSnKs8O(#?I;y`<(bpJwvnZ$YZ+H6_kY)ih@gnI~qcX&DaXl%KpJ;eVAey{p} zh5j249s6)$Vr;wjRnqSv{r%LFs?>8m@0^JY%3jO=`bs{|!6HYl^;_we`ZG7-uy$CB z(uY*?JV5@MN?GEO)tO42ie(a%jSm-+w(bwX#z_6hh9`#b9o5yw?_Nzt`-+j+4);p|g;#D6+o9fRa-je~vm z5kr}ny%wBY$oYKdMdGO(LClkk{onGlmw0+&{?>%^1b*vu-7P-&9{KTKuIr?Jja7Lh zW5?q1f8)FqdbWs{^}7>1bLBZ9AOZof|bI|Jz<o6Z~d%o}!DGgdv;xNw~%N{I}ZiTVlVG;{RfvODgdSzdT{Q%Pa8gNI2{N_o-8> zHP)r1+nimG*;f{HXH|8clH~dGN}k0N>X-vgX--u3x(VN_bG1qFyC%T$la)Lc_3Lhe zYW)q=e@~_U^>RnZ-_reM3 zi3$B~<@;V7?53Sxj_0ZviTn7uzXMgV*XRz?#BIdnO~Ff9+m=)2)q(FOFyDwAioG?E zAIRU!eI0{=PR@L;$++07U3BNfRpNUrVsG%HQ{8+&_#;1#wM{d;n7$#4uA4Fw+Kk)= z4HLfX%by~y(gxtWftVM4$i`l=ooAFe7Cj?gFgg>rXlJ=2kl$Q>&HPNd&u=w-zfvsL zR=3Yj@Qd?HCUozso4*yh`g3A7y>Z&&VmK>1lc~eEV*eey*YM7$>$p4Cm;Z2`Xaa3% ze$|fdB1u%zLgZy_)z!)_m35oo8OI~<$}1mL!PEPo3F5K7+vl|vpVw=E-z1a$mF#uR zS}XNVVFX{vKKNsw<#@(oPxvl>*M<1I4#Eot;XQ*6^ga!oa#`PnAL<)2O|iilWk0;d z&pP#t9~(jzS=z4mqrf2acSD6JaE{u@&*^ImE1hc#zfQ;(t-MzmN>Wb}xji9&$Ue{I zKl=vG|IxoMpo2{el#qM#%hA=D%wWl+xGMy^Vgy|%_L=?K_YcCe$3h`^{CfIDU6c=e zSZDNm17;xbvv5M#^&H1*mHjKnIimOwYyY~UWZj(xS%tpu&DHxYjrEA)#N3K+@z>Nv zy#w^~0Cl#f)-j&XX%E~44{zi=P2h+7Y=k(g7UyA@Kk*pp7Xm+AXk_)gfd%eP0nf(b z*sW}MIOG?x9-FcD-I|*Xz@T9lbBq6??8ll<+v9vPc4Wn&5U$q}gQA=HkguuyKmz-6 znsbE2e=z72pP`=rh~LM(&y>SI}l<}Ip^ZtmzRxu1OCSv zr{puya@B3+K2y*cYG8h(VaA=F&cv&3#e9pzD|ItobYS@?Iw+l;61)SuuUXvmd>FpQ zUg^3Bx@qcG%%BoB>*;B1yYPnheeG*`?Fntp>D~1&!d858MgjynqkYbEP);pgC?tK99t)?Z>r;SzOc{i~ly85&szd z7M@9dZ%&W;LzHh}?aS_QKsJ9Py%%%@-pM>&VsUparkTp!Sj)q zk9qXThCgq=$E(S32On$gfpj^xI5aOW-D^Wydn)+=aOR0VK}*8Aza)~yUl*7W>&Vl& zec7a-iyw;^_Ek~r^zeDjrR>+ieISV*Z^#zRe!m`*y}+Af_vD9cY+2N)m_(zr`vCA7 z$tnL5V!oagg(lRs6Ei_`rg~(vACjG(cj-42%k%ea_Q=qhQ}xFJZ~v4&2?p5xA5xj4 z_$&_rt7H6^jb8Btf;|lRhpKjZ`4lj|s+~SKKU=ZWPaL28>z+zWpDtfY?o8)ANppAo z6K7ZPBs~WFH~e?II&&M?5pw0{>&&m_Ti+hYvEGo4uo2nTksRY{Vl?_Ga|&+y$w$ zawp8#KKS8_#7*8ELf18vuHVP+MbQG;wna0f^OX;ieEMX^t*0L8x1U755KmQJ@zg(* zUv#xqx;S`60($#y-B~U6OW{-0b@%iD3yp~ddLoAH`Azz3akfx&=uLG0VHgJcjXJG? zP-3Xi3r}U5kP?#_q|A9Iiiq^rDLc08WatFPjJ+>~v4uX~Ks z!=?u(wqe%J&_*v=kRM!VqXH*4fOM>DP_7DT_b*4rm;FRBbsX* z>Lah#f_%nAXFpJ(v-0sZ~08>uGpM8ap0%+|09?XA4iAL6H6KdD7)`#@T+q=8{{yW4yPLE<2v!wu-cN z(h|vG=r(uV^G#zFzD%^?5zO+0ZJc^pgq~@G(TB~F_11ey$?8P&WTSS@Js1V->xU6d4pC_riG{GbSM4P_;b|J zOdWfvTYk`j%XGe%`Ozq2!zV7zx}}Y;w3hp=vJ-ivA;0>fz8)ptr|8S{UCOhh_&s8g z2wplf{4!6~C4XV%n^^9dTzSqTv=RD~n+huoJR5p2iE~UfjAie?o;o3!P50B!=6sUi z7u1{6+3*d>6k~ob>sxZxtMLta$xD)@q;ryePjhcPFVNjr<)_L2ll+9OO>5CpTh#Mr zVnhC!H2u!F#SP$E+#U60_Yl6Mi?$;)B9Ek19{P><21*mcCbVsq}W}JoYP&)JhxKl|G0j=q@hNrjexX;Hmc? zl}`X^is^2gKP}WaI|CWd&6Q~w{>Nc#k<&!qL>C_>uf{Sdz5%+r!GC5^*UQaR7PoL#>0hJ&^v%(v)?*65G{j~dH!x&#_A^lM`Ky6~Z_@S*IlqH{Tdk?xC` zgZ!YlnWwYA)tP|y+#3FKAE_-rpN&U#Z~Pp)51ND>9K2V2fVn)?R;Shh&m>Rzhj+x+ zuzsK!yd%Trg}*lh=LpJvi0C1vY3!0Qe*yf|=Q1uXDW2qi0-Be|4FvYgxzN5Ocr=%H z>1boj<(&9{U&k0a>;bCM=&Hy&j_6xgv3Xg^j-8pO&pk_rM81e~n(cnf*pfHaKS$$n2_81AVPC!@rV^C~Bkg2X?=v-z+dq3>kG^Y`vubY-Hg84VqKt93T$h} zMpuhnKZ<@;cUwjbF=vo-684B6%`L?*ri`P))z@fWxGEeKt_qigtCr<>9h3?16}~QC z5#j7f#_|Kkv52;W8^onOBHxu9{Sr+c0RO^_S$lV#IgcS%gyUr&1MKWi3+ITvaYSR? zNtqmF{vY|LJwu*0*7;s^C<}NB4_mfFBf&kB1rJlmfZ*V0l6P=2Vm2R@&EScJ(6HqC zqq0v&cxOH5F9a_GoWzzC!@d|v*7>i1BUPLnO=4q|%;PY(^vf9Z8R#L$pv$7cfA&_n z-*a-?0)8Yrh4JV^WxTqJFznq~3g_Ori|v0g2l7QuF0;&QOD%YM*&n&(vzB>%k!5bb zj&H0d?eku8*c0a16Y~5va~d(+-yC;~Uk;V~J>9DJZ+Y|7@9j^uH`Ts0;I-+Sy>Max zdkTINjCToj2v5bgMK7x|Qy{lgcy-yoW+d3ly(iD6y!fu*egU@03mK1aS$HiTJ7~`G zcXR$w{H=_eWB%Wz=r4Gg!&ZDUeh&Djy$^oAtW(MrI~h+iWBDig*MOgLHGK)`wWN1w zye@vN*d3G>1_o{VmT>b|XiN@pPcS!G?O#7%obu+WBRlD*0gjWlm+6wpZ1C$+8%nj5 zXRnxl8r-SUq}sP>(!f#q)&%x*)ysHv?~U%Ji=|cf=Zb&BoQn<#UnBPXLXE{(*ssXv zrv`bw>htpmaIrGTvCg*&85?~LyiDs__`aC><`dgQeC%rK6CW+t*Hx(2CE0&c#eYb5 zaEbPhfD0d@UsV{CEaa5*JGu$YJ$eJLtUE{*4;yS#|L0U7J4>zz&hO-~1LWL2(jmmz zC;dBfQiiu%#6S?NhqK{3fow^Mbg>P-qt@*w_t&t0^f(DnJIcH5P`XD(_ELv5*_XJJq7E1z zSy_4iBJWi@6gKp_2s*-d+n%~Ad6$rGQ#M(7{}}Hf`l@=_Bfo8Ls_OsY)pfduscK7+ z?Wt<#nmM7YVq{cx_tmnHso%5PG-J0Z$9DCK|3E!f#fEiIWmDL>68IfTj{(u6%zly9D;m)hheL31zE&B>r5TJz;#~?~#Z8 z{hqz51$))ckf&7V1MiWa*vh|WGufg%w4pOYl7}Lxtlt}#?FjyYoYZY`-@*<3g>})W z*Nhw-x~QkHE;Q3?);@XxcLmHK*8X+JwpRqYXhqd32nRTqIerQ9gxW2** zm&4y2@Vm-O-ox$$?{teR>6`3Df@c*b8|Z&)6(-QB){1>bwx=`BH^KdRx;IaD0o|P^ z9`yQEANW=L|6yaf3_VrV#&TY8r^=$DY$~t!|0vdAHUxK@zimHY{Odn7)9X+4d%ZJ| z@fp9?>TQf!cO^6+ABo;su3MamokaE$*-B(15wB`NexA;M*;-WYc3^>xD6p3xyK&Z~ zY%7tTZ+XQQB0Zeyj8lg36zSKou1XqvhQLOmxK4tZ+EIF#_9wnacqh;C8lLch;~}2N z1HrvD6KyE$eeiR~z6BgwXv3H^ep2^hCs|k0y&W-ZD#qL!+;6pNlV#k`SSB*z+ZgZD z!KG$oi6+iZ#qD(Al9}MhE;nxnb-Bg0Aqzd&!h&VH`TL1!vz~qSqDC!>w-4W&O4!_TqHbZ=rs{M6#<%WG@YIUwsVye{;^^9FN1^?a)W8 z6#kpdz4?}ubLpPB%geUFNjdpc$Uf#E&pXhb7p8tM;f8l7+{W)EZk%GFueC{2`IfjdmHX3}Ysc4_ z_qoJmK`+J?$JlylclBqW9q^7;=!b3A`vbgN=(@1Qfm7T8pXha{hpkdC>qp-lZ!Wef z!9}(%)$yT5&syeim!(1OY|nlhdBREU9x+%<~S>uSQea< zjU+$d+ez7?7ZfAO8}VUV8lRraM)Ajvqt`HY64(k3z-S}m(L9SjT|yru52{Zl>CU2G zm&n$@SrQYDFEzI9M5o6ce>He6oL9RltNb?Y3qMSf{Xe?Gz^;M+NW^=gv=%$aWcCWk z(jRNceH9twtDX(a)rW6Qs4GrgCk^m`Pc%>;I>rlyBeMO|A8_Qlyp`%6;6e4geeWhnjQ6qdQG=&U^*)&U&^D`)AEr zM(Ykc2y+$7FjpDoN_x|b-tR=GRHieM_bvO*LYDC(PXx5*$NWFzW}T&V^3q{2|Cc~t zE{z&@_Q`HwP20cu^nY*nINz+4bQ_$Xq21aP?WSlKx*bjF9X~hbOERTpb6+og_&RM- zZ(jAD0#5|@3!y=6%)z{sj0+e*lb&t?j90=%Ix_F-B6z*;F@Sg700FnhbmsNKgbLI;WX_#ZvNYvSN7>O$h9@;TRr44<}U3`PnG%0 z$$39Iru!6X(zkdvJXv=r#WJ^e8_6f1^=Rs5&nEA5)2IF6an^gV{u9h=2mXDk*J2Ef zmn`$vMIv59Zn-y|xk>;_$s<~l&9CN%`wW;SnB3{|`tu>1 zvh*cRyP_W_tup?FSVxNOnE~gfdE~v*Ob_aV0(O#|nfahu685g($pIGKK#Fu&ELl$!8rT+v^0RIBM22O~k zhGsJ^XzC>&22WH!WkV_Mq)hG0bCx4d%u~-oAG;&r&IsAPHs?rYhEuy|Xb%hRIZ~5x z^AA?mZj6}vhw(>=GCx`;p#}Sj$Qb)|N3qToDMqF4hinV<1`CTFz(h0;`ds`8<>DE1 zMJdIOy}sBU=ZO!v;vDF_Y>R`w33_1V9Oh5FHkA)KD?I$I%6O9NyOcSa6-(_d<4L^l zZ9J)ku4yemM_XE`i{aUECvV^DptzJVhgga136076sd&AgBF5pa9QMF&bd~HkYw@p;9|h82ejc(wSB|)d zHZir(1uSv6(}OZ!*FGuk=66QqGmgG0N4&fP#QDmSAGxoK{j9~AgRnE?rT9N-jppmR zVuE_o)Hlh+#@J0vTZ0b=zTS)3Z!aNVcy^CBDcj?9@ec1QhGxuXt*`bvXg8W>T_mBE zj+;+XhvI9_brp*Poer`3YvSul-=bd~)MFuY1aZZ|of@;LbX%prwT$Us;LmfZe|`pi zKzwbf#(baOrqZqC>7=e0HtQ&L8CSGF#}e{?zXEg0R(-2XZK4CGS!COBxU+biSHm?ZN~gwf_o{wj<%RPw5v#s4advX$?u z8QI5g~H zEyjsqQn|0K^8of0=;C46t>748kZH8y}dvka>7&*GunXq6 ztujC2m+OFiFvp~69n7fY4Rvc@m5(*i!Cb!o1He_^Qs6$m2;gTKE-Dkh*?S-J z*EpRqZC_h5!uQ+OmV}2ICvgL5vpoKPqYr{daAuXZG^S&G)BLHg3;92B{CVCd(t&@e zwv1Ck{Z^Ufiv}*|2V|^(&+d6@7$UZQidLoG}zG6x@WN-8q^ZwH; zbGoL>6Mwj$yVIrX7hYO+S0Uh?ZYO7=hCK0%J&8_a7tX9gU)rqo-HX@% zGz)Kr&#IkC*

9Wo&85Jw27Ps+*5${sWC+ax&*xwFY6 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%0ALenll+I=#{_ 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 eQzYsBzz1K!eF>6V`f?AmIoZJ1{e|n#`ulIZQo packets = new LinkedBlockingQueue(); + private AudioTrack track; + private RTPSession session; private DatagramSocket rtp; + private AvAudioDepacketizer depacketizer = new AvAudioDepacketizer(); + private AvBufferPool pool = new AvBufferPool(1500); - public void setupRtpSession(String host) throws SocketException - { - DatagramSocket rtcp; + public void startAudioStream(final String host) + { + new Thread(new Runnable() { + @Override + public void run() { + try { + setupRtpSession(host); + } catch (SocketException e) { + e.printStackTrace(); + return; + } + + setupAudio(); + + startReceiveThread(); + + startDepacketizerThread(); + + startUdpPingThread(); + + startDecoderThread(); + } + + }).start(); + } + + private void setupRtpSession(String host) throws SocketException + { rtp = new DatagramSocket(RTP_PORT); - rtcp = new DatagramSocket(RTCP_PORT); - session = new RTPSession(rtp, rtcp); - session.addParticipant(new Participant(host, RTP_PORT, RTCP_PORT)); + session = new RTPSession(rtp, null); + session.addParticipant(new Participant(host, RTP_PORT, 0)); + } + + private void setupAudio() + { + int channelConfig; + int err; + + err = OpusDecoder.init(); + if (err == 0) { + System.out.println("Opus decoder initialized"); + } + else { + System.err.println("Opus decoder init failed: "+err); + return; + } + + switch (OpusDecoder.getChannelCount()) + { + case 1: + channelConfig = AudioFormat.CHANNEL_OUT_MONO; + break; + case 2: + channelConfig = AudioFormat.CHANNEL_OUT_STEREO; + break; + default: + System.err.println("Unsupported channel count"); + return; + } + + track = new AudioTrack(AudioManager.STREAM_MUSIC, + OpusDecoder.getSampleRate(), + channelConfig, + AudioFormat.ENCODING_PCM_16BIT, + 1024, // 1KB buffer + AudioTrack.MODE_STREAM); + + track.play(); + } + + private void startDepacketizerThread() + { + // This thread lessens the work on the receive thread + // so it can spend more time waiting for data + new Thread(new Runnable() { + @Override + public void run() { + for (;;) + { + AvRtpPacket packet; + + try { + packet = packets.take(); + } catch (InterruptedException e) { + e.printStackTrace(); + return; + } + + // !!! We no longer own the data buffer at this point !!! + depacketizer.decodeInputData(packet); + } + } + }).start(); + } + + private void startDecoderThread() + { + // Decoder thread + new Thread(new Runnable() { + @Override + public void run() { + for (;;) + { + short[] samples; + try { + samples = depacketizer.getNextDecodedData(); + } catch (InterruptedException e) { + e.printStackTrace(); + return; + } + + track.write(samples, 0, samples.length); + } + } + }).start(); } private void startReceiveThread() @@ -101,24 +219,4 @@ public class NvAudioStream { } }).start(); } - - /*public void startStream(String host) throws SocketException, UnknownHostException - { - System.out.println("Starting audio group"); - group = new AudioGroup(); - group.setMode(AudioGroup.MODE_NORMAL); - - System.out.println("Starting audio stream"); - stream = new AudioStream(InetAddress.getByAddress(new byte[]{0,0,0,0})); - stream.setMode(AudioStream.MODE_NORMAL); - stream.associate(InetAddress.getByName(host), PORT); - stream.setCodec(AudioCodec.PCMA); - stream.join(group); - - for (AudioCodec c : AudioCodec.getCodecs()) - System.out.println(c.type + " " + c.fmtp + " " + c.rtpmap); - - System.out.println("Joined"); - }*/ - } diff --git a/src/com/limelight/nvstream/NvConnection.java b/src/com/limelight/nvstream/NvConnection.java index 164372fd..e20f2206 100644 --- a/src/com/limelight/nvstream/NvConnection.java +++ b/src/com/limelight/nvstream/NvConnection.java @@ -82,6 +82,7 @@ public class NvConnection { startSteamBigPicture(); performHandshake(); startVideo(video); + startAudio(); beginControlStream(); controlStream.startJitterPackets(); startController(); @@ -101,6 +102,11 @@ public class NvConnection { new NvVideoStream().startVideoStream(host, surface); } + public void startAudio() + { + new NvAudioStream().startAudioStream(host); + } + public void sendMouseMove(final short deltaX, final short deltaY) { if (inputStream == null) diff --git a/src/com/limelight/nvstream/av/audio/AvAudioDepacketizer.java b/src/com/limelight/nvstream/av/audio/AvAudioDepacketizer.java new file mode 100644 index 00000000..28c66752 --- /dev/null +++ b/src/com/limelight/nvstream/av/audio/AvAudioDepacketizer.java @@ -0,0 +1,59 @@ +package com.limelight.nvstream.av.audio; + +import java.util.concurrent.LinkedBlockingQueue; + +import com.limelight.nvstream.av.AvBufferDescriptor; +import com.limelight.nvstream.av.AvRtpPacket; + +public class AvAudioDepacketizer { + private LinkedBlockingQueue decodedUnits = new LinkedBlockingQueue(); + + // Sequencing state + private short lastSequenceNumber; + + public void decodeInputData(AvRtpPacket packet) + { + short seq = packet.getSequenceNumber(); + + if (packet.getPacketType() != 97) { + // Only type 97 is audio + return; + } + + // Toss out the current NAL if we receive a packet that is + // out of sequence + if (lastSequenceNumber != 0 && + (short)(lastSequenceNumber + 1) != seq) + { + System.out.println("Received OOS audio data (expected "+(lastSequenceNumber + 1)+", got "+seq+")"); + + // Tell the decoder about this + //OpusDecoder.decode(null, 0, 0, null); + } + + lastSequenceNumber = seq; + + // This is all the depacketizing we need to do + AvBufferDescriptor rtpPayload = packet.getNewPayloadDescriptor(); + + // Submit this data to the decoder + short[] pcmData = new short[OpusDecoder.getMaxOutputShorts()]; + + int decodeLen = OpusDecoder.decode(rtpPayload.data, rtpPayload.offset, rtpPayload.length, pcmData); + + // Return value of decode is frames decoded per channel + decodeLen *= OpusDecoder.getChannelCount(); + + if (decodeLen > 0) { + // Jank! + short[] trimmedPcmData = new short[decodeLen]; + System.arraycopy(pcmData, 0, trimmedPcmData, 0, decodeLen); + decodedUnits.add(trimmedPcmData); + } + } + + public short[] getNextDecodedData() throws InterruptedException + { + return decodedUnits.take(); + } +} diff --git a/src/com/limelight/nvstream/av/audio/OpusDecoder.java b/src/com/limelight/nvstream/av/audio/OpusDecoder.java new file mode 100644 index 00000000..c01f7fa5 --- /dev/null +++ b/src/com/limelight/nvstream/av/audio/OpusDecoder.java @@ -0,0 +1,14 @@ +package com.limelight.nvstream.av.audio; + +public class OpusDecoder { + static { + System.loadLibrary("nv_opus_dec"); + } + + public static native int init(); + public static native void destroy(); + public static native int getChannelCount(); + public static native int getMaxOutputShorts(); + public static native int getSampleRate(); + public static native int decode(byte[] indata, int inoff, int inlen, short[] outpcmdata); +} diff --git a/src/com/limelight/nvstream/av/video/AvVideoDepacketizer.java b/src/com/limelight/nvstream/av/video/AvVideoDepacketizer.java index 3335424b..8ae223c3 100644 --- a/src/com/limelight/nvstream/av/video/AvVideoDepacketizer.java +++ b/src/com/limelight/nvstream/av/video/AvVideoDepacketizer.java @@ -161,7 +161,7 @@ public class AvVideoDepacketizer { if (lastSequenceNumber != 0 && (short)(lastSequenceNumber + 1) != seq) { - System.out.println("Received OOS data (expected "+(lastSequenceNumber + 1)+", got "+seq+")"); + System.out.println("Received OOS video data (expected "+(lastSequenceNumber + 1)+", got "+seq+")"); // Reset the depacketizer state currentlyDecoding = AvDecodeUnit.TYPE_UNKNOWN;