diff --git a/Ryujinx.HLE/OsHle/Services/Aud/AudErr.cs b/Ryujinx.HLE/OsHle/Services/Aud/AudErr.cs new file mode 100644 index 000000000..fa201d8cd --- /dev/null +++ b/Ryujinx.HLE/OsHle/Services/Aud/AudErr.cs @@ -0,0 +1,8 @@ +namespace Ryujinx.HLE.OsHle.Services.Aud +{ + static class AudErr + { + public const int DeviceNotFound = 1; + public const int UnsupportedSampleRate = 3; + } +} \ No newline at end of file diff --git a/Ryujinx.HLE/OsHle/Services/Aud/IAudioOutManager.cs b/Ryujinx.HLE/OsHle/Services/Aud/IAudioOutManager.cs index 18aedb32c..54ffa6d90 100644 --- a/Ryujinx.HLE/OsHle/Services/Aud/IAudioOutManager.cs +++ b/Ryujinx.HLE/OsHle/Services/Aud/IAudioOutManager.cs @@ -6,6 +6,8 @@ using Ryujinx.HLE.OsHle.Ipc; using System.Collections.Generic; using System.Text; +using static Ryujinx.HLE.OsHle.ErrorCode; + namespace Ryujinx.HLE.OsHle.Services.Aud { class IAudioOutManager : IpcService @@ -28,36 +30,44 @@ namespace Ryujinx.HLE.OsHle.Services.Aud } public long ListAudioOuts(ServiceCtx Context) - { - ListAudioOutsMethod(Context, Context.Request.ReceiveBuff[0].Position, Context.Request.ReceiveBuff[0].Size); - - return 0; + { + return ListAudioOutsImpl( + Context, + Context.Request.ReceiveBuff[0].Position, + Context.Request.ReceiveBuff[0].Size); } public long OpenAudioOut(ServiceCtx Context) { - OpenAudioOutMethod(Context, Context.Request.SendBuff[0].Position, Context.Request.SendBuff[0].Size, - Context.Request.ReceiveBuff[0].Position, Context.Request.ReceiveBuff[0].Size); - - return 0; + return OpenAudioOutImpl( + Context, + Context.Request.SendBuff[0].Position, + Context.Request.SendBuff[0].Size, + Context.Request.ReceiveBuff[0].Position, + Context.Request.ReceiveBuff[0].Size); } - + public long ListAudioOutsAuto(ServiceCtx Context) - { - ListAudioOutsMethod(Context, Context.Request.GetBufferType0x22().Position, Context.Request.GetBufferType0x22().Size); + { + (long RecvPosition, long RecvSize) = Context.Request.GetBufferType0x22(); - return 0; + return ListAudioOutsImpl(Context, RecvPosition, RecvSize); } - + public long OpenAudioOutAuto(ServiceCtx Context) { - OpenAudioOutMethod(Context, Context.Request.GetBufferType0x21().Position, Context.Request.GetBufferType0x21().Size, - Context.Request.GetBufferType0x22().Position, Context.Request.GetBufferType0x22().Size); + (long SendPosition, long SendSize) = Context.Request.GetBufferType0x21(); + (long RecvPosition, long RecvSize) = Context.Request.GetBufferType0x22(); - return 0; + return OpenAudioOutImpl( + Context, + SendPosition, + SendSize, + RecvPosition, + RecvSize); } - - public void ListAudioOutsMethod(ServiceCtx Context, long Position, long Size) + + private long ListAudioOutsImpl(ServiceCtx Context, long Position, long Size) { int NameCount = 0; @@ -75,23 +85,29 @@ namespace Ryujinx.HLE.OsHle.Services.Aud } Context.ResponseData.Write(NameCount); + + return 0; } - - public void OpenAudioOutMethod(ServiceCtx Context, long SendPosition, long SendSize, long ReceivePosition, long ReceiveSize) + + private long OpenAudioOutImpl(ServiceCtx Context, long SendPosition, long SendSize, long ReceivePosition, long ReceiveSize) { - IAalOutput AudioOut = Context.Ns.AudioOut; - string DeviceName = AMemoryHelper.ReadAsciiString( Context.Memory, SendPosition, - SendSize - ); - + SendSize); + if (DeviceName == string.Empty) { DeviceName = DefaultAudioOutput; } + if (DeviceName != DefaultAudioOutput) + { + Context.Ns.Log.PrintWarning(LogClass.Audio, "Invalid device name!"); + + return MakeError(ErrorModule.Audio, AudErr.DeviceNotFound); + } + byte[] DeviceNameBuffer = Encoding.ASCII.GetBytes(DeviceName + "\0"); if ((ulong)DeviceNameBuffer.Length <= (ulong)ReceiveSize) @@ -101,19 +117,21 @@ namespace Ryujinx.HLE.OsHle.Services.Aud else { Context.Ns.Log.PrintError(LogClass.ServiceAudio, $"Output buffer size {ReceiveSize} too small!"); - } + } int SampleRate = Context.RequestData.ReadInt32(); int Channels = Context.RequestData.ReadInt32(); - Channels = (ushort)(Channels >> 16); - - if (SampleRate == 0) + if (SampleRate != 48000) { - SampleRate = 48000; + Context.Ns.Log.PrintWarning(LogClass.Audio, "Invalid sample rate!"); + + return MakeError(ErrorModule.Audio, AudErr.UnsupportedSampleRate); } - if (Channels < 1 || Channels > 2) + Channels = (ushort)Channels; + + if (Channels == 0) { Channels = 2; } @@ -125,7 +143,9 @@ namespace Ryujinx.HLE.OsHle.Services.Aud ReleaseEvent.WaitEvent.Set(); }; - int Track = AudioOut.OpenTrack(SampleRate, Channels, Callback, out AudioFormat Format); + IAalOutput AudioOut = Context.Ns.AudioOut; + + int Track = AudioOut.OpenTrack(SampleRate, 2, Callback, out AudioFormat Format); MakeObject(Context, new IAudioOut(AudioOut, ReleaseEvent, Track)); @@ -133,6 +153,8 @@ namespace Ryujinx.HLE.OsHle.Services.Aud Context.ResponseData.Write(Channels); Context.ResponseData.Write((int)Format); Context.ResponseData.Write((int)PlaybackState.Stopped); + + return 0; } } }