Memory Changes part 2 (ryubing/ryujinx!123)

See merge request ryubing/ryujinx!123
This commit is contained in:
LotP
2025-08-25 17:44:15 -05:00
parent d499449f57
commit 50ab108ee1
90 changed files with 2133 additions and 1159 deletions

View File

@@ -26,12 +26,15 @@ namespace Ryujinx.Audio.Renderer.Dsp
ReadOnlySpan<float> inputBuffer,
uint sampleCount)
{
float a0 = FixedPointHelper.ToFloat(parameter.Numerator[0], FixedPointPrecisionForParameter);
float a1 = FixedPointHelper.ToFloat(parameter.Numerator[1], FixedPointPrecisionForParameter);
float a2 = FixedPointHelper.ToFloat(parameter.Numerator[2], FixedPointPrecisionForParameter);
Span<short> numeratorSpan = parameter.Numerator.AsSpan();
Span<short> denominatorSpan = parameter.Denominator.AsSpan();
float a0 = FixedPointHelper.ToFloat(numeratorSpan[0], FixedPointPrecisionForParameter);
float a1 = FixedPointHelper.ToFloat(numeratorSpan[1], FixedPointPrecisionForParameter);
float a2 = FixedPointHelper.ToFloat(numeratorSpan[2], FixedPointPrecisionForParameter);
float b1 = FixedPointHelper.ToFloat(parameter.Denominator[0], FixedPointPrecisionForParameter);
float b2 = FixedPointHelper.ToFloat(parameter.Denominator[1], FixedPointPrecisionForParameter);
float b1 = FixedPointHelper.ToFloat(denominatorSpan[0], FixedPointPrecisionForParameter);
float b2 = FixedPointHelper.ToFloat(denominatorSpan[1], FixedPointPrecisionForParameter);
for (int i = 0; i < sampleCount; i++)
{
@@ -64,12 +67,15 @@ namespace Ryujinx.Audio.Renderer.Dsp
uint sampleCount,
float volume)
{
float a0 = FixedPointHelper.ToFloat(parameter.Numerator[0], FixedPointPrecisionForParameter);
float a1 = FixedPointHelper.ToFloat(parameter.Numerator[1], FixedPointPrecisionForParameter);
float a2 = FixedPointHelper.ToFloat(parameter.Numerator[2], FixedPointPrecisionForParameter);
Span<short> numeratorSpan = parameter.Numerator.AsSpan();
Span<short> denominatorSpan = parameter.Denominator.AsSpan();
float a0 = FixedPointHelper.ToFloat(numeratorSpan[0], FixedPointPrecisionForParameter);
float a1 = FixedPointHelper.ToFloat(numeratorSpan[1], FixedPointPrecisionForParameter);
float a2 = FixedPointHelper.ToFloat(numeratorSpan[2], FixedPointPrecisionForParameter);
float b1 = FixedPointHelper.ToFloat(parameter.Denominator[0], FixedPointPrecisionForParameter);
float b2 = FixedPointHelper.ToFloat(parameter.Denominator[1], FixedPointPrecisionForParameter);
float b1 = FixedPointHelper.ToFloat(denominatorSpan[0], FixedPointPrecisionForParameter);
float b2 = FixedPointHelper.ToFloat(denominatorSpan[1], FixedPointPrecisionForParameter);
for (int i = 0; i < sampleCount; i++)
{
@@ -107,12 +113,15 @@ namespace Ryujinx.Audio.Renderer.Dsp
float volume,
float ramp)
{
float a0 = FixedPointHelper.ToFloat(parameter.Numerator[0], FixedPointPrecisionForParameter);
float a1 = FixedPointHelper.ToFloat(parameter.Numerator[1], FixedPointPrecisionForParameter);
float a2 = FixedPointHelper.ToFloat(parameter.Numerator[2], FixedPointPrecisionForParameter);
Span<short> numeratorSpan = parameter.Numerator.AsSpan();
Span<short> denominatorSpan = parameter.Denominator.AsSpan();
float a0 = FixedPointHelper.ToFloat(numeratorSpan[0], FixedPointPrecisionForParameter);
float a1 = FixedPointHelper.ToFloat(numeratorSpan[1], FixedPointPrecisionForParameter);
float a2 = FixedPointHelper.ToFloat(numeratorSpan[2], FixedPointPrecisionForParameter);
float b1 = FixedPointHelper.ToFloat(parameter.Denominator[0], FixedPointPrecisionForParameter);
float b2 = FixedPointHelper.ToFloat(parameter.Denominator[1], FixedPointPrecisionForParameter);
float b1 = FixedPointHelper.ToFloat(denominatorSpan[0], FixedPointPrecisionForParameter);
float b2 = FixedPointHelper.ToFloat(denominatorSpan[1], FixedPointPrecisionForParameter);
float mixState = 0f;
@@ -157,13 +166,16 @@ namespace Ryujinx.Audio.Renderer.Dsp
BiquadFilterParameter parameter = parameters[stageIndex];
ref BiquadFilterState state = ref states[stageIndex];
Span<short> numeratorSpan = parameter.Numerator.AsSpan();
Span<short> denominatorSpan = parameter.Denominator.AsSpan();
float a0 = FixedPointHelper.ToFloat(parameter.Numerator[0], FixedPointPrecisionForParameter);
float a1 = FixedPointHelper.ToFloat(parameter.Numerator[1], FixedPointPrecisionForParameter);
float a2 = FixedPointHelper.ToFloat(parameter.Numerator[2], FixedPointPrecisionForParameter);
float a0 = FixedPointHelper.ToFloat(numeratorSpan[0], FixedPointPrecisionForParameter);
float a1 = FixedPointHelper.ToFloat(numeratorSpan[1], FixedPointPrecisionForParameter);
float a2 = FixedPointHelper.ToFloat(numeratorSpan[2], FixedPointPrecisionForParameter);
float b1 = FixedPointHelper.ToFloat(parameter.Denominator[0], FixedPointPrecisionForParameter);
float b2 = FixedPointHelper.ToFloat(parameter.Denominator[1], FixedPointPrecisionForParameter);
float b1 = FixedPointHelper.ToFloat(denominatorSpan[0], FixedPointPrecisionForParameter);
float b2 = FixedPointHelper.ToFloat(denominatorSpan[1], FixedPointPrecisionForParameter);
for (int i = 0; i < sampleCount; i++)
{
@@ -201,19 +213,25 @@ namespace Ryujinx.Audio.Renderer.Dsp
uint sampleCount,
float volume)
{
float a00 = FixedPointHelper.ToFloat(parameter0.Numerator[0], FixedPointPrecisionForParameter);
float a10 = FixedPointHelper.ToFloat(parameter0.Numerator[1], FixedPointPrecisionForParameter);
float a20 = FixedPointHelper.ToFloat(parameter0.Numerator[2], FixedPointPrecisionForParameter);
Span<short> numerator0Span = parameter0.Numerator.AsSpan();
Span<short> numerator1Span = parameter1.Numerator.AsSpan();
Span<short> denominator0Span = parameter0.Denominator.AsSpan();
Span<short> denominator1Span = parameter1.Denominator.AsSpan();
float a00 = FixedPointHelper.ToFloat(numerator0Span[0], FixedPointPrecisionForParameter);
float a10 = FixedPointHelper.ToFloat(numerator0Span[1], FixedPointPrecisionForParameter);
float a20 = FixedPointHelper.ToFloat(numerator0Span[2], FixedPointPrecisionForParameter);
float b10 = FixedPointHelper.ToFloat(parameter0.Denominator[0], FixedPointPrecisionForParameter);
float b20 = FixedPointHelper.ToFloat(parameter0.Denominator[1], FixedPointPrecisionForParameter);
float b10 = FixedPointHelper.ToFloat(denominator0Span[0], FixedPointPrecisionForParameter);
float b20 = FixedPointHelper.ToFloat(denominator0Span[1], FixedPointPrecisionForParameter);
float a01 = FixedPointHelper.ToFloat(parameter1.Numerator[0], FixedPointPrecisionForParameter);
float a11 = FixedPointHelper.ToFloat(parameter1.Numerator[1], FixedPointPrecisionForParameter);
float a21 = FixedPointHelper.ToFloat(parameter1.Numerator[2], FixedPointPrecisionForParameter);
float a01 = FixedPointHelper.ToFloat(numerator1Span[0], FixedPointPrecisionForParameter);
float a11 = FixedPointHelper.ToFloat(numerator1Span[1], FixedPointPrecisionForParameter);
float a21 = FixedPointHelper.ToFloat(numerator1Span[2], FixedPointPrecisionForParameter);
float b11 = FixedPointHelper.ToFloat(parameter1.Denominator[0], FixedPointPrecisionForParameter);
float b21 = FixedPointHelper.ToFloat(parameter1.Denominator[1], FixedPointPrecisionForParameter);
float b11 = FixedPointHelper.ToFloat(denominator1Span[0], FixedPointPrecisionForParameter);
float b21 = FixedPointHelper.ToFloat(denominator1Span[1], FixedPointPrecisionForParameter);
for (int i = 0; i < sampleCount; i++)
{
@@ -261,19 +279,24 @@ namespace Ryujinx.Audio.Renderer.Dsp
float volume,
float ramp)
{
float a00 = FixedPointHelper.ToFloat(parameter0.Numerator[0], FixedPointPrecisionForParameter);
float a10 = FixedPointHelper.ToFloat(parameter0.Numerator[1], FixedPointPrecisionForParameter);
float a20 = FixedPointHelper.ToFloat(parameter0.Numerator[2], FixedPointPrecisionForParameter);
Span<short> numerator0Span = parameter0.Numerator.AsSpan();
Span<short> numerator1Span = parameter1.Numerator.AsSpan();
Span<short> denominator0Span = parameter0.Denominator.AsSpan();
Span<short> denominator1Span = parameter1.Denominator.AsSpan();
float a00 = FixedPointHelper.ToFloat(numerator0Span[0], FixedPointPrecisionForParameter);
float a10 = FixedPointHelper.ToFloat(numerator0Span[1], FixedPointPrecisionForParameter);
float a20 = FixedPointHelper.ToFloat(numerator0Span[2], FixedPointPrecisionForParameter);
float b10 = FixedPointHelper.ToFloat(parameter0.Denominator[0], FixedPointPrecisionForParameter);
float b20 = FixedPointHelper.ToFloat(parameter0.Denominator[1], FixedPointPrecisionForParameter);
float b10 = FixedPointHelper.ToFloat(denominator0Span[0], FixedPointPrecisionForParameter);
float b20 = FixedPointHelper.ToFloat(denominator0Span[1], FixedPointPrecisionForParameter);
float a01 = FixedPointHelper.ToFloat(parameter1.Numerator[0], FixedPointPrecisionForParameter);
float a11 = FixedPointHelper.ToFloat(parameter1.Numerator[1], FixedPointPrecisionForParameter);
float a21 = FixedPointHelper.ToFloat(parameter1.Numerator[2], FixedPointPrecisionForParameter);
float a01 = FixedPointHelper.ToFloat(numerator1Span[0], FixedPointPrecisionForParameter);
float a11 = FixedPointHelper.ToFloat(numerator1Span[1], FixedPointPrecisionForParameter);
float a21 = FixedPointHelper.ToFloat(numerator1Span[2], FixedPointPrecisionForParameter);
float b11 = FixedPointHelper.ToFloat(parameter1.Denominator[0], FixedPointPrecisionForParameter);
float b21 = FixedPointHelper.ToFloat(parameter1.Denominator[1], FixedPointPrecisionForParameter);
float b11 = FixedPointHelper.ToFloat(denominator1Span[0], FixedPointPrecisionForParameter);
float b21 = FixedPointHelper.ToFloat(denominator1Span[1], FixedPointPrecisionForParameter);
float mixState = 0f;

View File

@@ -39,12 +39,14 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
OutputBufferIndex = outputBufferIndex;
SampleRate = serverState.SampleRate;
Pitch = serverState.Pitch;
Span<Server.Voice.WaveBuffer> waveBufferSpan = serverState.WaveBuffers.AsSpan();
WaveBuffers = new WaveBuffer[Constants.VoiceWaveBufferCount];
for (int i = 0; i < WaveBuffers.Length; i++)
{
ref Server.Voice.WaveBuffer voiceWaveBuffer = ref serverState.WaveBuffers[i];
ref Server.Voice.WaveBuffer voiceWaveBuffer = ref waveBufferSpan[i];
WaveBuffers[i] = voiceWaveBuffer.ToCommon(1);
}

View File

@@ -1,5 +1,6 @@
using Ryujinx.Audio.Renderer.Parameter.Sink;
using Ryujinx.Audio.Renderer.Server.MemoryPool;
using System;
using System.Diagnostics;
namespace Ryujinx.Audio.Renderer.Dsp.Command
@@ -28,10 +29,12 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
Input = new ushort[Constants.ChannelCountMax];
InputCount = parameter.InputCount;
Span<byte> inputSpan = parameter.Input.AsSpan();
for (int i = 0; i < InputCount; i++)
{
Input[i] = (ushort)(bufferOffset + parameter.Input[i]);
Input[i] = (ushort)(bufferOffset + inputSpan[i]);
}
CircularBuffer = circularBufferAddressInfo.GetReference(true);

View File

@@ -42,11 +42,14 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
InputBufferIndices = new ushort[Constants.VoiceChannelCountMax];
OutputBufferIndices = new ushort[Constants.VoiceChannelCountMax];
Span<byte> inputSpan = _parameter.Input.AsSpan();
Span<byte> outputSpan = _parameter.Output.AsSpan();
for (int i = 0; i < _parameter.ChannelCount; i++)
{
InputBufferIndices[i] = (ushort)(bufferOffset + _parameter.Input[i]);
OutputBufferIndices[i] = (ushort)(bufferOffset + _parameter.Output[i]);
InputBufferIndices[i] = (ushort)(bufferOffset + inputSpan[i]);
OutputBufferIndices[i] = (ushort)(bufferOffset + outputSpan[i]);
}
}
@@ -171,10 +174,12 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
statistics.MinimumGain = MathF.Min(statistics.MinimumGain, compressionGain * state.OutputGain);
statistics.MaximumMean = MathF.Max(statistics.MaximumMean, mean);
Span<float> lastSamplesSpan = statistics.LastSamples.AsSpan();
for (int channelIndex = 0; channelIndex < _parameter.ChannelCount; channelIndex++)
{
statistics.LastSamples[channelIndex] = MathF.Abs(channelInput[channelIndex] * (1f / 32768f));
lastSamplesSpan[channelIndex] = MathF.Abs(channelInput[channelIndex] * (1f / 32768f));
}
}
}

View File

@@ -52,12 +52,14 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
OutputBufferIndex = (ushort)(channelIndex + outputBufferIndex);
SampleRate = serverState.SampleRate;
Pitch = serverState.Pitch;
Span<Server.Voice.WaveBuffer> waveBufferSpan = serverState.WaveBuffers.AsSpan();
WaveBuffers = new WaveBuffer[Constants.VoiceWaveBufferCount];
for (int i = 0; i < WaveBuffers.Length; i++)
{
ref Server.Voice.WaveBuffer voiceWaveBuffer = ref serverState.WaveBuffers[i];
ref Server.Voice.WaveBuffer voiceWaveBuffer = ref waveBufferSpan[i];
WaveBuffers[i] = voiceWaveBuffer.ToCommon(2);
}

View File

@@ -42,11 +42,14 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
InputBufferIndices = new ushort[Constants.VoiceChannelCountMax];
OutputBufferIndices = new ushort[Constants.VoiceChannelCountMax];
Span<byte> inputSpan = Parameter.Input.AsSpan();
Span<byte> outputSpan = Parameter.Output.AsSpan();
for (int i = 0; i < Parameter.ChannelCount; i++)
{
InputBufferIndices[i] = (ushort)(bufferOffset + Parameter.Input[i]);
OutputBufferIndices[i] = (ushort)(bufferOffset + Parameter.Output[i]);
InputBufferIndices[i] = (ushort)(bufferOffset + inputSpan[i]);
OutputBufferIndices[i] = (ushort)(bufferOffset + outputSpan[i]);
}
DataSourceHelper.RemapLegacyChannelEffectMappingToChannelResourceMapping(newEffectChannelMappingSupported, InputBufferIndices, Parameter.ChannelCount);

View File

@@ -42,14 +42,15 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
ref VoiceUpdateState state = ref State.Span[0];
Span<float> depopBuffer = DepopBuffer.Span;
Span<float> lastSamplesSpan = state.LastSamples.AsSpan();
for (int i = 0; i < MixBufferCount; i++)
{
if (state.LastSamples[i] != 0)
if (lastSamplesSpan[i] != 0)
{
depopBuffer[OutputBufferIndices[i]] += state.LastSamples[i];
depopBuffer[OutputBufferIndices[i]] += lastSamplesSpan[i];
state.LastSamples[i] = 0;
lastSamplesSpan[i] = 0;
}
}
}

View File

@@ -34,10 +34,12 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
SessionId = sessionId;
InputCount = sink.Parameter.InputCount;
InputBufferIndices = new ushort[InputCount];
Span<byte> inputSpan = sink.Parameter.Input.AsSpan();
for (int i = 0; i < Math.Min(InputCount, Constants.ChannelCountMax); i++)
{
InputBufferIndices[i] = (ushort)(bufferOffset + sink.Parameter.Input[i]);
InputBufferIndices[i] = (ushort)(bufferOffset + inputSpan[i]);
}
if (sink.UpsamplerState != null)

View File

@@ -37,11 +37,14 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
InputBufferIndices = new ushort[Constants.VoiceChannelCountMax];
OutputBufferIndices = new ushort[Constants.VoiceChannelCountMax];
Span<byte> inputSpan = _parameter.Input.AsSpan();
Span<byte> outputSpan = _parameter.Output.AsSpan();
for (int i = 0; i < _parameter.ChannelCount; i++)
{
InputBufferIndices[i] = (ushort)(bufferOffset + _parameter.Input[i]);
OutputBufferIndices[i] = (ushort)(bufferOffset + _parameter.Output[i]);
InputBufferIndices[i] = (ushort)(bufferOffset + inputSpan[i]);
OutputBufferIndices[i] = (ushort)(bufferOffset + outputSpan[i]);
}
}

View File

@@ -48,11 +48,14 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
InputBufferIndices = new ushort[Constants.VoiceChannelCountMax];
OutputBufferIndices = new ushort[Constants.VoiceChannelCountMax];
Span<byte> inputSpan = _parameter.Input.AsSpan();
Span<byte> outputSpan = _parameter.Output.AsSpan();
for (int i = 0; i < _parameter.ChannelCount; i++)
{
InputBufferIndices[i] = (ushort)(bufferOffset + _parameter.Input[i]);
OutputBufferIndices[i] = (ushort)(bufferOffset + _parameter.Output[i]);
InputBufferIndices[i] = (ushort)(bufferOffset + inputSpan[i]);
OutputBufferIndices[i] = (ushort)(bufferOffset + outputSpan[i]);
}
}
@@ -150,8 +153,11 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
{
ref LimiterStatistics statistics = ref MemoryMarshal.Cast<byte, LimiterStatistics>(ResultState.Span[0].SpecificData)[0];
statistics.InputMax[channelIndex] = Math.Max(statistics.InputMax[channelIndex], sampleInputMax);
statistics.CompressionGainMin[channelIndex] = Math.Min(statistics.CompressionGainMin[channelIndex], compressionGain);
Span<float> inputMaxSpan = statistics.InputMax.AsSpan();
Span<float> compressionGainMinSpan = statistics.CompressionGainMin.AsSpan();
inputMaxSpan[channelIndex] = Math.Max(inputMaxSpan[channelIndex], sampleInputMax);
compressionGainMinSpan[channelIndex] = Math.Min(compressionGainMinSpan[channelIndex], compressionGain);
}
}
}

View File

@@ -79,6 +79,10 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
public void Process(CommandList context)
{
ref VoiceUpdateState state = ref State.Span[0];
Span<float> lastSamplesSpan = state.LastSamples.AsSpan();
for (int i = 0; i < MixBufferCount; i++)
{
ReadOnlySpan<float> inputBuffer = context.GetBuffer(InputBufferIndices[i]);
@@ -87,15 +91,13 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
float volume0 = Volume0[i];
float volume1 = Volume1[i];
ref VoiceUpdateState state = ref State.Span[0];
if (volume0 != 0 || volume1 != 0)
{
state.LastSamples[i] = ProcessMixRampGrouped(outputBuffer, inputBuffer, volume0, volume1, (int)context.SampleCount);
lastSamplesSpan[i] = ProcessMixRampGrouped(outputBuffer, inputBuffer, volume0, volume1, (int)context.SampleCount);
}
else
{
state.LastSamples[i] = 0;
lastSamplesSpan[i] = 0;
}
}
}

View File

@@ -42,10 +42,12 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
Pitch = serverState.Pitch;
WaveBuffers = new WaveBuffer[Constants.VoiceWaveBufferCount];
Span<Server.Voice.WaveBuffer> waveBufferSpan = serverState.WaveBuffers.AsSpan();
for (int i = 0; i < WaveBuffers.Length; i++)
{
ref Server.Voice.WaveBuffer voiceWaveBuffer = ref serverState.WaveBuffers[i];
ref Server.Voice.WaveBuffer voiceWaveBuffer = ref waveBufferSpan[i];
WaveBuffers[i] = voiceWaveBuffer.ToCommon(1);
}

View File

@@ -42,10 +42,12 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
Pitch = serverState.Pitch;
WaveBuffers = new WaveBuffer[Constants.VoiceWaveBufferCount];
Span<Server.Voice.WaveBuffer> waveBufferSpan = serverState.WaveBuffers.AsSpan();
for (int i = 0; i < WaveBuffers.Length; i++)
{
ref Server.Voice.WaveBuffer voiceWaveBuffer = ref serverState.WaveBuffers[i];
ref Server.Voice.WaveBuffer voiceWaveBuffer = ref waveBufferSpan[i];
WaveBuffers[i] = voiceWaveBuffer.ToCommon(1);
}

View File

@@ -65,11 +65,14 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
InputBufferIndices = new ushort[Constants.VoiceChannelCountMax];
OutputBufferIndices = new ushort[Constants.VoiceChannelCountMax];
Span<byte> inputSpan = Parameter.Input.AsSpan();
Span<byte> outputSpan = Parameter.Output.AsSpan();
for (int i = 0; i < Parameter.ChannelCount; i++)
{
InputBufferIndices[i] = (ushort)(bufferOffset + Parameter.Input[i]);
OutputBufferIndices[i] = (ushort)(bufferOffset + Parameter.Output[i]);
InputBufferIndices[i] = (ushort)(bufferOffset + inputSpan[i]);
OutputBufferIndices[i] = (ushort)(bufferOffset + outputSpan[i]);
}
// NOTE: We do the opposite as Nintendo here for now to restore previous behaviour

View File

@@ -63,11 +63,14 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
InputBufferIndices = new ushort[Constants.VoiceChannelCountMax];
OutputBufferIndices = new ushort[Constants.VoiceChannelCountMax];
Span<byte> inputSpan = Parameter.Input.AsSpan();
Span<byte> outputSpan = Parameter.Output.AsSpan();
for (int i = 0; i < Parameter.ChannelCount; i++)
{
InputBufferIndices[i] = (ushort)(bufferOffset + Parameter.Input[i]);
OutputBufferIndices[i] = (ushort)(bufferOffset + Parameter.Output[i]);
InputBufferIndices[i] = (ushort)(bufferOffset + inputSpan[i]);
OutputBufferIndices[i] = (ushort)(bufferOffset + outputSpan[i]);
}
IsLongSizePreDelaySupported = isLongSizePreDelaySupported;

View File

@@ -74,7 +74,7 @@ namespace Ryujinx.Audio.Renderer.Dsp
{
int tempBufferIndex = 0;
if (!info.DecodingBehaviour.HasFlag(DecodingBehaviour.SkipPitchAndSampleRateConversion))
if ((info.DecodingBehaviour & DecodingBehaviour.SkipPitchAndSampleRateConversion) != DecodingBehaviour.SkipPitchAndSampleRateConversion)
{
voiceState.Pitch.AsSpan()[..pitchMaxLength].CopyTo(tempBuffer);
tempBufferIndex += pitchMaxLength;
@@ -208,7 +208,7 @@ namespace Ryujinx.Audio.Renderer.Dsp
break;
}
if (info.DecodingBehaviour.HasFlag(DecodingBehaviour.PlayedSampleCountResetWhenLooping))
if ((info.DecodingBehaviour & DecodingBehaviour.PlayedSampleCountResetWhenLooping) == DecodingBehaviour.PlayedSampleCountResetWhenLooping)
{
playedSampleCount = 0;
}
@@ -222,7 +222,7 @@ namespace Ryujinx.Audio.Renderer.Dsp
Span<int> outputSpanInt = MemoryMarshal.Cast<float, int>(outputBuffer[i..]);
if (info.DecodingBehaviour.HasFlag(DecodingBehaviour.SkipPitchAndSampleRateConversion))
if ((info.DecodingBehaviour & DecodingBehaviour.SkipPitchAndSampleRateConversion) == DecodingBehaviour.SkipPitchAndSampleRateConversion)
{
for (int j = 0; j < y; j++)
{

View File

@@ -41,11 +41,12 @@ namespace Ryujinx.Audio.Renderer.Dsp
}
Array20<float> result = new();
Span<float> resultSpan = result.AsSpan();
for (int i = 0; i < FilterBankLength; i++)
{
float x = (Bank0CenterIndex - i) + offset;
result[i] = Sinc(x) * BlackmanWindow(x / FilterBankLength + 0.5f);
resultSpan[i] = Sinc(x) * BlackmanWindow(x / FilterBankLength + 0.5f);
}
return result;
@@ -78,6 +79,9 @@ namespace Ryujinx.Audio.Renderer.Dsp
Debug.Assert(state.History.Length == HistoryLength);
Debug.Assert(bank.Length == FilterBankLength);
Span<float> bankSpan = bank.AsSpan();
Span<float> historySpan = state.History.AsSpan();
int curIdx = 0;
if (Vector.IsHardwareAccelerated)
@@ -88,15 +92,15 @@ namespace Ryujinx.Audio.Renderer.Dsp
while (curIdx < stopIdx)
{
result += Vector.Dot(
new Vector<float>(bank.AsSpan().Slice(curIdx, Vector<float>.Count)),
new Vector<float>(state.History.AsSpan().Slice(curIdx, Vector<float>.Count)));
new Vector<float>(bankSpan[curIdx..(curIdx + Vector<float>.Count)]),
new Vector<float>(historySpan[curIdx..(curIdx + Vector<float>.Count)]));
curIdx += Vector<float>.Count;
}
}
while (curIdx < FilterBankLength)
{
result += bank[curIdx] * state.History[curIdx];
result += bankSpan[curIdx] * historySpan[curIdx];
curIdx++;
}

View File

@@ -141,18 +141,20 @@ namespace Ryujinx.Audio.Renderer.Server
{
bool supportsOptimizedPath = _rendererContext.BehaviourContext.UseMultiTapBiquadFilterProcessing();
if (supportsOptimizedPath && voiceState.BiquadFilters[0].Enable && voiceState.BiquadFilters[1].Enable)
Span<BiquadFilterParameter> biquadFiltersSpan = voiceState.BiquadFilters.AsSpan();
if (supportsOptimizedPath && biquadFiltersSpan[0].Enable && biquadFiltersSpan[1].Enable)
{
Memory<byte> biquadStateRawMemory = SpanMemoryManager<byte>.Cast(state)[..(Unsafe.SizeOf<BiquadFilterState>() * Constants.VoiceBiquadFilterCount)];
Memory<BiquadFilterState> stateMemory = SpanMemoryManager<BiquadFilterState>.Cast(biquadStateRawMemory);
_commandBuffer.GenerateMultiTapBiquadFilter(baseIndex, voiceState.BiquadFilters.AsSpan(), stateMemory, bufferOffset, bufferOffset, voiceState.BiquadFilterNeedInitialization, nodeId);
_commandBuffer.GenerateMultiTapBiquadFilter(baseIndex, biquadFiltersSpan, stateMemory, bufferOffset, bufferOffset, voiceState.BiquadFilterNeedInitialization, nodeId);
}
else
{
for (int i = 0; i < voiceState.BiquadFilters.Length; i++)
for (int i = 0; i < biquadFiltersSpan.Length; i++)
{
ref BiquadFilterParameter filter = ref voiceState.BiquadFilters[i];
ref BiquadFilterParameter filter = ref biquadFiltersSpan[i];
if (filter.Enable)
{
@@ -311,12 +313,15 @@ namespace Ryujinx.Audio.Renderer.Server
{
int nodeId = voiceState.NodeId;
uint channelsCount = voiceState.ChannelsCount;
Span<int> channelResourceIdsSpan = voiceState.ChannelResourceIds.AsSpan();
Span<BiquadFilterParameter> biquadFiltersSpan = voiceState.BiquadFilters.AsSpan();
for (int channelIndex = 0; channelIndex < channelsCount; channelIndex++)
{
Memory<VoiceUpdateState> dspStateMemory = _voiceContext.GetUpdateStateForDsp(voiceState.ChannelResourceIds[channelIndex]);
Memory<VoiceUpdateState> dspStateMemory = _voiceContext.GetUpdateStateForDsp(channelResourceIdsSpan[channelIndex]);
ref VoiceChannelResource channelResource = ref _voiceContext.GetChannelResource(voiceState.ChannelResourceIds[channelIndex]);
ref VoiceChannelResource channelResource = ref _voiceContext.GetChannelResource(channelResourceIdsSpan[channelIndex]);
PerformanceDetailType dataSourceDetailType = PerformanceDetailType.Adpcm;
@@ -476,7 +481,7 @@ namespace Ryujinx.Audio.Renderer.Server
for (int i = 0; i < voiceState.BiquadFilterNeedInitialization.Length; i++)
{
voiceState.BiquadFilterNeedInitialization[i] = voiceState.BiquadFilters[i].Enable;
voiceState.BiquadFilterNeedInitialization[i] = biquadFiltersSpan[i].Enable;
}
}
}
@@ -526,15 +531,19 @@ namespace Ryujinx.Audio.Renderer.Server
if (effect.IsEnabled)
{
Span<float> volumesSpan = effect.Parameter.Volumes.AsSpan();
Span<byte> inputSpan = effect.Parameter.Input.AsSpan();
Span<byte> outputSpan = effect.Parameter.Output.AsSpan();
for (int i = 0; i < effect.Parameter.MixesCount; i++)
{
if (effect.Parameter.Volumes[i] != 0.0f)
if (volumesSpan[i] != 0.0f)
{
_commandBuffer.GenerateMix(
(uint)bufferOffset + effect.Parameter.Input[i],
(uint)bufferOffset + effect.Parameter.Output[i],
(uint)bufferOffset + inputSpan[i],
(uint)bufferOffset + outputSpan[i],
nodeId,
effect.Parameter.Volumes[i]);
volumesSpan[i]);
}
}
}
@@ -554,6 +563,10 @@ namespace Ryujinx.Audio.Renderer.Server
{
int i = 0;
uint writeOffset = 0;
Span<byte> inputSpan = effect.Parameter.Input.AsSpan();
Span<byte> outputSpan = effect.Parameter.Output.AsSpan();
for (uint channelIndex = effect.Parameter.ChannelCount; channelIndex != 0; channelIndex--)
{
uint newUpdateCount = writeOffset + _commandBuffer.CommandList.SampleCount;
@@ -571,8 +584,8 @@ namespace Ryujinx.Audio.Renderer.Server
_commandBuffer.GenerateAuxEffect(
bufferOffset,
effect.Parameter.Input[i],
effect.Parameter.Output[i],
inputSpan[i],
outputSpan[i],
ref effect.State,
effect.IsEnabled,
effect.Parameter.BufferStorageSize,
@@ -619,6 +632,9 @@ namespace Ryujinx.Audio.Renderer.Server
private void GenerateBiquadFilterEffect(uint bufferOffset, BiquadFilterEffect effect, int nodeId)
{
Debug.Assert(effect.Type == EffectType.BiquadFilter);
Span<byte> inputSpan = effect.Parameter.Input.AsSpan();
Span<byte> outputSpan = effect.Parameter.Output.AsSpan();
if (effect.IsEnabled)
{
@@ -639,8 +655,8 @@ namespace Ryujinx.Audio.Renderer.Server
(int)bufferOffset,
ref parameter,
effect.State.Slice(i, 1),
effect.Parameter.Input[i],
effect.Parameter.Output[i],
inputSpan[i],
outputSpan[i],
needInitialization,
nodeId);
}
@@ -649,8 +665,8 @@ namespace Ryujinx.Audio.Renderer.Server
{
for (int i = 0; i < effect.Parameter.ChannelCount; i++)
{
uint inputBufferIndex = bufferOffset + effect.Parameter.Input[i];
uint outputBufferIndex = bufferOffset + effect.Parameter.Output[i];
uint inputBufferIndex = bufferOffset + inputSpan[i];
uint outputBufferIndex = bufferOffset + outputSpan[i];
// If the input and output isn't the same, generate a command.
if (inputBufferIndex != outputBufferIndex)
@@ -701,6 +717,8 @@ namespace Ryujinx.Audio.Renderer.Server
{
int i = 0;
uint writeOffset = 0;
Span<byte> inputSpan = effect.Parameter.Input.AsSpan();
for (uint channelIndex = effect.Parameter.ChannelCount; channelIndex != 0; channelIndex--)
{
@@ -719,7 +737,7 @@ namespace Ryujinx.Audio.Renderer.Server
_commandBuffer.GenerateCaptureEffect(
bufferOffset,
effect.Parameter.Input[i],
inputSpan[i],
effect.State.SendBufferInfo,
effect.IsEnabled,
effect.Parameter.BufferStorageSize,

View File

@@ -218,7 +218,8 @@ namespace Ryujinx.Audio.Renderer.Server.Splitter
/// <returns>True if any biquad filter is enabled.</returns>
public bool IsBiquadFilterEnabled()
{
return _biquadFilters[0].Enable || _biquadFilters[1].Enable;
Span<BiquadFilterParameter> biquadFiltersSpan = _biquadFilters.AsSpan();
return biquadFiltersSpan[0].Enable || biquadFiltersSpan[1].Enable;
}
/// <summary>

View File

@@ -162,9 +162,11 @@ namespace Ryujinx.Audio.Renderer.Server
{
ref VoiceState currentVoiceState = ref context.GetState(i);
Span<int> channelResourceIdsSpan = parameter.ChannelResourceIds.AsSpan();
for (int channelResourceIndex = 0; channelResourceIndex < parameter.ChannelCount; channelResourceIndex++)
{
int channelId = parameter.ChannelResourceIds[channelResourceIndex];
int channelId = channelResourceIdsSpan[channelResourceIndex];
Debug.Assert(channelId >= 0 && channelId < context.GetCount());

View File

@@ -126,9 +126,9 @@ namespace Ryujinx.Audio.Renderer.Server.Voice
_sortedVoices.Span[i] = i;
}
int[] sortedVoicesTemp = _sortedVoices[..(int)GetCount()].ToArray();
Span<int> sortedVoicesTemp = _sortedVoices[..(int)_voiceCount].Span;
Array.Sort(sortedVoicesTemp, (a, b) =>
sortedVoicesTemp.Sort((a, b) =>
{
ref VoiceState aState = ref GetState(a);
ref VoiceState bState = ref GetState(b);
@@ -143,7 +143,7 @@ namespace Ryujinx.Audio.Renderer.Server.Voice
return result;
});
sortedVoicesTemp.AsSpan().CopyTo(_sortedVoices.Span);
// sortedVoicesTemp.CopyTo(_sortedVoices.Span);
}
}
}

View File

@@ -219,15 +219,17 @@ namespace Ryujinx.Audio.Renderer.Server.Voice
/// </summary>
private void InitializeWaveBuffers()
{
for (int i = 0; i < WaveBuffers.Length; i++)
Span<WaveBuffer> waveBuffersSpan = WaveBuffers.AsSpan();
for (int i = 0; i < waveBuffersSpan.Length; i++)
{
WaveBuffers[i].StartSampleOffset = 0;
WaveBuffers[i].EndSampleOffset = 0;
WaveBuffers[i].ShouldLoop = false;
WaveBuffers[i].IsEndOfStream = false;
WaveBuffers[i].BufferAddressInfo.Setup(0, 0);
WaveBuffers[i].ContextAddressInfo.Setup(0, 0);
WaveBuffers[i].IsSendToAudioProcessor = true;
waveBuffersSpan[i].StartSampleOffset = 0;
waveBuffersSpan[i].EndSampleOffset = 0;
waveBuffersSpan[i].ShouldLoop = false;
waveBuffersSpan[i].IsEndOfStream = false;
waveBuffersSpan[i].BufferAddressInfo.Setup(0, 0);
waveBuffersSpan[i].ContextAddressInfo.Setup(0, 0);
waveBuffersSpan[i].IsSendToAudioProcessor = true;
}
}
@@ -446,10 +448,13 @@ namespace Ryujinx.Audio.Renderer.Server.Voice
}
ref VoiceUpdateState voiceUpdateState = ref voiceUpdateStates[0].Span[0];
Span<WaveBuffer> waveBuffersSpan = WaveBuffers.AsSpan();
Span<WaveBufferInternal> pWaveBuffersSpan = parameter.WaveBuffers.AsSpan();
for (int i = 0; i < Constants.VoiceWaveBufferCount; i++)
{
UpdateWaveBuffer(errorInfos.AsSpan(i * 2, 2), ref WaveBuffers[i], ref parameter.WaveBuffers[i], parameter.SampleFormat, voiceUpdateState.IsWaveBufferValid[i], mapper, ref behaviourContext);
UpdateWaveBuffer(errorInfos.AsSpan(i * 2, 2), ref waveBuffersSpan[i], ref pWaveBuffersSpan[i], parameter.SampleFormat, voiceUpdateState.IsWaveBufferValid[i], mapper, ref behaviourContext);
}
}
@@ -534,9 +539,11 @@ namespace Ryujinx.Audio.Renderer.Server.Voice
/// <param name="context">The voice context.</param>
private void ResetResources(VoiceContext context)
{
Span<int> channelResourceIdsSpan = ChannelResourceIds.AsSpan();
for (int i = 0; i < ChannelsCount; i++)
{
int channelResourceId = ChannelResourceIds[i];
int channelResourceId = channelResourceIdsSpan[i];
ref VoiceChannelResource voiceChannelResource = ref context.GetChannelResource(channelResourceId);
@@ -559,10 +566,12 @@ namespace Ryujinx.Audio.Renderer.Server.Voice
private void FlushWaveBuffers(uint waveBufferCount, Memory<VoiceUpdateState>[] voiceUpdateStates, uint channelCount)
{
uint waveBufferIndex = WaveBuffersIndex;
Span<WaveBuffer> waveBuffersSpan = WaveBuffers.AsSpan();
for (int i = 0; i < waveBufferCount; i++)
{
WaveBuffers[(int)waveBufferIndex].IsSendToAudioProcessor = true;
waveBuffersSpan[(int)waveBufferIndex].IsSendToAudioProcessor = true;
for (int j = 0; j < channelCount; j++)
{
@@ -591,14 +600,18 @@ namespace Ryujinx.Audio.Renderer.Server.Voice
FlushWaveBufferCount = 0;
}
Span<WaveBuffer> waveBuffersSpan;
switch (PlayState)
{
case PlayState.Started:
for (int i = 0; i < WaveBuffers.Length; i++)
waveBuffersSpan = WaveBuffers.AsSpan();
for (int i = 0; i < waveBuffersSpan.Length; i++)
{
ref WaveBuffer wavebuffer = ref WaveBuffers[i];
ref WaveBuffer waveBuffer = ref waveBuffersSpan[i];
if (!wavebuffer.IsSendToAudioProcessor)
if (!waveBuffer.IsSendToAudioProcessor)
{
for (int y = 0; y < ChannelsCount; y++)
{
@@ -607,7 +620,7 @@ namespace Ryujinx.Audio.Renderer.Server.Voice
voiceUpdateStates[y].Span[0].IsWaveBufferValid[i] = true;
}
wavebuffer.IsSendToAudioProcessor = true;
waveBuffer.IsSendToAudioProcessor = true;
}
}
@@ -626,11 +639,13 @@ namespace Ryujinx.Audio.Renderer.Server.Voice
return false;
case PlayState.Stopping:
for (int i = 0; i < WaveBuffers.Length; i++)
waveBuffersSpan = WaveBuffers.AsSpan();
for (int i = 0; i < waveBuffersSpan.Length; i++)
{
ref WaveBuffer wavebuffer = ref WaveBuffers[i];
ref WaveBuffer waveBuffer = ref waveBuffersSpan[i];
wavebuffer.IsSendToAudioProcessor = true;
waveBuffer.IsSendToAudioProcessor = true;
for (int j = 0; j < ChannelsCount; j++)
{
@@ -702,9 +717,11 @@ namespace Ryujinx.Audio.Renderer.Server.Voice
Memory<VoiceUpdateState>[] voiceUpdateStates = new Memory<VoiceUpdateState>[Constants.VoiceChannelCountMax];
Span<int> channelResourceIdsSpan = ChannelResourceIds.AsSpan();
for (int i = 0; i < ChannelsCount; i++)
{
voiceUpdateStates[i] = context.GetUpdateStateForDsp(ChannelResourceIds[i]);
voiceUpdateStates[i] = context.GetUpdateStateForDsp(channelResourceIdsSpan[i]);
}
return UpdateParametersForCommandGeneration(voiceUpdateStates);