SoundIoContext.cs 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. using System;
  2. using System.Reflection.Metadata;
  3. using System.Runtime.CompilerServices;
  4. using System.Runtime.InteropServices;
  5. using System.Threading;
  6. using static Ryujinx.Audio.Backends.SoundIo.Native.SoundIo;
  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. public IntPtr Context => _context;
  15. internal SoundIoContext(IntPtr context)
  16. {
  17. _context = context;
  18. _onBackendDisconnect = null;
  19. _onBackendDisconnectNative = null;
  20. }
  21. public SoundIoError Connect() => soundio_connect(_context);
  22. public void Disconnect() => soundio_disconnect(_context);
  23. public void FlushEvents() => soundio_flush_events(_context);
  24. public int OutputDeviceCount => soundio_output_device_count(_context);
  25. public int DefaultOutputDeviceIndex => soundio_default_output_device_index(_context);
  26. public Action<SoundIoError> OnBackendDisconnect
  27. {
  28. get { return _onBackendDisconnect; }
  29. set
  30. {
  31. _onBackendDisconnect = value;
  32. if (_onBackendDisconnect == null)
  33. {
  34. _onBackendDisconnectNative = null;
  35. }
  36. else
  37. {
  38. _onBackendDisconnectNative = (ctx, err) => _onBackendDisconnect(err);
  39. }
  40. GetContext().OnBackendDisconnected = Marshal.GetFunctionPointerForDelegate(_onBackendDisconnectNative);
  41. }
  42. }
  43. private ref SoundIoStruct GetContext()
  44. {
  45. unsafe
  46. {
  47. return ref Unsafe.AsRef<SoundIoStruct>((SoundIoStruct*)_context);
  48. }
  49. }
  50. public SoundIoDeviceContext GetOutputDevice(int index)
  51. {
  52. IntPtr deviceContext = soundio_get_output_device(_context, index);
  53. if (deviceContext == IntPtr.Zero)
  54. {
  55. return null;
  56. }
  57. return new SoundIoDeviceContext(deviceContext);
  58. }
  59. public static SoundIoContext Create()
  60. {
  61. IntPtr context = soundio_create();
  62. if (context == IntPtr.Zero)
  63. {
  64. return null;
  65. }
  66. return new SoundIoContext(context);
  67. }
  68. protected virtual void Dispose(bool disposing)
  69. {
  70. IntPtr currentContext = Interlocked.Exchange(ref _context, IntPtr.Zero);
  71. if (currentContext != IntPtr.Zero)
  72. {
  73. soundio_destroy(currentContext);
  74. }
  75. }
  76. public void Dispose()
  77. {
  78. Dispose(true);
  79. GC.SuppressFinalize(this);
  80. }
  81. ~SoundIoContext()
  82. {
  83. Dispose(false);
  84. }
  85. }
  86. }