Thing
This commit is contained in:
parent
2bd767f672
commit
94127f9c15
7 changed files with 166 additions and 47 deletions
|
@ -11,13 +11,13 @@
|
||||||
public int MixesSize;
|
public int MixesSize;
|
||||||
public int SinksSize;
|
public int SinksSize;
|
||||||
public int PerformanceBufferSize;
|
public int PerformanceBufferSize;
|
||||||
public int Padding0;
|
public int Unknown0;
|
||||||
public int Padding1;
|
public int Unknown1;
|
||||||
public int Padding2;
|
public int Unknown2;
|
||||||
public int Padding3;
|
public int Unknown3;
|
||||||
public int Padding4;
|
public int Unknown4;
|
||||||
public int Padding5;
|
public int Unknown5;
|
||||||
public int Padding6;
|
public int Unknown6;
|
||||||
public int TotalSize;
|
public int TotalSize;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
22
Ryujinx.HLE/OsHle/Services/Aud/AudioRendererParameters.cs
Normal file
22
Ryujinx.HLE/OsHle/Services/Aud/AudioRendererParameters.cs
Normal file
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,6 +1,4 @@
|
||||||
using System.Runtime.InteropServices;
|
namespace Ryujinx.HLE.OsHle.Services.Aud
|
||||||
|
|
||||||
namespace Ryujinx.HLE.OsHle.Services.Aud
|
|
||||||
{
|
{
|
||||||
struct AudioRendererResponse
|
struct AudioRendererResponse
|
||||||
{
|
{
|
||||||
|
@ -8,31 +6,18 @@ namespace Ryujinx.HLE.OsHle.Services.Aud
|
||||||
public int ErrorInfoSize;
|
public int ErrorInfoSize;
|
||||||
public int MemoryPoolsSize;
|
public int MemoryPoolsSize;
|
||||||
public int VoicesSize;
|
public int VoicesSize;
|
||||||
public int Unknown10;
|
public int Unknown0;
|
||||||
public int EffectsSize;
|
public int EffectsSize;
|
||||||
public int Unknown18;
|
public int Unknown1;
|
||||||
public int SinksSize;
|
public int SinksSize;
|
||||||
public int PerformanceManagerSize;
|
public int PerformanceManagerSize;
|
||||||
public int Padding0;
|
public int Unknown2;
|
||||||
public int Padding1;
|
public int Unknown3;
|
||||||
public int Padding2;
|
public int Unknown4;
|
||||||
public int Padding3;
|
public int Unknown5;
|
||||||
public int Padding4;
|
public int Unknown6;
|
||||||
public int Padding5;
|
public int Unknown7;
|
||||||
public int Padding6;
|
public int Unknown8;
|
||||||
public int TotalSize;
|
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,11 @@
|
||||||
|
using ChocolArm64.Memory;
|
||||||
using Ryujinx.HLE.Logging;
|
using Ryujinx.HLE.Logging;
|
||||||
using Ryujinx.HLE.OsHle.Handles;
|
using Ryujinx.HLE.OsHle.Handles;
|
||||||
using Ryujinx.HLE.OsHle.Ipc;
|
using Ryujinx.HLE.OsHle.Ipc;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
namespace Ryujinx.HLE.OsHle.Services.Aud
|
namespace Ryujinx.HLE.OsHle.Services.Aud
|
||||||
{
|
{
|
||||||
|
@ -14,7 +17,9 @@ namespace Ryujinx.HLE.OsHle.Services.Aud
|
||||||
|
|
||||||
private KEvent UpdateEvent;
|
private KEvent UpdateEvent;
|
||||||
|
|
||||||
public IAudioRenderer()
|
private AudioRendererParameters WorkerParams;
|
||||||
|
|
||||||
|
public IAudioRenderer(AudioRendererParameters WorkerParams)
|
||||||
{
|
{
|
||||||
m_Commands = new Dictionary<int, ServiceProcessRequest>()
|
m_Commands = new Dictionary<int, ServiceProcessRequest>()
|
||||||
{
|
{
|
||||||
|
@ -25,31 +30,106 @@ namespace Ryujinx.HLE.OsHle.Services.Aud
|
||||||
};
|
};
|
||||||
|
|
||||||
UpdateEvent = new KEvent();
|
UpdateEvent = new KEvent();
|
||||||
|
this.WorkerParams = WorkerParams;
|
||||||
}
|
}
|
||||||
|
|
||||||
public long RequestUpdateAudioRenderer(ServiceCtx Context)
|
public long RequestUpdateAudioRenderer(ServiceCtx Context)
|
||||||
{
|
{
|
||||||
//(buffer<unknown, 5, 0>) -> (buffer<unknown, 6, 0>, buffer<unknown, 6, 0>)
|
//(buffer<unknown, 5, 0>) -> (buffer<unknown, 6, 0>, buffer<unknown, 6, 0>)
|
||||||
|
|
||||||
long Position = Context.Request.ReceiveBuff[0].Position;
|
long OutputPosition = Context.Request.GetBufferType0x22().Position;
|
||||||
|
long InputPosition = Context.Request.GetBufferType0x21().Position;
|
||||||
|
|
||||||
//0x40 bytes header
|
AudioRendererConfig InputRequest = AMemoryHelper.Read<AudioRendererConfig>(Context.Memory, InputPosition);
|
||||||
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)
|
|
||||||
|
|
||||||
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<MemoryPoolInfo>(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.
|
//TODO: We shouldn't be signaling this here.
|
||||||
UpdateEvent.WaitEvent.Set();
|
UpdateEvent.WaitEvent.Set();
|
||||||
|
|
||||||
|
Context.Ns.Log.PrintStub(LogClass.ServiceAudio, "Stubbed.");
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -90,3 +170,4 @@ namespace Ryujinx.HLE.OsHle.Services.Aud
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
using Ryujinx.HLE.Logging;
|
using Ryujinx.HLE.Logging;
|
||||||
using Ryujinx.HLE.OsHle.Ipc;
|
using Ryujinx.HLE.OsHle.Ipc;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
namespace Ryujinx.HLE.OsHle.Services.Aud
|
namespace Ryujinx.HLE.OsHle.Services.Aud
|
||||||
{
|
{
|
||||||
|
@ -28,8 +29,13 @@ namespace Ryujinx.HLE.OsHle.Services.Aud
|
||||||
public long OpenAudioRenderer(ServiceCtx Context)
|
public long OpenAudioRenderer(ServiceCtx Context)
|
||||||
{
|
{
|
||||||
//Same buffer as GetAudioRendererWorkBufferSize is receive here.
|
//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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
12
Ryujinx.HLE/OsHle/Services/Aud/MemoryPoolInfo.cs
Normal file
12
Ryujinx.HLE/OsHle/Services/Aud/MemoryPoolInfo.cs
Normal file
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
13
Ryujinx.HLE/OsHle/Services/Aud/MemoryPoolStates.cs
Normal file
13
Ryujinx.HLE/OsHle/Services/Aud/MemoryPoolStates.cs
Normal file
|
@ -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
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue