Przeglądaj źródła

audio: Rewrite SoundIo bindings (#4088)

* audio: Rewrite SoundIo bindings

This rewrite SoundIo bindings to be safer and not a pedantic autogenerated mess.

* Address comments

* Switch DllImport to LibraryImport

* Address gdkchan's comment
Mary-nyan 3 lat temu
rodzic
commit
403e67d983
28 zmienionych plików z 701 dodań i 2402 usunięć
  1. 178 0
      Ryujinx.Audio.Backends.SoundIo/Native/SoundIo.cs
  2. 13 0
      Ryujinx.Audio.Backends.SoundIo/Native/SoundIoBackend.cs
  3. 75 0
      Ryujinx.Audio.Backends.SoundIo/Native/SoundIoChannelId.cs
  4. 107 0
      Ryujinx.Audio.Backends.SoundIo/Native/SoundIoContext.cs
  5. 8 0
      Ryujinx.Audio.Backends.SoundIo/Native/SoundIoDeviceAim.cs
  6. 49 0
      Ryujinx.Audio.Backends.SoundIo/Native/SoundIoDeviceContext.cs
  7. 22 0
      Ryujinx.Audio.Backends.SoundIo/Native/SoundIoError.cs
  8. 11 0
      Ryujinx.Audio.Backends.SoundIo/Native/SoundIoException.cs
  9. 25 0
      Ryujinx.Audio.Backends.SoundIo/Native/SoundIoFormat.cs
  10. 164 0
      Ryujinx.Audio.Backends.SoundIo/Native/SoundIoOutStreamContext.cs
  11. 0 38
      Ryujinx.Audio.Backends.SoundIo/Native/libsoundio/MarshalExtensions.cs
  12. 0 386
      Ryujinx.Audio.Backends.SoundIo/Native/libsoundio/SoundIO.cs
  13. 0 13
      Ryujinx.Audio.Backends.SoundIo/Native/libsoundio/SoundIOBackend.cs
  14. 0 30
      Ryujinx.Audio.Backends.SoundIo/Native/libsoundio/SoundIOChannelArea.cs
  15. 0 34
      Ryujinx.Audio.Backends.SoundIo/Native/libsoundio/SoundIOChannelAreas.cs
  16. 0 75
      Ryujinx.Audio.Backends.SoundIo/Native/libsoundio/SoundIOChannelId.cs
  17. 0 116
      Ryujinx.Audio.Backends.SoundIo/Native/libsoundio/SoundIOChannelLayout.cs
  18. 0 267
      Ryujinx.Audio.Backends.SoundIo/Native/libsoundio/SoundIODevice.cs
  19. 0 8
      Ryujinx.Audio.Backends.SoundIo/Native/libsoundio/SoundIODeviceAim.cs
  20. 0 10
      Ryujinx.Audio.Backends.SoundIo/Native/libsoundio/SoundIOException.cs
  21. 0 25
      Ryujinx.Audio.Backends.SoundIo/Native/libsoundio/SoundIOFormat.cs
  22. 0 293
      Ryujinx.Audio.Backends.SoundIo/Native/libsoundio/SoundIOInStream.cs
  23. 0 331
      Ryujinx.Audio.Backends.SoundIo/Native/libsoundio/SoundIOOutStream.cs
  24. 0 58
      Ryujinx.Audio.Backends.SoundIo/Native/libsoundio/SoundIORingBuffer.cs
  25. 0 14
      Ryujinx.Audio.Backends.SoundIo/Native/libsoundio/SoundIOSampleRateRange.cs
  26. 0 643
      Ryujinx.Audio.Backends.SoundIo/Native/libsoundio/libsoundio-interop.cs
  27. 29 36
      Ryujinx.Audio.Backends.SoundIo/SoundIoHardwareDeviceDriver.cs
  28. 20 25
      Ryujinx.Audio.Backends.SoundIo/SoundIoHardwareDeviceSession.cs

+ 178 - 0
Ryujinx.Audio.Backends.SoundIo/Native/SoundIo.cs

@@ -0,0 +1,178 @@
+using Ryujinx.Common.Memory;
+using System;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+namespace Ryujinx.Audio.Backends.SoundIo.Native
+{
+    public static partial class SoundIo
+    {
+        private const string LibraryName = "libsoundio";
+
+        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+        public unsafe delegate void OnDeviceChangeNativeDelegate(IntPtr ctx);
+
+        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+        public unsafe delegate void OnBackendDisconnectedDelegate(IntPtr ctx, SoundIoError err);
+
+        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+        public unsafe delegate void OnEventsSignalDelegate(IntPtr ctx);
+
+        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+        public unsafe delegate void EmitRtPrioWarningDelegate();
+
+        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+        public unsafe delegate void JackCallbackDelegate(IntPtr msg);
+
+        [StructLayout(LayoutKind.Sequential)]
+        public struct SoundIoStruct
+        {
+            public IntPtr UserData;
+            public IntPtr OnDeviceChange;
+            public IntPtr OnBackendDisconnected;
+            public IntPtr OnEventsSignal;
+            public SoundIoBackend CurrentBackend;
+            public IntPtr ApplicationName;
+            public IntPtr EmitRtPrioWarning;
+            public IntPtr JackInfoCallback;
+            public IntPtr JackErrorCallback;
+        }
+
+        public struct SoundIoChannelLayout
+        {
+            public IntPtr Name;
+            public int ChannelCount;
+            public Array24<SoundIoChannelId> Channels;
+
+            public static IntPtr GetDefault(int channelCount)
+            {
+                return soundio_channel_layout_get_default(channelCount);
+            }
+
+            public static unsafe SoundIoChannelLayout GetDefaultValue(int channelCount)
+            {
+                return Unsafe.AsRef<SoundIoChannelLayout>((SoundIoChannelLayout*)GetDefault(channelCount));
+            }
+        }
+
+        public struct SoundIoSampleRateRange
+        {
+            public int Min;
+            public int Max;
+        }
+
+        public struct SoundIoDevice
+        {
+            public IntPtr SoundIo;
+            public IntPtr Id;
+            public IntPtr Name;
+            public SoundIoDeviceAim Aim;
+            public IntPtr Layouts;
+            public int LayoutCount;
+            public SoundIoChannelLayout CurrentLayout;
+            public IntPtr Formats;
+            public int FormatCount;
+            public SoundIoFormat CurrentFormat;
+            public IntPtr SampleRates;
+            public int SampleRateCount;
+            public int SampleRateCurrent;
+            public double SoftwareLatencyMin;
+            public double SoftwareLatencyMax;
+            public double SoftwareLatencyCurrent;
+            public bool IsRaw;
+            public int RefCount;
+            public SoundIoError ProbeError;
+        }
+
+        public struct SoundIoOutStream
+        {
+            public IntPtr Device;
+            public SoundIoFormat Format;
+            public int SampleRate;
+            public SoundIoChannelLayout Layout;
+            public double SoftwareLatency;
+            public float Volume;
+            public IntPtr UserData;
+            public IntPtr WriteCallback;
+            public IntPtr UnderflowCallback;
+            public IntPtr ErrorCallback;
+            public IntPtr Name;
+            public bool NonTerminalHint;
+            public int BytesPerFrame;
+            public int BytesPerSample;
+            public SoundIoError LayoutError;
+        }
+
+        public struct SoundIoChannelArea
+        {
+            public IntPtr Pointer;
+            public int Step;
+        }
+
+        [LibraryImport(LibraryName)]
+        public static partial IntPtr soundio_create();
+
+        [LibraryImport(LibraryName)]
+        public static partial SoundIoError soundio_connect(IntPtr ctx);
+
+        [LibraryImport(LibraryName)]
+        public static partial void soundio_disconnect(IntPtr ctx);
+
+        [LibraryImport(LibraryName)]
+        public static partial void soundio_flush_events(IntPtr ctx);
+
+        [LibraryImport(LibraryName)]
+        public static partial int soundio_output_device_count(IntPtr ctx);
+
+        [LibraryImport(LibraryName)]
+        public static partial int soundio_default_output_device_index(IntPtr ctx);
+
+        [LibraryImport(LibraryName)]
+        public static partial IntPtr soundio_get_output_device(IntPtr ctx, int index);
+
+        [LibraryImport(LibraryName)]
+        [return: MarshalAs(UnmanagedType.Bool)]
+        public static partial bool soundio_device_supports_format(IntPtr devCtx, SoundIoFormat format);
+
+        [LibraryImport(LibraryName)]
+        [return: MarshalAs(UnmanagedType.Bool)]
+        public static partial bool soundio_device_supports_layout(IntPtr devCtx, IntPtr layout);
+
+        [LibraryImport(LibraryName)]
+        [return: MarshalAs(UnmanagedType.Bool)]
+        public static partial bool soundio_device_supports_sample_rate(IntPtr devCtx, int sampleRate);
+
+        [LibraryImport(LibraryName)]
+        public static partial IntPtr soundio_outstream_create(IntPtr devCtx);
+
+        [LibraryImport(LibraryName)]
+        public static partial SoundIoError soundio_outstream_open(IntPtr outStreamCtx);
+
+        [LibraryImport(LibraryName)]
+        public static partial SoundIoError soundio_outstream_start(IntPtr outStreamCtx);
+
+        [LibraryImport(LibraryName)]
+        public static partial SoundIoError soundio_outstream_begin_write(IntPtr outStreamCtx, IntPtr areas, IntPtr frameCount);
+
+        [LibraryImport(LibraryName)]
+        public static partial SoundIoError soundio_outstream_end_write(IntPtr outStreamCtx);
+
+        [LibraryImport(LibraryName)]
+        public static partial SoundIoError soundio_outstream_pause(IntPtr devCtx, [MarshalAs(UnmanagedType.Bool)] bool pause);
+
+        [LibraryImport(LibraryName)]
+        public static partial SoundIoError soundio_outstream_set_volume(IntPtr devCtx, double volume);
+
+        [LibraryImport(LibraryName)]
+        public static partial void soundio_outstream_destroy(IntPtr streamCtx);
+
+        [LibraryImport(LibraryName)]
+        public static partial void soundio_destroy(IntPtr ctx);
+
+        [LibraryImport(LibraryName)]
+        public static partial IntPtr soundio_channel_layout_get_default(int channelCount);
+
+        [LibraryImport(LibraryName)]
+        public static partial IntPtr soundio_strerror(SoundIoError err);
+    }
+}

+ 13 - 0
Ryujinx.Audio.Backends.SoundIo/Native/SoundIoBackend.cs

@@ -0,0 +1,13 @@
+namespace Ryujinx.Audio.Backends.SoundIo.Native
+{
+    public enum SoundIoBackend : int
+    {
+        None = 0,
+        Jack = 1,
+        PulseAudio = 2,
+        Alsa = 3,
+        CoreAudio = 4,
+        Wasapi = 5,
+        Dummy = 6
+    }
+}

+ 75 - 0
Ryujinx.Audio.Backends.SoundIo/Native/SoundIoChannelId.cs

@@ -0,0 +1,75 @@
+namespace Ryujinx.Audio.Backends.SoundIo.Native
+{
+    public enum SoundIoChannelId
+    {
+        Invalid = 0,
+        FrontLeft = 1,
+        FrontRight = 2,
+        FrontCenter = 3,
+        Lfe = 4,
+        BackLeft = 5,
+        BackRight = 6,
+        FrontLeftCenter = 7,
+        FrontRightCenter = 8,
+        BackCenter = 9,
+        SideLeft = 10,
+        SideRight = 11,
+        TopCenter = 12,
+        TopFrontLeft = 13,
+        TopFrontCenter = 14,
+        TopFrontRight = 15,
+        TopBackLeft = 16,
+        TopBackCenter = 17,
+        TopBackRight = 18,
+        BackLeftCenter = 19,
+        BackRightCenter = 20,
+        FrontLeftWide = 21,
+        FrontRightWide = 22,
+        FrontLeftHigh = 23,
+        FrontCenterHigh = 24,
+        FrontRightHigh = 25,
+        TopFrontLeftCenter = 26,
+        TopFrontRightCenter = 27,
+        TopSideLeft = 28,
+        TopSideRight = 29,
+        LeftLfe = 30,
+        RightLfe = 31,
+        Lfe2 = 32,
+        BottomCenter = 33,
+        BottomLeftCenter = 34,
+        BottomRightCenter = 35,
+        MsMid = 36,
+        MsSide = 37,
+        AmbisonicW = 38,
+        AmbisonicX = 39,
+        AmbisonicY = 40,
+        AmbisonicZ = 41,
+        XyX = 42,
+        XyY = 43,
+        HeadphonesLeft = 44,
+        HeadphonesRight = 45,
+        ClickTrack = 46,
+        ForeignLanguage = 47,
+        HearingImpaired = 48,
+        Narration = 49,
+        Haptic = 50,
+        DialogCentricMix = 51,
+        Aux = 52,
+        Aux0 = 53,
+        Aux1 = 54,
+        Aux2 = 55,
+        Aux3 = 56,
+        Aux4 = 57,
+        Aux5 = 58,
+        Aux6 = 59,
+        Aux7 = 60,
+        Aux8 = 61,
+        Aux9 = 62,
+        Aux10 = 63,
+        Aux11 = 64,
+        Aux12 = 65,
+        Aux13 = 66,
+        Aux14 = 67,
+        Aux15 = 68,
+    }
+}

+ 107 - 0
Ryujinx.Audio.Backends.SoundIo/Native/SoundIoContext.cs

@@ -0,0 +1,107 @@
+using System;
+using System.Reflection.Metadata;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Threading;
+using static Ryujinx.Audio.Backends.SoundIo.Native.SoundIo;
+
+namespace Ryujinx.Audio.Backends.SoundIo.Native
+{
+    public class SoundIoContext : IDisposable
+    {
+        private IntPtr _context;
+        private Action<SoundIoError> _onBackendDisconnect;
+        private OnBackendDisconnectedDelegate _onBackendDisconnectNative;
+
+        public IntPtr Context => _context;
+
+        internal SoundIoContext(IntPtr context)
+        {
+            _context = context;
+            _onBackendDisconnect = null;
+            _onBackendDisconnectNative = null;
+        }
+
+        public SoundIoError Connect() => soundio_connect(_context);
+        public void Disconnect() => soundio_disconnect(_context);
+
+        public void FlushEvents() => soundio_flush_events(_context);
+
+        public int OutputDeviceCount => soundio_output_device_count(_context);
+
+        public int DefaultOutputDeviceIndex => soundio_default_output_device_index(_context);
+
+        public Action<SoundIoError> OnBackendDisconnect
+        {
+            get { return _onBackendDisconnect; }
+            set
+            {
+                _onBackendDisconnect = value;
+
+                if (_onBackendDisconnect == null)
+                {
+                    _onBackendDisconnectNative = null;
+                }
+                else
+                {
+                    _onBackendDisconnectNative = (ctx, err) => _onBackendDisconnect(err);
+                }
+
+                GetContext().OnBackendDisconnected = Marshal.GetFunctionPointerForDelegate(_onBackendDisconnectNative);
+            }
+        }
+
+        private ref SoundIoStruct GetContext()
+        {
+            unsafe
+            {
+                return ref Unsafe.AsRef<SoundIoStruct>((SoundIoStruct*)_context);
+            }
+        }
+
+        public SoundIoDeviceContext GetOutputDevice(int index)
+        {
+            IntPtr deviceContext = soundio_get_output_device(_context, index);
+
+            if (deviceContext == IntPtr.Zero)
+            {
+                return null;
+            }
+
+            return new SoundIoDeviceContext(deviceContext);
+        }
+
+        public static SoundIoContext Create()
+        {
+            IntPtr context = soundio_create();
+
+            if (context == IntPtr.Zero)
+            {
+                return null;
+            }
+
+            return new SoundIoContext(context);
+        }
+
+        protected virtual void Dispose(bool disposing)
+        {
+            IntPtr currentContext = Interlocked.Exchange(ref _context, IntPtr.Zero);
+
+            if (currentContext != IntPtr.Zero)
+            {
+                soundio_destroy(currentContext);
+            }
+        }
+
+        public void Dispose()
+        {
+            Dispose(true);
+            GC.SuppressFinalize(this);
+        }
+
+        ~SoundIoContext()
+        {
+            Dispose(false);
+        }
+    }
+}

+ 8 - 0
Ryujinx.Audio.Backends.SoundIo/Native/SoundIoDeviceAim.cs

@@ -0,0 +1,8 @@
+namespace Ryujinx.Audio.Backends.SoundIo.Native
+{
+    public enum SoundIoDeviceAim
+    {
+        SoundIoDeviceAimInput = 0,
+        SoundIoDeviceAimOutput = 1
+    }
+}

+ 49 - 0
Ryujinx.Audio.Backends.SoundIo/Native/SoundIoDeviceContext.cs

@@ -0,0 +1,49 @@
+using System;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using static Ryujinx.Audio.Backends.SoundIo.Native.SoundIo;
+
+namespace Ryujinx.Audio.Backends.SoundIo.Native
+{
+    public class SoundIoDeviceContext
+    {
+        private readonly IntPtr _context;
+
+        public IntPtr Context => _context;
+
+        internal SoundIoDeviceContext(IntPtr context)
+        {
+            _context = context;
+        }
+
+        private ref SoundIoDevice GetDeviceContext()
+        {
+            unsafe
+            {
+                return ref Unsafe.AsRef<SoundIoDevice>((SoundIoDevice*)_context);
+            }
+        }
+
+        public bool IsRaw => GetDeviceContext().IsRaw;
+
+        public string Id => Marshal.PtrToStringAnsi(GetDeviceContext().Id);
+
+        public bool SupportsSampleRate(int sampleRate) => soundio_device_supports_sample_rate(_context, sampleRate);
+
+        public bool SupportsFormat(SoundIoFormat format) => soundio_device_supports_format(_context, format);
+
+        public bool SupportsChannelCount(int channelCount) => soundio_device_supports_layout(_context, SoundIoChannelLayout.GetDefault(channelCount));
+
+        public SoundIoOutStreamContext CreateOutStream()
+        {
+            IntPtr context = soundio_outstream_create(_context);
+
+            if (context == IntPtr.Zero)
+            {
+                return null;
+            }
+
+            return new SoundIoOutStreamContext(context);
+        }
+    }
+}

+ 22 - 0
Ryujinx.Audio.Backends.SoundIo/Native/SoundIoError.cs

@@ -0,0 +1,22 @@
+namespace Ryujinx.Audio.Backends.SoundIo.Native
+{
+    public enum SoundIoError
+    {
+        None = 0,
+        NoMem = 1,
+        InitAudioBackend = 2,
+        SystemResources = 3,
+        OpeningDevice = 4,
+        NoSuchDevice = 5,
+        Invalid = 6,
+        BackendUnavailable = 7,
+        Streaming = 8,
+        IncompatibleDevice = 9,
+        NoSuchClient = 10,
+        IncompatibleBackend = 11,
+        BackendDisconnected = 12,
+        Interrupted = 13,
+        Underflow = 14,
+        EncodingString = 15,
+    }
+}

+ 11 - 0
Ryujinx.Audio.Backends.SoundIo/Native/SoundIoException.cs

@@ -0,0 +1,11 @@
+using System;
+using System.Runtime.InteropServices;
+using static Ryujinx.Audio.Backends.SoundIo.Native.SoundIo;
+
+namespace Ryujinx.Audio.Backends.SoundIo.Native
+{
+    internal class SoundIoException : Exception
+    {
+        internal SoundIoException(SoundIoError error) : base(Marshal.PtrToStringAnsi(soundio_strerror(error))) { }
+    }
+}

+ 25 - 0
Ryujinx.Audio.Backends.SoundIo/Native/SoundIoFormat.cs

@@ -0,0 +1,25 @@
+namespace Ryujinx.Audio.Backends.SoundIo.Native
+{
+    public enum SoundIoFormat
+    {
+        Invalid = 0,
+        S8 = 1,
+        U8 = 2,
+        S16LE = 3,
+        S16BE = 4,
+        U16LE = 5,
+        U16BE = 6,
+        S24LE = 7,
+        S24BE = 8,
+        U24LE = 9,
+        U24BE = 10,
+        S32LE = 11,
+        S32BE = 12,
+        U32LE = 13,
+        U32BE = 14,
+        Float32LE = 15,
+        Float32BE = 16,
+        Float64LE = 17,
+        Float64BE = 18,
+    }
+}

+ 164 - 0
Ryujinx.Audio.Backends.SoundIo/Native/SoundIoOutStreamContext.cs

@@ -0,0 +1,164 @@
+using System;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using static Ryujinx.Audio.Backends.SoundIo.Native.SoundIo;
+
+namespace Ryujinx.Audio.Backends.SoundIo.Native
+{
+    public class SoundIoOutStreamContext : IDisposable
+    {
+        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+        private unsafe delegate void WriteCallbackDelegate(IntPtr ctx, int frameCountMin, int frameCountMax);
+
+        private IntPtr _context;
+        private IntPtr _nameStored;
+        private Action<int, int> _writeCallback;
+        private WriteCallbackDelegate _writeCallbackNative;
+
+        public IntPtr Context => _context;
+
+        internal SoundIoOutStreamContext(IntPtr context)
+        {
+            _context = context;
+            _nameStored = IntPtr.Zero;
+            _writeCallback = null;
+            _writeCallbackNative = null;
+        }
+
+        private ref SoundIoOutStream GetOutContext()
+        {
+            unsafe
+            {
+                return ref Unsafe.AsRef<SoundIoOutStream>((SoundIoOutStream*)_context);
+            }
+        }
+
+        public string Name
+        {
+            get => Marshal.PtrToStringAnsi(GetOutContext().Name);
+            set
+            {
+                var context = GetOutContext();
+
+                if (_nameStored != IntPtr.Zero && context.Name == _nameStored)
+                {
+                    Marshal.FreeHGlobal(_nameStored);
+                }
+
+                _nameStored = Marshal.StringToHGlobalAnsi(value);
+                GetOutContext().Name = _nameStored;
+            }
+        }
+
+        public SoundIoChannelLayout Layout
+        {
+            get => GetOutContext().Layout;
+            set => GetOutContext().Layout = value;
+        }
+
+        public SoundIoFormat Format
+        {
+            get => GetOutContext().Format;
+            set => GetOutContext().Format = value;
+        }
+
+        public int SampleRate
+        {
+            get => GetOutContext().SampleRate;
+            set => GetOutContext().SampleRate = value;
+        }
+
+        public float Volume
+        {
+            get => GetOutContext().Volume;
+            set => GetOutContext().Volume = value;
+        }
+
+        public int BytesPerFrame
+        {
+            get => GetOutContext().BytesPerFrame;
+            set => GetOutContext().BytesPerFrame = value;
+        }
+
+        public int BytesPerSample
+        {
+            get => GetOutContext().BytesPerSample;
+            set => GetOutContext().BytesPerSample = value;
+        }
+
+        public Action<int, int> WriteCallback
+        {
+            get { return _writeCallback; }
+            set
+            {
+                _writeCallback = value;
+
+                if (_writeCallback == null)
+                {
+                    _writeCallbackNative = null;
+                }
+                else
+                {
+                    _writeCallbackNative = (ctx, frameCountMin, frameCountMax) => _writeCallback(frameCountMin, frameCountMax);
+                }
+
+                GetOutContext().WriteCallback = Marshal.GetFunctionPointerForDelegate(_writeCallbackNative);
+            }
+        }
+
+        private static void CheckError(SoundIoError error)
+        {
+            if (error != SoundIoError.None)
+            {
+                throw new SoundIoException(error);
+            }
+        }
+
+        public void Open() => CheckError(soundio_outstream_open(_context));
+
+        public void Start() => CheckError(soundio_outstream_start(_context));
+
+        public void Pause(bool pause) => CheckError(soundio_outstream_pause(_context, pause));
+
+        public void SetVolume(double volume) => CheckError(soundio_outstream_set_volume(_context, volume));
+
+        public Span<SoundIoChannelArea> BeginWrite(ref int frameCount)
+        {
+            IntPtr arenas = default;
+            int nativeFrameCount = frameCount;
+
+            unsafe
+            {
+                var frameCountPtr = &nativeFrameCount;
+                var arenasPtr = &arenas;
+                CheckError(soundio_outstream_begin_write(_context, (IntPtr)arenasPtr, (IntPtr)frameCountPtr));
+
+                frameCount = *frameCountPtr;
+
+                return new Span<SoundIoChannelArea>((void*)arenas, Layout.ChannelCount);
+            }
+        }
+
+        public void EndWrite() => CheckError(soundio_outstream_end_write(_context));
+
+        protected virtual void Dispose(bool disposing)
+        {
+            if (_context != IntPtr.Zero)
+            {
+                soundio_outstream_destroy(_context);
+                _context = IntPtr.Zero;
+            }
+        }
+
+        public void Dispose()
+        {
+            Dispose(true);
+            GC.SuppressFinalize(this);
+        }
+
+        ~SoundIoOutStreamContext()
+        {
+            Dispose(false);
+        }
+    }
+}

+ 0 - 38
Ryujinx.Audio.Backends.SoundIo/Native/libsoundio/MarshalExtensions.cs

@@ -1,38 +0,0 @@
-using System;
-using System.Runtime.InteropServices;
-
-namespace SoundIOSharp
-{
-    public static class MarshalEx
-    {
-        public static double ReadDouble(IntPtr handle, int offset = 0)
-        {
-            return BitConverter.Int64BitsToDouble(Marshal.ReadInt64(handle, offset));
-        }
-
-        public static void WriteDouble(IntPtr handle, double value)
-        {
-            WriteDouble(handle, 0, value);
-        }
-
-        public static void WriteDouble(IntPtr handle, int offset, double value)
-        {
-            Marshal.WriteInt64(handle, offset, BitConverter.DoubleToInt64Bits(value));
-        }
-
-        public static float ReadFloat(IntPtr handle, int offset = 0)
-        {
-            return BitConverter.Int32BitsToSingle(Marshal.ReadInt32(handle, offset));
-        }
-
-        public static void WriteFloat(IntPtr handle, float value)
-        {
-            WriteFloat(handle, 0, value);
-        }
-
-        public static void WriteFloat(IntPtr handle, int offset, float value)
-        {
-            Marshal.WriteInt32(handle, offset, BitConverter.SingleToInt32Bits(value));
-        }
-    }
-}

+ 0 - 386
Ryujinx.Audio.Backends.SoundIo/Native/libsoundio/SoundIO.cs

@@ -1,386 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Runtime.InteropServices;
-
-namespace SoundIOSharp
-{
-    public class SoundIO : IDisposable
-    {
-        Pointer<SoundIo> handle;
-
-        public SoundIO()
-        {
-            handle = Natives.soundio_create();
-        }
-
-        internal SoundIO(Pointer<SoundIo> handle)
-        {
-            this.handle = handle;
-        }
-
-        public void Dispose ()
-        {
-            foreach (var h in allocated_hglobals)
-            {
-                Marshal.FreeHGlobal(h);
-            }
-
-            Natives.soundio_destroy(handle);
-        }
-
-        // Equality (based on handle)
-
-        public override bool Equals(object other)
-        {
-            var d = other as SoundIO;
-
-            return d != null && this.handle == d.handle;
-        }
-
-        public override int GetHashCode()
-        {
-            return (int)(IntPtr)handle;
-        }
-
-        public static bool operator == (SoundIO obj1, SoundIO obj2)
-        {
-            return obj1 is null ? obj2 is null : obj1.Equals(obj2);
-        }
-
-        public static bool operator != (SoundIO obj1, SoundIO obj2)
-        {
-            return obj1 is null ? obj2 is object : !obj1.Equals(obj2);
-        }
-
-        // fields
-
-        // FIXME: this should be taken care in more centralized/decent manner... we don't want to write
-        // this kind of code anywhere we need string marshaling.
-        List<IntPtr> allocated_hglobals = new List<IntPtr>();
-
-        public string ApplicationName {
-            get { return Marshal.PtrToStringAnsi(Marshal.ReadIntPtr(handle, app_name_offset)); }
-            set
-            {
-                unsafe
-                {
-                    var existing = Marshal.ReadIntPtr(handle, app_name_offset);
-                    if (allocated_hglobals.Contains (existing))
-                    {
-                        allocated_hglobals.Remove(existing);
-                        Marshal.FreeHGlobal(existing);
-                    }
-
-                    var ptr = Marshal.StringToHGlobalAnsi(value);
-                    Marshal.WriteIntPtr(handle, app_name_offset, ptr);
-                    allocated_hglobals.Add(ptr);
-                }
-            }
-        }
-
-        static readonly int app_name_offset = (int)Marshal.OffsetOf<SoundIo>("app_name");
-
-        public SoundIOBackend CurrentBackend
-        {
-            get { return (SoundIOBackend)Marshal.ReadInt32(handle, current_backend_offset); }
-        }
-
-        static readonly int current_backend_offset = (int)Marshal.OffsetOf<SoundIo>("current_backend");
-
-        // emit_rtprio_warning
-        public Action EmitRealtimePriorityWarning
-        {
-            get { return emit_rtprio_warning; }
-            set
-            {
-                emit_rtprio_warning = value;
-
-                var ptr = Marshal.GetFunctionPointerForDelegate(on_devices_change);
-
-                Marshal.WriteIntPtr(handle, emit_rtprio_warning_offset, ptr);
-            }
-        }
-
-        static readonly int emit_rtprio_warning_offset = (int)Marshal.OffsetOf<SoundIo>("emit_rtprio_warning");
-
-        Action emit_rtprio_warning;
-
-        // jack_error_callback
-        public Action<string> JackErrorCallback
-        {
-            get { return jack_error_callback; }
-            set
-            {
-                jack_error_callback = value;
-                if (value == null)
-                {
-                    jack_error_callback = null;
-                }
-                else
-                {
-                    jack_error_callback_native = msg => jack_error_callback(msg);
-                }
-
-                var ptr = Marshal.GetFunctionPointerForDelegate(jack_error_callback_native);
-                Marshal.WriteIntPtr(handle, jack_error_callback_offset, ptr);
-            }
-        }
-
-        static readonly int jack_error_callback_offset = (int)Marshal.OffsetOf<SoundIo>("jack_error_callback");
-
-        Action<string> jack_error_callback;
-        delegate void jack_error_delegate(string message);
-        jack_error_delegate jack_error_callback_native;
-
-        // jack_info_callback
-        public Action<string> JackInfoCallback
-        {
-            get { return jack_info_callback; }
-            set
-            {
-                jack_info_callback = value;
-                if (value == null)
-                {
-                    jack_info_callback = null;
-                }
-                else
-                {
-                    jack_info_callback_native = msg => jack_info_callback(msg);
-                }
-
-                var ptr = Marshal.GetFunctionPointerForDelegate(jack_info_callback_native);
-                Marshal.WriteIntPtr(handle, jack_info_callback_offset, ptr);
-            }
-        }
-
-        static readonly int jack_info_callback_offset = (int)Marshal.OffsetOf<SoundIo>("jack_info_callback");
-
-        Action<string> jack_info_callback;
-        delegate void jack_info_delegate(string message);
-        jack_info_delegate jack_info_callback_native;
-
-        // on_backend_disconnect
-        public Action<int> OnBackendDisconnect
-        {
-            get { return on_backend_disconnect; }
-            set
-            {
-                on_backend_disconnect = value;
-                if (value == null)
-                {
-                    on_backend_disconnect_native = null;
-                }
-                else
-                {
-                    on_backend_disconnect_native = (sio, err) => on_backend_disconnect(err);
-                }
-
-                var ptr = Marshal.GetFunctionPointerForDelegate(on_backend_disconnect_native);
-                Marshal.WriteIntPtr(handle, on_backend_disconnect_offset, ptr);
-            }
-        }
-
-        static readonly int on_backend_disconnect_offset = (int)Marshal.OffsetOf<SoundIo>("on_backend_disconnect");
-
-        Action<int> on_backend_disconnect;
-        delegate void on_backend_disconnect_delegate(IntPtr handle, int errorCode);
-        on_backend_disconnect_delegate on_backend_disconnect_native;
-
-        // on_devices_change
-        public Action OnDevicesChange
-        {
-            get { return on_devices_change; }
-            set
-            {
-                on_devices_change = value;
-                if (value == null)
-                {
-                    on_devices_change_native = null;
-                }
-                else
-                {
-                    on_devices_change_native = sio => on_devices_change();
-                }
-
-                var ptr = Marshal.GetFunctionPointerForDelegate(on_devices_change_native);
-                Marshal.WriteIntPtr(handle, on_devices_change_offset, ptr);
-            }
-        }
-
-        static readonly int on_devices_change_offset = (int)Marshal.OffsetOf<SoundIo>("on_devices_change");
-
-        Action on_devices_change;
-        delegate void on_devices_change_delegate(IntPtr handle);
-        on_devices_change_delegate on_devices_change_native;
-
-        // on_events_signal
-        public Action OnEventsSignal
-        {
-            get { return on_events_signal; }
-            set
-            {
-                on_events_signal = value;
-                if (value == null)
-                {
-                    on_events_signal_native = null;
-                }
-                else
-                {
-                    on_events_signal_native = sio => on_events_signal();
-                }
-
-                var ptr = Marshal.GetFunctionPointerForDelegate(on_events_signal_native);
-                Marshal.WriteIntPtr(handle, on_events_signal_offset, ptr);
-            }
-        }
-
-        static readonly int on_events_signal_offset = (int)Marshal.OffsetOf<SoundIo>("on_events_signal");
-
-        Action on_events_signal;
-        delegate void on_events_signal_delegate(IntPtr handle);
-        on_events_signal_delegate on_events_signal_native;
-
-
-        // functions
-
-        public int BackendCount
-        {
-            get { return Natives.soundio_backend_count(handle); }
-        }
-
-        public int InputDeviceCount
-        {
-            get { return Natives.soundio_input_device_count(handle); }
-        }
-
-        public int OutputDeviceCount
-        {
-            get { return Natives.soundio_output_device_count(handle); }
-        }
-
-        public int DefaultInputDeviceIndex
-        {
-            get { return Natives.soundio_default_input_device_index(handle); }
-        }
-
-        public int DefaultOutputDeviceIndex
-        {
-            get { return Natives.soundio_default_output_device_index(handle); }
-        }
-
-        public SoundIOBackend GetBackend(int index)
-        {
-            return (SoundIOBackend)Natives.soundio_get_backend(handle, index);
-        }
-
-        public SoundIODevice GetInputDevice(int index)
-        {
-            return new SoundIODevice(Natives.soundio_get_input_device(handle, index));
-        }
-
-        public SoundIODevice GetOutputDevice(int index)
-        {
-            return new SoundIODevice(Natives.soundio_get_output_device(handle, index));
-        }
-
-        public void Connect()
-        {
-            var ret = (SoundIoError)Natives.soundio_connect(handle);
-            if (ret != SoundIoError.SoundIoErrorNone)
-            {
-                throw new SoundIOException(ret);
-            }
-        }
-
-        public void ConnectBackend(SoundIOBackend backend)
-        {
-            var ret = (SoundIoError)Natives.soundio_connect_backend(handle, (SoundIoBackend)backend);
-            if (ret != SoundIoError.SoundIoErrorNone)
-            {
-                throw new SoundIOException(ret);
-            }
-        }
-
-        public void Disconnect()
-        {
-            Natives.soundio_disconnect(handle);
-        }
-
-        public void FlushEvents()
-        {
-            Natives.soundio_flush_events(handle);
-        }
-
-        public void WaitEvents()
-        {
-            Natives.soundio_wait_events(handle);
-        }
-
-        public void Wakeup()
-        {
-            Natives.soundio_wakeup(handle);
-        }
-
-        public void ForceDeviceScan()
-        {
-            Natives.soundio_force_device_scan(handle);
-        }
-
-        public SoundIORingBuffer CreateRingBuffer(int capacity)
-        {
-            return new SoundIORingBuffer(Natives.soundio_ring_buffer_create(handle, capacity));
-        }
-
-        // static methods
-
-        public static string VersionString
-        {
-            get { return Marshal.PtrToStringAnsi(Natives.soundio_version_string()); }
-        }
-
-        public static int VersionMajor
-        {
-            get { return Natives.soundio_version_major(); }
-        }
-
-        public static int VersionMinor
-        {
-            get { return Natives.soundio_version_minor(); }
-        }
-
-        public static int VersionPatch
-        {
-            get { return Natives.soundio_version_patch(); }
-        }
-
-        public static string GetBackendName(SoundIOBackend backend)
-        {
-            return Marshal.PtrToStringAnsi(Natives.soundio_backend_name((SoundIoBackend)backend));
-        }
-
-        public static bool HaveBackend(SoundIOBackend backend)
-        {
-            return Natives.soundio_have_backend((SoundIoBackend)backend);
-        }
-
-        public static int GetBytesPerSample(SoundIOFormat format)
-        {
-            return Natives.soundio_get_bytes_per_sample((SoundIoFormat)format);
-        }
-
-        public static int GetBytesPerFrame(SoundIOFormat format, int channelCount)
-        {
-            return Natives.soundio_get_bytes_per_frame((SoundIoFormat)format, channelCount);
-        }
-
-        public static int GetBytesPerSecond(SoundIOFormat format, int channelCount, int sampleRate)
-        {
-            return Natives.soundio_get_bytes_per_second((SoundIoFormat)format, channelCount, sampleRate);
-        }
-
-        public static string GetSoundFormatName(SoundIOFormat format)
-        {
-            return Marshal.PtrToStringAnsi(Natives.soundio_format_string((SoundIoFormat)format));
-        }
-    }
-}

+ 0 - 13
Ryujinx.Audio.Backends.SoundIo/Native/libsoundio/SoundIOBackend.cs

@@ -1,13 +0,0 @@
-namespace SoundIOSharp
-{
-    public enum SoundIOBackend
-    {
-        None,
-        Jack,
-        PulseAudio,
-        Alsa,
-        CoreAudio,
-        Wasapi,
-        Dummy
-    }
-}

+ 0 - 30
Ryujinx.Audio.Backends.SoundIo/Native/libsoundio/SoundIOChannelArea.cs

@@ -1,30 +0,0 @@
-using System;
-using System.Runtime.InteropServices;
-
-namespace SoundIOSharp
-{
-    public struct SoundIOChannelArea
-    {
-        internal SoundIOChannelArea(Pointer<SoundIoChannelArea> handle)
-        {
-            this.handle = handle;
-        }
-
-        Pointer<SoundIoChannelArea> handle;
-
-        public IntPtr Pointer
-        {
-            get { return Marshal.ReadIntPtr(handle, ptr_offset); }
-            set { Marshal.WriteIntPtr(handle, ptr_offset, value); }
-        }
-
-        static readonly int ptr_offset = (int)Marshal.OffsetOf<SoundIoChannelArea>("ptr");
-
-        public int Step
-        {
-            get { return Marshal.ReadInt32(handle, step_offset); }
-        }
-
-        static readonly int step_offset = (int)Marshal.OffsetOf<SoundIoChannelArea>("step");
-    }
-}

+ 0 - 34
Ryujinx.Audio.Backends.SoundIo/Native/libsoundio/SoundIOChannelAreas.cs

@@ -1,34 +0,0 @@
-using System;
-using System.Runtime.InteropServices;
-
-namespace SoundIOSharp
-{
-    public struct SoundIOChannelAreas
-    {
-        static readonly int native_size = Marshal.SizeOf<SoundIoChannelArea>();
-
-        internal SoundIOChannelAreas(IntPtr head, int channelCount, int frameCount)
-        {
-            this.head          = head;
-            this.channel_count = channelCount;
-            this.frame_count   = frameCount;
-        }
-
-        IntPtr head;
-        int    channel_count;
-        int    frame_count;
-
-        public bool IsEmpty
-        {
-            get { return head == IntPtr.Zero; }
-        }
-
-        public SoundIOChannelArea GetArea(int channel)
-        {
-            return new SoundIOChannelArea(head + native_size * channel);
-        }
-
-        public int ChannelCount => channel_count;
-        public int FrameCount => frame_count;
-    }
-}

+ 0 - 75
Ryujinx.Audio.Backends.SoundIo/Native/libsoundio/SoundIOChannelId.cs

@@ -1,75 +0,0 @@
-namespace SoundIOSharp
-{
-    public enum SoundIOChannelId
-    {
-        Invalid,
-        FrontLeft,
-        FrontRight,
-        FrontCenter,
-        Lfe,
-        BackLeft,
-        BackRight,
-        FrontLeftCenter,
-        FrontRightCenter,
-        BackCenter,
-        SideLeft,
-        SideRight,
-        TopCenter,
-        TopFrontLeft,
-        TopFrontCenter,
-        TopFrontRight,
-        TopBackLeft,
-        TopBackCenter,
-        TopBackRight,
-        BackLeftCenter,
-        BackRightCenter,
-        FrontLeftWide,
-        FrontRightWide,
-        FrontLeftHigh,
-        FrontCenterHigh,
-        FrontRightHigh,
-        TopFrontLeftCenter,
-        TopFrontRightCenter,
-        TopSideLeft,
-        TopSideRight,
-        LeftLfe,
-        RightLfe,
-        Lfe2,
-        BottomCenter,
-        BottomLeftCenter,
-        BottomRightCenter,
-        MsMid,
-        MsSide,
-        AmbisonicW,
-        AmbisonicX,
-        AmbisonicY,
-        AmbisonicZ,
-        XyX,
-        XyY,
-        HeadphonesLeft,
-        HeadphonesRight,
-        ClickTrack,
-        ForeignLanguage,
-        HearingImpaired,
-        Narration,
-        Haptic,
-        DialogCentricMix,
-        Aux,
-        Aux0,
-        Aux1,
-        Aux2,
-        Aux3,
-        Aux4,
-        Aux5,
-        Aux6,
-        Aux7,
-        Aux8,
-        Aux9,
-        Aux10,
-        Aux11,
-        Aux12,
-        Aux13,
-        Aux14,
-        Aux15
-    }
-}

+ 0 - 116
Ryujinx.Audio.Backends.SoundIo/Native/libsoundio/SoundIOChannelLayout.cs

@@ -1,116 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Runtime.InteropServices;
-
-namespace SoundIOSharp
-{
-    public readonly struct SoundIOChannelLayout
-    {
-        public static int BuiltInCount
-        {
-            get { return Natives.soundio_channel_layout_builtin_count(); }
-        }
-
-        public static SoundIOChannelLayout GetBuiltIn(int index)
-        {
-            return new SoundIOChannelLayout(Natives.soundio_channel_layout_get_builtin(index));
-        }
-
-        public static SoundIOChannelLayout GetDefault(int channelCount)
-        {
-            var handle = Natives.soundio_channel_layout_get_default(channelCount);
-
-            return new SoundIOChannelLayout (handle);
-        }
-
-        public static SoundIOChannelId ParseChannelId(string name)
-        {
-            var ptr = Marshal.StringToHGlobalAnsi(name);
-
-            try 
-            {
-                return (SoundIOChannelId)Natives.soundio_parse_channel_id(ptr, name.Length);
-            }
-            finally
-            {
-                Marshal.FreeHGlobal(ptr);
-            }
-        }
-
-        // instance members
-
-        internal SoundIOChannelLayout(Pointer<SoundIoChannelLayout> handle)
-        {
-            this.handle = handle;
-        }
-
-        readonly Pointer<SoundIoChannelLayout> handle;
-
-        public bool IsNull
-        {
-            get { return handle.Handle == IntPtr.Zero; }
-        }
-
-        internal IntPtr Handle
-        {
-            get { return handle; }
-        }
-
-        public int ChannelCount
-        {
-            get { return IsNull ? 0 : Marshal.ReadInt32((IntPtr)handle + channel_count_offset); }
-        }
-
-        static readonly int channel_count_offset = (int)Marshal.OffsetOf<SoundIoChannelLayout>("channel_count");
-
-        public string Name
-        {
-            get { return IsNull ? null : Marshal.PtrToStringAnsi(Marshal.ReadIntPtr((IntPtr)handle + name_offset)); }
-        }
-
-        static readonly int name_offset = (int)Marshal.OffsetOf<SoundIoChannelLayout>("name");
-
-        public IEnumerable<SoundIOChannelId> Channels
-        {
-            get
-            {
-                if (IsNull) yield break;
-
-                for (int i = 0; i < 24; i++)
-                {
-                    yield return (SoundIOChannelId)Marshal.ReadInt32((IntPtr)handle + channels_offset + sizeof(SoundIoChannelId) * i);
-                }
-            }
-        }
-
-        static readonly int channels_offset = (int)Marshal.OffsetOf<SoundIoChannelLayout>("channels");
-
-        public override bool Equals(object other)
-        {
-            if (!(other is SoundIOChannelLayout)) return false;
-
-            var s = (SoundIOChannelLayout) other;
-
-            return handle == s.handle || Natives.soundio_channel_layout_equal(handle, s.handle);
-        }
-
-        public override int GetHashCode()
-        {
-            return handle.GetHashCode();
-        }
-
-        public string DetectBuiltInName()
-        {
-            if (IsNull) throw new InvalidOperationException();
-
-            return Natives.soundio_channel_layout_detect_builtin(handle) ? Name : null;
-        }
-
-        public int FindChannel(SoundIOChannelId channel)
-        {
-            if (IsNull) throw new InvalidOperationException();
-
-            return Natives.soundio_channel_layout_find_channel(handle, (SoundIoChannelId)channel);
-        }
-    }
-}

+ 0 - 267
Ryujinx.Audio.Backends.SoundIo/Native/libsoundio/SoundIODevice.cs

@@ -1,267 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Runtime.InteropServices;
-
-namespace SoundIOSharp
-{
-    public class SoundIODevice
-    {
-        public static SoundIOChannelLayout BestMatchingChannelLayout(SoundIODevice device1, SoundIODevice device2)
-        {
-            var ptr1 = Marshal.ReadIntPtr(device1.handle, layouts_offset);
-            var ptr2 = Marshal.ReadIntPtr(device2.handle, layouts_offset);
-
-            return new SoundIOChannelLayout(Natives.soundio_best_matching_channel_layout(ptr1, device1.LayoutCount, ptr2, device2.LayoutCount));
-        }
-
-        internal SoundIODevice(Pointer<SoundIoDevice> handle)
-        {
-            this.handle = handle;
-        }
-
-        readonly Pointer<SoundIoDevice> handle;
-
-        // Equality (based on handle and native func)
-
-        public override bool Equals(object other)
-        {
-            var d = other as SoundIODevice;
-
-            return d != null && (this.handle == d.handle || Natives.soundio_device_equal (this.handle, d.handle));
-        }
-
-        public override int GetHashCode()
-        {
-            return (int)(IntPtr)handle;
-        }
-
-        public static bool operator == (SoundIODevice obj1, SoundIODevice obj2)
-        {
-            return obj1 is null ? obj2 is null : obj1.Equals(obj2);
-        }
-
-        public static bool operator != (SoundIODevice obj1, SoundIODevice obj2)
-        {
-            return obj1 is null ? obj2 is object : !obj1.Equals(obj2);
-        }
-
-        // fields
-
-        public SoundIODeviceAim Aim
-        {
-            get { return (SoundIODeviceAim)Marshal.ReadInt32(handle, aim_offset); }
-        }
-
-        static readonly int aim_offset = (int)Marshal.OffsetOf<SoundIoDevice>("aim");
-
-        public SoundIOFormat CurrentFormat
-        {
-            get { return (SoundIOFormat)Marshal.ReadInt32(handle, current_format_offset); }
-        }
-
-        static readonly int current_format_offset = (int)Marshal.OffsetOf<SoundIoDevice>("current_format");
-
-        public SoundIOChannelLayout CurrentLayout
-        {
-            get { return new SoundIOChannelLayout((IntPtr)handle + current_layout_offset); }
-        }
-
-        static readonly int current_layout_offset = (int)Marshal.OffsetOf<SoundIoDevice>("current_layout");
-
-        public int FormatCount
-        {
-            get { return Marshal.ReadInt32(handle, format_count_offset); }
-        }
-
-        static readonly int format_count_offset = (int)Marshal.OffsetOf<SoundIoDevice>("format_count");
-
-        public IEnumerable<SoundIOFormat> Formats
-        {
-            get
-            {
-                var ptr = Marshal.ReadIntPtr(handle, formats_offset);
-
-                for (int i = 0; i < FormatCount; i++)
-                {
-                    yield return (SoundIOFormat)Marshal.ReadInt32(ptr, i);
-                }
-            }
-        }
-
-        static readonly int formats_offset = (int)Marshal.OffsetOf<SoundIoDevice>("formats");
-
-        public string Id
-        {
-            get { return Marshal.PtrToStringAnsi(Marshal.ReadIntPtr(handle, id_offset)); }
-        }
-
-        static readonly int id_offset = (int)Marshal.OffsetOf<SoundIoDevice>("id");
-
-        public bool IsRaw
-        {
-            get { return Marshal.ReadInt32(handle, is_raw_offset) != 0; }
-        }
-
-        static readonly int is_raw_offset = (int)Marshal.OffsetOf<SoundIoDevice>("is_raw");
-
-        public int LayoutCount
-        {
-            get { return Marshal.ReadInt32(handle, layout_count_offset); }
-        }
-
-        static readonly int layout_count_offset = (int)Marshal.OffsetOf<SoundIoDevice>("layout_count");
-
-        public IEnumerable<SoundIOChannelLayout> Layouts
-        {
-            get
-            {
-                var ptr = Marshal.ReadIntPtr (handle, layouts_offset);
-
-                for (int i = 0; i < LayoutCount; i++)
-                {
-                    yield return new SoundIOChannelLayout(ptr + i * Marshal.SizeOf<SoundIoChannelLayout>());
-                }
-            }
-        }
-
-        static readonly int layouts_offset = (int)Marshal.OffsetOf<SoundIoDevice>("layouts");
-
-        public string Name
-        {
-            get { return Marshal.PtrToStringAnsi(Marshal.ReadIntPtr(handle, name_offset)); }
-        }
-
-        static readonly int name_offset = (int)Marshal.OffsetOf<SoundIoDevice>("name");
-
-        public int ProbeError
-        {
-            get { return Marshal.ReadInt32(handle, probe_error_offset); }
-        }
-
-        static readonly int probe_error_offset = (int)Marshal.OffsetOf<SoundIoDevice>("probe_error");
-
-        public int ReferenceCount
-        {
-            get { return Marshal.ReadInt32(handle, ref_count_offset); }
-        }
-
-        static readonly int ref_count_offset = (int)Marshal.OffsetOf<SoundIoDevice>("ref_count");
-
-        public int SampleRateCount
-        {
-            get { return Marshal.ReadInt32(handle, sample_rate_count_offset); }
-        }
-
-        static readonly int sample_rate_count_offset = (int)Marshal.OffsetOf<SoundIoDevice>("sample_rate_count");
-
-        public IEnumerable<SoundIOSampleRateRange> SampleRates
-        {
-            get
-            {
-                var ptr = Marshal.ReadIntPtr(handle, sample_rates_offset);
-
-                for (int i = 0; i < SampleRateCount; i++)
-                {
-                    yield return new SoundIOSampleRateRange(Marshal.ReadInt32(ptr, i * 2), Marshal.ReadInt32(ptr, i * 2 + 1));
-                }
-            }
-        }
-
-        static readonly int sample_rates_offset = (int)Marshal.OffsetOf<SoundIoDevice>("sample_rates");
-
-        public double SoftwareLatencyCurrent
-        {
-            get { return MarshalEx.ReadDouble(handle, software_latency_current_offset); }
-            set { MarshalEx.WriteDouble(handle, software_latency_current_offset, value); }
-        }
-
-        static readonly int software_latency_current_offset = (int)Marshal.OffsetOf<SoundIoDevice>("software_latency_current");
-
-        public double SoftwareLatencyMin
-        {
-            get { return MarshalEx.ReadDouble(handle, software_latency_min_offset); }
-            set { MarshalEx.WriteDouble(handle, software_latency_min_offset, value); }
-        }
-
-        static readonly int software_latency_min_offset = (int)Marshal.OffsetOf<SoundIoDevice>("software_latency_min");
-
-        public double SoftwareLatencyMax
-        {
-            get { return MarshalEx.ReadDouble(handle, software_latency_max_offset); }
-            set { MarshalEx.WriteDouble(handle, software_latency_max_offset, value); }
-        }
-
-        static readonly int software_latency_max_offset = (int)Marshal.OffsetOf<SoundIoDevice>("software_latency_max");
-
-        public SoundIO SoundIO
-        {
-            get { return new SoundIO(Marshal.ReadIntPtr(handle, soundio_offset)); }
-        }
-
-        static readonly int soundio_offset = (int)Marshal.OffsetOf<SoundIoDevice>("soundio");
-
-        // functions
-
-        public void AddReference()
-        {
-            Natives.soundio_device_ref(handle);
-        }
-
-        public void RemoveReference()
-        {
-            Natives.soundio_device_unref(handle);
-        }
-
-        public void SortDeviceChannelLayouts()
-        {
-            Natives.soundio_device_sort_channel_layouts(handle);
-        }
-
-        public static readonly SoundIOFormat S16NE     =  BitConverter.IsLittleEndian ? SoundIOFormat.S16LE     : SoundIOFormat.S16BE;
-        public static readonly SoundIOFormat U16NE     =  BitConverter.IsLittleEndian ? SoundIOFormat.U16LE     : SoundIOFormat.U16BE;
-        public static readonly SoundIOFormat S24NE     =  BitConverter.IsLittleEndian ? SoundIOFormat.S24LE     : SoundIOFormat.S24BE;
-        public static readonly SoundIOFormat U24NE     =  BitConverter.IsLittleEndian ? SoundIOFormat.U24LE     : SoundIOFormat.U24BE;
-        public static readonly SoundIOFormat S32NE     =  BitConverter.IsLittleEndian ? SoundIOFormat.S32LE     : SoundIOFormat.S32BE;
-        public static readonly SoundIOFormat U32NE     =  BitConverter.IsLittleEndian ? SoundIOFormat.U32LE     : SoundIOFormat.U32BE;
-        public static readonly SoundIOFormat Float32NE =  BitConverter.IsLittleEndian ? SoundIOFormat.Float32LE : SoundIOFormat.Float32BE;
-        public static readonly SoundIOFormat Float64NE =  BitConverter.IsLittleEndian ? SoundIOFormat.Float64LE : SoundIOFormat.Float64BE;
-        public static readonly SoundIOFormat S16FE     = !BitConverter.IsLittleEndian ? SoundIOFormat.S16LE     : SoundIOFormat.S16BE;
-        public static readonly SoundIOFormat U16FE     = !BitConverter.IsLittleEndian ? SoundIOFormat.U16LE     : SoundIOFormat.U16BE;
-        public static readonly SoundIOFormat S24FE     = !BitConverter.IsLittleEndian ? SoundIOFormat.S24LE     : SoundIOFormat.S24BE;
-        public static readonly SoundIOFormat U24FE     = !BitConverter.IsLittleEndian ? SoundIOFormat.U24LE     : SoundIOFormat.U24BE;
-        public static readonly SoundIOFormat S32FE     = !BitConverter.IsLittleEndian ? SoundIOFormat.S32LE     : SoundIOFormat.S32BE;
-        public static readonly SoundIOFormat U32FE     = !BitConverter.IsLittleEndian ? SoundIOFormat.U32LE     : SoundIOFormat.U32BE;
-        public static readonly SoundIOFormat Float32FE = !BitConverter.IsLittleEndian ? SoundIOFormat.Float32LE : SoundIOFormat.Float32BE;
-        public static readonly SoundIOFormat Float64FE = !BitConverter.IsLittleEndian ? SoundIOFormat.Float64LE : SoundIOFormat.Float64BE;
-
-        public bool SupportsFormat(SoundIOFormat format)
-        {
-            return Natives.soundio_device_supports_format(handle, (SoundIoFormat)format);
-        }
-
-        public bool SupportsSampleRate(int sampleRate)
-        {
-            return Natives.soundio_device_supports_sample_rate(handle, sampleRate);
-        }
-
-        public bool SupportsChannelCount(int channelCount)
-        {
-            return Natives.soundio_device_supports_layout(handle, SoundIOChannelLayout.GetDefault(channelCount).Handle);
-        }
-
-        public int GetNearestSampleRate(int sampleRate)
-        {
-            return Natives.soundio_device_nearest_sample_rate(handle, sampleRate);
-        }
-
-        public SoundIOInStream CreateInStream()
-        {
-            return new SoundIOInStream(Natives.soundio_instream_create(handle));
-        }
-
-        public SoundIOOutStream CreateOutStream()
-        {
-            return new SoundIOOutStream(Natives.soundio_outstream_create(handle));
-        }
-    }
-}

+ 0 - 8
Ryujinx.Audio.Backends.SoundIo/Native/libsoundio/SoundIODeviceAim.cs

@@ -1,8 +0,0 @@
-namespace SoundIOSharp
-{
-    public enum SoundIODeviceAim // soundio.h (228, 6)
-    {
-        Input,
-        Output
-    }
-}

+ 0 - 10
Ryujinx.Audio.Backends.SoundIo/Native/libsoundio/SoundIOException.cs

@@ -1,10 +0,0 @@
-using System;
-using System.Runtime.InteropServices;
-
-namespace SoundIOSharp
-{
-    public class SoundIOException : Exception
-    {
-        internal SoundIOException(SoundIoError errorCode) : base (Marshal.PtrToStringAnsi(Natives.soundio_strerror((int) errorCode))) { }
-    }
-}

+ 0 - 25
Ryujinx.Audio.Backends.SoundIo/Native/libsoundio/SoundIOFormat.cs

@@ -1,25 +0,0 @@
-namespace SoundIOSharp
-{
-    public enum SoundIOFormat
-	{
-		Invalid,
-		S8,
-		U8,
-		S16LE,
-		S16BE,
-		U16LE,
-		U16BE,
-		S24LE,
-		S24BE,
-		U24LE,
-		U24BE,
-		S32LE,
-		S32BE,
-		U32LE,
-		U32BE,
-		Float32LE,
-		Float32BE,
-		Float64LE,
-		Float64BE
-	}
-}

+ 0 - 293
Ryujinx.Audio.Backends.SoundIo/Native/libsoundio/SoundIOInStream.cs

@@ -1,293 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Runtime.InteropServices;
-
-namespace SoundIOSharp
-{
-    public class SoundIOInStream : IDisposable
-    {
-        internal SoundIOInStream(Pointer<SoundIoInStream> handle)
-        {
-            this.handle = handle;
-        }
-
-        Pointer<SoundIoInStream> handle;
-
-        public void Dispose()
-        {
-            Natives.soundio_instream_destroy(handle);
-        }
-
-        // Equality (based on handle)
-
-        public override bool Equals(object other)
-        {
-            var d = other as SoundIOInStream;
-
-            return d != null && (this.handle == d.handle);
-        }
-
-        public override int GetHashCode()
-        {
-            return (int)(IntPtr)handle;
-        }
-
-        public static bool operator == (SoundIOInStream obj1, SoundIOInStream obj2)
-        {
-            return obj1 is null ? obj2 is null : obj1.Equals(obj2);
-        }
-
-        public static bool operator != (SoundIOInStream obj1, SoundIOInStream obj2)
-        {
-            return obj1 is null ? obj2 is object : !obj1.Equals(obj2);
-        }
-
-        // fields
-
-        public SoundIODevice Device
-        {
-            get { return new SoundIODevice(Marshal.ReadIntPtr(handle, device_offset)); }
-        }
-
-        static readonly int device_offset = (int)Marshal.OffsetOf<SoundIoInStream>("device");
-
-        public SoundIOFormat Format
-        {
-            get { return (SoundIOFormat)Marshal.ReadInt32(handle, format_offset); }
-            set { Marshal.WriteInt32(handle, format_offset, (int) value); }
-        }
-
-        static readonly int format_offset = (int)Marshal.OffsetOf<SoundIoInStream>("format");
-
-        public int SampleRate
-        {
-            get { return Marshal.ReadInt32(handle, sample_rate_offset); }
-            set { Marshal.WriteInt32(handle, sample_rate_offset, value); }
-        }
-
-        static readonly int sample_rate_offset = (int)Marshal.OffsetOf<SoundIoInStream>("sample_rate");
-
-        public SoundIOChannelLayout Layout
-        {
-            get { return new SoundIOChannelLayout ((IntPtr) handle + layout_offset); }
-            set 
-            {
-                unsafe
-                {
-                    Buffer.MemoryCopy((void*)((IntPtr)handle + layout_offset), (void*)value.Handle, Marshal.SizeOf<SoundIoChannelLayout>(), Marshal.SizeOf<SoundIoChannelLayout>());
-                }
-            }
-        }
-
-        static readonly int layout_offset = (int)Marshal.OffsetOf<SoundIoInStream>("layout");
-
-        public double SoftwareLatency
-        {
-            get { return MarshalEx.ReadDouble(handle, software_latency_offset); }
-            set { MarshalEx.WriteDouble(handle, software_latency_offset, value); }
-        }
-
-        static readonly int software_latency_offset = (int)Marshal.OffsetOf<SoundIoInStream>("software_latency");
-
-        // error_callback
-        public Action ErrorCallback
-        {
-            get { return error_callback; }
-            set
-            {
-                error_callback = value;
-                error_callback_native = _ => error_callback();
-
-                var ptr = Marshal.GetFunctionPointerForDelegate(error_callback_native);
-
-                Marshal.WriteIntPtr(handle, error_callback_offset, ptr);
-            }
-        }
-
-        static readonly int error_callback_offset = (int)Marshal.OffsetOf<SoundIoInStream>("error_callback");
-
-        Action error_callback;
-        delegate void error_callback_delegate(IntPtr handle);
-        error_callback_delegate error_callback_native;
-
-        // read_callback
-        public Action<int,int> ReadCallback
-        {
-            get { return read_callback; }
-            set
-            {
-                read_callback = value;
-                read_callback_native = (_, minFrameCount, maxFrameCount) => read_callback(minFrameCount, maxFrameCount);
-
-                var ptr = Marshal.GetFunctionPointerForDelegate(read_callback_native);
-
-                Marshal.WriteIntPtr(handle, read_callback_offset, ptr);
-            }
-        }
-
-        static readonly int read_callback_offset = (int)Marshal.OffsetOf<SoundIoInStream>("read_callback");
-
-        Action<int, int> read_callback;
-        delegate void read_callback_delegate(IntPtr handle, int min, int max);
-        read_callback_delegate read_callback_native;
-
-        // overflow_callback
-        public Action OverflowCallback
-        {
-            get { return overflow_callback; }
-            set
-            {
-                overflow_callback = value;
-                overflow_callback_native = _ => overflow_callback();
-
-                var ptr = Marshal.GetFunctionPointerForDelegate(overflow_callback_native);
-
-                Marshal.WriteIntPtr(handle, overflow_callback_offset, ptr);
-            }
-        }
-        static readonly int overflow_callback_offset = (int)Marshal.OffsetOf<SoundIoInStream>("overflow_callback");
-
-        Action overflow_callback;
-        delegate void overflow_callback_delegate(IntPtr handle);
-        overflow_callback_delegate overflow_callback_native;
-
-        // FIXME: this should be taken care in more centralized/decent manner... we don't want to write
-        // this kind of code anywhere we need string marshaling.
-        List<IntPtr> allocated_hglobals = new List<IntPtr>();
-
-        public string Name
-        {
-            get { return Marshal.PtrToStringAnsi(Marshal.ReadIntPtr(handle, name_offset)); }
-            set
-            {
-                unsafe
-                {
-                    var existing = Marshal.ReadIntPtr(handle, name_offset);
-                    if (allocated_hglobals.Contains(existing))
-                    {
-                        allocated_hglobals.Remove(existing);
-                        Marshal.FreeHGlobal(existing);
-                    }
-
-                    var ptr = Marshal.StringToHGlobalAnsi(value);
-                    Marshal.WriteIntPtr(handle, name_offset, ptr);
-                    allocated_hglobals.Add(ptr);
-                }
-            }
-        }
-
-        static readonly int name_offset = (int)Marshal.OffsetOf<SoundIoInStream>("name");
-
-        public bool NonTerminalHint
-        {
-            get { return Marshal.ReadInt32(handle, non_terminal_hint_offset) != 0; }
-        }
-
-        static readonly int non_terminal_hint_offset = (int)Marshal.OffsetOf<SoundIoInStream>("non_terminal_hint");
-
-        public int BytesPerFrame
-        {
-            get { return Marshal.ReadInt32(handle, bytes_per_frame_offset); }
-        }
-
-        static readonly int bytes_per_frame_offset = (int)Marshal.OffsetOf<SoundIoInStream>("bytes_per_frame");
-
-        public int BytesPerSample
-        {
-            get { return Marshal.ReadInt32(handle, bytes_per_sample_offset); }
-        }
-
-        static readonly int bytes_per_sample_offset = (int)Marshal.OffsetOf<SoundIoInStream>("bytes_per_sample");
-
-        public string LayoutErrorMessage
-        {
-            get 
-            {
-                var code = (SoundIoError)Marshal.ReadInt32(handle, layout_error_offset);
-
-                return code == SoundIoError.SoundIoErrorNone ? null : Marshal.PtrToStringAnsi(Natives.soundio_strerror((int)code));
-            }
-        }
-
-        static readonly int layout_error_offset = (int)Marshal.OffsetOf<SoundIoInStream>("layout_error");
-
-        // functions
-
-        public void Open()
-        {
-            var ret = (SoundIoError)Natives.soundio_instream_open(handle);
-            if (ret != SoundIoError.SoundIoErrorNone)
-            {
-                throw new SoundIOException(ret);
-            }
-        }
-
-        public void Start()
-        {
-            var ret = (SoundIoError)Natives.soundio_instream_start(handle);
-            if (ret != SoundIoError.SoundIoErrorNone)
-            {
-                throw new SoundIOException(ret);
-            }
-        }
-
-        public SoundIOChannelAreas BeginRead(ref int frameCount)
-        {
-            IntPtr ptrs             = default;
-            int    nativeFrameCount = frameCount;
-
-            unsafe
-            {
-                var frameCountPtr = &nativeFrameCount;
-                var ptrptr        = &ptrs;
-                var ret           = (SoundIoError)Natives.soundio_instream_begin_read(handle, (IntPtr)ptrptr, (IntPtr)frameCountPtr);
-
-                frameCount = *frameCountPtr;
-
-                if (ret != SoundIoError.SoundIoErrorNone)
-                {
-                    throw new SoundIOException(ret);
-                }
-
-                return new SoundIOChannelAreas(ptrs, Layout.ChannelCount, frameCount);
-            }
-        }
-
-        public void EndRead()
-        {
-            var ret = (SoundIoError)Natives.soundio_instream_end_read(handle);
-            if (ret != SoundIoError.SoundIoErrorNone)
-            {
-                throw new SoundIOException(ret);
-            }
-        }
-
-        public void Pause(bool pause)
-        {
-            var ret = (SoundIoError)Natives.soundio_instream_pause(handle, pause);
-            if (ret != SoundIoError.SoundIoErrorNone)
-            {
-                throw new SoundIOException(ret);
-            }
-        }
-
-        public double GetLatency()
-        {
-            unsafe
-            {
-                double* dptr = null;
-                IntPtr  p    = new IntPtr(dptr);
-
-                var ret = (SoundIoError)Natives.soundio_instream_get_latency(handle, p);
-                if (ret != SoundIoError.SoundIoErrorNone)
-                {
-                    throw new SoundIOException(ret);
-                }
-
-                dptr = (double*)p;
-
-                return *dptr;
-            }
-        }
-    }
-}

+ 0 - 331
Ryujinx.Audio.Backends.SoundIo/Native/libsoundio/SoundIOOutStream.cs

@@ -1,331 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Runtime.InteropServices;
-
-namespace SoundIOSharp
-{
-    public class SoundIOOutStream : IDisposable
-    {
-        internal SoundIOOutStream (Pointer<SoundIoOutStream> handle)
-        {
-            this.handle = handle;
-        }
-
-        Pointer<SoundIoOutStream> handle;
-
-        public void Dispose ()
-        {
-            Natives.soundio_outstream_destroy (handle);
-        }
-        // Equality (based on handle)
-
-        public override bool Equals (object other)
-        {
-            var d = other as SoundIOOutStream;
-
-            return d != null && (this.handle == d.handle);
-        }
-
-        public override int GetHashCode ()
-        {
-            return (int)(IntPtr)handle;
-        }
-
-        public static bool operator == (SoundIOOutStream obj1, SoundIOOutStream obj2)
-        {
-            return obj1 is null ? obj2 is null : obj1.Equals(obj2);
-        }
-
-        public static bool operator != (SoundIOOutStream obj1, SoundIOOutStream obj2)
-        {
-            return obj1 is null ? obj2 is object : !obj1.Equals(obj2);
-        }
-
-        // fields
-
-        public SoundIODevice Device
-        {
-            get { return new SoundIODevice(Marshal.ReadIntPtr(handle, device_offset)); }
-        }
-
-        static readonly int device_offset = (int)Marshal.OffsetOf<SoundIoOutStream>("device");
-
-        public SoundIOFormat Format
-        {
-            get { return (SoundIOFormat) Marshal.ReadInt32(handle, format_offset); }
-            set { Marshal.WriteInt32(handle, format_offset, (int) value); }
-        }
-
-        static readonly int format_offset = (int)Marshal.OffsetOf<SoundIoOutStream>("format");
-
-        public int SampleRate
-        {
-            get { return Marshal.ReadInt32(handle, sample_rate_offset); }
-            set { Marshal.WriteInt32(handle, sample_rate_offset, value); }
-        }
-
-        static readonly int sample_rate_offset = (int)Marshal.OffsetOf<SoundIoOutStream>("sample_rate");
-
-        public SoundIOChannelLayout Layout
-        {
-            get { unsafe { return new SoundIOChannelLayout((IntPtr) (void*)((IntPtr)handle + layout_offset)); } }
-            set
-            {
-                unsafe
-                {
-                    Buffer.MemoryCopy((void*)value.Handle, (void*)((IntPtr)handle + layout_offset), Marshal.SizeOf<SoundIoChannelLayout>(), Marshal.SizeOf<SoundIoChannelLayout>());
-                }
-            }
-        }
-        static readonly int layout_offset = (int)Marshal.OffsetOf<SoundIoOutStream>("layout");
-
-        public double SoftwareLatency
-        {
-            get { return MarshalEx.ReadDouble (handle, software_latency_offset); }
-            set { MarshalEx.WriteDouble (handle, software_latency_offset, value); }
-        }
-
-        static readonly int software_latency_offset = (int)Marshal.OffsetOf<SoundIoOutStream>("software_latency");
-
-        public float Volume
-        {
-            get { return MarshalEx.ReadFloat(handle, volume_offset); }
-            set { MarshalEx.WriteFloat(handle, volume_offset, value); }
-        }
-
-        static readonly int volume_offset = (int)Marshal.OffsetOf<SoundIoOutStream>("volume");
-
-        // error_callback
-        public Action ErrorCallback
-        {
-            get { return error_callback; }
-            set
-            {
-                error_callback = value;
-                if (value == null)
-                {
-                    error_callback_native = null;
-                }
-                else
-                {
-                    error_callback_native = stream => error_callback();
-                }
-
-                var ptr = Marshal.GetFunctionPointerForDelegate(error_callback_native);
-                Marshal.WriteIntPtr(handle, error_callback_offset, ptr);
-            }
-        }
-
-        static readonly int error_callback_offset = (int)Marshal.OffsetOf<SoundIoOutStream>("error_callback");
-
-        Action error_callback;
-        delegate void error_callback_delegate (IntPtr handle);
-        error_callback_delegate error_callback_native;
-
-        // write_callback
-        public Action<int, int> WriteCallback
-        {
-            get { return write_callback; }
-            set
-            {
-                write_callback = value;
-                if (value == null)
-                {
-                    write_callback_native = null;
-                }
-                else
-                {
-                    write_callback_native = (h, frame_count_min, frame_count_max) => write_callback(frame_count_min, frame_count_max);
-                }
-
-                var ptr = Marshal.GetFunctionPointerForDelegate (write_callback_native);
-                Marshal.WriteIntPtr (handle, write_callback_offset, ptr);
-            }
-        }
-
-        static readonly int write_callback_offset = (int)Marshal.OffsetOf<SoundIoOutStream>("write_callback");
-
-        Action<int, int> write_callback;
-        delegate void write_callback_delegate(IntPtr handle, int min, int max);
-        write_callback_delegate write_callback_native;
-
-        // underflow_callback
-        public Action UnderflowCallback
-        {
-            get { return underflow_callback; }
-            set
-            {
-                underflow_callback = value;
-                if (value == null)
-                {
-                    underflow_callback_native = null;
-                }
-                else
-                {
-                    underflow_callback_native = h => underflow_callback();
-                }
-
-                var ptr = Marshal.GetFunctionPointerForDelegate (underflow_callback_native);
-                Marshal.WriteIntPtr (handle, underflow_callback_offset, ptr);
-            }
-        }
-
-        static readonly int underflow_callback_offset = (int)Marshal.OffsetOf<SoundIoOutStream>("underflow_callback");
-        
-        Action underflow_callback;
-        delegate void underflow_callback_delegate(IntPtr handle);
-        underflow_callback_delegate underflow_callback_native;
-
-        // FIXME: this should be taken care in more centralized/decent manner... we don't want to write
-        // this kind of code anywhere we need string marshaling.
-        List<IntPtr> allocated_hglobals = new List<IntPtr>();
-
-        public string Name {
-            get { return Marshal.PtrToStringAnsi(Marshal.ReadIntPtr(handle, name_offset)); }
-            set
-            {
-                unsafe
-                {
-                    var existing = Marshal.ReadIntPtr(handle, name_offset);
-                    if (allocated_hglobals.Contains(existing))
-                    {
-                        allocated_hglobals.Remove(existing);
-                        Marshal.FreeHGlobal(existing);
-                    }
-
-                    var ptr = Marshal.StringToHGlobalAnsi(value);
-                    Marshal.WriteIntPtr(handle, name_offset, ptr);
-                    allocated_hglobals.Add(ptr);
-                }
-            }
-        }
-
-        static readonly int name_offset = (int)Marshal.OffsetOf<SoundIoOutStream>("name");
-
-        public bool NonTerminalHint
-        {
-            get { return Marshal.ReadInt32(handle, non_terminal_hint_offset) != 0; }
-        }
-
-        static readonly int non_terminal_hint_offset = (int)Marshal.OffsetOf<SoundIoOutStream>("non_terminal_hint");
-
-        public int BytesPerFrame
-        {
-            get { return Marshal.ReadInt32(handle, bytes_per_frame_offset); }
-        }
-
-        static readonly int bytes_per_frame_offset = (int)Marshal.OffsetOf<SoundIoOutStream>("bytes_per_frame");
-
-        public int BytesPerSample
-        {
-            get { return Marshal.ReadInt32(handle, bytes_per_sample_offset); }
-        }
-
-        static readonly int bytes_per_sample_offset = (int)Marshal.OffsetOf<SoundIoOutStream>("bytes_per_sample");
-
-        public string LayoutErrorMessage
-        {
-            get
-            {
-                var code = (SoundIoError)Marshal.ReadInt32(handle, layout_error_offset);
-
-                return code == SoundIoError.SoundIoErrorNone ? null : Marshal.PtrToStringAnsi(Natives.soundio_strerror((int)code));
-            }
-        }
-
-        static readonly int layout_error_offset = (int)Marshal.OffsetOf<SoundIoOutStream> ("layout_error");
-
-        // functions
-
-        public void Open ()
-        {
-            var ret = (SoundIoError)Natives.soundio_outstream_open(handle);
-            if (ret != SoundIoError.SoundIoErrorNone)
-            {
-                throw new SoundIOException(ret);
-            }
-        }
-
-        public void Start ()
-        {
-            var ret = (SoundIoError)Natives.soundio_outstream_start(handle);
-            if (ret != SoundIoError.SoundIoErrorNone)
-            {
-                throw new SoundIOException(ret);
-            }
-        }
-
-        public SoundIOChannelAreas BeginWrite(ref int frameCount)
-        {
-            IntPtr ptrs             = default;
-            int    nativeFrameCount = frameCount;
-
-            unsafe
-            {
-                var frameCountPtr = &nativeFrameCount;
-                var ptrptr        = &ptrs;
-                var ret           = (SoundIoError)Natives.soundio_outstream_begin_write(handle, (IntPtr)ptrptr, (IntPtr)frameCountPtr);
-
-                frameCount = *frameCountPtr;
-
-                if (ret != SoundIoError.SoundIoErrorNone)
-                {
-                    throw new SoundIOException(ret);
-                }
-
-                return new SoundIOChannelAreas(ptrs, Layout.ChannelCount, frameCount);
-            }
-        }
-
-        public void EndWrite ()
-        {
-            var ret = (SoundIoError)Natives.soundio_outstream_end_write(handle);
-            if (ret != SoundIoError.SoundIoErrorNone)
-            {
-                throw new SoundIOException(ret);
-            }
-        }
-
-        public void ClearBuffer ()
-        {
-            _ = Natives.soundio_outstream_clear_buffer(handle);
-        }
-
-        public void Pause (bool pause)
-        {
-            var ret = (SoundIoError)Natives.soundio_outstream_pause(handle, pause);
-            if (ret != SoundIoError.SoundIoErrorNone)
-            {
-                throw new SoundIOException(ret);
-            }
-        }
-
-        public double GetLatency ()
-        {
-            unsafe
-            {
-                double* dptr = null;
-                IntPtr  p    = new IntPtr(dptr);
-
-                var ret = (SoundIoError)Natives.soundio_outstream_get_latency(handle, p);
-                if (ret != SoundIoError.SoundIoErrorNone)
-                {
-                    throw new SoundIOException(ret);
-                }
-
-                dptr = (double*)p;
-
-                return *dptr;
-            }
-        }
-
-        public void SetVolume (double volume)
-        {
-            var ret = (SoundIoError)Natives.soundio_outstream_set_volume(handle, volume);
-            if (ret != SoundIoError.SoundIoErrorNone)
-            {
-                throw new SoundIOException(ret);
-            }
-        }
-    }
-}

+ 0 - 58
Ryujinx.Audio.Backends.SoundIo/Native/libsoundio/SoundIORingBuffer.cs

@@ -1,58 +0,0 @@
-using System;
-namespace SoundIOSharp
-{
-    public class SoundIORingBuffer : IDisposable
-    {
-        internal SoundIORingBuffer(IntPtr handle)
-        {
-            this.handle = handle;
-        }
-
-        IntPtr handle;
-
-        public int Capacity
-        {
-            get { return Natives.soundio_ring_buffer_capacity(handle); }
-        }
-
-        public void Clear()
-        {
-            Natives.soundio_ring_buffer_clear(handle);
-        }
-
-        public void Dispose()
-        {
-            Natives.soundio_ring_buffer_destroy(handle);
-        }
-
-        public int FillCount
-        {
-            get { return Natives.soundio_ring_buffer_fill_count(handle); }
-        }
-
-        public int FreeCount
-        {
-            get { return Natives.soundio_ring_buffer_free_count(handle); }
-        }
-
-        public IntPtr ReadPointer
-        {
-            get { return Natives.soundio_ring_buffer_read_ptr(handle); }
-        }
-
-        public IntPtr WritePointer
-        {
-            get { return Natives.soundio_ring_buffer_write_ptr(handle); }
-        }
-
-        public void AdvanceReadPointer(int count)
-        {
-            Natives.soundio_ring_buffer_advance_read_ptr(handle, count);
-        }
-
-        public void AdvanceWritePointer(int count)
-        {
-            Natives.soundio_ring_buffer_advance_write_ptr(handle, count);
-        }
-    }
-}

+ 0 - 14
Ryujinx.Audio.Backends.SoundIo/Native/libsoundio/SoundIOSampleRateRange.cs

@@ -1,14 +0,0 @@
-namespace SoundIOSharp
-{
-    public readonly struct SoundIOSampleRateRange
-    {
-        internal SoundIOSampleRateRange(int min, int max)
-        {
-            Min = min;
-            Max = max;
-        }
-
-        public readonly int Min;
-        public readonly int Max;
-    }
-}

+ 0 - 643
Ryujinx.Audio.Backends.SoundIo/Native/libsoundio/libsoundio-interop.cs

@@ -1,643 +0,0 @@
-// This source file is generated by nclang PInvokeGenerator.
-using System;
-using System.Runtime.InteropServices;
-using delegate0 = SoundIOSharp.Delegates.delegate0;
-using delegate1 = SoundIOSharp.Delegates.delegate1;
-using delegate2 = SoundIOSharp.Delegates.delegate2;
-using delegate3 = SoundIOSharp.Delegates.delegate3;
-using delegate4 = SoundIOSharp.Delegates.delegate4;
-using delegate5 = SoundIOSharp.Delegates.delegate5;
-using delegate6 = SoundIOSharp.Delegates.delegate6;
-using delegate7 = SoundIOSharp.Delegates.delegate7;
-using delegate8 = SoundIOSharp.Delegates.delegate8;
-using delegate9 = SoundIOSharp.Delegates.delegate9;
-
-namespace SoundIOSharp
-{
-    enum SoundIoError // soundio.h (72, 6)
-    {
-        SoundIoErrorNone = 0,
-        SoundIoErrorNoMem = 1,
-        SoundIoErrorInitAudioBackend = 2,
-        SoundIoErrorSystemResources = 3,
-        SoundIoErrorOpeningDevice = 4,
-        SoundIoErrorNoSuchDevice = 5,
-        SoundIoErrorInvalid = 6,
-        SoundIoErrorBackendUnavailable = 7,
-        SoundIoErrorStreaming = 8,
-        SoundIoErrorIncompatibleDevice = 9,
-        SoundIoErrorNoSuchClient = 10,
-        SoundIoErrorIncompatibleBackend = 11,
-        SoundIoErrorBackendDisconnected = 12,
-        SoundIoErrorInterrupted = 13,
-        SoundIoErrorUnderflow = 14,
-        SoundIoErrorEncodingString = 15,
-    }
-
-    enum SoundIoChannelId // soundio.h (106, 6)
-    {
-        SoundIoChannelIdInvalid = 0,
-        SoundIoChannelIdFrontLeft = 1,
-        SoundIoChannelIdFrontRight = 2,
-        SoundIoChannelIdFrontCenter = 3,
-        SoundIoChannelIdLfe = 4,
-        SoundIoChannelIdBackLeft = 5,
-        SoundIoChannelIdBackRight = 6,
-        SoundIoChannelIdFrontLeftCenter = 7,
-        SoundIoChannelIdFrontRightCenter = 8,
-        SoundIoChannelIdBackCenter = 9,
-        SoundIoChannelIdSideLeft = 10,
-        SoundIoChannelIdSideRight = 11,
-        SoundIoChannelIdTopCenter = 12,
-        SoundIoChannelIdTopFrontLeft = 13,
-        SoundIoChannelIdTopFrontCenter = 14,
-        SoundIoChannelIdTopFrontRight = 15,
-        SoundIoChannelIdTopBackLeft = 16,
-        SoundIoChannelIdTopBackCenter = 17,
-        SoundIoChannelIdTopBackRight = 18,
-        SoundIoChannelIdBackLeftCenter = 19,
-        SoundIoChannelIdBackRightCenter = 20,
-        SoundIoChannelIdFrontLeftWide = 21,
-        SoundIoChannelIdFrontRightWide = 22,
-        SoundIoChannelIdFrontLeftHigh = 23,
-        SoundIoChannelIdFrontCenterHigh = 24,
-        SoundIoChannelIdFrontRightHigh = 25,
-        SoundIoChannelIdTopFrontLeftCenter = 26,
-        SoundIoChannelIdTopFrontRightCenter = 27,
-        SoundIoChannelIdTopSideLeft = 28,
-        SoundIoChannelIdTopSideRight = 29,
-        SoundIoChannelIdLeftLfe = 30,
-        SoundIoChannelIdRightLfe = 31,
-        SoundIoChannelIdLfe2 = 32,
-        SoundIoChannelIdBottomCenter = 33,
-        SoundIoChannelIdBottomLeftCenter = 34,
-        SoundIoChannelIdBottomRightCenter = 35,
-        SoundIoChannelIdMsMid = 36,
-        SoundIoChannelIdMsSide = 37,
-        SoundIoChannelIdAmbisonicW = 38,
-        SoundIoChannelIdAmbisonicX = 39,
-        SoundIoChannelIdAmbisonicY = 40,
-        SoundIoChannelIdAmbisonicZ = 41,
-        SoundIoChannelIdXyX = 42,
-        SoundIoChannelIdXyY = 43,
-        SoundIoChannelIdHeadphonesLeft = 44,
-        SoundIoChannelIdHeadphonesRight = 45,
-        SoundIoChannelIdClickTrack = 46,
-        SoundIoChannelIdForeignLanguage = 47,
-        SoundIoChannelIdHearingImpaired = 48,
-        SoundIoChannelIdNarration = 49,
-        SoundIoChannelIdHaptic = 50,
-        SoundIoChannelIdDialogCentricMix = 51,
-        SoundIoChannelIdAux = 52,
-        SoundIoChannelIdAux0 = 53,
-        SoundIoChannelIdAux1 = 54,
-        SoundIoChannelIdAux2 = 55,
-        SoundIoChannelIdAux3 = 56,
-        SoundIoChannelIdAux4 = 57,
-        SoundIoChannelIdAux5 = 58,
-        SoundIoChannelIdAux6 = 59,
-        SoundIoChannelIdAux7 = 60,
-        SoundIoChannelIdAux8 = 61,
-        SoundIoChannelIdAux9 = 62,
-        SoundIoChannelIdAux10 = 63,
-        SoundIoChannelIdAux11 = 64,
-        SoundIoChannelIdAux12 = 65,
-        SoundIoChannelIdAux13 = 66,
-        SoundIoChannelIdAux14 = 67,
-        SoundIoChannelIdAux15 = 68,
-    }
-
-    enum SoundIoChannelLayoutId // soundio.h (189, 6)
-    {
-        SoundIoChannelLayoutIdMono = 0,
-        SoundIoChannelLayoutIdStereo = 1,
-        SoundIoChannelLayoutId2Point1 = 2,
-        SoundIoChannelLayoutId3Point0 = 3,
-        SoundIoChannelLayoutId3Point0Back = 4,
-        SoundIoChannelLayoutId3Point1 = 5,
-        SoundIoChannelLayoutId4Point0 = 6,
-        SoundIoChannelLayoutIdQuad = 7,
-        SoundIoChannelLayoutIdQuadSide = 8,
-        SoundIoChannelLayoutId4Point1 = 9,
-        SoundIoChannelLayoutId5Point0Back = 10,
-        SoundIoChannelLayoutId5Point0Side = 11,
-        SoundIoChannelLayoutId5Point1 = 12,
-        SoundIoChannelLayoutId5Point1Back = 13,
-        SoundIoChannelLayoutId6Point0Side = 14,
-        SoundIoChannelLayoutId6Point0Front = 15,
-        SoundIoChannelLayoutIdHexagonal = 16,
-        SoundIoChannelLayoutId6Point1 = 17,
-        SoundIoChannelLayoutId6Point1Back = 18,
-        SoundIoChannelLayoutId6Point1Front = 19,
-        SoundIoChannelLayoutId7Point0 = 20,
-        SoundIoChannelLayoutId7Point0Front = 21,
-        SoundIoChannelLayoutId7Point1 = 22,
-        SoundIoChannelLayoutId7Point1Wide = 23,
-        SoundIoChannelLayoutId7Point1WideBack = 24,
-        SoundIoChannelLayoutIdOctagonal = 25,
-    }
-
-    enum SoundIoBackend // soundio.h (218, 6)
-    {
-        SoundIoBackendNone = 0,
-        SoundIoBackendJack = 1,
-        SoundIoBackendPulseAudio = 2,
-        SoundIoBackendAlsa = 3,
-        SoundIoBackendCoreAudio = 4,
-        SoundIoBackendWasapi = 5,
-        SoundIoBackendDummy = 6,
-    }
-
-    enum SoundIoDeviceAim // soundio.h (228, 6)
-    {
-        SoundIoDeviceAimInput = 0,
-        SoundIoDeviceAimOutput = 1,
-    }
-
-    enum SoundIoFormat // soundio.h (235, 6)
-    {
-        SoundIoFormatInvalid = 0,
-        SoundIoFormatS8 = 1,
-        SoundIoFormatU8 = 2,
-        SoundIoFormatS16LE = 3,
-        SoundIoFormatS16BE = 4,
-        SoundIoFormatU16LE = 5,
-        SoundIoFormatU16BE = 6,
-        SoundIoFormatS24LE = 7,
-        SoundIoFormatS24BE = 8,
-        SoundIoFormatU24LE = 9,
-        SoundIoFormatU24BE = 10,
-        SoundIoFormatS32LE = 11,
-        SoundIoFormatS32BE = 12,
-        SoundIoFormatU32LE = 13,
-        SoundIoFormatU32BE = 14,
-        SoundIoFormatFloat32LE = 15,
-        SoundIoFormatFloat32BE = 16,
-        SoundIoFormatFloat64LE = 17,
-        SoundIoFormatFloat64BE = 18,
-    }
-
-    [StructLayout(LayoutKind.Sequential)]
-    struct SoundIoChannelLayout // soundio.h (306, 8)
-    {
-        [CTypeDetails("Pointer<byte>")] public System.IntPtr @name;
-        public int @channel_count;
-        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 24)]
-        [CTypeDetails("ConstArrayOf<SoundIoChannelId>")] public SoundIoChannelId[] @channels;
-    }
-
-    [StructLayout(LayoutKind.Sequential)]
-    struct SoundIoSampleRateRange // soundio.h (313, 8)
-    {
-        public int @min;
-        public int @max;
-    }
-
-    [StructLayout(LayoutKind.Sequential)]
-    struct SoundIoChannelArea // soundio.h (319, 8)
-    {
-        [CTypeDetails("Pointer<byte>")] public System.IntPtr @ptr;
-        public int @step;
-    }
-
-    [StructLayout(LayoutKind.Sequential)]
-    struct SoundIo // soundio.h (328, 8)
-    {
-        [CTypeDetails("Pointer<void>")] public System.IntPtr @userdata;
-        [CTypeDetails("Pointer<void (SoundIo *)>")] public delegate0 @on_devices_change;
-        [CTypeDetails("Pointer<void (SoundIo *, int)>")] public delegate1 @on_backend_disconnect;
-        [CTypeDetails("Pointer<void (SoundIo *)>")] public Delegates.delegate0 @on_events_signal;
-        public SoundIoBackend @current_backend;
-        [CTypeDetails("Pointer<byte>")] public System.IntPtr @app_name;
-        [CTypeDetails("Pointer<void ()>")] public delegate2 @emit_rtprio_warning;
-        [CTypeDetails("Pointer<void (const char *)>")] public delegate3 @jack_info_callback;
-        [CTypeDetails("Pointer<void (const char *)>")] public Delegates.delegate3 @jack_error_callback;
-    }
-
-    [StructLayout(LayoutKind.Sequential)]
-    struct SoundIoDevice // soundio.h (387, 8)
-    {
-        [CTypeDetails("Pointer<SoundIo>")] public System.IntPtr @soundio;
-        [CTypeDetails("Pointer<byte>")] public System.IntPtr @id;
-        [CTypeDetails("Pointer<byte>")] public System.IntPtr @name;
-        public SoundIoDeviceAim @aim;
-        [CTypeDetails("Pointer<SoundIoChannelLayout>")] public System.IntPtr @layouts;
-        public int @layout_count;
-        public SoundIoChannelLayout @current_layout;
-        [CTypeDetails("Pointer<SoundIoFormat>")] public System.IntPtr @formats;
-        public int @format_count;
-        public SoundIoFormat @current_format;
-        [CTypeDetails("Pointer<SoundIoSampleRateRange>")] public System.IntPtr @sample_rates;
-        public int @sample_rate_count;
-        public int @sample_rate_current;
-        public double @software_latency_min;
-        public double @software_latency_max;
-        public double @software_latency_current;
-        public bool @is_raw;
-        public int @ref_count;
-        public int @probe_error;
-    }
-
-    [StructLayout(LayoutKind.Sequential)]
-    struct SoundIoOutStream // soundio.h (497, 8)
-    {
-        [CTypeDetails("Pointer<SoundIoDevice>")] public System.IntPtr @device;
-        public SoundIoFormat @format;
-        public int @sample_rate;
-        public SoundIoChannelLayout @layout;
-        public double @software_latency;
-        public float @volume;
-        [CTypeDetails("Pointer<void>")] public System.IntPtr @userdata;
-        [CTypeDetails("Pointer<void (SoundIoOutStream *, int, int)>")] public delegate4 @write_callback;
-        [CTypeDetails("Pointer<void (SoundIoOutStream *)>")] public delegate5 @underflow_callback;
-        [CTypeDetails("Pointer<void (SoundIoOutStream *, int)>")] public delegate6 @error_callback;
-        [CTypeDetails("Pointer<byte>")] public System.IntPtr @name;
-        public bool @non_terminal_hint;
-        public int @bytes_per_frame;
-        public int @bytes_per_sample;
-        public int @layout_error;
-    }
-
-    [StructLayout(LayoutKind.Sequential)]
-    struct SoundIoInStream // soundio.h (600, 8)
-    {
-        [CTypeDetails("Pointer<SoundIoDevice>")] public System.IntPtr @device;
-        public SoundIoFormat @format;
-        public int @sample_rate;
-        public SoundIoChannelLayout @layout;
-        public double @software_latency;
-        [CTypeDetails("Pointer<void>")] public System.IntPtr @userdata;
-        [CTypeDetails("Pointer<void (SoundIoInStream *, int, int)>")] public delegate7 @read_callback;
-        [CTypeDetails("Pointer<void (SoundIoInStream *)>")] public delegate8 @overflow_callback;
-        [CTypeDetails("Pointer<void (SoundIoInStream *, int)>")] public delegate9 @error_callback;
-        [CTypeDetails("Pointer<byte>")] public System.IntPtr @name;
-        public bool @non_terminal_hint;
-        public int @bytes_per_frame;
-        public int @bytes_per_sample;
-        public int @layout_error;
-    }
-
-    [StructLayout(LayoutKind.Sequential)]
-    struct SoundIoRingBuffer // soundio.h (1170, 8)
-    {
-    }
-
-    partial class Natives
-    {
-        const string LibraryName = "libsoundio";
-        // function soundio_version_string - soundio.h (682, 28)
-        [DllImport(LibraryName)]
-        internal static extern System.IntPtr soundio_version_string();
-
-        // function soundio_version_major - soundio.h (684, 20)
-        [DllImport(LibraryName)]
-        internal static extern int soundio_version_major();
-
-        // function soundio_version_minor - soundio.h (686, 20)
-        [DllImport(LibraryName)]
-        internal static extern int soundio_version_minor();
-
-        // function soundio_version_patch - soundio.h (688, 20)
-        [DllImport(LibraryName)]
-        internal static extern int soundio_version_patch();
-
-        // function soundio_create - soundio.h (694, 32)
-        [DllImport(LibraryName)]
-        internal static extern System.IntPtr soundio_create();
-
-        // function soundio_destroy - soundio.h (695, 21)
-        [DllImport(LibraryName)]
-        internal static extern void soundio_destroy([CTypeDetails("Pointer<SoundIo>")]System.IntPtr @soundio);
-
-        // function soundio_connect - soundio.h (705, 20)
-        [DllImport(LibraryName)]
-        internal static extern int soundio_connect([CTypeDetails("Pointer<SoundIo>")]System.IntPtr @soundio);
-
-        // function soundio_connect_backend - soundio.h (717, 20)
-        [DllImport(LibraryName)]
-        internal static extern int soundio_connect_backend([CTypeDetails("Pointer<SoundIo>")]System.IntPtr @soundio, SoundIoBackend @backend);
-
-        // function soundio_disconnect - soundio.h (718, 21)
-        [DllImport(LibraryName)]
-        internal static extern void soundio_disconnect([CTypeDetails("Pointer<SoundIo>")]System.IntPtr @soundio);
-
-        // function soundio_strerror - soundio.h (721, 28)
-        [DllImport(LibraryName)]
-        internal static extern System.IntPtr soundio_strerror(int @error);
-
-        // function soundio_backend_name - soundio.h (723, 28)
-        [DllImport(LibraryName)]
-        internal static extern System.IntPtr soundio_backend_name(SoundIoBackend @backend);
-
-        // function soundio_backend_count - soundio.h (726, 20)
-        [DllImport(LibraryName)]
-        internal static extern int soundio_backend_count([CTypeDetails("Pointer<SoundIo>")]System.IntPtr @soundio);
-
-        // function soundio_get_backend - soundio.h (729, 36)
-        [DllImport(LibraryName)]
-        internal static extern SoundIoBackend soundio_get_backend([CTypeDetails("Pointer<SoundIo>")]System.IntPtr @soundio, int @index);
-
-        // function soundio_have_backend - soundio.h (732, 21)
-        [DllImport(LibraryName)]
-        internal static extern bool soundio_have_backend(SoundIoBackend @backend);
-
-        // function soundio_flush_events - soundio.h (756, 21)
-        [DllImport(LibraryName)]
-        internal static extern void soundio_flush_events([CTypeDetails("Pointer<SoundIo>")]System.IntPtr @soundio);
-
-        // function soundio_wait_events - soundio.h (760, 21)
-        [DllImport(LibraryName)]
-        internal static extern void soundio_wait_events([CTypeDetails("Pointer<SoundIo>")]System.IntPtr @soundio);
-
-        // function soundio_wakeup - soundio.h (763, 21)
-        [DllImport(LibraryName)]
-        internal static extern void soundio_wakeup([CTypeDetails("Pointer<SoundIo>")]System.IntPtr @soundio);
-
-        // function soundio_force_device_scan - soundio.h (780, 21)
-        [DllImport(LibraryName)]
-        internal static extern void soundio_force_device_scan([CTypeDetails("Pointer<SoundIo>")]System.IntPtr @soundio);
-
-        // function soundio_channel_layout_equal - soundio.h (787, 21)
-        [DllImport(LibraryName)]
-        internal static extern bool soundio_channel_layout_equal([CTypeDetails("Pointer<SoundIoChannelLayout>")]System.IntPtr @a, [CTypeDetails("Pointer<SoundIoChannelLayout>")]System.IntPtr @b);
-
-        // function soundio_get_channel_name - soundio.h (791, 28)
-        [DllImport(LibraryName)]
-        internal static extern System.IntPtr soundio_get_channel_name(SoundIoChannelId @id);
-
-        // function soundio_parse_channel_id - soundio.h (795, 38)
-        [DllImport(LibraryName)]
-        internal static extern SoundIoChannelId soundio_parse_channel_id([CTypeDetails("Pointer<byte>")]System.IntPtr @str, int @str_len);
-
-        // function soundio_channel_layout_builtin_count - soundio.h (798, 20)
-        [DllImport(LibraryName)]
-        internal static extern int soundio_channel_layout_builtin_count();
-
-        // function soundio_channel_layout_get_builtin - soundio.h (803, 51)
-        [DllImport(LibraryName)]
-        internal static extern System.IntPtr soundio_channel_layout_get_builtin(int @index);
-
-        // function soundio_channel_layout_get_default - soundio.h (806, 51)
-        [DllImport(LibraryName)]
-        internal static extern System.IntPtr soundio_channel_layout_get_default(int @channel_count);
-
-        // function soundio_channel_layout_find_channel - soundio.h (809, 20)
-        [DllImport(LibraryName)]
-        internal static extern int soundio_channel_layout_find_channel([CTypeDetails("Pointer<SoundIoChannelLayout>")]System.IntPtr @layout, SoundIoChannelId @channel);
-
-        // function soundio_channel_layout_detect_builtin - soundio.h (814, 21)
-        [DllImport(LibraryName)]
-        internal static extern bool soundio_channel_layout_detect_builtin([CTypeDetails("Pointer<SoundIoChannelLayout>")]System.IntPtr @layout);
-
-        // function soundio_best_matching_channel_layout - soundio.h (819, 51)
-        [DllImport(LibraryName)]
-        internal static extern System.IntPtr soundio_best_matching_channel_layout([CTypeDetails("Pointer<SoundIoChannelLayout>")]System.IntPtr @preferred_layouts, int @preferred_layout_count, [CTypeDetails("Pointer<SoundIoChannelLayout>")]System.IntPtr @available_layouts, int @available_layout_count);
-
-        // function soundio_sort_channel_layouts - soundio.h (824, 21)
-        [DllImport(LibraryName)]
-        internal static extern void soundio_sort_channel_layouts([CTypeDetails("Pointer<SoundIoChannelLayout>")]System.IntPtr @layouts, int @layout_count);
-
-        // function soundio_get_bytes_per_sample - soundio.h (830, 20)
-        [DllImport(LibraryName)]
-        internal static extern int soundio_get_bytes_per_sample(SoundIoFormat @format);
-
-        // function soundio_get_bytes_per_frame - soundio.h (833, 19)
-        [DllImport(LibraryName)]
-        internal static extern int soundio_get_bytes_per_frame(SoundIoFormat @format, int @channel_count);
-
-        // function soundio_get_bytes_per_second - soundio.h (838, 19)
-        [DllImport(LibraryName)]
-        internal static extern int soundio_get_bytes_per_second(SoundIoFormat @format, int @channel_count, int @sample_rate);
-
-        // function soundio_format_string - soundio.h (845, 29)
-        [DllImport(LibraryName)]
-        internal static extern System.IntPtr soundio_format_string(SoundIoFormat @format);
-
-        // function soundio_input_device_count - soundio.h (861, 20)
-        [DllImport(LibraryName)]
-        internal static extern int soundio_input_device_count([CTypeDetails("Pointer<SoundIo>")]System.IntPtr @soundio);
-
-        // function soundio_output_device_count - soundio.h (864, 20)
-        [DllImport(LibraryName)]
-        internal static extern int soundio_output_device_count([CTypeDetails("Pointer<SoundIo>")]System.IntPtr @soundio);
-
-        // function soundio_get_input_device - soundio.h (870, 38)
-        [DllImport(LibraryName)]
-        internal static extern System.IntPtr soundio_get_input_device([CTypeDetails("Pointer<SoundIo>")]System.IntPtr @soundio, int @index);
-
-        // function soundio_get_output_device - soundio.h (875, 38)
-        [DllImport(LibraryName)]
-        internal static extern System.IntPtr soundio_get_output_device([CTypeDetails("Pointer<SoundIo>")]System.IntPtr @soundio, int @index);
-
-        // function soundio_default_input_device_index - soundio.h (880, 20)
-        [DllImport(LibraryName)]
-        internal static extern int soundio_default_input_device_index([CTypeDetails("Pointer<SoundIo>")]System.IntPtr @soundio);
-
-        // function soundio_default_output_device_index - soundio.h (885, 20)
-        [DllImport(LibraryName)]
-        internal static extern int soundio_default_output_device_index([CTypeDetails("Pointer<SoundIo>")]System.IntPtr @soundio);
-
-        // function soundio_device_ref - soundio.h (888, 21)
-        [DllImport(LibraryName)]
-        internal static extern void soundio_device_ref([CTypeDetails("Pointer<SoundIoDevice>")]System.IntPtr @device);
-
-        // function soundio_device_unref - soundio.h (891, 21)
-        [DllImport(LibraryName)]
-        internal static extern void soundio_device_unref([CTypeDetails("Pointer<SoundIoDevice>")]System.IntPtr @device);
-
-        // function soundio_device_equal - soundio.h (895, 21)
-        [DllImport(LibraryName)]
-        internal static extern bool soundio_device_equal([CTypeDetails("Pointer<SoundIoDevice>")]System.IntPtr @a, [CTypeDetails("Pointer<SoundIoDevice>")]System.IntPtr @b);
-
-        // function soundio_device_sort_channel_layouts - soundio.h (900, 21)
-        [DllImport(LibraryName)]
-        internal static extern void soundio_device_sort_channel_layouts([CTypeDetails("Pointer<SoundIoDevice>")]System.IntPtr @device);
-
-        // function soundio_device_supports_format - soundio.h (904, 21)
-        [DllImport(LibraryName)]
-        internal static extern bool soundio_device_supports_format([CTypeDetails("Pointer<SoundIoDevice>")]System.IntPtr @device, SoundIoFormat @format);
-
-        // function soundio_device_supports_layout - soundio.h (909, 21)
-        [DllImport(LibraryName)]
-        internal static extern bool soundio_device_supports_layout([CTypeDetails("Pointer<SoundIoDevice>")]System.IntPtr @device, [CTypeDetails("Pointer<SoundIoChannelLayout>")]System.IntPtr @layout);
-
-        // function soundio_device_supports_sample_rate - soundio.h (914, 21)
-        [DllImport(LibraryName)]
-        internal static extern bool soundio_device_supports_sample_rate([CTypeDetails("Pointer<SoundIoDevice>")]System.IntPtr @device, int @sample_rate);
-
-        // function soundio_device_nearest_sample_rate - soundio.h (919, 20)
-        [DllImport(LibraryName)]
-        internal static extern int soundio_device_nearest_sample_rate([CTypeDetails("Pointer<SoundIoDevice>")]System.IntPtr @device, int @sample_rate);
-
-        // function soundio_outstream_create - soundio.h (929, 41)
-        [DllImport(LibraryName)]
-        internal static extern System.IntPtr soundio_outstream_create([CTypeDetails("Pointer<SoundIoDevice>")]System.IntPtr @device);
-
-        // function soundio_outstream_destroy - soundio.h (931, 21)
-        [DllImport(LibraryName)]
-        internal static extern void soundio_outstream_destroy([CTypeDetails("Pointer<SoundIoOutStream>")]System.IntPtr @outstream);
-
-        // function soundio_outstream_open - soundio.h (954, 20)
-        [DllImport(LibraryName)]
-        internal static extern int soundio_outstream_open([CTypeDetails("Pointer<SoundIoOutStream>")]System.IntPtr @outstream);
-
-        // function soundio_outstream_start - soundio.h (965, 20)
-        [DllImport(LibraryName)]
-        internal static extern int soundio_outstream_start([CTypeDetails("Pointer<SoundIoOutStream>")]System.IntPtr @outstream);
-
-        // function soundio_outstream_begin_write - soundio.h (997, 20)
-        [DllImport(LibraryName)]
-        internal static extern int soundio_outstream_begin_write([CTypeDetails("Pointer<SoundIoOutStream>")]System.IntPtr @outstream, [CTypeDetails("Pointer<System.IntPtr>")]System.IntPtr @areas, [CTypeDetails("Pointer<int>")]System.IntPtr @frame_count);
-
-        // function soundio_outstream_end_write - soundio.h (1009, 20)
-        [DllImport(LibraryName)]
-        internal static extern int soundio_outstream_end_write([CTypeDetails("Pointer<SoundIoOutStream>")]System.IntPtr @outstream);
-
-        // function soundio_outstream_clear_buffer - soundio.h (1024, 20)
-        [DllImport(LibraryName)]
-        internal static extern int soundio_outstream_clear_buffer([CTypeDetails("Pointer<SoundIoOutStream>")]System.IntPtr @outstream);
-
-        // function soundio_outstream_pause - soundio.h (1045, 20)
-        [DllImport(LibraryName)]
-        internal static extern int soundio_outstream_pause([CTypeDetails("Pointer<SoundIoOutStream>")]System.IntPtr @outstream, bool @pause);
-
-        // function soundio_outstream_get_latency - soundio.h (1058, 20)
-        [DllImport(LibraryName)]
-        internal static extern int soundio_outstream_get_latency([CTypeDetails("Pointer<SoundIoOutStream>")]System.IntPtr @outstream, [CTypeDetails("Pointer<double>")]System.IntPtr @out_latency);
-
-        // function soundio_outstream_set_volume - soundio.h (1061, 20)
-        [DllImport(LibraryName)]
-        internal static extern int soundio_outstream_set_volume([CTypeDetails("Pointer<SoundIoOutStream>")]System.IntPtr @outstream, double @volume);
-
-        // function soundio_instream_create - soundio.h (1071, 40)
-        [DllImport(LibraryName)]
-        internal static extern System.IntPtr soundio_instream_create([CTypeDetails("Pointer<SoundIoDevice>")]System.IntPtr @device);
-
-        // function soundio_instream_destroy - soundio.h (1073, 21)
-        [DllImport(LibraryName)]
-        internal static extern void soundio_instream_destroy([CTypeDetails("Pointer<SoundIoInStream>")]System.IntPtr @instream);
-
-        // function soundio_instream_open - soundio.h (1093, 20)
-        [DllImport(LibraryName)]
-        internal static extern int soundio_instream_open([CTypeDetails("Pointer<SoundIoInStream>")]System.IntPtr @instream);
-
-        // function soundio_instream_start - soundio.h (1102, 20)
-        [DllImport(LibraryName)]
-        internal static extern int soundio_instream_start([CTypeDetails("Pointer<SoundIoInStream>")]System.IntPtr @instream);
-
-        // function soundio_instream_begin_read - soundio.h (1133, 20)
-        [DllImport(LibraryName)]
-        internal static extern int soundio_instream_begin_read([CTypeDetails("Pointer<SoundIoInStream>")]System.IntPtr @instream, [CTypeDetails("Pointer<System.IntPtr>")]System.IntPtr @areas, [CTypeDetails("Pointer<int>")]System.IntPtr @frame_count);
-
-        // function soundio_instream_end_read - soundio.h (1143, 20)
-        [DllImport(LibraryName)]
-        internal static extern int soundio_instream_end_read([CTypeDetails("Pointer<SoundIoInStream>")]System.IntPtr @instream);
-
-        // function soundio_instream_pause - soundio.h (1156, 20)
-        [DllImport(LibraryName)]
-        internal static extern int soundio_instream_pause([CTypeDetails("Pointer<SoundIoInStream>")]System.IntPtr @instream, bool @pause);
-
-        // function soundio_instream_get_latency - soundio.h (1166, 20)
-        [DllImport(LibraryName)]
-        internal static extern int soundio_instream_get_latency([CTypeDetails("Pointer<SoundIoInStream>")]System.IntPtr @instream, [CTypeDetails("Pointer<double>")]System.IntPtr @out_latency);
-
-        // function soundio_ring_buffer_create - soundio.h (1181, 42)
-        [DllImport(LibraryName)]
-        internal static extern System.IntPtr soundio_ring_buffer_create([CTypeDetails("Pointer<SoundIo>")]System.IntPtr @soundio, int @requested_capacity);
-
-        // function soundio_ring_buffer_destroy - soundio.h (1182, 21)
-        [DllImport(LibraryName)]
-        internal static extern void soundio_ring_buffer_destroy([CTypeDetails("Pointer<SoundIoRingBuffer>")]System.IntPtr @ring_buffer);
-
-        // function soundio_ring_buffer_capacity - soundio.h (1186, 20)
-        [DllImport(LibraryName)]
-        internal static extern int soundio_ring_buffer_capacity([CTypeDetails("Pointer<SoundIoRingBuffer>")]System.IntPtr @ring_buffer);
-
-        // function soundio_ring_buffer_write_ptr - soundio.h (1189, 22)
-        [DllImport(LibraryName)]
-        internal static extern System.IntPtr soundio_ring_buffer_write_ptr([CTypeDetails("Pointer<SoundIoRingBuffer>")]System.IntPtr @ring_buffer);
-
-        // function soundio_ring_buffer_advance_write_ptr - soundio.h (1191, 21)
-        [DllImport(LibraryName)]
-        internal static extern void soundio_ring_buffer_advance_write_ptr([CTypeDetails("Pointer<SoundIoRingBuffer>")]System.IntPtr @ring_buffer, int @count);
-
-        // function soundio_ring_buffer_read_ptr - soundio.h (1194, 22)
-        [DllImport(LibraryName)]
-        internal static extern System.IntPtr soundio_ring_buffer_read_ptr([CTypeDetails("Pointer<SoundIoRingBuffer>")]System.IntPtr @ring_buffer);
-
-        // function soundio_ring_buffer_advance_read_ptr - soundio.h (1196, 21)
-        [DllImport(LibraryName)]
-        internal static extern void soundio_ring_buffer_advance_read_ptr([CTypeDetails("Pointer<SoundIoRingBuffer>")]System.IntPtr @ring_buffer, int @count);
-
-        // function soundio_ring_buffer_fill_count - soundio.h (1199, 20)
-        [DllImport(LibraryName)]
-        internal static extern int soundio_ring_buffer_fill_count([CTypeDetails("Pointer<SoundIoRingBuffer>")]System.IntPtr @ring_buffer);
-
-        // function soundio_ring_buffer_free_count - soundio.h (1202, 20)
-        [DllImport(LibraryName)]
-        internal static extern int soundio_ring_buffer_free_count([CTypeDetails("Pointer<SoundIoRingBuffer>")]System.IntPtr @ring_buffer);
-
-        // function soundio_ring_buffer_clear - soundio.h (1205, 21)
-        [DllImport(LibraryName)]
-        internal static extern void soundio_ring_buffer_clear([CTypeDetails("Pointer<SoundIoRingBuffer>")]System.IntPtr @ring_buffer);
-
-    }
-
-    class Delegates
-    {
-        public delegate void delegate0(System.IntPtr p0);
-        public delegate void delegate1(System.IntPtr p0, int p1);
-        public delegate void delegate2();
-        public delegate void delegate3(System.IntPtr p0);
-        public delegate void delegate4(System.IntPtr p0, int p1, int p2);
-        public delegate void delegate5(System.IntPtr p0);
-        public delegate void delegate6(System.IntPtr p0, int p1);
-        public delegate void delegate7(System.IntPtr p0, int p1, int p2);
-        public delegate void delegate8(System.IntPtr p0);
-        public delegate void delegate9(System.IntPtr p0, int p1);
-    }
-
-    public struct Pointer<T>
-    {
-        public IntPtr Handle;
-        public static implicit operator IntPtr(Pointer<T> value) { return value.Handle; }
-        public static implicit operator Pointer<T>(IntPtr value) { return new Pointer<T>(value); }
-
-        public Pointer(IntPtr handle)
-        {
-            Handle = handle;
-        }
-
-        public override bool Equals(object obj)
-        {
-            return obj is Pointer<T> && this == (Pointer<T>)obj;
-        }
-
-        public override int GetHashCode()
-        {
-            return (int)Handle;
-        }
-
-        public static bool operator ==(Pointer<T> p1, Pointer<T> p2)
-        {
-            return p1.Handle == p2.Handle;
-        }
-
-        public static bool operator !=(Pointer<T> p1, Pointer<T> p2)
-        {
-            return p1.Handle != p2.Handle;
-        }
-    }
-    public struct ArrayOf<T> { }
-    public struct ConstArrayOf<T> { }
-    public class CTypeDetailsAttribute : Attribute
-    {
-        public CTypeDetailsAttribute(string value)
-        {
-            Value = value;
-        }
-
-        public string Value { get; set; }
-    }
-
-}

+ 29 - 36
Ryujinx.Audio.Backends.SoundIo/SoundIoHardwareDeviceDriver.cs

@@ -1,19 +1,20 @@
-using Ryujinx.Audio.Common;
+using Ryujinx.Audio.Backends.SoundIo.Native;
+using Ryujinx.Audio.Common;
 using Ryujinx.Audio.Integration;
 using Ryujinx.Memory;
-using SoundIOSharp;
 using System;
 using System.Collections.Concurrent;
 using System.Threading;
 
 using static Ryujinx.Audio.Integration.IHardwareDeviceDriver;
+using static Ryujinx.Audio.Backends.SoundIo.Native.SoundIo;
 
 namespace Ryujinx.Audio.Backends.SoundIo
 {
     public class SoundIoHardwareDeviceDriver : IHardwareDeviceDriver
     {
-        private readonly SoundIO _audioContext;
-        private readonly SoundIODevice _audioDevice;
+        private readonly SoundIoContext _audioContext;
+        private readonly SoundIoDeviceContext _audioDevice;
         private readonly ManualResetEvent _updateRequiredEvent;
         private readonly ManualResetEvent _pauseEvent;
         private readonly ConcurrentDictionary<SoundIoHardwareDeviceSession, byte> _sessions;
@@ -21,7 +22,7 @@ namespace Ryujinx.Audio.Backends.SoundIo
 
         public SoundIoHardwareDeviceDriver()
         {
-            _audioContext = new SoundIO();
+            _audioContext = SoundIoContext.Create();
             _updateRequiredEvent = new ManualResetEvent(false);
             _pauseEvent = new ManualResetEvent(true);
             _sessions = new ConcurrentDictionary<SoundIoHardwareDeviceSession, byte>();
@@ -29,24 +30,23 @@ namespace Ryujinx.Audio.Backends.SoundIo
             _audioContext.Connect();
             _audioContext.FlushEvents();
 
-            _audioDevice = FindNonRawDefaultAudioDevice(_audioContext, true);
+            _audioDevice = FindValidAudioDevice(_audioContext, true);
         }
 
         public static bool IsSupported => IsSupportedInternal();
 
         private static bool IsSupportedInternal()
         {
-            SoundIO context = null;
-            SoundIODevice device = null;
-            SoundIOOutStream stream = null;
+            SoundIoContext context = null;
+            SoundIoDeviceContext device = null;
+            SoundIoOutStreamContext stream = null;
 
             bool backendDisconnected = false;
 
             try
             {
-                context = new SoundIO();
-
-                context.OnBackendDisconnect = (i) =>
+                context = SoundIoContext.Create();
+                context.OnBackendDisconnect = err =>
                 {
                     backendDisconnected = true;
                 };
@@ -64,7 +64,7 @@ namespace Ryujinx.Audio.Backends.SoundIo
                     return false;
                 }
 
-                device = FindNonRawDefaultAudioDevice(context);
+                device = FindValidAudioDevice(context);
 
                 if (device == null || backendDisconnected)
                 {
@@ -86,30 +86,23 @@ namespace Ryujinx.Audio.Backends.SoundIo
             }
             finally
             {
-                if (stream != null)
-                {
-                    stream.Dispose();
-                }
-
-                if (context != null)
-                {
-                    context.Dispose();
-                }
+                stream?.Dispose();
+                context?.Dispose();
             }
         }
 
-        private static SoundIODevice FindNonRawDefaultAudioDevice(SoundIO audioContext, bool fallback = false)
+        private static SoundIoDeviceContext FindValidAudioDevice(SoundIoContext audioContext, bool fallback = false)
         {
-            SoundIODevice defaultAudioDevice = audioContext.GetOutputDevice(audioContext.DefaultOutputDeviceIndex);
+            SoundIoDeviceContext defaultAudioDevice = audioContext.GetOutputDevice(audioContext.DefaultOutputDeviceIndex);
 
             if (!defaultAudioDevice.IsRaw)
             {
                 return defaultAudioDevice;
             }
 
-            for (int i = 0; i < audioContext.BackendCount; i++)
+            for (int i = 0; i < audioContext.OutputDeviceCount; i++)
             {
-                SoundIODevice audioDevice = audioContext.GetOutputDevice(i);
+                SoundIoDeviceContext audioDevice = audioContext.GetOutputDevice(i);
 
                 if (audioDevice.Id == defaultAudioDevice.Id && !audioDevice.IsRaw)
                 {
@@ -161,22 +154,22 @@ namespace Ryujinx.Audio.Backends.SoundIo
             return _sessions.TryRemove(session, out _);
         }
 
-        public static SoundIOFormat GetSoundIoFormat(SampleFormat format)
+        public static SoundIoFormat GetSoundIoFormat(SampleFormat format)
         {
             return format switch
             {
-                SampleFormat.PcmInt8 => SoundIOFormat.S8,
-                SampleFormat.PcmInt16 => SoundIOFormat.S16LE,
-                SampleFormat.PcmInt24 => SoundIOFormat.S24LE,
-                SampleFormat.PcmInt32 => SoundIOFormat.S32LE,
-                SampleFormat.PcmFloat => SoundIOFormat.Float32LE,
+                SampleFormat.PcmInt8 => SoundIoFormat.S8,
+                SampleFormat.PcmInt16 => SoundIoFormat.S16LE,
+                SampleFormat.PcmInt24 => SoundIoFormat.S24LE,
+                SampleFormat.PcmInt32 => SoundIoFormat.S32LE,
+                SampleFormat.PcmFloat => SoundIoFormat.Float32LE,
                 _ => throw new ArgumentException ($"Unsupported sample format {format}"),
             };
         }
 
-        internal SoundIOOutStream OpenStream(SampleFormat requestedSampleFormat, uint requestedSampleRate, uint requestedChannelCount)
+        internal SoundIoOutStreamContext OpenStream(SampleFormat requestedSampleFormat, uint requestedSampleRate, uint requestedChannelCount)
         {
-            SoundIOFormat driverSampleFormat = GetSoundIoFormat(requestedSampleFormat);
+            SoundIoFormat driverSampleFormat = GetSoundIoFormat(requestedSampleFormat);
 
             if (!_audioDevice.SupportsSampleRate((int)requestedSampleRate))
             {
@@ -193,10 +186,10 @@ namespace Ryujinx.Audio.Backends.SoundIo
                 throw new ArgumentException($"This sound device does not support channel count {requestedChannelCount}");
             }
 
-            SoundIOOutStream result = _audioDevice.CreateOutStream();
+            SoundIoOutStreamContext result = _audioDevice.CreateOutStream();
 
             result.Name = "Ryujinx";
-            result.Layout = SoundIOChannelLayout.GetDefault((int)requestedChannelCount);
+            result.Layout = SoundIoChannelLayout.GetDefaultValue((int)requestedChannelCount);
             result.Format = driverSampleFormat;
             result.SampleRate = (int)requestedSampleRate;
 

+ 20 - 25
Ryujinx.Audio.Backends.SoundIo/SoundIoHardwareDeviceSession.cs

@@ -1,11 +1,12 @@
 using Ryujinx.Audio.Backends.Common;
+using Ryujinx.Audio.Backends.SoundIo.Native;
 using Ryujinx.Audio.Common;
 using Ryujinx.Memory;
-using SoundIOSharp;
 using System;
 using System.Collections.Concurrent;
 using System.Runtime.CompilerServices;
 using System.Threading;
+using static Ryujinx.Audio.Backends.SoundIo.Native.SoundIo;
 
 namespace Ryujinx.Audio.Backends.SoundIo
 {
@@ -13,7 +14,7 @@ namespace Ryujinx.Audio.Backends.SoundIo
     {
         private SoundIoHardwareDeviceDriver _driver;
         private ConcurrentQueue<SoundIoAudioBuffer> _queuedBuffers;
-        private SoundIOOutStream _outputStream;
+        private SoundIoOutStreamContext _outputStream;
         private DynamicRingBuffer _ringBuffer;
         private ulong _playedSampleCount;
         private ManualResetEvent _updateRequiredEvent;
@@ -106,9 +107,9 @@ namespace Ryujinx.Audio.Backends.SoundIo
                 return;
             }
 
-            SoundIOChannelAreas areas = _outputStream.BeginWrite(ref frameCount);
+            Span<SoundIoChannelArea> areas = _outputStream.BeginWrite(ref frameCount);
 
-            int channelCount = areas.ChannelCount;
+            int channelCount = areas.Length;
 
             byte[] samples = new byte[frameCount * bytesPerFrame];
 
@@ -117,12 +118,12 @@ namespace Ryujinx.Audio.Backends.SoundIo
             // This is a huge ugly block of code, but we save
             // a significant amount of time over the generic
             // loop that handles other channel counts.
-            // TODO: Is this still right in 2021?
+            // TODO: Is this still right in 2022?
 
             // Mono
             if (channelCount == 1)
             {
-                SoundIOChannelArea area = areas.GetArea(0);
+                ref SoundIoChannelArea area = ref areas[0];
 
                 fixed (byte* srcptr = samples)
                 {
@@ -167,8 +168,8 @@ namespace Ryujinx.Audio.Backends.SoundIo
             // Stereo
             else if (channelCount == 2)
             {
-                SoundIOChannelArea area1 = areas.GetArea(0);
-                SoundIOChannelArea area2 = areas.GetArea(1);
+                ref SoundIoChannelArea area1 = ref areas[0];
+                ref SoundIoChannelArea area2 = ref areas[1];
 
                 fixed (byte* srcptr = samples)
                 {
@@ -233,12 +234,12 @@ namespace Ryujinx.Audio.Backends.SoundIo
             // Surround
             else if (channelCount == 6)
             {
-                SoundIOChannelArea area1 = areas.GetArea(0);
-                SoundIOChannelArea area2 = areas.GetArea(1);
-                SoundIOChannelArea area3 = areas.GetArea(2);
-                SoundIOChannelArea area4 = areas.GetArea(3);
-                SoundIOChannelArea area5 = areas.GetArea(4);
-                SoundIOChannelArea area6 = areas.GetArea(5);
+                ref SoundIoChannelArea area1 = ref areas[0];
+                ref SoundIoChannelArea area2 = ref areas[1];
+                ref SoundIoChannelArea area3 = ref areas[2];
+                ref SoundIoChannelArea area4 = ref areas[3];
+                ref SoundIoChannelArea area5 = ref areas[4];
+                ref SoundIoChannelArea area6 = ref areas[5];
 
                 fixed (byte* srcptr = samples)
                 {
@@ -367,24 +368,18 @@ namespace Ryujinx.Audio.Backends.SoundIo
             // Every other channel count
             else
             {
-                SoundIOChannelArea[] channels = new SoundIOChannelArea[channelCount];
-
-                // Obtain the channel area for each channel
-                for (int i = 0; i < channelCount; i++)
-                {
-                    channels[i] = areas.GetArea(i);
-                }
-
                 fixed (byte* srcptr = samples)
                 {
                     for (int frame = 0; frame < frameCount; frame++)
-                        for (int channel = 0; channel < areas.ChannelCount; channel++)
+                    {
+                        for (int channel = 0; channel < areas.Length; channel++)
                         {
                             // Copy channel by channel, frame by frame. This is slow!
-                            Unsafe.CopyBlockUnaligned((byte*)channels[channel].Pointer, srcptr + (frame * bytesPerFrame) + (channel * bytesPerSample), bytesPerSample);
+                            Unsafe.CopyBlockUnaligned((byte*)areas[channel].Pointer, srcptr + (frame * bytesPerFrame) + (channel * bytesPerSample), bytesPerSample);
 
-                            channels[channel].Pointer += channels[channel].Step;
+                            areas[channel].Pointer += areas[channel].Step;
                         }
+                    }
                 }
             }