diff --git a/src/Ryujinx.Audio/Renderer/Dsp/Command/AdpcmDataSourceCommandVersion1.cs b/src/Ryujinx.Audio/Renderer/Dsp/Command/AdpcmDataSourceCommandVersion1.cs index 60161ee7a..6993ce0b2 100644 --- a/src/Ryujinx.Audio/Renderer/Dsp/Command/AdpcmDataSourceCommandVersion1.cs +++ b/src/Ryujinx.Audio/Renderer/Dsp/Command/AdpcmDataSourceCommandVersion1.cs @@ -11,27 +11,32 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command { public bool Enabled { get; set; } - public int NodeId { get; } + public int NodeId { get; private set; } public CommandType CommandType => CommandType.AdpcmDataSourceVersion1; public uint EstimatedProcessingTime { get; set; } - public ushort OutputBufferIndex { get; } - public uint SampleRate { get; } + public ushort OutputBufferIndex { get; private set; } + public uint SampleRate { get; private set; } - public float Pitch { get; } + public float Pitch { get; private set; } public WaveBuffer[] WaveBuffers { get; } - public Memory State { get; } + public Memory State { get; private set; } - public ulong AdpcmParameter { get; } - public ulong AdpcmParameterSize { get; } + public ulong AdpcmParameter { get; private set; } + public ulong AdpcmParameterSize { get; private set; } - public DecodingBehaviour DecodingBehaviour { get; } + public DecodingBehaviour DecodingBehaviour { get; private set; } - public AdpcmDataSourceCommandVersion1(ref VoiceInfo serverInfo, Memory state, ushort outputBufferIndex, int nodeId) + public AdpcmDataSourceCommandVersion1() + { + WaveBuffers = new WaveBuffer[Constants.VoiceWaveBufferCount]; + } + + public AdpcmDataSourceCommandVersion1 Initialize(ref VoiceInfo serverInfo, Memory state, ushort outputBufferIndex, int nodeId) { Enabled = true; NodeId = nodeId; @@ -42,8 +47,6 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command Span waveBufferSpan = serverInfo.WaveBuffers.AsSpan(); - WaveBuffers = new WaveBuffer[Constants.VoiceWaveBufferCount]; - for (int i = 0; i < WaveBuffers.Length; i++) { ref Server.Voice.WaveBuffer voiceWaveBuffer = ref waveBufferSpan[i]; @@ -55,6 +58,8 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command AdpcmParameterSize = serverInfo.DataSourceStateAddressInfo.Size; State = state; DecodingBehaviour = serverInfo.DecodingBehaviour; + + return this; } public void Process(CommandList context) diff --git a/src/Ryujinx.Audio/Renderer/Dsp/Command/AuxiliaryBufferCommand.cs b/src/Ryujinx.Audio/Renderer/Dsp/Command/AuxiliaryBufferCommand.cs index 73d66dcf4..adc20cb4f 100644 --- a/src/Ryujinx.Audio/Renderer/Dsp/Command/AuxiliaryBufferCommand.cs +++ b/src/Ryujinx.Audio/Renderer/Dsp/Command/AuxiliaryBufferCommand.cs @@ -12,26 +12,31 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command { public bool Enabled { get; set; } - public int NodeId { get; } + public int NodeId { get; private set; } public CommandType CommandType => CommandType.AuxiliaryBuffer; public uint EstimatedProcessingTime { get; set; } - public uint InputBufferIndex { get; } - public uint OutputBufferIndex { get; } + public uint InputBufferIndex { get; private set; } + public uint OutputBufferIndex { get; private set; } - public AuxiliaryBufferAddresses BufferInfo { get; } + public AuxiliaryBufferAddresses BufferInfo { get; private set; } - public CpuAddress InputBuffer { get; } - public CpuAddress OutputBuffer { get; } - public uint CountMax { get; } - public uint UpdateCount { get; } - public uint WriteOffset { get; } + public CpuAddress InputBuffer { get; private set; } + public CpuAddress OutputBuffer { get; private set; } + public uint CountMax { get; private set; } + public uint UpdateCount { get; private set; } + public uint WriteOffset { get; private set; } - public bool IsEffectEnabled { get; } + public bool IsEffectEnabled { get; private set; } - public AuxiliaryBufferCommand( + public AuxiliaryBufferCommand() + { + + } + + public AuxiliaryBufferCommand Initialize( uint bufferOffset, byte inputBufferOffset, byte outputBufferOffset, @@ -55,6 +60,8 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command UpdateCount = updateCount; WriteOffset = writeOffset; IsEffectEnabled = isEnabled; + + return this; } [MethodImpl(MethodImplOptions.AggressiveInlining)] diff --git a/src/Ryujinx.Audio/Renderer/Dsp/Command/BiquadFilterAndMixCommand.cs b/src/Ryujinx.Audio/Renderer/Dsp/Command/BiquadFilterAndMixCommand.cs index 624c0d55b..6fb6ebdc9 100644 --- a/src/Ryujinx.Audio/Renderer/Dsp/Command/BiquadFilterAndMixCommand.cs +++ b/src/Ryujinx.Audio/Renderer/Dsp/Command/BiquadFilterAndMixCommand.cs @@ -9,32 +9,37 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command { public bool Enabled { get; set; } - public int NodeId { get; } + public int NodeId { get; private set; } public CommandType CommandType => CommandType.BiquadFilterAndMix; public uint EstimatedProcessingTime { get; set; } - public ushort InputBufferIndex { get; } - public ushort OutputBufferIndex { get; } + public ushort InputBufferIndex { get; private set; } + public ushort OutputBufferIndex { get; private set; } private BiquadFilterParameter2 _parameter; - public Memory BiquadFilterState { get; } - public Memory PreviousBiquadFilterState { get; } + public Memory BiquadFilterState { get; private set; } + public Memory PreviousBiquadFilterState { get; private set; } - public Memory State { get; } + public Memory State { get; private set; } - public int LastSampleIndex { get; } + public int LastSampleIndex { get; private set; } - public float Volume0 { get; } - public float Volume1 { get; } + public float Volume0 { get; private set; } + public float Volume1 { get; private set; } - public bool NeedInitialization { get; } - public bool HasVolumeRamp { get; } - public bool IsFirstMixBuffer { get; } + public bool NeedInitialization { get; private set; } + public bool HasVolumeRamp { get; private set; } + public bool IsFirstMixBuffer { get; private set; } - public BiquadFilterAndMixCommand( + public BiquadFilterAndMixCommand() + { + + } + + public BiquadFilterAndMixCommand Initialize( float volume0, float volume1, uint inputBufferIndex, @@ -68,6 +73,8 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command NeedInitialization = needInitialization; HasVolumeRamp = hasVolumeRamp; IsFirstMixBuffer = isFirstMixBuffer; + + return this; } public void Process(CommandList context) diff --git a/src/Ryujinx.Audio/Renderer/Dsp/Command/BiquadFilterCommand.cs b/src/Ryujinx.Audio/Renderer/Dsp/Command/BiquadFilterCommand.cs index a8c996428..496c83a58 100644 --- a/src/Ryujinx.Audio/Renderer/Dsp/Command/BiquadFilterCommand.cs +++ b/src/Ryujinx.Audio/Renderer/Dsp/Command/BiquadFilterCommand.cs @@ -8,20 +8,25 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command { public bool Enabled { get; set; } - public int NodeId { get; } + public int NodeId { get; private set; } public CommandType CommandType => CommandType.BiquadFilter; public uint EstimatedProcessingTime { get; set; } - public Memory BiquadFilterState { get; } - public int InputBufferIndex { get; } - public int OutputBufferIndex { get; } - public bool NeedInitialization { get; } + public Memory BiquadFilterState { get; private set; } + public int InputBufferIndex { get; private set; } + public int OutputBufferIndex { get; private set; } + public bool NeedInitialization { get; private set; } private BiquadFilterParameter2 _parameter; - public BiquadFilterCommand( + public BiquadFilterCommand() + { + + } + + public BiquadFilterCommand Initialize( int baseIndex, ref BiquadFilterParameter2 filter, Memory biquadFilterStateMemory, @@ -38,6 +43,8 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command Enabled = true; NodeId = nodeId; + + return this; } public void Process(CommandList context) diff --git a/src/Ryujinx.Audio/Renderer/Dsp/Command/CaptureBufferCommand.cs b/src/Ryujinx.Audio/Renderer/Dsp/Command/CaptureBufferCommand.cs index 01bff1e7d..a3b8b37da 100644 --- a/src/Ryujinx.Audio/Renderer/Dsp/Command/CaptureBufferCommand.cs +++ b/src/Ryujinx.Audio/Renderer/Dsp/Command/CaptureBufferCommand.cs @@ -12,25 +12,30 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command { public bool Enabled { get; set; } - public int NodeId { get; } + public int NodeId { get; private set; } public CommandType CommandType => CommandType.CaptureBuffer; public uint EstimatedProcessingTime { get; set; } - public uint InputBufferIndex { get; } + public uint InputBufferIndex { get; private set; } - public ulong CpuBufferInfoAddress { get; } - public ulong DspBufferInfoAddress { get; } + public ulong CpuBufferInfoAddress { get; private set; } + public ulong DspBufferInfoAddress { get; private set; } - public CpuAddress OutputBuffer { get; } - public uint CountMax { get; } - public uint UpdateCount { get; } - public uint WriteOffset { get; } + public CpuAddress OutputBuffer { get; private set; } + public uint CountMax { get; private set; } + public uint UpdateCount { get; private set; } + public uint WriteOffset { get; private set; } - public bool IsEffectEnabled { get; } + public bool IsEffectEnabled { get; private set; } - public CaptureBufferCommand(uint bufferOffset, byte inputBufferOffset, ulong sendBufferInfo, bool isEnabled, + public CaptureBufferCommand() + { + + } + + public CaptureBufferCommand Initialize(uint bufferOffset, byte inputBufferOffset, ulong sendBufferInfo, bool isEnabled, uint countMax, CpuAddress outputBuffer, uint updateCount, uint writeOffset, int nodeId) { Enabled = true; @@ -43,6 +48,8 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command UpdateCount = updateCount; WriteOffset = writeOffset; IsEffectEnabled = isEnabled; + + return this; } [MethodImpl(MethodImplOptions.AggressiveInlining)] diff --git a/src/Ryujinx.Audio/Renderer/Dsp/Command/CircularBufferSinkCommand.cs b/src/Ryujinx.Audio/Renderer/Dsp/Command/CircularBufferSinkCommand.cs index d5488b321..dc319e560 100644 --- a/src/Ryujinx.Audio/Renderer/Dsp/Command/CircularBufferSinkCommand.cs +++ b/src/Ryujinx.Audio/Renderer/Dsp/Command/CircularBufferSinkCommand.cs @@ -9,25 +9,29 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command { public bool Enabled { get; set; } - public int NodeId { get; } + public int NodeId { get; private set; } public CommandType CommandType => CommandType.CircularBufferSink; public uint EstimatedProcessingTime { get; set; } public ushort[] Input { get; } - public uint InputCount { get; } + public uint InputCount { get; private set; } - public ulong CircularBuffer { get; } - public ulong CircularBufferSize { get; } - public ulong CurrentOffset { get; } + public ulong CircularBuffer { get; private set; } + public ulong CircularBufferSize { get; private set; } + public ulong CurrentOffset { get; private set; } - public CircularBufferSinkCommand(uint bufferOffset, ref CircularBufferParameter parameter, ref AddressInfo circularBufferAddressInfo, uint currentOffset, int nodeId) + public CircularBufferSinkCommand() + { + Input = new ushort[Constants.ChannelCountMax]; + } + + public CircularBufferSinkCommand Initialize(uint bufferOffset, ref CircularBufferParameter parameter, ref AddressInfo circularBufferAddressInfo, uint currentOffset, int nodeId) { Enabled = true; NodeId = nodeId; - Input = new ushort[Constants.ChannelCountMax]; InputCount = parameter.InputCount; Span inputSpan = parameter.Input.AsSpan(); @@ -42,6 +46,8 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command CurrentOffset = currentOffset; Debug.Assert(CircularBuffer != 0); + + return this; } public void Process(CommandList context) diff --git a/src/Ryujinx.Audio/Renderer/Dsp/Command/ClearMixBufferCommand.cs b/src/Ryujinx.Audio/Renderer/Dsp/Command/ClearMixBufferCommand.cs index f0f85b0b2..b8a7efd1f 100644 --- a/src/Ryujinx.Audio/Renderer/Dsp/Command/ClearMixBufferCommand.cs +++ b/src/Ryujinx.Audio/Renderer/Dsp/Command/ClearMixBufferCommand.cs @@ -4,16 +4,23 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command { public bool Enabled { get; set; } - public int NodeId { get; } + public int NodeId { get; private set; } public CommandType CommandType => CommandType.ClearMixBuffer; public uint EstimatedProcessingTime { get; set; } - public ClearMixBufferCommand(int nodeId) + public ClearMixBufferCommand() + { + + } + + public ClearMixBufferCommand Initialize(int nodeId) { Enabled = true; NodeId = nodeId; + + return this; } public void Process(CommandList context) diff --git a/src/Ryujinx.Audio/Renderer/Dsp/Command/CommandList.cs b/src/Ryujinx.Audio/Renderer/Dsp/Command/CommandList.cs index 9abd6a18a..f29e8218e 100644 --- a/src/Ryujinx.Audio/Renderer/Dsp/Command/CommandList.cs +++ b/src/Ryujinx.Audio/Renderer/Dsp/Command/CommandList.cs @@ -20,6 +20,7 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command public Memory Buffers { get; } public uint BufferCount { get; } + private readonly static ObjectPool> CommandsListPool = new(() => new List(256)); public List Commands { get; } public IVirtualMemoryManager MemoryManager { get; } @@ -46,7 +47,7 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command SampleRate = sampleRate; BufferCount = mixBufferCount + voiceChannelCountMax; Buffers = mixBuffer; - Commands = []; + Commands = CommandsListPool.Allocate(); MemoryManager = memoryManager; _buffersEntryCount = Buffers.Length; @@ -142,6 +143,8 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command } } } + + CommandBuffer.ReleaseCommand(command); } EndTime = (ulong)PerformanceCounter.ElapsedNanoseconds; @@ -149,6 +152,8 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command public void Dispose() { + Commands.Clear(); + CommandsListPool.Release(Commands); GC.SuppressFinalize(this); _buffersMemoryHandle.Dispose(); } diff --git a/src/Ryujinx.Audio/Renderer/Dsp/Command/CompressorCommand.cs b/src/Ryujinx.Audio/Renderer/Dsp/Command/CompressorCommand.cs index a668155f8..0267ab239 100644 --- a/src/Ryujinx.Audio/Renderer/Dsp/Command/CompressorCommand.cs +++ b/src/Ryujinx.Audio/Renderer/Dsp/Command/CompressorCommand.cs @@ -15,22 +15,28 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command public bool Enabled { get; set; } - public int NodeId { get; } + public int NodeId { get; private set; } public CommandType CommandType => CommandType.Compressor; public uint EstimatedProcessingTime { get; set; } public CompressorParameter Parameter => _parameter; - public Memory State { get; } - public Memory ResultState { get; } + public Memory State { get; private set; } + public Memory ResultState { get; private set; } public ushort[] OutputBufferIndices { get; } public ushort[] InputBufferIndices { get; } - public bool IsEffectEnabled { get; } + public bool IsEffectEnabled { get; private set; } private CompressorParameter _parameter; - public CompressorCommand(uint bufferOffset, CompressorParameter parameter, Memory state, Memory resultState, bool isEnabled, int nodeId) + public CompressorCommand() + { + InputBufferIndices = new ushort[Constants.VoiceChannelCountMax]; + OutputBufferIndices = new ushort[Constants.VoiceChannelCountMax]; + } + + public CompressorCommand Initialize(uint bufferOffset, CompressorParameter parameter, Memory state, Memory resultState, bool isEnabled, int nodeId) { Enabled = true; NodeId = nodeId; @@ -39,9 +45,6 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command ResultState = resultState; IsEffectEnabled = isEnabled; - - InputBufferIndices = new ushort[Constants.VoiceChannelCountMax]; - OutputBufferIndices = new ushort[Constants.VoiceChannelCountMax]; Span inputSpan = _parameter.Input.AsSpan(); Span outputSpan = _parameter.Output.AsSpan(); @@ -51,6 +54,8 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command InputBufferIndices[i] = (ushort)(bufferOffset + inputSpan[i]); OutputBufferIndices[i] = (ushort)(bufferOffset + outputSpan[i]); } + + return this; } public void Process(CommandList context) diff --git a/src/Ryujinx.Audio/Renderer/Dsp/Command/CopyMixBufferCommand.cs b/src/Ryujinx.Audio/Renderer/Dsp/Command/CopyMixBufferCommand.cs index 3f6aa8390..5fc8e7258 100644 --- a/src/Ryujinx.Audio/Renderer/Dsp/Command/CopyMixBufferCommand.cs +++ b/src/Ryujinx.Audio/Renderer/Dsp/Command/CopyMixBufferCommand.cs @@ -4,22 +4,29 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command { public bool Enabled { get; set; } - public int NodeId { get; } + public int NodeId { get; private set; } public CommandType CommandType => CommandType.CopyMixBuffer; public uint EstimatedProcessingTime { get; set; } - public ushort InputBufferIndex { get; } - public ushort OutputBufferIndex { get; } + public ushort InputBufferIndex { get; private set; } + public ushort OutputBufferIndex { get; private set; } - public CopyMixBufferCommand(uint inputBufferIndex, uint outputBufferIndex, int nodeId) + public CopyMixBufferCommand() + { + + } + + public CopyMixBufferCommand Initialize(uint inputBufferIndex, uint outputBufferIndex, int nodeId) { Enabled = true; NodeId = nodeId; InputBufferIndex = (ushort)inputBufferIndex; OutputBufferIndex = (ushort)outputBufferIndex; + + return this; } public void Process(CommandList context) diff --git a/src/Ryujinx.Audio/Renderer/Dsp/Command/DataSourceVersion2Command.cs b/src/Ryujinx.Audio/Renderer/Dsp/Command/DataSourceVersion2Command.cs index 1fbd95c32..8b72687da 100644 --- a/src/Ryujinx.Audio/Renderer/Dsp/Command/DataSourceVersion2Command.cs +++ b/src/Ryujinx.Audio/Renderer/Dsp/Command/DataSourceVersion2Command.cs @@ -3,6 +3,7 @@ using Ryujinx.Audio.Renderer.Common; using Ryujinx.Audio.Renderer.Server.Voice; using System; using Ryujinx.Audio.Renderer.Parameter; +using Ryujinx.Memory; using WaveBuffer = Ryujinx.Audio.Renderer.Common.WaveBuffer; namespace Ryujinx.Audio.Renderer.Dsp.Command @@ -11,35 +12,40 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command { public bool Enabled { get; set; } - public int NodeId { get; } + public int NodeId { get; private set; } - public CommandType CommandType { get; } + public CommandType CommandType { get; private set; } public uint EstimatedProcessingTime { get; set; } - public ushort OutputBufferIndex { get; } - public uint SampleRate { get; } + public ushort OutputBufferIndex { get; private set; } + public uint SampleRate { get; private set; } - public float Pitch { get; } + public float Pitch { get; private set; } public WaveBuffer[] WaveBuffers { get; } - public Memory State { get; } + public Memory State { get; private set; } - public ulong ExtraParameter { get; } - public ulong ExtraParameterSize { get; } + public ulong ExtraParameter { get; private set; } + public ulong ExtraParameterSize { get; private set; } - public uint ChannelIndex { get; } + public uint ChannelIndex { get; private set; } - public uint ChannelCount { get; } + public uint ChannelCount { get; private set; } - public DecodingBehaviour DecodingBehaviour { get; } + public DecodingBehaviour DecodingBehaviour { get; private set; } - public SampleFormat SampleFormat { get; } + public SampleFormat SampleFormat { get; private set; } - public SampleRateConversionQuality SrcQuality { get; } + public SampleRateConversionQuality SrcQuality { get; private set; } - public DataSourceVersion2Command(ref VoiceInfo serverInfo, Memory state, ushort outputBufferIndex, ushort channelIndex, int nodeId) + public DataSourceVersion2Command() + { + WaveBuffers = new WaveBuffer[Constants.VoiceWaveBufferCount]; + } + + public DataSourceVersion2Command Initialize(ref VoiceInfo serverInfo, Memory state, ushort outputBufferIndex, ushort channelIndex, int nodeId) { Enabled = true; NodeId = nodeId; @@ -55,8 +61,6 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command Span waveBufferSpan = serverInfo.WaveBuffers.AsSpan(); - WaveBuffers = new WaveBuffer[Constants.VoiceWaveBufferCount]; - for (int i = 0; i < WaveBuffers.Length; i++) { ref Server.Voice.WaveBuffer voiceWaveBuffer = ref waveBufferSpan[i]; @@ -72,6 +76,8 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command State = state; DecodingBehaviour = serverInfo.DecodingBehaviour; + + return this; } private static CommandType GetCommandTypeBySampleFormat(SampleFormat sampleFormat) diff --git a/src/Ryujinx.Audio/Renderer/Dsp/Command/DelayCommand.cs b/src/Ryujinx.Audio/Renderer/Dsp/Command/DelayCommand.cs index 491233770..295278dc6 100644 --- a/src/Ryujinx.Audio/Renderer/Dsp/Command/DelayCommand.cs +++ b/src/Ryujinx.Audio/Renderer/Dsp/Command/DelayCommand.cs @@ -13,24 +13,30 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command { public bool Enabled { get; set; } - public int NodeId { get; } + public int NodeId { get; private set; } public CommandType CommandType => CommandType.Delay; public uint EstimatedProcessingTime { get; set; } public DelayParameter Parameter => _parameter; - public Memory State { get; } - public ulong WorkBuffer { get; } + public Memory State { get; private set; } + public ulong WorkBuffer { get; private set; } public ushort[] OutputBufferIndices { get; } public ushort[] InputBufferIndices { get; } - public bool IsEffectEnabled { get; } + public bool IsEffectEnabled { get; private set; } private DelayParameter _parameter; private const int FixedPointPrecision = 14; - public DelayCommand(uint bufferOffset, DelayParameter parameter, Memory state, bool isEnabled, ulong workBuffer, int nodeId, bool newEffectChannelMappingSupported) + public DelayCommand() + { + InputBufferIndices = new ushort[Constants.VoiceChannelCountMax]; + OutputBufferIndices = new ushort[Constants.VoiceChannelCountMax]; + } + + public DelayCommand Initialize(uint bufferOffset, DelayParameter parameter, Memory state, bool isEnabled, ulong workBuffer, int nodeId, bool newEffectChannelMappingSupported) { Enabled = true; NodeId = nodeId; @@ -39,9 +45,6 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command WorkBuffer = workBuffer; IsEffectEnabled = isEnabled; - - InputBufferIndices = new ushort[Constants.VoiceChannelCountMax]; - OutputBufferIndices = new ushort[Constants.VoiceChannelCountMax]; Span inputSpan = Parameter.Input.AsSpan(); Span outputSpan = Parameter.Output.AsSpan(); @@ -54,6 +57,8 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command DataSourceHelper.RemapLegacyChannelEffectMappingToChannelResourceMapping(newEffectChannelMappingSupported, InputBufferIndices, Parameter.ChannelCount); DataSourceHelper.RemapLegacyChannelEffectMappingToChannelResourceMapping(newEffectChannelMappingSupported, OutputBufferIndices, Parameter.ChannelCount); + + return this; } [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] diff --git a/src/Ryujinx.Audio/Renderer/Dsp/Command/DepopForMixBuffersCommand.cs b/src/Ryujinx.Audio/Renderer/Dsp/Command/DepopForMixBuffersCommand.cs index ff38f38ca..6986043c7 100644 --- a/src/Ryujinx.Audio/Renderer/Dsp/Command/DepopForMixBuffersCommand.cs +++ b/src/Ryujinx.Audio/Renderer/Dsp/Command/DepopForMixBuffersCommand.cs @@ -7,21 +7,26 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command { public bool Enabled { get; set; } - public int NodeId { get; } + public int NodeId { get; private set; } public CommandType CommandType => CommandType.DepopForMixBuffers; public uint EstimatedProcessingTime { get; set; } - public uint MixBufferOffset { get; } + public uint MixBufferOffset { get; private set; } - public uint MixBufferCount { get; } + public uint MixBufferCount { get; private set; } - public float Decay { get; } + public float Decay { get; private set; } - public Memory DepopBuffer { get; } + public Memory DepopBuffer { get; private set; } - public DepopForMixBuffersCommand(Memory depopBuffer, uint bufferOffset, uint mixBufferCount, int nodeId, uint sampleRate) + public DepopForMixBuffersCommand() + { + + } + + public DepopForMixBuffersCommand Initialize(Memory depopBuffer, uint bufferOffset, uint mixBufferCount, int nodeId, uint sampleRate) { Enabled = true; NodeId = nodeId; @@ -37,6 +42,8 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command { Decay = 0.943695f; } + + return this; } [MethodImpl(MethodImplOptions.AggressiveInlining)] diff --git a/src/Ryujinx.Audio/Renderer/Dsp/Command/DepopPrepareCommand.cs b/src/Ryujinx.Audio/Renderer/Dsp/Command/DepopPrepareCommand.cs index 18ae11eb4..24af18ea5 100644 --- a/src/Ryujinx.Audio/Renderer/Dsp/Command/DepopPrepareCommand.cs +++ b/src/Ryujinx.Audio/Renderer/Dsp/Command/DepopPrepareCommand.cs @@ -7,27 +7,30 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command { public bool Enabled { get; set; } - public int NodeId { get; } + public int NodeId { get; private set; } public CommandType CommandType => CommandType.DepopPrepare; public uint EstimatedProcessingTime { get; set; } - public uint MixBufferCount { get; } + public uint MixBufferCount { get; private set; } public ushort[] OutputBufferIndices { get; } - public Memory State { get; } - public Memory DepopBuffer { get; } + public Memory State { get; private set; } + public Memory DepopBuffer { get; private set; } - public DepopPrepareCommand(Memory state, Memory depopBuffer, uint mixBufferCount, uint bufferOffset, int nodeId, bool enabled) + public DepopPrepareCommand() + { + OutputBufferIndices = new ushort[Constants.MixBufferCountMax]; + } + + public DepopPrepareCommand Initialize(Memory state, Memory depopBuffer, uint mixBufferCount, uint bufferOffset, int nodeId, bool enabled) { Enabled = enabled; NodeId = nodeId; MixBufferCount = mixBufferCount; - OutputBufferIndices = new ushort[Constants.MixBufferCountMax]; - for (int i = 0; i < Constants.MixBufferCountMax; i++) { OutputBufferIndices[i] = (ushort)(bufferOffset + i); @@ -35,6 +38,8 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command State = state; DepopBuffer = depopBuffer; + + return this; } public void Process(CommandList context) diff --git a/src/Ryujinx.Audio/Renderer/Dsp/Command/DeviceSinkCommand.cs b/src/Ryujinx.Audio/Renderer/Dsp/Command/DeviceSinkCommand.cs index b0e4b3c99..aeb187b41 100644 --- a/src/Ryujinx.Audio/Renderer/Dsp/Command/DeviceSinkCommand.cs +++ b/src/Ryujinx.Audio/Renderer/Dsp/Command/DeviceSinkCommand.cs @@ -10,22 +10,27 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command { public bool Enabled { get; set; } - public int NodeId { get; } + public int NodeId { get; private set; } public CommandType CommandType => CommandType.DeviceSink; public uint EstimatedProcessingTime { get; set; } - public string DeviceName { get; } + public string DeviceName { get; private set; } - public int SessionId { get; } + public int SessionId { get; private set; } - public uint InputCount { get; } - public ushort[] InputBufferIndices { get; } + public uint InputCount { get; private set; } + public ushort[] InputBufferIndices { get; private set; } - public Memory Buffers { get; } + public Memory Buffers { get; private set; } - public DeviceSinkCommand(uint bufferOffset, DeviceSink sink, int sessionId, Memory buffers, int nodeId) + public DeviceSinkCommand() + { + + } + + public DeviceSinkCommand Initialize(uint bufferOffset, DeviceSink sink, int sessionId, Memory buffers, int nodeId) { Enabled = true; NodeId = nodeId; @@ -50,6 +55,8 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command { Buffers = buffers; } + + return this; } [MethodImpl(MethodImplOptions.AggressiveInlining)] diff --git a/src/Ryujinx.Audio/Renderer/Dsp/Command/DownMixSurroundToStereoCommand.cs b/src/Ryujinx.Audio/Renderer/Dsp/Command/DownMixSurroundToStereoCommand.cs index 8997b0dbd..751954fc8 100644 --- a/src/Ryujinx.Audio/Renderer/Dsp/Command/DownMixSurroundToStereoCommand.cs +++ b/src/Ryujinx.Audio/Renderer/Dsp/Command/DownMixSurroundToStereoCommand.cs @@ -7,7 +7,7 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command { public bool Enabled { get; set; } - public int NodeId { get; } + public int NodeId { get; private set; } public CommandType CommandType => CommandType.DownMixSurroundToStereo; @@ -16,16 +16,19 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command public ushort[] InputBufferIndices { get; } public ushort[] OutputBufferIndices { get; } - public float[] Coefficients { get; } + public float[] Coefficients { get; private set; } - public DownMixSurroundToStereoCommand(uint bufferOffset, Span inputBufferOffset, Span outputBufferOffset, float[] downMixParameter, int nodeId) + public DownMixSurroundToStereoCommand() + { + InputBufferIndices = new ushort[Constants.VoiceChannelCountMax]; + OutputBufferIndices = new ushort[Constants.VoiceChannelCountMax]; + } + + public DownMixSurroundToStereoCommand Initialize(uint bufferOffset, Span inputBufferOffset, Span outputBufferOffset, float[] downMixParameter, int nodeId) { Enabled = true; NodeId = nodeId; - InputBufferIndices = new ushort[Constants.VoiceChannelCountMax]; - OutputBufferIndices = new ushort[Constants.VoiceChannelCountMax]; - for (int i = 0; i < Constants.VoiceChannelCountMax; i++) { InputBufferIndices[i] = (ushort)(bufferOffset + inputBufferOffset[i]); @@ -33,6 +36,8 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command } Coefficients = downMixParameter; + + return this; } [MethodImpl(MethodImplOptions.AggressiveInlining)] diff --git a/src/Ryujinx.Audio/Renderer/Dsp/Command/FillBufferCommand.cs b/src/Ryujinx.Audio/Renderer/Dsp/Command/FillBufferCommand.cs index ca5428c56..15ccd5239 100644 --- a/src/Ryujinx.Audio/Renderer/Dsp/Command/FillBufferCommand.cs +++ b/src/Ryujinx.Audio/Renderer/Dsp/Command/FillBufferCommand.cs @@ -8,38 +8,43 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command { public bool Enabled { get; set; } - public int NodeId { get; } + public int NodeId { get; private set; } public CommandType CommandType => CommandType.FillBuffer; public uint EstimatedProcessingTime { get; set; } - public SplitterDestinationVersion1 Destination1 { get; } - public SplitterDestinationVersion2 Destination2 { get; } - public bool IsV2 { get; } - public int Length { get; } - public float Value { get; } + public SplitterDestinationVersion1 Destination1 { get; private set; } + public SplitterDestinationVersion2 Destination2 { get; private set; } + public bool IsV2 { get; private set; } + public int Length { get; private set; } + public float Value { get; private set; } - public FillBufferCommand(SplitterDestinationVersion1 destination, int length, float value, int nodeId) + public FillBufferCommand() { - Enabled = true; - NodeId = nodeId; - - Destination1 = destination; - IsV2 = false; - Length = length; - Value = value; + } - public FillBufferCommand(SplitterDestinationVersion2 destination, int length, float value, int nodeId) + public FillBufferCommand Initialize(SplitterDestination destination, int length, float value, int nodeId) { Enabled = true; NodeId = nodeId; + + if (Unsafe.IsNullRef(ref destination.GetV2RefOrNull())) + { + Destination1 = destination.GetV1RefOrNull(); + IsV2 = false; + } + else + { + Destination2 = destination.GetV2RefOrNull(); + IsV2 = true; + } - Destination2 = destination; - IsV2 = true; Length = length; Value = value; + + return this; } [MethodImpl(MethodImplOptions.AggressiveInlining)] diff --git a/src/Ryujinx.Audio/Renderer/Dsp/Command/LimiterCommandVersion1.cs b/src/Ryujinx.Audio/Renderer/Dsp/Command/LimiterCommandVersion1.cs index b0a0183f8..115f494d2 100644 --- a/src/Ryujinx.Audio/Renderer/Dsp/Command/LimiterCommandVersion1.cs +++ b/src/Ryujinx.Audio/Renderer/Dsp/Command/LimiterCommandVersion1.cs @@ -10,22 +10,28 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command { public bool Enabled { get; set; } - public int NodeId { get; } + public int NodeId { get; private set; } public CommandType CommandType => CommandType.LimiterVersion1; public uint EstimatedProcessingTime { get; set; } public LimiterParameter Parameter => _parameter; - public Memory State { get; } - public ulong WorkBuffer { get; } + public Memory State { get; private set; } + public ulong WorkBuffer { get; private set; } public ushort[] OutputBufferIndices { get; } public ushort[] InputBufferIndices { get; } - public bool IsEffectEnabled { get; } + public bool IsEffectEnabled { get; private set; } private LimiterParameter _parameter; - public LimiterCommandVersion1(uint bufferOffset, LimiterParameter parameter, Memory state, bool isEnabled, ulong workBuffer, int nodeId) + public LimiterCommandVersion1() + { + InputBufferIndices = new ushort[Constants.VoiceChannelCountMax]; + OutputBufferIndices = new ushort[Constants.VoiceChannelCountMax]; + } + + public LimiterCommandVersion1 Initialize(uint bufferOffset, LimiterParameter parameter, Memory state, bool isEnabled, ulong workBuffer, int nodeId) { Enabled = true; NodeId = nodeId; @@ -35,9 +41,6 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command IsEffectEnabled = isEnabled; - InputBufferIndices = new ushort[Constants.VoiceChannelCountMax]; - OutputBufferIndices = new ushort[Constants.VoiceChannelCountMax]; - Span inputSpan = _parameter.Input.AsSpan(); Span outputSpan = _parameter.Output.AsSpan(); @@ -46,6 +49,8 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command InputBufferIndices[i] = (ushort)(bufferOffset + inputSpan[i]); OutputBufferIndices[i] = (ushort)(bufferOffset + outputSpan[i]); } + + return this; } public void Process(CommandList context) diff --git a/src/Ryujinx.Audio/Renderer/Dsp/Command/LimiterCommandVersion2.cs b/src/Ryujinx.Audio/Renderer/Dsp/Command/LimiterCommandVersion2.cs index 36cc0e768..f00529925 100644 --- a/src/Ryujinx.Audio/Renderer/Dsp/Command/LimiterCommandVersion2.cs +++ b/src/Ryujinx.Audio/Renderer/Dsp/Command/LimiterCommandVersion2.cs @@ -12,23 +12,29 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command { public bool Enabled { get; set; } - public int NodeId { get; } + public int NodeId { get; private set; } public CommandType CommandType => CommandType.LimiterVersion2; public uint EstimatedProcessingTime { get; set; } public LimiterParameter Parameter => _parameter; - public Memory State { get; } - public Memory ResultState { get; } - public ulong WorkBuffer { get; } + public Memory State { get; private set; } + public Memory ResultState { get; private set; } + public ulong WorkBuffer { get; private set; } public ushort[] OutputBufferIndices { get; } public ushort[] InputBufferIndices { get; } - public bool IsEffectEnabled { get; } + public bool IsEffectEnabled { get; private set; } private LimiterParameter _parameter; - public LimiterCommandVersion2( + public LimiterCommandVersion2() + { + InputBufferIndices = new ushort[Constants.VoiceChannelCountMax]; + OutputBufferIndices = new ushort[Constants.VoiceChannelCountMax]; + } + + public LimiterCommandVersion2 Initialize( uint bufferOffset, LimiterParameter parameter, Memory state, @@ -45,9 +51,6 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command WorkBuffer = workBuffer; IsEffectEnabled = isEnabled; - - InputBufferIndices = new ushort[Constants.VoiceChannelCountMax]; - OutputBufferIndices = new ushort[Constants.VoiceChannelCountMax]; Span inputSpan = _parameter.Input.AsSpan(); Span outputSpan = _parameter.Output.AsSpan(); @@ -57,6 +60,8 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command InputBufferIndices[i] = (ushort)(bufferOffset + inputSpan[i]); OutputBufferIndices[i] = (ushort)(bufferOffset + outputSpan[i]); } + + return this; } public void Process(CommandList context) diff --git a/src/Ryujinx.Audio/Renderer/Dsp/Command/MixCommand.cs b/src/Ryujinx.Audio/Renderer/Dsp/Command/MixCommand.cs index c701f80eb..0dca27bca 100644 --- a/src/Ryujinx.Audio/Renderer/Dsp/Command/MixCommand.cs +++ b/src/Ryujinx.Audio/Renderer/Dsp/Command/MixCommand.cs @@ -11,18 +11,23 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command { public bool Enabled { get; set; } - public int NodeId { get; } + public int NodeId { get; private set; } public CommandType CommandType => CommandType.Mix; public uint EstimatedProcessingTime { get; set; } - public ushort InputBufferIndex { get; } - public ushort OutputBufferIndex { get; } + public ushort InputBufferIndex { get; private set; } + public ushort OutputBufferIndex { get; private set; } - public float Volume { get; } + public float Volume { get; private set; } - public MixCommand(uint inputBufferIndex, uint outputBufferIndex, int nodeId, float volume) + public MixCommand() + { + + } + + public MixCommand Initialize(uint inputBufferIndex, uint outputBufferIndex, int nodeId, float volume) { Enabled = true; NodeId = nodeId; @@ -31,6 +36,8 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command OutputBufferIndex = (ushort)outputBufferIndex; Volume = volume; + + return this; } [MethodImpl(MethodImplOptions.AggressiveInlining)] diff --git a/src/Ryujinx.Audio/Renderer/Dsp/Command/MixRampCommand.cs b/src/Ryujinx.Audio/Renderer/Dsp/Command/MixRampCommand.cs index 6c5f7628c..be6aec5a6 100644 --- a/src/Ryujinx.Audio/Renderer/Dsp/Command/MixRampCommand.cs +++ b/src/Ryujinx.Audio/Renderer/Dsp/Command/MixRampCommand.cs @@ -8,23 +8,28 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command { public bool Enabled { get; set; } - public int NodeId { get; } + public int NodeId { get; private set; } public CommandType CommandType => CommandType.MixRamp; public uint EstimatedProcessingTime { get; set; } - public ushort InputBufferIndex { get; } - public ushort OutputBufferIndex { get; } + public ushort InputBufferIndex { get; private set; } + public ushort OutputBufferIndex { get; private set; } - public float Volume0 { get; } - public float Volume1 { get; } + public float Volume0 { get; private set; } + public float Volume1 { get; private set; } - public Memory State { get; } + public Memory State { get; private set; } - public int LastSampleIndex { get; } + public int LastSampleIndex { get; private set; } - public MixRampCommand(float volume0, float volume1, uint inputBufferIndex, uint outputBufferIndex, int lastSampleIndex, Memory state, int nodeId) + public MixRampCommand() + { + + } + + public MixRampCommand Initialize(float volume0, float volume1, uint inputBufferIndex, uint outputBufferIndex, int lastSampleIndex, Memory state, int nodeId) { Enabled = true; NodeId = nodeId; @@ -37,6 +42,8 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command State = state; LastSampleIndex = lastSampleIndex; + + return this; } [MethodImpl(MethodImplOptions.AggressiveInlining)] diff --git a/src/Ryujinx.Audio/Renderer/Dsp/Command/MixRampGroupedCommand.cs b/src/Ryujinx.Audio/Renderer/Dsp/Command/MixRampGroupedCommand.cs index 0d732c3fa..b08a78ee6 100644 --- a/src/Ryujinx.Audio/Renderer/Dsp/Command/MixRampGroupedCommand.cs +++ b/src/Ryujinx.Audio/Renderer/Dsp/Command/MixRampGroupedCommand.cs @@ -8,23 +8,28 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command { public bool Enabled { get; set; } - public int NodeId { get; } + public int NodeId { get; private set; } public CommandType CommandType => CommandType.MixRampGrouped; public uint EstimatedProcessingTime { get; set; } - public uint MixBufferCount { get; } + public uint MixBufferCount { get; private set; } - public ushort[] InputBufferIndices { get; } - public ushort[] OutputBufferIndices { get; } + public ushort[] InputBufferIndices { get; private set; } + public ushort[] OutputBufferIndices { get; private set; } - public float[] Volume0 { get; } - public float[] Volume1 { get; } + public float[] Volume0 { get; private set; } + public float[] Volume1 { get; private set; } - public Memory State { get; } + public Memory State { get; private set; } - public MixRampGroupedCommand( + public MixRampGroupedCommand() + { + + } + + public MixRampGroupedCommand Initialize( uint mixBufferCount, uint inputBufferIndex, uint outputBufferIndex, @@ -52,6 +57,8 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command } State = state; + + return this; } [MethodImpl(MethodImplOptions.AggressiveInlining)] diff --git a/src/Ryujinx.Audio/Renderer/Dsp/Command/MultiTapBiquadFilterAndMixCommand.cs b/src/Ryujinx.Audio/Renderer/Dsp/Command/MultiTapBiquadFilterAndMixCommand.cs index ee28ce2fb..6cc6b4897 100644 --- a/src/Ryujinx.Audio/Renderer/Dsp/Command/MultiTapBiquadFilterAndMixCommand.cs +++ b/src/Ryujinx.Audio/Renderer/Dsp/Command/MultiTapBiquadFilterAndMixCommand.cs @@ -9,36 +9,41 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command { public bool Enabled { get; set; } - public int NodeId { get; } + public int NodeId { get; private set; } public CommandType CommandType => CommandType.MultiTapBiquadFilterAndMix; public uint EstimatedProcessingTime { get; set; } - public ushort InputBufferIndex { get; } - public ushort OutputBufferIndex { get; } + public ushort InputBufferIndex { get; private set; } + public ushort OutputBufferIndex { get; private set; } private BiquadFilterParameter2 _parameter0; private BiquadFilterParameter2 _parameter1; - public Memory BiquadFilterState0 { get; } - public Memory BiquadFilterState1 { get; } - public Memory PreviousBiquadFilterState0 { get; } - public Memory PreviousBiquadFilterState1 { get; } + public Memory BiquadFilterState0 { get; private set; } + public Memory BiquadFilterState1 { get; private set; } + public Memory PreviousBiquadFilterState0 { get; private set; } + public Memory PreviousBiquadFilterState1 { get; private set; } - public Memory State { get; } + public Memory State { get; private set; } - public int LastSampleIndex { get; } + public int LastSampleIndex { get; private set; } - public float Volume0 { get; } - public float Volume1 { get; } + public float Volume0 { get; private set; } + public float Volume1 { get; private set; } - public bool NeedInitialization0 { get; } - public bool NeedInitialization1 { get; } - public bool HasVolumeRamp { get; } - public bool IsFirstMixBuffer { get; } + public bool NeedInitialization0 { get; private set; } + public bool NeedInitialization1 { get; private set; } + public bool HasVolumeRamp { get; private set; } + public bool IsFirstMixBuffer { get; private set; } - public MultiTapBiquadFilterAndMixCommand( + public MultiTapBiquadFilterAndMixCommand() + { + + } + + public MultiTapBiquadFilterAndMixCommand Initialize( float volume0, float volume1, uint inputBufferIndex, @@ -80,6 +85,8 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command NeedInitialization1 = needInitialization1; HasVolumeRamp = hasVolumeRamp; IsFirstMixBuffer = isFirstMixBuffer; + + return this; } private void UpdateState(Memory state, Memory previousState, bool needInitialization) diff --git a/src/Ryujinx.Audio/Renderer/Dsp/Command/MultiTapBiquadFilterCommand.cs b/src/Ryujinx.Audio/Renderer/Dsp/Command/MultiTapBiquadFilterCommand.cs index 84998056f..fad864982 100644 --- a/src/Ryujinx.Audio/Renderer/Dsp/Command/MultiTapBiquadFilterCommand.cs +++ b/src/Ryujinx.Audio/Renderer/Dsp/Command/MultiTapBiquadFilterCommand.cs @@ -8,40 +8,47 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command { public bool Enabled { get; set; } - public int NodeId { get; } + public int NodeId { get; private set; } public CommandType CommandType => CommandType.MultiTapBiquadFilter; public uint EstimatedProcessingTime { get; set; } - private readonly BiquadFilterParameter2[] _parameters; - private readonly Memory _biquadFilterStates; - private readonly int _inputBufferIndex; - private readonly int _outputBufferIndex; - private readonly bool[] _isInitialized; + public BiquadFilterParameter2[] Parameters { get; private set; } + public Memory BiquadFilterStates { get; private set; } + public int InputBufferIndex { get; private set; } + public int OutputBufferIndex { get; private set; } + public bool[] IsInitialized { get; private set; } - public MultiTapBiquadFilterCommand(int baseIndex, ReadOnlySpan filters, Memory biquadFilterStateMemory, int inputBufferOffset, int outputBufferOffset, ReadOnlySpan isInitialized, int nodeId) + public MultiTapBiquadFilterCommand() { - _parameters = filters.ToArray(); - _biquadFilterStates = biquadFilterStateMemory; - _inputBufferIndex = baseIndex + inputBufferOffset; - _outputBufferIndex = baseIndex + outputBufferOffset; - _isInitialized = isInitialized.ToArray(); + + } + + public MultiTapBiquadFilterCommand Initialize(int baseIndex, ReadOnlySpan filters, Memory biquadFilterStateMemory, int inputBufferOffset, int outputBufferOffset, ReadOnlySpan isInitialized, int nodeId) + { + Parameters = filters.ToArray(); + BiquadFilterStates = biquadFilterStateMemory; + InputBufferIndex = baseIndex + inputBufferOffset; + OutputBufferIndex = baseIndex + outputBufferOffset; + IsInitialized = isInitialized.ToArray(); Enabled = true; NodeId = nodeId; + + return this; } public void Process(CommandList context) { - Span states = _biquadFilterStates.Span; + Span states = BiquadFilterStates.Span; - ReadOnlySpan inputBuffer = context.GetBuffer(_inputBufferIndex); - Span outputBuffer = context.GetBuffer(_outputBufferIndex); + ReadOnlySpan inputBuffer = context.GetBuffer(InputBufferIndex); + Span outputBuffer = context.GetBuffer(OutputBufferIndex); - for (int i = 0; i < _parameters.Length; i++) + for (int i = 0; i < Parameters.Length; i++) { - if (!_isInitialized[i]) + if (!IsInitialized[i]) { states[i] = new BiquadFilterState(); } @@ -49,13 +56,13 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command // NOTE: Nintendo only implement single and double biquad filters but no generic path when the command definition suggests it could be done. // As such we currently only implement a generic path for simplicity for double biquad. - if (_parameters.Length == 1) + if (Parameters.Length == 1) { - BiquadFilterHelper.ProcessBiquadFilter(ref _parameters[0], ref states[0], outputBuffer, inputBuffer, context.SampleCount); + BiquadFilterHelper.ProcessBiquadFilter(ref Parameters[0], ref states[0], outputBuffer, inputBuffer, context.SampleCount); } else { - BiquadFilterHelper.ProcessBiquadFilter(_parameters, states, outputBuffer, inputBuffer, context.SampleCount); + BiquadFilterHelper.ProcessBiquadFilter(Parameters, states, outputBuffer, inputBuffer, context.SampleCount); } } } diff --git a/src/Ryujinx.Audio/Renderer/Dsp/Command/PcmFloatDataSourceCommandVersion1.cs b/src/Ryujinx.Audio/Renderer/Dsp/Command/PcmFloatDataSourceCommandVersion1.cs index d54158541..5bf003dfb 100644 --- a/src/Ryujinx.Audio/Renderer/Dsp/Command/PcmFloatDataSourceCommandVersion1.cs +++ b/src/Ryujinx.Audio/Renderer/Dsp/Command/PcmFloatDataSourceCommandVersion1.cs @@ -11,26 +11,31 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command { public bool Enabled { get; set; } - public int NodeId { get; } + public int NodeId { get; private set; } public CommandType CommandType => CommandType.PcmFloatDataSourceVersion1; public uint EstimatedProcessingTime { get; set; } - public ushort OutputBufferIndex { get; } - public uint SampleRate { get; } - public uint ChannelIndex { get; } + public ushort OutputBufferIndex { get; private set; } + public uint SampleRate { get; private set; } + public uint ChannelIndex { get; private set; } - public uint ChannelCount { get; } + public uint ChannelCount { get; private set; } - public float Pitch { get; } + public float Pitch { get; private set; } public WaveBuffer[] WaveBuffers { get; } - public Memory State { get; } - public DecodingBehaviour DecodingBehaviour { get; } + public Memory State { get; private set; } + public DecodingBehaviour DecodingBehaviour { get; private set; } - public PcmFloatDataSourceCommandVersion1(ref VoiceInfo serverInfo, Memory state, ushort outputBufferIndex, ushort channelIndex, int nodeId) + public PcmFloatDataSourceCommandVersion1() + { + WaveBuffers = new WaveBuffer[Constants.VoiceWaveBufferCount]; + } + + public PcmFloatDataSourceCommandVersion1 Initialize(ref VoiceInfo serverInfo, Memory state, ushort outputBufferIndex, ushort channelIndex, int nodeId) { Enabled = true; NodeId = nodeId; @@ -40,8 +45,6 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command ChannelIndex = channelIndex; ChannelCount = serverInfo.ChannelsCount; Pitch = serverInfo.Pitch; - - WaveBuffers = new WaveBuffer[Constants.VoiceWaveBufferCount]; Span waveBufferSpan = serverInfo.WaveBuffers.AsSpan(); @@ -54,6 +57,8 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command State = state; DecodingBehaviour = serverInfo.DecodingBehaviour; + + return this; } public void Process(CommandList context) diff --git a/src/Ryujinx.Audio/Renderer/Dsp/Command/PcmInt16DataSourceCommandVersion1.cs b/src/Ryujinx.Audio/Renderer/Dsp/Command/PcmInt16DataSourceCommandVersion1.cs index 91619d80f..2bcffa59b 100644 --- a/src/Ryujinx.Audio/Renderer/Dsp/Command/PcmInt16DataSourceCommandVersion1.cs +++ b/src/Ryujinx.Audio/Renderer/Dsp/Command/PcmInt16DataSourceCommandVersion1.cs @@ -11,26 +11,31 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command { public bool Enabled { get; set; } - public int NodeId { get; } + public int NodeId { get; private set; } public CommandType CommandType => CommandType.PcmInt16DataSourceVersion1; public uint EstimatedProcessingTime { get; set; } - public ushort OutputBufferIndex { get; } - public uint SampleRate { get; } - public uint ChannelIndex { get; } + public ushort OutputBufferIndex { get; private set; } + public uint SampleRate { get; private set; } + public uint ChannelIndex { get; private set; } - public uint ChannelCount { get; } + public uint ChannelCount { get; private set; } - public float Pitch { get; } + public float Pitch { get; private set; } public WaveBuffer[] WaveBuffers { get; } - public Memory State { get; } - public DecodingBehaviour DecodingBehaviour { get; } + public Memory State { get; private set; } + public DecodingBehaviour DecodingBehaviour { get; private set; } - public PcmInt16DataSourceCommandVersion1(ref VoiceInfo serverInfo, Memory state, ushort outputBufferIndex, ushort channelIndex, int nodeId) + public PcmInt16DataSourceCommandVersion1() + { + WaveBuffers = new WaveBuffer[Constants.VoiceWaveBufferCount]; + } + + public PcmInt16DataSourceCommandVersion1 Initialize(ref VoiceInfo serverInfo, Memory state, ushort outputBufferIndex, ushort channelIndex, int nodeId) { Enabled = true; NodeId = nodeId; @@ -40,8 +45,6 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command ChannelIndex = channelIndex; ChannelCount = serverInfo.ChannelsCount; Pitch = serverInfo.Pitch; - - WaveBuffers = new WaveBuffer[Constants.VoiceWaveBufferCount]; Span waveBufferSpan = serverInfo.WaveBuffers.AsSpan(); @@ -54,6 +57,8 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command State = state; DecodingBehaviour = serverInfo.DecodingBehaviour; + + return this; } public void Process(CommandList context) diff --git a/src/Ryujinx.Audio/Renderer/Dsp/Command/PerformanceCommand.cs b/src/Ryujinx.Audio/Renderer/Dsp/Command/PerformanceCommand.cs index d3d2ee306..c5d7d8ef1 100644 --- a/src/Ryujinx.Audio/Renderer/Dsp/Command/PerformanceCommand.cs +++ b/src/Ryujinx.Audio/Renderer/Dsp/Command/PerformanceCommand.cs @@ -13,22 +13,34 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command public bool Enabled { get; set; } - public int NodeId { get; } + public int NodeId { get; private set; } public CommandType CommandType => CommandType.Performance; public uint EstimatedProcessingTime { get; set; } - public PerformanceEntryAddresses PerformanceEntryAddresses { get; } + public PerformanceEntryAddresses PerformanceEntryAddresses { get; private set; } public Type PerformanceType { get; set; } - public PerformanceCommand(ref PerformanceEntryAddresses performanceEntryAddresses, Type performanceType, int nodeId) + public PerformanceCommand() { + + } + + public PerformanceCommand Initialize(ref PerformanceEntryAddresses performanceEntryAddresses, Type performanceType, int nodeId) + { + if (PerformanceEntryAddresses is not null) + { + PerformanceEntryAddresses.PerformanceEntryAddressesPool.Release(PerformanceEntryAddresses); + } + Enabled = true; PerformanceEntryAddresses = performanceEntryAddresses; PerformanceType = performanceType; NodeId = nodeId; + + return this; } public void Process(CommandList context) diff --git a/src/Ryujinx.Audio/Renderer/Dsp/Command/Reverb3dCommand.cs b/src/Ryujinx.Audio/Renderer/Dsp/Command/Reverb3dCommand.cs index f183641cd..56b5ef313 100644 --- a/src/Ryujinx.Audio/Renderer/Dsp/Command/Reverb3dCommand.cs +++ b/src/Ryujinx.Audio/Renderer/Dsp/Command/Reverb3dCommand.cs @@ -35,26 +35,32 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command public bool Enabled { get; set; } - public int NodeId { get; } + public int NodeId { get; private set; } public CommandType CommandType => CommandType.Reverb3d; public uint EstimatedProcessingTime { get; set; } - public ushort InputBufferIndex { get; } - public ushort OutputBufferIndex { get; } + public ushort InputBufferIndex { get; private set; } + public ushort OutputBufferIndex { get; private set; } public Reverb3dParameter Parameter => _parameter; - public Memory State { get; } - public ulong WorkBuffer { get; } + public Memory State { get; private set; } + public ulong WorkBuffer { get; private set; } public ushort[] OutputBufferIndices { get; } public ushort[] InputBufferIndices { get; } - public bool IsEffectEnabled { get; } + public bool IsEffectEnabled { get; private set; } private Reverb3dParameter _parameter; - public Reverb3dCommand(uint bufferOffset, Reverb3dParameter parameter, Memory state, bool isEnabled, ulong workBuffer, int nodeId, bool newEffectChannelMappingSupported) + public Reverb3dCommand() + { + InputBufferIndices = new ushort[Constants.VoiceChannelCountMax]; + OutputBufferIndices = new ushort[Constants.VoiceChannelCountMax]; + } + + public Reverb3dCommand Initialize(uint bufferOffset, Reverb3dParameter parameter, Memory state, bool isEnabled, ulong workBuffer, int nodeId, bool newEffectChannelMappingSupported) { Enabled = true; IsEffectEnabled = isEnabled; @@ -62,9 +68,6 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command _parameter = parameter; State = state; WorkBuffer = workBuffer; - - InputBufferIndices = new ushort[Constants.VoiceChannelCountMax]; - OutputBufferIndices = new ushort[Constants.VoiceChannelCountMax]; Span inputSpan = Parameter.Input.AsSpan(); Span outputSpan = Parameter.Output.AsSpan(); @@ -79,6 +82,8 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command // TODO: Update reverb 3d processing and remove this to use RemapLegacyChannelEffectMappingToChannelResourceMapping. DataSourceHelper.RemapChannelResourceMappingToLegacy(newEffectChannelMappingSupported, InputBufferIndices, Parameter.ChannelCount); DataSourceHelper.RemapChannelResourceMappingToLegacy(newEffectChannelMappingSupported, OutputBufferIndices, Parameter.ChannelCount); + + return this; } [MethodImpl(MethodImplOptions.AggressiveInlining)] diff --git a/src/Ryujinx.Audio/Renderer/Dsp/Command/ReverbCommand.cs b/src/Ryujinx.Audio/Renderer/Dsp/Command/ReverbCommand.cs index 20a8422d1..b99cb551b 100644 --- a/src/Ryujinx.Audio/Renderer/Dsp/Command/ReverbCommand.cs +++ b/src/Ryujinx.Audio/Renderer/Dsp/Command/ReverbCommand.cs @@ -33,26 +33,32 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command public bool Enabled { get; set; } - public int NodeId { get; } + public int NodeId { get; private set; } public CommandType CommandType => CommandType.Reverb; public uint EstimatedProcessingTime { get; set; } public ReverbParameter Parameter => _parameter; - public Memory State { get; } - public ulong WorkBuffer { get; } + public Memory State { get; private set; } + public ulong WorkBuffer { get; private set; } public ushort[] OutputBufferIndices { get; } public ushort[] InputBufferIndices { get; } - public bool IsLongSizePreDelaySupported { get; } + public bool IsLongSizePreDelaySupported { get; private set; } - public bool IsEffectEnabled { get; } + public bool IsEffectEnabled { get; private set; } private ReverbParameter _parameter; private const int FixedPointPrecision = 14; - public ReverbCommand(uint bufferOffset, ReverbParameter parameter, Memory state, bool isEnabled, ulong workBuffer, int nodeId, bool isLongSizePreDelaySupported, bool newEffectChannelMappingSupported) + public ReverbCommand() + { + InputBufferIndices = new ushort[Constants.VoiceChannelCountMax]; + OutputBufferIndices = new ushort[Constants.VoiceChannelCountMax]; + } + + public ReverbCommand Initialize(uint bufferOffset, ReverbParameter parameter, Memory state, bool isEnabled, ulong workBuffer, int nodeId, bool isLongSizePreDelaySupported, bool newEffectChannelMappingSupported) { Enabled = true; IsEffectEnabled = isEnabled; @@ -60,9 +66,6 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command _parameter = parameter; State = state; WorkBuffer = workBuffer; - - InputBufferIndices = new ushort[Constants.VoiceChannelCountMax]; - OutputBufferIndices = new ushort[Constants.VoiceChannelCountMax]; Span inputSpan = Parameter.Input.AsSpan(); Span outputSpan = Parameter.Output.AsSpan(); @@ -79,6 +82,8 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command // TODO: Update reverb processing and remove this to use RemapLegacyChannelEffectMappingToChannelResourceMapping. DataSourceHelper.RemapChannelResourceMappingToLegacy(newEffectChannelMappingSupported, InputBufferIndices, Parameter.ChannelCount); DataSourceHelper.RemapChannelResourceMappingToLegacy(newEffectChannelMappingSupported, OutputBufferIndices, Parameter.ChannelCount); + + return this; } [MethodImpl(MethodImplOptions.AggressiveInlining)] diff --git a/src/Ryujinx.Audio/Renderer/Dsp/Command/UpsampleCommand.cs b/src/Ryujinx.Audio/Renderer/Dsp/Command/UpsampleCommand.cs index 5d23addae..f9c17863f 100644 --- a/src/Ryujinx.Audio/Renderer/Dsp/Command/UpsampleCommand.cs +++ b/src/Ryujinx.Audio/Renderer/Dsp/Command/UpsampleCommand.cs @@ -7,22 +7,27 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command { public bool Enabled { get; set; } - public int NodeId { get; } + public int NodeId { get; private set; } public CommandType CommandType => CommandType.Upsample; public uint EstimatedProcessingTime { get; set; } - public uint BufferCount { get; } - public uint InputBufferIndex { get; } - public uint InputSampleCount { get; } - public uint InputSampleRate { get; } + public uint BufferCount { get; private set; } + public uint InputBufferIndex { get; private set; } + public uint InputSampleCount { get; private set; } + public uint InputSampleRate { get; private set; } - public UpsamplerInfo UpsamplerInfo { get; } + public UpsamplerInfo UpsamplerInfo { get; private set; } - public Memory OutBuffer { get; } + public Memory OutBuffer { get; private set; } - public UpsampleCommand(uint bufferOffset, UpsamplerInfo info, uint inputCount, Span inputBufferOffset, uint bufferCount, uint sampleCount, uint sampleRate, int nodeId) + public UpsampleCommand() + { + + } + + public UpsampleCommand Initialize(uint bufferOffset, UpsamplerInfo info, uint inputCount, Span inputBufferOffset, uint bufferCount, uint sampleCount, uint sampleRate, int nodeId) { Enabled = true; NodeId = nodeId; @@ -47,6 +52,8 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command } UpsamplerInfo = info; + + return this; } private Span GetBuffer(int index, int sampleCount) diff --git a/src/Ryujinx.Audio/Renderer/Dsp/Command/VolumeCommand.cs b/src/Ryujinx.Audio/Renderer/Dsp/Command/VolumeCommand.cs index 5deeb07f1..ef5a28bd2 100644 --- a/src/Ryujinx.Audio/Renderer/Dsp/Command/VolumeCommand.cs +++ b/src/Ryujinx.Audio/Renderer/Dsp/Command/VolumeCommand.cs @@ -11,18 +11,23 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command { public bool Enabled { get; set; } - public int NodeId { get; } + public int NodeId { get; private set; } public CommandType CommandType => CommandType.Volume; public uint EstimatedProcessingTime { get; set; } - public ushort InputBufferIndex { get; } - public ushort OutputBufferIndex { get; } + public ushort InputBufferIndex { get; private set; } + public ushort OutputBufferIndex { get; private set; } - public float Volume { get; } + public float Volume { get; private set; } - public VolumeCommand(float volume, uint bufferIndex, int nodeId) + public VolumeCommand() + { + + } + + public VolumeCommand Initialize(float volume, uint bufferIndex, int nodeId) { Enabled = true; NodeId = nodeId; @@ -31,6 +36,8 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command OutputBufferIndex = (ushort)bufferIndex; Volume = volume; + + return this; } [MethodImpl(MethodImplOptions.AggressiveInlining)] diff --git a/src/Ryujinx.Audio/Renderer/Dsp/Command/VolumeRampCommand.cs b/src/Ryujinx.Audio/Renderer/Dsp/Command/VolumeRampCommand.cs index bffbcbc63..47753dc79 100644 --- a/src/Ryujinx.Audio/Renderer/Dsp/Command/VolumeRampCommand.cs +++ b/src/Ryujinx.Audio/Renderer/Dsp/Command/VolumeRampCommand.cs @@ -7,19 +7,24 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command { public bool Enabled { get; set; } - public int NodeId { get; } + public int NodeId { get; private set; } public CommandType CommandType => CommandType.VolumeRamp; public uint EstimatedProcessingTime { get; set; } - public ushort InputBufferIndex { get; } - public ushort OutputBufferIndex { get; } + public ushort InputBufferIndex { get; private set; } + public ushort OutputBufferIndex { get; private set; } - public float Volume0 { get; } - public float Volume1 { get; } + public float Volume0 { get; private set; } + public float Volume1 { get; private set; } - public VolumeRampCommand(float volume0, float volume1, uint bufferIndex, int nodeId) + public VolumeRampCommand() + { + + } + + public VolumeRampCommand Initialize(float volume0, float volume1, uint bufferIndex, int nodeId) { Enabled = true; NodeId = nodeId; @@ -29,6 +34,8 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command Volume0 = volume0; Volume1 = volume1; + + return this; } [MethodImpl(MethodImplOptions.AggressiveInlining)] diff --git a/src/Ryujinx.Audio/Renderer/Parameter/EffectInParameterVersion3.cs b/src/Ryujinx.Audio/Renderer/Parameter/EffectInParameterVersion3.cs deleted file mode 100644 index 2cf4911a6..000000000 --- a/src/Ryujinx.Audio/Renderer/Parameter/EffectInParameterVersion3.cs +++ /dev/null @@ -1,97 +0,0 @@ -using Ryujinx.Audio.Renderer.Common; -using Ryujinx.Common.Utilities; -using System; -using System.Runtime.InteropServices; - -namespace Ryujinx.Audio.Renderer.Parameter -{ - /// - /// Input information for an effect version 2. (added with REV9) - /// - [StructLayout(LayoutKind.Sequential, Pack = 1)] - public struct EffectInParameterVersion3 : IEffectInParameter - { - /// - /// Type of the effect. - /// - public EffectType Type; - - /// - /// Set to true if the effect is new. - /// - [MarshalAs(UnmanagedType.I1)] - public bool IsNew; - - /// - /// Set to true if the effect must be active. - /// - [MarshalAs(UnmanagedType.I1)] - public bool IsEnabled; - - /// - /// Reserved/padding. - /// - private readonly byte _reserved1; - - /// - /// The target mix id of the effect. - /// - public int MixId; - - /// - /// Address of the processing workbuffer. - /// - /// This is additional data that could be required by the effect processing. - public ulong BufferBase; - - /// - /// Size of the processing workbuffer. - /// - /// This is additional data that could be required by the effect processing. - public ulong BufferSize; - - /// - /// Position of the effect while processing effects. - /// - public uint ProcessingOrder; - - /// - /// Reserved/padding. - /// - private readonly uint _reserved2; - - /// - /// Specific data storage. - /// - private SpecificDataStruct _specificDataStart; - - [StructLayout(LayoutKind.Sequential, Size = 0xA0, Pack = 1)] - private struct SpecificDataStruct { } - - public Span SpecificData => SpanHelpers.AsSpan(ref _specificDataStart); - - readonly EffectType IEffectInParameter.Type => Type; - - readonly bool IEffectInParameter.IsNew => IsNew; - - readonly bool IEffectInParameter.IsEnabled => IsEnabled; - - readonly int IEffectInParameter.MixId => MixId; - - readonly ulong IEffectInParameter.BufferBase => BufferBase; - - readonly ulong IEffectInParameter.BufferSize => BufferSize; - - readonly uint IEffectInParameter.ProcessingOrder => ProcessingOrder; - - /// - /// Check if the given channel count is valid. - /// - /// The channel count to check - /// Returns true if the channel count is valid. - public static bool IsChannelCountValid(int channelCount) - { - return channelCount is 1 or 2 or 4 or 6; - } - } -} diff --git a/src/Ryujinx.Audio/Renderer/Server/CommandBuffer.cs b/src/Ryujinx.Audio/Renderer/Server/CommandBuffer.cs index 62380f926..70564ace9 100644 --- a/src/Ryujinx.Audio/Renderer/Server/CommandBuffer.cs +++ b/src/Ryujinx.Audio/Renderer/Server/CommandBuffer.cs @@ -8,6 +8,7 @@ using Ryujinx.Audio.Renderer.Server.Sink; using Ryujinx.Audio.Renderer.Server.Splitter; using Ryujinx.Audio.Renderer.Server.Upsampler; using Ryujinx.Audio.Renderer.Server.Voice; +using Ryujinx.Common; using System; using System.Runtime.CompilerServices; using CpuAddress = System.UInt64; @@ -34,6 +35,170 @@ namespace Ryujinx.Audio.Renderer.Server /// public CommandList CommandList { get; } + private readonly static ObjectPool _pcmInt16DataSourceCommandVersion1Pool = new(() => new PcmInt16DataSourceCommandVersion1()); + private readonly static ObjectPool _pcmFloatDataSourceCommandVersion1Pool = new(() => new PcmFloatDataSourceCommandVersion1()); + private readonly static ObjectPool _adpcmDataSourceCommandVersion1Pool = new(() => new AdpcmDataSourceCommandVersion1()); + private readonly static ObjectPool _dataSourceVersion2CommandPool = new(() => new DataSourceVersion2Command()); + private readonly static ObjectPool _volumeCommandPool = new(() => new VolumeCommand()); + private readonly static ObjectPool _volumeRampCommandPool = new(() => new VolumeRampCommand()); + private readonly static ObjectPool _biquadFilterCommandPool = new(() => new BiquadFilterCommand()); + private readonly static ObjectPool _mixCommandPool = new(() => new MixCommand()); + private readonly static ObjectPool _mixRampCommandPool = new(() => new MixRampCommand()); + private readonly static ObjectPool _mixRampGroupedCommandPool = new(() => new MixRampGroupedCommand()); + private readonly static ObjectPool _depopPrepareCommandPool = new(() => new DepopPrepareCommand()); + private readonly static ObjectPool _depopForMixBuffersCommandPool = new(() => new DepopForMixBuffersCommand()); + private readonly static ObjectPool _delayCommandPool = new(() => new DelayCommand()); + private readonly static ObjectPool _upsampleCommandPool = new(() => new UpsampleCommand()); + private readonly static ObjectPool _downMixSurroundToStereoCommandPool = new(() => new DownMixSurroundToStereoCommand()); + private readonly static ObjectPool _auxiliaryBufferCommandPool = new(() => new AuxiliaryBufferCommand()); + private readonly static ObjectPool _deviceSinkCommandPool = new(() => new DeviceSinkCommand()); + private readonly static ObjectPool _circularBufferSinkCommandPool = new(() => new CircularBufferSinkCommand()); + private readonly static ObjectPool _reverbCommandPool = new(() => new ReverbCommand()); + private readonly static ObjectPool _reverb3dCommandPool = new(() => new Reverb3dCommand()); + private readonly static ObjectPool _performanceCommandPool = new(() => new PerformanceCommand()); + private readonly static ObjectPool _clearMixBufferCommandPool = new(() => new ClearMixBufferCommand()); + private readonly static ObjectPool _copyMixBufferCommandPool = new(() => new CopyMixBufferCommand()); + private readonly static ObjectPool _limiterCommandVersion1Pool = new(() => new LimiterCommandVersion1()); + private readonly static ObjectPool _limiterCommandVersion2Pool = new(() => new LimiterCommandVersion2()); + private readonly static ObjectPool _multiTapBiquadFilterCommandPool = new(() => new MultiTapBiquadFilterCommand()); + private readonly static ObjectPool _captureBufferCommandPool = new(() => new CaptureBufferCommand()); + private readonly static ObjectPool _compressorCommandPool = new(() => new CompressorCommand()); + private readonly static ObjectPool _biquadFilterAndMixCommandPool = new(() => new BiquadFilterAndMixCommand()); + private readonly static ObjectPool _multiTapBiquadFilterAndMixCommandPool = new(() => new MultiTapBiquadFilterAndMixCommand()); + private readonly static ObjectPool _fillBufferCommandPool = new(() => new FillBufferCommand()); + + public static void ReleaseCommand(ICommand command) + { + switch (command.CommandType) + { + case CommandType.PcmInt16DataSourceVersion1: + _pcmInt16DataSourceCommandVersion1Pool.Release((PcmInt16DataSourceCommandVersion1)command); + break; + case CommandType.PcmInt16DataSourceVersion2: + _dataSourceVersion2CommandPool.Release((DataSourceVersion2Command)command); + break; + case CommandType.PcmFloatDataSourceVersion1: + _pcmFloatDataSourceCommandVersion1Pool.Release((PcmFloatDataSourceCommandVersion1)command); + break; + case CommandType.PcmFloatDataSourceVersion2: + _dataSourceVersion2CommandPool.Release((DataSourceVersion2Command)command); + break; + case CommandType.AdpcmDataSourceVersion1: + _adpcmDataSourceCommandVersion1Pool.Release((AdpcmDataSourceCommandVersion1)command); + break; + case CommandType.AdpcmDataSourceVersion2: + _dataSourceVersion2CommandPool.Release((DataSourceVersion2Command)command); + break; + case CommandType.Volume: + _volumeCommandPool.Release((VolumeCommand)command); + break; + case CommandType.VolumeRamp: + _volumeRampCommandPool.Release((VolumeRampCommand)command); + break; + case CommandType.BiquadFilter: + _biquadFilterCommandPool.Release((BiquadFilterCommand)command); + break; + case CommandType.BiquadFilterFloatCoeff: + throw new NotImplementedException(); + break; + case CommandType.Mix: + _mixCommandPool.Release((MixCommand)command); + break; + case CommandType.MixRamp: + _mixRampCommandPool.Release((MixRampCommand)command); + break; + case CommandType.MixRampGrouped: + _mixRampGroupedCommandPool.Release((MixRampGroupedCommand)command); + break; + case CommandType.DepopPrepare: + _depopPrepareCommandPool.Release((DepopPrepareCommand)command); + break; + case CommandType.DepopForMixBuffers: + _depopForMixBuffersCommandPool.Release((DepopForMixBuffersCommand)command); + break; + case CommandType.Delay: + _delayCommandPool.Release((DelayCommand)command); + break; + case CommandType.Upsample: + _upsampleCommandPool.Release((UpsampleCommand)command); + break; + case CommandType.DownMixSurroundToStereo: + _downMixSurroundToStereoCommandPool.Release((DownMixSurroundToStereoCommand)command); + break; + case CommandType.AuxiliaryBuffer: + _auxiliaryBufferCommandPool.Release((AuxiliaryBufferCommand)command); + break; + case CommandType.DeviceSink: + _deviceSinkCommandPool.Release((DeviceSinkCommand)command); + break; + case CommandType.CircularBufferSink: + _circularBufferSinkCommandPool.Release((CircularBufferSinkCommand)command); + break; + case CommandType.Reverb: + _reverbCommandPool.Release((ReverbCommand)command); + break; + case CommandType.Reverb3d: + _reverb3dCommandPool.Release((Reverb3dCommand)command); + break; + case CommandType.Performance: + _performanceCommandPool.Release((PerformanceCommand)command); + break; + case CommandType.ClearMixBuffer: + _clearMixBufferCommandPool.Release((ClearMixBufferCommand)command); + break; + case CommandType.CopyMixBuffer: + _copyMixBufferCommandPool.Release((CopyMixBufferCommand)command); + break; + case CommandType.LimiterVersion1: + _limiterCommandVersion1Pool.Release((LimiterCommandVersion1)command); + break; + case CommandType.LimiterVersion2: + _limiterCommandVersion2Pool.Release((LimiterCommandVersion2)command); + break; + case CommandType.MultiTapBiquadFilter: + _multiTapBiquadFilterCommandPool.Release((MultiTapBiquadFilterCommand)command); + break; + case CommandType.MultiTapBiquadFilterFloatCoeff: + throw new NotImplementedException(); + break; + case CommandType.CaptureBuffer: + _captureBufferCommandPool.Release((CaptureBufferCommand)command); + break; + case CommandType.Compressor: + _compressorCommandPool.Release((CompressorCommand)command); + break; + case CommandType.BiquadFilterAndMix: + _biquadFilterAndMixCommandPool.Release((BiquadFilterAndMixCommand)command); + break; + case CommandType.BiquadFilterAndMixFloatCoeff: + throw new NotImplementedException(); + break; + case CommandType.MultiTapBiquadFilterAndMix: + _multiTapBiquadFilterAndMixCommandPool.Release((MultiTapBiquadFilterAndMixCommand)command); + break; + case CommandType.MultiTapBiquadFilterAndMixFloatCoef: + throw new NotImplementedException(); + break; + case CommandType.AuxiliaryBufferGrouped: + throw new NotImplementedException(); + break; + case CommandType.FillMixBuffer: + throw new NotImplementedException(); + break; + case CommandType.BiquadFilterCrossFade: + throw new NotImplementedException(); + break; + case CommandType.MultiTapBiquadFilterCrossFade: + throw new NotImplementedException(); + break; + case CommandType.FillBuffer: + _fillBufferCommandPool.Release((FillBufferCommand)command); + break; + default: + throw new NotImplementedException(); + } + } + /// /// Create a new . /// @@ -63,7 +228,7 @@ namespace Ryujinx.Audio.Renderer.Server /// The node id associated to this command. public void GenerateClearMixBuffer(int nodeId) { - ClearMixBufferCommand command = new(nodeId); + ClearMixBufferCommand command = _clearMixBufferCommandPool.Allocate().Initialize(nodeId); command.EstimatedProcessingTime = _commandProcessingTimeEstimator.Estimate(command); @@ -81,7 +246,7 @@ namespace Ryujinx.Audio.Renderer.Server /// Set to true if the voice was playing previously. public void GenerateDepopPrepare(Memory state, Memory depopBuffer, uint bufferCount, uint bufferOffset, int nodeId, bool wasPlaying) { - DepopPrepareCommand command = new(state, depopBuffer, bufferCount, bufferOffset, nodeId, wasPlaying); + DepopPrepareCommand command = _depopPrepareCommandPool.Allocate().Initialize(state, depopBuffer, bufferCount, bufferOffset, nodeId, wasPlaying); command.EstimatedProcessingTime = _commandProcessingTimeEstimator.Estimate(command); @@ -96,7 +261,7 @@ namespace Ryujinx.Audio.Renderer.Server /// The node id associated to this command. public void GeneratePerformance(ref PerformanceEntryAddresses performanceEntryAddresses, PerformanceCommand.Type type, int nodeId) { - PerformanceCommand command = new(ref performanceEntryAddresses, type, nodeId); + PerformanceCommand command = _performanceCommandPool.Allocate().Initialize(ref performanceEntryAddresses, type, nodeId); command.EstimatedProcessingTime = _commandProcessingTimeEstimator.Estimate(command); @@ -112,7 +277,7 @@ namespace Ryujinx.Audio.Renderer.Server /// The node id associated to this command. public void GenerateVolumeRamp(float previousVolume, float volume, uint bufferIndex, int nodeId) { - VolumeRampCommand command = new(previousVolume, volume, bufferIndex, nodeId); + VolumeRampCommand command = _volumeRampCommandPool.Allocate().Initialize(previousVolume, volume, bufferIndex, nodeId); command.EstimatedProcessingTime = _commandProcessingTimeEstimator.Estimate(command); @@ -129,7 +294,7 @@ namespace Ryujinx.Audio.Renderer.Server /// The node id associated to this command. public void GenerateDataSourceVersion2(ref VoiceInfo voiceInfo, Memory state, ushort outputBufferIndex, ushort channelIndex, int nodeId) { - DataSourceVersion2Command command = new(ref voiceInfo, state, outputBufferIndex, channelIndex, nodeId); + DataSourceVersion2Command command = _dataSourceVersion2CommandPool.Allocate().Initialize(ref voiceInfo, state, outputBufferIndex, channelIndex, nodeId); command.EstimatedProcessingTime = _commandProcessingTimeEstimator.Estimate(command); @@ -146,7 +311,7 @@ namespace Ryujinx.Audio.Renderer.Server /// The node id associated to this command. public void GeneratePcmInt16DataSourceVersion1(ref VoiceInfo voiceInfo, Memory state, ushort outputBufferIndex, ushort channelIndex, int nodeId) { - PcmInt16DataSourceCommandVersion1 command = new(ref voiceInfo, state, outputBufferIndex, channelIndex, nodeId); + PcmInt16DataSourceCommandVersion1 command = _pcmInt16DataSourceCommandVersion1Pool.Allocate().Initialize(ref voiceInfo, state, outputBufferIndex, channelIndex, nodeId); command.EstimatedProcessingTime = _commandProcessingTimeEstimator.Estimate(command); @@ -163,7 +328,7 @@ namespace Ryujinx.Audio.Renderer.Server /// The node id associated to this command. public void GeneratePcmFloatDataSourceVersion1(ref VoiceInfo voiceInfo, Memory state, ushort outputBufferIndex, ushort channelIndex, int nodeId) { - PcmFloatDataSourceCommandVersion1 command = new(ref voiceInfo, state, outputBufferIndex, channelIndex, nodeId); + PcmFloatDataSourceCommandVersion1 command = _pcmFloatDataSourceCommandVersion1Pool.Allocate().Initialize(ref voiceInfo, state, outputBufferIndex, channelIndex, nodeId); command.EstimatedProcessingTime = _commandProcessingTimeEstimator.Estimate(command); @@ -179,7 +344,7 @@ namespace Ryujinx.Audio.Renderer.Server /// The node id associated to this command. public void GenerateAdpcmDataSourceVersion1(ref VoiceInfo voiceInfo, Memory state, ushort outputBufferIndex, int nodeId) { - AdpcmDataSourceCommandVersion1 command = new(ref voiceInfo, state, outputBufferIndex, nodeId); + AdpcmDataSourceCommandVersion1 command = _adpcmDataSourceCommandVersion1Pool.Allocate().Initialize(ref voiceInfo, state, outputBufferIndex, nodeId); command.EstimatedProcessingTime = _commandProcessingTimeEstimator.Estimate(command); @@ -198,7 +363,7 @@ namespace Ryujinx.Audio.Renderer.Server /// The node id associated to this command. public void GenerateBiquadFilter(int baseIndex, ref BiquadFilterParameter2 filter, Memory biquadFilterStateMemory, int inputBufferOffset, int outputBufferOffset, bool needInitialization, int nodeId) { - BiquadFilterCommand command = new(baseIndex, ref filter, biquadFilterStateMemory, inputBufferOffset, outputBufferOffset, needInitialization, nodeId); + BiquadFilterCommand command = _biquadFilterCommandPool.Allocate().Initialize(baseIndex, ref filter, biquadFilterStateMemory, inputBufferOffset, outputBufferOffset, needInitialization, nodeId); command.EstimatedProcessingTime = _commandProcessingTimeEstimator.Estimate(command); @@ -217,7 +382,7 @@ namespace Ryujinx.Audio.Renderer.Server /// The node id associated to this command. public void GenerateMultiTapBiquadFilter(int baseIndex, ReadOnlySpan filters, Memory biquadFilterStatesMemory, int inputBufferOffset, int outputBufferOffset, ReadOnlySpan isInitialized, int nodeId) { - MultiTapBiquadFilterCommand command = new(baseIndex, filters, biquadFilterStatesMemory, inputBufferOffset, outputBufferOffset, isInitialized, nodeId); + MultiTapBiquadFilterCommand command = _multiTapBiquadFilterCommandPool.Allocate().Initialize(baseIndex, filters, biquadFilterStatesMemory, inputBufferOffset, outputBufferOffset, isInitialized, nodeId); command.EstimatedProcessingTime = _commandProcessingTimeEstimator.Estimate(command); @@ -236,7 +401,7 @@ namespace Ryujinx.Audio.Renderer.Server /// The node id associated to this command. public void GenerateMixRampGrouped(uint mixBufferCount, uint inputBufferIndex, uint outputBufferIndex, ReadOnlySpan previousVolume, ReadOnlySpan volume, Memory state, int nodeId) { - MixRampGroupedCommand command = new(mixBufferCount, inputBufferIndex, outputBufferIndex, previousVolume, volume, state, nodeId); + MixRampGroupedCommand command = _mixRampGroupedCommandPool.Allocate().Initialize(mixBufferCount, inputBufferIndex, outputBufferIndex, previousVolume, volume, state, nodeId); command.EstimatedProcessingTime = _commandProcessingTimeEstimator.Estimate(command); @@ -255,7 +420,7 @@ namespace Ryujinx.Audio.Renderer.Server /// The node id associated to this command. public void GenerateMixRamp(float previousVolume, float volume, uint inputBufferIndex, uint outputBufferIndex, int lastSampleIndex, Memory state, int nodeId) { - MixRampCommand command = new(previousVolume, volume, inputBufferIndex, outputBufferIndex, lastSampleIndex, state, nodeId); + MixRampCommand command = _mixRampCommandPool.Allocate().Initialize(previousVolume, volume, inputBufferIndex, outputBufferIndex, lastSampleIndex, state, nodeId); command.EstimatedProcessingTime = _commandProcessingTimeEstimator.Estimate(command); @@ -293,7 +458,7 @@ namespace Ryujinx.Audio.Renderer.Server bool isFirstMixBuffer, int nodeId) { - BiquadFilterAndMixCommand command = new( + BiquadFilterAndMixCommand command = _biquadFilterAndMixCommandPool.Allocate().Initialize( previousVolume, volume, inputBufferIndex, @@ -352,7 +517,7 @@ namespace Ryujinx.Audio.Renderer.Server bool isFirstMixBuffer, int nodeId) { - MultiTapBiquadFilterAndMixCommand command = new( + MultiTapBiquadFilterAndMixCommand command = _multiTapBiquadFilterAndMixCommandPool.Allocate().Initialize( previousVolume, volume, inputBufferIndex, @@ -386,7 +551,7 @@ namespace Ryujinx.Audio.Renderer.Server /// The target sample rate in use. public void GenerateDepopForMixBuffers(Memory depopBuffer, uint bufferOffset, uint bufferCount, int nodeId, uint sampleRate) { - DepopForMixBuffersCommand command = new(depopBuffer, bufferOffset, bufferCount, nodeId, sampleRate); + DepopForMixBuffersCommand command = _depopForMixBuffersCommandPool.Allocate().Initialize(depopBuffer, bufferOffset, bufferCount, nodeId, sampleRate); command.EstimatedProcessingTime = _commandProcessingTimeEstimator.Estimate(command); @@ -401,7 +566,7 @@ namespace Ryujinx.Audio.Renderer.Server /// The node id associated to this command. public void GenerateCopyMixBuffer(uint inputBufferIndex, uint outputBufferIndex, int nodeId) { - CopyMixBufferCommand command = new(inputBufferIndex, outputBufferIndex, nodeId); + CopyMixBufferCommand command = _copyMixBufferCommandPool.Allocate().Initialize(inputBufferIndex, outputBufferIndex, nodeId); command.EstimatedProcessingTime = _commandProcessingTimeEstimator.Estimate(command); @@ -417,7 +582,7 @@ namespace Ryujinx.Audio.Renderer.Server /// The mix volume. public void GenerateMix(uint inputBufferIndex, uint outputBufferIndex, int nodeId, float volume) { - MixCommand command = new(inputBufferIndex, outputBufferIndex, nodeId, volume); + MixCommand command = _mixCommandPool.Allocate().Initialize(inputBufferIndex, outputBufferIndex, nodeId, volume); command.EstimatedProcessingTime = _commandProcessingTimeEstimator.Estimate(command); @@ -439,7 +604,7 @@ namespace Ryujinx.Audio.Renderer.Server { if (parameter.IsChannelCountValid()) { - ReverbCommand command = new(bufferOffset, parameter, state, isEnabled, workBuffer, nodeId, isLongSizePreDelaySupported, newEffectChannelMappingSupported); + ReverbCommand command = _reverbCommandPool.Allocate().Initialize(bufferOffset, parameter, state, isEnabled, workBuffer, nodeId, isLongSizePreDelaySupported, newEffectChannelMappingSupported); command.EstimatedProcessingTime = _commandProcessingTimeEstimator.Estimate(command); @@ -461,7 +626,7 @@ namespace Ryujinx.Audio.Renderer.Server { if (parameter.IsChannelCountValid()) { - Reverb3dCommand command = new(bufferOffset, parameter, state, isEnabled, workBuffer, nodeId, newEffectChannelMappingSupported); + Reverb3dCommand command = _reverb3dCommandPool.Allocate().Initialize(bufferOffset, parameter, state, isEnabled, workBuffer, nodeId, newEffectChannelMappingSupported); command.EstimatedProcessingTime = _commandProcessingTimeEstimator.Estimate(command); @@ -483,7 +648,7 @@ namespace Ryujinx.Audio.Renderer.Server { if (parameter.IsChannelCountValid()) { - DelayCommand command = new(bufferOffset, parameter, state, isEnabled, workBuffer, nodeId, newEffectChannelMappingSupported); + DelayCommand command = _delayCommandPool.Allocate().Initialize(bufferOffset, parameter, state, isEnabled, workBuffer, nodeId, newEffectChannelMappingSupported); command.EstimatedProcessingTime = _commandProcessingTimeEstimator.Estimate(command); @@ -504,7 +669,7 @@ namespace Ryujinx.Audio.Renderer.Server { if (parameter.IsChannelCountValid()) { - LimiterCommandVersion1 command = new(bufferOffset, parameter, state, isEnabled, workBuffer, nodeId); + LimiterCommandVersion1 command = _limiterCommandVersion1Pool.Allocate().Initialize(bufferOffset, parameter, state, isEnabled, workBuffer, nodeId); command.EstimatedProcessingTime = _commandProcessingTimeEstimator.Estimate(command); @@ -526,7 +691,7 @@ namespace Ryujinx.Audio.Renderer.Server { if (parameter.IsChannelCountValid()) { - LimiterCommandVersion2 command = new(bufferOffset, parameter, state, effectResultState, isEnabled, workBuffer, nodeId); + LimiterCommandVersion2 command = _limiterCommandVersion2Pool.Allocate().Initialize(bufferOffset, parameter, state, effectResultState, isEnabled, workBuffer, nodeId); command.EstimatedProcessingTime = _commandProcessingTimeEstimator.Estimate(command); @@ -552,7 +717,7 @@ namespace Ryujinx.Audio.Renderer.Server { if (state.SendBufferInfoBase != 0 && state.ReturnBufferInfoBase != 0) { - AuxiliaryBufferCommand command = new(bufferOffset, inputBufferOffset, outputBufferOffset, ref state, isEnabled, countMax, outputBuffer, inputBuffer, updateCount, writeOffset, nodeId); + AuxiliaryBufferCommand command = _auxiliaryBufferCommandPool.Allocate().Initialize(bufferOffset, inputBufferOffset, outputBufferOffset, ref state, isEnabled, countMax, outputBuffer, inputBuffer, updateCount, writeOffset, nodeId); command.EstimatedProcessingTime = _commandProcessingTimeEstimator.Estimate(command); @@ -576,7 +741,7 @@ namespace Ryujinx.Audio.Renderer.Server { if (sendBufferInfo != 0) { - CaptureBufferCommand command = new(bufferOffset, inputBufferOffset, sendBufferInfo, isEnabled, countMax, outputBuffer, updateCount, writeOffset, nodeId); + CaptureBufferCommand command = _captureBufferCommandPool.Allocate().Initialize(bufferOffset, inputBufferOffset, sendBufferInfo, isEnabled, countMax, outputBuffer, updateCount, writeOffset, nodeId); command.EstimatedProcessingTime = _commandProcessingTimeEstimator.Estimate(command); @@ -597,7 +762,7 @@ namespace Ryujinx.Audio.Renderer.Server { if (parameter.IsChannelCountValid()) { - CompressorCommand command = new(bufferOffset, parameter, state, effectResultState, isEnabled, nodeId); + CompressorCommand command = _compressorCommandPool.Allocate().Initialize(bufferOffset, parameter, state, effectResultState, isEnabled, nodeId); command.EstimatedProcessingTime = _commandProcessingTimeEstimator.Estimate(command); @@ -613,7 +778,7 @@ namespace Ryujinx.Audio.Renderer.Server /// The node id associated to this command. public void GenerateVolume(float volume, uint bufferOffset, int nodeId) { - VolumeCommand command = new(volume, bufferOffset, nodeId); + VolumeCommand command = _volumeCommandPool.Allocate().Initialize(volume, bufferOffset, nodeId); command.EstimatedProcessingTime = _commandProcessingTimeEstimator.Estimate(command); @@ -628,7 +793,7 @@ namespace Ryujinx.Audio.Renderer.Server /// The node id associated to this command. public void GenerateCircularBuffer(uint bufferOffset, CircularBufferSink sink, int nodeId) { - CircularBufferSinkCommand command = new(bufferOffset, ref sink.Parameter, ref sink.CircularBufferAddressInfo, sink.CurrentWriteOffset, nodeId); + CircularBufferSinkCommand command = _circularBufferSinkCommandPool.Allocate().Initialize(bufferOffset, ref sink.Parameter, ref sink.CircularBufferAddressInfo, sink.CurrentWriteOffset, nodeId); command.EstimatedProcessingTime = _commandProcessingTimeEstimator.Estimate(command); @@ -645,7 +810,7 @@ namespace Ryujinx.Audio.Renderer.Server /// The node id associated to this command. public void GenerateDownMixSurroundToStereo(uint bufferOffset, Span inputBufferOffset, Span outputBufferOffset, float[] downMixParameter, int nodeId) { - DownMixSurroundToStereoCommand command = new(bufferOffset, inputBufferOffset, outputBufferOffset, downMixParameter, nodeId); + DownMixSurroundToStereoCommand command = _downMixSurroundToStereoCommandPool.Allocate().Initialize(bufferOffset, inputBufferOffset, outputBufferOffset, downMixParameter, nodeId); command.EstimatedProcessingTime = _commandProcessingTimeEstimator.Estimate(command); @@ -665,7 +830,7 @@ namespace Ryujinx.Audio.Renderer.Server /// The node id associated to this command. public void GenerateUpsample(uint bufferOffset, UpsamplerInfo upsampler, uint inputCount, Span inputBufferOffset, uint bufferCountPerSample, uint sampleCount, uint sampleRate, int nodeId) { - UpsampleCommand command = new(bufferOffset, upsampler, inputCount, inputBufferOffset, bufferCountPerSample, sampleCount, sampleRate, nodeId); + UpsampleCommand command = _upsampleCommandPool.Allocate().Initialize(bufferOffset, upsampler, inputCount, inputBufferOffset, bufferCountPerSample, sampleCount, sampleRate, nodeId); command.EstimatedProcessingTime = _commandProcessingTimeEstimator.Estimate(command); @@ -682,7 +847,7 @@ namespace Ryujinx.Audio.Renderer.Server /// The node id associated to this command. public void GenerateDeviceSink(uint bufferOffset, DeviceSink sink, int sessionId, Memory buffer, int nodeId) { - DeviceSinkCommand command = new(bufferOffset, sink, sessionId, buffer, nodeId); + DeviceSinkCommand command = _deviceSinkCommandPool.Allocate().Initialize(bufferOffset, sink, sessionId, buffer, nodeId); command.EstimatedProcessingTime = _commandProcessingTimeEstimator.Estimate(command); @@ -691,16 +856,7 @@ namespace Ryujinx.Audio.Renderer.Server public void GenerateFillBuffer(SplitterDestination destination, float value, int length, int nodeId) { - FillBufferCommand command; - - if (Unsafe.IsNullRef(ref destination.GetV2RefOrNull())) - { - command = new(destination.GetV1RefOrNull(), length, value, nodeId); - } - else - { - command = new(destination.GetV2RefOrNull(), length, value, nodeId); - } + FillBufferCommand command = _fillBufferCommandPool.Allocate().Initialize(destination, length, value, nodeId); command.EstimatedProcessingTime = _commandProcessingTimeEstimator.Estimate(command); diff --git a/src/Ryujinx.Audio/Renderer/Server/CommandGenerator.cs b/src/Ryujinx.Audio/Renderer/Server/CommandGenerator.cs index c88aa51f2..600f51576 100644 --- a/src/Ryujinx.Audio/Renderer/Server/CommandGenerator.cs +++ b/src/Ryujinx.Audio/Renderer/Server/CommandGenerator.cs @@ -339,7 +339,7 @@ namespace Ryujinx.Audio.Renderer.Server bool performanceInitialized = false; - PerformanceEntryAddresses performanceEntry = new(); + PerformanceEntryAddresses performanceEntry = null; if (_performanceManager != null && _performanceManager.IsTargetNodeId(nodeId) && _performanceManager.GetNextEntry(out performanceEntry, dataSourceDetailType, PerformanceEntryType.Voice, nodeId)) { @@ -500,7 +500,7 @@ namespace Ryujinx.Audio.Renderer.Server { int nodeId = sortedInfo.NodeId; - PerformanceEntryAddresses performanceEntry = new(); + PerformanceEntryAddresses performanceEntry = null; bool performanceInitialized = false; @@ -786,7 +786,7 @@ namespace Ryujinx.Audio.Renderer.Server bool isFinalMix = mix.MixId == Constants.FinalMixId; - PerformanceEntryAddresses performanceEntry = new(); + PerformanceEntryAddresses performanceEntry = null; bool performanceInitialized = false; @@ -1050,7 +1050,7 @@ namespace Ryujinx.Audio.Renderer.Server GenerateEffects(ref subMix); - PerformanceEntryAddresses performanceEntry = new(); + PerformanceEntryAddresses performanceEntry = null; int nodeId = subMix.NodeId; @@ -1081,7 +1081,7 @@ namespace Ryujinx.Audio.Renderer.Server { int nodeId = sortedInfo.NodeId; - PerformanceEntryAddresses performanceEntry = new(); + PerformanceEntryAddresses performanceEntry = null; bool performanceInitialized = false; @@ -1115,7 +1115,7 @@ namespace Ryujinx.Audio.Renderer.Server GenerateEffects(ref finalMix); - PerformanceEntryAddresses performanceEntry = new(); + PerformanceEntryAddresses performanceEntry = null; int nodeId = finalMix.NodeId; @@ -1164,7 +1164,7 @@ namespace Ryujinx.Audio.Renderer.Server { int nodeId = _mixContext.GetFinalState().NodeId; - PerformanceEntryAddresses performanceEntry = new(); + PerformanceEntryAddresses performanceEntry = null; bool performanceInitialized = false; @@ -1244,7 +1244,7 @@ namespace Ryujinx.Audio.Renderer.Server { bool performanceInitialized = false; - PerformanceEntryAddresses performanceEntry = new(); + PerformanceEntryAddresses performanceEntry = null; if (_performanceManager != null && _performanceManager.GetNextEntry(out performanceEntry, PerformanceEntryType.Sink, sink.NodeId)) { diff --git a/src/Ryujinx.Audio/Renderer/Server/Effect/BaseEffect.cs b/src/Ryujinx.Audio/Renderer/Server/Effect/BaseEffect.cs index 6324689e4..77d9b5c29 100644 --- a/src/Ryujinx.Audio/Renderer/Server/Effect/BaseEffect.cs +++ b/src/Ryujinx.Audio/Renderer/Server/Effect/BaseEffect.cs @@ -174,19 +174,6 @@ namespace Ryujinx.Audio.Renderer.Server.Effect updateErrorInfo = new ErrorInfo(); } - - /// - /// Update the internal state from a user version 3 parameter. - /// - /// The possible that was generated. - /// The user parameter. - /// The mapper to use. - public virtual void Update(out ErrorInfo updateErrorInfo, in EffectInParameterVersion3 parameter, PoolMapper mapper) - { - Debug.Assert(IsTypeValid(in parameter)); - - updateErrorInfo = new ErrorInfo(); - } /// /// Get the work buffer DSP address at the given index. diff --git a/src/Ryujinx.Audio/Renderer/Server/Effect/BiquadFilterEffect.cs b/src/Ryujinx.Audio/Renderer/Server/Effect/BiquadFilterEffect.cs index f920c6873..55a898529 100644 --- a/src/Ryujinx.Audio/Renderer/Server/Effect/BiquadFilterEffect.cs +++ b/src/Ryujinx.Audio/Renderer/Server/Effect/BiquadFilterEffect.cs @@ -25,13 +25,19 @@ namespace Ryujinx.Audio.Renderer.Server.Effect /// public Memory State { get; } + /// + /// The biquad filter effect version. + /// + public int BiquadFilterEffectVersion; + /// /// Create a new . /// - public BiquadFilterEffect() + public BiquadFilterEffect(int version) { Parameter = new BiquadFilterEffectParameter2(); State = new BiquadFilterState[Constants.ChannelCountMax]; + BiquadFilterEffectVersion = version; } public override EffectType TargetEffectType => EffectType.BiquadFilter; @@ -45,11 +51,6 @@ namespace Ryujinx.Audio.Renderer.Server.Effect { Update(out updateErrorInfo, in parameter, mapper); } - - public override void Update(out BehaviourParameter.ErrorInfo updateErrorInfo, in EffectInParameterVersion3 parameter, PoolMapper mapper) - { - Update(out updateErrorInfo, in parameter, mapper); - } public void Update(out BehaviourParameter.ErrorInfo updateErrorInfo, in T parameter, PoolMapper mapper) where T : unmanaged, IEffectInParameter { @@ -57,7 +58,7 @@ namespace Ryujinx.Audio.Renderer.Server.Effect UpdateParameterBase(in parameter); - if (typeof(T) == typeof(EffectInParameterVersion3)) + if (BiquadFilterEffectVersion == 2) { Parameter = MemoryMarshal.Cast(parameter.SpecificData)[0]; } diff --git a/src/Ryujinx.Audio/Renderer/Server/Performance/PerformanceEntryAddresses.cs b/src/Ryujinx.Audio/Renderer/Server/Performance/PerformanceEntryAddresses.cs index d24b96a27..d59cc01a1 100644 --- a/src/Ryujinx.Audio/Renderer/Server/Performance/PerformanceEntryAddresses.cs +++ b/src/Ryujinx.Audio/Renderer/Server/Performance/PerformanceEntryAddresses.cs @@ -1,3 +1,4 @@ +using Ryujinx.Common; using System; namespace Ryujinx.Audio.Renderer.Server.Performance @@ -7,6 +8,8 @@ namespace Ryujinx.Audio.Renderer.Server.Performance /// public class PerformanceEntryAddresses { + public static readonly ObjectPool PerformanceEntryAddressesPool = new(() => new PerformanceEntryAddresses()); + /// /// The memory storing the performance entry. /// @@ -52,5 +55,10 @@ namespace Ryujinx.Audio.Renderer.Server.Performance { BaseMemory.Span[(int)ProcessingTimeOffset / 4] = (int)(endTimeNano / 1000) - BaseMemory.Span[(int)StartTimeOffset / 4]; } + + public void Clear() + { + + } } } diff --git a/src/Ryujinx.Audio/Renderer/Server/Performance/PerformanceManagerGeneric.cs b/src/Ryujinx.Audio/Renderer/Server/Performance/PerformanceManagerGeneric.cs index 2e5d25b9c..8881c7243 100644 --- a/src/Ryujinx.Audio/Renderer/Server/Performance/PerformanceManagerGeneric.cs +++ b/src/Ryujinx.Audio/Renderer/Server/Performance/PerformanceManagerGeneric.cs @@ -208,11 +208,9 @@ namespace Ryujinx.Audio.Renderer.Server.Performance public override bool GetNextEntry(out PerformanceEntryAddresses performanceEntry, PerformanceEntryType entryType, int nodeId) { - performanceEntry = new PerformanceEntryAddresses - { - BaseMemory = SpanMemoryManager.Cast(CurrentBuffer), - EntryCountOffset = (uint)CurrentHeader.GetEntryCountOffset(), - }; + performanceEntry = PerformanceEntryAddresses.PerformanceEntryAddressesPool.Allocate(); + performanceEntry.BaseMemory = SpanMemoryManager.Cast(CurrentBuffer); + performanceEntry.EntryCountOffset = (uint)CurrentHeader.GetEntryCountOffset(); uint baseEntryOffset = (uint)(Unsafe.SizeOf() + Unsafe.SizeOf() * _entryIndex); @@ -238,12 +236,10 @@ namespace Ryujinx.Audio.Renderer.Server.Performance { return false; } - - performanceEntry = new PerformanceEntryAddresses - { - BaseMemory = SpanMemoryManager.Cast(CurrentBuffer), - EntryCountOffset = (uint)CurrentHeader.GetEntryCountOffset(), - }; + + performanceEntry = PerformanceEntryAddresses.PerformanceEntryAddressesPool.Allocate(); + performanceEntry.BaseMemory = SpanMemoryManager.Cast(CurrentBuffer); + performanceEntry.EntryCountOffset = (uint)CurrentHeader.GetEntryCountOffset(); uint baseEntryOffset = (uint)(Unsafe.SizeOf() + GetEntriesSize() + Unsafe.SizeOf() * _entryDetailIndex); diff --git a/src/Ryujinx.Audio/Renderer/Server/StateUpdater.cs b/src/Ryujinx.Audio/Renderer/Server/StateUpdater.cs index a02d70240..917d63716 100644 --- a/src/Ryujinx.Audio/Renderer/Server/StateUpdater.cs +++ b/src/Ryujinx.Audio/Renderer/Server/StateUpdater.cs @@ -300,7 +300,7 @@ namespace Ryujinx.Audio.Renderer.Server return ResultCode.Success; } - private static void ResetEffect(ref BaseEffect effect, in T parameter, PoolMapper mapper) where T : unmanaged, IEffectInParameter + private void ResetEffect(ref BaseEffect effect, in T parameter, PoolMapper mapper) where T : unmanaged, IEffectInParameter { effect.ForceUnmapBuffers(mapper); @@ -312,7 +312,8 @@ namespace Ryujinx.Audio.Renderer.Server EffectType.Delay => new DelayEffect(), EffectType.Reverb => new ReverbEffect(), EffectType.Reverb3d => new Reverb3dEffect(), - EffectType.BiquadFilter => new BiquadFilterEffect(), + EffectType.BiquadFilter when _behaviourInfo.IsBiquadFilterParameterFloatSupported() => new BiquadFilterEffect(2), + EffectType.BiquadFilter => new BiquadFilterEffect(1), EffectType.Limiter => new LimiterEffect(), EffectType.CaptureBuffer => new CaptureBufferEffect(), EffectType.Compressor => new CompressorEffect(), @@ -322,11 +323,6 @@ namespace Ryujinx.Audio.Renderer.Server public ResultCode UpdateEffects(EffectContext context, bool isAudioRendererActive, PoolMapper mapper) { - if (_behaviourInfo.IsBiquadFilterParameterFloatSupported()) - { - return UpdateEffectsVersion3(context, isAudioRendererActive, mapper); - } - if (_behaviourInfo.IsEffectInfoVersion2Supported()) { return UpdateEffectsVersion2(context, isAudioRendererActive, mapper); @@ -334,60 +330,6 @@ namespace Ryujinx.Audio.Renderer.Server return UpdateEffectsVersion1(context, isAudioRendererActive, mapper); } - - public ResultCode UpdateEffectsVersion3(EffectContext context, bool isAudioRendererActive, PoolMapper mapper) - { - if (context.GetCount() * Unsafe.SizeOf() != _inputHeader.EffectsSize) - { - return ResultCode.InvalidUpdateInfo; - } - - int initialOutputSize = _output.Length; - - long initialInputConsumed = _inputReader.Consumed; - - for (int i = 0; i < context.GetCount(); i++) - { - ref readonly EffectInParameterVersion3 parameter = ref _inputReader.GetRefOrRefToCopy(out _); - - ref EffectOutStatusVersion2 outStatus = ref SpanIOHelper.GetWriteRef(ref _output)[0]; - - ref BaseEffect effect = ref context.GetEffect(i); - - if (!effect.IsTypeValid(in parameter)) - { - ResetEffect(ref effect, in parameter, mapper); - } - - effect.Update(out ErrorInfo updateErrorInfo, in parameter, mapper); - - if (updateErrorInfo.ErrorCode != ResultCode.Success) - { - _behaviourInfo.AppendError(ref updateErrorInfo); - } - - effect.StoreStatus(ref outStatus, isAudioRendererActive); - - if (parameter.IsNew) - { - effect.InitializeResultState(ref context.GetDspState(i)); - effect.InitializeResultState(ref context.GetState(i)); - } - - effect.UpdateResultState(ref outStatus.ResultState, ref context.GetState(i)); - } - - int currentOutputSize = _output.Length; - - OutputHeader.EffectsSize = (uint)(Unsafe.SizeOf() * context.GetCount()); - OutputHeader.TotalSize += OutputHeader.EffectsSize; - - Debug.Assert((initialOutputSize - currentOutputSize) == OutputHeader.EffectsSize); - - _inputReader.SetConsumed(initialInputConsumed + _inputHeader.EffectsSize); - - return ResultCode.Success; - } public ResultCode UpdateEffectsVersion2(EffectContext context, bool isAudioRendererActive, PoolMapper mapper) { diff --git a/src/Ryujinx.Audio/Renderer/Server/Voice/VoiceInfo.cs b/src/Ryujinx.Audio/Renderer/Server/Voice/VoiceInfo.cs index ba6158b71..c6a4149f8 100644 --- a/src/Ryujinx.Audio/Renderer/Server/Voice/VoiceInfo.cs +++ b/src/Ryujinx.Audio/Renderer/Server/Voice/VoiceInfo.cs @@ -4,9 +4,11 @@ using Ryujinx.Audio.Renderer.Dsp; using Ryujinx.Audio.Renderer.Dsp.State; using Ryujinx.Audio.Renderer.Parameter; using Ryujinx.Audio.Renderer.Server.MemoryPool; +using Ryujinx.Common; using Ryujinx.Common.Memory; using Ryujinx.Common.Utilities; using System; +using System.Collections.Generic; using System.Diagnostics; using System.Runtime.InteropServices; using static Ryujinx.Audio.Renderer.Common.BehaviourParameter; @@ -20,6 +22,8 @@ namespace Ryujinx.Audio.Renderer.Server.Voice { public const int Alignment = 0x10; + private static readonly ObjectPool[]> voiceStatesPool = new(() => new Memory[Constants.VoiceChannelCountMax]); + /// /// Set to true if the voice is used. /// @@ -568,7 +572,7 @@ namespace Ryujinx.Audio.Renderer.Server.Voice PoolMapper mapper, ref BehaviourInfo behaviourInfo) { - errorInfos = new ErrorInfo[Constants.VoiceWaveBufferCount * 2]; + if (parameter.IsNew) { @@ -584,11 +588,14 @@ namespace Ryujinx.Audio.Renderer.Server.Voice Span waveBuffersSpan = WaveBuffers.AsSpan(); Span pWaveBuffersSpan = parameter.WaveBuffers.AsSpan(); + List errorInfosList = []; for (int i = 0; i < Constants.VoiceWaveBufferCount; i++) { - UpdateWaveBuffer(errorInfos.AsSpan(i * 2, 2), ref waveBuffersSpan[i], ref pWaveBuffersSpan[i], parameter.SampleFormat, voiceState.IsWaveBufferValid[i], mapper, ref behaviourInfo); + UpdateWaveBuffer(errorInfosList, ref waveBuffersSpan[i], ref pWaveBuffersSpan[i], parameter.SampleFormat, voiceState.IsWaveBufferValid[i], mapper, ref behaviourInfo); } + + errorInfos = errorInfosList.ToArray(); } /// @@ -606,7 +613,7 @@ namespace Ryujinx.Audio.Renderer.Server.Voice PoolMapper mapper, ref BehaviourInfo behaviourInfo) { - errorInfos = new ErrorInfo[Constants.VoiceWaveBufferCount * 2]; + if (parameter.IsNew) { @@ -622,11 +629,14 @@ namespace Ryujinx.Audio.Renderer.Server.Voice Span waveBuffersSpan = WaveBuffers.AsSpan(); Span pWaveBuffersSpan = parameter.WaveBuffers.AsSpan(); + List errorInfosList = []; for (int i = 0; i < Constants.VoiceWaveBufferCount; i++) { - UpdateWaveBuffer(errorInfos.AsSpan(i * 2, 2), ref waveBuffersSpan[i], ref pWaveBuffersSpan[i], parameter.SampleFormat, voiceState.IsWaveBufferValid[i], mapper, ref behaviourInfo); + UpdateWaveBuffer(errorInfosList, ref waveBuffersSpan[i], ref pWaveBuffersSpan[i], parameter.SampleFormat, voiceState.IsWaveBufferValid[i], mapper, ref behaviourInfo); } + + errorInfos = errorInfosList.ToArray(); } /// @@ -640,7 +650,7 @@ namespace Ryujinx.Audio.Renderer.Server.Voice /// The mapper to use. /// The behaviour context. private void UpdateWaveBuffer( - Span errorInfos, + List errorInfos, ref WaveBuffer waveBuffer, ref WaveBufferInternal inputWaveBuffer, SampleFormat sampleFormat, @@ -671,7 +681,10 @@ namespace Ryujinx.Audio.Renderer.Server.Voice BufferInfoUnmapped = !mapper.TryAttachBuffer(out ErrorInfo bufferInfoError, ref waveBuffer.BufferAddressInfo, inputWaveBuffer.Address, inputWaveBuffer.Size); - errorInfos[0] = bufferInfoError; + if (bufferInfoError.ErrorCode != ResultCode.Success) + { + errorInfos.Add(bufferInfoError); + } if (sampleFormat == SampleFormat.Adpcm && behaviourInfo.IsAdpcmLoopContextBugFixed() && inputWaveBuffer.ContextAddress != 0) { @@ -680,7 +693,10 @@ namespace Ryujinx.Audio.Renderer.Server.Voice inputWaveBuffer.ContextAddress, inputWaveBuffer.ContextSize); - errorInfos[1] = adpcmLoopContextInfoError; + if (adpcmLoopContextInfoError.ErrorCode != ResultCode.Success) + { + errorInfos.Add(adpcmLoopContextInfoError); + } if (!adpcmLoopContextMapped || BufferInfoUnmapped) { @@ -698,8 +714,11 @@ namespace Ryujinx.Audio.Renderer.Server.Voice } else { - errorInfos[0].ErrorCode = ResultCode.InvalidAddressInfo; - errorInfos[0].ExtraErrorInfo = inputWaveBuffer.Address; + errorInfos.Add(new ErrorInfo + { + ErrorCode = ResultCode.InvalidAddressInfo, + ExtraErrorInfo = inputWaveBuffer.Address + }); } } } @@ -891,7 +910,7 @@ namespace Ryujinx.Audio.Renderer.Server.Voice IsNew = false; } - Memory[] voiceStates = new Memory[Constants.VoiceChannelCountMax]; + Memory[] voiceStates = voiceStatesPool.Allocate(); Span channelResourceIdsSpan = ChannelResourceIds.AsSpan(); @@ -900,7 +919,12 @@ namespace Ryujinx.Audio.Renderer.Server.Voice voiceStates[i] = context.GetUpdateStateForDsp(channelResourceIdsSpan[i]); } - return UpdateParametersForCommandGeneration(voiceStates); + bool result = UpdateParametersForCommandGeneration(voiceStates); + + voiceStatesPool.Release(voiceStates); + //might contain garbage data, but said data will never be accessed + + return result; } } } diff --git a/src/Ryujinx.Common/Pools/ObjectPool.cs b/src/Ryujinx.Common/Pools/ObjectPool.cs index c4610a59c..65baa00f9 100644 --- a/src/Ryujinx.Common/Pools/ObjectPool.cs +++ b/src/Ryujinx.Common/Pools/ObjectPool.cs @@ -1,67 +1,35 @@ using System; +using System.Collections.Concurrent; using System.Threading; namespace Ryujinx.Common { - public class ObjectPool(Func factory, int size) + public class ObjectPool(Func factory, int size = -1) where T : class { - private T _firstItem; - private readonly T[] _items = new T[size - 1]; + private int _size = size; + private readonly ConcurrentStack _items = new(); public T Allocate() { - T instance = _firstItem; + bool success = _items.TryPop(out T instance); - if (instance == null || instance != Interlocked.CompareExchange(ref _firstItem, null, instance)) + if (!success) { - instance = AllocateInternal(); + instance = factory(); } return instance; } - private T AllocateInternal() - { - T[] items = _items; - - for (int i = 0; i < items.Length; i++) - { - T instance = items[i]; - - if (instance != null && instance == Interlocked.CompareExchange(ref items[i], null, instance)) - { - return instance; - } - } - - return factory(); - } - public void Release(T obj) { - if (_firstItem == null) + if (_size < 0 || _items.Count < _size) { - _firstItem = obj; - } - else - { - ReleaseInternal(obj); - } - } - - private void ReleaseInternal(T obj) - { - T[] items = _items; - - for (int i = 0; i < items.Length; i++) - { - if (items[i] == null) - { - items[i] = obj; - break; - } + _items.Push(obj); } } + + public void Clear() => _items.Clear(); } } diff --git a/src/Ryujinx.HLE/HOS/Kernel/Threading/KScheduler.cs b/src/Ryujinx.HLE/HOS/Kernel/Threading/KScheduler.cs index fa81ef983..b97ba705c 100644 --- a/src/Ryujinx.HLE/HOS/Kernel/Threading/KScheduler.cs +++ b/src/Ryujinx.HLE/HOS/Kernel/Threading/KScheduler.cs @@ -293,7 +293,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Threading KThread currentThread = KernelStatic.GetCurrentThread(); KThread selectedThread = _state.SelectedThread; - if (!currentThread.IsThreadNamed && string.IsNullOrEmpty(currentThread.GetThreadName())) + if (!currentThread.IsThreadNamed && !string.IsNullOrEmpty(currentThread.GetThreadName())) { currentThread.HostThread.Name = $"<{currentThread.GetThreadName()}>"; currentThread.IsThreadNamed = true; diff --git a/src/Ryujinx.Memory/WindowsShared/PlaceholderManager.cs b/src/Ryujinx.Memory/WindowsShared/PlaceholderManager.cs index 436efe98b..6ae540178 100644 --- a/src/Ryujinx.Memory/WindowsShared/PlaceholderManager.cs +++ b/src/Ryujinx.Memory/WindowsShared/PlaceholderManager.cs @@ -1,3 +1,4 @@ +using Ryujinx.Common; using Ryujinx.Common.Collections; using Ryujinx.Common.Memory.PartialUnmaps; using System; @@ -9,24 +10,6 @@ using System.Threading; namespace Ryujinx.Memory.WindowsShared { - public class ObjectPool - { - private readonly Stack _objects; - private readonly Func _objectGenerator; - - public ObjectPool(Func objectGenerator) - { - _objectGenerator = objectGenerator ?? throw new ArgumentNullException(nameof(objectGenerator)); - _objects = new Stack(); - } - - public T Get() => _objects.Count > 0 ? _objects.Pop() : _objectGenerator(); - - public void Return(T item) => _objects.Push(item); - - public void Clear() => _objects.Clear(); - } - /// /// Windows memory placeholder manager. /// @@ -97,7 +80,7 @@ namespace Ryujinx.Memory.WindowsShared lock (_protections) { - _protections.Add(_protectionObjectPool.Get().Init(address, address + size, MemoryPermission.None)); + _protections.Add(_protectionObjectPool.Allocate().Init(address, address + size, MemoryPermission.None)); } } @@ -650,16 +633,16 @@ namespace Ryujinx.Memory.WindowsShared { if (startAddress > protAddress) { - _protections.Add(_protectionObjectPool.Get().Init(protAddress, startAddress, protPermission)); + _protections.Add(_protectionObjectPool.Allocate().Init(protAddress, startAddress, protPermission)); } if (endAddress < protEndAddress) { - _protections.Add(_protectionObjectPool.Get().Init(endAddress, protEndAddress, protPermission)); + _protections.Add(_protectionObjectPool.Allocate().Init(endAddress, protEndAddress, protPermission)); } } - _protectionObjectPool.Return(protection); + _protectionObjectPool.Release(protection); if (node.End >= endAddress) { @@ -667,7 +650,7 @@ namespace Ryujinx.Memory.WindowsShared } } - _protections.Add(_protectionObjectPool.Get().Init(startAddress, endAddress, permission)); + _protections.Add(_protectionObjectPool.Allocate().Init(startAddress, endAddress, permission)); } } @@ -698,15 +681,15 @@ namespace Ryujinx.Memory.WindowsShared if (address > protAddress) { - _protections.Add(_protectionObjectPool.Get().Init(protAddress, address, protPermission)); + _protections.Add(_protectionObjectPool.Allocate().Init(protAddress, address, protPermission)); } if (endAddress < protEndAddress) { - _protections.Add(_protectionObjectPool.Get().Init(endAddress, protEndAddress, protPermission)); + _protections.Add(_protectionObjectPool.Allocate().Init(endAddress, protEndAddress, protPermission)); } - _protectionObjectPool.Return(protection); + _protectionObjectPool.Release(protection); if (node.End >= endAddress) {