From 92b10211699dd5840b5981e9561801e1864bb9ec Mon Sep 17 00:00:00 2001 From: Robert Kausch Date: Sun, 10 Mar 2024 16:32:28 +0100 Subject: [PATCH] Update Opus headers and add support for Opus Speech Coding Enhancement (OSCE). --- components/decoder/opus/Makefile | 2 +- components/decoder/opus/config.cpp | 67 ++++++++++++ components/decoder/opus/config.h | 47 +++++++++ components/decoder/opus/dllinterface.cpp | 5 +- components/decoder/opus/dllinterface.h | 4 +- components/decoder/opus/opus.cpp | 40 ++++++- components/decoder/opus/opus.h | 6 +- include/support/opus/opus.h | 126 ++++++++++++++++++++++- include/support/opus/opus_defines.h | 37 ++++++- include/support/opus/opus_multistream.h | 2 +- 10 files changed, 322 insertions(+), 14 deletions(-) create mode 100644 components/decoder/opus/config.cpp create mode 100644 components/decoder/opus/config.h diff --git a/components/decoder/opus/Makefile b/components/decoder/opus/Makefile index 146bacb5b..502c6a8a8 100644 --- a/components/decoder/opus/Makefile +++ b/components/decoder/opus/Makefile @@ -8,7 +8,7 @@ VERSION = 1.0 BOCA_PATH = ../../.. # Enter object files here: -OBJECTS = dllinterface.o opus.o +OBJECTS = config.o dllinterface.o opus.o # Enter additional defines here: DEFINE = -I"$(SRCDIR)"/$(BOCA_PATH)/include/support diff --git a/components/decoder/opus/config.cpp b/components/decoder/opus/config.cpp new file mode 100644 index 000000000..8b20f6f3b --- /dev/null +++ b/components/decoder/opus/config.cpp @@ -0,0 +1,67 @@ + /* BoCA - BonkEnc Component Architecture + * Copyright (C) 2007-2024 Robert Kausch + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 2 of + * the License, or (at your option) any later version. + * + * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ + +#include "config.h" + +const String BoCA::ConfigureOpus::ConfigID = "OpusDecoder"; + +BoCA::ConfigureOpus::ConfigureOpus() +{ + const Config *config = Config::Get(); + + complexity = config->GetIntValue(ConfigID, "Complexity", 10); + + I18n *i18n = I18n::Get(); + + i18n->SetContext("Decoders::Opus"); + + group_quality = new GroupBox(i18n->TranslateString("Quality"), Point(7, 11), Size(286, 41)); + + text_complexity = new Text(i18n->AddColon(i18n->TranslateString("Complexity")), Point(10, 14)); + + slider_complexity = new Slider(Point(17 + text_complexity->GetUnscaledTextWidth(), 12), Size(240 - text_complexity->GetUnscaledTextWidth(), 0), OR_HORZ, &complexity, 0, 10); + slider_complexity->onValueChange.Connect(&ConfigureOpus::SetComplexity, this); + + text_complexity_value = new Text(NIL, Point(264, 14)); + + group_quality->Add(text_complexity); + group_quality->Add(slider_complexity); + group_quality->Add(text_complexity_value); + + SetComplexity(); + + Add(group_quality); + + SetSize(Size(300, 169)); +} + +BoCA::ConfigureOpus::~ConfigureOpus() +{ + DeleteObject(group_quality); + DeleteObject(text_complexity); + DeleteObject(slider_complexity); + DeleteObject(text_complexity_value); +} + +Int BoCA::ConfigureOpus::SaveSettings() +{ + Config *config = Config::Get(); + + config->SetIntValue(ConfigID, "Complexity", complexity); + + return Success(); +} + +Void BoCA::ConfigureOpus::SetComplexity() +{ + text_complexity_value->SetText(String::FromInt(complexity)); +} diff --git a/components/decoder/opus/config.h b/components/decoder/opus/config.h new file mode 100644 index 000000000..a07872c11 --- /dev/null +++ b/components/decoder/opus/config.h @@ -0,0 +1,47 @@ + /* BoCA - BonkEnc Component Architecture + * Copyright (C) 2007-2024 Robert Kausch + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 2 of + * the License, or (at your option) any later version. + * + * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ + +#ifndef H_OPUSCONFIG +#define H_OPUSCONFIG + +#include +#include + +using namespace smooth; +using namespace smooth::GUI; + +using namespace BoCA; + +namespace BoCA +{ + class ConfigureOpus : public ConfigLayer + { + private: + GroupBox *group_quality; + Text *text_complexity; + Slider *slider_complexity; + Text *text_complexity_value; + + Int complexity; + slots: + Void SetComplexity(); + public: + static const String ConfigID; + + ConfigureOpus(); + ~ConfigureOpus(); + + Int SaveSettings(); + }; +}; + +#endif diff --git a/components/decoder/opus/dllinterface.cpp b/components/decoder/opus/dllinterface.cpp index 24fd48f9f..56ea7ffe3 100644 --- a/components/decoder/opus/dllinterface.cpp +++ b/components/decoder/opus/dllinterface.cpp @@ -1,5 +1,5 @@ /* BoCA - BonkEnc Component Architecture - * Copyright (C) 2007-2017 Robert Kausch + * Copyright (C) 2007-2024 Robert Kausch * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -34,6 +34,7 @@ OPUSMULTISTREAMDECODERCREATE ex_opus_multistream_decoder_create = NIL; OPUSMULTISTREAMDECODE ex_opus_multistream_decode = NIL; OPUSMULTISTREAMDECODERCTL ex_opus_multistream_decoder_ctl = NIL; OPUSMULTISTREAMDECODERDESTROY ex_opus_multistream_decoder_destroy = NIL; +OPUSDECODERCTL ex_opus_decoder_ctl = NIL; OPUSGETVERSIONSTRING ex_opus_get_version_string = NIL; DynamicLoader *oggdll = NIL; @@ -95,12 +96,14 @@ Bool LoadOpusDLL() ex_opus_multistream_decode = (OPUSMULTISTREAMDECODE) opusdll->GetFunctionAddress("opus_multistream_decode"); ex_opus_multistream_decoder_ctl = (OPUSMULTISTREAMDECODERCTL) opusdll->GetFunctionAddress("opus_multistream_decoder_ctl"); ex_opus_multistream_decoder_destroy = (OPUSMULTISTREAMDECODERDESTROY) opusdll->GetFunctionAddress("opus_multistream_decoder_destroy"); + ex_opus_decoder_ctl = (OPUSDECODERCTL) opusdll->GetFunctionAddress("opus_decoder_ctl"); ex_opus_get_version_string = (OPUSGETVERSIONSTRING) opusdll->GetFunctionAddress("opus_get_version_string"); if (ex_opus_multistream_decoder_create == NIL || ex_opus_multistream_decode == NIL || ex_opus_multistream_decoder_ctl == NIL || ex_opus_multistream_decoder_destroy == NIL || + ex_opus_decoder_ctl == NIL || ex_opus_get_version_string == NIL) { FreeOpusDLL(); return False; } return True; diff --git a/components/decoder/opus/dllinterface.h b/components/decoder/opus/dllinterface.h index 6adbfe19d..5917384f9 100644 --- a/components/decoder/opus/dllinterface.h +++ b/components/decoder/opus/dllinterface.h @@ -1,5 +1,5 @@ /* BoCA - BonkEnc Component Architecture - * Copyright (C) 2007-2017 Robert Kausch + * Copyright (C) 2007-2024 Robert Kausch * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -61,10 +61,12 @@ typedef OpusMSDecoder * (*OPUSMULTISTREAMDECODERCREATE) (opus_int32, int, in typedef int (*OPUSMULTISTREAMDECODE) (OpusMSDecoder *, const unsigned char *, opus_int32, opus_int16 *, int, int); typedef int (*OPUSMULTISTREAMDECODERCTL) (OpusMSDecoder *, int, ...); typedef void (*OPUSMULTISTREAMDECODERDESTROY) (OpusMSDecoder *); +typedef int (*OPUSDECODERCTL) (OpusDecoder *, int, ...); typedef const char * (*OPUSGETVERSIONSTRING) (); extern OPUSMULTISTREAMDECODERCREATE ex_opus_multistream_decoder_create; extern OPUSMULTISTREAMDECODE ex_opus_multistream_decode; extern OPUSMULTISTREAMDECODERCTL ex_opus_multistream_decoder_ctl; extern OPUSMULTISTREAMDECODERDESTROY ex_opus_multistream_decoder_destroy; +extern OPUSDECODERCTL ex_opus_decoder_ctl; extern OPUSGETVERSIONSTRING ex_opus_get_version_string; diff --git a/components/decoder/opus/opus.cpp b/components/decoder/opus/opus.cpp index f0461ad1c..b0f4f85b1 100644 --- a/components/decoder/opus/opus.cpp +++ b/components/decoder/opus/opus.cpp @@ -1,5 +1,5 @@ /* BoCA - BonkEnc Component Architecture - * Copyright (C) 2007-2021 Robert Kausch + * Copyright (C) 2007-2024 Robert Kausch * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -16,9 +16,12 @@ #include #include "opus.h" +#include "config.h" using namespace smooth::IO; +static Bool osceSupported = False; + const String &BoCA::DecoderOpus::GetComponentSpecs() { static String componentSpecs; @@ -45,6 +48,12 @@ const String &BoCA::DecoderOpus::GetComponentSpecs() "; componentSpecs.Replace("%VERSION%", String("v").Append(String(ex_opus_get_version_string()).Replace("libopus ", NIL))); + + /* Check availability of Opus Speech Coding Enhancement (OSCE). + */ + const Array &version = String(ex_opus_get_version_string()).Replace("libopus ", NIL).Explode("."); + + if (version.GetNth(0).ToInt() > 1 || (version.GetNth(0).ToInt() == 1 && version.GetNth(1).ToInt() >= 5)) osceSupported = True; } return componentSpecs; @@ -330,6 +339,8 @@ Error BoCA::DecoderOpus::GetStreamInfo(const String &streamURI, Track &track) BoCA::DecoderOpus::DecoderOpus() { + configLayer = NIL; + decoder = NIL; sampleRate = 48000; @@ -347,12 +358,19 @@ BoCA::DecoderOpus::DecoderOpus() BoCA::DecoderOpus::~DecoderOpus() { + if (configLayer != NIL) Object::DeleteObject(configLayer); } Bool BoCA::DecoderOpus::Activate() { static Endianness endianness = CPU().GetEndianness(); + /* Get configuration. + */ + const Config *config = GetConfiguration(); + + /* Parse packets and init decoder. + */ ex_ogg_sync_init(&oy); Bool initialized = False; @@ -403,7 +421,7 @@ Bool BoCA::DecoderOpus::Activate() else sampleRate = 48000; } - int error = 0; + int error = OPUS_OK; unsigned char mapping[2] = { 0, 1 }; if (setup->channel_mapping == 0) decoder = ex_opus_multistream_decoder_create(sampleRate, setup->nb_channels, 1, setup->nb_channels - 1, mapping, &error); @@ -411,6 +429,17 @@ Bool BoCA::DecoderOpus::Activate() preSkip = setup->preskip / (48000 / sampleRate); preSkipLeft = setup->preskip / (48000 / sampleRate); + + if (osceSupported && error == OPUS_OK) + { + for (Int i = 0; i < (setup->channel_mapping == 0 ? 1 : setup->nb_streams); i++) + { + OpusDecoder *streamDecoder = NIL; + + ex_opus_multistream_decoder_ctl(decoder, OPUS_MULTISTREAM_GET_DECODER_STATE(i, &streamDecoder)); + ex_opus_decoder_ctl(streamDecoder, OPUS_SET_COMPLEXITY(config->GetIntValue(ConfigureOpus::ConfigID, "Complexity", 10))); + } + } } if (packetNum >= 1) done = True; @@ -522,3 +551,10 @@ Int BoCA::DecoderOpus::ReadData(Buffer &data) return size; } + +ConfigLayer *BoCA::DecoderOpus::GetConfigurationLayer() +{ + if (osceSupported && configLayer == NIL) configLayer = new ConfigureOpus(); + + return configLayer; +} diff --git a/components/decoder/opus/opus.h b/components/decoder/opus/opus.h index e58c6b516..1552f5825 100644 --- a/components/decoder/opus/opus.h +++ b/components/decoder/opus/opus.h @@ -1,5 +1,5 @@ /* BoCA - BonkEnc Component Architecture - * Copyright (C) 2007-2015 Robert Kausch + * Copyright (C) 2007-2024 Robert Kausch * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -20,6 +20,8 @@ namespace BoCA class DecoderOpus : public CS::DecoderComponent { private: + ConfigLayer *configLayer; + ogg_sync_state oy; ogg_stream_state os; ogg_page og; @@ -48,6 +50,8 @@ namespace BoCA Bool Seek(Int64); Int ReadData(Buffer &); + + ConfigLayer *GetConfigurationLayer(); }; }; diff --git a/include/support/opus/opus.h b/include/support/opus/opus.h index d282f21d2..eadeda75a 100644 --- a/include/support/opus/opus.h +++ b/include/support/opus/opus.h @@ -103,7 +103,7 @@ extern "C" { * @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. + * future versions of this code may change the size, so no assumptions 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()) @@ -198,7 +198,7 @@ OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_encoder_get_size(int channels); * 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 [in] application int: Coding mode (one of @ref OPUS_APPLICATION_VOIP, @ref OPUS_APPLICATION_AUDIO, or @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 @@ -222,7 +222,7 @@ OPUS_EXPORT OPUS_WARN_UNUSED_RESULT OpusEncoder *opus_encoder_create( * 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) + * @param [in] application int: Coding mode (one of OPUS_APPLICATION_VOIP, OPUS_APPLICATION_AUDIO, or OPUS_APPLICATION_RESTRICTED_LOWDELAY) * @retval #OPUS_OK Success or @ref opus_errorcodes */ OPUS_EXPORT int opus_encoder_init( @@ -357,7 +357,7 @@ OPUS_EXPORT int opus_encoder_ctl(OpusEncoder *st, int request, ...) OPUS_ARG_NON * 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. + * future versions of this code may change the size, so no assumptions 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()) @@ -398,6 +398,21 @@ OPUS_EXPORT int opus_encoder_ctl(OpusEncoder *st, int request, ...) OPUS_ARG_NON */ typedef struct OpusDecoder OpusDecoder; +/** Opus DRED decoder. + * This contains the complete state of an Opus DRED decoder. + * It is position independent and can be freely copied. + * @see opus_dred_decoder_create,opus_dred_decoder_init + */ +typedef struct OpusDREDDecoder OpusDREDDecoder; + + +/** Opus DRED state. + * This contains the complete state of an Opus DRED packet. + * It is position independent and can be freely copied. + * @see opus_dred_create,opus_dred_init + */ +typedef struct OpusDRED OpusDRED; + /** Gets the size of an OpusDecoder structure. * @param [in] channels int: Number of channels. * This must be 1 or 2. @@ -511,6 +526,101 @@ OPUS_EXPORT int opus_decoder_ctl(OpusDecoder *st, int request, ...) OPUS_ARG_NON */ OPUS_EXPORT void opus_decoder_destroy(OpusDecoder *st); +/** Gets the size of an OpusDREDDecoder structure. + * @returns The size in bytes. + */ +OPUS_EXPORT int opus_dred_decoder_get_size(void); + +/** Allocates and initializes an OpusDREDDecoder state. + * @param [out] error int*: #OPUS_OK Success or @ref opus_errorcodes + */ +OPUS_EXPORT OpusDREDDecoder *opus_dred_decoder_create(int *error); + +/** Initializes an OpusDREDDecoder state. + * @param[in] dec OpusDREDDecoder*: State to be initialized. + */ +OPUS_EXPORT int opus_dred_decoder_init(OpusDREDDecoder *dec); + +/** Frees an OpusDREDDecoder allocated by opus_dred_decoder_create(). + * @param[in] dec OpusDREDDecoder*: State to be freed. + */ +OPUS_EXPORT void opus_dred_decoder_destroy(OpusDREDDecoder *dec); + +/** Perform a CTL function on an Opus DRED decoder. + * + * Generally the request and subsequent arguments are generated + * by a convenience macro. + * @param dred_dec OpusDREDDecoder*: DRED 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_dred_decoder_ctl(OpusDREDDecoder *dred_dec, int request, ...); + +/** Gets the size of an OpusDRED structure. + * @returns The size in bytes. + */ +OPUS_EXPORT int opus_dred_get_size(void); + +/** Allocates and initializes a DRED state. + * @param [out] error int*: #OPUS_OK Success or @ref opus_errorcodes + */ +OPUS_EXPORT OpusDRED *opus_dred_alloc(int *error); + +/** Frees an OpusDRED allocated by opus_dred_create(). + * @param[in] dec OpusDRED*: State to be freed. + */ +OPUS_EXPORT void opus_dred_free(OpusDRED *dec); + +/** Decode an Opus DRED packet. + * @param [in] dred_dec OpusDRED*: DRED Decoder state + * @param [in] dred OpusDRED*: DRED state + * @param [in] data char*: Input payload + * @param [in] len opus_int32: Number of bytes in payload + * @param [in] max_dred_samples opus_int32: Maximum number of DRED samples that may be needed (if available in the packet). + * @param [in] sampling_rate opus_int32: Sampling rate used for max_dred_samples argument. Needs not match the actual sampling rate of the decoder. + * @param [out] dred_end opus_int32*: Number of non-encoded (silence) samples between the DRED timestamp and the last DRED sample. + * @param [in] defer_processing int: Flag (0 or 1). If set to one, the CPU-intensive part of the DRED decoding is deferred until opus_dred_process() is called. + * @returns Offset (positive) of the first decoded DRED samples, zero if no DRED is present, or @ref opus_errorcodes + */ +OPUS_EXPORT int opus_dred_parse(OpusDREDDecoder *dred_dec, OpusDRED *dred, const unsigned char *data, opus_int32 len, opus_int32 max_dred_samples, opus_int32 sampling_rate, int *dred_end, int defer_processing) OPUS_ARG_NONNULL(1); + +/** Finish decoding an Opus DRED packet. The function only needs to be called if opus_dred_parse() was called with defer_processing=1. + * The source and destination will often be the same DRED state. + * @param [in] dred_dec OpusDRED*: DRED Decoder state + * @param [in] src OpusDRED*: Source DRED state to start the processing from. + * @param [out] dst OpusDRED*: Destination DRED state to store the updated state after processing. + * @returns @ref opus_errorcodes + */ +OPUS_EXPORT int opus_dred_process(OpusDREDDecoder *dred_dec, const OpusDRED *src, OpusDRED *dst); + +/** Decode audio from an Opus DRED packet with floating point output. + * @param [in] st OpusDecoder*: Decoder state + * @param [in] dred OpusDRED*: DRED state + * @param [in] dred_offset opus_int32: position of the redundancy to decode (in samples before the beginning of the real audio data in the packet). + * @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 to decode in \a pcm. + * frame_size must be a multiple of 2.5 ms. + * @returns Number of decoded samples or @ref opus_errorcodes + */ +OPUS_EXPORT int opus_decoder_dred_decode(OpusDecoder *st, const OpusDRED *dred, opus_int32 dred_offset, opus_int16 *pcm, opus_int32 frame_size); + +/** Decode audio from an Opus DRED packet with floating point output. + * @param [in] st OpusDecoder*: Decoder state + * @param [in] dred OpusDRED*: DRED state + * @param [in] dred_offset opus_int32: position of the redundancy to decode (in samples before the beginning of the real audio data in the packet). + * @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 to decode in \a pcm. + * frame_size must be a multiple of 2.5 ms. + * @returns Number of decoded samples or @ref opus_errorcodes + */ +OPUS_EXPORT int opus_decoder_dred_decode_float(OpusDecoder *st, const OpusDRED *dred, opus_int32 dred_offset, float *pcm, opus_int32 frame_size); + + /** 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. @@ -583,6 +693,14 @@ OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_packet_get_nb_frames(const unsigned */ 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); +/** Checks whether an Opus packet has LBRR. + * @param [in] packet char*: Opus packet + * @param [in] len opus_int32: Length of packet + * @returns 1 is LBRR is present, 0 otherwise + * @retval OPUS_INVALID_PACKET The compressed data passed is corrupted or of an unsupported type + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_packet_has_lbrr(const unsigned char packet[], opus_int32 len); + /** Gets the number of samples of an Opus packet. * @param [in] dec OpusDecoder*: Decoder state * @param [in] packet char*: Opus packet diff --git a/include/support/opus/opus_defines.h b/include/support/opus/opus_defines.h index d141418b2..cd8f4dde8 100644 --- a/include/support/opus/opus_defines.h +++ b/include/support/opus/opus_defines.h @@ -64,7 +64,7 @@ extern "C" { /**Export control for opus functions */ #ifndef OPUS_EXPORT -# if defined(WIN32) +# if defined(_WIN32) # if defined(OPUS_BUILD) && defined(DLL_EXPORT) # define OPUS_EXPORT __declspec(dllexport) # else @@ -169,15 +169,32 @@ extern "C" { #define OPUS_SET_PHASE_INVERSION_DISABLED_REQUEST 4046 #define OPUS_GET_PHASE_INVERSION_DISABLED_REQUEST 4047 #define OPUS_GET_IN_DTX_REQUEST 4049 +#define OPUS_SET_DRED_DURATION_REQUEST 4050 +#define OPUS_GET_DRED_DURATION_REQUEST 4051 +#define OPUS_SET_DNN_BLOB_REQUEST 4052 +/*#define OPUS_GET_DNN_BLOB_REQUEST 4053 */ /** Defines for the presence of extended APIs. */ #define OPUS_HAVE_OPUS_PROJECTION_H /* 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)) + +#ifdef DISABLE_PTR_CHECK +/* Disable checks to prevent ubsan from complaining about NULL checks + in test_opus_api. */ +#define __opus_check_int_ptr(ptr) (ptr) +#define __opus_check_uint_ptr(ptr) (ptr) +#define __opus_check_uint8_ptr(ptr) (ptr) +#define __opus_check_val16_ptr(ptr) (ptr) +#define __opus_check_void_ptr(ptr) (ptr) +#else #define __opus_check_int_ptr(ptr) ((ptr) + ((ptr) - (opus_int32*)(ptr))) #define __opus_check_uint_ptr(ptr) ((ptr) + ((ptr) - (opus_uint32*)(ptr))) +#define __opus_check_uint8_ptr(ptr) ((ptr) + ((ptr) - (opus_uint8*)(ptr))) #define __opus_check_val16_ptr(ptr) ((ptr) + ((ptr) - (opus_val16*)(ptr))) +#define __opus_check_void_ptr(x) ((void)((void *)0 == (x)), (x)) +#endif /** @endcond */ /** @defgroup opus_ctlvalues Pre-defined values for CTL interface @@ -482,7 +499,8 @@ extern "C" { * @param[in] x opus_int32: Allowed values: *
*
0
Disable inband FEC (default).
- *
1
Enable inband FEC.
+ *
1
Inband FEC enabled. If the packet loss rate is sufficiently high, Opus will automatically switch to SILK even at high rates to enable use of that FEC.
+ *
2
Inband FEC enabled, but does not necessarily switch to SILK if we have music.
*
* @hideinitializer */ #define OPUS_SET_INBAND_FEC(x) OPUS_SET_INBAND_FEC_REQUEST, __opus_check_int(x) @@ -491,7 +509,8 @@ extern "C" { * @param[out] x opus_int32 *: Returns one of the following values: *
*
0
Inband FEC disabled (default).
- *
1
Inband FEC enabled.
+ *
1
Inband FEC enabled. If the packet loss rate is sufficiently high, Opus will automatically switch to SILK even at high rates to enable use of that FEC.
+ *
2
Inband FEC enabled, but does not necessarily switch to SILK if we have music.
*
* @hideinitializer */ #define OPUS_GET_INBAND_FEC(x) OPUS_GET_INBAND_FEC_REQUEST, __opus_check_int_ptr(x) @@ -618,6 +637,18 @@ extern "C" { * @hideinitializer */ #define OPUS_GET_PREDICTION_DISABLED(x) OPUS_GET_PREDICTION_DISABLED_REQUEST, __opus_check_int_ptr(x) +/** If non-zero, enables Deep Redundancy (DRED) and use the specified maximum number of 10-ms redundant frames + * @hideinitializer */ +#define OPUS_SET_DRED_DURATION(x) OPUS_SET_DRED_DURATION_REQUEST, __opus_check_int(x) +/** Gets the encoder's configured Deep Redundancy (DRED) maximum number of frames. + * @hideinitializer */ +#define OPUS_GET_DRED_DURATION(x) OPUS_GET_DRED_DURATION_REQUEST, __opus_check_int_ptr(x) + +/** Provide external DNN weights from binary object (only when explicitly built without the weights) + * @hideinitializer */ +#define OPUS_SET_DNN_BLOB(data, len) OPUS_SET_DNN_BLOB_REQUEST, __opus_check_void_ptr(data), __opus_check_int(len) + + /**@}*/ /** @defgroup opus_genericctls Generic CTLs diff --git a/include/support/opus/opus_multistream.h b/include/support/opus/opus_multistream.h index babcee690..824cc55ac 100644 --- a/include/support/opus/opus_multistream.h +++ b/include/support/opus/opus_multistream.h @@ -143,7 +143,7 @@ extern "C" { * 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). + * order (e.g. for outputting 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