diff --git a/Ryujinx.Core/OsHle/Services/Aud/IAudioOutManager.cs b/Ryujinx.Core/OsHle/Services/Aud/IAudioOutManager.cs index 82e547ae5..d2106232c 100644 --- a/Ryujinx.Core/OsHle/Services/Aud/IAudioOutManager.cs +++ b/Ryujinx.Core/OsHle/Services/Aud/IAudioOutManager.cs @@ -20,8 +20,10 @@ namespace Ryujinx.Core.OsHle.Services.Aud { m_Commands = new Dictionary() { - { 0, ListAudioOuts }, - { 1, OpenAudioOut } + { 0, ListAudioOuts }, + { 1, OpenAudioOut }, + { 2, ListAudioOutsAuto }, + { 3, OpenAudioOutAuto } }; } @@ -111,5 +113,94 @@ namespace Ryujinx.Core.OsHle.Services.Aud return 0; } + + public long ListAudioOutsAuto(ServiceCtx Context) + { + (long Position, long Size) = Context.Request.GetBufferType0x22(); + + int NameCount = 0; + + byte[] DeviceNameBuffer = Encoding.ASCII.GetBytes(DefaultAudioOutput + "\0"); + + if ((ulong)DeviceNameBuffer.Length <= (ulong)Size) + { + Context.Memory.WriteBytes(Position, DeviceNameBuffer); + + NameCount++; + } + else + { + Context.Ns.Log.PrintError(LogClass.ServiceAudio, $"Output buffer size {Size} too small!"); + } + + Context.ResponseData.Write(NameCount); + + return 0; + } + + public long OpenAudioOutAuto(ServiceCtx Context) + { + IAalOutput AudioOut = Context.Ns.AudioOut; + + (long SendPosition, long SendSize) = Context.Request.GetBufferType0x21(); + + string DeviceName = AMemoryHelper.ReadAsciiString( + Context.Memory, + SendPosition, + SendSize + ); + + if (DeviceName == string.Empty) + { + DeviceName = DefaultAudioOutput; + } + + long Position = Context.Request.ReceiveBuff[0].Position; + long Size = Context.Request.ReceiveBuff[0].Size; + + byte[] DeviceNameBuffer = Encoding.ASCII.GetBytes(DeviceName + "\0"); + + if ((ulong)DeviceNameBuffer.Length <= (ulong)Size) + { + Context.Memory.WriteBytes(Position, DeviceNameBuffer); + } + else + { + Context.Ns.Log.PrintError(LogClass.ServiceAudio, $"Output buffer size {Size} too small!"); + } + + int SampleRate = Context.RequestData.ReadInt32(); + int Channels = Context.RequestData.ReadInt32(); + + Channels = (ushort)(Channels >> 16); + + if (SampleRate == 0) + { + SampleRate = 48000; + } + + if (Channels < 1 || Channels > 2) + { + Channels = 2; + } + + KEvent ReleaseEvent = new KEvent(); + + ReleaseCallback Callback = () => + { + ReleaseEvent.WaitEvent.Set(); + }; + + int Track = AudioOut.OpenTrack(SampleRate, Channels, Callback, out AudioFormat Format); + + MakeObject(Context, new IAudioOut(AudioOut, ReleaseEvent, Track)); + + Context.ResponseData.Write(SampleRate); + Context.ResponseData.Write(Channels); + Context.ResponseData.Write((int)Format); + Context.ResponseData.Write((int)PlaybackState.Stopped); + + return 0; + } } -} \ No newline at end of file +}