aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.HLE/HOS/Services/Audio/AudioOutManager
diff options
context:
space:
mode:
authorAc_K <Acoustik666@gmail.com>2019-09-19 02:45:11 +0200
committerjduncanator <1518948+jduncanator@users.noreply.github.com>2019-09-19 10:45:11 +1000
commita0720b5681852f3d786d77bd3793b0359dea321c (patch)
tree9d8f61e540d1d1d827999902dad95e5c0c1e076e /Ryujinx.HLE/HOS/Services/Audio/AudioOutManager
parent4af3101b22e6957d6aa48a2768566d658699f4ed (diff)
Refactoring HOS folder structure (#771)
* Refactoring HOS folder structure Refactoring HOS folder structure: - Added some subfolders when needed (Following structure decided in private). - Added some `Types` folders when needed. - Little cleanup here and there. - Add services placeholders for every HOS services (close #766 and #753). * Remove Types namespaces
Diffstat (limited to 'Ryujinx.HLE/HOS/Services/Audio/AudioOutManager')
-rw-r--r--Ryujinx.HLE/HOS/Services/Audio/AudioOutManager/IAudioOut.cs163
-rw-r--r--Ryujinx.HLE/HOS/Services/Audio/AudioOutManager/Types/AudioOutData.cs14
2 files changed, 177 insertions, 0 deletions
diff --git a/Ryujinx.HLE/HOS/Services/Audio/AudioOutManager/IAudioOut.cs b/Ryujinx.HLE/HOS/Services/Audio/AudioOutManager/IAudioOut.cs
new file mode 100644
index 00000000..5b6983d6
--- /dev/null
+++ b/Ryujinx.HLE/HOS/Services/Audio/AudioOutManager/IAudioOut.cs
@@ -0,0 +1,163 @@
+using ARMeilleure.Memory;
+using Ryujinx.Audio;
+using Ryujinx.HLE.HOS.Ipc;
+using Ryujinx.HLE.HOS.Kernel.Common;
+using Ryujinx.HLE.HOS.Kernel.Threading;
+using System;
+
+namespace Ryujinx.HLE.HOS.Services.Audio.AudioOutManager
+{
+ class IAudioOut : IpcService, IDisposable
+ {
+ private IAalOutput _audioOut;
+ private KEvent _releaseEvent;
+ private int _track;
+
+ public IAudioOut(IAalOutput audioOut, KEvent releaseEvent, int track)
+ {
+ _audioOut = audioOut;
+ _releaseEvent = releaseEvent;
+ _track = track;
+ }
+
+ [Command(0)]
+ // GetAudioOutState() -> u32 state
+ public ResultCode GetAudioOutState(ServiceCtx context)
+ {
+ context.ResponseData.Write((int)_audioOut.GetState(_track));
+
+ return ResultCode.Success;
+ }
+
+ [Command(1)]
+ // StartAudioOut()
+ public ResultCode StartAudioOut(ServiceCtx context)
+ {
+ _audioOut.Start(_track);
+
+ return ResultCode.Success;
+ }
+
+ [Command(2)]
+ // StopAudioOut()
+ public ResultCode StopAudioOut(ServiceCtx context)
+ {
+ _audioOut.Stop(_track);
+
+ return ResultCode.Success;
+ }
+
+ [Command(3)]
+ // AppendAudioOutBuffer(u64 tag, buffer<nn::audio::AudioOutBuffer, 5>)
+ public ResultCode AppendAudioOutBuffer(ServiceCtx context)
+ {
+ return AppendAudioOutBufferImpl(context, context.Request.SendBuff[0].Position);
+ }
+
+ [Command(4)]
+ // RegisterBufferEvent() -> handle<copy>
+ public ResultCode RegisterBufferEvent(ServiceCtx context)
+ {
+ if (context.Process.HandleTable.GenerateHandle(_releaseEvent.ReadableEvent, out int handle) != KernelResult.Success)
+ {
+ throw new InvalidOperationException("Out of handles!");
+ }
+
+ context.Response.HandleDesc = IpcHandleDesc.MakeCopy(handle);
+
+ return ResultCode.Success;
+ }
+
+ [Command(5)]
+ // GetReleasedAudioOutBuffer() -> (u32 count, buffer<nn::audio::AudioOutBuffer, 6>)
+ public ResultCode GetReleasedAudioOutBuffer(ServiceCtx context)
+ {
+ long position = context.Request.ReceiveBuff[0].Position;
+ long size = context.Request.ReceiveBuff[0].Size;
+
+ return GetReleasedAudioOutBufferImpl(context, position, size);
+ }
+
+ [Command(6)]
+ // ContainsAudioOutBuffer(u64 tag) -> b8
+ public ResultCode ContainsAudioOutBuffer(ServiceCtx context)
+ {
+ long tag = context.RequestData.ReadInt64();
+
+ context.ResponseData.Write(_audioOut.ContainsBuffer(_track, tag) ? 1 : 0);
+
+ return 0;
+ }
+
+ [Command(7)] // 3.0.0+
+ // AppendAudioOutBufferAuto(u64 tag, buffer<nn::audio::AudioOutBuffer, 0x21>)
+ public ResultCode AppendAudioOutBufferAuto(ServiceCtx context)
+ {
+ (long position, long size) = context.Request.GetBufferType0x21();
+
+ return AppendAudioOutBufferImpl(context, position);
+ }
+
+ public ResultCode AppendAudioOutBufferImpl(ServiceCtx context, long position)
+ {
+ long tag = context.RequestData.ReadInt64();
+
+ AudioOutData data = MemoryHelper.Read<AudioOutData>(
+ context.Memory,
+ position);
+
+ byte[] buffer = context.Memory.ReadBytes(
+ data.SampleBufferPtr,
+ data.SampleBufferSize);
+
+ _audioOut.AppendBuffer(_track, tag, buffer);
+
+ return ResultCode.Success;
+ }
+
+ [Command(8)] // 3.0.0+
+ // GetReleasedAudioOutBufferAuto() -> (u32 count, buffer<nn::audio::AudioOutBuffer, 0x22>)
+ public ResultCode GetReleasedAudioOutBufferAuto(ServiceCtx context)
+ {
+ (long position, long size) = context.Request.GetBufferType0x22();
+
+ return GetReleasedAudioOutBufferImpl(context, position, size);
+ }
+
+ public ResultCode GetReleasedAudioOutBufferImpl(ServiceCtx context, long position, long size)
+ {
+ uint count = (uint)((ulong)size >> 3);
+
+ long[] releasedBuffers = _audioOut.GetReleasedBuffers(_track, (int)count);
+
+ for (uint index = 0; index < count; index++)
+ {
+ long tag = 0;
+
+ if (index < releasedBuffers.Length)
+ {
+ tag = releasedBuffers[index];
+ }
+
+ context.Memory.WriteInt64(position + index * 8, tag);
+ }
+
+ context.ResponseData.Write(releasedBuffers.Length);
+
+ return ResultCode.Success;
+ }
+
+ public void Dispose()
+ {
+ Dispose(true);
+ }
+
+ protected virtual void Dispose(bool disposing)
+ {
+ if (disposing)
+ {
+ _audioOut.CloseTrack(_track);
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/Ryujinx.HLE/HOS/Services/Audio/AudioOutManager/Types/AudioOutData.cs b/Ryujinx.HLE/HOS/Services/Audio/AudioOutManager/Types/AudioOutData.cs
new file mode 100644
index 00000000..2598d0f8
--- /dev/null
+++ b/Ryujinx.HLE/HOS/Services/Audio/AudioOutManager/Types/AudioOutData.cs
@@ -0,0 +1,14 @@
+using System.Runtime.InteropServices;
+
+namespace Ryujinx.HLE.HOS.Services.Audio.AudioOutManager
+{
+ [StructLayout(LayoutKind.Sequential)]
+ struct AudioOutData
+ {
+ public long NextBufferPtr;
+ public long SampleBufferPtr;
+ public long SampleBufferCapacity;
+ public long SampleBufferSize;
+ public long SampleBufferInnerOffset;
+ }
+} \ No newline at end of file