From ddb8351375fe58e37072a9577e1341a2e7f437d2 Mon Sep 17 00:00:00 2001 From: Billy Laws Date: Tue, 6 Jul 2021 18:49:51 +0100 Subject: [PATCH] Implement 12.0.0 hwopus functions (#2410) Based off of my RE of 12.0.2 audio services, the newly added parameter can be safely ignored due to ryu not using fixed-size I/O buffers. --- .../Audio/IHardwareOpusDecoderManager.cs | 31 ++++++++++++++++++- .../Services/Audio/Types/OpusDecoderFlags.cs | 11 +++++++ .../Services/Audio/Types/OpusParametersEx.cs | 15 +++++++++ 3 files changed, 56 insertions(+), 1 deletion(-) create mode 100644 Ryujinx.HLE/HOS/Services/Audio/Types/OpusDecoderFlags.cs create mode 100644 Ryujinx.HLE/HOS/Services/Audio/Types/OpusParametersEx.cs diff --git a/Ryujinx.HLE/HOS/Services/Audio/IHardwareOpusDecoderManager.cs b/Ryujinx.HLE/HOS/Services/Audio/IHardwareOpusDecoderManager.cs index b341f087..d8e4f75d 100644 --- a/Ryujinx.HLE/HOS/Services/Audio/IHardwareOpusDecoderManager.cs +++ b/Ryujinx.HLE/HOS/Services/Audio/IHardwareOpusDecoderManager.cs @@ -1,4 +1,6 @@ +using Ryujinx.Common; using Ryujinx.HLE.HOS.Services.Audio.HardwareOpusDecoderManager; +using Ryujinx.HLE.HOS.Services.Audio.Types; namespace Ryujinx.HLE.HOS.Services.Audio { @@ -26,7 +28,7 @@ namespace Ryujinx.HLE.HOS.Services.Audio // GetWorkBufferSize(bytes<8, 4>) -> u32 public ResultCode GetWorkBufferSize(ServiceCtx context) { - // Note: The sample rate is ignored because it is fixed to 48KHz. + // NOTE: The sample rate is ignored because it is fixed to 48KHz. int sampleRate = context.RequestData.ReadInt32(); int channelsCount = context.RequestData.ReadInt32(); @@ -35,6 +37,33 @@ namespace Ryujinx.HLE.HOS.Services.Audio return ResultCode.Success; } + [CommandHipc(4)] // 12.0.0+ + // InitializeEx(OpusParametersEx, u32, handle) -> object + public ResultCode InitializeEx(ServiceCtx context) + { + OpusParametersEx parameters = context.RequestData.ReadStruct(); + + // UseLargeFrameSize can be ignored due to not relying on fixed size buffers for storing the decoded result. + MakeObject(context, new IHardwareOpusDecoder(parameters.SampleRate, parameters.ChannelCount)); + + // Close transfer memory immediately as we don't use it. + context.Device.System.KernelContext.Syscall.CloseHandle(context.Request.HandleDesc.ToCopy[0]); + + return ResultCode.Success; + } + + [CommandHipc(5)] // 12.0.0+ + // GetWorkBufferSizeEx(OpusParametersEx) -> u32 + public ResultCode GetWorkBufferSizeEx(ServiceCtx context) + { + OpusParametersEx parameters = context.RequestData.ReadStruct(); + + // NOTE: The sample rate is ignored because it is fixed to 48KHz. + context.ResponseData.Write(GetOpusDecoderSize(parameters.ChannelCount)); + + return ResultCode.Success; + } + private static int GetOpusDecoderSize(int channelsCount) { const int silkDecoderSize = 0x2198; diff --git a/Ryujinx.HLE/HOS/Services/Audio/Types/OpusDecoderFlags.cs b/Ryujinx.HLE/HOS/Services/Audio/Types/OpusDecoderFlags.cs new file mode 100644 index 00000000..e49c294c --- /dev/null +++ b/Ryujinx.HLE/HOS/Services/Audio/Types/OpusDecoderFlags.cs @@ -0,0 +1,11 @@ +using System; + +namespace Ryujinx.HLE.HOS.Services.Audio.Types +{ + [Flags] + enum OpusDecoderFlags : uint + { + None, + LargeFrameSize = 1 << 0, + } +} diff --git a/Ryujinx.HLE/HOS/Services/Audio/Types/OpusParametersEx.cs b/Ryujinx.HLE/HOS/Services/Audio/Types/OpusParametersEx.cs new file mode 100644 index 00000000..f00df2f8 --- /dev/null +++ b/Ryujinx.HLE/HOS/Services/Audio/Types/OpusParametersEx.cs @@ -0,0 +1,15 @@ +using Ryujinx.Common.Memory; +using System.Runtime.InteropServices; + +namespace Ryujinx.HLE.HOS.Services.Audio.Types +{ + [StructLayout(LayoutKind.Sequential, Size = 0x10)] + struct OpusParametersEx + { + public int SampleRate; + public int ChannelCount; + public OpusDecoderFlags UseLargeFrameSize; + + Array4 Padding1; + } +}