From 4d696a3b39ec9f8752524c9a0286af4f6a55cbcd Mon Sep 17 00:00:00 2001 From: SineVector241 Date: Sun, 29 Mar 2026 13:18:16 +1100 Subject: [PATCH 1/9] add basic asmdef file. This needs to be copied in a unity project when needed. --- OpusSharp.asmdef | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 OpusSharp.asmdef diff --git a/OpusSharp.asmdef b/OpusSharp.asmdef new file mode 100644 index 0000000..134155c --- /dev/null +++ b/OpusSharp.asmdef @@ -0,0 +1,14 @@ +{ + "name": "OpusSharp", + "rootNamespace": "", + "references": [], + "includePlatforms": [], + "excludePlatforms": [], + "allowUnsafeCode": true, + "overrideReferences": false, + "precompiledReferences": [], + "autoReferenced": true, + "defineConstraints": [], + "versionDefines": [], + "noEngineReferences": false +} \ No newline at end of file From f99f01b89f241dc493e4cc750d9b3eb7101e02ab Mon Sep 17 00:00:00 2001 From: SineVector241 Date: Sun, 29 Mar 2026 13:27:29 +1100 Subject: [PATCH 2/9] Update Docs for unity integration. --- docs/quick-start/index.md | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/docs/quick-start/index.md b/docs/quick-start/index.md index e2b1385..f61f749 100644 --- a/docs/quick-start/index.md +++ b/docs/quick-start/index.md @@ -60,6 +60,27 @@ byte[] decodedSamples = decoder.Decode(encoded, encoded.Length, decoded, 960, fa Console.WriteLine(decodedSamples); ``` +### Unity + +For unity integration, you may want to use `Static.OpusDecoder`, `Dynamic.OpusDecoder`, `Static.OpusEncoder` or +`Dynamic.OpusEncoder` to prevent IL2CPP errors for example... + +```csharp +using OpusSharp.Core; + +IOpusEncoder encoder; +IOpusDecoder decoder; +//Decoder +#if UNITY_IOS && !UNITY_EDITOR +encoder = new Static.OpusEncoder(...); +decoder = new Static.OpusDecoder(...); +#else +encoder = new Dynamic.OpusEncoder(...); +decoder = new Dynamic.OpusDecoder(...); +``` + +You can also copy the basic [OpusSharp.asmdef](https://github.com/AvionBlock/OpusSharp/blob/master/OpusSharp.asmdef) when you import OpusSharp as a package. + # Next Steps 📖 [Read the API for more information about the library](xref:OpusSharp.Core) From 92b88a516a7f1a0ff1c9c09920841e2dab25423e Mon Sep 17 00:00:00 2001 From: SineVector241 Date: Sun, 29 Mar 2026 13:37:11 +1100 Subject: [PATCH 3/9] Update README.md with unity example. --- README.md | 67 ++++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 54 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 6ca658b..22a1739 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,19 @@ # OpusSharp -OpusSharp aims to be a cross-platform, pure and ported C# compatible version of the native opus codec/library. The core library uses the native compiled DLL's/binaries. Windows, Android, Linux, macOS and iOS are supported. OpusSharp compiles the opus binaries using a github actions file which is available [here](.github/workflows/OpusCompile.yml). +OpusSharp aims to be a cross-platform, pure and ported C# compatible version of the native opus codec/library. The core +library uses the native compiled DLL's/binaries. Windows, Android, Linux, macOS and iOS are supported. OpusSharp +compiles the opus binaries using a github actions file which is available [here](.github/workflows/OpusCompile.yml). > [!NOTE] -> While OpusSharp.Core contains minimal pre-made decoder and encoder handlers, you can create your own as all the SafeHandlers and NativeOpus functions are exposed and fully documented. However to get a minimal setup working, check the example below. +> While OpusSharp.Core contains minimal pre-made decoder and encoder handlers, you can create your own as all the +> SafeHandlers and NativeOpus functions are exposed and fully documented. However to get a minimal setup working, check +> the example below. ## Encoder Example +Simple encoder example for initializing and encoding. You of course can use `short[]` or `float[]` arrays to encode as +well. + ```cs using OpusSharp.Core; @@ -25,6 +32,9 @@ var encodedBytes = encoder.Encode(someAudioData, samplesPerFrame, encodedAudio, ## Decoder Example +Simple decoder example for initializing and decoding. You of course can use `short[]` or `float[]` arrays to encode as +well. + ```cs using OpusSharp.Core; @@ -41,6 +51,8 @@ var decodedSamples = decoder.Decode(someEncodedAudio, someEncodedAudio.Length, d ## Static Usage Example +This example shows a forced usage of OpusSharp to use the statically linked opus binary. + ```csharp // On iOS OpusSharp switches to StaticNativeOpus automatically. // You can still force the same behavior manually with use_static: true. @@ -48,6 +60,25 @@ var encoder = new OpusEncoder(sampleRate, channels, OpusPredefinedValues.OPUS_AP var encoder = new OpusDecoder(sampleRate, channels, use_static: true); ``` +### Unity Example + +For unity integration, you may want to use `Static.OpusDecoder`, `Dynamic.OpusDecoder`, `Static.OpusEncoder` or +`Dynamic.OpusEncoder` to prevent IL2CPP errors for example... + +```csharp +using OpusSharp.Core; + +IOpusEncoder encoder; +IOpusDecoder decoder; +//Decoder +#if UNITY_IOS && !UNITY_EDITOR +encoder = new Static.OpusEncoder(...); +decoder = new Static.OpusDecoder(...); +#else +encoder = new Dynamic.OpusEncoder(...); +decoder = new Dynamic.OpusDecoder(...); +``` + ## Basic NAudio Example ```cs @@ -82,6 +113,8 @@ Console.ReadLine(); ## CTL Example using OpusSharp.Core.Extensions +This CTL example shows the usage of extensions to make setting CTL's easier. + ```csharp using OpusSharp.Core; using OpusSharp.Core.Extensions; @@ -94,6 +127,9 @@ Console.WriteLine(encoder.GetComplexity()); ## CTL Example +This example shows the raw usage of calling a CTL with no extensions, OpusSharp will directly pass the call to the opus +binary. + ```cs using OpusSharp.Core; @@ -106,7 +142,10 @@ encoder.Ctl(EncoderCTL.OPUS_SET_VBR, 1); //OpusSharp already checks if an e ``` > [!NOTE] -> While disposing of encoder's and decoder's are handled by the GC (garbage collector) since unmanaged states are wrapped in a SafeHandler, It is still recommended to directly call the Dispose() function due to different runtime environments such as unity's mono runtime (at the time of writing this) which can take an impact on performance depending on how many is initialized and dereferenced over time. +> While disposing of encoder's and decoder's are handled by the GC (garbage collector) since unmanaged states are +> wrapped in a SafeHandler, It is still recommended to directly call the Dispose() function due to different runtime +> environments such as unity's mono runtime (at the time of writing this) which can take an impact on performance +> depending on how many is initialized and dereferenced over time. ## Supported Devices @@ -116,20 +155,22 @@ encoder.Ctl(EncoderCTL.OPUS_SET_VBR, 1); //OpusSharp already checks if an e - ❌ Not planned, Not supported. | Device | x64 | x86 | arm32 | arm64 | -| ------- | --- | --- | ----- | ----- | -| Linux | ✅ | ✅ | ✅ | ✅ | -| Android | ✅ | ✅ | ✅ | ✅ | -| Windows | ✅ | ✅ | ✅ | ✅ | -| iOS | ❌ | ❌ | ❌ | ✅ | -| MacOS | ✅ | ❌ | ❌ | ✅ | -| WASM | ✅ | ❗ | ❗ | ❗ | +|---------|-----|-----|-------|-------| +| Linux | ✅ | ✅ | ✅ | ✅ | +| Android | ✅ | ✅ | ✅ | ✅ | +| Windows | ✅ | ✅ | ✅ | ✅ | +| iOS | ❌ | ❌ | ❌ | ✅ | +| MacOS | ✅ | ❌ | ❌ | ✅ | +| WASM | ✅ | ❗ | ❗ | ❗ | ## Installation -Please check [QuickStart](https://avionblock.github.io/OpusSharp/quick-start/index.html) OR [Nuget](https://www.nuget.org/packages/OpusSharp) -For the default cross-platform experience, install [OpusSharp](https://www.nuget.org/packages/OpusSharp). It brings in both `OpusSharp.Core` and the prebuilt native assets, including automatic iOS linking through `OpusSharp.Natives`. +Please check [QuickStart](https://avionblock.github.io/OpusSharp/quick-start/index.html) +OR [Nuget](https://www.nuget.org/packages/OpusSharp). +For the default cross-platform experience, install [OpusSharp](https://www.nuget.org/packages/OpusSharp). It brings in +both `OpusSharp.Core` and the prebuilt native assets, including automatic iOS linking through `OpusSharp.Natives`. -If you want to manage native binaries yourself, install only `OpusSharp.Core`. +If you want to manage native binaries yourself, only install the `OpusSharp.Core` package. ## API Documentation From 8649ce2202493f0b5dac8865133508d8b7831a39 Mon Sep 17 00:00:00 2001 From: SineVector241 Date: Sun, 29 Mar 2026 13:38:04 +1100 Subject: [PATCH 4/9] H3 mistake. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 22a1739..efae595 100644 --- a/README.md +++ b/README.md @@ -60,7 +60,7 @@ var encoder = new OpusEncoder(sampleRate, channels, OpusPredefinedValues.OPUS_AP var encoder = new OpusDecoder(sampleRate, channels, use_static: true); ``` -### Unity Example +## Unity Example For unity integration, you may want to use `Static.OpusDecoder`, `Dynamic.OpusDecoder`, `Static.OpusEncoder` or `Dynamic.OpusEncoder` to prevent IL2CPP errors for example... From d63f4421ca6908ece9eec0514b4ea563675a6537 Mon Sep 17 00:00:00 2001 From: SineVector241 Date: Sun, 29 Mar 2026 13:51:27 +1100 Subject: [PATCH 5/9] Update extensions to support the interfaces. --- .../Extensions/OpusDecoderExtensions.cs | 29 +++---- .../Extensions/OpusEncoderExtensions.cs | 79 ++++++++++--------- 2 files changed, 55 insertions(+), 53 deletions(-) diff --git a/OpusSharp.Core/Extensions/OpusDecoderExtensions.cs b/OpusSharp.Core/Extensions/OpusDecoderExtensions.cs index 2ecfd4d..4c6107c 100644 --- a/OpusSharp.Core/Extensions/OpusDecoderExtensions.cs +++ b/OpusSharp.Core/Extensions/OpusDecoderExtensions.cs @@ -1,4 +1,5 @@ using System; +using OpusSharp.Core.Interfaces; namespace OpusSharp.Core.Extensions { @@ -15,7 +16,7 @@ public static class OpusDecoderExtensions /// The gain to set. /// /// - public static void SetGain(this OpusDecoder decoder, short gain) + public static void SetGain(this IOpusDecoder decoder, short gain) { decoder.Ctl(DecoderCTL.OPUS_SET_GAIN, gain); } @@ -27,7 +28,7 @@ public static void SetGain(this OpusDecoder decoder, short gain) /// The gain for the opus decoder. /// /// - public static int GetGain(this OpusDecoder decoder) + public static int GetGain(this IOpusDecoder decoder) { var gain = 0; decoder.Ctl(DecoderCTL.OPUS_GET_GAIN, ref gain); @@ -41,7 +42,7 @@ public static int GetGain(this OpusDecoder decoder) /// The last packet duration (in samples). /// /// - public static int GetLastPacketDuration(this OpusDecoder decoder) + public static int GetLastPacketDuration(this IOpusDecoder decoder) { var lastPacketDuration = 0; decoder.Ctl(DecoderCTL.OPUS_GET_LAST_PACKET_DURATION, ref lastPacketDuration); @@ -55,7 +56,7 @@ public static int GetLastPacketDuration(this OpusDecoder decoder) /// The pitch of the last decoded frame if available. /// /// - public static int GetPitch(this OpusDecoder decoder) + public static int GetPitch(this IOpusDecoder decoder) { var pitch = 0; decoder.Ctl(DecoderCTL.OPUS_GET_PITCH, ref pitch); @@ -69,7 +70,7 @@ public static int GetPitch(this OpusDecoder decoder) /// Whether to enable or disable the OSCE BWE module. /// /// - public static void SetOsceBwe(this OpusDecoder decoder, bool enabled) + public static void SetOsceBwe(this IOpusDecoder decoder, bool enabled) { decoder.Ctl(DecoderCTL.OPUS_SET_OSCE_BWE, enabled ? 1 : 0); } @@ -81,7 +82,7 @@ public static void SetOsceBwe(this OpusDecoder decoder, bool enabled) /// Whether the OSCE BWE module is enabled or not. /// /// - public static bool GetOsceBwe(this OpusDecoder decoder) + public static bool GetOsceBwe(this IOpusDecoder decoder) { var value = 0; decoder.Ctl(DecoderCTL.OPUS_GET_OSCE_BWE, ref value); @@ -95,7 +96,7 @@ public static bool GetOsceBwe(this OpusDecoder decoder) /// Whether to disable all found extensions in the padding area. /// /// - public static void SetIgnoreExtensions(this OpusDecoder decoder, bool disabled) + public static void SetIgnoreExtensions(this IOpusDecoder decoder, bool disabled) { decoder.Ctl(DecoderCTL.OPUS_SET_IGNORE_EXTENSIONS, disabled ? 1 : 0); } @@ -107,7 +108,7 @@ public static void SetIgnoreExtensions(this OpusDecoder decoder, bool disabled) /// Whether the decoder is ignoring extensions. /// /// - public static bool GetIgnoreExtensions(this OpusDecoder decoder) + public static bool GetIgnoreExtensions(this IOpusDecoder decoder) { var value = 0; decoder.Ctl(DecoderCTL.OPUS_GET_IGNORE_EXTENSIONS, ref value); @@ -120,7 +121,7 @@ public static bool GetIgnoreExtensions(this OpusDecoder decoder) /// The decoder state. /// /// - public static void Reset(this OpusDecoder decoder) + public static void Reset(this IOpusDecoder decoder) { decoder.Ctl(GenericCTL.OPUS_RESET_STATE); } @@ -132,7 +133,7 @@ public static void Reset(this OpusDecoder decoder) /// The final state of the codec's entropy coder. /// /// - public static uint GetFinalRange(this OpusDecoder decoder) + public static uint GetFinalRange(this IOpusDecoder decoder) { var finalRange = 0u; decoder.Ctl(GenericCTL.OPUS_GET_FINAL_RANGE, ref finalRange); @@ -146,7 +147,7 @@ public static uint GetFinalRange(this OpusDecoder decoder) /// The decoder's last bandpass. /// /// - public static OpusPredefinedValues GetBandwidth(this OpusDecoder decoder) + public static OpusPredefinedValues GetBandwidth(this IOpusDecoder decoder) { var bandPass = 0; decoder.Ctl(GenericCTL.OPUS_GET_BANDWIDTH, ref bandPass); @@ -160,7 +161,7 @@ public static OpusPredefinedValues GetBandwidth(this OpusDecoder decoder) /// The decoder's configured sample rate. /// /// - public static int GetSampleRate(this OpusDecoder decoder) + public static int GetSampleRate(this IOpusDecoder decoder) { var sampleRate = 0; decoder.Ctl(GenericCTL.OPUS_GET_SAMPLE_RATE, ref sampleRate); @@ -174,7 +175,7 @@ public static int GetSampleRate(this OpusDecoder decoder) /// Whether to disable or not. /// /// - public static void SetPhaseInversionDisabled(this OpusDecoder decoder, bool disabled) + public static void SetPhaseInversionDisabled(this IOpusDecoder decoder, bool disabled) { decoder.Ctl(GenericCTL.OPUS_SET_PHASE_INVERSION_DISABLED, disabled ? 1 : 0); } @@ -186,7 +187,7 @@ public static void SetPhaseInversionDisabled(this OpusDecoder decoder, bool disa /// Whether the phase inversion is disabled or not. /// /// - public static bool GetPhaseInversionDisabled(this OpusDecoder decoder) + public static bool GetPhaseInversionDisabled(this IOpusDecoder decoder) { var disabled = 0; decoder.Ctl(GenericCTL.OPUS_GET_PHASE_INVERSION_DISABLED, ref disabled); diff --git a/OpusSharp.Core/Extensions/OpusEncoderExtensions.cs b/OpusSharp.Core/Extensions/OpusEncoderExtensions.cs index 377908c..8a9d34b 100644 --- a/OpusSharp.Core/Extensions/OpusEncoderExtensions.cs +++ b/OpusSharp.Core/Extensions/OpusEncoderExtensions.cs @@ -1,4 +1,5 @@ using System; +using OpusSharp.Core.Interfaces; namespace OpusSharp.Core.Extensions { @@ -14,7 +15,7 @@ public static class OpusEncoderExtensions /// The application to set. Must be one of , or . /// /// - public static void SetApplication(this OpusEncoder encoder, OpusPredefinedValues application) + public static void SetApplication(this IOpusEncoder encoder, OpusPredefinedValues application) { encoder.Ctl(EncoderCTL.OPUS_SET_APPLICATION, (int)application); } @@ -26,7 +27,7 @@ public static void SetApplication(this OpusEncoder encoder, OpusPredefinedValues /// The encoder's configured application. /// /// - public static OpusPredefinedValues GetApplication(this OpusEncoder encoder) + public static OpusPredefinedValues GetApplication(this IOpusEncoder encoder) { var value = (int)OpusPredefinedValues.OPUS_AUTO; encoder.Ctl(EncoderCTL.OPUS_GET_APPLICATION, ref value); @@ -40,7 +41,7 @@ public static OpusPredefinedValues GetApplication(this OpusEncoder encoder) /// The bitRate to set. /// /// - public static void SetBitRate(this OpusEncoder encoder, int bitRate) + public static void SetBitRate(this IOpusEncoder encoder, int bitRate) { encoder.Ctl(EncoderCTL.OPUS_SET_BITRATE, bitRate); } @@ -52,7 +53,7 @@ public static void SetBitRate(this OpusEncoder encoder, int bitRate) /// The encoder's bitrate. /// /// - public static int GetBitRate(this OpusEncoder encoder) + public static int GetBitRate(this IOpusEncoder encoder) { var value = 0; encoder.Ctl(EncoderCTL.OPUS_GET_BITRATE, ref value); @@ -66,7 +67,7 @@ public static int GetBitRate(this OpusEncoder encoder) /// The max bandwidth to set. /// /// - public static void SetMaxBandwidth(this OpusEncoder encoder, int maxBandwidth) + public static void SetMaxBandwidth(this IOpusEncoder encoder, int maxBandwidth) { encoder.Ctl(EncoderCTL.OPUS_SET_MAX_BANDWIDTH, maxBandwidth); } @@ -78,7 +79,7 @@ public static void SetMaxBandwidth(this OpusEncoder encoder, int maxBandwidth) /// The encoder's max bandwidth. /// /// - public static int GetMaxBandwidth(this OpusEncoder encoder) + public static int GetMaxBandwidth(this IOpusEncoder encoder) { var value = 0; encoder.Ctl(EncoderCTL.OPUS_GET_MAX_BANDWIDTH, ref value); @@ -92,7 +93,7 @@ public static int GetMaxBandwidth(this OpusEncoder encoder) /// Whether to enable/disable the encoder's vbr. /// /// - public static void SetVbr(this OpusEncoder encoder, bool enabled) + public static void SetVbr(this IOpusEncoder encoder, bool enabled) { encoder.Ctl(EncoderCTL.OPUS_SET_VBR, enabled ? 1 : 0); } @@ -104,7 +105,7 @@ public static void SetVbr(this OpusEncoder encoder, bool enabled) /// Whether the vbr is enabled or not. /// /// - public static bool GetVbr(this OpusEncoder encoder) + public static bool GetVbr(this IOpusEncoder encoder) { var enabled = 0; encoder.Ctl(EncoderCTL.OPUS_GET_VBR, ref enabled); @@ -118,7 +119,7 @@ public static bool GetVbr(this OpusEncoder encoder) /// The bandwidth to set. /// /// - public static void SetBandwidth(this OpusEncoder encoder, OpusPredefinedValues bandwidth) + public static void SetBandwidth(this IOpusEncoder encoder, OpusPredefinedValues bandwidth) { encoder.Ctl(EncoderCTL.OPUS_SET_BANDWIDTH, (int)bandwidth); } @@ -130,7 +131,7 @@ public static void SetBandwidth(this OpusEncoder encoder, OpusPredefinedValues b /// The complexity to set between 1-10. /// /// - public static void SetComplexity(this OpusEncoder encoder, int complexity) + public static void SetComplexity(this IOpusEncoder encoder, int complexity) { encoder.Ctl(EncoderCTL.OPUS_SET_COMPLEXITY, complexity); } @@ -142,7 +143,7 @@ public static void SetComplexity(this OpusEncoder encoder, int complexity) /// The encoder's complexity. /// /// - public static int GetComplexity(this OpusEncoder encoder) + public static int GetComplexity(this IOpusEncoder encoder) { var value = 0; encoder.Ctl(EncoderCTL.OPUS_GET_COMPLEXITY, ref value); @@ -157,7 +158,7 @@ public static int GetComplexity(this OpusEncoder encoder) /// 0: Disable in-band FEC (default). 1: In-band 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: In-band FEC enabled, but does not necessarily switch to SILK if we have music. /// /// - public static void SetInbandFec(this OpusEncoder encoder, int mode) + public static void SetInbandFec(this IOpusEncoder encoder, int mode) { encoder.Ctl(EncoderCTL.OPUS_SET_INBAND_FEC, mode); } @@ -169,7 +170,7 @@ public static void SetInbandFec(this OpusEncoder encoder, int mode) /// The encoder's configured use of forward error correction. /// /// - public static int GetInbandFec(this OpusEncoder encoder) + public static int GetInbandFec(this IOpusEncoder encoder) { var value = 0; encoder.Ctl(EncoderCTL.OPUS_GET_INBAND_FEC, ref value); @@ -183,7 +184,7 @@ public static int GetInbandFec(this OpusEncoder encoder) /// The expected packet loss percentage value between 0-100. /// /// - public static void SetPacketLostPercent(this OpusEncoder encoder, int percent) + public static void SetPacketLostPercent(this IOpusEncoder encoder, int percent) { encoder.Ctl(EncoderCTL.OPUS_SET_PACKET_LOSS_PERC, percent); } @@ -195,7 +196,7 @@ public static void SetPacketLostPercent(this OpusEncoder encoder, int percent) /// The encoder's packet loss percentage. /// /// - public static int GetPacketLostPercent(this OpusEncoder encoder) + public static int GetPacketLostPercent(this IOpusEncoder encoder) { var value = 0; encoder.Ctl(EncoderCTL.OPUS_GET_PACKET_LOSS_PERC, ref value); @@ -209,7 +210,7 @@ public static int GetPacketLostPercent(this OpusEncoder encoder) /// Whether to enable the DTX or not. /// /// - public static void SetDtx(this OpusEncoder encoder, bool enabled) + public static void SetDtx(this IOpusEncoder encoder, bool enabled) { encoder.Ctl(EncoderCTL.OPUS_SET_DTX, enabled ? 1 : 0); } @@ -221,7 +222,7 @@ public static void SetDtx(this OpusEncoder encoder, bool enabled) /// Whether DTX is enabled or not. /// /// - public static bool GetDtx(this OpusEncoder encoder) + public static bool GetDtx(this IOpusEncoder encoder) { var enabled = 0; encoder.Ctl(EncoderCTL.OPUS_GET_DTX, ref enabled); @@ -235,7 +236,7 @@ public static bool GetDtx(this OpusEncoder encoder) /// Whether to enable the constrained VBR or not. /// /// - public static void SetVbrConstraint(this OpusEncoder encoder, bool enabled) + public static void SetVbrConstraint(this IOpusEncoder encoder, bool enabled) { encoder.Ctl(EncoderCTL.OPUS_SET_VBR_CONSTRAINT, enabled ? 1 : 0); } @@ -247,7 +248,7 @@ public static void SetVbrConstraint(this OpusEncoder encoder, bool enabled) /// Whether the constrained VBR is enabled or not. /// /// - public static bool GetVbrConstraint(this OpusEncoder encoder) + public static bool GetVbrConstraint(this IOpusEncoder encoder) { var enabled = 0; encoder.Ctl(EncoderCTL.OPUS_GET_VBR_CONSTRAINT, ref enabled); @@ -261,7 +262,7 @@ public static bool GetVbrConstraint(this OpusEncoder encoder) /// The number of channels to set. /// /// - public static void SetForceChannels(this OpusEncoder encoder, int channels) + public static void SetForceChannels(this IOpusEncoder encoder, int channels) { encoder.Ctl(EncoderCTL.OPUS_SET_FORCE_CHANNELS, channels); } @@ -274,7 +275,7 @@ public static void SetForceChannels(this OpusEncoder encoder, int channels) /// By default, this is set to . /// /// - public static int GetForceChannels(this OpusEncoder encoder) + public static int GetForceChannels(this IOpusEncoder encoder) { var value = 0; encoder.Ctl(EncoderCTL.OPUS_GET_FORCE_CHANNELS, ref value); @@ -288,7 +289,7 @@ public static int GetForceChannels(this OpusEncoder encoder) /// The signal type to set. Must be one of , or . /// /// - public static void SetSignal(this OpusEncoder encoder, OpusPredefinedValues signal) + public static void SetSignal(this IOpusEncoder encoder, OpusPredefinedValues signal) { encoder.Ctl(EncoderCTL.OPUS_SET_SIGNAL, (int)signal); } @@ -300,7 +301,7 @@ public static void SetSignal(this OpusEncoder encoder, OpusPredefinedValues sign /// The encoder's signal type. /// /// - public static OpusPredefinedValues GetSignal(this OpusEncoder encoder) + public static OpusPredefinedValues GetSignal(this IOpusEncoder encoder) { var value = (int)OpusPredefinedValues.OPUS_AUTO; encoder.Ctl(EncoderCTL.OPUS_GET_SIGNAL, ref value); @@ -314,7 +315,7 @@ public static OpusPredefinedValues GetSignal(this OpusEncoder encoder) /// The total samples of delay added by the entire codec. /// /// - public static int GetLookahead(this OpusEncoder encoder) + public static int GetLookahead(this IOpusEncoder encoder) { var value = 0; encoder.Ctl(EncoderCTL.OPUS_GET_LOOKAHEAD, ref value); @@ -328,7 +329,7 @@ public static int GetLookahead(this OpusEncoder encoder) /// The LSB depth to set. /// /// - public static void SetLsbDepth(this OpusEncoder encoder, int depth) + public static void SetLsbDepth(this IOpusEncoder encoder, int depth) { encoder.Ctl(EncoderCTL.OPUS_SET_LSB_DEPTH, depth); } @@ -340,7 +341,7 @@ public static void SetLsbDepth(this OpusEncoder encoder, int depth) /// The encoder's LSB depth. /// /// - public static int GetLsbDepth(this OpusEncoder encoder) + public static int GetLsbDepth(this IOpusEncoder encoder) { var value = 0; encoder.Ctl(EncoderCTL.OPUS_GET_LSB_DEPTH, ref value); @@ -354,7 +355,7 @@ public static int GetLsbDepth(this OpusEncoder encoder) /// The frame duration to set. Must be one of , , , , , , , , or /// /// - public static void SetExpertFrameDuration(this OpusEncoder encoder, OpusPredefinedValues expertDuration) + public static void SetExpertFrameDuration(this IOpusEncoder encoder, OpusPredefinedValues expertDuration) { encoder.Ctl(EncoderCTL.OPUS_SET_EXPERT_FRAME_DURATION, (int)expertDuration); } @@ -366,7 +367,7 @@ public static void SetExpertFrameDuration(this OpusEncoder encoder, OpusPredefin /// The encoder's configured expert frame duration. /// /// - public static OpusPredefinedValues GetExpertFrameDuration(this OpusEncoder encoder) + public static OpusPredefinedValues GetExpertFrameDuration(this IOpusEncoder encoder) { var value = (int)OpusPredefinedValues.OPUS_AUTO; encoder.Ctl(EncoderCTL.OPUS_GET_EXPERT_FRAME_DURATION, ref value); @@ -380,7 +381,7 @@ public static OpusPredefinedValues GetExpertFrameDuration(this OpusEncoder encod /// Whether to disable to encoder's prediction. /// /// - public static void SetPredictionDisabled(this OpusEncoder encoder, bool disabled) + public static void SetPredictionDisabled(this IOpusEncoder encoder, bool disabled) { encoder.Ctl(EncoderCTL.OPUS_SET_PREDICTION_DISABLED, disabled ? 1 : 0); } @@ -392,7 +393,7 @@ public static void SetPredictionDisabled(this OpusEncoder encoder, bool disabled /// Whether the encoder's prediction is disabled or not. /// /// - public static bool GetPredictionDisabled(this OpusEncoder encoder) + public static bool GetPredictionDisabled(this IOpusEncoder encoder) { var value = 0; encoder.Ctl(EncoderCTL.OPUS_GET_PREDICTION_DISABLED, ref value); @@ -407,7 +408,7 @@ public static bool GetPredictionDisabled(this OpusEncoder encoder) /// I have no idea how this works even by looking at the source code, it seems to do something with speech but that's as far as I've gotten. (Sine) /// /// - public static int GetInDtx(this OpusEncoder encoder) + public static int GetInDtx(this IOpusEncoder encoder) { var value = 0; encoder.Ctl(EncoderCTL.OPUS_GET_IN_DTX, ref value); @@ -421,7 +422,7 @@ public static int GetInDtx(this OpusEncoder encoder) /// Whether to enable the QEXT extension or not. /// /// - public static void SetQext(this OpusEncoder encoder, bool enabled) + public static void SetQext(this IOpusEncoder encoder, bool enabled) { encoder.Ctl(EncoderCTL.OPUS_SET_QEXT, enabled ? 1 : 0); } @@ -433,7 +434,7 @@ public static void SetQext(this OpusEncoder encoder, bool enabled) /// Whether the QEXT extension is enabled or not. /// /// - public static bool GetQext(this OpusEncoder encoder) + public static bool GetQext(this IOpusEncoder encoder) { var value = 0; encoder.Ctl(EncoderCTL.OPUS_GET_QEXT, ref value); @@ -446,7 +447,7 @@ public static bool GetQext(this OpusEncoder encoder) /// The encoder state. /// /// - public static void Reset(this OpusEncoder encoder) + public static void Reset(this IOpusEncoder encoder) { encoder.Ctl(GenericCTL.OPUS_RESET_STATE); } @@ -458,7 +459,7 @@ public static void Reset(this OpusEncoder encoder) /// The final state of the codec's entropy coder. /// /// - public static uint GetFinalRange(this OpusEncoder encoder) + public static uint GetFinalRange(this IOpusEncoder encoder) { var finalRange = 0u; encoder.Ctl(GenericCTL.OPUS_GET_FINAL_RANGE, ref finalRange); @@ -472,7 +473,7 @@ public static uint GetFinalRange(this OpusEncoder encoder) /// The encoder's last bandpass. /// /// - public static OpusPredefinedValues GetBandwidth(this OpusEncoder encoder) + public static OpusPredefinedValues GetBandwidth(this IOpusEncoder encoder) { var bandPass = 0; encoder.Ctl(GenericCTL.OPUS_GET_BANDWIDTH, ref bandPass); @@ -486,7 +487,7 @@ public static OpusPredefinedValues GetBandwidth(this OpusEncoder encoder) /// The encoder's configured sample rate. /// /// - public static int GetSampleRate(this OpusEncoder encoder) + public static int GetSampleRate(this IOpusEncoder encoder) { var sampleRate = 0; encoder.Ctl(GenericCTL.OPUS_GET_SAMPLE_RATE, ref sampleRate); @@ -500,7 +501,7 @@ public static int GetSampleRate(this OpusEncoder encoder) /// Whether to disable or not. /// /// - public static void SetPhaseInversionDisabled(this OpusEncoder encoder, bool disabled) + public static void SetPhaseInversionDisabled(this IOpusEncoder encoder, bool disabled) { encoder.Ctl(GenericCTL.OPUS_SET_PHASE_INVERSION_DISABLED, disabled ? 1 : 0); } @@ -512,7 +513,7 @@ public static void SetPhaseInversionDisabled(this OpusEncoder encoder, bool disa /// Whether the phase inversion is disabled or not. /// /// - public static bool GetPhaseInversionDisabled(this OpusEncoder encoder) + public static bool GetPhaseInversionDisabled(this IOpusEncoder encoder) { var disabled = 0; encoder.Ctl(GenericCTL.OPUS_GET_PHASE_INVERSION_DISABLED, ref disabled); From a423ef8132812367be6a6b9ac10fca92ff8f6549 Mon Sep 17 00:00:00 2001 From: SineVector241 Date: Sun, 29 Mar 2026 14:00:42 +1100 Subject: [PATCH 6/9] Update OpusSharp versions. --- Directory.Build.props | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Directory.Build.props b/Directory.Build.props index 8a7a99c..598bda6 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -1,7 +1,7 @@ - 1.6.3 - 1.6.0.3 + 1.6.4 + 1.6.0.4 1.6.0.2 https://avionblock.github.io/OpusSharp/index.html https://github.com/AvionBlock/OpusSharp From 3b25b7d6e6b596dd2c5ad0ce930dc282ff2e1801 Mon Sep 17 00:00:00 2001 From: SineVector241 Date: Sun, 29 Mar 2026 17:29:13 +1100 Subject: [PATCH 7/9] Update README.md --- OpusSharp.Natives/README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/OpusSharp.Natives/README.md b/OpusSharp.Natives/README.md index 6737859..977977c 100644 --- a/OpusSharp.Natives/README.md +++ b/OpusSharp.Natives/README.md @@ -17,11 +17,12 @@ # Statically Linked Runtimes > [!NOTE] -> iOS is included in the package as `libopus.xcframework` and linked automatically for .NET iOS projects. +> iOS is included in the package as `libopus.xcframework` and linked automatically for .NET iOS projects. WASM still +> needs to be manually linked. - wasm > [!NOTE] > - ARM32 is no longer supported by the windows OS and is no longer provided in this package. > - Android builds are 16kb aligned. -> - Binaries have been updated to commit [c5a745b](https://github.com/xiph/opus/commit/c5a745b665831704e54ffdfb8f018573af11290f) +> - Binaries have been updated to commit [788cc89](https://github.com/xiph/opus/commit/788cc89ce4f2c42025d8c70ec1b4457dc89cd50f) From fcd1fd215df1d2865d1e0d3a875aaa76337fcadd Mon Sep 17 00:00:00 2001 From: SineVector241 Date: Sun, 29 Mar 2026 17:30:16 +1100 Subject: [PATCH 8/9] Update opussharp versions to be reflective of the opus version. --- Directory.Build.props | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Directory.Build.props b/Directory.Build.props index 598bda6..46d3e22 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -1,8 +1,8 @@ 1.6.4 - 1.6.0.4 - 1.6.0.2 + 1.6.1.0 + 1.6.1.0 https://avionblock.github.io/OpusSharp/index.html https://github.com/AvionBlock/OpusSharp From 8b279ee3316142228b1f25eea522f5a0cf36d3b6 Mon Sep 17 00:00:00 2001 From: SineVector241 Date: Sun, 29 Mar 2026 17:35:21 +1100 Subject: [PATCH 9/9] Update Binaries. --- .../ios/native/libopus.xcframework/Info.plist | 10 +++++----- .../runtimes/linux-arm64/native/opus.so | Bin 570752 -> 570752 bytes .../runtimes/win-arm64/native/opus.dll | Bin 347136 -> 347136 bytes .../runtimes/win-x64/native/opus.dll | Bin 472576 -> 472576 bytes .../runtimes/win-x86/native/opus.dll | Bin 367616 -> 367616 bytes 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/OpusSharp.Natives/runtimes/ios/native/libopus.xcframework/Info.plist b/OpusSharp.Natives/runtimes/ios/native/libopus.xcframework/Info.plist index d978ed4..e910abd 100644 --- a/OpusSharp.Natives/runtimes/ios/native/libopus.xcframework/Info.plist +++ b/OpusSharp.Natives/runtimes/ios/native/libopus.xcframework/Info.plist @@ -10,15 +10,18 @@ HeadersPath Headers LibraryIdentifier - ios-arm64 + ios-arm64_x86_64-simulator LibraryPath libopus.a SupportedArchitectures arm64 + x86_64 SupportedPlatform ios + SupportedPlatformVariant + simulator BinaryPath @@ -26,18 +29,15 @@ HeadersPath Headers LibraryIdentifier - ios-arm64_x86_64-simulator + ios-arm64 LibraryPath libopus.a SupportedArchitectures arm64 - x86_64 SupportedPlatform ios - SupportedPlatformVariant - simulator CFBundlePackageType diff --git a/OpusSharp.Natives/runtimes/linux-arm64/native/opus.so b/OpusSharp.Natives/runtimes/linux-arm64/native/opus.so index ab3cfb9b15333085fb614a279da97e44ea461c10..912c386375f2b3386b0b8d521970633b4119532f 100644 GIT binary patch delta 84 zcmZp8t<>;ZX~PXhk;3c^QOrHv1s^hPH+LSG8pO2c;JM~EjO}k2L6`}MnSq!Eh*^P{ iZTlNW_H+N4^bDu(V&u@+{)CZZ&n8CQ=?k}T+y?+v%p{or delta 81 zcmZp8t<>;ZX~PXhk&p*hO+PGQTq(7xO(MR#X8o+ge_u7fVQhcH2*ON2%nZaVK+Fon fY}?;3vY-1ueGemt#`Z^y9Q!sgYENIdh2uT|HH{@X diff --git a/OpusSharp.Natives/runtimes/win-arm64/native/opus.dll b/OpusSharp.Natives/runtimes/win-arm64/native/opus.dll index 6b64ade58fae5b2d714a9e399d4b347b2444310b..8ee99c537b1065e336d4863a24f2909d2caa7a55 100644 GIT binary patch delta 47 vcmZpeA=)rQbb|mRbJ+0{&BBcB!i*ry1jNih%rae=k+l&dw|zPzYo-?fM6?Yt delta 47 vcmZpeA=)rQbb|mRvwPU#W?{y5VMY*U0%B$$W|=O`$l3^!+diF9X11jNih%mT!$+qoIpI5&V4Y!~0i_Ob;4q)89o delta 52 zcmZp8Bh&CkW&;N!b7a`zW^TrIZblGh0%B$$W&vW>?c9uPoEtz2wu^6Md)Wd2h4>Do diff --git a/OpusSharp.Natives/runtimes/win-x86/native/opus.dll b/OpusSharp.Natives/runtimes/win-x86/native/opus.dll index 037747fc2abc51eb0d16be8bf57a7e6bdb7eeb81..2bd536fdf4162ed97cb70d94db02afbfacc61ee1 100644 GIT binary patch delta 47 vcmZqJA=a=%Yyl&4{P7db%#7{Kj3CSe#LPg