blob: afa86befa4adc1d09f421904f64786ee7d2d2b08 (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
|
using System;
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);
}
}
}
|