From 403e67d9835b7412022ff4d98685f83590641c88 Mon Sep 17 00:00:00 2001 From: Mary-nyan Date: Sun, 11 Dec 2022 00:57:01 +0100 Subject: [PATCH] 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 --- .../Native/SoundIo.cs | 178 +++++ .../Native/SoundIoBackend.cs | 13 + .../Native/SoundIoChannelId.cs | 75 ++ .../Native/SoundIoContext.cs | 107 +++ .../Native/SoundIoDeviceAim.cs | 8 + .../Native/SoundIoDeviceContext.cs | 49 ++ .../Native/SoundIoError.cs | 22 + .../Native/SoundIoException.cs | 11 + .../Native/SoundIoFormat.cs | 25 + .../Native/SoundIoOutStreamContext.cs | 164 +++++ .../Native/libsoundio/MarshalExtensions.cs | 38 -- .../Native/libsoundio/SoundIO.cs | 386 ----------- .../Native/libsoundio/SoundIOBackend.cs | 13 - .../Native/libsoundio/SoundIOChannelArea.cs | 30 - .../Native/libsoundio/SoundIOChannelAreas.cs | 34 - .../Native/libsoundio/SoundIOChannelId.cs | 75 -- .../Native/libsoundio/SoundIOChannelLayout.cs | 116 ---- .../Native/libsoundio/SoundIODevice.cs | 267 -------- .../Native/libsoundio/SoundIODeviceAim.cs | 8 - .../Native/libsoundio/SoundIOException.cs | 10 - .../Native/libsoundio/SoundIOFormat.cs | 25 - .../Native/libsoundio/SoundIOInStream.cs | 293 -------- .../Native/libsoundio/SoundIOOutStream.cs | 331 --------- .../Native/libsoundio/SoundIORingBuffer.cs | 58 -- .../libsoundio/SoundIOSampleRateRange.cs | 14 - .../Native/libsoundio/libsoundio-interop.cs | 643 ------------------ .../SoundIoHardwareDeviceDriver.cs | 65 +- .../SoundIoHardwareDeviceSession.cs | 45 +- 28 files changed, 701 insertions(+), 2402 deletions(-) create mode 100644 Ryujinx.Audio.Backends.SoundIo/Native/SoundIo.cs create mode 100644 Ryujinx.Audio.Backends.SoundIo/Native/SoundIoBackend.cs create mode 100644 Ryujinx.Audio.Backends.SoundIo/Native/SoundIoChannelId.cs create mode 100644 Ryujinx.Audio.Backends.SoundIo/Native/SoundIoContext.cs create mode 100644 Ryujinx.Audio.Backends.SoundIo/Native/SoundIoDeviceAim.cs create mode 100644 Ryujinx.Audio.Backends.SoundIo/Native/SoundIoDeviceContext.cs create mode 100644 Ryujinx.Audio.Backends.SoundIo/Native/SoundIoError.cs create mode 100644 Ryujinx.Audio.Backends.SoundIo/Native/SoundIoException.cs create mode 100644 Ryujinx.Audio.Backends.SoundIo/Native/SoundIoFormat.cs create mode 100644 Ryujinx.Audio.Backends.SoundIo/Native/SoundIoOutStreamContext.cs delete mode 100644 Ryujinx.Audio.Backends.SoundIo/Native/libsoundio/MarshalExtensions.cs delete mode 100644 Ryujinx.Audio.Backends.SoundIo/Native/libsoundio/SoundIO.cs delete mode 100644 Ryujinx.Audio.Backends.SoundIo/Native/libsoundio/SoundIOBackend.cs delete mode 100644 Ryujinx.Audio.Backends.SoundIo/Native/libsoundio/SoundIOChannelArea.cs delete mode 100644 Ryujinx.Audio.Backends.SoundIo/Native/libsoundio/SoundIOChannelAreas.cs delete mode 100644 Ryujinx.Audio.Backends.SoundIo/Native/libsoundio/SoundIOChannelId.cs delete mode 100644 Ryujinx.Audio.Backends.SoundIo/Native/libsoundio/SoundIOChannelLayout.cs delete mode 100644 Ryujinx.Audio.Backends.SoundIo/Native/libsoundio/SoundIODevice.cs delete mode 100644 Ryujinx.Audio.Backends.SoundIo/Native/libsoundio/SoundIODeviceAim.cs delete mode 100644 Ryujinx.Audio.Backends.SoundIo/Native/libsoundio/SoundIOException.cs delete mode 100644 Ryujinx.Audio.Backends.SoundIo/Native/libsoundio/SoundIOFormat.cs delete mode 100644 Ryujinx.Audio.Backends.SoundIo/Native/libsoundio/SoundIOInStream.cs delete mode 100644 Ryujinx.Audio.Backends.SoundIo/Native/libsoundio/SoundIOOutStream.cs delete mode 100644 Ryujinx.Audio.Backends.SoundIo/Native/libsoundio/SoundIORingBuffer.cs delete mode 100644 Ryujinx.Audio.Backends.SoundIo/Native/libsoundio/SoundIOSampleRateRange.cs delete mode 100644 Ryujinx.Audio.Backends.SoundIo/Native/libsoundio/libsoundio-interop.cs diff --git a/Ryujinx.Audio.Backends.SoundIo/Native/SoundIo.cs b/Ryujinx.Audio.Backends.SoundIo/Native/SoundIo.cs new file mode 100644 index 000000000..9c3e686df --- /dev/null +++ b/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 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*)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); + } +} diff --git a/Ryujinx.Audio.Backends.SoundIo/Native/SoundIoBackend.cs b/Ryujinx.Audio.Backends.SoundIo/Native/SoundIoBackend.cs new file mode 100644 index 000000000..92f8ea375 --- /dev/null +++ b/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 + } +} diff --git a/Ryujinx.Audio.Backends.SoundIo/Native/SoundIoChannelId.cs b/Ryujinx.Audio.Backends.SoundIo/Native/SoundIoChannelId.cs new file mode 100644 index 000000000..70346e0bf --- /dev/null +++ b/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, + } +} diff --git a/Ryujinx.Audio.Backends.SoundIo/Native/SoundIoContext.cs b/Ryujinx.Audio.Backends.SoundIo/Native/SoundIoContext.cs new file mode 100644 index 000000000..3744c2e64 --- /dev/null +++ b/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 _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 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*)_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); + } + } +} diff --git a/Ryujinx.Audio.Backends.SoundIo/Native/SoundIoDeviceAim.cs b/Ryujinx.Audio.Backends.SoundIo/Native/SoundIoDeviceAim.cs new file mode 100644 index 000000000..a0689d6d6 --- /dev/null +++ b/Ryujinx.Audio.Backends.SoundIo/Native/SoundIoDeviceAim.cs @@ -0,0 +1,8 @@ +namespace Ryujinx.Audio.Backends.SoundIo.Native +{ + public enum SoundIoDeviceAim + { + SoundIoDeviceAimInput = 0, + SoundIoDeviceAimOutput = 1 + } +} diff --git a/Ryujinx.Audio.Backends.SoundIo/Native/SoundIoDeviceContext.cs b/Ryujinx.Audio.Backends.SoundIo/Native/SoundIoDeviceContext.cs new file mode 100644 index 000000000..42bcc6e3b --- /dev/null +++ b/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*)_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); + } + } +} diff --git a/Ryujinx.Audio.Backends.SoundIo/Native/SoundIoError.cs b/Ryujinx.Audio.Backends.SoundIo/Native/SoundIoError.cs new file mode 100644 index 000000000..9e33fa194 --- /dev/null +++ b/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, + } +} diff --git a/Ryujinx.Audio.Backends.SoundIo/Native/SoundIoException.cs b/Ryujinx.Audio.Backends.SoundIo/Native/SoundIoException.cs new file mode 100644 index 000000000..a033356e8 --- /dev/null +++ b/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))) { } + } +} diff --git a/Ryujinx.Audio.Backends.SoundIo/Native/SoundIoFormat.cs b/Ryujinx.Audio.Backends.SoundIo/Native/SoundIoFormat.cs new file mode 100644 index 000000000..0eee97804 --- /dev/null +++ b/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, + } +} diff --git a/Ryujinx.Audio.Backends.SoundIo/Native/SoundIoOutStreamContext.cs b/Ryujinx.Audio.Backends.SoundIo/Native/SoundIoOutStreamContext.cs new file mode 100644 index 000000000..2e432b311 --- /dev/null +++ b/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 _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*)_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 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 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((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); + } + } +} diff --git a/Ryujinx.Audio.Backends.SoundIo/Native/libsoundio/MarshalExtensions.cs b/Ryujinx.Audio.Backends.SoundIo/Native/libsoundio/MarshalExtensions.cs deleted file mode 100644 index 5e86263ea..000000000 --- a/Ryujinx.Audio.Backends.SoundIo/Native/libsoundio/MarshalExtensions.cs +++ /dev/null @@ -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)); - } - } -} \ No newline at end of file diff --git a/Ryujinx.Audio.Backends.SoundIo/Native/libsoundio/SoundIO.cs b/Ryujinx.Audio.Backends.SoundIo/Native/libsoundio/SoundIO.cs deleted file mode 100644 index c4ce1887d..000000000 --- a/Ryujinx.Audio.Backends.SoundIo/Native/libsoundio/SoundIO.cs +++ /dev/null @@ -1,386 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Runtime.InteropServices; - -namespace SoundIOSharp -{ - public class SoundIO : IDisposable - { - Pointer handle; - - public SoundIO() - { - handle = Natives.soundio_create(); - } - - internal SoundIO(Pointer 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 allocated_hglobals = new List(); - - 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("app_name"); - - public SoundIOBackend CurrentBackend - { - get { return (SoundIOBackend)Marshal.ReadInt32(handle, current_backend_offset); } - } - - static readonly int current_backend_offset = (int)Marshal.OffsetOf("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("emit_rtprio_warning"); - - Action emit_rtprio_warning; - - // jack_error_callback - public Action 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("jack_error_callback"); - - Action jack_error_callback; - delegate void jack_error_delegate(string message); - jack_error_delegate jack_error_callback_native; - - // jack_info_callback - public Action 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("jack_info_callback"); - - Action jack_info_callback; - delegate void jack_info_delegate(string message); - jack_info_delegate jack_info_callback_native; - - // on_backend_disconnect - public Action 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("on_backend_disconnect"); - - Action 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("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("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)); - } - } -} \ No newline at end of file diff --git a/Ryujinx.Audio.Backends.SoundIo/Native/libsoundio/SoundIOBackend.cs b/Ryujinx.Audio.Backends.SoundIo/Native/libsoundio/SoundIOBackend.cs deleted file mode 100644 index fd1058047..000000000 --- a/Ryujinx.Audio.Backends.SoundIo/Native/libsoundio/SoundIOBackend.cs +++ /dev/null @@ -1,13 +0,0 @@ -namespace SoundIOSharp -{ - public enum SoundIOBackend - { - None, - Jack, - PulseAudio, - Alsa, - CoreAudio, - Wasapi, - Dummy - } -} \ No newline at end of file diff --git a/Ryujinx.Audio.Backends.SoundIo/Native/libsoundio/SoundIOChannelArea.cs b/Ryujinx.Audio.Backends.SoundIo/Native/libsoundio/SoundIOChannelArea.cs deleted file mode 100644 index c15fb7447..000000000 --- a/Ryujinx.Audio.Backends.SoundIo/Native/libsoundio/SoundIOChannelArea.cs +++ /dev/null @@ -1,30 +0,0 @@ -using System; -using System.Runtime.InteropServices; - -namespace SoundIOSharp -{ - public struct SoundIOChannelArea - { - internal SoundIOChannelArea(Pointer handle) - { - this.handle = handle; - } - - Pointer 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("ptr"); - - public int Step - { - get { return Marshal.ReadInt32(handle, step_offset); } - } - - static readonly int step_offset = (int)Marshal.OffsetOf("step"); - } -} \ No newline at end of file diff --git a/Ryujinx.Audio.Backends.SoundIo/Native/libsoundio/SoundIOChannelAreas.cs b/Ryujinx.Audio.Backends.SoundIo/Native/libsoundio/SoundIOChannelAreas.cs deleted file mode 100644 index e0f375b96..000000000 --- a/Ryujinx.Audio.Backends.SoundIo/Native/libsoundio/SoundIOChannelAreas.cs +++ /dev/null @@ -1,34 +0,0 @@ -using System; -using System.Runtime.InteropServices; - -namespace SoundIOSharp -{ - public struct SoundIOChannelAreas - { - static readonly int native_size = Marshal.SizeOf(); - - 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; - } -} \ No newline at end of file diff --git a/Ryujinx.Audio.Backends.SoundIo/Native/libsoundio/SoundIOChannelId.cs b/Ryujinx.Audio.Backends.SoundIo/Native/libsoundio/SoundIOChannelId.cs deleted file mode 100644 index 002669dcf..000000000 --- a/Ryujinx.Audio.Backends.SoundIo/Native/libsoundio/SoundIOChannelId.cs +++ /dev/null @@ -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 - } -} \ No newline at end of file diff --git a/Ryujinx.Audio.Backends.SoundIo/Native/libsoundio/SoundIOChannelLayout.cs b/Ryujinx.Audio.Backends.SoundIo/Native/libsoundio/SoundIOChannelLayout.cs deleted file mode 100644 index ea617d4b4..000000000 --- a/Ryujinx.Audio.Backends.SoundIo/Native/libsoundio/SoundIOChannelLayout.cs +++ /dev/null @@ -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 handle) - { - this.handle = handle; - } - - readonly Pointer 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("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("name"); - - public IEnumerable 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("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); - } - } -} \ No newline at end of file diff --git a/Ryujinx.Audio.Backends.SoundIo/Native/libsoundio/SoundIODevice.cs b/Ryujinx.Audio.Backends.SoundIo/Native/libsoundio/SoundIODevice.cs deleted file mode 100644 index 6e7c49649..000000000 --- a/Ryujinx.Audio.Backends.SoundIo/Native/libsoundio/SoundIODevice.cs +++ /dev/null @@ -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 handle) - { - this.handle = handle; - } - - readonly Pointer 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("aim"); - - public SoundIOFormat CurrentFormat - { - get { return (SoundIOFormat)Marshal.ReadInt32(handle, current_format_offset); } - } - - static readonly int current_format_offset = (int)Marshal.OffsetOf("current_format"); - - public SoundIOChannelLayout CurrentLayout - { - get { return new SoundIOChannelLayout((IntPtr)handle + current_layout_offset); } - } - - static readonly int current_layout_offset = (int)Marshal.OffsetOf("current_layout"); - - public int FormatCount - { - get { return Marshal.ReadInt32(handle, format_count_offset); } - } - - static readonly int format_count_offset = (int)Marshal.OffsetOf("format_count"); - - public IEnumerable 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("formats"); - - public string Id - { - get { return Marshal.PtrToStringAnsi(Marshal.ReadIntPtr(handle, id_offset)); } - } - - static readonly int id_offset = (int)Marshal.OffsetOf("id"); - - public bool IsRaw - { - get { return Marshal.ReadInt32(handle, is_raw_offset) != 0; } - } - - static readonly int is_raw_offset = (int)Marshal.OffsetOf("is_raw"); - - public int LayoutCount - { - get { return Marshal.ReadInt32(handle, layout_count_offset); } - } - - static readonly int layout_count_offset = (int)Marshal.OffsetOf("layout_count"); - - public IEnumerable Layouts - { - get - { - var ptr = Marshal.ReadIntPtr (handle, layouts_offset); - - for (int i = 0; i < LayoutCount; i++) - { - yield return new SoundIOChannelLayout(ptr + i * Marshal.SizeOf()); - } - } - } - - static readonly int layouts_offset = (int)Marshal.OffsetOf("layouts"); - - public string Name - { - get { return Marshal.PtrToStringAnsi(Marshal.ReadIntPtr(handle, name_offset)); } - } - - static readonly int name_offset = (int)Marshal.OffsetOf("name"); - - public int ProbeError - { - get { return Marshal.ReadInt32(handle, probe_error_offset); } - } - - static readonly int probe_error_offset = (int)Marshal.OffsetOf("probe_error"); - - public int ReferenceCount - { - get { return Marshal.ReadInt32(handle, ref_count_offset); } - } - - static readonly int ref_count_offset = (int)Marshal.OffsetOf("ref_count"); - - public int SampleRateCount - { - get { return Marshal.ReadInt32(handle, sample_rate_count_offset); } - } - - static readonly int sample_rate_count_offset = (int)Marshal.OffsetOf("sample_rate_count"); - - public IEnumerable 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("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("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("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("software_latency_max"); - - public SoundIO SoundIO - { - get { return new SoundIO(Marshal.ReadIntPtr(handle, soundio_offset)); } - } - - static readonly int soundio_offset = (int)Marshal.OffsetOf("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)); - } - } -} \ No newline at end of file diff --git a/Ryujinx.Audio.Backends.SoundIo/Native/libsoundio/SoundIODeviceAim.cs b/Ryujinx.Audio.Backends.SoundIo/Native/libsoundio/SoundIODeviceAim.cs deleted file mode 100644 index 1e596127b..000000000 --- a/Ryujinx.Audio.Backends.SoundIo/Native/libsoundio/SoundIODeviceAim.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace SoundIOSharp -{ - public enum SoundIODeviceAim // soundio.h (228, 6) - { - Input, - Output - } -} \ No newline at end of file diff --git a/Ryujinx.Audio.Backends.SoundIo/Native/libsoundio/SoundIOException.cs b/Ryujinx.Audio.Backends.SoundIo/Native/libsoundio/SoundIOException.cs deleted file mode 100644 index 537b6cde2..000000000 --- a/Ryujinx.Audio.Backends.SoundIo/Native/libsoundio/SoundIOException.cs +++ /dev/null @@ -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))) { } - } -} \ No newline at end of file diff --git a/Ryujinx.Audio.Backends.SoundIo/Native/libsoundio/SoundIOFormat.cs b/Ryujinx.Audio.Backends.SoundIo/Native/libsoundio/SoundIOFormat.cs deleted file mode 100644 index df1b71c6b..000000000 --- a/Ryujinx.Audio.Backends.SoundIo/Native/libsoundio/SoundIOFormat.cs +++ /dev/null @@ -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 - } -} \ No newline at end of file diff --git a/Ryujinx.Audio.Backends.SoundIo/Native/libsoundio/SoundIOInStream.cs b/Ryujinx.Audio.Backends.SoundIo/Native/libsoundio/SoundIOInStream.cs deleted file mode 100644 index df97d6536..000000000 --- a/Ryujinx.Audio.Backends.SoundIo/Native/libsoundio/SoundIOInStream.cs +++ /dev/null @@ -1,293 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Runtime.InteropServices; - -namespace SoundIOSharp -{ - public class SoundIOInStream : IDisposable - { - internal SoundIOInStream(Pointer handle) - { - this.handle = handle; - } - - Pointer 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("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("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("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(), Marshal.SizeOf()); - } - } - } - - static readonly int layout_offset = (int)Marshal.OffsetOf("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("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("error_callback"); - - Action error_callback; - delegate void error_callback_delegate(IntPtr handle); - error_callback_delegate error_callback_native; - - // read_callback - public Action 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("read_callback"); - - Action 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("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 allocated_hglobals = new List(); - - 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("name"); - - public bool NonTerminalHint - { - get { return Marshal.ReadInt32(handle, non_terminal_hint_offset) != 0; } - } - - static readonly int non_terminal_hint_offset = (int)Marshal.OffsetOf("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("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("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("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; - } - } - } -} diff --git a/Ryujinx.Audio.Backends.SoundIo/Native/libsoundio/SoundIOOutStream.cs b/Ryujinx.Audio.Backends.SoundIo/Native/libsoundio/SoundIOOutStream.cs deleted file mode 100644 index 432ca42b8..000000000 --- a/Ryujinx.Audio.Backends.SoundIo/Native/libsoundio/SoundIOOutStream.cs +++ /dev/null @@ -1,331 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Runtime.InteropServices; - -namespace SoundIOSharp -{ - public class SoundIOOutStream : IDisposable - { - internal SoundIOOutStream (Pointer handle) - { - this.handle = handle; - } - - Pointer 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("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("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("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(), Marshal.SizeOf()); - } - } - } - static readonly int layout_offset = (int)Marshal.OffsetOf("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("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("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("error_callback"); - - Action error_callback; - delegate void error_callback_delegate (IntPtr handle); - error_callback_delegate error_callback_native; - - // write_callback - public Action 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("write_callback"); - - Action 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("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 allocated_hglobals = new List(); - - 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("name"); - - public bool NonTerminalHint - { - get { return Marshal.ReadInt32(handle, non_terminal_hint_offset) != 0; } - } - - static readonly int non_terminal_hint_offset = (int)Marshal.OffsetOf("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("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("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 ("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); - } - } - } -} diff --git a/Ryujinx.Audio.Backends.SoundIo/Native/libsoundio/SoundIORingBuffer.cs b/Ryujinx.Audio.Backends.SoundIo/Native/libsoundio/SoundIORingBuffer.cs deleted file mode 100644 index 7530da72c..000000000 --- a/Ryujinx.Audio.Backends.SoundIo/Native/libsoundio/SoundIORingBuffer.cs +++ /dev/null @@ -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); - } - } -} \ No newline at end of file diff --git a/Ryujinx.Audio.Backends.SoundIo/Native/libsoundio/SoundIOSampleRateRange.cs b/Ryujinx.Audio.Backends.SoundIo/Native/libsoundio/SoundIOSampleRateRange.cs deleted file mode 100644 index daf7921b5..000000000 --- a/Ryujinx.Audio.Backends.SoundIo/Native/libsoundio/SoundIOSampleRateRange.cs +++ /dev/null @@ -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; - } -} diff --git a/Ryujinx.Audio.Backends.SoundIo/Native/libsoundio/libsoundio-interop.cs b/Ryujinx.Audio.Backends.SoundIo/Native/libsoundio/libsoundio-interop.cs deleted file mode 100644 index 5377582f3..000000000 --- a/Ryujinx.Audio.Backends.SoundIo/Native/libsoundio/libsoundio-interop.cs +++ /dev/null @@ -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")] public System.IntPtr @name; - public int @channel_count; - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 24)] - [CTypeDetails("ConstArrayOf")] 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")] public System.IntPtr @ptr; - public int @step; - } - - [StructLayout(LayoutKind.Sequential)] - struct SoundIo // soundio.h (328, 8) - { - [CTypeDetails("Pointer")] public System.IntPtr @userdata; - [CTypeDetails("Pointer")] public delegate0 @on_devices_change; - [CTypeDetails("Pointer")] public delegate1 @on_backend_disconnect; - [CTypeDetails("Pointer")] public Delegates.delegate0 @on_events_signal; - public SoundIoBackend @current_backend; - [CTypeDetails("Pointer")] public System.IntPtr @app_name; - [CTypeDetails("Pointer")] public delegate2 @emit_rtprio_warning; - [CTypeDetails("Pointer")] public delegate3 @jack_info_callback; - [CTypeDetails("Pointer")] public Delegates.delegate3 @jack_error_callback; - } - - [StructLayout(LayoutKind.Sequential)] - struct SoundIoDevice // soundio.h (387, 8) - { - [CTypeDetails("Pointer")] public System.IntPtr @soundio; - [CTypeDetails("Pointer")] public System.IntPtr @id; - [CTypeDetails("Pointer")] public System.IntPtr @name; - public SoundIoDeviceAim @aim; - [CTypeDetails("Pointer")] public System.IntPtr @layouts; - public int @layout_count; - public SoundIoChannelLayout @current_layout; - [CTypeDetails("Pointer")] public System.IntPtr @formats; - public int @format_count; - public SoundIoFormat @current_format; - [CTypeDetails("Pointer")] 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")] public System.IntPtr @device; - public SoundIoFormat @format; - public int @sample_rate; - public SoundIoChannelLayout @layout; - public double @software_latency; - public float @volume; - [CTypeDetails("Pointer")] public System.IntPtr @userdata; - [CTypeDetails("Pointer")] public delegate4 @write_callback; - [CTypeDetails("Pointer")] public delegate5 @underflow_callback; - [CTypeDetails("Pointer")] public delegate6 @error_callback; - [CTypeDetails("Pointer")] 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")] public System.IntPtr @device; - public SoundIoFormat @format; - public int @sample_rate; - public SoundIoChannelLayout @layout; - public double @software_latency; - [CTypeDetails("Pointer")] public System.IntPtr @userdata; - [CTypeDetails("Pointer")] public delegate7 @read_callback; - [CTypeDetails("Pointer")] public delegate8 @overflow_callback; - [CTypeDetails("Pointer")] public delegate9 @error_callback; - [CTypeDetails("Pointer")] 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")]System.IntPtr @soundio); - - // function soundio_connect - soundio.h (705, 20) - [DllImport(LibraryName)] - internal static extern int soundio_connect([CTypeDetails("Pointer")]System.IntPtr @soundio); - - // function soundio_connect_backend - soundio.h (717, 20) - [DllImport(LibraryName)] - internal static extern int soundio_connect_backend([CTypeDetails("Pointer")]System.IntPtr @soundio, SoundIoBackend @backend); - - // function soundio_disconnect - soundio.h (718, 21) - [DllImport(LibraryName)] - internal static extern void soundio_disconnect([CTypeDetails("Pointer")]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")]System.IntPtr @soundio); - - // function soundio_get_backend - soundio.h (729, 36) - [DllImport(LibraryName)] - internal static extern SoundIoBackend soundio_get_backend([CTypeDetails("Pointer")]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")]System.IntPtr @soundio); - - // function soundio_wait_events - soundio.h (760, 21) - [DllImport(LibraryName)] - internal static extern void soundio_wait_events([CTypeDetails("Pointer")]System.IntPtr @soundio); - - // function soundio_wakeup - soundio.h (763, 21) - [DllImport(LibraryName)] - internal static extern void soundio_wakeup([CTypeDetails("Pointer")]System.IntPtr @soundio); - - // function soundio_force_device_scan - soundio.h (780, 21) - [DllImport(LibraryName)] - internal static extern void soundio_force_device_scan([CTypeDetails("Pointer")]System.IntPtr @soundio); - - // function soundio_channel_layout_equal - soundio.h (787, 21) - [DllImport(LibraryName)] - internal static extern bool soundio_channel_layout_equal([CTypeDetails("Pointer")]System.IntPtr @a, [CTypeDetails("Pointer")]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")]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")]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")]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")]System.IntPtr @preferred_layouts, int @preferred_layout_count, [CTypeDetails("Pointer")]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")]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")]System.IntPtr @soundio); - - // function soundio_output_device_count - soundio.h (864, 20) - [DllImport(LibraryName)] - internal static extern int soundio_output_device_count([CTypeDetails("Pointer")]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")]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")]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")]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")]System.IntPtr @soundio); - - // function soundio_device_ref - soundio.h (888, 21) - [DllImport(LibraryName)] - internal static extern void soundio_device_ref([CTypeDetails("Pointer")]System.IntPtr @device); - - // function soundio_device_unref - soundio.h (891, 21) - [DllImport(LibraryName)] - internal static extern void soundio_device_unref([CTypeDetails("Pointer")]System.IntPtr @device); - - // function soundio_device_equal - soundio.h (895, 21) - [DllImport(LibraryName)] - internal static extern bool soundio_device_equal([CTypeDetails("Pointer")]System.IntPtr @a, [CTypeDetails("Pointer")]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")]System.IntPtr @device); - - // function soundio_device_supports_format - soundio.h (904, 21) - [DllImport(LibraryName)] - internal static extern bool soundio_device_supports_format([CTypeDetails("Pointer")]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")]System.IntPtr @device, [CTypeDetails("Pointer")]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")]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")]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")]System.IntPtr @device); - - // function soundio_outstream_destroy - soundio.h (931, 21) - [DllImport(LibraryName)] - internal static extern void soundio_outstream_destroy([CTypeDetails("Pointer")]System.IntPtr @outstream); - - // function soundio_outstream_open - soundio.h (954, 20) - [DllImport(LibraryName)] - internal static extern int soundio_outstream_open([CTypeDetails("Pointer")]System.IntPtr @outstream); - - // function soundio_outstream_start - soundio.h (965, 20) - [DllImport(LibraryName)] - internal static extern int soundio_outstream_start([CTypeDetails("Pointer")]System.IntPtr @outstream); - - // function soundio_outstream_begin_write - soundio.h (997, 20) - [DllImport(LibraryName)] - internal static extern int soundio_outstream_begin_write([CTypeDetails("Pointer")]System.IntPtr @outstream, [CTypeDetails("Pointer")]System.IntPtr @areas, [CTypeDetails("Pointer")]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")]System.IntPtr @outstream); - - // function soundio_outstream_clear_buffer - soundio.h (1024, 20) - [DllImport(LibraryName)] - internal static extern int soundio_outstream_clear_buffer([CTypeDetails("Pointer")]System.IntPtr @outstream); - - // function soundio_outstream_pause - soundio.h (1045, 20) - [DllImport(LibraryName)] - internal static extern int soundio_outstream_pause([CTypeDetails("Pointer")]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")]System.IntPtr @outstream, [CTypeDetails("Pointer")]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")]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")]System.IntPtr @device); - - // function soundio_instream_destroy - soundio.h (1073, 21) - [DllImport(LibraryName)] - internal static extern void soundio_instream_destroy([CTypeDetails("Pointer")]System.IntPtr @instream); - - // function soundio_instream_open - soundio.h (1093, 20) - [DllImport(LibraryName)] - internal static extern int soundio_instream_open([CTypeDetails("Pointer")]System.IntPtr @instream); - - // function soundio_instream_start - soundio.h (1102, 20) - [DllImport(LibraryName)] - internal static extern int soundio_instream_start([CTypeDetails("Pointer")]System.IntPtr @instream); - - // function soundio_instream_begin_read - soundio.h (1133, 20) - [DllImport(LibraryName)] - internal static extern int soundio_instream_begin_read([CTypeDetails("Pointer")]System.IntPtr @instream, [CTypeDetails("Pointer")]System.IntPtr @areas, [CTypeDetails("Pointer")]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")]System.IntPtr @instream); - - // function soundio_instream_pause - soundio.h (1156, 20) - [DllImport(LibraryName)] - internal static extern int soundio_instream_pause([CTypeDetails("Pointer")]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")]System.IntPtr @instream, [CTypeDetails("Pointer")]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")]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")]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")]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")]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")]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")]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")]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")]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")]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")]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 - { - public IntPtr Handle; - public static implicit operator IntPtr(Pointer value) { return value.Handle; } - public static implicit operator Pointer(IntPtr value) { return new Pointer(value); } - - public Pointer(IntPtr handle) - { - Handle = handle; - } - - public override bool Equals(object obj) - { - return obj is Pointer && this == (Pointer)obj; - } - - public override int GetHashCode() - { - return (int)Handle; - } - - public static bool operator ==(Pointer p1, Pointer p2) - { - return p1.Handle == p2.Handle; - } - - public static bool operator !=(Pointer p1, Pointer p2) - { - return p1.Handle != p2.Handle; - } - } - public struct ArrayOf { } - public struct ConstArrayOf { } - public class CTypeDetailsAttribute : Attribute - { - public CTypeDetailsAttribute(string value) - { - Value = value; - } - - public string Value { get; set; } - } - -} diff --git a/Ryujinx.Audio.Backends.SoundIo/SoundIoHardwareDeviceDriver.cs b/Ryujinx.Audio.Backends.SoundIo/SoundIoHardwareDeviceDriver.cs index 02a9a2287..2eab59086 100644 --- a/Ryujinx.Audio.Backends.SoundIo/SoundIoHardwareDeviceDriver.cs +++ b/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 _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(); @@ -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; diff --git a/Ryujinx.Audio.Backends.SoundIo/SoundIoHardwareDeviceSession.cs b/Ryujinx.Audio.Backends.SoundIo/SoundIoHardwareDeviceSession.cs index 1e8c814e5..96d9ce970 100644 --- a/Ryujinx.Audio.Backends.SoundIo/SoundIoHardwareDeviceSession.cs +++ b/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 _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 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; } + } } }