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