IAudioDevice.cs 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. using ChocolArm64.Memory;
  2. using Ryujinx.Core.Logging;
  3. using Ryujinx.Core.OsHle.Handles;
  4. using Ryujinx.Core.OsHle.Ipc;
  5. using System.Collections.Generic;
  6. using System.Text;
  7. namespace Ryujinx.Core.OsHle.Services.Aud
  8. {
  9. class IAudioDevice : IpcService
  10. {
  11. private Dictionary<int, ServiceProcessRequest> m_Commands;
  12. public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
  13. private KEvent SystemEvent;
  14. public IAudioDevice()
  15. {
  16. m_Commands = new Dictionary<int, ServiceProcessRequest>()
  17. {
  18. { 0, ListAudioDeviceName },
  19. { 1, SetAudioDeviceOutputVolume },
  20. { 3, GetActiveAudioDeviceName },
  21. { 4, QueryAudioDeviceSystemEvent },
  22. { 5, GetActiveChannelCount }
  23. };
  24. SystemEvent = new KEvent();
  25. //TODO: We shouldn't be signaling this here.
  26. SystemEvent.WaitEvent.Set();
  27. }
  28. public long ListAudioDeviceName(ServiceCtx Context)
  29. {
  30. string[] DeviceNames = SystemStateMgr.AudioOutputs;
  31. Context.ResponseData.Write(DeviceNames.Length);
  32. long Position = Context.Request.ReceiveBuff[0].Position;
  33. long Size = Context.Request.ReceiveBuff[0].Size;
  34. long BasePosition = Position;
  35. foreach (string Name in DeviceNames)
  36. {
  37. byte[] Buffer = Encoding.ASCII.GetBytes(Name + "\0");
  38. if ((Position - BasePosition) + Buffer.Length > Size)
  39. {
  40. Context.Ns.Log.PrintError(LogClass.ServiceAudio, $"Output buffer size {Size} too small!");
  41. break;
  42. }
  43. AMemoryHelper.WriteBytes(Context.Memory, Position, Buffer);
  44. Position += Buffer.Length;
  45. }
  46. return 0;
  47. }
  48. public long SetAudioDeviceOutputVolume(ServiceCtx Context)
  49. {
  50. float Volume = Context.RequestData.ReadSingle();
  51. long Position = Context.Request.SendBuff[0].Position;
  52. long Size = Context.Request.SendBuff[0].Size;
  53. byte[] DeviceNameBuffer = AMemoryHelper.ReadBytes(Context.Memory, Position, Size);
  54. string DeviceName = Encoding.ASCII.GetString(DeviceNameBuffer);
  55. Context.Ns.Log.PrintStub(LogClass.ServiceAudio, "Stubbed.");
  56. return 0;
  57. }
  58. public long GetActiveAudioDeviceName(ServiceCtx Context)
  59. {
  60. string Name = Context.Ns.Os.SystemState.ActiveAudioOutput;
  61. long Position = Context.Request.ReceiveBuff[0].Position;
  62. long Size = Context.Request.ReceiveBuff[0].Size;
  63. byte[] DeviceNameBuffer = Encoding.ASCII.GetBytes(Name + "\0");
  64. if ((ulong)DeviceNameBuffer.Length <= (ulong)Size)
  65. {
  66. AMemoryHelper.WriteBytes(Context.Memory, Position, DeviceNameBuffer);
  67. }
  68. else
  69. {
  70. Context.Ns.Log.PrintError(LogClass.ServiceAudio, $"Output buffer size {Size} too small!");
  71. }
  72. return 0;
  73. }
  74. public long QueryAudioDeviceSystemEvent(ServiceCtx Context)
  75. {
  76. int Handle = Context.Process.HandleTable.OpenHandle(SystemEvent);
  77. Context.Response.HandleDesc = IpcHandleDesc.MakeCopy(Handle);
  78. Context.Ns.Log.PrintStub(LogClass.ServiceAudio, "Stubbed.");
  79. return 0;
  80. }
  81. public long GetActiveChannelCount(ServiceCtx Context)
  82. {
  83. Context.ResponseData.Write(2);
  84. Context.Ns.Log.PrintStub(LogClass.ServiceAudio, "Stubbed.");
  85. return 0;
  86. }
  87. }
  88. }