IAudioOutManager.cs 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. using ChocolArm64.Memory;
  2. using Ryujinx.Audio;
  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 IAudioOutManager : IpcService
  10. {
  11. private Dictionary<int, ServiceProcessRequest> m_Commands;
  12. public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
  13. public IAudioOutManager()
  14. {
  15. m_Commands = new Dictionary<int, ServiceProcessRequest>()
  16. {
  17. { 0, ListAudioOuts },
  18. { 1, OpenAudioOut }
  19. };
  20. }
  21. public long ListAudioOuts(ServiceCtx Context)
  22. {
  23. long Position = Context.Request.ReceiveBuff[0].Position;
  24. AMemoryHelper.WriteBytes(Context.Memory, Position, Encoding.ASCII.GetBytes("iface"));
  25. Context.ResponseData.Write(1);
  26. return 0;
  27. }
  28. public long OpenAudioOut(ServiceCtx Context)
  29. {
  30. IAalOutput AudioOut = Context.Ns.AudioOut;
  31. string DeviceName = AMemoryHelper.ReadAsciiString(
  32. Context.Memory,
  33. Context.Request.SendBuff[0].Position,
  34. Context.Request.SendBuff[0].Size);
  35. if (DeviceName == string.Empty)
  36. {
  37. DeviceName = "FIXME";
  38. }
  39. long DeviceNamePosition = Context.Request.ReceiveBuff[0].Position;
  40. long DeviceNameSize = Context.Request.ReceiveBuff[0].Size;
  41. byte[] DeviceNameBuffer = Encoding.ASCII.GetBytes(DeviceName);
  42. if (DeviceName.Length <= DeviceNameSize)
  43. {
  44. AMemoryHelper.WriteBytes(Context.Memory, DeviceNamePosition, DeviceNameBuffer);
  45. }
  46. int SampleRate = Context.RequestData.ReadInt32();
  47. int Channels = Context.RequestData.ReadInt32();
  48. Channels = (ushort)(Channels >> 16);
  49. if (SampleRate == 0)
  50. {
  51. SampleRate = 48000;
  52. }
  53. if (Channels < 1 || Channels > 2)
  54. {
  55. Channels = 2;
  56. }
  57. KEvent ReleaseEvent = new KEvent();
  58. ReleaseCallback Callback = () =>
  59. {
  60. ReleaseEvent.Handle.Set();
  61. };
  62. int Track = AudioOut.OpenTrack(SampleRate, Channels, Callback, out AudioFormat Format);
  63. MakeObject(Context, new IAudioOut(AudioOut, ReleaseEvent, Track));
  64. Context.ResponseData.Write(SampleRate);
  65. Context.ResponseData.Write(Channels);
  66. Context.ResponseData.Write((int)Format);
  67. Context.ResponseData.Write((int)PlaybackState.Stopped);
  68. return 0;
  69. }
  70. }
  71. }