ryujinx/Ryujinx.HLE/OsHle/Services/Aud/IAudioRenderer.cs

121 lines
4.2 KiB
C#
Raw Normal View History

2018-06-23 01:00:14 -04:00
using ChocolArm64.Memory;
using Ryujinx.HLE.Logging;
using Ryujinx.HLE.OsHle.Handles;
using Ryujinx.HLE.OsHle.Ipc;
using System;
using System.Collections.Generic;
2018-06-23 01:00:14 -04:00
using System.Runtime.InteropServices;
namespace Ryujinx.HLE.OsHle.Services.Aud
2018-02-04 18:08:20 -05:00
{
class IAudioRenderer : IpcService, IDisposable
2018-02-04 18:08:20 -05:00
{
private Dictionary<int, ServiceProcessRequest> m_Commands;
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
private KEvent UpdateEvent;
2018-06-23 01:00:14 -04:00
private AudioRendererParameter Params;
public IAudioRenderer(AudioRendererParameter Params)
{
m_Commands = new Dictionary<int, ServiceProcessRequest>()
{
{ 4, RequestUpdateAudioRenderer },
{ 5, StartAudioRenderer },
{ 6, StopAudioRenderer },
{ 7, QuerySystemEvent }
};
UpdateEvent = new KEvent();
2018-06-23 01:00:14 -04:00
this.Params = Params;
}
public long RequestUpdateAudioRenderer(ServiceCtx Context)
2018-02-04 18:08:20 -05:00
{
2018-06-23 01:00:14 -04:00
long OutputPosition = Context.Request.ReceiveBuff[0].Position;
long InputPosition = Context.Request.SendBuff[0].Position;
UpdateDataHeader InputDataHeader = AMemoryHelper.Read<UpdateDataHeader>(Context.Memory, InputPosition);
int MemoryPoolOffset = Marshal.SizeOf(InputDataHeader) + InputDataHeader.BehaviorSize;
UpdateDataHeader OutputDataHeader = new UpdateDataHeader();
2018-06-23 01:00:14 -04:00
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;
2018-02-04 18:08:20 -05:00
2018-06-23 01:00:14 -04:00
AMemoryHelper.Write(Context.Memory, OutputPosition, OutputDataHeader);
2018-02-04 18:08:20 -05:00
2018-06-23 01:00:14 -04:00
for (int Offset = 0x40; Offset < 0x40 + OutputDataHeader.MemoryPoolsSize; Offset += 0x10, MemoryPoolOffset += 0x20)
2018-02-04 18:08:20 -05:00
{
2018-06-23 01:00:14 -04:00
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);
}
2018-02-04 18:08:20 -05:00
}
//TODO: We shouldn't be signaling this here.
UpdateEvent.WaitEvent.Set();
2018-02-04 18:08:20 -05:00
return 0;
}
public long StartAudioRenderer(ServiceCtx Context)
2018-02-04 18:08:20 -05:00
{
2018-04-24 14:57:39 -04:00
Context.Ns.Log.PrintStub(LogClass.ServiceAudio, "Stubbed.");
2018-02-04 18:08:20 -05:00
return 0;
}
public long StopAudioRenderer(ServiceCtx Context)
{
2018-04-24 14:57:39 -04:00
Context.Ns.Log.PrintStub(LogClass.ServiceAudio, "Stubbed.");
return 0;
}
public long QuerySystemEvent(ServiceCtx Context)
2018-02-04 18:08:20 -05:00
{
int Handle = Context.Process.HandleTable.OpenHandle(UpdateEvent);
Context.Response.HandleDesc = IpcHandleDesc.MakeCopy(Handle);
2018-02-04 18:08:20 -05:00
return 0;
}
public void Dispose()
{
Dispose(true);
}
protected virtual void Dispose(bool Disposing)
{
if (Disposing)
{
UpdateEvent.Dispose();
}
}
2018-02-04 18:08:20 -05:00
}
2018-06-23 01:00:14 -04:00
}