AudioInServer.cs 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  1. using Ryujinx.Audio.Common;
  2. using Ryujinx.Cpu;
  3. using Ryujinx.HLE.HOS.Ipc;
  4. using Ryujinx.HLE.HOS.Kernel.Common;
  5. using Ryujinx.HLE.HOS.Kernel.Threading;
  6. using Ryujinx.Memory;
  7. using System;
  8. using System.Runtime.InteropServices;
  9. namespace Ryujinx.HLE.HOS.Services.Audio.AudioIn
  10. {
  11. class AudioInServer : DisposableIpcService
  12. {
  13. private IAudioIn _impl;
  14. public AudioInServer(IAudioIn impl)
  15. {
  16. _impl = impl;
  17. }
  18. [CommandHipc(0)]
  19. // GetAudioInState() -> u32 state
  20. public ResultCode GetAudioInState(ServiceCtx context)
  21. {
  22. context.ResponseData.Write((uint)_impl.GetState());
  23. return ResultCode.Success;
  24. }
  25. [CommandHipc(1)]
  26. // Start()
  27. public ResultCode Start(ServiceCtx context)
  28. {
  29. return _impl.Start();
  30. }
  31. [CommandHipc(2)]
  32. // Stop()
  33. public ResultCode StopAudioIn(ServiceCtx context)
  34. {
  35. return _impl.Stop();
  36. }
  37. [CommandHipc(3)]
  38. // AppendAudioInBuffer(u64 tag, buffer<nn::audio::AudioInBuffer, 5>)
  39. public ResultCode AppendAudioInBuffer(ServiceCtx context)
  40. {
  41. ulong position = context.Request.SendBuff[0].Position;
  42. ulong bufferTag = context.RequestData.ReadUInt64();
  43. AudioUserBuffer data = MemoryHelper.Read<AudioUserBuffer>(context.Memory, position);
  44. return _impl.AppendBuffer(bufferTag, ref data);
  45. }
  46. [CommandHipc(4)]
  47. // RegisterBufferEvent() -> handle<copy>
  48. public ResultCode RegisterBufferEvent(ServiceCtx context)
  49. {
  50. KEvent bufferEvent = _impl.RegisterBufferEvent();
  51. if (context.Process.HandleTable.GenerateHandle(bufferEvent.ReadableEvent, out int handle) != KernelResult.Success)
  52. {
  53. throw new InvalidOperationException("Out of handles!");
  54. }
  55. context.Response.HandleDesc = IpcHandleDesc.MakeCopy(handle);
  56. return ResultCode.Success;
  57. }
  58. [CommandHipc(5)]
  59. // GetReleasedAudioInBuffers() -> (u32 count, buffer<u64, 6> tags)
  60. public ResultCode GetReleasedAudioInBuffers(ServiceCtx context)
  61. {
  62. ulong position = context.Request.ReceiveBuff[0].Position;
  63. ulong size = context.Request.ReceiveBuff[0].Size;
  64. using (WritableRegion outputRegion = context.Memory.GetWritableRegion((ulong)position, (int)size))
  65. {
  66. ResultCode result = _impl.GetReleasedBuffers(MemoryMarshal.Cast<byte, ulong>(outputRegion.Memory.Span), out uint releasedCount);
  67. context.ResponseData.Write(releasedCount);
  68. return result;
  69. }
  70. }
  71. [CommandHipc(6)]
  72. // ContainsAudioInBuffer(u64 tag) -> b8
  73. public ResultCode ContainsAudioInBuffer(ServiceCtx context)
  74. {
  75. ulong bufferTag = context.RequestData.ReadUInt64();
  76. context.ResponseData.Write(_impl.ContainsBuffer(bufferTag));
  77. return ResultCode.Success;
  78. }
  79. [CommandHipc(7)] // 3.0.0+
  80. // AppendUacInBuffer(u64 tag, handle<copy, unknown>, buffer<nn::audio::AudioInBuffer, 5>)
  81. public ResultCode AppendUacInBuffer(ServiceCtx context)
  82. {
  83. ulong position = context.Request.SendBuff[0].Position;
  84. ulong bufferTag = context.RequestData.ReadUInt64();
  85. uint handle = (uint)context.Request.HandleDesc.ToCopy[0];
  86. AudioUserBuffer data = MemoryHelper.Read<AudioUserBuffer>(context.Memory, position);
  87. return _impl.AppendUacBuffer(bufferTag, ref data, handle);
  88. }
  89. [CommandHipc(8)] // 3.0.0+
  90. // AppendAudioInBufferAuto(u64 tag, buffer<nn::audio::AudioInBuffer, 0x21>)
  91. public ResultCode AppendAudioInBufferAuto(ServiceCtx context)
  92. {
  93. (ulong position, _) = context.Request.GetBufferType0x21();
  94. ulong bufferTag = context.RequestData.ReadUInt64();
  95. AudioUserBuffer data = MemoryHelper.Read<AudioUserBuffer>(context.Memory, position);
  96. return _impl.AppendBuffer(bufferTag, ref data);
  97. }
  98. [CommandHipc(9)] // 3.0.0+
  99. // GetReleasedAudioInBuffersAuto() -> (u32 count, buffer<u64, 0x22> tags)
  100. public ResultCode GetReleasedAudioInBuffersAuto(ServiceCtx context)
  101. {
  102. (ulong position, ulong size) = context.Request.GetBufferType0x22();
  103. using (WritableRegion outputRegion = context.Memory.GetWritableRegion(position, (int)size))
  104. {
  105. ResultCode result = _impl.GetReleasedBuffers(MemoryMarshal.Cast<byte, ulong>(outputRegion.Memory.Span), out uint releasedCount);
  106. context.ResponseData.Write(releasedCount);
  107. return result;
  108. }
  109. }
  110. [CommandHipc(10)] // 3.0.0+
  111. // AppendUacInBufferAuto(u64 tag, handle<copy, event>, buffer<nn::audio::AudioInBuffer, 0x21>)
  112. public ResultCode AppendUacInBufferAuto(ServiceCtx context)
  113. {
  114. (ulong position, _) = context.Request.GetBufferType0x21();
  115. ulong bufferTag = context.RequestData.ReadUInt64();
  116. uint handle = (uint)context.Request.HandleDesc.ToCopy[0];
  117. AudioUserBuffer data = MemoryHelper.Read<AudioUserBuffer>(context.Memory, position);
  118. return _impl.AppendUacBuffer(bufferTag, ref data, handle);
  119. }
  120. [CommandHipc(11)] // 4.0.0+
  121. // GetAudioInBufferCount() -> u32
  122. public ResultCode GetAudioInBufferCount(ServiceCtx context)
  123. {
  124. context.ResponseData.Write(_impl.GetBufferCount());
  125. return ResultCode.Success;
  126. }
  127. [CommandHipc(12)] // 4.0.0+
  128. // SetAudioInVolume(s32)
  129. public ResultCode SetAudioInVolume(ServiceCtx context)
  130. {
  131. float volume = context.RequestData.ReadSingle();
  132. _impl.SetVolume(volume);
  133. return ResultCode.Success;
  134. }
  135. [CommandHipc(13)] // 4.0.0+
  136. // GetAudioInVolume() -> s32
  137. public ResultCode GetAudioInVolume(ServiceCtx context)
  138. {
  139. context.ResponseData.Write(_impl.GetVolume());
  140. return ResultCode.Success;
  141. }
  142. [CommandHipc(14)] // 6.0.0+
  143. // FlushAudioInBuffers() -> b8
  144. public ResultCode FlushAudioInBuffers(ServiceCtx context)
  145. {
  146. context.ResponseData.Write(_impl.FlushBuffers());
  147. return ResultCode.Success;
  148. }
  149. protected override void Dispose(bool isDisposing)
  150. {
  151. if (isDisposing)
  152. {
  153. _impl.Dispose();
  154. }
  155. }
  156. }
  157. }