public IAudioRenderer( Horizon system, MemoryManager memory, IAalOutput audioOut, AudioRendererParameter Params) { _updateEvent = new KEvent(system); _memory = memory; _audioOut = audioOut; _params = Params; _track = audioOut.OpenTrack( AudioConsts.HostSampleRate, AudioConsts.HostChannelsCount, AudioCallback); _memoryPools = CreateArray <MemoryPoolContext>(Params.EffectCount + Params.VoiceCount * 4); _voices = CreateArray <VoiceContext>(Params.VoiceCount); InitializeAudioOut(); _playState = PlayState.Stopped; }
public IAudioRenderer(AMemory Memory, IAalOutput AudioOut, AudioRendererParameter Params) { m_Commands = new Dictionary <int, ServiceProcessRequest>() { { 4, RequestUpdateAudioRenderer }, { 5, StartAudioRenderer }, { 6, StopAudioRenderer }, { 7, QuerySystemEvent } }; UpdateEvent = new KEvent(); this.Memory = Memory; this.AudioOut = AudioOut; this.Params = Params; Track = AudioOut.OpenTrack( AudioConsts.HostSampleRate, AudioConsts.HostChannelsCount, AudioCallback); MemoryPools = CreateArray <MemoryPoolContext>(Params.EffectCount + Params.VoiceCount * 4); Voices = CreateArray <VoiceContext>(Params.VoiceCount); InitializeAudioOut(); }
public static long CalculateCommandBufferSize(AudioRendererParameter parameters) { return(parameters.EffectCount * 0x840 + parameters.SubMixCount * 0x5A38 + parameters.SinkCount * 0x148 + parameters.SplitterDestinationDataCount * 0x540 + (parameters.SplitterCount * 0x68 + 0x2E0) * parameters.VoiceCount + ((parameters.VoiceCount + parameters.SubMixCount + parameters.EffectCount + parameters.SinkCount + 0x65) << 6) + 0x3F8); }
// OpenAudioRenderer(nn::audio::detail::AudioRendererParameterInternal, u64, nn::applet::AppletResourceUserId, pid, handle<copy>, handle<copy>) // -> object<nn::audio::detail::IAudioRenderer> public ResultCode OpenAudioRenderer(ServiceCtx context) { IAalOutput audioOut = context.Device.AudioOut; AudioRendererParameter Params = GetAudioRendererParameter(context); MakeObject(context, new IAudioRenderer( context.Device.System, context.Memory, audioOut, Params)); return(ResultCode.Success); }
private AudioRendererParameter GetAudioRendererParameter(ServiceCtx context) { AudioRendererParameter Params = new AudioRendererParameter { SampleRate = context.RequestData.ReadInt32(), SampleCount = context.RequestData.ReadInt32(), MixBufferCount = context.RequestData.ReadInt32(), SubMixCount = context.RequestData.ReadInt32(), VoiceCount = context.RequestData.ReadInt32(), SinkCount = context.RequestData.ReadInt32(), EffectCount = context.RequestData.ReadInt32(), PerformanceManagerCount = context.RequestData.ReadInt32(), VoiceDropEnable = context.RequestData.ReadInt32(), SplitterCount = context.RequestData.ReadInt32(), SplitterDestinationDataCount = context.RequestData.ReadInt32(), Unknown2C = context.RequestData.ReadInt32(), Revision = context.RequestData.ReadInt32() }; return(Params); }
public IAudioRenderer( Horizon system, MemoryManager memory, 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; _audioOut = audioOut; _params = Params; _track = audioOut.OpenTrack( AudioConsts.HostSampleRate, AudioConsts.HostChannelsCount, AudioCallback); _memoryPools = CreateArray <MemoryPoolContext>(Params.EffectCount + Params.VoiceCount * 4); _voices = CreateArray <VoiceContext>(Params.VoiceCount); InitializeAudioOut(); _playState = PlayState.Stopped; }
// GetWorkBufferSize(nn::audio::detail::AudioRendererParameterInternal) -> u64 public ResultCode GetAudioRendererWorkBufferSize(ServiceCtx context) { AudioRendererParameter parameters = GetAudioRendererParameter(context); if (AudioRendererCommon.CheckValidRevision(parameters)) { BehaviorInfo behaviorInfo = new BehaviorInfo(); behaviorInfo.SetUserLibRevision(parameters.Revision); long size; int totalMixCount = parameters.SubMixCount + 1; size = BitUtils.AlignUp(parameters.MixBufferCount * 4, AudioRendererConsts.BufferAlignment) + parameters.SubMixCount * 0x400 + totalMixCount * 0x940 + parameters.VoiceCount * 0x3F0 + BitUtils.AlignUp(totalMixCount * 8, 16) + BitUtils.AlignUp(parameters.VoiceCount * 8, 16) + BitUtils.AlignUp(((parameters.SinkCount + parameters.SubMixCount) * 0x3C0 + parameters.SampleCount * 4) * (parameters.MixBufferCount + 6), AudioRendererConsts.BufferAlignment) + (parameters.SinkCount + parameters.SubMixCount) * 0x2C0 + (parameters.EffectCount + parameters.VoiceCount * 4) * 0x30 + 0x50; if (behaviorInfo.IsSplitterSupported()) { size += BitUtils.AlignUp(NodeStates.GetWorkBufferSize(totalMixCount) + EdgeMatrix.GetWorkBufferSize(totalMixCount), 16); } size = parameters.SinkCount * 0x170 + (parameters.SinkCount + parameters.SubMixCount) * 0x280 + parameters.EffectCount * 0x4C0 + ((size + SplitterContext.CalcWorkBufferSize(behaviorInfo, parameters) + 0x30 * parameters.EffectCount + (4 * parameters.VoiceCount) + 0x8F) & ~0x3FL) + ((parameters.VoiceCount << 8) | 0x40); if (parameters.PerformanceManagerCount >= 1) { size += (PerformanceManager.GetRequiredBufferSizeForPerformanceMetricsPerFrame(behaviorInfo, parameters) * (parameters.PerformanceManagerCount + 1) + 0xFF) & ~0x3FL; } if (behaviorInfo.IsVariadicCommandBufferSizeSupported()) { size += CommandGenerator.CalculateCommandBufferSize(parameters) + 0x7E; } else { size += 0x1807E; } size = BitUtils.AlignUp(size, 0x1000); context.ResponseData.Write(size); Logger.PrintDebug(LogClass.ServiceAudio, $"WorkBufferSize is 0x{size:x16}."); return(ResultCode.Success); } else { context.ResponseData.Write(0L); Logger.PrintWarning(LogClass.ServiceAudio, $"Library Revision REV{AudioRendererCommon.GetRevisionVersion(parameters.Revision)} is not supported!"); return(ResultCode.UnsupportedRevision); } }
public static bool CheckValidRevision(AudioRendererParameter parameters) => GetRevisionVersion(parameters.Revision) <= AudioRendererConsts.Revision;