diff options
| author | TSR Berry <20988865+TSRBerry@users.noreply.github.com> | 2023-04-08 01:22:00 +0200 |
|---|---|---|
| committer | Mary <thog@protonmail.com> | 2023-04-27 23:51:14 +0200 |
| commit | cee712105850ac3385cd0091a923438167433f9f (patch) | |
| tree | 4a5274b21d8b7f938c0d0ce18736d3f2993b11b1 /src/Ryujinx.HLE/HOS/Services/Audio/AudioIn | |
| parent | cd124bda587ef09668a971fa1cac1c3f0cfc9f21 (diff) | |
Move solution and projects to src
Diffstat (limited to 'src/Ryujinx.HLE/HOS/Services/Audio/AudioIn')
3 files changed, 346 insertions, 0 deletions
diff --git a/src/Ryujinx.HLE/HOS/Services/Audio/AudioIn/AudioIn.cs b/src/Ryujinx.HLE/HOS/Services/Audio/AudioIn/AudioIn.cs new file mode 100644 index 00000000..ee85ded9 --- /dev/null +++ b/src/Ryujinx.HLE/HOS/Services/Audio/AudioIn/AudioIn.cs @@ -0,0 +1,108 @@ +using Ryujinx.Audio.Common; +using Ryujinx.Audio.Input; +using Ryujinx.Audio.Integration; +using Ryujinx.HLE.HOS.Kernel; +using Ryujinx.HLE.HOS.Kernel.Threading; +using Ryujinx.HLE.HOS.Services.Audio.AudioRenderer; +using System; + +namespace Ryujinx.HLE.HOS.Services.Audio.AudioIn +{ + class AudioIn : IAudioIn + { + private AudioInputSystem _system; + private uint _processHandle; + private KernelContext _kernelContext; + + public AudioIn(AudioInputSystem system, KernelContext kernelContext, uint processHandle) + { + _system = system; + _kernelContext = kernelContext; + _processHandle = processHandle; + } + + public ResultCode AppendBuffer(ulong bufferTag, ref AudioUserBuffer buffer) + { + return (ResultCode)_system.AppendBuffer(bufferTag, ref buffer); + } + + public ResultCode AppendUacBuffer(ulong bufferTag, ref AudioUserBuffer buffer, uint handle) + { + return (ResultCode)_system.AppendUacBuffer(bufferTag, ref buffer, handle); + } + + public bool ContainsBuffer(ulong bufferTag) + { + return _system.ContainsBuffer(bufferTag); + } + + public void Dispose() + { + Dispose(true); + } + + protected virtual void Dispose(bool disposing) + { + if (disposing) + { + _system.Dispose(); + + _kernelContext.Syscall.CloseHandle((int)_processHandle); + } + } + + public bool FlushBuffers() + { + return _system.FlushBuffers(); + } + + public uint GetBufferCount() + { + return _system.GetBufferCount(); + } + + public ResultCode GetReleasedBuffers(Span<ulong> releasedBuffers, out uint releasedCount) + { + return (ResultCode)_system.GetReleasedBuffers(releasedBuffers, out releasedCount); + } + + public AudioDeviceState GetState() + { + return _system.GetState(); + } + + public float GetVolume() + { + return _system.GetVolume(); + } + + public KEvent RegisterBufferEvent() + { + IWritableEvent outEvent = _system.RegisterBufferEvent(); + + if (outEvent is AudioKernelEvent) + { + return ((AudioKernelEvent)outEvent).Event; + } + else + { + throw new NotImplementedException(); + } + } + + public void SetVolume(float volume) + { + _system.SetVolume(volume); + } + + public ResultCode Start() + { + return (ResultCode)_system.Start(); + } + + public ResultCode Stop() + { + return (ResultCode)_system.Stop(); + } + } +}
\ No newline at end of file diff --git a/src/Ryujinx.HLE/HOS/Services/Audio/AudioIn/AudioInServer.cs b/src/Ryujinx.HLE/HOS/Services/Audio/AudioIn/AudioInServer.cs new file mode 100644 index 00000000..a80b9402 --- /dev/null +++ b/src/Ryujinx.HLE/HOS/Services/Audio/AudioIn/AudioInServer.cs @@ -0,0 +1,204 @@ +using Ryujinx.Audio.Common; +using Ryujinx.Cpu; +using Ryujinx.HLE.HOS.Ipc; +using Ryujinx.HLE.HOS.Kernel.Threading; +using Ryujinx.Horizon.Common; +using Ryujinx.Memory; +using System; +using System.Runtime.InteropServices; + +namespace Ryujinx.HLE.HOS.Services.Audio.AudioIn +{ + class AudioInServer : DisposableIpcService + { + private IAudioIn _impl; + + public AudioInServer(IAudioIn impl) + { + _impl = impl; + } + + [CommandCmif(0)] + // GetAudioInState() -> u32 state + public ResultCode GetAudioInState(ServiceCtx context) + { + context.ResponseData.Write((uint)_impl.GetState()); + + return ResultCode.Success; + } + + [CommandCmif(1)] + // Start() + public ResultCode Start(ServiceCtx context) + { + return _impl.Start(); + } + + [CommandCmif(2)] + // Stop() + public ResultCode StopAudioIn(ServiceCtx context) + { + return _impl.Stop(); + } + + [CommandCmif(3)] + // AppendAudioInBuffer(u64 tag, buffer<nn::audio::AudioInBuffer, 5>) + public ResultCode AppendAudioInBuffer(ServiceCtx context) + { + ulong position = context.Request.SendBuff[0].Position; + + ulong bufferTag = context.RequestData.ReadUInt64(); + + AudioUserBuffer data = MemoryHelper.Read<AudioUserBuffer>(context.Memory, position); + + return _impl.AppendBuffer(bufferTag, ref data); + } + + [CommandCmif(4)] + // RegisterBufferEvent() -> handle<copy> + public ResultCode RegisterBufferEvent(ServiceCtx context) + { + KEvent bufferEvent = _impl.RegisterBufferEvent(); + + if (context.Process.HandleTable.GenerateHandle(bufferEvent.ReadableEvent, out int handle) != Result.Success) + { + throw new InvalidOperationException("Out of handles!"); + } + + context.Response.HandleDesc = IpcHandleDesc.MakeCopy(handle); + + return ResultCode.Success; + } + + [CommandCmif(5)] + // GetReleasedAudioInBuffers() -> (u32 count, buffer<u64, 6> tags) + public ResultCode GetReleasedAudioInBuffers(ServiceCtx context) + { + ulong position = context.Request.ReceiveBuff[0].Position; + ulong size = context.Request.ReceiveBuff[0].Size; + + using (WritableRegion outputRegion = context.Memory.GetWritableRegion((ulong)position, (int)size)) + { + ResultCode result = _impl.GetReleasedBuffers(MemoryMarshal.Cast<byte, ulong>(outputRegion.Memory.Span), out uint releasedCount); + + context.ResponseData.Write(releasedCount); + + return result; + } + } + + [CommandCmif(6)] + // ContainsAudioInBuffer(u64 tag) -> b8 + public ResultCode ContainsAudioInBuffer(ServiceCtx context) + { + ulong bufferTag = context.RequestData.ReadUInt64(); + + context.ResponseData.Write(_impl.ContainsBuffer(bufferTag)); + + return ResultCode.Success; + } + + [CommandCmif(7)] // 3.0.0+ + // AppendUacInBuffer(u64 tag, handle<copy, unknown>, buffer<nn::audio::AudioInBuffer, 5>) + public ResultCode AppendUacInBuffer(ServiceCtx context) + { + ulong position = context.Request.SendBuff[0].Position; + + ulong bufferTag = context.RequestData.ReadUInt64(); + uint handle = (uint)context.Request.HandleDesc.ToCopy[0]; + + AudioUserBuffer data = MemoryHelper.Read<AudioUserBuffer>(context.Memory, position); + + return _impl.AppendUacBuffer(bufferTag, ref data, handle); + } + + [CommandCmif(8)] // 3.0.0+ + // AppendAudioInBufferAuto(u64 tag, buffer<nn::audio::AudioInBuffer, 0x21>) + public ResultCode AppendAudioInBufferAuto(ServiceCtx context) + { + (ulong position, _) = context.Request.GetBufferType0x21(); + + ulong bufferTag = context.RequestData.ReadUInt64(); + + AudioUserBuffer data = MemoryHelper.Read<AudioUserBuffer>(context.Memory, position); + + return _impl.AppendBuffer(bufferTag, ref data); + } + + [CommandCmif(9)] // 3.0.0+ + // GetReleasedAudioInBuffersAuto() -> (u32 count, buffer<u64, 0x22> tags) + public ResultCode GetReleasedAudioInBuffersAuto(ServiceCtx context) + { + (ulong position, ulong size) = context.Request.GetBufferType0x22(); + + using (WritableRegion outputRegion = context.Memory.GetWritableRegion(position, (int)size)) + { + ResultCode result = _impl.GetReleasedBuffers(MemoryMarshal.Cast<byte, ulong>(outputRegion.Memory.Span), out uint releasedCount); + + context.ResponseData.Write(releasedCount); + + return result; + } + } + + [CommandCmif(10)] // 3.0.0+ + // AppendUacInBufferAuto(u64 tag, handle<copy, event>, buffer<nn::audio::AudioInBuffer, 0x21>) + public ResultCode AppendUacInBufferAuto(ServiceCtx context) + { + (ulong position, _) = context.Request.GetBufferType0x21(); + + ulong bufferTag = context.RequestData.ReadUInt64(); + uint handle = (uint)context.Request.HandleDesc.ToCopy[0]; + + AudioUserBuffer data = MemoryHelper.Read<AudioUserBuffer>(context.Memory, position); + + return _impl.AppendUacBuffer(bufferTag, ref data, handle); + } + + [CommandCmif(11)] // 4.0.0+ + // GetAudioInBufferCount() -> u32 + public ResultCode GetAudioInBufferCount(ServiceCtx context) + { + context.ResponseData.Write(_impl.GetBufferCount()); + + return ResultCode.Success; + } + + [CommandCmif(12)] // 4.0.0+ + // SetAudioInVolume(s32) + public ResultCode SetAudioInVolume(ServiceCtx context) + { + float volume = context.RequestData.ReadSingle(); + + _impl.SetVolume(volume); + + return ResultCode.Success; + } + + [CommandCmif(13)] // 4.0.0+ + // GetAudioInVolume() -> s32 + public ResultCode GetAudioInVolume(ServiceCtx context) + { + context.ResponseData.Write(_impl.GetVolume()); + + return ResultCode.Success; + } + + [CommandCmif(14)] // 6.0.0+ + // FlushAudioInBuffers() -> b8 + public ResultCode FlushAudioInBuffers(ServiceCtx context) + { + context.ResponseData.Write(_impl.FlushBuffers()); + + return ResultCode.Success; + } + + protected override void Dispose(bool isDisposing) + { + if (isDisposing) + { + _impl.Dispose(); + } + } + } +} diff --git a/src/Ryujinx.HLE/HOS/Services/Audio/AudioIn/IAudioIn.cs b/src/Ryujinx.HLE/HOS/Services/Audio/AudioIn/IAudioIn.cs new file mode 100644 index 00000000..b5073fce --- /dev/null +++ b/src/Ryujinx.HLE/HOS/Services/Audio/AudioIn/IAudioIn.cs @@ -0,0 +1,34 @@ +using Ryujinx.Audio.Common; +using Ryujinx.HLE.HOS.Kernel.Threading; +using System; + +namespace Ryujinx.HLE.HOS.Services.Audio.AudioIn +{ + interface IAudioIn : IDisposable + { + AudioDeviceState GetState(); + + ResultCode Start(); + + ResultCode Stop(); + + ResultCode AppendBuffer(ulong bufferTag, ref AudioUserBuffer buffer); + + // NOTE: This is broken by design... not quite sure what it's used for (if anything in production). + ResultCode AppendUacBuffer(ulong bufferTag, ref AudioUserBuffer buffer, uint handle); + + KEvent RegisterBufferEvent(); + + ResultCode GetReleasedBuffers(Span<ulong> releasedBuffers, out uint releasedCount); + + bool ContainsBuffer(ulong bufferTag); + + uint GetBufferCount(); + + bool FlushBuffers(); + + void SetVolume(float volume); + + float GetVolume(); + } +} |
