2018-06-23 06:00:14 +01:00
|
|
|
using ChocolArm64.Memory;
|
2018-06-11 01:46:42 +01:00
|
|
|
using Ryujinx.HLE.Logging;
|
|
|
|
using Ryujinx.HLE.OsHle.Handles;
|
|
|
|
using Ryujinx.HLE.OsHle.Ipc;
|
2018-03-19 18:58:46 +00:00
|
|
|
using System;
|
2018-02-10 00:14:55 +00:00
|
|
|
using System.Collections.Generic;
|
2018-06-23 06:00:14 +01:00
|
|
|
using System.Runtime.InteropServices;
|
2018-02-08 16:52:02 +00:00
|
|
|
|
2018-06-11 01:46:42 +01:00
|
|
|
namespace Ryujinx.HLE.OsHle.Services.Aud
|
2018-02-04 23:08:20 +00:00
|
|
|
{
|
2018-03-19 18:58:46 +00:00
|
|
|
class IAudioRenderer : IpcService, IDisposable
|
2018-02-04 23:08:20 +00:00
|
|
|
{
|
2018-02-10 00:14:55 +00:00
|
|
|
private Dictionary<int, ServiceProcessRequest> m_Commands;
|
|
|
|
|
2018-03-19 18:58:46 +00:00
|
|
|
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => m_Commands;
|
|
|
|
|
|
|
|
private KEvent UpdateEvent;
|
2018-02-10 00:14:55 +00:00
|
|
|
|
2018-06-23 06:00:14 +01:00
|
|
|
private AudioRendererParameter Params;
|
|
|
|
|
|
|
|
public IAudioRenderer(AudioRendererParameter Params)
|
2018-02-10 00:14:55 +00:00
|
|
|
{
|
|
|
|
m_Commands = new Dictionary<int, ServiceProcessRequest>()
|
|
|
|
{
|
|
|
|
{ 4, RequestUpdateAudioRenderer },
|
|
|
|
{ 5, StartAudioRenderer },
|
|
|
|
{ 6, StopAudioRenderer },
|
|
|
|
{ 7, QuerySystemEvent }
|
|
|
|
};
|
2018-03-19 18:58:46 +00:00
|
|
|
|
|
|
|
UpdateEvent = new KEvent();
|
2018-06-23 06:00:14 +01:00
|
|
|
|
|
|
|
this.Params = Params;
|
2018-02-10 00:14:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public long RequestUpdateAudioRenderer(ServiceCtx Context)
|
2018-02-04 23:08:20 +00:00
|
|
|
{
|
2018-06-23 06:00:14 +01:00
|
|
|
long OutputPosition = Context.Request.ReceiveBuff[0].Position;
|
2018-06-23 07:17:07 +01:00
|
|
|
long OutputSize = Context.Request.ReceiveBuff[0].Size;
|
|
|
|
|
|
|
|
AMemoryHelper.FillWithZeros(Context.Memory, OutputPosition, (int)OutputSize);
|
2018-06-23 06:00:14 +01:00
|
|
|
|
|
|
|
long InputPosition = Context.Request.SendBuff[0].Position;
|
|
|
|
|
|
|
|
UpdateDataHeader InputDataHeader = AMemoryHelper.Read<UpdateDataHeader>(Context.Memory, InputPosition);
|
|
|
|
|
|
|
|
UpdateDataHeader OutputDataHeader = new UpdateDataHeader();
|
2018-02-08 16:52:02 +00:00
|
|
|
|
2018-06-25 06:04:19 +01:00
|
|
|
int UpdateHeaderSize = Marshal.SizeOf<UpdateDataHeader>();
|
|
|
|
|
2018-06-23 06:00:14 +01:00
|
|
|
OutputDataHeader.Revision = Params.Revision;
|
|
|
|
OutputDataHeader.BehaviorSize = 0xb0;
|
2018-06-25 06:04:19 +01:00
|
|
|
OutputDataHeader.MemoryPoolsSize = (Params.EffectCount + Params.VoiceCount * 4) * 0x10;
|
2018-06-23 06:00:14 +01:00
|
|
|
OutputDataHeader.VoicesSize = Params.VoiceCount * 0x10;
|
|
|
|
OutputDataHeader.EffectsSize = Params.EffectCount * 0x10;
|
|
|
|
OutputDataHeader.SinksSize = Params.SinkCount * 0x20;
|
|
|
|
OutputDataHeader.PerformanceManagerSize = 0x10;
|
2018-06-25 06:04:19 +01:00
|
|
|
OutputDataHeader.TotalSize = UpdateHeaderSize +
|
2018-06-23 07:17:07 +01:00
|
|
|
OutputDataHeader.BehaviorSize +
|
|
|
|
OutputDataHeader.MemoryPoolsSize +
|
|
|
|
OutputDataHeader.VoicesSize +
|
|
|
|
OutputDataHeader.EffectsSize +
|
|
|
|
OutputDataHeader.SinksSize +
|
|
|
|
OutputDataHeader.PerformanceManagerSize;
|
2018-02-04 23:08:20 +00:00
|
|
|
|
2018-06-23 06:00:14 +01:00
|
|
|
AMemoryHelper.Write(Context.Memory, OutputPosition, OutputDataHeader);
|
2018-02-04 23:08:20 +00:00
|
|
|
|
2018-06-25 06:04:19 +01:00
|
|
|
int InMemoryPoolOffset = UpdateHeaderSize + InputDataHeader.BehaviorSize;
|
|
|
|
|
|
|
|
int OutMemoryPoolOffset = UpdateHeaderSize;
|
|
|
|
|
|
|
|
for (int Offset = 0; Offset < OutputDataHeader.MemoryPoolsSize; Offset += 0x10, InMemoryPoolOffset += 0x20)
|
2018-02-04 23:08:20 +00:00
|
|
|
{
|
2018-06-25 06:04:19 +01:00
|
|
|
MemoryPoolState PoolState = (MemoryPoolState)Context.Memory.ReadInt32(InputPosition + InMemoryPoolOffset + 0x10);
|
2018-06-23 06:00:14 +01:00
|
|
|
|
2018-06-23 07:17:07 +01:00
|
|
|
//TODO: Figure out what the other values does.
|
|
|
|
if (PoolState == MemoryPoolState.RequestAttach)
|
2018-06-23 06:00:14 +01:00
|
|
|
{
|
2018-06-25 06:04:19 +01:00
|
|
|
Context.Memory.WriteInt32(OutputPosition + OutMemoryPoolOffset + Offset, (int)MemoryPoolState.Attached);
|
2018-06-23 06:00:14 +01:00
|
|
|
}
|
2018-06-23 07:17:07 +01:00
|
|
|
else if (PoolState == MemoryPoolState.RequestDetach)
|
2018-06-23 06:00:14 +01:00
|
|
|
{
|
2018-06-25 06:04:19 +01:00
|
|
|
Context.Memory.WriteInt32(OutputPosition + OutMemoryPoolOffset + Offset, (int)MemoryPoolState.Detached);
|
2018-06-23 06:00:14 +01:00
|
|
|
}
|
2018-02-04 23:08:20 +00:00
|
|
|
}
|
2018-02-06 15:15:08 +00:00
|
|
|
|
2018-06-25 06:04:19 +01:00
|
|
|
int OutVoicesOffset = OutMemoryPoolOffset + OutputDataHeader.MemoryPoolsSize;
|
|
|
|
|
|
|
|
for (int Offset = 0; Offset < OutputDataHeader.VoicesSize; Offset += 0x10)
|
|
|
|
{
|
|
|
|
Context.Memory.WriteInt32(OutputPosition + OutVoicesOffset + Offset + 8, (int)VoicePlaybackState.Finished);
|
|
|
|
}
|
|
|
|
|
2018-03-19 18:58:46 +00:00
|
|
|
//TODO: We shouldn't be signaling this here.
|
2018-04-19 03:52:23 +01:00
|
|
|
UpdateEvent.WaitEvent.Set();
|
2018-03-19 18:58:46 +00:00
|
|
|
|
2018-02-04 23:08:20 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2018-02-10 00:14:55 +00:00
|
|
|
public long StartAudioRenderer(ServiceCtx Context)
|
2018-02-04 23:08:20 +00:00
|
|
|
{
|
2018-04-24 19:57:39 +01:00
|
|
|
Context.Ns.Log.PrintStub(LogClass.ServiceAudio, "Stubbed.");
|
2018-04-17 01:24:42 +01:00
|
|
|
|
2018-02-04 23:08:20 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2018-02-10 00:14:55 +00:00
|
|
|
public long StopAudioRenderer(ServiceCtx Context)
|
2018-02-08 16:52:02 +00:00
|
|
|
{
|
2018-04-24 19:57:39 +01:00
|
|
|
Context.Ns.Log.PrintStub(LogClass.ServiceAudio, "Stubbed.");
|
2018-04-17 01:24:42 +01:00
|
|
|
|
2018-02-08 16:52:02 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2018-02-10 00:14:55 +00:00
|
|
|
public long QuerySystemEvent(ServiceCtx Context)
|
2018-02-04 23:08:20 +00:00
|
|
|
{
|
2018-03-19 18:58:46 +00:00
|
|
|
int Handle = Context.Process.HandleTable.OpenHandle(UpdateEvent);
|
2018-02-08 16:52:02 +00:00
|
|
|
|
|
|
|
Context.Response.HandleDesc = IpcHandleDesc.MakeCopy(Handle);
|
|
|
|
|
2018-02-04 23:08:20 +00:00
|
|
|
return 0;
|
|
|
|
}
|
2018-03-19 18:58:46 +00:00
|
|
|
|
|
|
|
public void Dispose()
|
|
|
|
{
|
|
|
|
Dispose(true);
|
|
|
|
}
|
|
|
|
|
|
|
|
protected virtual void Dispose(bool Disposing)
|
|
|
|
{
|
|
|
|
if (Disposing)
|
|
|
|
{
|
|
|
|
UpdateEvent.Dispose();
|
|
|
|
}
|
|
|
|
}
|
2018-02-04 23:08:20 +00:00
|
|
|
}
|
2018-06-23 06:00:14 +01:00
|
|
|
}
|