2018-03-02 04:06:05 +00:00
|
|
|
using ChocolArm64.Memory;
|
2018-03-16 00:06:24 +00:00
|
|
|
using Ryujinx.Audio;
|
2018-06-11 00:46:42 +00:00
|
|
|
using Ryujinx.HLE.OsHle.Handles;
|
|
|
|
using Ryujinx.HLE.OsHle.Ipc;
|
2018-02-08 17:20:07 +00:00
|
|
|
using System;
|
2018-02-08 16:52:02 +00:00
|
|
|
using System.Collections.Generic;
|
2018-02-08 17:20:07 +00:00
|
|
|
|
2018-07-15 02:57:41 +00:00
|
|
|
namespace Ryujinx.HLE.OsHle.Services.Aud.AudioOut
|
2018-02-08 16:52:02 +00:00
|
|
|
{
|
2018-03-19 18:58:46 +00:00
|
|
|
class IAudioOut : IpcService, IDisposable
|
2018-02-08 16:52:02 +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;
|
2018-02-10 00:14:55 +00:00
|
|
|
|
2018-03-16 00:06:24 +00:00
|
|
|
private IAalOutput AudioOut;
|
|
|
|
|
2018-03-19 18:58:46 +00:00
|
|
|
private KEvent ReleaseEvent;
|
|
|
|
|
2018-03-16 00:06:24 +00:00
|
|
|
private int Track;
|
|
|
|
|
2018-03-19 18:58:46 +00:00
|
|
|
public IAudioOut(IAalOutput AudioOut, KEvent ReleaseEvent, int Track)
|
2018-02-10 00:14:55 +00:00
|
|
|
{
|
|
|
|
m_Commands = new Dictionary<int, ServiceProcessRequest>()
|
|
|
|
{
|
2018-06-30 15:53:04 +00:00
|
|
|
{ 0, GetAudioOutState },
|
|
|
|
{ 1, StartAudioOut },
|
|
|
|
{ 2, StopAudioOut },
|
|
|
|
{ 3, AppendAudioOutBuffer },
|
|
|
|
{ 4, RegisterBufferEvent },
|
|
|
|
{ 5, GetReleasedAudioOutBuffer },
|
|
|
|
{ 6, ContainsAudioOutBuffer },
|
|
|
|
{ 7, AppendAudioOutBufferAuto },
|
|
|
|
{ 8, GetReleasedAudioOutBufferAuto }
|
2018-02-10 00:14:55 +00:00
|
|
|
};
|
2018-02-08 16:52:02 +00:00
|
|
|
|
2018-03-19 18:58:46 +00:00
|
|
|
this.AudioOut = AudioOut;
|
|
|
|
this.ReleaseEvent = ReleaseEvent;
|
|
|
|
this.Track = Track;
|
2018-03-16 00:06:24 +00:00
|
|
|
}
|
2018-02-08 16:52:02 +00:00
|
|
|
|
2018-02-10 00:14:55 +00:00
|
|
|
public long GetAudioOutState(ServiceCtx Context)
|
2018-02-08 16:52:02 +00:00
|
|
|
{
|
2018-03-16 00:06:24 +00:00
|
|
|
Context.ResponseData.Write((int)AudioOut.GetState(Track));
|
2018-02-08 16:52:02 +00:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2018-02-10 00:14:55 +00:00
|
|
|
public long StartAudioOut(ServiceCtx Context)
|
2018-02-08 16:52:02 +00:00
|
|
|
{
|
2018-03-16 00:06:24 +00:00
|
|
|
AudioOut.Start(Track);
|
2018-02-08 16:52:02 +00:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2018-02-10 00:14:55 +00:00
|
|
|
public long StopAudioOut(ServiceCtx Context)
|
2018-02-08 16:52:02 +00:00
|
|
|
{
|
2018-03-16 00:06:24 +00:00
|
|
|
AudioOut.Stop(Track);
|
2018-02-08 16:52:02 +00:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2018-02-10 00:14:55 +00:00
|
|
|
public long AppendAudioOutBuffer(ServiceCtx Context)
|
2018-06-30 15:53:04 +00:00
|
|
|
{
|
|
|
|
return AppendAudioOutBufferImpl(Context, Context.Request.SendBuff[0].Position);
|
|
|
|
}
|
|
|
|
|
|
|
|
public long RegisterBufferEvent(ServiceCtx Context)
|
|
|
|
{
|
|
|
|
int Handle = Context.Process.HandleTable.OpenHandle(ReleaseEvent);
|
|
|
|
|
|
|
|
Context.Response.HandleDesc = IpcHandleDesc.MakeCopy(Handle);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
public long GetReleasedAudioOutBuffer(ServiceCtx Context)
|
|
|
|
{
|
|
|
|
long Position = Context.Request.ReceiveBuff[0].Position;
|
|
|
|
long Size = Context.Request.ReceiveBuff[0].Size;
|
|
|
|
|
|
|
|
return GetReleasedAudioOutBufferImpl(Context, Position, Size);
|
|
|
|
}
|
|
|
|
|
|
|
|
public long ContainsAudioOutBuffer(ServiceCtx Context)
|
|
|
|
{
|
|
|
|
long Tag = Context.RequestData.ReadInt64();
|
|
|
|
|
|
|
|
Context.ResponseData.Write(AudioOut.ContainsBuffer(Track, Tag) ? 1 : 0);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
public long AppendAudioOutBufferAuto(ServiceCtx Context)
|
|
|
|
{
|
|
|
|
(long Position, long Size) = Context.Request.GetBufferType0x21();
|
|
|
|
|
|
|
|
return AppendAudioOutBufferImpl(Context, Position);
|
|
|
|
}
|
|
|
|
|
|
|
|
public long AppendAudioOutBufferImpl(ServiceCtx Context, long Position)
|
2018-02-08 16:52:02 +00:00
|
|
|
{
|
2018-03-16 00:06:24 +00:00
|
|
|
long Tag = Context.RequestData.ReadInt64();
|
2018-02-08 16:52:02 +00:00
|
|
|
|
2018-03-16 00:06:24 +00:00
|
|
|
AudioOutData Data = AMemoryHelper.Read<AudioOutData>(
|
|
|
|
Context.Memory,
|
2018-06-30 15:53:04 +00:00
|
|
|
Position);
|
2018-04-24 18:57:39 +00:00
|
|
|
|
2018-06-09 00:15:02 +00:00
|
|
|
byte[] Buffer = Context.Memory.ReadBytes(
|
2018-03-16 00:06:24 +00:00
|
|
|
Data.SampleBufferPtr,
|
|
|
|
Data.SampleBufferSize);
|
2018-03-02 04:06:05 +00:00
|
|
|
|
2018-03-16 00:06:24 +00:00
|
|
|
AudioOut.AppendBuffer(Track, Tag, Buffer);
|
2018-02-08 16:52:02 +00:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2018-06-30 15:53:04 +00:00
|
|
|
public long GetReleasedAudioOutBufferAuto(ServiceCtx Context)
|
2018-02-08 16:52:02 +00:00
|
|
|
{
|
2018-06-30 15:53:04 +00:00
|
|
|
(long Position, long Size) = Context.Request.GetBufferType0x22();
|
2018-02-08 16:52:02 +00:00
|
|
|
|
2018-06-30 15:53:04 +00:00
|
|
|
return GetReleasedAudioOutBufferImpl(Context, Position, Size);
|
2018-02-08 16:52:02 +00:00
|
|
|
}
|
|
|
|
|
2018-06-30 15:53:04 +00:00
|
|
|
public long GetReleasedAudioOutBufferImpl(ServiceCtx Context, long Position, long Size)
|
2018-02-08 16:52:02 +00:00
|
|
|
{
|
2018-03-16 00:06:24 +00:00
|
|
|
uint Count = (uint)((ulong)Size >> 3);
|
2018-02-08 16:52:02 +00:00
|
|
|
|
2018-03-16 03:42:44 +00:00
|
|
|
long[] ReleasedBuffers = AudioOut.GetReleasedBuffers(Track, (int)Count);
|
2018-03-16 00:06:24 +00:00
|
|
|
|
|
|
|
for (uint Index = 0; Index < Count; Index++)
|
2018-02-08 16:52:02 +00:00
|
|
|
{
|
2018-03-16 00:06:24 +00:00
|
|
|
long Tag = 0;
|
2018-03-02 04:06:05 +00:00
|
|
|
|
2018-03-16 00:06:24 +00:00
|
|
|
if (Index < ReleasedBuffers.Length)
|
|
|
|
{
|
|
|
|
Tag = ReleasedBuffers[Index];
|
|
|
|
}
|
2018-02-08 16:52:02 +00:00
|
|
|
|
2018-03-16 00:06:24 +00:00
|
|
|
Context.Memory.WriteInt64(Position + Index * 8, Tag);
|
2018-02-08 16:52:02 +00:00
|
|
|
}
|
|
|
|
|
2018-03-16 00:06:24 +00:00
|
|
|
Context.ResponseData.Write(ReleasedBuffers.Length);
|
2018-03-02 04:06:05 +00:00
|
|
|
|
2018-02-08 16:52:02 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2018-03-04 04:41:35 +00:00
|
|
|
public void Dispose()
|
|
|
|
{
|
|
|
|
Dispose(true);
|
|
|
|
}
|
|
|
|
|
2018-03-16 00:06:24 +00:00
|
|
|
protected virtual void Dispose(bool Disposing)
|
2018-03-04 04:41:35 +00:00
|
|
|
{
|
2018-03-16 00:06:24 +00:00
|
|
|
if (Disposing)
|
2018-03-04 04:41:35 +00:00
|
|
|
{
|
2018-03-16 00:06:24 +00:00
|
|
|
AudioOut.CloseTrack(Track);
|
2018-03-19 18:58:46 +00:00
|
|
|
|
|
|
|
ReleaseEvent.Dispose();
|
2018-03-04 04:41:35 +00:00
|
|
|
}
|
|
|
|
}
|
2018-02-08 16:52:02 +00:00
|
|
|
}
|
|
|
|
}
|