Refactoring commands handling (#728)
* Refactoring commands handling - Use Reflection to handle commands ID. - Add all symbols (from SwIPC so not all time accurate). - Re-sort some services commands methods. - Some cleanup. - Keep some empty constructor for consistency. * Fix order in IProfile
This commit is contained in:
parent
f723f6f39a
commit
560ccbeb2d
99 changed files with 1035 additions and 1983 deletions
|
@ -4,42 +4,24 @@ using Ryujinx.HLE.HOS.Ipc;
|
|||
using Ryujinx.HLE.HOS.Kernel.Common;
|
||||
using Ryujinx.HLE.HOS.Kernel.Threading;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Ryujinx.HLE.HOS.Services.Aud.AudioOut
|
||||
{
|
||||
class IAudioOut : IpcService, IDisposable
|
||||
{
|
||||
private Dictionary<int, ServiceProcessRequest> _commands;
|
||||
|
||||
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
|
||||
|
||||
private IAalOutput _audioOut;
|
||||
|
||||
private KEvent _releaseEvent;
|
||||
|
||||
private int _track;
|
||||
private KEvent _releaseEvent;
|
||||
private int _track;
|
||||
|
||||
public IAudioOut(IAalOutput audioOut, KEvent releaseEvent, int track)
|
||||
{
|
||||
_commands = new Dictionary<int, ServiceProcessRequest>
|
||||
{
|
||||
{ 0, GetAudioOutState },
|
||||
{ 1, StartAudioOut },
|
||||
{ 2, StopAudioOut },
|
||||
{ 3, AppendAudioOutBuffer },
|
||||
{ 4, RegisterBufferEvent },
|
||||
{ 5, GetReleasedAudioOutBuffer },
|
||||
{ 6, ContainsAudioOutBuffer },
|
||||
{ 7, AppendAudioOutBufferAuto },
|
||||
{ 8, GetReleasedAudioOutBufferAuto }
|
||||
};
|
||||
|
||||
_audioOut = audioOut;
|
||||
_releaseEvent = releaseEvent;
|
||||
_track = track;
|
||||
}
|
||||
|
||||
[Command(0)]
|
||||
// GetAudioOutState() -> u32 state
|
||||
public long GetAudioOutState(ServiceCtx context)
|
||||
{
|
||||
context.ResponseData.Write((int)_audioOut.GetState(_track));
|
||||
|
@ -47,6 +29,8 @@ namespace Ryujinx.HLE.HOS.Services.Aud.AudioOut
|
|||
return 0;
|
||||
}
|
||||
|
||||
[Command(1)]
|
||||
// StartAudioOut()
|
||||
public long StartAudioOut(ServiceCtx context)
|
||||
{
|
||||
_audioOut.Start(_track);
|
||||
|
@ -54,6 +38,8 @@ namespace Ryujinx.HLE.HOS.Services.Aud.AudioOut
|
|||
return 0;
|
||||
}
|
||||
|
||||
[Command(2)]
|
||||
// StopAudioOut()
|
||||
public long StopAudioOut(ServiceCtx context)
|
||||
{
|
||||
_audioOut.Stop(_track);
|
||||
|
@ -61,11 +47,15 @@ namespace Ryujinx.HLE.HOS.Services.Aud.AudioOut
|
|||
return 0;
|
||||
}
|
||||
|
||||
[Command(3)]
|
||||
// AppendAudioOutBuffer(u64 tag, buffer<nn::audio::AudioOutBuffer, 5>)
|
||||
public long AppendAudioOutBuffer(ServiceCtx context)
|
||||
{
|
||||
return AppendAudioOutBufferImpl(context, context.Request.SendBuff[0].Position);
|
||||
}
|
||||
|
||||
[Command(4)]
|
||||
// RegisterBufferEvent() -> handle<copy>
|
||||
public long RegisterBufferEvent(ServiceCtx context)
|
||||
{
|
||||
if (context.Process.HandleTable.GenerateHandle(_releaseEvent.ReadableEvent, out int handle) != KernelResult.Success)
|
||||
|
@ -78,6 +68,8 @@ namespace Ryujinx.HLE.HOS.Services.Aud.AudioOut
|
|||
return 0;
|
||||
}
|
||||
|
||||
[Command(5)]
|
||||
// GetReleasedAudioOutBuffer() -> (u32 count, buffer<nn::audio::AudioOutBuffer, 6>)
|
||||
public long GetReleasedAudioOutBuffer(ServiceCtx context)
|
||||
{
|
||||
long position = context.Request.ReceiveBuff[0].Position;
|
||||
|
@ -86,6 +78,8 @@ namespace Ryujinx.HLE.HOS.Services.Aud.AudioOut
|
|||
return GetReleasedAudioOutBufferImpl(context, position, size);
|
||||
}
|
||||
|
||||
[Command(6)]
|
||||
// ContainsAudioOutBuffer(u64 tag) -> b8
|
||||
public long ContainsAudioOutBuffer(ServiceCtx context)
|
||||
{
|
||||
long tag = context.RequestData.ReadInt64();
|
||||
|
@ -95,6 +89,8 @@ namespace Ryujinx.HLE.HOS.Services.Aud.AudioOut
|
|||
return 0;
|
||||
}
|
||||
|
||||
[Command(7)] // 3.0.0+
|
||||
// AppendAudioOutBufferAuto(u64 tag, buffer<nn::audio::AudioOutBuffer, 0x21>)
|
||||
public long AppendAudioOutBufferAuto(ServiceCtx context)
|
||||
{
|
||||
(long position, long size) = context.Request.GetBufferType0x21();
|
||||
|
@ -119,6 +115,8 @@ namespace Ryujinx.HLE.HOS.Services.Aud.AudioOut
|
|||
return 0;
|
||||
}
|
||||
|
||||
[Command(8)] // 3.0.0+
|
||||
// GetReleasedAudioOutBufferAuto() -> (u32 count, buffer<nn::audio::AudioOutBuffer, 0x22>)
|
||||
public long GetReleasedAudioOutBufferAuto(ServiceCtx context)
|
||||
{
|
||||
(long position, long size) = context.Request.GetBufferType0x22();
|
||||
|
@ -162,4 +160,4 @@ namespace Ryujinx.HLE.HOS.Services.Aud.AudioOut
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -7,7 +7,6 @@ using Ryujinx.HLE.HOS.Kernel.Common;
|
|||
using Ryujinx.HLE.HOS.Kernel.Threading;
|
||||
using Ryujinx.HLE.Utilities;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Runtime.Intrinsics;
|
||||
using System.Runtime.Intrinsics.X86;
|
||||
|
@ -23,10 +22,6 @@ namespace Ryujinx.HLE.HOS.Services.Aud.AudioRenderer
|
|||
// high latency).
|
||||
private const int MixBufferSamplesCount = 960;
|
||||
|
||||
private Dictionary<int, ServiceProcessRequest> _commands;
|
||||
|
||||
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
|
||||
|
||||
private KEvent _updateEvent;
|
||||
|
||||
private MemoryManager _memory;
|
||||
|
@ -49,18 +44,6 @@ namespace Ryujinx.HLE.HOS.Services.Aud.AudioRenderer
|
|||
IAalOutput audioOut,
|
||||
AudioRendererParameter Params)
|
||||
{
|
||||
_commands = new Dictionary<int, ServiceProcessRequest>
|
||||
{
|
||||
{ 0, GetSampleRate },
|
||||
{ 1, GetSampleCount },
|
||||
{ 2, GetMixBufferCount },
|
||||
{ 3, GetState },
|
||||
{ 4, RequestUpdateAudioRenderer },
|
||||
{ 5, StartAudioRenderer },
|
||||
{ 6, StopAudioRenderer },
|
||||
{ 7, QuerySystemEvent }
|
||||
};
|
||||
|
||||
_updateEvent = new KEvent(system);
|
||||
|
||||
_memory = memory;
|
||||
|
@ -81,7 +64,8 @@ namespace Ryujinx.HLE.HOS.Services.Aud.AudioRenderer
|
|||
_playState = PlayState.Stopped;
|
||||
}
|
||||
|
||||
// GetSampleRate() -> u32
|
||||
[Command(0)]
|
||||
// GetSampleRate() -> u32
|
||||
public long GetSampleRate(ServiceCtx context)
|
||||
{
|
||||
context.ResponseData.Write(_params.SampleRate);
|
||||
|
@ -89,7 +73,8 @@ namespace Ryujinx.HLE.HOS.Services.Aud.AudioRenderer
|
|||
return 0;
|
||||
}
|
||||
|
||||
// GetSampleCount() -> u32
|
||||
[Command(1)]
|
||||
// GetSampleCount() -> u32
|
||||
public long GetSampleCount(ServiceCtx context)
|
||||
{
|
||||
context.ResponseData.Write(_params.SampleCount);
|
||||
|
@ -97,6 +82,7 @@ namespace Ryujinx.HLE.HOS.Services.Aud.AudioRenderer
|
|||
return 0;
|
||||
}
|
||||
|
||||
[Command(2)]
|
||||
// GetMixBufferCount() -> u32
|
||||
public long GetMixBufferCount(ServiceCtx context)
|
||||
{
|
||||
|
@ -105,6 +91,7 @@ namespace Ryujinx.HLE.HOS.Services.Aud.AudioRenderer
|
|||
return 0;
|
||||
}
|
||||
|
||||
[Command(3)]
|
||||
// GetState() -> u32
|
||||
private long GetState(ServiceCtx context)
|
||||
{
|
||||
|
@ -141,6 +128,9 @@ namespace Ryujinx.HLE.HOS.Services.Aud.AudioRenderer
|
|||
_audioOut.Start(_track);
|
||||
}
|
||||
|
||||
[Command(4)]
|
||||
// RequestUpdateAudioRenderer(buffer<nn::audio::detail::AudioRendererUpdateDataHeader, 5>)
|
||||
// -> (buffer<nn::audio::detail::AudioRendererUpdateDataHeader, 6>, buffer<nn::audio::detail::AudioRendererUpdateDataHeader, 6>)
|
||||
public long RequestUpdateAudioRenderer(ServiceCtx context)
|
||||
{
|
||||
long outputPosition = context.Request.ReceiveBuff[0].Position;
|
||||
|
@ -247,6 +237,8 @@ namespace Ryujinx.HLE.HOS.Services.Aud.AudioRenderer
|
|||
return 0;
|
||||
}
|
||||
|
||||
[Command(5)]
|
||||
// Start()
|
||||
public long StartAudioRenderer(ServiceCtx context)
|
||||
{
|
||||
Logger.PrintStub(LogClass.ServiceAudio);
|
||||
|
@ -256,6 +248,8 @@ namespace Ryujinx.HLE.HOS.Services.Aud.AudioRenderer
|
|||
return 0;
|
||||
}
|
||||
|
||||
[Command(6)]
|
||||
// Stop()
|
||||
public long StopAudioRenderer(ServiceCtx context)
|
||||
{
|
||||
Logger.PrintStub(LogClass.ServiceAudio);
|
||||
|
@ -265,6 +259,8 @@ namespace Ryujinx.HLE.HOS.Services.Aud.AudioRenderer
|
|||
return 0;
|
||||
}
|
||||
|
||||
[Command(7)]
|
||||
// QuerySystemEvent() -> handle<copy, event>
|
||||
public long QuerySystemEvent(ServiceCtx context)
|
||||
{
|
||||
if (context.Process.HandleTable.GenerateHandle(_updateEvent.ReadableEvent, out int handle) != KernelResult.Success)
|
||||
|
@ -405,4 +401,4 @@ namespace Ryujinx.HLE.HOS.Services.Aud.AudioRenderer
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -4,42 +4,24 @@ using Ryujinx.HLE.HOS.Kernel.Common;
|
|||
using Ryujinx.HLE.HOS.Kernel.Threading;
|
||||
using Ryujinx.HLE.HOS.SystemState;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Ryujinx.HLE.HOS.Services.Aud
|
||||
{
|
||||
class IAudioDevice : IpcService
|
||||
{
|
||||
private Dictionary<int, ServiceProcessRequest> _commands;
|
||||
|
||||
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
|
||||
|
||||
private KEvent _systemEvent;
|
||||
|
||||
public IAudioDevice(Horizon system)
|
||||
{
|
||||
_commands = new Dictionary<int, ServiceProcessRequest>
|
||||
{
|
||||
{ 0, ListAudioDeviceName },
|
||||
{ 1, SetAudioDeviceOutputVolume },
|
||||
{ 3, GetActiveAudioDeviceName },
|
||||
{ 4, QueryAudioDeviceSystemEvent },
|
||||
{ 5, GetActiveChannelCount },
|
||||
{ 6, ListAudioDeviceNameAuto },
|
||||
{ 7, SetAudioDeviceOutputVolumeAuto },
|
||||
{ 8, GetAudioDeviceOutputVolumeAuto },
|
||||
{ 10, GetActiveAudioDeviceNameAuto },
|
||||
{ 11, QueryAudioDeviceInputEvent },
|
||||
{ 12, QueryAudioDeviceOutputEvent }
|
||||
};
|
||||
|
||||
_systemEvent = new KEvent(system);
|
||||
|
||||
// TODO: We shouldn't be signaling this here.
|
||||
_systemEvent.ReadableEvent.Signal();
|
||||
}
|
||||
|
||||
[Command(0)]
|
||||
// ListAudioDeviceName() -> (u32, buffer<bytes, 6>)
|
||||
public long ListAudioDeviceName(ServiceCtx context)
|
||||
{
|
||||
string[] deviceNames = SystemStateMgr.AudioOutputs;
|
||||
|
@ -70,6 +52,8 @@ namespace Ryujinx.HLE.HOS.Services.Aud
|
|||
return 0;
|
||||
}
|
||||
|
||||
[Command(1)]
|
||||
// SetAudioDeviceOutputVolume(u32, buffer<bytes, 5>)
|
||||
public long SetAudioDeviceOutputVolume(ServiceCtx context)
|
||||
{
|
||||
float volume = context.RequestData.ReadSingle();
|
||||
|
@ -86,6 +70,8 @@ namespace Ryujinx.HLE.HOS.Services.Aud
|
|||
return 0;
|
||||
}
|
||||
|
||||
[Command(3)]
|
||||
// GetActiveAudioDeviceName() -> buffer<bytes, 6>
|
||||
public long GetActiveAudioDeviceName(ServiceCtx context)
|
||||
{
|
||||
string name = context.Device.System.State.ActiveAudioOutput;
|
||||
|
@ -107,6 +93,8 @@ namespace Ryujinx.HLE.HOS.Services.Aud
|
|||
return 0;
|
||||
}
|
||||
|
||||
[Command(4)]
|
||||
// QueryAudioDeviceSystemEvent() -> handle<copy, event>
|
||||
public long QueryAudioDeviceSystemEvent(ServiceCtx context)
|
||||
{
|
||||
if (context.Process.HandleTable.GenerateHandle(_systemEvent.ReadableEvent, out int handle) != KernelResult.Success)
|
||||
|
@ -121,6 +109,8 @@ namespace Ryujinx.HLE.HOS.Services.Aud
|
|||
return 0;
|
||||
}
|
||||
|
||||
[Command(5)]
|
||||
// GetActiveChannelCount() -> u32
|
||||
public long GetActiveChannelCount(ServiceCtx context)
|
||||
{
|
||||
context.ResponseData.Write(2);
|
||||
|
@ -130,6 +120,8 @@ namespace Ryujinx.HLE.HOS.Services.Aud
|
|||
return 0;
|
||||
}
|
||||
|
||||
[Command(6)]
|
||||
// ListAudioDeviceNameAuto() -> (u32, buffer<bytes, 0x22>)
|
||||
public long ListAudioDeviceNameAuto(ServiceCtx context)
|
||||
{
|
||||
string[] deviceNames = SystemStateMgr.AudioOutputs;
|
||||
|
@ -159,6 +151,8 @@ namespace Ryujinx.HLE.HOS.Services.Aud
|
|||
return 0;
|
||||
}
|
||||
|
||||
[Command(7)]
|
||||
// SetAudioDeviceOutputVolumeAuto(u32, buffer<bytes, 0x21>)
|
||||
public long SetAudioDeviceOutputVolumeAuto(ServiceCtx context)
|
||||
{
|
||||
float volume = context.RequestData.ReadSingle();
|
||||
|
@ -174,6 +168,8 @@ namespace Ryujinx.HLE.HOS.Services.Aud
|
|||
return 0;
|
||||
}
|
||||
|
||||
[Command(8)]
|
||||
// GetAudioDeviceOutputVolumeAuto(buffer<bytes, 0x21>) -> u32
|
||||
public long GetAudioDeviceOutputVolumeAuto(ServiceCtx context)
|
||||
{
|
||||
context.ResponseData.Write(1f);
|
||||
|
@ -183,6 +179,8 @@ namespace Ryujinx.HLE.HOS.Services.Aud
|
|||
return 0;
|
||||
}
|
||||
|
||||
[Command(10)]
|
||||
// GetActiveAudioDeviceNameAuto() -> buffer<bytes, 0x22>
|
||||
public long GetActiveAudioDeviceNameAuto(ServiceCtx context)
|
||||
{
|
||||
string name = context.Device.System.State.ActiveAudioOutput;
|
||||
|
@ -203,6 +201,8 @@ namespace Ryujinx.HLE.HOS.Services.Aud
|
|||
return 0;
|
||||
}
|
||||
|
||||
[Command(11)]
|
||||
// QueryAudioDeviceInputEvent() -> handle<copy, event>
|
||||
public long QueryAudioDeviceInputEvent(ServiceCtx context)
|
||||
{
|
||||
if (context.Process.HandleTable.GenerateHandle(_systemEvent.ReadableEvent, out int handle) != KernelResult.Success)
|
||||
|
@ -217,6 +217,8 @@ namespace Ryujinx.HLE.HOS.Services.Aud
|
|||
return 0;
|
||||
}
|
||||
|
||||
[Command(12)]
|
||||
// QueryAudioDeviceOutputEvent() -> handle<copy, event>
|
||||
public long QueryAudioDeviceOutputEvent(ServiceCtx context)
|
||||
{
|
||||
if (context.Process.HandleTable.GenerateHandle(_systemEvent.ReadableEvent, out int handle) != KernelResult.Success)
|
||||
|
@ -231,4 +233,4 @@ namespace Ryujinx.HLE.HOS.Services.Aud
|
|||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,10 +1,8 @@
|
|||
using ChocolArm64.Memory;
|
||||
using Ryujinx.Audio;
|
||||
using Ryujinx.Common.Logging;
|
||||
using Ryujinx.HLE.HOS.Ipc;
|
||||
using Ryujinx.HLE.HOS.Kernel.Threading;
|
||||
using Ryujinx.HLE.HOS.Services.Aud.AudioOut;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
using static Ryujinx.HLE.HOS.ErrorCode;
|
||||
|
@ -14,27 +12,14 @@ namespace Ryujinx.HLE.HOS.Services.Aud
|
|||
[Service("audout:u")]
|
||||
class IAudioOutManager : IpcService
|
||||
{
|
||||
private const string DefaultAudioOutput = "DeviceOut";
|
||||
private const string DefaultAudioOutput = "DeviceOut";
|
||||
private const int DefaultSampleRate = 48000;
|
||||
private const int DefaultChannelsCount = 2;
|
||||
|
||||
private const int DefaultSampleRate = 48000;
|
||||
|
||||
private const int DefaultChannelsCount = 2;
|
||||
|
||||
private Dictionary<int, ServiceProcessRequest> _commands;
|
||||
|
||||
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
|
||||
|
||||
public IAudioOutManager(ServiceCtx context)
|
||||
{
|
||||
_commands = new Dictionary<int, ServiceProcessRequest>
|
||||
{
|
||||
{ 0, ListAudioOuts },
|
||||
{ 1, OpenAudioOut },
|
||||
{ 2, ListAudioOutsAuto },
|
||||
{ 3, OpenAudioOutAuto }
|
||||
};
|
||||
}
|
||||
public IAudioOutManager(ServiceCtx context) { }
|
||||
|
||||
[Command(0)]
|
||||
// ListAudioOuts() -> (u32 count, buffer<bytes, 6>)
|
||||
public long ListAudioOuts(ServiceCtx context)
|
||||
{
|
||||
return ListAudioOutsImpl(
|
||||
|
@ -43,6 +28,9 @@ namespace Ryujinx.HLE.HOS.Services.Aud
|
|||
context.Request.ReceiveBuff[0].Size);
|
||||
}
|
||||
|
||||
[Command(1)]
|
||||
// OpenAudioOut(u32 sample_rate, u16 unused, u16 channel_count, nn::applet::AppletResourceUserId, pid, handle<copy, process>, buffer<bytes, 5> name_in)
|
||||
// -> (u32 sample_rate, u32 channel_count, u32 pcm_format, u32, object<nn::audio::detail::IAudioOut>, buffer<bytes, 6> name_out)
|
||||
public long OpenAudioOut(ServiceCtx context)
|
||||
{
|
||||
return OpenAudioOutImpl(
|
||||
|
@ -53,6 +41,8 @@ namespace Ryujinx.HLE.HOS.Services.Aud
|
|||
context.Request.ReceiveBuff[0].Size);
|
||||
}
|
||||
|
||||
[Command(2)] // 3.0.0+
|
||||
// ListAudioOutsAuto() -> (u32 count, buffer<bytes, 0x22>)
|
||||
public long ListAudioOutsAuto(ServiceCtx context)
|
||||
{
|
||||
(long recvPosition, long recvSize) = context.Request.GetBufferType0x22();
|
||||
|
@ -60,6 +50,9 @@ namespace Ryujinx.HLE.HOS.Services.Aud
|
|||
return ListAudioOutsImpl(context, recvPosition, recvSize);
|
||||
}
|
||||
|
||||
[Command(3)] // 3.0.0+
|
||||
// OpenAudioOutAuto(u32 sample_rate, u16 unused, u16 channel_count, nn::applet::AppletResourceUserId, pid, handle<copy, process>, buffer<bytes, 0x21>)
|
||||
// -> (u32 sample_rate, u32 channel_count, u32 pcm_format, u32, object<nn::audio::detail::IAudioOut>, buffer<bytes, 0x22> name_out)
|
||||
public long OpenAudioOutAuto(ServiceCtx context)
|
||||
{
|
||||
(long sendPosition, long sendSize) = context.Request.GetBufferType0x21();
|
||||
|
@ -168,4 +161,4 @@ namespace Ryujinx.HLE.HOS.Services.Aud
|
|||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,9 +1,7 @@
|
|||
using Ryujinx.Audio;
|
||||
using Ryujinx.Common.Logging;
|
||||
using Ryujinx.HLE.HOS.Ipc;
|
||||
using Ryujinx.HLE.HOS.Services.Aud.AudioRenderer;
|
||||
using Ryujinx.HLE.Utilities;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using static Ryujinx.HLE.HOS.ErrorCode;
|
||||
|
||||
|
@ -21,21 +19,11 @@ namespace Ryujinx.HLE.HOS.Services.Aud
|
|||
|
||||
public const int RevMagic = Rev0Magic + (Rev << 24);
|
||||
|
||||
private Dictionary<int, ServiceProcessRequest> _commands;
|
||||
|
||||
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
|
||||
|
||||
public IAudioRendererManager(ServiceCtx context)
|
||||
{
|
||||
_commands = new Dictionary<int, ServiceProcessRequest>
|
||||
{
|
||||
{ 0, OpenAudioRenderer },
|
||||
{ 1, GetAudioRendererWorkBufferSize },
|
||||
{ 2, GetAudioDeviceService },
|
||||
{ 4, GetAudioDeviceServiceWithRevisionInfo }
|
||||
};
|
||||
}
|
||||
public IAudioRendererManager(ServiceCtx context) { }
|
||||
|
||||
[Command(0)]
|
||||
// OpenAudioRenderer(nn::audio::detail::AudioRendererParameterInternal, u64, nn::applet::AppletResourceUserId, pid, handle<copy>, handle<copy>)
|
||||
// -> object<nn::audio::detail::IAudioRenderer>
|
||||
public long OpenAudioRenderer(ServiceCtx context)
|
||||
{
|
||||
IAalOutput audioOut = context.Device.AudioOut;
|
||||
|
@ -51,6 +39,8 @@ namespace Ryujinx.HLE.HOS.Services.Aud
|
|||
return 0;
|
||||
}
|
||||
|
||||
[Command(1)]
|
||||
// GetWorkBufferSize(nn::audio::detail::AudioRendererParameterInternal) -> u64
|
||||
public long GetAudioRendererWorkBufferSize(ServiceCtx context)
|
||||
{
|
||||
AudioRendererParameter Params = GetAudioRendererParameter(context);
|
||||
|
@ -178,6 +168,7 @@ namespace Ryujinx.HLE.HOS.Services.Aud
|
|||
return result / 8;
|
||||
}
|
||||
|
||||
[Command(2)]
|
||||
// GetAudioDeviceService(nn::applet::AppletResourceUserId) -> object<nn::audio::detail::IAudioDevice>
|
||||
public long GetAudioDeviceService(ServiceCtx context)
|
||||
{
|
||||
|
@ -188,6 +179,7 @@ namespace Ryujinx.HLE.HOS.Services.Aud
|
|||
return 0;
|
||||
}
|
||||
|
||||
[Command(4)] // 4.0.0+
|
||||
// GetAudioDeviceServiceWithRevisionInfo(nn::applet::AppletResourceUserId, u32) -> object<nn::audio::detail::IAudioDevice>
|
||||
private long GetAudioDeviceServiceWithRevisionInfo(ServiceCtx context)
|
||||
{
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
using Concentus.Structs;
|
||||
using Ryujinx.HLE.HOS.Ipc;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using static Ryujinx.HLE.HOS.ErrorCode;
|
||||
|
||||
|
@ -10,10 +8,6 @@ namespace Ryujinx.HLE.HOS.Services.Aud
|
|||
{
|
||||
private const int FixedSampleRate = 48000;
|
||||
|
||||
private Dictionary<int, ServiceProcessRequest> _commands;
|
||||
|
||||
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
|
||||
|
||||
private int _sampleRate;
|
||||
private int _channelsCount;
|
||||
|
||||
|
@ -21,29 +15,14 @@ namespace Ryujinx.HLE.HOS.Services.Aud
|
|||
|
||||
public IHardwareOpusDecoder(int sampleRate, int channelsCount)
|
||||
{
|
||||
_commands = new Dictionary<int, ServiceProcessRequest>
|
||||
{
|
||||
{ 0, DecodeInterleaved },
|
||||
{ 4, DecodeInterleavedWithPerf }
|
||||
};
|
||||
|
||||
_sampleRate = sampleRate;
|
||||
_channelsCount = channelsCount;
|
||||
|
||||
_decoder = new OpusDecoder(FixedSampleRate, channelsCount);
|
||||
}
|
||||
|
||||
public long DecodeInterleavedWithPerf(ServiceCtx context)
|
||||
{
|
||||
long result = DecodeInterleaved(context);
|
||||
|
||||
// TODO: Figure out what this value is.
|
||||
// According to switchbrew, it is now used.
|
||||
context.ResponseData.Write(0L);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
[Command(0)]
|
||||
// DecodeInterleaved(buffer<unknown, 5>) -> (u32, u32, buffer<unknown, 6>)
|
||||
public long DecodeInterleaved(ServiceCtx context)
|
||||
{
|
||||
long inPosition = context.Request.SendBuff[0].Position;
|
||||
|
@ -87,5 +66,18 @@ namespace Ryujinx.HLE.HOS.Services.Aud
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
[Command(4)]
|
||||
// DecodeInterleavedWithPerf(buffer<unknown, 5>) -> (u32, u32, u64, buffer<unknown, 0x46>)
|
||||
public long DecodeInterleavedWithPerf(ServiceCtx context)
|
||||
{
|
||||
long result = DecodeInterleaved(context);
|
||||
|
||||
// TODO: Figure out what this value is.
|
||||
// According to switchbrew, it is now used.
|
||||
context.ResponseData.Write(0L);
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,24 +1,12 @@
|
|||
using Ryujinx.HLE.HOS.Ipc;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Ryujinx.HLE.HOS.Services.Aud
|
||||
{
|
||||
[Service("hwopus")]
|
||||
class IHardwareOpusDecoderManager : IpcService
|
||||
{
|
||||
private Dictionary<int, ServiceProcessRequest> _commands;
|
||||
|
||||
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
|
||||
|
||||
public IHardwareOpusDecoderManager(ServiceCtx context)
|
||||
{
|
||||
_commands = new Dictionary<int, ServiceProcessRequest>
|
||||
{
|
||||
{ 0, Initialize },
|
||||
{ 1, GetWorkBufferSize }
|
||||
};
|
||||
}
|
||||
public IHardwareOpusDecoderManager(ServiceCtx context) { }
|
||||
|
||||
[Command(0)]
|
||||
// Initialize(bytes<8, 4>, u32, handle<copy>) -> object<nn::codec::detail::IHardwareOpusDecoder>
|
||||
public long Initialize(ServiceCtx context)
|
||||
{
|
||||
int sampleRate = context.RequestData.ReadInt32();
|
||||
|
@ -29,6 +17,8 @@ namespace Ryujinx.HLE.HOS.Services.Aud
|
|||
return 0;
|
||||
}
|
||||
|
||||
[Command(1)]
|
||||
// GetWorkBufferSize(bytes<8, 4>) -> u32
|
||||
public long GetWorkBufferSize(ServiceCtx context)
|
||||
{
|
||||
// Note: The sample rate is ignored because it is fixed to 48KHz.
|
||||
|
@ -70,4 +60,4 @@ namespace Ryujinx.HLE.HOS.Services.Aud
|
|||
celtSigSize;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue