Ver Fonte

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.
Billy Laws há 4 anos atrás
pai
commit
ddb8351375

+ 30 - 1
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<copy>) -> object<nn::codec::detail::IHardwareOpusDecoder>
+        public ResultCode InitializeEx(ServiceCtx context)
+        {
+            OpusParametersEx parameters = context.RequestData.ReadStruct<OpusParametersEx>();
+
+            // 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<OpusParametersEx>();
+
+            // 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;

+ 11 - 0
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,
+    }
+}

+ 15 - 0
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<byte> Padding1;
+    }
+}