/ src / Ryujinx.Audio.Backends.SoundIo / Native / SoundIoContext.cs
SoundIoContext.cs
  1  using System;
  2  using System.Runtime.CompilerServices;
  3  using System.Runtime.InteropServices;
  4  using System.Threading;
  5  using static Ryujinx.Audio.Backends.SoundIo.Native.SoundIo;
  6  
  7  namespace Ryujinx.Audio.Backends.SoundIo.Native
  8  {
  9      public class SoundIoContext : IDisposable
 10      {
 11          private IntPtr _context;
 12          private Action<SoundIoError> _onBackendDisconnect;
 13          private OnBackendDisconnectedDelegate _onBackendDisconnectNative;
 14  
 15          public IntPtr Context => _context;
 16  
 17          internal SoundIoContext(IntPtr context)
 18          {
 19              _context = context;
 20              _onBackendDisconnect = null;
 21              _onBackendDisconnectNative = null;
 22          }
 23  
 24          public SoundIoError Connect() => soundio_connect(_context);
 25          public void Disconnect() => soundio_disconnect(_context);
 26  
 27          public void FlushEvents() => soundio_flush_events(_context);
 28  
 29          public int OutputDeviceCount => soundio_output_device_count(_context);
 30  
 31          public int DefaultOutputDeviceIndex => soundio_default_output_device_index(_context);
 32  
 33          public Action<SoundIoError> OnBackendDisconnect
 34          {
 35              get { return _onBackendDisconnect; }
 36              set
 37              {
 38                  _onBackendDisconnect = value;
 39  
 40                  if (_onBackendDisconnect == null)
 41                  {
 42                      _onBackendDisconnectNative = null;
 43                  }
 44                  else
 45                  {
 46                      _onBackendDisconnectNative = (ctx, err) => _onBackendDisconnect(err);
 47                  }
 48  
 49                  GetContext().OnBackendDisconnected = Marshal.GetFunctionPointerForDelegate(_onBackendDisconnectNative);
 50              }
 51          }
 52  
 53          private ref SoundIoStruct GetContext()
 54          {
 55              unsafe
 56              {
 57                  return ref Unsafe.AsRef<SoundIoStruct>((SoundIoStruct*)_context);
 58              }
 59          }
 60  
 61          public SoundIoDeviceContext GetOutputDevice(int index)
 62          {
 63              IntPtr deviceContext = soundio_get_output_device(_context, index);
 64  
 65              if (deviceContext == IntPtr.Zero)
 66              {
 67                  return null;
 68              }
 69  
 70              return new SoundIoDeviceContext(deviceContext);
 71          }
 72  
 73          public static SoundIoContext Create()
 74          {
 75              IntPtr context = soundio_create();
 76  
 77              if (context == IntPtr.Zero)
 78              {
 79                  return null;
 80              }
 81  
 82              return new SoundIoContext(context);
 83          }
 84  
 85          protected virtual void Dispose(bool disposing)
 86          {
 87              IntPtr currentContext = Interlocked.Exchange(ref _context, IntPtr.Zero);
 88  
 89              if (currentContext != IntPtr.Zero)
 90              {
 91                  soundio_destroy(currentContext);
 92              }
 93          }
 94  
 95          public void Dispose()
 96          {
 97              Dispose(true);
 98              GC.SuppressFinalize(this);
 99          }
100  
101          ~SoundIoContext()
102          {
103              Dispose(false);
104          }
105      }
106  }