From 94127f9c159e8b222e7fedd9c8e2de76ab1b401d Mon Sep 17 00:00:00 2001 From: Starlet Date: Fri, 22 Jun 2018 02:06:46 -0400 Subject: [PATCH] Thing --- .../OsHle/Services/Aud/AudioRendererConfig.cs | 14 +-- .../Services/Aud/AudioRendererParameters.cs | 22 ++++ .../Services/Aud/AudioRendererResponse.cs | 35 ++---- .../OsHle/Services/Aud/IAudioRenderer.cs | 109 +++++++++++++++--- .../Services/Aud/IAudioRendererManager.cs | 8 +- .../OsHle/Services/Aud/MemoryPoolInfo.cs | 12 ++ .../OsHle/Services/Aud/MemoryPoolStates.cs | 13 +++ 7 files changed, 166 insertions(+), 47 deletions(-) create mode 100644 Ryujinx.HLE/OsHle/Services/Aud/AudioRendererParameters.cs create mode 100644 Ryujinx.HLE/OsHle/Services/Aud/MemoryPoolInfo.cs create mode 100644 Ryujinx.HLE/OsHle/Services/Aud/MemoryPoolStates.cs diff --git a/Ryujinx.HLE/OsHle/Services/Aud/AudioRendererConfig.cs b/Ryujinx.HLE/OsHle/Services/Aud/AudioRendererConfig.cs index 3072eb6f52..8c28224950 100644 --- a/Ryujinx.HLE/OsHle/Services/Aud/AudioRendererConfig.cs +++ b/Ryujinx.HLE/OsHle/Services/Aud/AudioRendererConfig.cs @@ -11,13 +11,13 @@ public int MixesSize; public int SinksSize; public int PerformanceBufferSize; - public int Padding0; - public int Padding1; - public int Padding2; - public int Padding3; - public int Padding4; - public int Padding5; - public int Padding6; + public int Unknown0; + public int Unknown1; + public int Unknown2; + public int Unknown3; + public int Unknown4; + public int Unknown5; + public int Unknown6; public int TotalSize; } } diff --git a/Ryujinx.HLE/OsHle/Services/Aud/AudioRendererParameters.cs b/Ryujinx.HLE/OsHle/Services/Aud/AudioRendererParameters.cs new file mode 100644 index 0000000000..09a0a20150 --- /dev/null +++ b/Ryujinx.HLE/OsHle/Services/Aud/AudioRendererParameters.cs @@ -0,0 +1,22 @@ +namespace Ryujinx.HLE.OsHle.Services.Aud +{ + struct AudioRendererParameters + { + public int SampleRate; + public int SampleCount; + public int Unknown0; + public int Unknown1; + public int VoiceCount; + public int SinkCount; + public int EffectCount; + public int Unknown2; + public byte Unknown3; + public byte Padding0; + public byte Padding1; + public byte Padding2; + public int SplitterCount; + public int Unknown4; + public int Padding3; + public int Magic; + } +} diff --git a/Ryujinx.HLE/OsHle/Services/Aud/AudioRendererResponse.cs b/Ryujinx.HLE/OsHle/Services/Aud/AudioRendererResponse.cs index 3e7c04c764..bd95516418 100644 --- a/Ryujinx.HLE/OsHle/Services/Aud/AudioRendererResponse.cs +++ b/Ryujinx.HLE/OsHle/Services/Aud/AudioRendererResponse.cs @@ -1,6 +1,4 @@ -using System.Runtime.InteropServices; - -namespace Ryujinx.HLE.OsHle.Services.Aud +namespace Ryujinx.HLE.OsHle.Services.Aud { struct AudioRendererResponse { @@ -8,31 +6,18 @@ namespace Ryujinx.HLE.OsHle.Services.Aud public int ErrorInfoSize; public int MemoryPoolsSize; public int VoicesSize; - public int Unknown10; + public int Unknown0; public int EffectsSize; - public int Unknown18; + public int Unknown1; public int SinksSize; public int PerformanceManagerSize; - public int Padding0; - public int Padding1; - public int Padding2; - public int Padding3; - public int Padding4; - public int Padding5; - public int Padding6; + public int Unknown2; + public int Unknown3; + public int Unknown4; + public int Unknown5; + public int Unknown6; + public int Unknown7; + public int Unknown8; public int TotalSize; - - AudioRendererResponse(AudioRendererConfig Config) - { - Revision = Config.Revision; - ErrorInfoSize = 0xb0; - MemoryPoolsSize = (Config.MemoryPoolsSize / 0x20) * 0x10; - VoicesSize = (Config.VoicesSize / 0x170) * 0x10; - EffectsSize = (Config.EffectsSize / 0xC0) * 0x10; - SinksSize = (Config.SinksSize / 0x140) * 0x20; - PerformanceManagerSize = 0x10; - TotalSize = Marshal.SizeOf(AudioRendererResponse) + ErrorInfoSize + MemoryPoolsSize + - VoicesSize + EffectsSize + SinksSize + PerformanceManagerSize; - } } } diff --git a/Ryujinx.HLE/OsHle/Services/Aud/IAudioRenderer.cs b/Ryujinx.HLE/OsHle/Services/Aud/IAudioRenderer.cs index 9c495db5a0..cd551cc06d 100644 --- a/Ryujinx.HLE/OsHle/Services/Aud/IAudioRenderer.cs +++ b/Ryujinx.HLE/OsHle/Services/Aud/IAudioRenderer.cs @@ -1,8 +1,11 @@ +using ChocolArm64.Memory; using Ryujinx.HLE.Logging; using Ryujinx.HLE.OsHle.Handles; using Ryujinx.HLE.OsHle.Ipc; using System; using System.Collections.Generic; +using System.IO; +using System.Runtime.InteropServices; namespace Ryujinx.HLE.OsHle.Services.Aud { @@ -14,7 +17,9 @@ namespace Ryujinx.HLE.OsHle.Services.Aud private KEvent UpdateEvent; - public IAudioRenderer() + private AudioRendererParameters WorkerParams; + + public IAudioRenderer(AudioRendererParameters WorkerParams) { m_Commands = new Dictionary() { @@ -24,32 +29,107 @@ namespace Ryujinx.HLE.OsHle.Services.Aud { 7, QuerySystemEvent } }; - UpdateEvent = new KEvent(); + UpdateEvent = new KEvent(); + this.WorkerParams = WorkerParams; } public long RequestUpdateAudioRenderer(ServiceCtx Context) { //(buffer) -> (buffer, buffer) - long Position = Context.Request.ReceiveBuff[0].Position; + long OutputPosition = Context.Request.GetBufferType0x22().Position; + long InputPosition = Context.Request.GetBufferType0x21().Position; - //0x40 bytes header - Context.Memory.WriteInt32(Position + 0x4, 0xb0); //Behavior Out State Size? (note: this is the last section) - Context.Memory.WriteInt32(Position + 0x8, 0x18e0); //Memory Pool Out State Size? - Context.Memory.WriteInt32(Position + 0xc, 0x600); //Voice Out State Size? - Context.Memory.WriteInt32(Position + 0x14, 0xe0); //Effect Out State Size? - Context.Memory.WriteInt32(Position + 0x1c, 0x20); //Sink Out State Size? - Context.Memory.WriteInt32(Position + 0x20, 0x10); //Performance Out State Size? - Context.Memory.WriteInt32(Position + 0x3c, 0x20e0); //Total Size (including 0x40 bytes header) + AudioRendererConfig InputRequest = AMemoryHelper.Read(Context.Memory, InputPosition); - for (int Offset = 0x40; Offset < 0x40 + 0x18e0; Offset += 0x10) + int MemoryPoolCount = WorkerParams.EffectCount + (WorkerParams.VoiceCount * 4); + + int MemoryPoolOffset = Marshal.SizeOf(InputRequest) + InputRequest.BehaviourSize; + + MemoryPoolInfo[] PoolInfo = new MemoryPoolInfo[MemoryPoolCount]; + + for (int Index = 0; Index < MemoryPoolCount; Index++) { - Context.Memory.WriteInt32(Position + Offset, 5); + PoolInfo[Index] = AMemoryHelper.Read(Context.Memory, InputPosition + MemoryPoolOffset + Index * 0x20); } + GCHandle Handle = GCHandle.Alloc(WorkerParams, GCHandleType.Pinned); + + AudioRendererResponse OutputResponse = (AudioRendererResponse)Marshal.PtrToStructure(Handle.AddrOfPinnedObject(), typeof(AudioRendererResponse)); + + Handle.Free(); + + OutputResponse.Revision = WorkerParams.Magic; + OutputResponse.ErrorInfoSize = 0xb0; + OutputResponse.MemoryPoolsSize = (WorkerParams.EffectCount + (WorkerParams.VoiceCount * 4)) * 0x10; + OutputResponse.VoicesSize = WorkerParams.VoiceCount * 0x10; + OutputResponse.EffectsSize = WorkerParams.EffectCount * 0x10; + OutputResponse.SinksSize = WorkerParams.SinkCount * 0x20; + OutputResponse.PerformanceManagerSize = 0x10; + OutputResponse.TotalSize = Marshal.SizeOf(OutputResponse) + OutputResponse.ErrorInfoSize + OutputResponse.MemoryPoolsSize + + OutputResponse.VoicesSize + OutputResponse.EffectsSize + OutputResponse.SinksSize + OutputResponse.PerformanceManagerSize; + + Context.Ns.Log.PrintInfo(LogClass.ServiceAudio, $"TotalSize: {OutputResponse.TotalSize}"); + Context.Ns.Log.PrintInfo(LogClass.ServiceAudio, $"MemoryPoolsSize: {OutputResponse.MemoryPoolsSize}"); + Context.Ns.Log.PrintInfo(LogClass.ServiceAudio, $"MemoryPoolCount: {MemoryPoolCount}"); + + byte[] Output = new byte[OutputResponse.TotalSize]; + + IntPtr Ptr = Marshal.AllocHGlobal(Output.Length); + + Marshal.StructureToPtr(OutputResponse, Ptr, true); + + Marshal.Copy(Ptr, Output, 0, Output.Length); + + Marshal.FreeHGlobal(Ptr); + + MemoryPoolEntry[] PoolEntry = new MemoryPoolEntry[MemoryPoolCount]; + + for (int Index = 0; Index < PoolEntry.Length; Index++) + { + if (PoolInfo[Index].PoolState == (int)MemoryPoolStates.MPS_RequestAttach) + PoolEntry[Index].State = (int)MemoryPoolStates.MPS_RequestAttach; + else if (PoolInfo[Index].PoolState == (int)MemoryPoolStates.MPS_RequestDetatch) + PoolEntry[Index].State = (int)MemoryPoolStates.MPS_Detatched; + else + PoolEntry[Index].State = PoolInfo[Index].PoolState; + } + + bool First = false; + + byte[] PoolEntryArray = new byte[16 * MemoryPoolCount]; + + for (int Index = 0; Index < PoolEntry.Length; Index++) + { + if (!First) + { + IntPtr PtrPool = Marshal.AllocHGlobal(PoolEntryArray.Length); + Marshal.StructureToPtr(PoolEntry[Index], PtrPool, true); + Marshal.Copy(PtrPool, PoolEntryArray, Index, PoolEntryArray.Length); + Marshal.FreeHGlobal(PtrPool); + } + /*else + { + IntPtr PtrPool = Marshal.AllocHGlobal(PoolEntryArray.Length); + Marshal.StructureToPtr(PoolEntry[Index], PtrPool, true); + Marshal.Copy(PtrPool, PoolEntryArray, Marshal.SizeOf(PoolEntry[Index]) * Index, PoolEntryArray.Length); + Marshal.FreeHGlobal(PtrPool); + }*/ + + First = true; + } + + File.WriteAllBytes("PoolTest.bin", PoolEntryArray); + + Array.Copy(PoolEntryArray, 0, Output, Marshal.SizeOf(OutputResponse), PoolEntryArray.Length); + + Context.Memory.WriteBytes(OutputPosition + 0x4, Output); + //TODO: We shouldn't be signaling this here. UpdateEvent.WaitEvent.Set(); + Context.Ns.Log.PrintStub(LogClass.ServiceAudio, "Stubbed."); + return 0; } @@ -89,4 +169,5 @@ namespace Ryujinx.HLE.OsHle.Services.Aud } } } -} \ No newline at end of file +} + \ No newline at end of file diff --git a/Ryujinx.HLE/OsHle/Services/Aud/IAudioRendererManager.cs b/Ryujinx.HLE/OsHle/Services/Aud/IAudioRendererManager.cs index 6c0ba87058..64acfab9cc 100644 --- a/Ryujinx.HLE/OsHle/Services/Aud/IAudioRendererManager.cs +++ b/Ryujinx.HLE/OsHle/Services/Aud/IAudioRendererManager.cs @@ -1,6 +1,7 @@ using Ryujinx.HLE.Logging; using Ryujinx.HLE.OsHle.Ipc; using System.Collections.Generic; +using System.Runtime.InteropServices; namespace Ryujinx.HLE.OsHle.Services.Aud { @@ -28,8 +29,13 @@ namespace Ryujinx.HLE.OsHle.Services.Aud public long OpenAudioRenderer(ServiceCtx Context) { //Same buffer as GetAudioRendererWorkBufferSize is receive here. + GCHandle Handle = GCHandle.Alloc(Context.RequestData.ReadBytes(Marshal.SizeOf(typeof(AudioRendererParameters))), GCHandleType.Pinned); - MakeObject(Context, new IAudioRenderer()); + AudioRendererParameters WorkerParams = (AudioRendererParameters)Marshal.PtrToStructure(Handle.AddrOfPinnedObject(), typeof(AudioRendererParameters)); + + Handle.Free(); + + MakeObject(Context, new IAudioRenderer(WorkerParams)); return 0; } diff --git a/Ryujinx.HLE/OsHle/Services/Aud/MemoryPoolInfo.cs b/Ryujinx.HLE/OsHle/Services/Aud/MemoryPoolInfo.cs new file mode 100644 index 0000000000..2d808439e6 --- /dev/null +++ b/Ryujinx.HLE/OsHle/Services/Aud/MemoryPoolInfo.cs @@ -0,0 +1,12 @@ +namespace Ryujinx.HLE.OsHle.Services.Aud +{ + struct MemoryPoolInfo + { + public long PoolAddress; + public long PoolSize; + public int PoolState; + public int Unknown0; + public int Unknown1; + public int Unknown2; + } +} diff --git a/Ryujinx.HLE/OsHle/Services/Aud/MemoryPoolStates.cs b/Ryujinx.HLE/OsHle/Services/Aud/MemoryPoolStates.cs new file mode 100644 index 0000000000..4b7ca2b983 --- /dev/null +++ b/Ryujinx.HLE/OsHle/Services/Aud/MemoryPoolStates.cs @@ -0,0 +1,13 @@ +namespace Ryujinx.HLE.OsHle.Services.Aud +{ + enum MemoryPoolStates : int + { + MPS_Invalid = 0x0, + MPS_Unknown = 0x1, + MPS_RequestDetatch = 0x2, + MPS_Detatched = 0x3, + MPS_RequestAttach = 0x4, + MPS_Attached = 0x5, + MPS_Released = 0x6 + } +}