aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.Audio.Backends.SoundIo
diff options
context:
space:
mode:
authorTSR Berry <20988865+TSRBerry@users.noreply.github.com>2023-04-08 01:22:00 +0200
committerMary <thog@protonmail.com>2023-04-27 23:51:14 +0200
commitcee712105850ac3385cd0091a923438167433f9f (patch)
tree4a5274b21d8b7f938c0d0ce18736d3f2993b11b1 /Ryujinx.Audio.Backends.SoundIo
parentcd124bda587ef09668a971fa1cac1c3f0cfc9f21 (diff)
Move solution and projects to src
Diffstat (limited to 'Ryujinx.Audio.Backends.SoundIo')
-rw-r--r--Ryujinx.Audio.Backends.SoundIo/Native/SoundIo.cs178
-rw-r--r--Ryujinx.Audio.Backends.SoundIo/Native/SoundIoBackend.cs13
-rw-r--r--Ryujinx.Audio.Backends.SoundIo/Native/SoundIoChannelId.cs75
-rw-r--r--Ryujinx.Audio.Backends.SoundIo/Native/SoundIoContext.cs107
-rw-r--r--Ryujinx.Audio.Backends.SoundIo/Native/SoundIoDeviceAim.cs8
-rw-r--r--Ryujinx.Audio.Backends.SoundIo/Native/SoundIoDeviceContext.cs49
-rw-r--r--Ryujinx.Audio.Backends.SoundIo/Native/SoundIoError.cs22
-rw-r--r--Ryujinx.Audio.Backends.SoundIo/Native/SoundIoException.cs11
-rw-r--r--Ryujinx.Audio.Backends.SoundIo/Native/SoundIoFormat.cs25
-rw-r--r--Ryujinx.Audio.Backends.SoundIo/Native/SoundIoOutStreamContext.cs164
-rw-r--r--Ryujinx.Audio.Backends.SoundIo/Native/libsoundio/libs/libsoundio.dllbin85504 -> 0 bytes
-rw-r--r--Ryujinx.Audio.Backends.SoundIo/Native/libsoundio/libs/libsoundio.dylibbin54976 -> 0 bytes
-rw-r--r--Ryujinx.Audio.Backends.SoundIo/Native/libsoundio/libs/libsoundio.sobin88584 -> 0 bytes
-rw-r--r--Ryujinx.Audio.Backends.SoundIo/Ryujinx.Audio.Backends.SoundIo.csproj28
-rw-r--r--Ryujinx.Audio.Backends.SoundIo/SoundIoAudioBuffer.cs16
-rw-r--r--Ryujinx.Audio.Backends.SoundIo/SoundIoHardwareDeviceDriver.cs247
-rw-r--r--Ryujinx.Audio.Backends.SoundIo/SoundIoHardwareDeviceSession.cs438
17 files changed, 0 insertions, 1381 deletions
diff --git a/Ryujinx.Audio.Backends.SoundIo/Native/SoundIo.cs b/Ryujinx.Audio.Backends.SoundIo/Native/SoundIo.cs
deleted file mode 100644
index 9c3e686d..00000000
--- a/Ryujinx.Audio.Backends.SoundIo/Native/SoundIo.cs
+++ /dev/null
@@ -1,178 +0,0 @@
-using Ryujinx.Common.Memory;
-using System;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-
-namespace Ryujinx.Audio.Backends.SoundIo.Native
-{
- public static partial class SoundIo
- {
- private const string LibraryName = "libsoundio";
-
- [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
- public unsafe delegate void OnDeviceChangeNativeDelegate(IntPtr ctx);
-
- [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
- public unsafe delegate void OnBackendDisconnectedDelegate(IntPtr ctx, SoundIoError err);
-
- [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
- public unsafe delegate void OnEventsSignalDelegate(IntPtr ctx);
-
- [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
- public unsafe delegate void EmitRtPrioWarningDelegate();
-
- [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
- public unsafe delegate void JackCallbackDelegate(IntPtr msg);
-
- [StructLayout(LayoutKind.Sequential)]
- public struct SoundIoStruct
- {
- public IntPtr UserData;
- public IntPtr OnDeviceChange;
- public IntPtr OnBackendDisconnected;
- public IntPtr OnEventsSignal;
- public SoundIoBackend CurrentBackend;
- public IntPtr ApplicationName;
- public IntPtr EmitRtPrioWarning;
- public IntPtr JackInfoCallback;
- public IntPtr JackErrorCallback;
- }
-
- public struct SoundIoChannelLayout
- {
- public IntPtr Name;
- public int ChannelCount;
- public Array24<SoundIoChannelId> Channels;
-
- public static IntPtr GetDefault(int channelCount)
- {
- return soundio_channel_layout_get_default(channelCount);
- }
-
- public static unsafe SoundIoChannelLayout GetDefaultValue(int channelCount)
- {
- return Unsafe.AsRef<SoundIoChannelLayout>((SoundIoChannelLayout*)GetDefault(channelCount));
- }
- }
-
- public struct SoundIoSampleRateRange
- {
- public int Min;
- public int Max;
- }
-
- public struct SoundIoDevice
- {
- public IntPtr SoundIo;
- public IntPtr Id;
- public IntPtr Name;
- public SoundIoDeviceAim Aim;
- public IntPtr Layouts;
- public int LayoutCount;
- public SoundIoChannelLayout CurrentLayout;
- public IntPtr Formats;
- public int FormatCount;
- public SoundIoFormat CurrentFormat;
- public IntPtr SampleRates;
- public int SampleRateCount;
- public int SampleRateCurrent;
- public double SoftwareLatencyMin;
- public double SoftwareLatencyMax;
- public double SoftwareLatencyCurrent;
- public bool IsRaw;
- public int RefCount;
- public SoundIoError ProbeError;
- }
-
- public struct SoundIoOutStream
- {
- public IntPtr Device;
- public SoundIoFormat Format;
- public int SampleRate;
- public SoundIoChannelLayout Layout;
- public double SoftwareLatency;
- public float Volume;
- public IntPtr UserData;
- public IntPtr WriteCallback;
- public IntPtr UnderflowCallback;
- public IntPtr ErrorCallback;
- public IntPtr Name;
- public bool NonTerminalHint;
- public int BytesPerFrame;
- public int BytesPerSample;
- public SoundIoError LayoutError;
- }
-
- public struct SoundIoChannelArea
- {
- public IntPtr Pointer;
- public int Step;
- }
-
- [LibraryImport(LibraryName)]
- public static partial IntPtr soundio_create();
-
- [LibraryImport(LibraryName)]
- public static partial SoundIoError soundio_connect(IntPtr ctx);
-
- [LibraryImport(LibraryName)]
- public static partial void soundio_disconnect(IntPtr ctx);
-
- [LibraryImport(LibraryName)]
- public static partial void soundio_flush_events(IntPtr ctx);
-
- [LibraryImport(LibraryName)]
- public static partial int soundio_output_device_count(IntPtr ctx);
-
- [LibraryImport(LibraryName)]
- public static partial int soundio_default_output_device_index(IntPtr ctx);
-
- [LibraryImport(LibraryName)]
- public static partial IntPtr soundio_get_output_device(IntPtr ctx, int index);
-
- [LibraryImport(LibraryName)]
- [return: MarshalAs(UnmanagedType.Bool)]
- public static partial bool soundio_device_supports_format(IntPtr devCtx, SoundIoFormat format);
-
- [LibraryImport(LibraryName)]
- [return: MarshalAs(UnmanagedType.Bool)]
- public static partial bool soundio_device_supports_layout(IntPtr devCtx, IntPtr layout);
-
- [LibraryImport(LibraryName)]
- [return: MarshalAs(UnmanagedType.Bool)]
- public static partial bool soundio_device_supports_sample_rate(IntPtr devCtx, int sampleRate);
-
- [LibraryImport(LibraryName)]
- public static partial IntPtr soundio_outstream_create(IntPtr devCtx);
-
- [LibraryImport(LibraryName)]
- public static partial SoundIoError soundio_outstream_open(IntPtr outStreamCtx);
-
- [LibraryImport(LibraryName)]
- public static partial SoundIoError soundio_outstream_start(IntPtr outStreamCtx);
-
- [LibraryImport(LibraryName)]
- public static partial SoundIoError soundio_outstream_begin_write(IntPtr outStreamCtx, IntPtr areas, IntPtr frameCount);
-
- [LibraryImport(LibraryName)]
- public static partial SoundIoError soundio_outstream_end_write(IntPtr outStreamCtx);
-
- [LibraryImport(LibraryName)]
- public static partial SoundIoError soundio_outstream_pause(IntPtr devCtx, [MarshalAs(UnmanagedType.Bool)] bool pause);
-
- [LibraryImport(LibraryName)]
- public static partial SoundIoError soundio_outstream_set_volume(IntPtr devCtx, double volume);
-
- [LibraryImport(LibraryName)]
- public static partial void soundio_outstream_destroy(IntPtr streamCtx);
-
- [LibraryImport(LibraryName)]
- public static partial void soundio_destroy(IntPtr ctx);
-
- [LibraryImport(LibraryName)]
- public static partial IntPtr soundio_channel_layout_get_default(int channelCount);
-
- [LibraryImport(LibraryName)]
- public static partial IntPtr soundio_strerror(SoundIoError err);
- }
-}
diff --git a/Ryujinx.Audio.Backends.SoundIo/Native/SoundIoBackend.cs b/Ryujinx.Audio.Backends.SoundIo/Native/SoundIoBackend.cs
deleted file mode 100644
index 92f8ea37..00000000
--- a/Ryujinx.Audio.Backends.SoundIo/Native/SoundIoBackend.cs
+++ /dev/null
@@ -1,13 +0,0 @@
-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
deleted file mode 100644
index 70346e0b..00000000
--- a/Ryujinx.Audio.Backends.SoundIo/Native/SoundIoChannelId.cs
+++ /dev/null
@@ -1,75 +0,0 @@
-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
deleted file mode 100644
index 3744c2e6..00000000
--- a/Ryujinx.Audio.Backends.SoundIo/Native/SoundIoContext.cs
+++ /dev/null
@@ -1,107 +0,0 @@
-using System;
-using System.Reflection.Metadata;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-using System.Threading;
-using static Ryujinx.Audio.Backends.SoundIo.Native.SoundIo;
-
-namespace Ryujinx.Audio.Backends.SoundIo.Native
-{
- public class SoundIoContext : IDisposable
- {
- private IntPtr _context;
- private Action<SoundIoError> _onBackendDisconnect;
- private OnBackendDisconnectedDelegate _onBackendDisconnectNative;
-
- public IntPtr Context => _context;
-
- internal SoundIoContext(IntPtr context)
- {
- _context = context;
- _onBackendDisconnect = null;
- _onBackendDisconnectNative = null;
- }
-
- public SoundIoError Connect() => soundio_connect(_context);
- public void Disconnect() => soundio_disconnect(_context);
-
- public void FlushEvents() => soundio_flush_events(_context);
-
- public int OutputDeviceCount => soundio_output_device_count(_context);
-
- public int DefaultOutputDeviceIndex => soundio_default_output_device_index(_context);
-
- public Action<SoundIoError> OnBackendDisconnect
- {
- get { return _onBackendDisconnect; }
- set
- {
- _onBackendDisconnect = value;
-
- if (_onBackendDisconnect == null)
- {
- _onBackendDisconnectNative = null;
- }
- else
- {
- _onBackendDisconnectNative = (ctx, err) => _onBackendDisconnect(err);
- }
-
- GetContext().OnBackendDisconnected = Marshal.GetFunctionPointerForDelegate(_onBackendDisconnectNative);
- }
- }
-
- private ref SoundIoStruct GetContext()
- {
- unsafe
- {
- return ref Unsafe.AsRef<SoundIoStruct>((SoundIoStruct*)_context);
- }
- }
-
- public SoundIoDeviceContext GetOutputDevice(int index)
- {
- IntPtr deviceContext = soundio_get_output_device(_context, index);
-
- if (deviceContext == IntPtr.Zero)
- {
- return null;
- }
-
- return new SoundIoDeviceContext(deviceContext);
- }
-
- public static SoundIoContext Create()
- {
- IntPtr context = soundio_create();
-
- if (context == IntPtr.Zero)
- {
- return null;
- }
-
- return new SoundIoContext(context);
- }
-
- protected virtual void Dispose(bool disposing)
- {
- IntPtr currentContext = Interlocked.Exchange(ref _context, IntPtr.Zero);
-
- if (currentContext != IntPtr.Zero)
- {
- soundio_destroy(currentContext);
- }
- }
-
- public void Dispose()
- {
- Dispose(true);
- GC.SuppressFinalize(this);
- }
-
- ~SoundIoContext()
- {
- Dispose(false);
- }
- }
-}
diff --git a/Ryujinx.Audio.Backends.SoundIo/Native/SoundIoDeviceAim.cs b/Ryujinx.Audio.Backends.SoundIo/Native/SoundIoDeviceAim.cs
deleted file mode 100644
index a0689d6d..00000000
--- a/Ryujinx.Audio.Backends.SoundIo/Native/SoundIoDeviceAim.cs
+++ /dev/null
@@ -1,8 +0,0 @@
-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
deleted file mode 100644
index 42bcc6e3..00000000
--- a/Ryujinx.Audio.Backends.SoundIo/Native/SoundIoDeviceContext.cs
+++ /dev/null
@@ -1,49 +0,0 @@
-using System;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-using static Ryujinx.Audio.Backends.SoundIo.Native.SoundIo;
-
-namespace Ryujinx.Audio.Backends.SoundIo.Native
-{
- public class SoundIoDeviceContext
- {
- private readonly IntPtr _context;
-
- public IntPtr Context => _context;
-
- internal SoundIoDeviceContext(IntPtr context)
- {
- _context = context;
- }
-
- private ref SoundIoDevice GetDeviceContext()
- {
- unsafe
- {
- return ref Unsafe.AsRef<SoundIoDevice>((SoundIoDevice*)_context);
- }
- }
-
- public bool IsRaw => GetDeviceContext().IsRaw;
-
- public string Id => Marshal.PtrToStringAnsi(GetDeviceContext().Id);
-
- public bool SupportsSampleRate(int sampleRate) => soundio_device_supports_sample_rate(_context, sampleRate);
-
- public bool SupportsFormat(SoundIoFormat format) => soundio_device_supports_format(_context, format);
-
- public bool SupportsChannelCount(int channelCount) => soundio_device_supports_layout(_context, SoundIoChannelLayout.GetDefault(channelCount));
-
- public SoundIoOutStreamContext CreateOutStream()
- {
- IntPtr context = soundio_outstream_create(_context);
-
- if (context == IntPtr.Zero)
- {
- return null;
- }
-
- return new SoundIoOutStreamContext(context);
- }
- }
-}
diff --git a/Ryujinx.Audio.Backends.SoundIo/Native/SoundIoError.cs b/Ryujinx.Audio.Backends.SoundIo/Native/SoundIoError.cs
deleted file mode 100644
index 9e33fa19..00000000
--- a/Ryujinx.Audio.Backends.SoundIo/Native/SoundIoError.cs
+++ /dev/null
@@ -1,22 +0,0 @@
-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
deleted file mode 100644
index a033356e..00000000
--- a/Ryujinx.Audio.Backends.SoundIo/Native/SoundIoException.cs
+++ /dev/null
@@ -1,11 +0,0 @@
-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
deleted file mode 100644
index 0eee9780..00000000
--- a/Ryujinx.Audio.Backends.SoundIo/Native/SoundIoFormat.cs
+++ /dev/null
@@ -1,25 +0,0 @@
-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
deleted file mode 100644
index 2e432b31..00000000
--- a/Ryujinx.Audio.Backends.SoundIo/Native/SoundIoOutStreamContext.cs
+++ /dev/null
@@ -1,164 +0,0 @@
-using System;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-using static Ryujinx.Audio.Backends.SoundIo.Native.SoundIo;
-
-namespace Ryujinx.Audio.Backends.SoundIo.Native
-{
- public class SoundIoOutStreamContext : IDisposable
- {
- [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
- private unsafe delegate void WriteCallbackDelegate(IntPtr ctx, int frameCountMin, int frameCountMax);
-
- private IntPtr _context;
- private IntPtr _nameStored;
- private Action<int, int> _writeCallback;
- private WriteCallbackDelegate _writeCallbackNative;
-
- public IntPtr Context => _context;
-
- internal SoundIoOutStreamContext(IntPtr context)
- {
- _context = context;
- _nameStored = IntPtr.Zero;
- _writeCallback = null;
- _writeCallbackNative = null;
- }
-
- private ref SoundIoOutStream GetOutContext()
- {
- unsafe
- {
- return ref Unsafe.AsRef<SoundIoOutStream>((SoundIoOutStream*)_context);
- }
- }
-
- public string Name
- {
- get => Marshal.PtrToStringAnsi(GetOutContext().Name);
- set
- {
- var context = GetOutContext();
-
- if (_nameStored != IntPtr.Zero && context.Name == _nameStored)
- {
- Marshal.FreeHGlobal(_nameStored);
- }
-
- _nameStored = Marshal.StringToHGlobalAnsi(value);
- GetOutContext().Name = _nameStored;
- }
- }
-
- public SoundIoChannelLayout Layout
- {
- get => GetOutContext().Layout;
- set => GetOutContext().Layout = value;
- }
-
- public SoundIoFormat Format
- {
- get => GetOutContext().Format;
- set => GetOutContext().Format = value;
- }
-
- public int SampleRate
- {
- get => GetOutContext().SampleRate;
- set => GetOutContext().SampleRate = value;
- }
-
- public float Volume
- {
- get => GetOutContext().Volume;
- set => GetOutContext().Volume = value;
- }
-
- public int BytesPerFrame
- {
- get => GetOutContext().BytesPerFrame;
- set => GetOutContext().BytesPerFrame = value;
- }
-
- public int BytesPerSample
- {
- get => GetOutContext().BytesPerSample;
- set => GetOutContext().BytesPerSample = value;
- }
-
- public Action<int, int> WriteCallback
- {
- get { return _writeCallback; }
- set
- {
- _writeCallback = value;
-
- if (_writeCallback == null)
- {
- _writeCallbackNative = null;
- }
- else
- {
- _writeCallbackNative = (ctx, frameCountMin, frameCountMax) => _writeCallback(frameCountMin, frameCountMax);
- }
-
- GetOutContext().WriteCallback = Marshal.GetFunctionPointerForDelegate(_writeCallbackNative);
- }
- }
-
- private static void CheckError(SoundIoError error)
- {
- if (error != SoundIoError.None)
- {
- throw new SoundIoException(error);
- }
- }
-
- public void Open() => CheckError(soundio_outstream_open(_context));
-
- public void Start() => CheckError(soundio_outstream_start(_context));
-
- public void Pause(bool pause) => CheckError(soundio_outstream_pause(_context, pause));
-
- public void SetVolume(double volume) => CheckError(soundio_outstream_set_volume(_context, volume));
-
- public Span<SoundIoChannelArea> BeginWrite(ref int frameCount)
- {
- IntPtr arenas = default;
- int nativeFrameCount = frameCount;
-
- unsafe
- {
- var frameCountPtr = &nativeFrameCount;
- var arenasPtr = &arenas;
- CheckError(soundio_outstream_begin_write(_context, (IntPtr)arenasPtr, (IntPtr)frameCountPtr));
-
- frameCount = *frameCountPtr;
-
- return new Span<SoundIoChannelArea>((void*)arenas, Layout.ChannelCount);
- }
- }
-
- public void EndWrite() => CheckError(soundio_outstream_end_write(_context));
-
- protected virtual void Dispose(bool disposing)
- {
- if (_context != IntPtr.Zero)
- {
- soundio_outstream_destroy(_context);
- _context = IntPtr.Zero;
- }
- }
-
- public void Dispose()
- {
- Dispose(true);
- GC.SuppressFinalize(this);
- }
-
- ~SoundIoOutStreamContext()
- {
- Dispose(false);
- }
- }
-}
diff --git a/Ryujinx.Audio.Backends.SoundIo/Native/libsoundio/libs/libsoundio.dll b/Ryujinx.Audio.Backends.SoundIo/Native/libsoundio/libs/libsoundio.dll
deleted file mode 100644
index 48804312..00000000
--- a/Ryujinx.Audio.Backends.SoundIo/Native/libsoundio/libs/libsoundio.dll
+++ /dev/null
Binary files differ
diff --git a/Ryujinx.Audio.Backends.SoundIo/Native/libsoundio/libs/libsoundio.dylib b/Ryujinx.Audio.Backends.SoundIo/Native/libsoundio/libs/libsoundio.dylib
deleted file mode 100644
index 10171f4f..00000000
--- a/Ryujinx.Audio.Backends.SoundIo/Native/libsoundio/libs/libsoundio.dylib
+++ /dev/null
Binary files differ
diff --git a/Ryujinx.Audio.Backends.SoundIo/Native/libsoundio/libs/libsoundio.so b/Ryujinx.Audio.Backends.SoundIo/Native/libsoundio/libs/libsoundio.so
deleted file mode 100644
index 87c8b506..00000000
--- a/Ryujinx.Audio.Backends.SoundIo/Native/libsoundio/libs/libsoundio.so
+++ /dev/null
Binary files differ
diff --git a/Ryujinx.Audio.Backends.SoundIo/Ryujinx.Audio.Backends.SoundIo.csproj b/Ryujinx.Audio.Backends.SoundIo/Ryujinx.Audio.Backends.SoundIo.csproj
deleted file mode 100644
index 9f242dbe..00000000
--- a/Ryujinx.Audio.Backends.SoundIo/Ryujinx.Audio.Backends.SoundIo.csproj
+++ /dev/null
@@ -1,28 +0,0 @@
-<Project Sdk="Microsoft.NET.Sdk">
-
- <PropertyGroup>
- <TargetFramework>net7.0</TargetFramework>
- <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
- <RuntimeIdentifiers>win10-x64;linux-x64;osx-x64</RuntimeIdentifiers>
- </PropertyGroup>
-
- <ItemGroup>
- <ProjectReference Include="..\Ryujinx.Audio\Ryujinx.Audio.csproj" />
- </ItemGroup>
-
- <ItemGroup>
- <ContentWithTargetPath Include="Native\libsoundio\libs\libsoundio.dll" Condition="'$(RuntimeIdentifier)' != 'linux-x64' AND '$(RuntimeIdentifier)' != 'osx-x64'">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- <TargetPath>libsoundio.dll</TargetPath>
- </ContentWithTargetPath>
- <ContentWithTargetPath Include="Native\libsoundio\libs\libsoundio.dylib" Condition="'$(RuntimeIdentifier)' != 'linux-x64' AND '$(RuntimeIdentifier)' != 'win10-x64'">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- <TargetPath>libsoundio.dylib</TargetPath>
- </ContentWithTargetPath>
- <ContentWithTargetPath Include="Native\libsoundio\libs\libsoundio.so" Condition="'$(RuntimeIdentifier)' != 'win10-x64' AND '$(RuntimeIdentifier)' != 'osx-x64'">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- <TargetPath>libsoundio.so</TargetPath>
- </ContentWithTargetPath>
- </ItemGroup>
-
-</Project>
diff --git a/Ryujinx.Audio.Backends.SoundIo/SoundIoAudioBuffer.cs b/Ryujinx.Audio.Backends.SoundIo/SoundIoAudioBuffer.cs
deleted file mode 100644
index 7f32b953..00000000
--- a/Ryujinx.Audio.Backends.SoundIo/SoundIoAudioBuffer.cs
+++ /dev/null
@@ -1,16 +0,0 @@
-namespace Ryujinx.Audio.Backends.SoundIo
-{
- class SoundIoAudioBuffer
- {
- public readonly ulong DriverIdentifier;
- public readonly ulong SampleCount;
- public ulong SamplePlayed;
-
- public SoundIoAudioBuffer(ulong driverIdentifier, ulong sampleCount)
- {
- DriverIdentifier = driverIdentifier;
- SampleCount = sampleCount;
- SamplePlayed = 0;
- }
- }
-}
diff --git a/Ryujinx.Audio.Backends.SoundIo/SoundIoHardwareDeviceDriver.cs b/Ryujinx.Audio.Backends.SoundIo/SoundIoHardwareDeviceDriver.cs
deleted file mode 100644
index 02da2776..00000000
--- a/Ryujinx.Audio.Backends.SoundIo/SoundIoHardwareDeviceDriver.cs
+++ /dev/null
@@ -1,247 +0,0 @@
-using Ryujinx.Audio.Backends.SoundIo.Native;
-using Ryujinx.Audio.Common;
-using Ryujinx.Audio.Integration;
-using Ryujinx.Memory;
-using System;
-using System.Collections.Concurrent;
-using System.Threading;
-using static Ryujinx.Audio.Backends.SoundIo.Native.SoundIo;
-using static Ryujinx.Audio.Integration.IHardwareDeviceDriver;
-
-namespace Ryujinx.Audio.Backends.SoundIo
-{
- public class SoundIoHardwareDeviceDriver : IHardwareDeviceDriver
- {
- private readonly SoundIoContext _audioContext;
- private readonly SoundIoDeviceContext _audioDevice;
- private readonly ManualResetEvent _updateRequiredEvent;
- private readonly ManualResetEvent _pauseEvent;
- private readonly ConcurrentDictionary<SoundIoHardwareDeviceSession, byte> _sessions;
- private int _disposeState;
-
- public SoundIoHardwareDeviceDriver()
- {
- _audioContext = SoundIoContext.Create();
- _updateRequiredEvent = new ManualResetEvent(false);
- _pauseEvent = new ManualResetEvent(true);
- _sessions = new ConcurrentDictionary<SoundIoHardwareDeviceSession, byte>();
-
- _audioContext.Connect();
- _audioContext.FlushEvents();
-
- _audioDevice = FindValidAudioDevice(_audioContext, true);
- }
-
- public static bool IsSupported => IsSupportedInternal();
-
- private static bool IsSupportedInternal()
- {
- SoundIoContext context = null;
- SoundIoDeviceContext device = null;
- SoundIoOutStreamContext stream = null;
-
- bool backendDisconnected = false;
-
- try
- {
- context = SoundIoContext.Create();
- context.OnBackendDisconnect = err =>
- {
- backendDisconnected = true;
- };
-
- context.Connect();
- context.FlushEvents();
-
- if (backendDisconnected)
- {
- return false;
- }
-
- if (context.OutputDeviceCount == 0)
- {
- return false;
- }
-
- device = FindValidAudioDevice(context);
-
- if (device == null || backendDisconnected)
- {
- return false;
- }
-
- stream = device.CreateOutStream();
-
- if (stream == null || backendDisconnected)
- {
- return false;
- }
-
- return true;
- }
- catch
- {
- return false;
- }
- finally
- {
- stream?.Dispose();
- context?.Dispose();
- }
- }
-
- private static SoundIoDeviceContext FindValidAudioDevice(SoundIoContext audioContext, bool fallback = false)
- {
- SoundIoDeviceContext defaultAudioDevice = audioContext.GetOutputDevice(audioContext.DefaultOutputDeviceIndex);
-
- if (!defaultAudioDevice.IsRaw)
- {
- return defaultAudioDevice;
- }
-
- for (int i = 0; i < audioContext.OutputDeviceCount; i++)
- {
- SoundIoDeviceContext audioDevice = audioContext.GetOutputDevice(i);
-
- if (audioDevice.Id == defaultAudioDevice.Id && !audioDevice.IsRaw)
- {
- return audioDevice;
- }
- }
-
- return fallback ? defaultAudioDevice : null;
- }
-
- public ManualResetEvent GetUpdateRequiredEvent()
- {
- return _updateRequiredEvent;
- }
-
- public ManualResetEvent GetPauseEvent()
- {
- return _pauseEvent;
- }
-
- public IHardwareDeviceSession OpenDeviceSession(Direction direction, IVirtualMemoryManager memoryManager, SampleFormat sampleFormat, uint sampleRate, uint channelCount, float volume)
- {
- if (channelCount == 0)
- {
- channelCount = 2;
- }
-
- if (sampleRate == 0)
- {
- sampleRate = Constants.TargetSampleRate;
- }
-
- volume = Math.Clamp(volume, 0, 1);
-
- if (direction != Direction.Output)
- {
- throw new NotImplementedException("Input direction is currently not implemented on SoundIO backend!");
- }
-
- SoundIoHardwareDeviceSession session = new SoundIoHardwareDeviceSession(this, memoryManager, sampleFormat, sampleRate, channelCount, volume);
-
- _sessions.TryAdd(session, 0);
-
- return session;
- }
-
- internal bool Unregister(SoundIoHardwareDeviceSession session)
- {
- return _sessions.TryRemove(session, out _);
- }
-
- 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,
- _ => throw new ArgumentException ($"Unsupported sample format {format}"),
- };
- }
-
- internal SoundIoOutStreamContext OpenStream(SampleFormat requestedSampleFormat, uint requestedSampleRate, uint requestedChannelCount)
- {
- SoundIoFormat driverSampleFormat = GetSoundIoFormat(requestedSampleFormat);
-
- if (!_audioDevice.SupportsSampleRate((int)requestedSampleRate))
- {
- throw new ArgumentException($"This sound device does not support a sample rate of {requestedSampleRate}Hz");
- }
-
- if (!_audioDevice.SupportsFormat(driverSampleFormat))
- {
- throw new ArgumentException($"This sound device does not support {requestedSampleFormat}");
- }
-
- if (!_audioDevice.SupportsChannelCount((int)requestedChannelCount))
- {
- throw new ArgumentException($"This sound device does not support channel count {requestedChannelCount}");
- }
-
- SoundIoOutStreamContext result = _audioDevice.CreateOutStream();
-
- result.Name = "Ryujinx";
- result.Layout = SoundIoChannelLayout.GetDefaultValue((int)requestedChannelCount);
- result.Format = driverSampleFormat;
- result.SampleRate = (int)requestedSampleRate;
-
- return result;
- }
-
- internal void FlushContextEvents()
- {
- _audioContext.FlushEvents();
- }
-
- public void Dispose()
- {
- if (Interlocked.CompareExchange(ref _disposeState, 1, 0) == 0)
- {
- Dispose(true);
- }
- }
-
- protected virtual void Dispose(bool disposing)
- {
- if (disposing)
- {
- foreach (SoundIoHardwareDeviceSession session in _sessions.Keys)
- {
- session.Dispose();
- }
-
- _audioContext.Disconnect();
- _audioContext.Dispose();
- _pauseEvent.Dispose();
- }
- }
-
- public bool SupportsSampleRate(uint sampleRate)
- {
- return _audioDevice.SupportsSampleRate((int)sampleRate);
- }
-
- public bool SupportsSampleFormat(SampleFormat sampleFormat)
- {
- return _audioDevice.SupportsFormat(GetSoundIoFormat(sampleFormat));
- }
-
- public bool SupportsChannelCount(uint channelCount)
- {
- return _audioDevice.SupportsChannelCount((int)channelCount);
- }
-
- public bool SupportsDirection(Direction direction)
- {
- // TODO: add direction input when supported.
- return direction == Direction.Output;
- }
- }
-}
diff --git a/Ryujinx.Audio.Backends.SoundIo/SoundIoHardwareDeviceSession.cs b/Ryujinx.Audio.Backends.SoundIo/SoundIoHardwareDeviceSession.cs
deleted file mode 100644
index 96d9ce97..00000000
--- a/Ryujinx.Audio.Backends.SoundIo/SoundIoHardwareDeviceSession.cs
+++ /dev/null
@@ -1,438 +0,0 @@
-using Ryujinx.Audio.Backends.Common;
-using Ryujinx.Audio.Backends.SoundIo.Native;
-using Ryujinx.Audio.Common;
-using Ryujinx.Memory;
-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
-{
- class SoundIoHardwareDeviceSession : HardwareDeviceSessionOutputBase
- {
- private SoundIoHardwareDeviceDriver _driver;
- private ConcurrentQueue<SoundIoAudioBuffer> _queuedBuffers;
- private SoundIoOutStreamContext _outputStream;
- private DynamicRingBuffer _ringBuffer;
- private ulong _playedSampleCount;
- private ManualResetEvent _updateRequiredEvent;
- private int _disposeState;
-
- public SoundIoHardwareDeviceSession(SoundIoHardwareDeviceDriver driver, IVirtualMemoryManager memoryManager, SampleFormat requestedSampleFormat, uint requestedSampleRate, uint requestedChannelCount, float requestedVolume) : base(memoryManager, requestedSampleFormat, requestedSampleRate, requestedChannelCount)
- {
- _driver = driver;
- _updateRequiredEvent = _driver.GetUpdateRequiredEvent();
- _queuedBuffers = new ConcurrentQueue<SoundIoAudioBuffer>();
- _ringBuffer = new DynamicRingBuffer();
-
- SetupOutputStream(requestedVolume);
- }
-
- private void SetupOutputStream(float requestedVolume)
- {
- _outputStream = _driver.OpenStream(RequestedSampleFormat, RequestedSampleRate, RequestedChannelCount);
- _outputStream.WriteCallback += Update;
- _outputStream.Volume = requestedVolume;
- // TODO: Setup other callbacks (errors, ect).
-
- _outputStream.Open();
- }
-
- public override ulong GetPlayedSampleCount()
- {
- return Interlocked.Read(ref _playedSampleCount);
- }
-
- public override float GetVolume()
- {
- return _outputStream.Volume;
- }
-
- public override void PrepareToClose() { }
-
- public override void QueueBuffer(AudioBuffer buffer)
- {
- SoundIoAudioBuffer driverBuffer = new SoundIoAudioBuffer(buffer.DataPointer, GetSampleCount(buffer));
-
- _ringBuffer.Write(buffer.Data, 0, buffer.Data.Length);
-
- _queuedBuffers.Enqueue(driverBuffer);
- }
-
- public override void SetVolume(float volume)
- {
- _outputStream.SetVolume(volume);
- }
-
- public override void Start()
- {
- _outputStream.Start();
- _outputStream.Pause(false);
-
- _driver.FlushContextEvents();
- }
-
- public override void Stop()
- {
- _outputStream.Pause(true);
-
- _driver.FlushContextEvents();
- }
-
- public override void UnregisterBuffer(AudioBuffer buffer) {}
-
- public override bool WasBufferFullyConsumed(AudioBuffer buffer)
- {
- if (!_queuedBuffers.TryPeek(out SoundIoAudioBuffer driverBuffer))
- {
- return true;
- }
-
- return driverBuffer.DriverIdentifier != buffer.DataPointer;
- }
-
- private unsafe void Update(int minFrameCount, int maxFrameCount)
- {
- int bytesPerFrame = _outputStream.BytesPerFrame;
- uint bytesPerSample = (uint)_outputStream.BytesPerSample;
-
- int bufferedFrames = _ringBuffer.Length / bytesPerFrame;
-
- int frameCount = Math.Min(bufferedFrames, maxFrameCount);
-
- if (frameCount == 0)
- {
- return;
- }
-
- Span<SoundIoChannelArea> areas = _outputStream.BeginWrite(ref frameCount);
-
- int channelCount = areas.Length;
-
- byte[] samples = new byte[frameCount * bytesPerFrame];
-
- _ringBuffer.Read(samples, 0, samples.Length);
-
- // 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 2022?
-
- // Mono
- if (channelCount == 1)
- {
- ref SoundIoChannelArea area = ref areas[0];
-
- fixed (byte* srcptr = samples)
- {
- if (bytesPerSample == 1)
- {
- for (int frame = 0; frame < frameCount; frame++)
- {
- ((byte*)area.Pointer)[0] = srcptr[frame * bytesPerFrame];
-
- area.Pointer += area.Step;
- }
- }
- else if (bytesPerSample == 2)
- {
- for (int frame = 0; frame < frameCount; frame++)
- {
- ((short*)area.Pointer)[0] = ((short*)srcptr)[frame * bytesPerFrame >> 1];
-
- area.Pointer += area.Step;
- }
- }
- else if (bytesPerSample == 4)
- {
- for (int frame = 0; frame < frameCount; frame++)
- {
- ((int*)area.Pointer)[0] = ((int*)srcptr)[frame * bytesPerFrame >> 2];
-
- area.Pointer += area.Step;
- }
- }
- else
- {
- for (int frame = 0; frame < frameCount; frame++)
- {
- Unsafe.CopyBlockUnaligned((byte*)area.Pointer, srcptr + (frame * bytesPerFrame), bytesPerSample);
-
- area.Pointer += area.Step;
- }
- }
- }
- }
- // Stereo
- else if (channelCount == 2)
- {
- ref SoundIoChannelArea area1 = ref areas[0];
- ref SoundIoChannelArea area2 = ref areas[1];
-
- fixed (byte* srcptr = samples)
- {
- if (bytesPerSample == 1)
- {
- for (int frame = 0; frame < frameCount; frame++)
- {
- // Channel 1
- ((byte*)area1.Pointer)[0] = srcptr[(frame * bytesPerFrame) + 0];
-
- // Channel 2
- ((byte*)area2.Pointer)[0] = srcptr[(frame * bytesPerFrame) + 1];
-
- area1.Pointer += area1.Step;
- area2.Pointer += area2.Step;
- }
- }
- else if (bytesPerSample == 2)
- {
- for (int frame = 0; frame < frameCount; frame++)
- {
- // Channel 1
- ((short*)area1.Pointer)[0] = ((short*)srcptr)[(frame * bytesPerFrame >> 1) + 0];
-
- // Channel 2
- ((short*)area2.Pointer)[0] = ((short*)srcptr)[(frame * bytesPerFrame >> 1) + 1];
-
- area1.Pointer += area1.Step;
- area2.Pointer += area2.Step;
- }
- }
- else if (bytesPerSample == 4)
- {
- for (int frame = 0; frame < frameCount; frame++)
- {
- // Channel 1
- ((int*)area1.Pointer)[0] = ((int*)srcptr)[(frame * bytesPerFrame >> 2) + 0];
-
- // Channel 2
- ((int*)area2.Pointer)[0] = ((int*)srcptr)[(frame * bytesPerFrame >> 2) + 1];
-
- area1.Pointer += area1.Step;
- area2.Pointer += area2.Step;
- }
- }
- else
- {
- for (int frame = 0; frame < frameCount; frame++)
- {
- // Channel 1
- Unsafe.CopyBlockUnaligned((byte*)area1.Pointer, srcptr + (frame * bytesPerFrame) + (0 * bytesPerSample), bytesPerSample);
-
- // Channel 2
- Unsafe.CopyBlockUnaligned((byte*)area2.Pointer, srcptr + (frame * bytesPerFrame) + (1 * bytesPerSample), bytesPerSample);
-
- area1.Pointer += area1.Step;
- area2.Pointer += area2.Step;
- }
- }
- }
- }
- // Surround
- else if (channelCount == 6)
- {
- 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)
- {
- if (bytesPerSample == 1)
- {
- for (int frame = 0; frame < frameCount; frame++)
- {
- // Channel 1
- ((byte*)area1.Pointer)[0] = srcptr[(frame * bytesPerFrame) + 0];
-
- // Channel 2
- ((byte*)area2.Pointer)[0] = srcptr[(frame * bytesPerFrame) + 1];
-
- // Channel 3
- ((byte*)area3.Pointer)[0] = srcptr[(frame * bytesPerFrame) + 2];
-
- // Channel 4
- ((byte*)area4.Pointer)[0] = srcptr[(frame * bytesPerFrame) + 3];
-
- // Channel 5
- ((byte*)area5.Pointer)[0] = srcptr[(frame * bytesPerFrame) + 4];
-
- // Channel 6
- ((byte*)area6.Pointer)[0] = srcptr[(frame * bytesPerFrame) + 5];
-
- area1.Pointer += area1.Step;
- area2.Pointer += area2.Step;
- area3.Pointer += area3.Step;
- area4.Pointer += area4.Step;
- area5.Pointer += area5.Step;
- area6.Pointer += area6.Step;
- }
- }
- else if (bytesPerSample == 2)
- {
- for (int frame = 0; frame < frameCount; frame++)
- {
- // Channel 1
- ((short*)area1.Pointer)[0] = ((short*)srcptr)[(frame * bytesPerFrame >> 1) + 0];
-
- // Channel 2
- ((short*)area2.Pointer)[0] = ((short*)srcptr)[(frame * bytesPerFrame >> 1) + 1];
-
- // Channel 3
- ((short*)area3.Pointer)[0] = ((short*)srcptr)[(frame * bytesPerFrame >> 1) + 2];
-
- // Channel 4
- ((short*)area4.Pointer)[0] = ((short*)srcptr)[(frame * bytesPerFrame >> 1) + 3];
-
- // Channel 5
- ((short*)area5.Pointer)[0] = ((short*)srcptr)[(frame * bytesPerFrame >> 1) + 4];
-
- // Channel 6
- ((short*)area6.Pointer)[0] = ((short*)srcptr)[(frame * bytesPerFrame >> 1) + 5];
-
- area1.Pointer += area1.Step;
- area2.Pointer += area2.Step;
- area3.Pointer += area3.Step;
- area4.Pointer += area4.Step;
- area5.Pointer += area5.Step;
- area6.Pointer += area6.Step;
- }
- }
- else if (bytesPerSample == 4)
- {
- for (int frame = 0; frame < frameCount; frame++)
- {
- // Channel 1
- ((int*)area1.Pointer)[0] = ((int*)srcptr)[(frame * bytesPerFrame >> 2) + 0];
-
- // Channel 2
- ((int*)area2.Pointer)[0] = ((int*)srcptr)[(frame * bytesPerFrame >> 2) + 1];
-
- // Channel 3
- ((int*)area3.Pointer)[0] = ((int*)srcptr)[(frame * bytesPerFrame >> 2) + 2];
-
- // Channel 4
- ((int*)area4.Pointer)[0] = ((int*)srcptr)[(frame * bytesPerFrame >> 2) + 3];
-
- // Channel 5
- ((int*)area5.Pointer)[0] = ((int*)srcptr)[(frame * bytesPerFrame >> 2) + 4];
-
- // Channel 6
- ((int*)area6.Pointer)[0] = ((int*)srcptr)[(frame * bytesPerFrame >> 2) + 5];
-
- area1.Pointer += area1.Step;
- area2.Pointer += area2.Step;
- area3.Pointer += area3.Step;
- area4.Pointer += area4.Step;
- area5.Pointer += area5.Step;
- area6.Pointer += area6.Step;
- }
- }
- else
- {
- for (int frame = 0; frame < frameCount; frame++)
- {
- // Channel 1
- Unsafe.CopyBlockUnaligned((byte*)area1.Pointer, srcptr + (frame * bytesPerFrame) + (0 * bytesPerSample), bytesPerSample);
-
- // Channel 2
- Unsafe.CopyBlockUnaligned((byte*)area2.Pointer, srcptr + (frame * bytesPerFrame) + (1 * bytesPerSample), bytesPerSample);
-
- // Channel 3
- Unsafe.CopyBlockUnaligned((byte*)area3.Pointer, srcptr + (frame * bytesPerFrame) + (2 * bytesPerSample), bytesPerSample);
-
- // Channel 4
- Unsafe.CopyBlockUnaligned((byte*)area4.Pointer, srcptr + (frame * bytesPerFrame) + (3 * bytesPerSample), bytesPerSample);
-
- // Channel 5
- Unsafe.CopyBlockUnaligned((byte*)area5.Pointer, srcptr + (frame * bytesPerFrame) + (4 * bytesPerSample), bytesPerSample);
-
- // Channel 6
- Unsafe.CopyBlockUnaligned((byte*)area6.Pointer, srcptr + (frame * bytesPerFrame) + (5 * bytesPerSample), bytesPerSample);
-
- area1.Pointer += area1.Step;
- area2.Pointer += area2.Step;
- area3.Pointer += area3.Step;
- area4.Pointer += area4.Step;
- area5.Pointer += area5.Step;
- area6.Pointer += area6.Step;
- }
- }
- }
- }
- // Every other channel count
- else
- {
- fixed (byte* srcptr = samples)
- {
- for (int frame = 0; frame < frameCount; frame++)
- {
- for (int channel = 0; channel < areas.Length; channel++)
- {
- // Copy channel by channel, frame by frame. This is slow!
- Unsafe.CopyBlockUnaligned((byte*)areas[channel].Pointer, srcptr + (frame * bytesPerFrame) + (channel * bytesPerSample), bytesPerSample);
-
- areas[channel].Pointer += areas[channel].Step;
- }
- }
- }
- }
-
- _outputStream.EndWrite();
-
- ulong sampleCount = (ulong)(samples.Length / bytesPerSample / channelCount);
-
- ulong availaibleSampleCount = sampleCount;
-
- bool needUpdate = false;
-
- while (availaibleSampleCount > 0 && _queuedBuffers.TryPeek(out SoundIoAudioBuffer driverBuffer))
- {
- ulong sampleStillNeeded = driverBuffer.SampleCount - Interlocked.Read(ref driverBuffer.SamplePlayed);
- ulong playedAudioBufferSampleCount = Math.Min(sampleStillNeeded, availaibleSampleCount);
-
- Interlocked.Add(ref driverBuffer.SamplePlayed, playedAudioBufferSampleCount);
- availaibleSampleCount -= playedAudioBufferSampleCount;
-
- if (Interlocked.Read(ref driverBuffer.SamplePlayed) == driverBuffer.SampleCount)
- {
- _queuedBuffers.TryDequeue(out _);
-
- needUpdate = true;
- }
-
- Interlocked.Add(ref _playedSampleCount, playedAudioBufferSampleCount);
- }
-
- // Notify the output if needed.
- if (needUpdate)
- {
- _updateRequiredEvent.Set();
- }
- }
-
- protected virtual void Dispose(bool disposing)
- {
- if (disposing && _driver.Unregister(this))
- {
- PrepareToClose();
- Stop();
-
- _outputStream.Dispose();
- }
- }
-
- public override void Dispose()
- {
- if (Interlocked.CompareExchange(ref _disposeState, 1, 0) == 0)
- {
- Dispose(true);
- }
- }
- }
-}