diff --git a/opus_flutter_ios/CHANGELOG.md b/opus_flutter_ios/CHANGELOG.md index 6a897af..3760b77 100644 --- a/opus_flutter_ios/CHANGELOG.md +++ b/opus_flutter_ios/CHANGELOG.md @@ -1,3 +1,11 @@ +## 3.0.2 + +* Rebuild `opus.xcframework` with an arm64 simulator slice, fixing + `Framework 'opus' not found` when building for the iOS simulator on Apple Silicon +* Build every slice from opus 1.5.2, so device and simulator run the same codec version +* Add `tool/build_opus_xcframework.sh`, which reproduces the framework from source + + ## 3.0.1 * Using new opus.xcframework diff --git a/opus_flutter_ios/README.md b/opus_flutter_ios/README.md index 758f6d2..9a7727c 100644 --- a/opus_flutter_ios/README.md +++ b/opus_flutter_ios/README.md @@ -32,7 +32,21 @@ dependencies: ``` ## How opus is contained in this package -[opus_xcframework](https://github.com/EPNW/opus_xcframework) is incorporated into this plugin. +An `opus.xcframework` is incorporated into this plugin, in the spirit of +[opus_xcframework](https://github.com/EPNW/opus_xcframework). + +It carries three architectures: + +| Slice | Used for | +| --- | --- | +| `ios-arm64` | devices | +| `ios-arm64_x86_64-simulator` | simulators, on Apple Silicon and Intel hosts | + +To reproduce it from an official opus release, run: + +```bash +./tool/build_opus_xcframework.sh +``` [1]: ../opus_flutter diff --git a/opus_flutter_ios/ios/opus.xcframework/Info.plist b/opus_flutter_ios/ios/opus.xcframework/Info.plist index 67bf2e3..0e80bcb 100644 --- a/opus_flutter_ios/ios/opus.xcframework/Info.plist +++ b/opus_flutter_ios/ios/opus.xcframework/Info.plist @@ -8,31 +8,32 @@ BinaryPath opus.framework/opus LibraryIdentifier - ios-x86_64-simulator + ios-arm64 LibraryPath opus.framework SupportedArchitectures - x86_64 + arm64 SupportedPlatform ios - SupportedPlatformVariant - simulator BinaryPath opus.framework/opus LibraryIdentifier - ios-arm64 + ios-arm64_x86_64-simulator LibraryPath opus.framework SupportedArchitectures arm64 + x86_64 SupportedPlatform ios + SupportedPlatformVariant + simulator CFBundlePackageType diff --git a/opus_flutter_ios/ios/opus.xcframework/ios-arm64/opus.framework/Headers/opus.h b/opus_flutter_ios/ios/opus.xcframework/ios-arm64/opus.framework/Headers/opus.h index d282f21..eadeda7 100644 --- a/opus_flutter_ios/ios/opus.xcframework/ios-arm64/opus.framework/Headers/opus.h +++ b/opus_flutter_ios/ios/opus.xcframework/ios-arm64/opus.framework/Headers/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/opus_flutter_ios/ios/opus.xcframework/ios-arm64/opus.framework/Headers/opus_defines.h b/opus_flutter_ios/ios/opus.xcframework/ios-arm64/opus.framework/Headers/opus_defines.h index d141418..cd8f4dd 100644 --- a/opus_flutter_ios/ios/opus.xcframework/ios-arm64/opus.framework/Headers/opus_defines.h +++ b/opus_flutter_ios/ios/opus.xcframework/ios-arm64/opus.framework/Headers/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/opus_flutter_ios/ios/opus.xcframework/ios-arm64/opus.framework/Headers/opus_multistream.h b/opus_flutter_ios/ios/opus.xcframework/ios-arm64/opus.framework/Headers/opus_multistream.h index babcee6..824cc55 100644 --- a/opus_flutter_ios/ios/opus.xcframework/ios-arm64/opus.framework/Headers/opus_multistream.h +++ b/opus_flutter_ios/ios/opus.xcframework/ios-arm64/opus.framework/Headers/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 diff --git a/opus_flutter_ios/ios/opus.xcframework/ios-arm64/opus.framework/Info.plist b/opus_flutter_ios/ios/opus.xcframework/ios-arm64/opus.framework/Info.plist index 312bea7..6ac84d7 100644 Binary files a/opus_flutter_ios/ios/opus.xcframework/ios-arm64/opus.framework/Info.plist and b/opus_flutter_ios/ios/opus.xcframework/ios-arm64/opus.framework/Info.plist differ diff --git a/opus_flutter_ios/ios/opus.xcframework/ios-arm64/opus.framework/opus b/opus_flutter_ios/ios/opus.xcframework/ios-arm64/opus.framework/opus index 75c7747..92a03fb 100755 Binary files a/opus_flutter_ios/ios/opus.xcframework/ios-arm64/opus.framework/opus and b/opus_flutter_ios/ios/opus.xcframework/ios-arm64/opus.framework/opus differ diff --git a/opus_flutter_ios/ios/opus.xcframework/ios-x86_64-simulator/opus.framework/Headers/opus.h b/opus_flutter_ios/ios/opus.xcframework/ios-arm64_x86_64-simulator/opus.framework/Headers/opus.h similarity index 88% rename from opus_flutter_ios/ios/opus.xcframework/ios-x86_64-simulator/opus.framework/Headers/opus.h rename to opus_flutter_ios/ios/opus.xcframework/ios-arm64_x86_64-simulator/opus.framework/Headers/opus.h index d282f21..eadeda7 100644 --- a/opus_flutter_ios/ios/opus.xcframework/ios-x86_64-simulator/opus.framework/Headers/opus.h +++ b/opus_flutter_ios/ios/opus.xcframework/ios-arm64_x86_64-simulator/opus.framework/Headers/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/opus_flutter_ios/ios/opus.xcframework/ios-x86_64-simulator/opus.framework/Headers/opus_defines.h b/opus_flutter_ios/ios/opus.xcframework/ios-arm64_x86_64-simulator/opus.framework/Headers/opus_defines.h similarity index 94% rename from opus_flutter_ios/ios/opus.xcframework/ios-x86_64-simulator/opus.framework/Headers/opus_defines.h rename to opus_flutter_ios/ios/opus.xcframework/ios-arm64_x86_64-simulator/opus.framework/Headers/opus_defines.h index d141418..cd8f4dd 100644 --- a/opus_flutter_ios/ios/opus.xcframework/ios-x86_64-simulator/opus.framework/Headers/opus_defines.h +++ b/opus_flutter_ios/ios/opus.xcframework/ios-arm64_x86_64-simulator/opus.framework/Headers/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/opus_flutter_ios/ios/opus.xcframework/ios-x86_64-simulator/opus.framework/Headers/opus_multistream.h b/opus_flutter_ios/ios/opus.xcframework/ios-arm64_x86_64-simulator/opus.framework/Headers/opus_multistream.h similarity index 99% rename from opus_flutter_ios/ios/opus.xcframework/ios-x86_64-simulator/opus.framework/Headers/opus_multistream.h rename to opus_flutter_ios/ios/opus.xcframework/ios-arm64_x86_64-simulator/opus.framework/Headers/opus_multistream.h index babcee6..824cc55 100644 --- a/opus_flutter_ios/ios/opus.xcframework/ios-x86_64-simulator/opus.framework/Headers/opus_multistream.h +++ b/opus_flutter_ios/ios/opus.xcframework/ios-arm64_x86_64-simulator/opus.framework/Headers/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 diff --git a/opus_flutter_ios/ios/opus.xcframework/ios-x86_64-simulator/opus.framework/Headers/opus_types.h b/opus_flutter_ios/ios/opus.xcframework/ios-arm64_x86_64-simulator/opus.framework/Headers/opus_types.h similarity index 100% rename from opus_flutter_ios/ios/opus.xcframework/ios-x86_64-simulator/opus.framework/Headers/opus_types.h rename to opus_flutter_ios/ios/opus.xcframework/ios-arm64_x86_64-simulator/opus.framework/Headers/opus_types.h diff --git a/opus_flutter_ios/ios/opus.xcframework/ios-arm64_x86_64-simulator/opus.framework/Info.plist b/opus_flutter_ios/ios/opus.xcframework/ios-arm64_x86_64-simulator/opus.framework/Info.plist new file mode 100644 index 0000000..1cb5fb2 --- /dev/null +++ b/opus_flutter_ios/ios/opus.xcframework/ios-arm64_x86_64-simulator/opus.framework/Info.plist @@ -0,0 +1,17 @@ + + + + + CFBundleDevelopmentRegionen + CFBundleExecutableopus + CFBundleIdentifierorg.opus-codec.org + CFBundleInfoDictionaryVersion6.0 + CFBundleNameopus + CFBundlePackageTypeFMWK + CFBundleShortVersionString1.5.2 + CFBundleVersion1 + CFBundleSupportedPlatformsiPhoneSimulator + MinimumOSVersion13.0 + UIDeviceFamily12 + + diff --git a/opus_flutter_ios/ios/opus.xcframework/ios-x86_64-simulator/opus.framework/Modules/module.modulemap b/opus_flutter_ios/ios/opus.xcframework/ios-arm64_x86_64-simulator/opus.framework/Modules/module.modulemap similarity index 100% rename from opus_flutter_ios/ios/opus.xcframework/ios-x86_64-simulator/opus.framework/Modules/module.modulemap rename to opus_flutter_ios/ios/opus.xcframework/ios-arm64_x86_64-simulator/opus.framework/Modules/module.modulemap diff --git a/opus_flutter_ios/ios/opus.xcframework/ios-arm64_x86_64-simulator/opus.framework/opus b/opus_flutter_ios/ios/opus.xcframework/ios-arm64_x86_64-simulator/opus.framework/opus new file mode 100755 index 0000000..9125c0f Binary files /dev/null and b/opus_flutter_ios/ios/opus.xcframework/ios-arm64_x86_64-simulator/opus.framework/opus differ diff --git a/opus_flutter_ios/ios/opus.xcframework/ios-x86_64-simulator/opus.framework/Info.plist b/opus_flutter_ios/ios/opus.xcframework/ios-x86_64-simulator/opus.framework/Info.plist deleted file mode 100644 index 312bea7..0000000 Binary files a/opus_flutter_ios/ios/opus.xcframework/ios-x86_64-simulator/opus.framework/Info.plist and /dev/null differ diff --git a/opus_flutter_ios/ios/opus.xcframework/ios-x86_64-simulator/opus.framework/opus b/opus_flutter_ios/ios/opus.xcframework/ios-x86_64-simulator/opus.framework/opus deleted file mode 100755 index e1b1e5b..0000000 Binary files a/opus_flutter_ios/ios/opus.xcframework/ios-x86_64-simulator/opus.framework/opus and /dev/null differ diff --git a/opus_flutter_ios/pubspec.yaml b/opus_flutter_ios/pubspec.yaml index 07addbc..3599424 100644 --- a/opus_flutter_ios/pubspec.yaml +++ b/opus_flutter_ios/pubspec.yaml @@ -1,7 +1,7 @@ name: opus_flutter_ios description: iOS implementation of the opus_flutter plugin. repository: https://github.com/EPNW/opus_flutter/tree/master/opus_flutter_ios -version: 3.0.1 +version: 3.0.2 environment: sdk: ">=2.12.0 <3.0.0" diff --git a/opus_flutter_ios/tool/build_opus_xcframework.sh b/opus_flutter_ios/tool/build_opus_xcframework.sh new file mode 100755 index 0000000..1eed77c --- /dev/null +++ b/opus_flutter_ios/tool/build_opus_xcframework.sh @@ -0,0 +1,124 @@ +#!/usr/bin/env bash +# +# Rebuilds ios/opus.xcframework from an official opus release. +# +# The framework it produces carries three architectures: +# +# ios-arm64 device +# ios-arm64_x86_64-simulator simulator, Apple Silicon and Intel hosts +# +# The arm64 simulator architecture is the reason this script exists. Without it the +# link step on an Apple Silicon Mac fails with "Framework 'opus' not found", because +# no slice matches the arm64-ios-simulator target. +# +# Usage: +# ./tool/build_opus_xcframework.sh [opus-version] +# +# Requirements: Xcode command line tools, CMake, curl. + +set -euo pipefail + +OPUS_VER="${1:-1.5.2}" +MIN_IOS="13.0" +BUNDLE_ID="org.opus-codec.org" + +HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +OUT_XCFW="$HERE/../ios/opus.xcframework" +WORK="$(mktemp -d)" +trap 'rm -rf "$WORK"' EXIT + +echo "Building opus ${OPUS_VER} for iOS" + +curl -fsSL "https://downloads.xiph.org/releases/opus/opus-${OPUS_VER}.tar.gz" \ + | tar xz -C "$WORK" +SRC="$WORK/opus-${OPUS_VER}" + +# The autotools configure script cannot cross-configure for the simulator triple, +# so the CMake build is used for both platforms. +build_static() { + local name="$1" sysroot="$2" archs="$3" + cmake -S "$SRC" -B "$WORK/build-$name" -G Xcode \ + -DCMAKE_SYSTEM_NAME=iOS \ + -DCMAKE_OSX_SYSROOT="$sysroot" \ + -DCMAKE_OSX_ARCHITECTURES="$archs" \ + -DCMAKE_OSX_DEPLOYMENT_TARGET="$MIN_IOS" \ + -DBUILD_SHARED_LIBS=OFF \ + -DOPUS_BUILD_PROGRAMS=OFF \ + -DOPUS_BUILD_TESTING=OFF >/dev/null + cmake --build "$WORK/build-$name" --config Release -- \ + -quiet CODE_SIGNING_ALLOWED=NO >/dev/null +} + +# opus builds as a static library. It is relinked as a dynamic library here because +# the framework is consumed as a dynamic framework by the CocoaPods integration. +link_dylib() { + local name="$1" sdk="$2" triple_suffix="$3" arch="$4" + xcrun -sdk "$sdk" clang -dynamiclib \ + -target "${arch}-apple-ios${MIN_IOS}${triple_suffix}" \ + -isysroot "$(xcrun --sdk "$sdk" --show-sdk-path)" \ + -install_name "@rpath/opus.framework/opus" \ + -compatibility_version 1.0.0 -current_version 1.0.0 \ + -Wl,-all_load \ + "$WORK/build-$name/Release-${sdk}/libopus.a" \ + -o "$WORK/$name-$arch.dylib" +} + +write_plist() { + local plist="$1" platform="$2" + cat > "$plist" < + + + + CFBundleDevelopmentRegionen + CFBundleExecutableopus + CFBundleIdentifier${BUNDLE_ID} + CFBundleInfoDictionaryVersion6.0 + CFBundleNameopus + CFBundlePackageTypeFMWK + CFBundleShortVersionString${OPUS_VER} + CFBundleVersion1 + CFBundleSupportedPlatforms${platform} + MinimumOSVersion${MIN_IOS} + UIDeviceFamily12 + + +PLIST +} + +assemble_framework() { + local dest="$1" binary="$2" platform="$3" + mkdir -p "$dest/Headers" "$dest/Modules" + cp "$SRC"/include/opus.h "$SRC"/include/opus_defines.h \ + "$SRC"/include/opus_multistream.h "$SRC"/include/opus_types.h "$dest/Headers/" + cat > "$dest/Modules/module.modulemap" <<'MODMAP' +framework module opus { + umbrella header "opus.h" + export * + + module * { export * } +} +MODMAP + cp "$binary" "$dest/opus" + write_plist "$dest/Info.plist" "$platform" +} + +build_static device iphoneos "arm64" +build_static sim iphonesimulator "arm64;x86_64" + +link_dylib device iphoneos "" arm64 +link_dylib sim iphonesimulator "-simulator" arm64 +link_dylib sim iphonesimulator "-simulator" x86_64 +lipo -create "$WORK/sim-arm64.dylib" "$WORK/sim-x86_64.dylib" -output "$WORK/sim.dylib" + +assemble_framework "$WORK/fw-device/opus.framework" "$WORK/device-arm64.dylib" iPhoneOS +assemble_framework "$WORK/fw-sim/opus.framework" "$WORK/sim.dylib" iPhoneSimulator + +rm -rf "$OUT_XCFW" +xcodebuild -create-xcframework \ + -framework "$WORK/fw-device/opus.framework" \ + -framework "$WORK/fw-sim/opus.framework" \ + -output "$OUT_XCFW" >/dev/null + +echo "Wrote $OUT_XCFW" +plutil -p "$OUT_XCFW/Info.plist" | grep LibraryIdentifier