diff --git a/Ryujinx.HLE/OsHle/Services/Aud/AudErr.cs b/Ryujinx.HLE/OsHle/Services/Aud/AudErr.cs index fa201d8cdf..72c3e65eb9 100644 --- a/Ryujinx.HLE/OsHle/Services/Aud/AudErr.cs +++ b/Ryujinx.HLE/OsHle/Services/Aud/AudErr.cs @@ -3,6 +3,7 @@ namespace Ryujinx.HLE.OsHle.Services.Aud static class AudErr { public const int DeviceNotFound = 1; + public const int UnsupportedRevision = 2; public const int UnsupportedSampleRate = 3; } } \ No newline at end of file diff --git a/Ryujinx.HLE/OsHle/Services/Aud/AudioOut/IAudioOut.cs b/Ryujinx.HLE/OsHle/Services/Aud/AudioOut/IAudioOut.cs index 900187ba89..d89fc293af 100644 --- a/Ryujinx.HLE/OsHle/Services/Aud/AudioOut/IAudioOut.cs +++ b/Ryujinx.HLE/OsHle/Services/Aud/AudioOut/IAudioOut.cs @@ -1,6 +1,5 @@ using ChocolArm64.Memory; using Ryujinx.Audio; -using Ryujinx.HLE.Logging; using Ryujinx.HLE.OsHle.Handles; using Ryujinx.HLE.OsHle.Ipc; using System; diff --git a/Ryujinx.HLE/OsHle/Services/Aud/AudioRenderer/VoiceContext.cs b/Ryujinx.HLE/OsHle/Services/Aud/AudioRenderer/VoiceContext.cs index 7fbe46eafa..1bf9ed73e8 100644 --- a/Ryujinx.HLE/OsHle/Services/Aud/AudioRenderer/VoiceContext.cs +++ b/Ryujinx.HLE/OsHle/Services/Aud/AudioRenderer/VoiceContext.cs @@ -180,7 +180,7 @@ namespace Ryujinx.HLE.OsHle.Services.Aud.AudioRenderer public void SetBufferIndex(int Index) { - BufferIndex = Index; + BufferIndex = Index & 3; BufferReload = true; } diff --git a/Ryujinx.HLE/OsHle/Services/Aud/IAudioRendererManager.cs b/Ryujinx.HLE/OsHle/Services/Aud/IAudioRendererManager.cs index f2086e15b8..543b0697a5 100644 --- a/Ryujinx.HLE/OsHle/Services/Aud/IAudioRendererManager.cs +++ b/Ryujinx.HLE/OsHle/Services/Aud/IAudioRendererManager.cs @@ -2,8 +2,11 @@ using Ryujinx.Audio; using Ryujinx.HLE.Logging; using Ryujinx.HLE.OsHle.Ipc; using Ryujinx.HLE.OsHle.Services.Aud.AudioRenderer; +using Ryujinx.HLE.OsHle.Utilities; using System.Collections.Generic; +using static Ryujinx.HLE.OsHle.ErrorCode; + namespace Ryujinx.HLE.OsHle.Services.Aud { class IAudioRendererManager : IpcService @@ -31,6 +34,82 @@ namespace Ryujinx.HLE.OsHle.Services.Aud { IAalOutput AudioOut = Context.Ns.AudioOut; + AudioRendererParameter Params = GetAudioRendererParameter(Context); + + MakeObject(Context, new IAudioRenderer(Context.Memory, AudioOut, Params)); + + return 0; + } + + public long GetAudioRendererWorkBufferSize(ServiceCtx Context) + { + AudioRendererParameter Params = GetAudioRendererParameter(Context); + + int Revision = (Params.Revision - Rev0Magic) >> 24; + + if (Revision <= 3) //REV3 Max is supported + { + bool IsSplitterSupported = Revision >= 3; + + long Size; + + Size = IntUtils.AlignUp(Params.Unknown8 * 4, 64); + Size += Params.UnknownC * 0x400; + Size += (Params.UnknownC + 1) * 0x940; + Size += Params.VoiceCount * 0x3F0; + Size += IntUtils.AlignUp((Params.UnknownC + 1) * 8, 16); + Size += IntUtils.AlignUp(Params.VoiceCount * 8, 16); + Size += IntUtils.AlignUp( + ((Params.SinkCount + Params.UnknownC) * 0x3C0 + Params.SampleCount * 4) * + (Params.Unknown8 + 6), 64); + Size += (Params.SinkCount + Params.UnknownC) * 0x2C0; + Size += (Params.EffectCount + 4 * Params.VoiceCount) * 0x30 + 0x50; + + if (IsSplitterSupported) + { + Size += IntUtils.AlignUp(( + NodeStatesGetWorkBufferSize(Params.UnknownC + 1) + + EdgeMatrixGetWorkBufferSize(Params.UnknownC + 1)), 16); + + Size += Params.Unknown28 * 0xE0; + Size += Params.SplitterCount * 0x20; + Size += IntUtils.AlignUp(Params.Unknown28 * 4, 16); + } + + Size = Params.EffectCount * 0x4C0 + + Params.SinkCount * 0x170 + + Params.VoiceCount * 0x100 + + IntUtils.AlignUp(Size, 64) + 0x40; + + if (Params.Unknown1C >= 1) + { + Size += (((Params.EffectCount + + Params.SinkCount + + Params.VoiceCount + + Params.UnknownC + 1) * 16 + 0x658) * + (Params.Unknown1C + 1) + 0x13F) & ~0x3FL; + } + + Size = (Size + 0x1907D) & ~0xFFFL; + + Context.ResponseData.Write(Size); + + Context.Ns.Log.PrintDebug(LogClass.ServiceAudio, $"WorkBufferSize is 0x{Size:x16}."); + + return 0; + } + else + { + Context.ResponseData.Write(0L); + + Context.Ns.Log.PrintWarning(LogClass.ServiceAudio, $"Library Revision 0x{Params.Revision:x8} is not supported!"); + + return MakeError(ErrorModule.Audio, AudErr.UnsupportedRevision); + } + } + + private AudioRendererParameter GetAudioRendererParameter(ServiceCtx Context) + { AudioRendererParameter Params = new AudioRendererParameter(); Params.SampleRate = Context.RequestData.ReadInt32(); @@ -47,79 +126,12 @@ namespace Ryujinx.HLE.OsHle.Services.Aud Params.Unknown2C = Context.RequestData.ReadInt32(); Params.Revision = Context.RequestData.ReadInt32(); - MakeObject(Context, new IAudioRenderer(Context.Memory, AudioOut, Params)); - - return 0; - } - - public long GetAudioRendererWorkBufferSize(ServiceCtx Context) - { - long SampleRate = Context.RequestData.ReadUInt32(); - long Unknown4 = Context.RequestData.ReadUInt32(); - long Unknown8 = Context.RequestData.ReadUInt32(); - long UnknownC = Context.RequestData.ReadUInt32(); - long Unknown10 = Context.RequestData.ReadUInt32(); //VoiceCount - long Unknown14 = Context.RequestData.ReadUInt32(); //SinkCount - long Unknown18 = Context.RequestData.ReadUInt32(); //EffectCount - long Unknown1c = Context.RequestData.ReadUInt32(); //Boolean - long Unknown20 = Context.RequestData.ReadUInt32(); //Not used here in FW3.0.1 - Boolean - long Unknown24 = Context.RequestData.ReadUInt32(); - long Unknown28 = Context.RequestData.ReadUInt32(); //SplitterCount - long Unknown2c = Context.RequestData.ReadUInt32(); //Not used here in FW3.0.1 - int RevMagic = Context.RequestData.ReadInt32(); - - int Version = (RevMagic - Rev0Magic) >> 24; - - if (Version <= 3) //REV3 Max is supported - { - long Size = RoundUp(Unknown8 * 4, 64); - Size += (UnknownC << 10); - Size += (UnknownC + 1) * 0x940; - Size += Unknown10 * 0x3F0; - Size += RoundUp((UnknownC + 1) * 8, 16); - Size += RoundUp(Unknown10 * 8, 16); - Size += RoundUp((0x3C0 * (Unknown14 + UnknownC) + 4 * Unknown4) * (Unknown8 + 6), 64); - Size += 0x2C0 * (Unknown14 + UnknownC) + 0x30 * (Unknown18 + (4 * Unknown10)) + 0x50; - - if (Version >= 3) //IsSplitterSupported - { - Size += RoundUp((NodeStatesGetWorkBufferSize((int)UnknownC + 1) + EdgeMatrixGetWorkBufferSize((int)UnknownC + 1)), 16); - Size += 0xE0 * Unknown28 + 0x20 * Unknown24 + RoundUp(Unknown28 * 4, 16); - } - - Size = 0x4C0 * Unknown18 + RoundUp(Size, 64) + 0x170 * Unknown14 + ((Unknown10 << 8) | 0x40); - - if (Unknown1c >= 1) - { - Size += ((((Unknown18 + Unknown14 + Unknown10 + UnknownC + 1) * 16) + 0x658) * (Unknown1c + 1) + 0x13F) & ~0x3FL; - } - - long WorkBufferSize = (Size + 0x1907D) & ~0xFFFL; - - Context.ResponseData.Write(WorkBufferSize); - - Context.Ns.Log.PrintDebug(LogClass.ServiceAudio, $"WorkBufferSize is 0x{WorkBufferSize:x16}."); - - return 0; - } - else - { - Context.ResponseData.Write(0L); - - Context.Ns.Log.PrintError(LogClass.ServiceAudio, $"Library Revision 0x{RevMagic:x8} is not supported!"); - - return 0x499; - } - } - - private static long RoundUp(long Value, int Size) - { - return (Value + (Size - 1)) & ~((long)Size - 1); + return Params; } private static int NodeStatesGetWorkBufferSize(int Value) { - int Result = (int)RoundUp(Value, 64); + int Result = IntUtils.AlignUp(Value, 64); if (Result < 0) { @@ -131,7 +143,7 @@ namespace Ryujinx.HLE.OsHle.Services.Aud private static int EdgeMatrixGetWorkBufferSize(int Value) { - int Result = (int)RoundUp(Value * Value, 64); + int Result = IntUtils.AlignUp(Value * Value, 64); if (Result < 0) { diff --git a/Ryujinx.HLE/OsHle/Services/Nv/NvMap/NvMapIoctl.cs b/Ryujinx.HLE/OsHle/Services/Nv/NvMap/NvMapIoctl.cs index ec10a37588..4c6107f8f8 100644 --- a/Ryujinx.HLE/OsHle/Services/Nv/NvMap/NvMapIoctl.cs +++ b/Ryujinx.HLE/OsHle/Services/Nv/NvMap/NvMapIoctl.cs @@ -48,7 +48,7 @@ namespace Ryujinx.HLE.OsHle.Services.Nv.NvMap return NvResult.InvalidInput; } - int Size = IntUtils.RoundUp(Args.Size, NvGpuVmm.PageSize); + int Size = IntUtils.AlignUp(Args.Size, NvGpuVmm.PageSize); Args.Handle = AddNvMap(Context, new NvMapHandle(Size)); @@ -121,7 +121,7 @@ namespace Ryujinx.HLE.OsHle.Services.Nv.NvMap Map.Align = Args.Align; Map.Kind = (byte)Args.Kind; - int Size = IntUtils.RoundUp(Map.Size, NvGpuVmm.PageSize); + int Size = IntUtils.AlignUp(Map.Size, NvGpuVmm.PageSize); long Address = Args.Address; diff --git a/Ryujinx.HLE/OsHle/Utilities/IntUtils.cs b/Ryujinx.HLE/OsHle/Utilities/IntUtils.cs index ba0726c317..39cced280a 100644 --- a/Ryujinx.HLE/OsHle/Utilities/IntUtils.cs +++ b/Ryujinx.HLE/OsHle/Utilities/IntUtils.cs @@ -2,12 +2,12 @@ namespace Ryujinx.HLE.OsHle.Utilities { static class IntUtils { - public static int RoundUp(int Value, int Size) + public static int AlignUp(int Value, int Size) { return (Value + (Size - 1)) & ~(Size - 1); } - public static long RoundUp(long Value, int Size) + public static long AlignUp(long Value, int Size) { return (Value + (Size - 1)) & ~((long)Size - 1); }