forked from Mirror/Ryujinx
Better audren implementation (#179)
This commit is contained in:
parent
3e6afeb513
commit
5182361f4b
5 changed files with 119 additions and 16 deletions
22
Ryujinx.HLE/OsHle/Services/Aud/AudioRendererParameter.cs
Normal file
22
Ryujinx.HLE/OsHle/Services/Aud/AudioRendererParameter.cs
Normal file
|
@ -0,0 +1,22 @@
|
|||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Ryujinx.HLE.OsHle.Services.Aud
|
||||
{
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
struct AudioRendererParameter
|
||||
{
|
||||
public int SampleRate;
|
||||
public int SampleCount;
|
||||
public int Unknown8;
|
||||
public int UnknownC;
|
||||
public int VoiceCount;
|
||||
public int SinkCount;
|
||||
public int EffectCount;
|
||||
public int Unknown1C;
|
||||
public int Unknown20;
|
||||
public int SplitterCount;
|
||||
public int Unknown28;
|
||||
public int Unknown2C;
|
||||
public int Revision;
|
||||
}
|
||||
}
|
|
@ -1,8 +1,10 @@
|
|||
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.Runtime.InteropServices;
|
||||
|
||||
namespace Ryujinx.HLE.OsHle.Services.Aud
|
||||
{
|
||||
|
@ -14,7 +16,9 @@ namespace Ryujinx.HLE.OsHle.Services.Aud
|
|||
|
||||
private KEvent UpdateEvent;
|
||||
|
||||
public IAudioRenderer()
|
||||
private AudioRendererParameter Params;
|
||||
|
||||
public IAudioRenderer(AudioRendererParameter Params)
|
||||
{
|
||||
m_Commands = new Dictionary<int, ServiceProcessRequest>()
|
||||
{
|
||||
|
@ -25,26 +29,50 @@ namespace Ryujinx.HLE.OsHle.Services.Aud
|
|||
};
|
||||
|
||||
UpdateEvent = new KEvent();
|
||||
|
||||
this.Params = Params;
|
||||
}
|
||||
|
||||
public long RequestUpdateAudioRenderer(ServiceCtx Context)
|
||||
{
|
||||
//(buffer<unknown, 5, 0>) -> (buffer<unknown, 6, 0>, buffer<unknown, 6, 0>)
|
||||
long OutputPosition = Context.Request.ReceiveBuff[0].Position;
|
||||
|
||||
long Position = Context.Request.ReceiveBuff[0].Position;
|
||||
long InputPosition = Context.Request.SendBuff[0].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)
|
||||
UpdateDataHeader InputDataHeader = AMemoryHelper.Read<UpdateDataHeader>(Context.Memory, InputPosition);
|
||||
|
||||
for (int Offset = 0x40; Offset < 0x40 + 0x18e0; Offset += 0x10)
|
||||
int MemoryPoolOffset = Marshal.SizeOf(InputDataHeader) + InputDataHeader.BehaviorSize;
|
||||
|
||||
UpdateDataHeader OutputDataHeader = new UpdateDataHeader();
|
||||
|
||||
OutputDataHeader.Revision = Params.Revision;
|
||||
OutputDataHeader.BehaviorSize = 0xb0;
|
||||
OutputDataHeader.MemoryPoolsSize = (Params.EffectCount + (Params.VoiceCount * 4)) * 0x10;
|
||||
OutputDataHeader.VoicesSize = Params.VoiceCount * 0x10;
|
||||
OutputDataHeader.EffectsSize = Params.EffectCount * 0x10;
|
||||
OutputDataHeader.SinksSize = Params.SinkCount * 0x20;
|
||||
OutputDataHeader.PerformanceManagerSize = 0x10;
|
||||
OutputDataHeader.TotalSize = Marshal.SizeOf(OutputDataHeader) + OutputDataHeader.BehaviorSize + OutputDataHeader.MemoryPoolsSize +
|
||||
OutputDataHeader.VoicesSize + OutputDataHeader.EffectsSize + OutputDataHeader.SinksSize + OutputDataHeader.PerformanceManagerSize;
|
||||
|
||||
AMemoryHelper.Write(Context.Memory, OutputPosition, OutputDataHeader);
|
||||
|
||||
for (int Offset = 0x40; Offset < 0x40 + OutputDataHeader.MemoryPoolsSize; Offset += 0x10, MemoryPoolOffset += 0x20)
|
||||
{
|
||||
Context.Memory.WriteInt32(Position + Offset, 5);
|
||||
MemoryPoolStates PoolState = (MemoryPoolStates) Context.Memory.ReadInt32(InputPosition + MemoryPoolOffset + 0x10);
|
||||
|
||||
if (PoolState == MemoryPoolStates.RequestAttach)
|
||||
{
|
||||
Context.Memory.WriteInt32(OutputPosition + Offset, (int)MemoryPoolStates.Attached);
|
||||
}
|
||||
else if (PoolState == MemoryPoolStates.RequestDetach)
|
||||
{
|
||||
Context.Memory.WriteInt32(OutputPosition + Offset, (int)MemoryPoolStates.Detached);
|
||||
}
|
||||
else
|
||||
{
|
||||
Context.Memory.WriteInt32(OutputPosition + Offset, (int)PoolState);
|
||||
}
|
||||
}
|
||||
|
||||
//TODO: We shouldn't be signaling this here.
|
||||
|
@ -89,4 +117,5 @@ namespace Ryujinx.HLE.OsHle.Services.Aud
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
{
|
||||
|
@ -29,7 +30,23 @@ namespace Ryujinx.HLE.OsHle.Services.Aud
|
|||
{
|
||||
//Same buffer as GetAudioRendererWorkBufferSize is receive here.
|
||||
|
||||
MakeObject(Context, new IAudioRenderer());
|
||||
AudioRendererParameter Params = new AudioRendererParameter();
|
||||
|
||||
Params.SampleRate = Context.RequestData.ReadInt32();
|
||||
Params.SampleCount = Context.RequestData.ReadInt32();
|
||||
Params.Unknown8 = Context.RequestData.ReadInt32();
|
||||
Params.UnknownC = Context.RequestData.ReadInt32();
|
||||
Params.VoiceCount = Context.RequestData.ReadInt32();
|
||||
Params.SinkCount = Context.RequestData.ReadInt32();
|
||||
Params.EffectCount = Context.RequestData.ReadInt32();
|
||||
Params.Unknown1C = Context.RequestData.ReadInt32();
|
||||
Params.Unknown20 = Context.RequestData.ReadInt32();
|
||||
Params.SplitterCount = Context.RequestData.ReadInt32();
|
||||
Params.Unknown28 = Context.RequestData.ReadInt32();
|
||||
Params.Unknown2C = Context.RequestData.ReadInt32();
|
||||
Params.Revision = Context.RequestData.ReadInt32();
|
||||
|
||||
MakeObject(Context, new IAudioRenderer(Params));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -48,7 +65,7 @@ namespace Ryujinx.HLE.OsHle.Services.Aud
|
|||
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 RevMagic = Context.RequestData.ReadInt32();
|
||||
|
||||
int Version = (RevMagic - Rev0Magic) >> 24;
|
||||
|
||||
|
|
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
|
||||
{
|
||||
Invalid = 0x0,
|
||||
Unknown = 0x1,
|
||||
RequestDetach = 0x2,
|
||||
Detached = 0x3,
|
||||
RequestAttach = 0x4,
|
||||
Attached = 0x5,
|
||||
Released = 0x6,
|
||||
}
|
||||
}
|
22
Ryujinx.HLE/OsHle/Services/Aud/UpdateDataHeader.cs
Normal file
22
Ryujinx.HLE/OsHle/Services/Aud/UpdateDataHeader.cs
Normal file
|
@ -0,0 +1,22 @@
|
|||
namespace Ryujinx.HLE.OsHle.Services.Aud
|
||||
{
|
||||
struct UpdateDataHeader
|
||||
{
|
||||
public int Revision;
|
||||
public int BehaviorSize;
|
||||
public int MemoryPoolsSize;
|
||||
public int VoicesSize;
|
||||
public int VoiceResourceSize;
|
||||
public int EffectsSize;
|
||||
public int MixesSize;
|
||||
public int SinksSize;
|
||||
public int PerformanceManagerSize;
|
||||
public int Unknown24;
|
||||
public int Unknown28;
|
||||
public int Unknown2C;
|
||||
public int Unknown30;
|
||||
public int Unknown34;
|
||||
public int Unknown38;
|
||||
public int TotalSize;
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue