diff --git a/src/Ryujinx.Audio/Renderer/Common/BehaviourParameter.cs b/src/Ryujinx.Audio/Renderer/Common/BehaviourParameter.cs
index 3b8d15dc5..5b4f39e23 100644
--- a/src/Ryujinx.Audio/Renderer/Common/BehaviourParameter.cs
+++ b/src/Ryujinx.Audio/Renderer/Common/BehaviourParameter.cs
@@ -1,9 +1,11 @@
+using Ryujinx.Audio.Renderer.Server;
+using Ryujinx.Audio.Renderer.Server.MemoryPool;
using System.Runtime.InteropServices;
namespace Ryujinx.Audio.Renderer.Common
{
///
- /// Represents the input parameter for .
+ /// Represents the input parameter for .
///
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct BehaviourParameter
@@ -21,7 +23,7 @@ namespace Ryujinx.Audio.Renderer.Common
///
/// The flags given controlling behaviour of the audio renderer
///
- /// See and .
+ /// See and .
public ulong Flags;
///
@@ -43,7 +45,7 @@ namespace Ryujinx.Audio.Renderer.Common
///
/// Extra information given with the
///
- /// This is usually used to report a faulting cpu address when a mapping fail.
+ /// This is usually used to report a faulting cpu address when a mapping fail.
public ulong ExtraErrorInfo;
}
}
diff --git a/src/Ryujinx.Audio/Renderer/Common/VoiceUpdateState.cs b/src/Ryujinx.Audio/Renderer/Common/VoiceState.cs
similarity index 95%
rename from src/Ryujinx.Audio/Renderer/Common/VoiceUpdateState.cs
rename to src/Ryujinx.Audio/Renderer/Common/VoiceState.cs
index 7f881373f..508daa6e2 100644
--- a/src/Ryujinx.Audio/Renderer/Common/VoiceUpdateState.cs
+++ b/src/Ryujinx.Audio/Renderer/Common/VoiceState.cs
@@ -1,4 +1,5 @@
using Ryujinx.Audio.Renderer.Dsp.State;
+using Ryujinx.Audio.Renderer.Parameter;
using Ryujinx.Common.Memory;
using Ryujinx.Common.Utilities;
using System;
@@ -11,7 +12,7 @@ namespace Ryujinx.Audio.Renderer.Common
///
/// This is shared between the server and audio processor.
[StructLayout(LayoutKind.Sequential, Pack = Align)]
- public struct VoiceUpdateState
+ public struct VoiceState
{
public const int Align = 0x10;
public const int BiquadStateOffset = 0x0;
@@ -25,7 +26,7 @@ namespace Ryujinx.Audio.Renderer.Common
/// The total amount of samples that was played.
///
/// This is reset to 0 when a finishes playing and is set.
- /// This is reset to 0 when looping while is set.
+ /// This is reset to 0 when looping while is set.
public ulong PlayedSampleCount;
///
diff --git a/src/Ryujinx.Audio/Renderer/Dsp/BiquadFilterHelper.cs b/src/Ryujinx.Audio/Renderer/Dsp/BiquadFilterHelper.cs
index 2122f2b44..4f98a8fb5 100644
--- a/src/Ryujinx.Audio/Renderer/Dsp/BiquadFilterHelper.cs
+++ b/src/Ryujinx.Audio/Renderer/Dsp/BiquadFilterHelper.cs
@@ -1,5 +1,7 @@
using Ryujinx.Audio.Renderer.Dsp.State;
using Ryujinx.Audio.Renderer.Parameter;
+using Ryujinx.Audio.Renderer.Parameter.Effect;
+using Ryujinx.Common.Memory;
using System;
using System.Runtime.CompilerServices;
@@ -9,6 +11,112 @@ namespace Ryujinx.Audio.Renderer.Dsp
{
private const int FixedPointPrecisionForParameter = 14;
+ public static BiquadFilterParameter1 ToBiquadFilterParameter1(BiquadFilterParameter2 parameter)
+ {
+ BiquadFilterParameter1 result = new()
+ {
+ Enable = parameter.Enable, Numerator = new Array3(), Denominator = new Array2()
+ };
+
+ Span resultNumeratorSpan = result.Numerator.AsSpan();
+ Span resultDenominatorSpan = result.Denominator.AsSpan();
+
+ Span parameterNumeratorSpan = parameter.Numerator.AsSpan();
+ Span parameterDenominatorSpan = parameter.Denominator.AsSpan();
+
+
+ resultNumeratorSpan[0] = (short)FixedPointHelper.ToFixed(parameterNumeratorSpan[0], FixedPointPrecisionForParameter);
+ resultNumeratorSpan[1] = (short)FixedPointHelper.ToFixed(parameterNumeratorSpan[1], FixedPointPrecisionForParameter);
+ resultNumeratorSpan[2] = (short)FixedPointHelper.ToFixed(parameterNumeratorSpan[2], FixedPointPrecisionForParameter);
+
+ resultDenominatorSpan[0] = (short)FixedPointHelper.ToFixed(parameterDenominatorSpan[0], FixedPointPrecisionForParameter);
+ resultDenominatorSpan[1] = (short)FixedPointHelper.ToFixed(parameterDenominatorSpan[1], FixedPointPrecisionForParameter);
+
+ return result;
+ }
+
+ public static BiquadFilterParameter2 ToBiquadFilterParameter2(BiquadFilterParameter1 parameter)
+ {
+ BiquadFilterParameter2 result = new()
+ {
+ Enable = parameter.Enable, Numerator = new Array3(), Denominator = new Array2()
+ };
+
+ Span resultNumeratorSpan = result.Numerator.AsSpan();
+ Span resultDenominatorSpan = result.Denominator.AsSpan();
+
+ Span parameterNumeratorSpan = parameter.Numerator.AsSpan();
+ Span parameterDenominatorSpan = parameter.Denominator.AsSpan();
+
+
+ resultNumeratorSpan[0] = FixedPointHelper.ToFloat(parameterNumeratorSpan[0], FixedPointPrecisionForParameter);
+ resultNumeratorSpan[1] = FixedPointHelper.ToFloat(parameterNumeratorSpan[1], FixedPointPrecisionForParameter);
+ resultNumeratorSpan[2] = FixedPointHelper.ToFloat(parameterNumeratorSpan[2], FixedPointPrecisionForParameter);
+
+ resultDenominatorSpan[0] = FixedPointHelper.ToFloat(parameterDenominatorSpan[0], FixedPointPrecisionForParameter);
+ resultDenominatorSpan[1] = FixedPointHelper.ToFloat(parameterDenominatorSpan[1], FixedPointPrecisionForParameter);
+
+ return result;
+ }
+
+ public static BiquadFilterEffectParameter1 ToBiquadFilterEffectParameter1(BiquadFilterEffectParameter2 parameter)
+ {
+ BiquadFilterEffectParameter1 result = new()
+ {
+ Input = parameter.Input,
+ Output = parameter.Output,
+ Numerator = new Array3(),
+ Denominator = new Array2(),
+ ChannelCount = parameter.ChannelCount,
+ Status = parameter.Status,
+ };
+
+ Span resultNumeratorSpan = result.Numerator.AsSpan();
+ Span resultDenominatorSpan = result.Denominator.AsSpan();
+
+ Span parameterNumeratorSpan = parameter.Numerator.AsSpan();
+ Span parameterDenominatorSpan = parameter.Denominator.AsSpan();
+
+
+ resultNumeratorSpan[0] = (short)FixedPointHelper.ToFixed(parameterNumeratorSpan[0], FixedPointPrecisionForParameter);
+ resultNumeratorSpan[1] = (short)FixedPointHelper.ToFixed(parameterNumeratorSpan[1], FixedPointPrecisionForParameter);
+ resultNumeratorSpan[2] = (short)FixedPointHelper.ToFixed(parameterNumeratorSpan[2], FixedPointPrecisionForParameter);
+
+ resultDenominatorSpan[0] = (short)FixedPointHelper.ToFixed(parameterDenominatorSpan[0], FixedPointPrecisionForParameter);
+ resultDenominatorSpan[1] = (short)FixedPointHelper.ToFixed(parameterDenominatorSpan[1], FixedPointPrecisionForParameter);
+
+ return result;
+ }
+
+ public static BiquadFilterEffectParameter2 ToBiquadFilterEffectParameter2(BiquadFilterEffectParameter1 parameter)
+ {
+ BiquadFilterEffectParameter2 result = new()
+ {
+ Input = parameter.Input,
+ Output = parameter.Output,
+ Numerator = new Array3(),
+ Denominator = new Array2(),
+ ChannelCount = parameter.ChannelCount,
+ Status = parameter.Status,
+ };
+
+ Span resultNumeratorSpan = result.Numerator.AsSpan();
+ Span resultDenominatorSpan = result.Denominator.AsSpan();
+
+ Span parameterNumeratorSpan = parameter.Numerator.AsSpan();
+ Span parameterDenominatorSpan = parameter.Denominator.AsSpan();
+
+
+ resultNumeratorSpan[0] = FixedPointHelper.ToFloat(parameterNumeratorSpan[0], FixedPointPrecisionForParameter);
+ resultNumeratorSpan[1] = FixedPointHelper.ToFloat(parameterNumeratorSpan[1], FixedPointPrecisionForParameter);
+ resultNumeratorSpan[2] = FixedPointHelper.ToFloat(parameterNumeratorSpan[2], FixedPointPrecisionForParameter);
+
+ resultDenominatorSpan[0] = FixedPointHelper.ToFloat(parameterDenominatorSpan[0], FixedPointPrecisionForParameter);
+ resultDenominatorSpan[1] = FixedPointHelper.ToFloat(parameterDenominatorSpan[1], FixedPointPrecisionForParameter);
+
+ return result;
+ }
+
///
/// Apply a single biquad filter.
///
@@ -20,21 +128,21 @@ namespace Ryujinx.Audio.Renderer.Dsp
/// The count of samples to process
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void ProcessBiquadFilter(
- ref BiquadFilterParameter parameter,
+ ref BiquadFilterParameter2 parameter,
ref BiquadFilterState state,
Span outputBuffer,
ReadOnlySpan inputBuffer,
uint sampleCount)
{
- Span numeratorSpan = parameter.Numerator.AsSpan();
- Span denominatorSpan = parameter.Denominator.AsSpan();
+ Span numeratorSpan = parameter.Numerator.AsSpan();
+ Span 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 a0 = numeratorSpan[0];
+ float a1 = numeratorSpan[1];
+ float a2 = numeratorSpan[2];
- float b1 = FixedPointHelper.ToFloat(denominatorSpan[0], FixedPointPrecisionForParameter);
- float b2 = FixedPointHelper.ToFloat(denominatorSpan[1], FixedPointPrecisionForParameter);
+ float b1 = denominatorSpan[0];
+ float b2 = denominatorSpan[1];
for (int i = 0; i < sampleCount; i++)
{
@@ -60,22 +168,22 @@ namespace Ryujinx.Audio.Renderer.Dsp
/// Mix volume
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void ProcessBiquadFilterAndMix(
- ref BiquadFilterParameter parameter,
+ ref BiquadFilterParameter2 parameter,
ref BiquadFilterState state,
Span outputBuffer,
ReadOnlySpan inputBuffer,
uint sampleCount,
float volume)
{
- Span numeratorSpan = parameter.Numerator.AsSpan();
- Span denominatorSpan = parameter.Denominator.AsSpan();
+ Span numeratorSpan = parameter.Numerator.AsSpan();
+ Span 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 a0 = numeratorSpan[0];
+ float a1 = numeratorSpan[1];
+ float a2 = numeratorSpan[2];
- float b1 = FixedPointHelper.ToFloat(denominatorSpan[0], FixedPointPrecisionForParameter);
- float b2 = FixedPointHelper.ToFloat(denominatorSpan[1], FixedPointPrecisionForParameter);
+ float b1 = denominatorSpan[0];
+ float b2 = denominatorSpan[1];
for (int i = 0; i < sampleCount; i++)
{
@@ -105,7 +213,7 @@ namespace Ryujinx.Audio.Renderer.Dsp
/// Last filtered sample value
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static float ProcessBiquadFilterAndMixRamp(
- ref BiquadFilterParameter parameter,
+ ref BiquadFilterParameter2 parameter,
ref BiquadFilterState state,
Span outputBuffer,
ReadOnlySpan inputBuffer,
@@ -113,15 +221,15 @@ namespace Ryujinx.Audio.Renderer.Dsp
float volume,
float ramp)
{
- Span numeratorSpan = parameter.Numerator.AsSpan();
- Span denominatorSpan = parameter.Denominator.AsSpan();
+ Span numeratorSpan = parameter.Numerator.AsSpan();
+ Span 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 a0 = numeratorSpan[0];
+ float a1 = numeratorSpan[1];
+ float a2 = numeratorSpan[2];
- float b1 = FixedPointHelper.ToFloat(denominatorSpan[0], FixedPointPrecisionForParameter);
- float b2 = FixedPointHelper.ToFloat(denominatorSpan[1], FixedPointPrecisionForParameter);
+ float b1 = denominatorSpan[0];
+ float b2 = denominatorSpan[1];
float mixState = 0f;
@@ -155,7 +263,7 @@ namespace Ryujinx.Audio.Renderer.Dsp
/// The count of samples to process
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void ProcessBiquadFilter(
- ReadOnlySpan parameters,
+ ReadOnlySpan parameters,
Span states,
Span outputBuffer,
ReadOnlySpan inputBuffer,
@@ -163,19 +271,19 @@ namespace Ryujinx.Audio.Renderer.Dsp
{
for (int stageIndex = 0; stageIndex < parameters.Length; stageIndex++)
{
- BiquadFilterParameter parameter = parameters[stageIndex];
+ BiquadFilterParameter2 parameter = parameters[stageIndex];
ref BiquadFilterState state = ref states[stageIndex];
- Span numeratorSpan = parameter.Numerator.AsSpan();
- Span denominatorSpan = parameter.Denominator.AsSpan();
+ Span numeratorSpan = parameter.Numerator.AsSpan();
+ Span 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 a0 = numeratorSpan[0];
+ float a1 = numeratorSpan[1];
+ float a2 = numeratorSpan[2];
- float b1 = FixedPointHelper.ToFloat(denominatorSpan[0], FixedPointPrecisionForParameter);
- float b2 = FixedPointHelper.ToFloat(denominatorSpan[1], FixedPointPrecisionForParameter);
+ float b1 = denominatorSpan[0];
+ float b2 = denominatorSpan[1];
for (int i = 0; i < sampleCount; i++)
{
@@ -204,8 +312,8 @@ namespace Ryujinx.Audio.Renderer.Dsp
/// Mix volume
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void ProcessDoubleBiquadFilterAndMix(
- ref BiquadFilterParameter parameter0,
- ref BiquadFilterParameter parameter1,
+ ref BiquadFilterParameter2 parameter0,
+ ref BiquadFilterParameter2 parameter1,
ref BiquadFilterState state0,
ref BiquadFilterState state1,
Span outputBuffer,
@@ -213,25 +321,25 @@ namespace Ryujinx.Audio.Renderer.Dsp
uint sampleCount,
float volume)
{
- Span numerator0Span = parameter0.Numerator.AsSpan();
- Span numerator1Span = parameter1.Numerator.AsSpan();
- Span denominator0Span = parameter0.Denominator.AsSpan();
- Span denominator1Span = parameter1.Denominator.AsSpan();
+ Span numerator0Span = parameter0.Numerator.AsSpan();
+ Span numerator1Span = parameter1.Numerator.AsSpan();
+ Span denominator0Span = parameter0.Denominator.AsSpan();
+ Span 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 a00 = numerator0Span[0];
+ float a10 = numerator0Span[1];
+ float a20 = numerator0Span[2];
- float b10 = FixedPointHelper.ToFloat(denominator0Span[0], FixedPointPrecisionForParameter);
- float b20 = FixedPointHelper.ToFloat(denominator0Span[1], FixedPointPrecisionForParameter);
+ float b10 = denominator0Span[0];
+ float b20 = denominator0Span[1];
- float a01 = FixedPointHelper.ToFloat(numerator1Span[0], FixedPointPrecisionForParameter);
- float a11 = FixedPointHelper.ToFloat(numerator1Span[1], FixedPointPrecisionForParameter);
- float a21 = FixedPointHelper.ToFloat(numerator1Span[2], FixedPointPrecisionForParameter);
+ float a01 = numerator1Span[0];
+ float a11 = numerator1Span[1];
+ float a21 = numerator1Span[2];
- float b11 = FixedPointHelper.ToFloat(denominator1Span[0], FixedPointPrecisionForParameter);
- float b21 = FixedPointHelper.ToFloat(denominator1Span[1], FixedPointPrecisionForParameter);
+ float b11 = denominator1Span[0];
+ float b21 = denominator1Span[1];
for (int i = 0; i < sampleCount; i++)
{
@@ -269,8 +377,8 @@ namespace Ryujinx.Audio.Renderer.Dsp
/// Last filtered sample value
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static float ProcessDoubleBiquadFilterAndMixRamp(
- ref BiquadFilterParameter parameter0,
- ref BiquadFilterParameter parameter1,
+ ref BiquadFilterParameter2 parameter0,
+ ref BiquadFilterParameter2 parameter1,
ref BiquadFilterState state0,
ref BiquadFilterState state1,
Span outputBuffer,
@@ -279,24 +387,24 @@ namespace Ryujinx.Audio.Renderer.Dsp
float volume,
float ramp)
{
- Span numerator0Span = parameter0.Numerator.AsSpan();
- Span numerator1Span = parameter1.Numerator.AsSpan();
- Span denominator0Span = parameter0.Denominator.AsSpan();
- Span denominator1Span = parameter1.Denominator.AsSpan();
+ Span numerator0Span = parameter0.Numerator.AsSpan();
+ Span numerator1Span = parameter1.Numerator.AsSpan();
+ Span denominator0Span = parameter0.Denominator.AsSpan();
+ Span 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 a00 = numerator0Span[0];
+ float a10 = numerator0Span[1];
+ float a20 = numerator0Span[2];
- float b10 = FixedPointHelper.ToFloat(denominator0Span[0], FixedPointPrecisionForParameter);
- float b20 = FixedPointHelper.ToFloat(denominator0Span[1], FixedPointPrecisionForParameter);
+ float b10 = denominator0Span[0];
+ float b20 = denominator0Span[1];
- float a01 = FixedPointHelper.ToFloat(numerator1Span[0], FixedPointPrecisionForParameter);
- float a11 = FixedPointHelper.ToFloat(numerator1Span[1], FixedPointPrecisionForParameter);
- float a21 = FixedPointHelper.ToFloat(numerator1Span[2], FixedPointPrecisionForParameter);
+ float a01 = numerator1Span[0];
+ float a11 = numerator1Span[1];
+ float a21 = numerator1Span[2];
- float b11 = FixedPointHelper.ToFloat(denominator1Span[0], FixedPointPrecisionForParameter);
- float b21 = FixedPointHelper.ToFloat(denominator1Span[1], FixedPointPrecisionForParameter);
+ float b11 = denominator1Span[0];
+ float b21 = denominator1Span[1];
float mixState = 0f;
diff --git a/src/Ryujinx.Audio/Renderer/Dsp/Command/AdpcmDataSourceCommandVersion1.cs b/src/Ryujinx.Audio/Renderer/Dsp/Command/AdpcmDataSourceCommandVersion1.cs
index 59786c059..60161ee7a 100644
--- a/src/Ryujinx.Audio/Renderer/Dsp/Command/AdpcmDataSourceCommandVersion1.cs
+++ b/src/Ryujinx.Audio/Renderer/Dsp/Command/AdpcmDataSourceCommandVersion1.cs
@@ -2,7 +2,7 @@ using Ryujinx.Audio.Common;
using Ryujinx.Audio.Renderer.Common;
using Ryujinx.Audio.Renderer.Server.Voice;
using System;
-using static Ryujinx.Audio.Renderer.Parameter.VoiceInParameter;
+using Ryujinx.Audio.Renderer.Parameter;
using WaveBuffer = Ryujinx.Audio.Renderer.Common.WaveBuffer;
namespace Ryujinx.Audio.Renderer.Dsp.Command
@@ -24,23 +24,23 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
public WaveBuffer[] WaveBuffers { get; }
- public Memory State { get; }
+ public Memory State { get; }
public ulong AdpcmParameter { get; }
public ulong AdpcmParameterSize { get; }
public DecodingBehaviour DecodingBehaviour { get; }
- public AdpcmDataSourceCommandVersion1(ref VoiceState serverState, Memory state, ushort outputBufferIndex, int nodeId)
+ public AdpcmDataSourceCommandVersion1(ref VoiceInfo serverInfo, Memory state, ushort outputBufferIndex, int nodeId)
{
Enabled = true;
NodeId = nodeId;
OutputBufferIndex = outputBufferIndex;
- SampleRate = serverState.SampleRate;
- Pitch = serverState.Pitch;
+ SampleRate = serverInfo.SampleRate;
+ Pitch = serverInfo.Pitch;
- Span waveBufferSpan = serverState.WaveBuffers.AsSpan();
+ Span waveBufferSpan = serverInfo.WaveBuffers.AsSpan();
WaveBuffers = new WaveBuffer[Constants.VoiceWaveBufferCount];
@@ -51,10 +51,10 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
WaveBuffers[i] = voiceWaveBuffer.ToCommon(1);
}
- AdpcmParameter = serverState.DataSourceStateAddressInfo.GetReference(true);
- AdpcmParameterSize = serverState.DataSourceStateAddressInfo.Size;
+ AdpcmParameter = serverInfo.DataSourceStateAddressInfo.GetReference(true);
+ AdpcmParameterSize = serverInfo.DataSourceStateAddressInfo.Size;
State = state;
- DecodingBehaviour = serverState.DecodingBehaviour;
+ DecodingBehaviour = serverInfo.DecodingBehaviour;
}
public void Process(CommandList context)
diff --git a/src/Ryujinx.Audio/Renderer/Dsp/Command/BiquadFilterAndMixCommand.cs b/src/Ryujinx.Audio/Renderer/Dsp/Command/BiquadFilterAndMixCommand.cs
index 106fc0357..624c0d55b 100644
--- a/src/Ryujinx.Audio/Renderer/Dsp/Command/BiquadFilterAndMixCommand.cs
+++ b/src/Ryujinx.Audio/Renderer/Dsp/Command/BiquadFilterAndMixCommand.cs
@@ -18,12 +18,12 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
public ushort InputBufferIndex { get; }
public ushort OutputBufferIndex { get; }
- private BiquadFilterParameter _parameter;
+ private BiquadFilterParameter2 _parameter;
public Memory BiquadFilterState { get; }
public Memory PreviousBiquadFilterState { get; }
- public Memory State { get; }
+ public Memory State { get; }
public int LastSampleIndex { get; }
@@ -40,8 +40,8 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
uint inputBufferIndex,
uint outputBufferIndex,
int lastSampleIndex,
- Memory state,
- ref BiquadFilterParameter filter,
+ Memory state,
+ ref BiquadFilterParameter2 filter,
Memory biquadFilterState,
Memory previousBiquadFilterState,
bool needInitialization,
diff --git a/src/Ryujinx.Audio/Renderer/Dsp/Command/BiquadFilterCommand.cs b/src/Ryujinx.Audio/Renderer/Dsp/Command/BiquadFilterCommand.cs
index ac1e581f6..a8c996428 100644
--- a/src/Ryujinx.Audio/Renderer/Dsp/Command/BiquadFilterCommand.cs
+++ b/src/Ryujinx.Audio/Renderer/Dsp/Command/BiquadFilterCommand.cs
@@ -19,11 +19,11 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
public int OutputBufferIndex { get; }
public bool NeedInitialization { get; }
- private BiquadFilterParameter _parameter;
+ private BiquadFilterParameter2 _parameter;
public BiquadFilterCommand(
int baseIndex,
- ref BiquadFilterParameter filter,
+ ref BiquadFilterParameter2 filter,
Memory biquadFilterStateMemory,
int inputBufferOffset,
int outputBufferOffset,
diff --git a/src/Ryujinx.Audio/Renderer/Dsp/Command/CommandList.cs b/src/Ryujinx.Audio/Renderer/Dsp/Command/CommandList.cs
index 185d169f0..9abd6a18a 100644
--- a/src/Ryujinx.Audio/Renderer/Dsp/Command/CommandList.cs
+++ b/src/Ryujinx.Audio/Renderer/Dsp/Command/CommandList.cs
@@ -129,7 +129,7 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
{
startTime = PerformanceCounter.ElapsedNanoseconds;
}
-
+
command.Process(this);
if (shouldMeter)
diff --git a/src/Ryujinx.Audio/Renderer/Dsp/Command/CommandType.cs b/src/Ryujinx.Audio/Renderer/Dsp/Command/CommandType.cs
index de5c0ea2c..377eb6e57 100644
--- a/src/Ryujinx.Audio/Renderer/Dsp/Command/CommandType.cs
+++ b/src/Ryujinx.Audio/Renderer/Dsp/Command/CommandType.cs
@@ -12,6 +12,7 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
Volume,
VolumeRamp,
BiquadFilter,
+ BiquadFilterFloatCoeff, // new
Mix,
MixRamp,
MixRampGrouped,
@@ -31,9 +32,17 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
LimiterVersion1,
LimiterVersion2,
MultiTapBiquadFilter,
+ MultiTapBiquadFilterFloatCoeff, // new
CaptureBuffer,
Compressor,
BiquadFilterAndMix,
+ BiquadFilterAndMixFloatCoeff, // new
MultiTapBiquadFilterAndMix,
+ MultiTapBiquadFilterAndMixFloatCoef, // new
+ AuxiliaryBufferGrouped, // new
+ FillMixBuffer, // new
+ BiquadFilterCrossFade, // new
+ MultiTapBiquadFilterCrossFade, // new
+ FillBuffer, // new
}
}
diff --git a/src/Ryujinx.Audio/Renderer/Dsp/Command/DataSourceVersion2Command.cs b/src/Ryujinx.Audio/Renderer/Dsp/Command/DataSourceVersion2Command.cs
index d3d3d2418..1fbd95c32 100644
--- a/src/Ryujinx.Audio/Renderer/Dsp/Command/DataSourceVersion2Command.cs
+++ b/src/Ryujinx.Audio/Renderer/Dsp/Command/DataSourceVersion2Command.cs
@@ -2,7 +2,7 @@ using Ryujinx.Audio.Common;
using Ryujinx.Audio.Renderer.Common;
using Ryujinx.Audio.Renderer.Server.Voice;
using System;
-using static Ryujinx.Audio.Renderer.Parameter.VoiceInParameter;
+using Ryujinx.Audio.Renderer.Parameter;
using WaveBuffer = Ryujinx.Audio.Renderer.Common.WaveBuffer;
namespace Ryujinx.Audio.Renderer.Dsp.Command
@@ -24,7 +24,7 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
public WaveBuffer[] WaveBuffers { get; }
- public Memory State { get; }
+ public Memory State { get; }
public ulong ExtraParameter { get; }
public ulong ExtraParameterSize { get; }
@@ -39,21 +39,21 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
public SampleRateConversionQuality SrcQuality { get; }
- public DataSourceVersion2Command(ref VoiceState serverState, Memory state, ushort outputBufferIndex, ushort channelIndex, int nodeId)
+ public DataSourceVersion2Command(ref VoiceInfo serverInfo, Memory state, ushort outputBufferIndex, ushort channelIndex, int nodeId)
{
Enabled = true;
NodeId = nodeId;
ChannelIndex = channelIndex;
- ChannelCount = serverState.ChannelsCount;
- SampleFormat = serverState.SampleFormat;
- SrcQuality = serverState.SrcQuality;
+ ChannelCount = serverInfo.ChannelsCount;
+ SampleFormat = serverInfo.SampleFormat;
+ SrcQuality = serverInfo.SrcQuality;
CommandType = GetCommandTypeBySampleFormat(SampleFormat);
OutputBufferIndex = (ushort)(channelIndex + outputBufferIndex);
- SampleRate = serverState.SampleRate;
- Pitch = serverState.Pitch;
+ SampleRate = serverInfo.SampleRate;
+ Pitch = serverInfo.Pitch;
- Span waveBufferSpan = serverState.WaveBuffers.AsSpan();
+ Span waveBufferSpan = serverInfo.WaveBuffers.AsSpan();
WaveBuffers = new WaveBuffer[Constants.VoiceWaveBufferCount];
@@ -66,12 +66,12 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
if (SampleFormat == SampleFormat.Adpcm)
{
- ExtraParameter = serverState.DataSourceStateAddressInfo.GetReference(true);
- ExtraParameterSize = serverState.DataSourceStateAddressInfo.Size;
+ ExtraParameter = serverInfo.DataSourceStateAddressInfo.GetReference(true);
+ ExtraParameterSize = serverInfo.DataSourceStateAddressInfo.Size;
}
State = state;
- DecodingBehaviour = serverState.DecodingBehaviour;
+ DecodingBehaviour = serverInfo.DecodingBehaviour;
}
private static CommandType GetCommandTypeBySampleFormat(SampleFormat sampleFormat)
diff --git a/src/Ryujinx.Audio/Renderer/Dsp/Command/DepopPrepareCommand.cs b/src/Ryujinx.Audio/Renderer/Dsp/Command/DepopPrepareCommand.cs
index a76f690e4..18ae11eb4 100644
--- a/src/Ryujinx.Audio/Renderer/Dsp/Command/DepopPrepareCommand.cs
+++ b/src/Ryujinx.Audio/Renderer/Dsp/Command/DepopPrepareCommand.cs
@@ -17,10 +17,10 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
public ushort[] OutputBufferIndices { get; }
- public Memory State { get; }
+ public Memory State { get; }
public Memory DepopBuffer { get; }
- public DepopPrepareCommand(Memory state, Memory depopBuffer, uint mixBufferCount, uint bufferOffset, int nodeId, bool enabled)
+ public DepopPrepareCommand(Memory state, Memory depopBuffer, uint mixBufferCount, uint bufferOffset, int nodeId, bool enabled)
{
Enabled = enabled;
NodeId = nodeId;
@@ -39,7 +39,7 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
public void Process(CommandList context)
{
- ref VoiceUpdateState state = ref State.Span[0];
+ ref VoiceState state = ref State.Span[0];
Span depopBuffer = DepopBuffer.Span;
Span lastSamplesSpan = state.LastSamples.AsSpan();
diff --git a/src/Ryujinx.Audio/Renderer/Dsp/Command/DeviceSinkCommand.cs b/src/Ryujinx.Audio/Renderer/Dsp/Command/DeviceSinkCommand.cs
index 322c5d386..b0e4b3c99 100644
--- a/src/Ryujinx.Audio/Renderer/Dsp/Command/DeviceSinkCommand.cs
+++ b/src/Ryujinx.Audio/Renderer/Dsp/Command/DeviceSinkCommand.cs
@@ -42,9 +42,9 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
InputBufferIndices[i] = (ushort)(bufferOffset + inputSpan[i]);
}
- if (sink.UpsamplerState != null)
+ if (sink.UpsamplerInfo != null)
{
- Buffers = sink.UpsamplerState.OutputBuffer;
+ Buffers = sink.UpsamplerInfo.OutputBuffer;
}
else
{
diff --git a/src/Ryujinx.Audio/Renderer/Dsp/Command/FillBufferCommand.cs b/src/Ryujinx.Audio/Renderer/Dsp/Command/FillBufferCommand.cs
new file mode 100644
index 000000000..ca5428c56
--- /dev/null
+++ b/src/Ryujinx.Audio/Renderer/Dsp/Command/FillBufferCommand.cs
@@ -0,0 +1,69 @@
+using Ryujinx.Audio.Renderer.Server.Splitter;
+using System;
+using System.Runtime.CompilerServices;
+
+namespace Ryujinx.Audio.Renderer.Dsp.Command
+{
+ public class FillBufferCommand : ICommand
+ {
+ public bool Enabled { get; set; }
+
+ public int NodeId { get; }
+
+ 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 FillBufferCommand(SplitterDestinationVersion1 destination, int length, float value, int nodeId)
+ {
+ Enabled = true;
+ NodeId = nodeId;
+
+ Destination1 = destination;
+ IsV2 = false;
+ Length = length;
+ Value = value;
+ }
+
+ public FillBufferCommand(SplitterDestinationVersion2 destination, int length, float value, int nodeId)
+ {
+ Enabled = true;
+ NodeId = nodeId;
+
+ Destination2 = destination;
+ IsV2 = true;
+ Length = length;
+ Value = value;
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ private void ProcessFillBuffer()
+ {
+ if (IsV2)
+ {
+ for (int i = 0; i < Length; i++)
+ {
+ Destination2.PreviousMixBufferVolume[i] = Value;
+ }
+ }
+ else
+ {
+ for (int i = 0; i < Length; i++)
+ {
+ Destination1.PreviousMixBufferVolume[i] = Value;
+ }
+ }
+ }
+
+ public void Process(CommandList context)
+ {
+ ProcessFillBuffer();
+ }
+ }
+}
diff --git a/src/Ryujinx.Audio/Renderer/Dsp/Command/MixRampCommand.cs b/src/Ryujinx.Audio/Renderer/Dsp/Command/MixRampCommand.cs
index f77a233e1..6c5f7628c 100644
--- a/src/Ryujinx.Audio/Renderer/Dsp/Command/MixRampCommand.cs
+++ b/src/Ryujinx.Audio/Renderer/Dsp/Command/MixRampCommand.cs
@@ -20,11 +20,11 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
public float Volume0 { get; }
public float Volume1 { get; }
- public Memory State { get; }
+ public Memory State { get; }
public int LastSampleIndex { get; }
- public MixRampCommand(float volume0, float volume1, uint inputBufferIndex, uint outputBufferIndex, int lastSampleIndex, Memory state, int nodeId)
+ public MixRampCommand(float volume0, float volume1, uint inputBufferIndex, uint outputBufferIndex, int lastSampleIndex, Memory state, int nodeId)
{
Enabled = true;
NodeId = nodeId;
diff --git a/src/Ryujinx.Audio/Renderer/Dsp/Command/MixRampGroupedCommand.cs b/src/Ryujinx.Audio/Renderer/Dsp/Command/MixRampGroupedCommand.cs
index bc1f277ac..0d732c3fa 100644
--- a/src/Ryujinx.Audio/Renderer/Dsp/Command/MixRampGroupedCommand.cs
+++ b/src/Ryujinx.Audio/Renderer/Dsp/Command/MixRampGroupedCommand.cs
@@ -22,7 +22,7 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
public float[] Volume0 { get; }
public float[] Volume1 { get; }
- public Memory State { get; }
+ public Memory State { get; }
public MixRampGroupedCommand(
uint mixBufferCount,
@@ -30,7 +30,7 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
uint outputBufferIndex,
ReadOnlySpan volume0,
ReadOnlySpan volume1,
- Memory state,
+ Memory state,
int nodeId)
{
Enabled = true;
@@ -79,7 +79,7 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
public void Process(CommandList context)
{
- ref VoiceUpdateState state = ref State.Span[0];
+ ref VoiceState state = ref State.Span[0];
Span lastSamplesSpan = state.LastSamples.AsSpan();
diff --git a/src/Ryujinx.Audio/Renderer/Dsp/Command/MultiTapBiquadFilterAndMixCommand.cs b/src/Ryujinx.Audio/Renderer/Dsp/Command/MultiTapBiquadFilterAndMixCommand.cs
index e359371b4..ee28ce2fb 100644
--- a/src/Ryujinx.Audio/Renderer/Dsp/Command/MultiTapBiquadFilterAndMixCommand.cs
+++ b/src/Ryujinx.Audio/Renderer/Dsp/Command/MultiTapBiquadFilterAndMixCommand.cs
@@ -18,15 +18,15 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
public ushort InputBufferIndex { get; }
public ushort OutputBufferIndex { get; }
- private BiquadFilterParameter _parameter0;
- private BiquadFilterParameter _parameter1;
+ private BiquadFilterParameter2 _parameter0;
+ private BiquadFilterParameter2 _parameter1;
public Memory BiquadFilterState0 { get; }
public Memory BiquadFilterState1 { get; }
public Memory PreviousBiquadFilterState0 { get; }
public Memory PreviousBiquadFilterState1 { get; }
- public Memory State { get; }
+ public Memory State { get; }
public int LastSampleIndex { get; }
@@ -44,9 +44,9 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
uint inputBufferIndex,
uint outputBufferIndex,
int lastSampleIndex,
- Memory state,
- ref BiquadFilterParameter filter0,
- ref BiquadFilterParameter filter1,
+ Memory state,
+ ref BiquadFilterParameter2 filter0,
+ ref BiquadFilterParameter2 filter1,
Memory biquadFilterState0,
Memory biquadFilterState1,
Memory previousBiquadFilterState0,
diff --git a/src/Ryujinx.Audio/Renderer/Dsp/Command/MultiTapBiquadFilterCommand.cs b/src/Ryujinx.Audio/Renderer/Dsp/Command/MultiTapBiquadFilterCommand.cs
index e159f8ef7..84998056f 100644
--- a/src/Ryujinx.Audio/Renderer/Dsp/Command/MultiTapBiquadFilterCommand.cs
+++ b/src/Ryujinx.Audio/Renderer/Dsp/Command/MultiTapBiquadFilterCommand.cs
@@ -14,13 +14,13 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
public uint EstimatedProcessingTime { get; set; }
- private readonly BiquadFilterParameter[] _parameters;
+ private readonly BiquadFilterParameter2[] _parameters;
private readonly Memory _biquadFilterStates;
private readonly int _inputBufferIndex;
private readonly int _outputBufferIndex;
private readonly bool[] _isInitialized;
- public MultiTapBiquadFilterCommand(int baseIndex, ReadOnlySpan filters, Memory biquadFilterStateMemory, int inputBufferOffset, int outputBufferOffset, ReadOnlySpan isInitialized, int nodeId)
+ public MultiTapBiquadFilterCommand(int baseIndex, ReadOnlySpan filters, Memory biquadFilterStateMemory, int inputBufferOffset, int outputBufferOffset, ReadOnlySpan isInitialized, int nodeId)
{
_parameters = filters.ToArray();
_biquadFilterStates = biquadFilterStateMemory;
diff --git a/src/Ryujinx.Audio/Renderer/Dsp/Command/PcmFloatDataSourceCommandVersion1.cs b/src/Ryujinx.Audio/Renderer/Dsp/Command/PcmFloatDataSourceCommandVersion1.cs
index 2b5f0de72..d54158541 100644
--- a/src/Ryujinx.Audio/Renderer/Dsp/Command/PcmFloatDataSourceCommandVersion1.cs
+++ b/src/Ryujinx.Audio/Renderer/Dsp/Command/PcmFloatDataSourceCommandVersion1.cs
@@ -2,7 +2,7 @@ using Ryujinx.Audio.Common;
using Ryujinx.Audio.Renderer.Common;
using Ryujinx.Audio.Renderer.Server.Voice;
using System;
-using static Ryujinx.Audio.Renderer.Parameter.VoiceInParameter;
+using Ryujinx.Audio.Renderer.Parameter;
using WaveBuffer = Ryujinx.Audio.Renderer.Common.WaveBuffer;
namespace Ryujinx.Audio.Renderer.Dsp.Command
@@ -27,23 +27,23 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
public WaveBuffer[] WaveBuffers { get; }
- public Memory State { get; }
+ public Memory State { get; }
public DecodingBehaviour DecodingBehaviour { get; }
- public PcmFloatDataSourceCommandVersion1(ref VoiceState serverState, Memory state, ushort outputBufferIndex, ushort channelIndex, int nodeId)
+ public PcmFloatDataSourceCommandVersion1(ref VoiceInfo serverInfo, Memory state, ushort outputBufferIndex, ushort channelIndex, int nodeId)
{
Enabled = true;
NodeId = nodeId;
OutputBufferIndex = (ushort)(channelIndex + outputBufferIndex);
- SampleRate = serverState.SampleRate;
+ SampleRate = serverInfo.SampleRate;
ChannelIndex = channelIndex;
- ChannelCount = serverState.ChannelsCount;
- Pitch = serverState.Pitch;
+ ChannelCount = serverInfo.ChannelsCount;
+ Pitch = serverInfo.Pitch;
WaveBuffers = new WaveBuffer[Constants.VoiceWaveBufferCount];
- Span waveBufferSpan = serverState.WaveBuffers.AsSpan();
+ Span waveBufferSpan = serverInfo.WaveBuffers.AsSpan();
for (int i = 0; i < WaveBuffers.Length; i++)
{
@@ -53,7 +53,7 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
}
State = state;
- DecodingBehaviour = serverState.DecodingBehaviour;
+ DecodingBehaviour = serverInfo.DecodingBehaviour;
}
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 9c30de41d..91619d80f 100644
--- a/src/Ryujinx.Audio/Renderer/Dsp/Command/PcmInt16DataSourceCommandVersion1.cs
+++ b/src/Ryujinx.Audio/Renderer/Dsp/Command/PcmInt16DataSourceCommandVersion1.cs
@@ -2,7 +2,7 @@ using Ryujinx.Audio.Common;
using Ryujinx.Audio.Renderer.Common;
using Ryujinx.Audio.Renderer.Server.Voice;
using System;
-using static Ryujinx.Audio.Renderer.Parameter.VoiceInParameter;
+using Ryujinx.Audio.Renderer.Parameter;
using WaveBuffer = Ryujinx.Audio.Renderer.Common.WaveBuffer;
namespace Ryujinx.Audio.Renderer.Dsp.Command
@@ -27,23 +27,23 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
public WaveBuffer[] WaveBuffers { get; }
- public Memory State { get; }
+ public Memory State { get; }
public DecodingBehaviour DecodingBehaviour { get; }
- public PcmInt16DataSourceCommandVersion1(ref VoiceState serverState, Memory state, ushort outputBufferIndex, ushort channelIndex, int nodeId)
+ public PcmInt16DataSourceCommandVersion1(ref VoiceInfo serverInfo, Memory state, ushort outputBufferIndex, ushort channelIndex, int nodeId)
{
Enabled = true;
NodeId = nodeId;
OutputBufferIndex = (ushort)(channelIndex + outputBufferIndex);
- SampleRate = serverState.SampleRate;
+ SampleRate = serverInfo.SampleRate;
ChannelIndex = channelIndex;
- ChannelCount = serverState.ChannelsCount;
- Pitch = serverState.Pitch;
+ ChannelCount = serverInfo.ChannelsCount;
+ Pitch = serverInfo.Pitch;
WaveBuffers = new WaveBuffer[Constants.VoiceWaveBufferCount];
- Span waveBufferSpan = serverState.WaveBuffers.AsSpan();
+ Span waveBufferSpan = serverInfo.WaveBuffers.AsSpan();
for (int i = 0; i < WaveBuffers.Length; i++)
{
@@ -53,7 +53,7 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
}
State = state;
- DecodingBehaviour = serverState.DecodingBehaviour;
+ DecodingBehaviour = serverInfo.DecodingBehaviour;
}
public void Process(CommandList context)
diff --git a/src/Ryujinx.Audio/Renderer/Dsp/Command/UpsampleCommand.cs b/src/Ryujinx.Audio/Renderer/Dsp/Command/UpsampleCommand.cs
index 8882500cd..5d23addae 100644
--- a/src/Ryujinx.Audio/Renderer/Dsp/Command/UpsampleCommand.cs
+++ b/src/Ryujinx.Audio/Renderer/Dsp/Command/UpsampleCommand.cs
@@ -18,11 +18,11 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
public uint InputSampleCount { get; }
public uint InputSampleRate { get; }
- public UpsamplerState UpsamplerInfo { get; }
+ public UpsamplerInfo UpsamplerInfo { get; }
public Memory OutBuffer { get; }
- public UpsampleCommand(uint bufferOffset, UpsamplerState info, uint inputCount, Span inputBufferOffset, uint bufferCount, uint sampleCount, uint sampleRate, int nodeId)
+ public UpsampleCommand(uint bufferOffset, UpsamplerInfo info, uint inputCount, Span inputBufferOffset, uint bufferCount, uint sampleCount, uint sampleRate, int nodeId)
{
Enabled = true;
NodeId = nodeId;
diff --git a/src/Ryujinx.Audio/Renderer/Dsp/DataSourceHelper.cs b/src/Ryujinx.Audio/Renderer/Dsp/DataSourceHelper.cs
index 130836c6b..9e4e04890 100644
--- a/src/Ryujinx.Audio/Renderer/Dsp/DataSourceHelper.cs
+++ b/src/Ryujinx.Audio/Renderer/Dsp/DataSourceHelper.cs
@@ -10,7 +10,7 @@ using System.Runtime.InteropServices;
using System.Runtime.Intrinsics;
using System.Runtime.Intrinsics.Arm;
using System.Runtime.Intrinsics.X86;
-using static Ryujinx.Audio.Renderer.Parameter.VoiceInParameter;
+using Ryujinx.Audio.Renderer.Parameter;
namespace Ryujinx.Audio.Renderer.Dsp
{
@@ -42,7 +42,7 @@ namespace Ryujinx.Audio.Renderer.Dsp
};
}
- public static void ProcessWaveBuffers(IVirtualMemoryManager memoryManager, Span outputBuffer, ref WaveBufferInformation info, Span wavebuffers, ref VoiceUpdateState voiceState, uint targetSampleRate, int sampleCount)
+ public static void ProcessWaveBuffers(IVirtualMemoryManager memoryManager, Span outputBuffer, ref WaveBufferInformation info, Span wavebuffers, ref VoiceState voiceState, uint targetSampleRate, int sampleCount)
{
const int TempBufferSize = 0x3F00;
diff --git a/src/Ryujinx.Audio/Renderer/Dsp/ResamplerHelper.cs b/src/Ryujinx.Audio/Renderer/Dsp/ResamplerHelper.cs
index 16048d7ff..0de34101e 100644
--- a/src/Ryujinx.Audio/Renderer/Dsp/ResamplerHelper.cs
+++ b/src/Ryujinx.Audio/Renderer/Dsp/ResamplerHelper.cs
@@ -3,7 +3,7 @@ using System.Linq;
using System.Runtime.CompilerServices;
using System.Runtime.Intrinsics;
using System.Runtime.Intrinsics.X86;
-using static Ryujinx.Audio.Renderer.Parameter.VoiceInParameter;
+using Ryujinx.Audio.Renderer.Parameter;
namespace Ryujinx.Audio.Renderer.Dsp
{
diff --git a/src/Ryujinx.Audio/Renderer/Parameter/AudioRendererConfiguration.cs b/src/Ryujinx.Audio/Renderer/Parameter/AudioRendererConfiguration.cs
index 491a05c86..c70e16544 100644
--- a/src/Ryujinx.Audio/Renderer/Parameter/AudioRendererConfiguration.cs
+++ b/src/Ryujinx.Audio/Renderer/Parameter/AudioRendererConfiguration.cs
@@ -1,3 +1,4 @@
+using Ryujinx.Audio.Renderer.Server;
using Ryujinx.Audio.Renderer.Server.Types;
using System.Runtime.InteropServices;
@@ -93,7 +94,7 @@ namespace Ryujinx.Audio.Renderer.Parameter
///
/// The user audio revision
///
- ///
+ ///
public int Revision;
}
}
diff --git a/src/Ryujinx.Audio/Renderer/Parameter/BiquadFilterParameter.cs b/src/Ryujinx.Audio/Renderer/Parameter/BiquadFilterParameter1.cs
similarity index 95%
rename from src/Ryujinx.Audio/Renderer/Parameter/BiquadFilterParameter.cs
rename to src/Ryujinx.Audio/Renderer/Parameter/BiquadFilterParameter1.cs
index f1492b0b1..5a3091f62 100644
--- a/src/Ryujinx.Audio/Renderer/Parameter/BiquadFilterParameter.cs
+++ b/src/Ryujinx.Audio/Renderer/Parameter/BiquadFilterParameter1.cs
@@ -7,7 +7,7 @@ namespace Ryujinx.Audio.Renderer.Parameter
/// Biquad filter parameters.
///
[StructLayout(LayoutKind.Sequential, Size = 0xC, Pack = 1)]
- public struct BiquadFilterParameter
+ public struct BiquadFilterParameter1
{
///
/// Set to true if the biquad filter is active.
diff --git a/src/Ryujinx.Audio/Renderer/Parameter/BiquadFilterParameter2.cs b/src/Ryujinx.Audio/Renderer/Parameter/BiquadFilterParameter2.cs
new file mode 100644
index 000000000..8e47b22e0
--- /dev/null
+++ b/src/Ryujinx.Audio/Renderer/Parameter/BiquadFilterParameter2.cs
@@ -0,0 +1,36 @@
+using Ryujinx.Common.Memory;
+using System.Runtime.InteropServices;
+
+namespace Ryujinx.Audio.Renderer.Parameter
+{
+ ///
+ /// Biquad filter parameters.
+ ///
+ [StructLayout(LayoutKind.Sequential, Size = 0x18, Pack = 1)]
+ public struct BiquadFilterParameter2
+ {
+ ///
+ /// Set to true if the biquad filter is active.
+ ///
+ [MarshalAs(UnmanagedType.I1)]
+ public bool Enable;
+
+ ///
+ /// Reserved/padding.
+ ///
+ private readonly byte _reserved1;
+ private readonly byte _reserved2;
+ private readonly byte _reserved3;
+
+ ///
+ /// Biquad filter numerator (b0, b1, b2).
+ ///
+ public Array3 Numerator;
+
+ ///
+ /// Biquad filter denominator (a1, a2).
+ ///
+ /// a0 = 1
+ public Array2 Denominator;
+ }
+}
diff --git a/src/Ryujinx.Audio/Renderer/Parameter/Effect/BiquadFilterEffectParameter.cs b/src/Ryujinx.Audio/Renderer/Parameter/Effect/BiquadFilterEffectParameter1.cs
similarity index 96%
rename from src/Ryujinx.Audio/Renderer/Parameter/Effect/BiquadFilterEffectParameter.cs
rename to src/Ryujinx.Audio/Renderer/Parameter/Effect/BiquadFilterEffectParameter1.cs
index b12a941a5..443b257be 100644
--- a/src/Ryujinx.Audio/Renderer/Parameter/Effect/BiquadFilterEffectParameter.cs
+++ b/src/Ryujinx.Audio/Renderer/Parameter/Effect/BiquadFilterEffectParameter1.cs
@@ -8,7 +8,7 @@ namespace Ryujinx.Audio.Renderer.Parameter.Effect
/// for .
///
[StructLayout(LayoutKind.Sequential, Pack = 1)]
- public struct BiquadFilterEffectParameter
+ public struct BiquadFilterEffectParameter1
{
///
/// The input channel indices that will be used by the .
diff --git a/src/Ryujinx.Audio/Renderer/Parameter/Effect/BiquadFilterEffectParameter2.cs b/src/Ryujinx.Audio/Renderer/Parameter/Effect/BiquadFilterEffectParameter2.cs
new file mode 100644
index 000000000..0c74f1e7b
--- /dev/null
+++ b/src/Ryujinx.Audio/Renderer/Parameter/Effect/BiquadFilterEffectParameter2.cs
@@ -0,0 +1,49 @@
+using Ryujinx.Audio.Renderer.Server.Effect;
+using Ryujinx.Common.Memory;
+using System.Runtime.InteropServices;
+
+namespace Ryujinx.Audio.Renderer.Parameter.Effect
+{
+ ///
+ /// for .
+ ///
+ [StructLayout(LayoutKind.Sequential, Pack = 1)]
+ public struct BiquadFilterEffectParameter2
+ {
+ ///
+ /// The input channel indices that will be used by the .
+ ///
+ public Array6 Input;
+
+ ///
+ /// The output channel indices that will be used by the .
+ ///
+ public Array6 Output;
+
+ ///
+ /// Biquad filter numerator (b0, b1, b2).
+ ///
+ public Array3 Numerator;
+
+ ///
+ /// Biquad filter denominator (a1, a2).
+ ///
+ /// a0 = 1
+ public Array2 Denominator;
+
+ ///
+ /// The total channel count used.
+ ///
+ public byte ChannelCount;
+
+ ///
+ /// The current usage status of the effect on the client side.
+ ///
+ public UsageState Status;
+
+ ///
+ /// Reserved/unused.
+ ///
+ private readonly ushort _reserved;
+ }
+}
diff --git a/src/Ryujinx.Audio/Renderer/Parameter/EffectInParameterVersion3.cs b/src/Ryujinx.Audio/Renderer/Parameter/EffectInParameterVersion3.cs
new file mode 100644
index 000000000..2cf4911a6
--- /dev/null
+++ b/src/Ryujinx.Audio/Renderer/Parameter/EffectInParameterVersion3.cs
@@ -0,0 +1,97 @@
+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/Parameter/ISplitterDestinationInParameter.cs b/src/Ryujinx.Audio/Renderer/Parameter/ISplitterDestinationInParameter.cs
index 7ee49f11a..c3224c57d 100644
--- a/src/Ryujinx.Audio/Renderer/Parameter/ISplitterDestinationInParameter.cs
+++ b/src/Ryujinx.Audio/Renderer/Parameter/ISplitterDestinationInParameter.cs
@@ -17,11 +17,11 @@ namespace Ryujinx.Audio.Renderer.Parameter
/// The mix to output the result of the splitter.
///
int DestinationId { get; }
-
+
///
/// Biquad filter parameters.
///
- Array2 BiquadFilters { get; }
+ Array2 BiquadFilters2 { get; }
///
/// Set to true if in use.
diff --git a/src/Ryujinx.Audio/Renderer/Parameter/SinkInParameter.cs b/src/Ryujinx.Audio/Renderer/Parameter/SinkInParameter.cs
index 3c1ac09c0..86ceea30a 100644
--- a/src/Ryujinx.Audio/Renderer/Parameter/SinkInParameter.cs
+++ b/src/Ryujinx.Audio/Renderer/Parameter/SinkInParameter.cs
@@ -25,7 +25,7 @@ namespace Ryujinx.Audio.Renderer.Parameter
///
/// Reserved/padding.
///
- private readonly ushort _reserved1;
+ private readonly ushort _magic; // 0xCAFE
///
/// The node id of the sink.
diff --git a/src/Ryujinx.Audio/Renderer/Parameter/SplitterDestinationInParameterVersion1.cs b/src/Ryujinx.Audio/Renderer/Parameter/SplitterDestinationInParameterVersion1.cs
index f346efcb0..fbc036806 100644
--- a/src/Ryujinx.Audio/Renderer/Parameter/SplitterDestinationInParameterVersion1.cs
+++ b/src/Ryujinx.Audio/Renderer/Parameter/SplitterDestinationInParameterVersion1.cs
@@ -60,8 +60,8 @@ namespace Ryujinx.Audio.Renderer.Parameter
readonly int ISplitterDestinationInParameter.Id => Id;
readonly int ISplitterDestinationInParameter.DestinationId => DestinationId;
-
- readonly Array2 ISplitterDestinationInParameter.BiquadFilters => default;
+
+ readonly Array2 ISplitterDestinationInParameter.BiquadFilters2 => default;
readonly bool ISplitterDestinationInParameter.IsUsed => IsUsed;
readonly bool ISplitterDestinationInParameter.ResetPrevVolume => ResetPrevVolume;
diff --git a/src/Ryujinx.Audio/Renderer/Parameter/SplitterDestinationInParameterVersion2a.cs b/src/Ryujinx.Audio/Renderer/Parameter/SplitterDestinationInParameterVersion2a.cs
new file mode 100644
index 000000000..4270b5e20
--- /dev/null
+++ b/src/Ryujinx.Audio/Renderer/Parameter/SplitterDestinationInParameterVersion2a.cs
@@ -0,0 +1,100 @@
+using Ryujinx.Audio.Renderer.Dsp;
+using Ryujinx.Common.Memory;
+using Ryujinx.Common.Utilities;
+using System;
+using System.Runtime.InteropServices;
+
+namespace Ryujinx.Audio.Renderer.Parameter
+{
+ ///
+ /// Input header for a splitter destination version 2 update.
+ ///
+ [StructLayout(LayoutKind.Sequential, Pack = 1)]
+ public struct SplitterDestinationInParameterVersion2a : ISplitterDestinationInParameter
+ {
+ ///
+ /// Magic of the input header.
+ ///
+ public uint Magic;
+
+ ///
+ /// Target splitter destination data id.
+ ///
+ public int Id;
+
+ ///
+ /// Mix buffer volumes storage.
+ ///
+ private MixArray _mixBufferVolume;
+
+ ///
+ /// The mix to output the result of the splitter.
+ ///
+ public int DestinationId;
+
+ ///
+ /// Biquad filter parameters.
+ ///
+ public Array2 BiquadFilters;
+
+ ///
+ /// Set to true if in use.
+ ///
+ [MarshalAs(UnmanagedType.I1)]
+ public bool IsUsed;
+
+ ///
+ /// Set to true to force resetting the previous mix volumes.
+ ///
+ [MarshalAs(UnmanagedType.I1)]
+ public bool ResetPrevVolume;
+
+ ///
+ /// Reserved/padding.
+ ///
+ private unsafe fixed byte _reserved[10];
+
+ [StructLayout(LayoutKind.Sequential, Size = sizeof(float) * Constants.MixBufferCountMax, Pack = 1)]
+ private struct MixArray { }
+
+ ///
+ /// Mix buffer volumes.
+ ///
+ /// Used when a splitter id is specified in the mix.
+ public Span MixBufferVolume => SpanHelpers.AsSpan(ref _mixBufferVolume);
+
+ readonly int ISplitterDestinationInParameter.Id => Id;
+
+ readonly int ISplitterDestinationInParameter.DestinationId => DestinationId;
+
+ readonly Array2 ISplitterDestinationInParameter.BiquadFilters2
+ {
+ get
+ {
+ Array2 newFilters = new();
+ Span newFiltersSpan = newFilters.AsSpan();
+ newFiltersSpan[0] = BiquadFilterHelper.ToBiquadFilterParameter2(BiquadFilters[0]);
+ newFiltersSpan[1] = BiquadFilterHelper.ToBiquadFilterParameter2(BiquadFilters[1]);
+
+ return newFilters;
+ }
+ }
+
+ readonly bool ISplitterDestinationInParameter.IsUsed => IsUsed;
+ readonly bool ISplitterDestinationInParameter.ResetPrevVolume => ResetPrevVolume;
+
+ ///
+ /// The expected constant of any input header.
+ ///
+ private const uint ValidMagic = 0x44444E53;
+
+ ///
+ /// Check if the magic is valid.
+ ///
+ /// Returns true if the magic is valid.
+ public readonly bool IsMagicValid()
+ {
+ return Magic == ValidMagic;
+ }
+ }
+}
diff --git a/src/Ryujinx.Audio/Renderer/Parameter/SplitterDestinationInParameterVersion2.cs b/src/Ryujinx.Audio/Renderer/Parameter/SplitterDestinationInParameterVersion2b.cs
similarity index 90%
rename from src/Ryujinx.Audio/Renderer/Parameter/SplitterDestinationInParameterVersion2.cs
rename to src/Ryujinx.Audio/Renderer/Parameter/SplitterDestinationInParameterVersion2b.cs
index 1d867919d..81e9d823b 100644
--- a/src/Ryujinx.Audio/Renderer/Parameter/SplitterDestinationInParameterVersion2.cs
+++ b/src/Ryujinx.Audio/Renderer/Parameter/SplitterDestinationInParameterVersion2b.cs
@@ -9,7 +9,7 @@ namespace Ryujinx.Audio.Renderer.Parameter
/// Input header for a splitter destination version 2 update.
///
[StructLayout(LayoutKind.Sequential, Pack = 1)]
- public struct SplitterDestinationInParameterVersion2 : ISplitterDestinationInParameter
+ public struct SplitterDestinationInParameterVersion2b : ISplitterDestinationInParameter
{
///
/// Magic of the input header.
@@ -34,7 +34,7 @@ namespace Ryujinx.Audio.Renderer.Parameter
///
/// Biquad filter parameters.
///
- public Array2 BiquadFilters;
+ public Array2 BiquadFilters;
///
/// Set to true if in use.
@@ -66,7 +66,7 @@ namespace Ryujinx.Audio.Renderer.Parameter
readonly int ISplitterDestinationInParameter.DestinationId => DestinationId;
- readonly Array2 ISplitterDestinationInParameter.BiquadFilters => BiquadFilters;
+ readonly Array2 ISplitterDestinationInParameter.BiquadFilters2 => BiquadFilters;
readonly bool ISplitterDestinationInParameter.IsUsed => IsUsed;
readonly bool ISplitterDestinationInParameter.ResetPrevVolume => ResetPrevVolume;
diff --git a/src/Ryujinx.Audio/Renderer/Parameter/VoiceInParameter.cs b/src/Ryujinx.Audio/Renderer/Parameter/VoiceInParameter1.cs
similarity index 98%
rename from src/Ryujinx.Audio/Renderer/Parameter/VoiceInParameter.cs
rename to src/Ryujinx.Audio/Renderer/Parameter/VoiceInParameter1.cs
index f33d82aa0..a3633edbd 100644
--- a/src/Ryujinx.Audio/Renderer/Parameter/VoiceInParameter.cs
+++ b/src/Ryujinx.Audio/Renderer/Parameter/VoiceInParameter1.cs
@@ -12,7 +12,7 @@ namespace Ryujinx.Audio.Renderer.Parameter
/// Input information for a voice.
///
[StructLayout(LayoutKind.Sequential, Size = 0x170, Pack = 1)]
- public struct VoiceInParameter
+ public struct VoiceInParameter1
{
///
/// Id of the voice.
@@ -79,7 +79,7 @@ namespace Ryujinx.Audio.Renderer.Parameter
///
/// Biquad filters to apply to the output of the voice.
///
- public Array2 BiquadFilters;
+ public Array2 BiquadFilters;
///
/// Total count of of the voice.
@@ -171,8 +171,9 @@ namespace Ryujinx.Audio.Renderer.Parameter
/// Reserved/unused.
///
private unsafe fixed uint _reserved3[2];
-
- ///
+ }
+
+ ///
/// Input information for a voice wavebuffer.
///
[StructLayout(LayoutKind.Sequential, Size = 0x38, Pack = 1)]
@@ -328,5 +329,4 @@ namespace Ryujinx.Audio.Renderer.Parameter
///
Low,
}
- }
}
diff --git a/src/Ryujinx.Audio/Renderer/Parameter/VoiceInParameter2.cs b/src/Ryujinx.Audio/Renderer/Parameter/VoiceInParameter2.cs
new file mode 100644
index 000000000..78e47b69a
--- /dev/null
+++ b/src/Ryujinx.Audio/Renderer/Parameter/VoiceInParameter2.cs
@@ -0,0 +1,176 @@
+using Ryujinx.Audio.Common;
+using Ryujinx.Audio.Renderer.Common;
+using Ryujinx.Audio.Renderer.Dsp;
+using Ryujinx.Common.Memory;
+using System;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+namespace Ryujinx.Audio.Renderer.Parameter
+{
+ ///
+ /// Input information for a voice.
+ ///
+ [StructLayout(LayoutKind.Sequential, Size = 0x188, Pack = 1)]
+ public struct VoiceInParameter2
+ {
+ ///
+ /// Id of the voice.
+ ///
+ public int Id;
+
+ ///
+ /// Node id of the voice.
+ ///
+ public int NodeId;
+
+ ///
+ /// Set to true if the voice is new.
+ ///
+ [MarshalAs(UnmanagedType.I1)]
+ public bool IsNew;
+
+ ///
+ /// Set to true if the voice is used.
+ ///
+ [MarshalAs(UnmanagedType.I1)]
+ public bool InUse;
+
+ ///
+ /// The voice wanted by the user.
+ ///
+ public PlayState PlayState;
+
+ ///
+ /// The of the voice.
+ ///
+ public SampleFormat SampleFormat;
+
+ ///
+ /// The sample rate of the voice.
+ ///
+ public uint SampleRate;
+
+ ///
+ /// The priority of the voice.
+ ///
+ public uint Priority;
+
+ ///
+ /// Target sorting position of the voice. (Used to sort voices with the same )
+ ///
+ public uint SortingOrder;
+
+ ///
+ /// The total channel count used.
+ ///
+ public uint ChannelCount;
+
+ ///
+ /// The pitch used on the voice.
+ ///
+ public float Pitch;
+
+ ///
+ /// The output volume of the voice.
+ ///
+ public float Volume;
+
+ ///
+ /// Biquad filters to apply to the output of the voice.
+ ///
+ public Array2 BiquadFilters;
+
+ ///
+ /// Total count of of the voice.
+ ///
+ public uint WaveBuffersCount;
+
+ ///
+ /// Current playing of the voice.
+ ///
+ public uint WaveBuffersIndex;
+
+ ///
+ /// Reserved/unused.
+ ///
+ private readonly uint
+ _reserved1;
+
+ ///
+ /// User state address required by the data source.
+ ///
+ /// Only used for as the address of the GC-ADPCM coefficients.
+ public ulong DataSourceStateAddress;
+
+ ///
+ /// User state size required by the data source.
+ ///
+ /// Only used for as the size of the GC-ADPCM coefficients.
+ public ulong DataSourceStateSize;
+
+ ///
+ /// The target mix id of the voice.
+ ///
+ public int MixId;
+
+ ///
+ /// The target splitter id of the voice.
+ ///
+ public uint SplitterId;
+
+ ///
+ /// The wavebuffer parameters of this voice.
+ ///
+ public Array4 WaveBuffers;
+
+ ///
+ /// The channel resource ids associated to the voice.
+ ///
+ public Array6 ChannelResourceIds;
+
+ ///
+ /// Reset the voice drop flag during voice server update.
+ ///
+ [MarshalAs(UnmanagedType.I1)]
+ public bool ResetVoiceDropFlag;
+
+ ///
+ /// Flush the amount of wavebuffer specified. This will result in the wavebuffer being skipped and marked played.
+ ///
+ /// This was added on REV5.
+ public byte FlushWaveBufferCount;
+
+ ///
+ /// Reserved/unused.
+ ///
+ private readonly ushort _reserved2;
+
+ ///
+ /// Change the behaviour of the voice.
+ ///
+ /// This was added on REV5.
+ public DecodingBehaviour DecodingBehaviourFlags;
+
+ ///
+ /// Change the Sample Rate Conversion (SRC) quality of the voice.
+ ///
+ /// This was added on REV8.
+ public SampleRateConversionQuality SrcQuality;
+
+ ///
+ /// This was previously used for opus codec support on the Audio Renderer and was removed on REV3.
+ ///
+ public uint ExternalContext;
+
+ ///
+ /// This was previously used for opus codec support on the Audio Renderer and was removed on REV3.
+ ///
+ public uint ExternalContextSize;
+
+ ///
+ /// Reserved/unused.
+ ///
+ private unsafe fixed uint _reserved3[2];
+ }
+}
diff --git a/src/Ryujinx.Audio/Renderer/Parameter/VoiceOutStatus.cs b/src/Ryujinx.Audio/Renderer/Parameter/VoiceOutStatus.cs
index a7c749835..0ec864cdc 100644
--- a/src/Ryujinx.Audio/Renderer/Parameter/VoiceOutStatus.cs
+++ b/src/Ryujinx.Audio/Renderer/Parameter/VoiceOutStatus.cs
@@ -1,3 +1,5 @@
+using Ryujinx.Audio.Renderer.Common;
+using Ryujinx.Audio.Renderer.Server;
using System.Runtime.InteropServices;
namespace Ryujinx.Audio.Renderer.Parameter
@@ -5,7 +7,7 @@ namespace Ryujinx.Audio.Renderer.Parameter
///
/// Output information about a voice.
///
- /// See
+ /// See
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct VoiceOutStatus
{
@@ -13,7 +15,7 @@ namespace Ryujinx.Audio.Renderer.Parameter
/// The total amount of samples that was played.
///
/// This is reset to 0 when a finishes playing and is set.
- /// This is reset to 0 when looping while is set.
+ /// This is reset to 0 when looping while is set.
public ulong PlayedSampleCount;
///
diff --git a/src/Ryujinx.Audio/Renderer/Server/AudioRenderSystem.cs b/src/Ryujinx.Audio/Renderer/Server/AudioRenderSystem.cs
index ee2f23479..188af8640 100644
--- a/src/Ryujinx.Audio/Renderer/Server/AudioRenderSystem.cs
+++ b/src/Ryujinx.Audio/Renderer/Server/AudioRenderSystem.cs
@@ -31,7 +31,7 @@ namespace Ryujinx.Audio.Renderer.Server
private AudioRendererRenderingDevice _renderingDevice;
private AudioRendererExecutionMode _executionMode;
private readonly IWritableEvent _systemEvent;
- private MemoryPoolState _dspMemoryPoolState;
+ private MemoryPoolInfo _dspMemoryPoolInfo;
private readonly VoiceContext _voiceContext;
private readonly MixContext _mixContext;
private readonly SinkContext _sinkContext;
@@ -40,13 +40,13 @@ namespace Ryujinx.Audio.Renderer.Server
private PerformanceManager _performanceManager;
private UpsamplerManager _upsamplerManager;
private bool _isActive;
- private BehaviourContext _behaviourContext;
+ private BehaviourInfo _behaviourInfo;
#pragma warning disable IDE0052 // Remove unread private member
private ulong _totalElapsedTicksUpdating;
private ulong _totalElapsedTicks;
#pragma warning restore IDE0052
private int _sessionId;
- private Memory _memoryPools;
+ private Memory _memoryPools;
private uint _sampleRate;
private uint _sampleCount;
@@ -84,7 +84,7 @@ namespace Ryujinx.Audio.Renderer.Server
public AudioRenderSystem(AudioRendererManager manager, IWritableEvent systemEvent)
{
_manager = manager;
- _dspMemoryPoolState = MemoryPoolState.Create(MemoryPoolState.LocationType.Dsp);
+ _dspMemoryPoolInfo = MemoryPoolInfo.Create(MemoryPoolInfo.LocationType.Dsp);
_voiceContext = new VoiceContext();
_mixContext = new MixContext();
_sinkContext = new SinkContext();
@@ -93,7 +93,7 @@ namespace Ryujinx.Audio.Renderer.Server
_commandProcessingTimeEstimator = null;
_systemEvent = systemEvent;
- _behaviourContext = new BehaviourContext();
+ _behaviourInfo = new BehaviourInfo();
_totalElapsedTicksUpdating = 0;
_sessionId = 0;
@@ -110,7 +110,7 @@ namespace Ryujinx.Audio.Renderer.Server
ulong appletResourceId,
IVirtualMemoryManager memoryManager)
{
- if (!BehaviourContext.CheckValidRevision(parameter.Revision))
+ if (!BehaviourInfo.CheckValidRevision(parameter.Revision))
{
return ResultCode.OperationFailed;
}
@@ -122,9 +122,9 @@ namespace Ryujinx.Audio.Renderer.Server
Debug.Assert(parameter.RenderingDevice == AudioRendererRenderingDevice.Dsp && parameter.ExecutionMode == AudioRendererExecutionMode.Auto);
- Logger.Info?.Print(LogClass.AudioRenderer, $"Initializing with REV{BehaviourContext.GetRevisionNumber(parameter.Revision)}");
+ Logger.Info?.Print(LogClass.AudioRenderer, $"Initializing with REV{BehaviourInfo.GetRevisionNumber(parameter.Revision)}");
- _behaviourContext.SetUserRevision(parameter.Revision);
+ _behaviourInfo.SetUserRevision(parameter.Revision);
_sampleRate = parameter.SampleRate;
_sampleCount = parameter.SampleCount;
@@ -151,7 +151,7 @@ namespace Ryujinx.Audio.Renderer.Server
workBufferAllocator = new WorkBufferAllocator(workBufferMemory);
PoolMapper poolMapper = new(processHandle, false);
- poolMapper.InitializeSystemPool(ref _dspMemoryPoolState, workBuffer, workBufferSize);
+ poolMapper.InitializeSystemPool(ref _dspMemoryPoolInfo, workBuffer, workBufferSize);
_mixBuffer = workBufferAllocator.Allocate(_sampleCount * (_voiceChannelCountMax + _mixBufferCount), 0x10);
@@ -176,7 +176,7 @@ namespace Ryujinx.Audio.Renderer.Server
Memory splitterBqfStates = Memory.Empty;
- if (_behaviourContext.IsBiquadFilterParameterForSplitterEnabled() &&
+ if (_behaviourInfo.IsBiquadFilterParameterForSplitterEnabled() &&
parameter.SplitterCount > 0 &&
parameter.SplitterDestinationCount > 0)
{
@@ -191,23 +191,23 @@ namespace Ryujinx.Audio.Renderer.Server
}
// Invalidate DSP cache on what was currently allocated with workBuffer.
- AudioProcessorMemoryManager.InvalidateDspCache(_dspMemoryPoolState.Translate(workBuffer, workBufferAllocator.Offset), workBufferAllocator.Offset);
+ AudioProcessorMemoryManager.InvalidateDspCache(_dspMemoryPoolInfo.Translate(workBuffer, workBufferAllocator.Offset), workBufferAllocator.Offset);
Debug.Assert((workBufferAllocator.Offset % Constants.BufferAlignment) == 0);
- Memory voices = workBufferAllocator.Allocate(parameter.VoiceCount, VoiceState.Alignment);
+ Memory voices = workBufferAllocator.Allocate(parameter.VoiceCount, VoiceInfo.Alignment);
if (voices.IsEmpty)
{
return ResultCode.WorkBufferTooSmall;
}
- foreach (ref VoiceState voice in voices.Span)
+ foreach (ref VoiceInfo voice in voices.Span)
{
voice.Initialize();
}
- // A pain to handle as we can't have VoiceState*, use indices to be a bit more safe
+ // A pain to handle as we can't have VoiceInfo*, use indices to be a bit more safe
Memory sortedVoices = workBufferAllocator.Allocate(parameter.VoiceCount, 0x10);
if (sortedVoices.IsEmpty)
@@ -233,16 +233,16 @@ namespace Ryujinx.Audio.Renderer.Server
voiceChannelResource.IsUsed = false;
}
- Memory voiceUpdateStates = workBufferAllocator.Allocate(parameter.VoiceCount, VoiceUpdateState.Align);
+ Memory voiceStates = workBufferAllocator.Allocate(parameter.VoiceCount, VoiceState.Align);
- if (voiceUpdateStates.IsEmpty)
+ if (voiceStates.IsEmpty)
{
return ResultCode.WorkBufferTooSmall;
}
uint mixesCount = parameter.SubMixBufferCount + 1;
- Memory mixes = workBufferAllocator.Allocate(mixesCount, MixState.Alignment);
+ Memory mixes = workBufferAllocator.Allocate(mixesCount, MixInfo.Alignment);
if (mixes.IsEmpty)
{
@@ -251,18 +251,18 @@ namespace Ryujinx.Audio.Renderer.Server
if (parameter.EffectCount == 0)
{
- foreach (ref MixState mix in mixes.Span)
+ foreach (ref MixInfo mix in mixes.Span)
{
- mix = new MixState(Memory.Empty, ref _behaviourContext);
+ mix = new MixInfo(Memory.Empty, ref _behaviourInfo);
}
}
else
{
Memory effectProcessingOrderArray = workBufferAllocator.Allocate(parameter.EffectCount * mixesCount, 0x10);
- foreach (ref MixState mix in mixes.Span)
+ foreach (ref MixInfo mix in mixes.Span)
{
- mix = new MixState(effectProcessingOrderArray[..(int)parameter.EffectCount], ref _behaviourContext);
+ mix = new MixInfo(effectProcessingOrderArray[..(int)parameter.EffectCount], ref _behaviourInfo);
effectProcessingOrderArray = effectProcessingOrderArray[(int)parameter.EffectCount..];
}
@@ -271,20 +271,20 @@ namespace Ryujinx.Audio.Renderer.Server
// Initialize the final mix id
mixes.Span[0].MixId = Constants.FinalMixId;
- Memory sortedMixesState = workBufferAllocator.Allocate(mixesCount, 0x10);
+ Memory sortedMixesInfo = workBufferAllocator.Allocate(mixesCount, 0x10);
- if (sortedMixesState.IsEmpty)
+ if (sortedMixesInfo.IsEmpty)
{
return ResultCode.WorkBufferTooSmall;
}
// Clear memory (use -1 as it's an invalid index)
- sortedMixesState.Span.Fill(-1);
+ sortedMixesInfo.Span.Fill(-1);
Memory nodeStatesWorkBuffer = Memory.Empty;
Memory edgeMatrixWorkBuffer = Memory.Empty;
- if (_behaviourContext.IsSplitterSupported())
+ if (_behaviourInfo.IsSplitterSupported())
{
nodeStatesWorkBuffer = workBufferAllocator.Allocate((uint)NodeStates.GetWorkBufferSize((int)mixesCount), 1);
edgeMatrixWorkBuffer = workBufferAllocator.Allocate((uint)EdgeMatrix.GetWorkBufferSize((int)mixesCount), 1);
@@ -295,21 +295,21 @@ namespace Ryujinx.Audio.Renderer.Server
}
}
- _mixContext.Initialize(sortedMixesState, mixes, nodeStatesWorkBuffer, edgeMatrixWorkBuffer);
+ _mixContext.Initialize(sortedMixesInfo, mixes, nodeStatesWorkBuffer, edgeMatrixWorkBuffer);
- _memoryPools = workBufferAllocator.Allocate(_memoryPoolCount, MemoryPoolState.Alignment);
+ _memoryPools = workBufferAllocator.Allocate(_memoryPoolCount, MemoryPoolInfo.Alignment);
if (_memoryPools.IsEmpty)
{
return ResultCode.WorkBufferTooSmall;
}
- foreach (ref MemoryPoolState state in _memoryPools.Span)
+ foreach (ref MemoryPoolInfo info in _memoryPools.Span)
{
- state = MemoryPoolState.Create(MemoryPoolState.LocationType.Cpu);
+ info = MemoryPoolInfo.Create(MemoryPoolInfo.LocationType.Cpu);
}
- if (!_splitterContext.Initialize(ref _behaviourContext, ref parameter, workBufferAllocator, splitterBqfStates))
+ if (!_splitterContext.Initialize(ref _behaviourInfo, ref parameter, workBufferAllocator, splitterBqfStates))
{
return ResultCode.WorkBufferTooSmall;
}
@@ -318,21 +318,21 @@ namespace Ryujinx.Audio.Renderer.Server
_upsamplerManager = new UpsamplerManager(upSamplerWorkBuffer, _upsamplerCount);
- _effectContext.Initialize(parameter.EffectCount, _behaviourContext.IsEffectInfoVersion2Supported() ? parameter.EffectCount : 0);
+ _effectContext.Initialize(parameter.EffectCount, _behaviourInfo.IsEffectInfoVersion2Supported() ? parameter.EffectCount : 0);
_sinkContext.Initialize(parameter.SinkCount);
- Memory voiceUpdateStatesDsp = workBufferAllocator.Allocate(parameter.VoiceCount, VoiceUpdateState.Align);
+ Memory voiceStatesDsp = workBufferAllocator.Allocate(parameter.VoiceCount, VoiceState.Align);
- if (voiceUpdateStatesDsp.IsEmpty)
+ if (voiceStatesDsp.IsEmpty)
{
return ResultCode.WorkBufferTooSmall;
}
- _voiceContext.Initialize(sortedVoices, voices, voiceChannelResources, voiceUpdateStates, voiceUpdateStatesDsp, parameter.VoiceCount);
+ _voiceContext.Initialize(sortedVoices, voices, voiceChannelResources, voiceStates, voiceStatesDsp, parameter.VoiceCount);
if (parameter.PerformanceMetricFramesCount > 0)
{
- ulong performanceBufferSize = PerformanceManager.GetRequiredBufferSizeForPerformanceMetricsPerFrame(ref parameter, ref _behaviourContext) * (parameter.PerformanceMetricFramesCount + 1) + 0xC;
+ ulong performanceBufferSize = PerformanceManager.GetRequiredBufferSizeForPerformanceMetricsPerFrame(ref parameter, ref _behaviourInfo) * (parameter.PerformanceMetricFramesCount + 1) + 0xC;
_performanceBuffer = workBufferAllocator.Allocate(performanceBufferSize, Constants.BufferAlignment);
@@ -341,7 +341,7 @@ namespace Ryujinx.Audio.Renderer.Server
return ResultCode.WorkBufferTooSmall;
}
- _performanceManager = PerformanceManager.Create(_performanceBuffer, ref parameter, _behaviourContext);
+ _performanceManager = PerformanceManager.Create(_performanceBuffer, ref parameter, _behaviourInfo);
}
else
{
@@ -359,14 +359,14 @@ namespace Ryujinx.Audio.Renderer.Server
_elapsedFrameCount = 0;
_voiceDropParameter = 1.0f;
- _commandProcessingTimeEstimator = _behaviourContext.GetCommandProcessingTimeEstimatorVersion() switch
+ _commandProcessingTimeEstimator = _behaviourInfo.GetCommandProcessingTimeEstimatorVersion() switch
{
1 => new CommandProcessingTimeEstimatorVersion1(_sampleCount, _mixBufferCount),
2 => new CommandProcessingTimeEstimatorVersion2(_sampleCount, _mixBufferCount),
3 => new CommandProcessingTimeEstimatorVersion3(_sampleCount, _mixBufferCount),
4 => new CommandProcessingTimeEstimatorVersion4(_sampleCount, _mixBufferCount),
5 => new CommandProcessingTimeEstimatorVersion5(_sampleCount, _mixBufferCount),
- _ => throw new NotImplementedException($"Unsupported processing time estimator version {_behaviourContext.GetCommandProcessingTimeEstimatorVersion()}."),
+ _ => throw new NotImplementedException($"Unsupported processing time estimator version {_behaviourInfo.GetCommandProcessingTimeEstimatorVersion()}."),
};
return ResultCode.Success;
@@ -411,11 +411,11 @@ namespace Ryujinx.Audio.Renderer.Server
output.Span.Clear();
- StateUpdater stateUpdater = new(input, output, _processHandle, _behaviourContext);
+ StateUpdater stateUpdater = new(input, output, _processHandle, _behaviourInfo);
ResultCode result;
- result = stateUpdater.UpdateBehaviourContext();
+ result = stateUpdater.UpdateBehaviourInfo();
if (result != ResultCode.Success)
{
@@ -436,9 +436,16 @@ namespace Ryujinx.Audio.Renderer.Server
return result;
}
- PoolMapper poolMapper = new(_processHandle, _memoryPools, _behaviourContext.IsMemoryPoolForceMappingEnabled());
+ PoolMapper poolMapper = new(_processHandle, _memoryPools, _behaviourInfo.IsMemoryPoolForceMappingEnabled());
- result = stateUpdater.UpdateVoices(_voiceContext, poolMapper);
+ if (_behaviourInfo.IsBiquadFilterParameterFloatSupported())
+ {
+ result = stateUpdater.UpdateVoices2(_voiceContext, poolMapper);
+ }
+ else
+ {
+ result = stateUpdater.UpdateVoices1(_voiceContext, poolMapper);
+ }
if (result != ResultCode.Success)
{
@@ -452,7 +459,7 @@ namespace Ryujinx.Audio.Renderer.Server
return result;
}
- if (_behaviourContext.IsSplitterSupported())
+ if (_behaviourInfo.IsSplitterSupported())
{
result = stateUpdater.UpdateSplitter(_splitterContext);
@@ -490,7 +497,7 @@ namespace Ryujinx.Audio.Renderer.Server
return result;
}
- if (_behaviourContext.IsElapsedFrameCountSupported())
+ if (_behaviourInfo.IsElapsedFrameCountSupported())
{
result = stateUpdater.UpdateRendererInfo(_elapsedFrameCount);
@@ -557,7 +564,7 @@ namespace Ryujinx.Audio.Renderer.Server
break;
}
- ref VoiceState voice = ref _voiceContext.GetState(NodeIdHelper.GetBase(targetNodeId));
+ ref VoiceInfo voice = ref _voiceContext.GetState(NodeIdHelper.GetBase(targetNodeId));
if (voice.Priority == Constants.VoiceHighestPriority)
{
@@ -646,7 +653,7 @@ namespace Ryujinx.Audio.Renderer.Server
_voiceContext.UpdateForCommandGeneration();
- if (_behaviourContext.IsEffectInfoVersion2Supported())
+ if (_behaviourInfo.IsEffectInfoVersion2Supported())
{
_effectContext.UpdateResultStateForCommandGeneration();
}
@@ -661,7 +668,7 @@ namespace Ryujinx.Audio.Renderer.Server
private int GetMaxAllocatedTimeForDsp()
{
- return (int)(Constants.AudioProcessorMaxUpdateTimePerSessions * _behaviourContext.GetAudioRendererProcessingTimeLimit() * (GetRenderingTimeLimit() / 100.0f));
+ return (int)(Constants.AudioProcessorMaxUpdateTimePerSessions * _behaviourInfo.GetAudioRendererProcessingTimeLimit() * (GetRenderingTimeLimit() / 100.0f));
}
public void SendCommands()
@@ -736,7 +743,7 @@ namespace Ryujinx.Audio.Renderer.Server
return new RendererSystemContext
{
ChannelCount = _manager.Processor.OutputDevices[_sessionId].GetChannelCount(),
- BehaviourContext = _behaviourContext,
+ BehaviourInfo = _behaviourInfo,
DepopBuffer = _depopBuffer,
MixBufferCount = GetMixBufferCount(),
SessionId = _sessionId,
@@ -751,9 +758,9 @@ namespace Ryujinx.Audio.Renderer.Server
public static ulong GetWorkBufferSize(ref AudioRendererConfiguration parameter)
{
- BehaviourContext behaviourContext = new();
+ BehaviourInfo behaviourInfo = new();
- behaviourContext.SetUserRevision(parameter.Revision);
+ behaviourInfo.SetUserRevision(parameter.Revision);
uint mixesCount = parameter.SubMixBufferCount + 1;
@@ -771,28 +778,28 @@ namespace Ryujinx.Audio.Renderer.Server
size = WorkBufferAllocator.GetTargetSize(size, BitUtils.AlignUp(parameter.MixBufferCount, Constants.BufferAlignment), Constants.BufferAlignment);
// Voice
- size = WorkBufferAllocator.GetTargetSize(size, parameter.VoiceCount, VoiceState.Alignment);
+ size = WorkBufferAllocator.GetTargetSize(size, parameter.VoiceCount, VoiceInfo.Alignment);
size = WorkBufferAllocator.GetTargetSize(size, parameter.VoiceCount, 0x10);
size = WorkBufferAllocator.GetTargetSize(size, parameter.VoiceCount, VoiceChannelResource.Alignment);
- size = WorkBufferAllocator.GetTargetSize(size, parameter.VoiceCount, VoiceUpdateState.Align);
+ size = WorkBufferAllocator.GetTargetSize(size, parameter.VoiceCount, VoiceState.Align);
// Mix
- size = WorkBufferAllocator.GetTargetSize(size, mixesCount, MixState.Alignment);
+ size = WorkBufferAllocator.GetTargetSize(size, mixesCount, MixInfo.Alignment);
size = WorkBufferAllocator.GetTargetSize(size, parameter.EffectCount * mixesCount, 0x10);
size = WorkBufferAllocator.GetTargetSize(size, mixesCount, 0x10);
- if (behaviourContext.IsSplitterSupported())
+ if (behaviourInfo.IsSplitterSupported())
{
size += (ulong)BitUtils.AlignUp(NodeStates.GetWorkBufferSize((int)mixesCount) + EdgeMatrix.GetWorkBufferSize((int)mixesCount), 0x10);
}
// Memory Pool
- size = WorkBufferAllocator.GetTargetSize(size, memoryPoolCount, MemoryPoolState.Alignment);
+ size = WorkBufferAllocator.GetTargetSize(size, memoryPoolCount, MemoryPoolInfo.Alignment);
// Splitter
- size = SplitterContext.GetWorkBufferSize(size, ref behaviourContext, ref parameter);
+ size = SplitterContext.GetWorkBufferSize(size, ref behaviourInfo, ref parameter);
- if (behaviourContext.IsBiquadFilterParameterForSplitterEnabled() &&
+ if (behaviourInfo.IsBiquadFilterParameterForSplitterEnabled() &&
parameter.SplitterCount > 0 &&
parameter.SplitterDestinationCount > 0)
{
@@ -800,12 +807,12 @@ namespace Ryujinx.Audio.Renderer.Server
}
// DSP Voice
- size = WorkBufferAllocator.GetTargetSize(size, parameter.VoiceCount, VoiceUpdateState.Align);
+ size = WorkBufferAllocator.GetTargetSize(size, parameter.VoiceCount, VoiceState.Align);
// Performance
if (parameter.PerformanceMetricFramesCount > 0)
{
- ulong performanceMetricsPerFramesSize = PerformanceManager.GetRequiredBufferSizeForPerformanceMetricsPerFrame(ref parameter, ref behaviourContext) * (parameter.PerformanceMetricFramesCount + 1) + 0xC;
+ ulong performanceMetricsPerFramesSize = PerformanceManager.GetRequiredBufferSizeForPerformanceMetricsPerFrame(ref parameter, ref behaviourInfo) * (parameter.PerformanceMetricFramesCount + 1) + 0xC;
size += BitUtils.AlignUp(performanceMetricsPerFramesSize, Constants.PerformanceMetricsPerFramesSizeAlignment);
}
@@ -847,13 +854,13 @@ namespace Ryujinx.Audio.Renderer.Server
}
PoolMapper mapper = new(_processHandle, false);
- mapper.Unmap(ref _dspMemoryPoolState);
+ mapper.Unmap(ref _dspMemoryPoolInfo);
PoolMapper.ClearUsageState(_memoryPools);
for (int i = 0; i < _memoryPoolCount; i++)
{
- ref MemoryPoolState memoryPool = ref _memoryPools.Span[i];
+ ref MemoryPoolInfo memoryPool = ref _memoryPools.Span[i];
if (memoryPool.IsMapped())
{
@@ -875,7 +882,7 @@ namespace Ryujinx.Audio.Renderer.Server
public void SetVoiceDropParameter(float voiceDropParameter)
{
- _voiceDropParameter = Math.Clamp(voiceDropParameter, 0.0f, 2.0f);
+ _voiceDropParameter = Math.Clamp(voiceDropParameter, 0.0f, 4.0f);
}
public float GetVoiceDropParameter()
diff --git a/src/Ryujinx.Audio/Renderer/Server/BehaviourContext.cs b/src/Ryujinx.Audio/Renderer/Server/BehaviourInfo.cs
similarity index 89%
rename from src/Ryujinx.Audio/Renderer/Server/BehaviourContext.cs
rename to src/Ryujinx.Audio/Renderer/Server/BehaviourInfo.cs
index f725eb9f3..04463e876 100644
--- a/src/Ryujinx.Audio/Renderer/Server/BehaviourContext.cs
+++ b/src/Ryujinx.Audio/Renderer/Server/BehaviourInfo.cs
@@ -1,3 +1,5 @@
+using Ryujinx.Audio.Renderer.Parameter;
+using Ryujinx.Common.Memory;
using System;
using System.Buffers;
using System.Diagnostics;
@@ -9,7 +11,7 @@ namespace Ryujinx.Audio.Renderer.Server
/// Behaviour context.
///
/// This handles features based on the audio renderer revision provided by the user.
- public class BehaviourContext
+ public class BehaviourInfo
{
///
/// The base magic of the Audio Renderer revision.
@@ -40,7 +42,7 @@ namespace Ryujinx.Audio.Renderer.Server
public const int Revision4 = 4 << 24;
///
- /// REV5: , were added to voice.
+ /// REV5: , were added to voice.
/// A new performance frame format (version 2) was added with support for more information about DSP timing.
/// was added to supply the count of update done sent to the DSP.
/// A new version of the command estimator was added to address timing changes caused by the voice changes.
@@ -64,7 +66,7 @@ namespace Ryujinx.Audio.Renderer.Server
///
/// REV8:
/// Wavebuffer was changed to support more control over loop (you can now specify where to start and end a loop, and how many times to loop).
- /// was added (see for more info).
+ /// was added (see for more info).
/// Final leftovers of the codec system were removed.
/// support was added.
/// A new version of the command estimator was added to address timing changes caused by the voice and command changes.
@@ -115,16 +117,27 @@ namespace Ryujinx.Audio.Renderer.Server
///
/// This was added in system update 18.0.0
public const int Revision13 = 13 << 24;
+
+ ///
+ /// REV14:
+ /// Fixes the Depop Bug.
+ ///
+ ///
+ /// This was added in system update 19.0.0
+ public const int Revision14 = 14 << 24;
+
+ ///
+ /// REV15:
+ /// Support for float coefficients in biquad filters
+ ///
+ ///
+ /// This was added in system update 19.0.0
+ public const int Revision15 = 15 << 24;
///
/// Last revision supported by the implementation.
///
- public const int LastRevision = Revision13;
-
- ///
- /// Target revision magic supported by the implementation.
- ///
- public const int ProcessRevision = BaseRevisionMagic + LastRevision;
+ public const int LastRevision = Revision15;
///
/// Get the revision number from the revision magic.
@@ -133,15 +146,25 @@ namespace Ryujinx.Audio.Renderer.Server
/// The revision number.
public static int GetRevisionNumber(int revision) => (revision - BaseRevisionMagic) >> 24;
+ ///
+ /// Target revision magic supported by the implementation.
+ ///
+ public const int ProcessRevision = BaseRevisionMagic + LastRevision;
+
///
/// Current active revision.
///
public int UserRevision { get; private set; }
+
+ ///
+ /// Current flags of the .
+ ///
+ private ulong _flags;
///
/// Error storage.
///
- private readonly ErrorInfo[] _errorInfos;
+ private readonly Array10 _errorInfos;
///
/// Current position in the array.
@@ -149,17 +172,12 @@ namespace Ryujinx.Audio.Renderer.Server
private uint _errorIndex;
///
- /// Current flags of the .
+ /// Create a new instance of .
///
- private ulong _flags;
-
- ///
- /// Create a new instance of .
- ///
- public BehaviourContext()
+ public BehaviourInfo()
{
UserRevision = 0;
- _errorInfos = new ErrorInfo[Constants.MaxErrorInfos];
+ _errorInfos = new Array10();
_errorIndex = 0;
}
@@ -173,7 +191,7 @@ namespace Ryujinx.Audio.Renderer.Server
}
///
- /// Update flags of the .
+ /// Update flags of the .
///
/// The new flags.
public void UpdateFlags(ulong flags)
@@ -321,9 +339,9 @@ namespace Ryujinx.Audio.Renderer.Server
}
///
- /// Check if the audio renderer should support .
+ /// Check if the audio renderer should support .
///
- /// True if the audio renderer should support .
+ /// True if the audio renderer should support .
public bool IsDecodingBehaviourFlagSupported()
{
return CheckFeatureSupported(UserRevision, BaseRevisionMagic + Revision5);
@@ -400,6 +418,24 @@ namespace Ryujinx.Audio.Renderer.Server
{
return CheckFeatureSupported(UserRevision, BaseRevisionMagic + Revision13);
}
+
+ ///
+ /// Check if the audio renderer should support the depop bug fix.
+ ///
+ /// True if the audio renderer supports the depop bug fix
+ public bool IsSplitterDepopBugFixEnabled()
+ {
+ return CheckFeatureSupported(UserRevision, BaseRevisionMagic + Revision14);
+ }
+
+ ///
+ /// Check if the audio renderer should support biquad filter with float coefficients.
+ ///
+ /// True if the audio renderer support biquad filter with float coefficients
+ public bool IsBiquadFilterParameterFloatSupported()
+ {
+ return CheckFeatureSupported(UserRevision, BaseRevisionMagic + Revision15);
+ }
///
/// Get the version of the .
@@ -440,7 +476,7 @@ namespace Ryujinx.Audio.Renderer.Server
if (_errorIndex <= Constants.MaxErrorInfos - 1)
{
- _errorInfos[_errorIndex++] = errorInfo;
+ _errorInfos[(int)_errorIndex++] = errorInfo;
}
}
@@ -457,22 +493,8 @@ namespace Ryujinx.Audio.Renderer.Server
}
errorCount = Math.Min(_errorIndex, Constants.MaxErrorInfos);
-
- for (int i = 0; i < Constants.MaxErrorInfos; i++)
- {
- if (i < errorCount)
- {
- errorInfos[i] = _errorInfos[i];
- }
- else
- {
- errorInfos[i] = new ErrorInfo
- {
- ErrorCode = 0,
- ExtraErrorInfo = 0,
- };
- }
- }
+
+ _errorInfos.AsSpan().CopyTo(errorInfos);
}
///
diff --git a/src/Ryujinx.Audio/Renderer/Server/CommandBuffer.cs b/src/Ryujinx.Audio/Renderer/Server/CommandBuffer.cs
index d65897e45..62380f926 100644
--- a/src/Ryujinx.Audio/Renderer/Server/CommandBuffer.cs
+++ b/src/Ryujinx.Audio/Renderer/Server/CommandBuffer.cs
@@ -5,9 +5,11 @@ using Ryujinx.Audio.Renderer.Parameter;
using Ryujinx.Audio.Renderer.Parameter.Effect;
using Ryujinx.Audio.Renderer.Server.Performance;
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 System;
+using System.Runtime.CompilerServices;
using CpuAddress = System.UInt64;
namespace Ryujinx.Audio.Renderer.Server
@@ -77,7 +79,7 @@ namespace Ryujinx.Audio.Renderer.Server
/// The target buffer offset.
/// The node id associated to this command.
/// Set to true if the voice was playing previously.
- public void GenerateDepopPrepare(Memory state, Memory depopBuffer, uint bufferCount, uint bufferOffset, int nodeId, bool wasPlaying)
+ public void GenerateDepopPrepare(Memory state, Memory depopBuffer, uint bufferCount, uint bufferOffset, int nodeId, bool wasPlaying)
{
DepopPrepareCommand command = new(state, depopBuffer, bufferCount, bufferOffset, nodeId, wasPlaying);
@@ -120,14 +122,14 @@ namespace Ryujinx.Audio.Renderer.Server
///
/// Create a new .
///
- /// The to generate the command from.
- /// The to generate the command from.
+ /// The to generate the command from.
+ /// The to generate the command from.
/// The output buffer index to use.
/// The target channel index.
/// The node id associated to this command.
- public void GenerateDataSourceVersion2(ref VoiceState voiceState, Memory state, ushort outputBufferIndex, ushort channelIndex, int nodeId)
+ public void GenerateDataSourceVersion2(ref VoiceInfo voiceInfo, Memory state, ushort outputBufferIndex, ushort channelIndex, int nodeId)
{
- DataSourceVersion2Command command = new(ref voiceState, state, outputBufferIndex, channelIndex, nodeId);
+ DataSourceVersion2Command command = new(ref voiceInfo, state, outputBufferIndex, channelIndex, nodeId);
command.EstimatedProcessingTime = _commandProcessingTimeEstimator.Estimate(command);
@@ -137,14 +139,14 @@ namespace Ryujinx.Audio.Renderer.Server
///
/// Create a new .
///
- /// The to generate the command from.
- /// The to generate the command from.
+ /// The to generate the command from.
+ /// The to generate the command from.
/// The output buffer index to use.
/// The target channel index.
/// The node id associated to this command.
- public void GeneratePcmInt16DataSourceVersion1(ref VoiceState voiceState, Memory state, ushort outputBufferIndex, ushort channelIndex, int nodeId)
+ public void GeneratePcmInt16DataSourceVersion1(ref VoiceInfo voiceInfo, Memory state, ushort outputBufferIndex, ushort channelIndex, int nodeId)
{
- PcmInt16DataSourceCommandVersion1 command = new(ref voiceState, state, outputBufferIndex, channelIndex, nodeId);
+ PcmInt16DataSourceCommandVersion1 command = new(ref voiceInfo, state, outputBufferIndex, channelIndex, nodeId);
command.EstimatedProcessingTime = _commandProcessingTimeEstimator.Estimate(command);
@@ -154,14 +156,14 @@ namespace Ryujinx.Audio.Renderer.Server
///
/// Create a new .
///
- /// The to generate the command from.
- /// The to generate the command from.
+ /// The to generate the command from.
+ /// The to generate the command from.
/// The output buffer index to use.
/// The target channel index.
/// The node id associated to this command.
- public void GeneratePcmFloatDataSourceVersion1(ref VoiceState voiceState, Memory state, ushort outputBufferIndex, ushort channelIndex, int nodeId)
+ public void GeneratePcmFloatDataSourceVersion1(ref VoiceInfo voiceInfo, Memory state, ushort outputBufferIndex, ushort channelIndex, int nodeId)
{
- PcmFloatDataSourceCommandVersion1 command = new(ref voiceState, state, outputBufferIndex, channelIndex, nodeId);
+ PcmFloatDataSourceCommandVersion1 command = new(ref voiceInfo, state, outputBufferIndex, channelIndex, nodeId);
command.EstimatedProcessingTime = _commandProcessingTimeEstimator.Estimate(command);
@@ -171,13 +173,13 @@ namespace Ryujinx.Audio.Renderer.Server
///
/// Create a new .
///
- /// The to generate the command from.
- /// The to generate the command from.
+ /// The to generate the command from.
+ /// The to generate the command from.
/// The output buffer index to use.
/// The node id associated to this command.
- public void GenerateAdpcmDataSourceVersion1(ref VoiceState voiceState, Memory state, ushort outputBufferIndex, int nodeId)
+ public void GenerateAdpcmDataSourceVersion1(ref VoiceInfo voiceInfo, Memory state, ushort outputBufferIndex, int nodeId)
{
- AdpcmDataSourceCommandVersion1 command = new(ref voiceState, state, outputBufferIndex, nodeId);
+ AdpcmDataSourceCommandVersion1 command = new(ref voiceInfo, state, outputBufferIndex, nodeId);
command.EstimatedProcessingTime = _commandProcessingTimeEstimator.Estimate(command);
@@ -194,7 +196,7 @@ namespace Ryujinx.Audio.Renderer.Server
/// The output buffer offset.
/// Set to true if the biquad filter state needs to be initialized.
/// The node id associated to this command.
- public void GenerateBiquadFilter(int baseIndex, ref BiquadFilterParameter filter, Memory biquadFilterStateMemory, int inputBufferOffset, int outputBufferOffset, bool needInitialization, int nodeId)
+ 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);
@@ -213,7 +215,7 @@ namespace Ryujinx.Audio.Renderer.Server
/// The output buffer offset.
/// Set to true if the biquad filter state is initialized.
/// The node id associated to this command.
- public void GenerateMultiTapBiquadFilter(int baseIndex, ReadOnlySpan filters, Memory biquadFilterStatesMemory, int inputBufferOffset, int outputBufferOffset, ReadOnlySpan isInitialized, int nodeId)
+ 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);
@@ -230,9 +232,9 @@ namespace Ryujinx.Audio.Renderer.Server
/// The base output index.
/// The previous volume.
/// The new volume.
- /// The to generate the command from.
+ /// The to generate the command from.
/// The node id associated to this command.
- public void GenerateMixRampGrouped(uint mixBufferCount, uint inputBufferIndex, uint outputBufferIndex, ReadOnlySpan previousVolume, ReadOnlySpan volume, Memory state, int nodeId)
+ 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);
@@ -248,10 +250,10 @@ namespace Ryujinx.Audio.Renderer.Server
/// The new volume.
/// The input buffer index.
/// The output buffer index.
- /// The index in the array to store the ramped sample.
- /// The to generate the command from.
+ /// The index in the array to store the ramped sample.
+ /// The to generate the command from.
/// The node id associated to this command.
- public void GenerateMixRamp(float previousVolume, float volume, uint inputBufferIndex, uint outputBufferIndex, int lastSampleIndex, Memory state, int nodeId)
+ 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);
@@ -267,8 +269,8 @@ namespace Ryujinx.Audio.Renderer.Server
/// The new volume.
/// The input buffer index.
/// The output buffer index.
- /// The index in the array to store the ramped sample.
- /// The to generate the command from.
+ /// The index in the array to store the ramped sample.
+ /// The to generate the command from.
/// The biquad filter parameter.
/// The biquad state.
/// The previous biquad state.
@@ -282,8 +284,8 @@ namespace Ryujinx.Audio.Renderer.Server
uint inputBufferIndex,
uint outputBufferIndex,
int lastSampleIndex,
- Memory state,
- ref BiquadFilterParameter filter,
+ Memory state,
+ ref BiquadFilterParameter2 filter,
Memory biquadFilterState,
Memory previousBiquadFilterState,
bool needInitialization,
@@ -318,8 +320,8 @@ namespace Ryujinx.Audio.Renderer.Server
/// The new volume.
/// The input buffer index.
/// The output buffer index.
- /// The index in the array to store the ramped sample.
- /// The to generate the command from.
+ /// The index in the array to store the ramped sample.
+ /// The to generate the command from.
/// First biquad filter parameter.
/// Second biquad filter parameter.
/// First biquad state.
@@ -337,9 +339,9 @@ namespace Ryujinx.Audio.Renderer.Server
uint inputBufferIndex,
uint outputBufferIndex,
int lastSampleIndex,
- Memory state,
- ref BiquadFilterParameter filter0,
- ref BiquadFilterParameter filter1,
+ Memory state,
+ ref BiquadFilterParameter2 filter0,
+ ref BiquadFilterParameter2 filter1,
Memory biquadFilterState0,
Memory biquadFilterState1,
Memory previousBiquadFilterState0,
@@ -654,14 +656,14 @@ namespace Ryujinx.Audio.Renderer.Server
/// Create a new .
///
/// The offset of the mix buffer.
- /// The associated.
+ /// The associated.
/// The total input count.
/// The input buffer mix offset.
/// The buffer count per sample.
/// The source sample count.
/// The source sample rate.
/// The node id associated to this command.
- public void GenerateUpsample(uint bufferOffset, UpsamplerState upsampler, uint inputCount, Span inputBufferOffset, uint bufferCountPerSample, uint sampleCount, uint sampleRate, int nodeId)
+ 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);
@@ -686,5 +688,23 @@ namespace Ryujinx.Audio.Renderer.Server
AddCommand(command);
}
+
+ 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);
+ }
+
+ command.EstimatedProcessingTime = _commandProcessingTimeEstimator.Estimate(command);
+
+ AddCommand(command);
+ }
}
}
diff --git a/src/Ryujinx.Audio/Renderer/Server/CommandGenerator.cs b/src/Ryujinx.Audio/Renderer/Server/CommandGenerator.cs
index 519de9b65..c88aa51f2 100644
--- a/src/Ryujinx.Audio/Renderer/Server/CommandGenerator.cs
+++ b/src/Ryujinx.Audio/Renderer/Server/CommandGenerator.cs
@@ -1,5 +1,6 @@
using Ryujinx.Audio.Common;
using Ryujinx.Audio.Renderer.Common;
+using Ryujinx.Audio.Renderer.Dsp;
using Ryujinx.Audio.Renderer.Dsp.Command;
using Ryujinx.Audio.Renderer.Dsp.State;
using Ryujinx.Audio.Renderer.Parameter;
@@ -41,27 +42,27 @@ namespace Ryujinx.Audio.Renderer.Server
_commandBuffer.GenerateClearMixBuffer(Constants.InvalidNodeId);
}
- private void GenerateDataSource(ref VoiceState voiceState, Memory dspState, int channelIndex)
+ private void GenerateDataSource(ref VoiceInfo voiceInfo, Memory dspState, int channelIndex)
{
- if (voiceState.MixId != Constants.UnusedMixId)
+ if (voiceInfo.MixId != Constants.UnusedMixId)
{
- ref MixState mix = ref _mixContext.GetState(voiceState.MixId);
+ ref MixInfo mix = ref _mixContext.GetState(voiceInfo.MixId);
_commandBuffer.GenerateDepopPrepare(
dspState,
_rendererContext.DepopBuffer,
mix.BufferCount,
mix.BufferOffset,
- voiceState.NodeId,
- voiceState.WasPlaying);
+ voiceInfo.NodeId,
+ voiceInfo.WasPlaying);
}
- else if (voiceState.SplitterId != Constants.UnusedSplitterId)
+ else if (voiceInfo.SplitterId != Constants.UnusedSplitterId)
{
int destinationId = 0;
while (true)
{
- SplitterDestination destination = _splitterContext.GetDestination((int)voiceState.SplitterId, destinationId++);
+ SplitterDestination destination = _splitterContext.GetDestination((int)voiceInfo.SplitterId, destinationId++);
if (destination.IsNull)
{
@@ -74,15 +75,17 @@ namespace Ryujinx.Audio.Renderer.Server
if (mixId < _mixContext.GetCount() && mixId != Constants.UnusedSplitterIdInt)
{
- ref MixState mix = ref _mixContext.GetState(mixId);
+ ref MixInfo mix = ref _mixContext.GetState(mixId);
+
+ // _commandBuffer.GenerateFillBuffer();
_commandBuffer.GenerateDepopPrepare(
dspState,
_rendererContext.DepopBuffer,
mix.BufferCount,
mix.BufferOffset,
- voiceState.NodeId,
- voiceState.WasPlaying);
+ voiceInfo.NodeId,
+ voiceInfo.WasPlaying);
destination.MarkAsNeedToUpdateInternalState();
}
@@ -90,71 +93,71 @@ namespace Ryujinx.Audio.Renderer.Server
}
}
- if (!voiceState.WasPlaying)
+ if (!voiceInfo.WasPlaying)
{
- Debug.Assert(voiceState.SampleFormat != SampleFormat.Adpcm || channelIndex == 0);
+ Debug.Assert(voiceInfo.SampleFormat != SampleFormat.Adpcm || channelIndex == 0);
- if (_rendererContext.BehaviourContext.IsWaveBufferVersion2Supported())
+ if (_rendererContext.BehaviourInfo.IsWaveBufferVersion2Supported())
{
_commandBuffer.GenerateDataSourceVersion2(
- ref voiceState,
+ ref voiceInfo,
dspState,
(ushort)_rendererContext.MixBufferCount,
(ushort)channelIndex,
- voiceState.NodeId);
+ voiceInfo.NodeId);
}
else
{
- switch (voiceState.SampleFormat)
+ switch (voiceInfo.SampleFormat)
{
case SampleFormat.PcmInt16:
_commandBuffer.GeneratePcmInt16DataSourceVersion1(
- ref voiceState,
+ ref voiceInfo,
dspState,
(ushort)_rendererContext.MixBufferCount,
(ushort)channelIndex,
- voiceState.NodeId);
+ voiceInfo.NodeId);
break;
case SampleFormat.PcmFloat:
_commandBuffer.GeneratePcmFloatDataSourceVersion1(
- ref voiceState,
+ ref voiceInfo,
dspState,
(ushort)_rendererContext.MixBufferCount,
(ushort)channelIndex,
- voiceState.NodeId);
+ voiceInfo.NodeId);
break;
case SampleFormat.Adpcm:
_commandBuffer.GenerateAdpcmDataSourceVersion1(
- ref voiceState,
+ ref voiceInfo,
dspState,
(ushort)_rendererContext.MixBufferCount,
- voiceState.NodeId);
+ voiceInfo.NodeId);
break;
default:
- throw new NotImplementedException($"Unsupported data source {voiceState.SampleFormat}");
+ throw new NotImplementedException($"Unsupported data source {voiceInfo.SampleFormat}");
}
}
}
}
- private void GenerateBiquadFilterForVoice(ref VoiceState voiceState, Memory state, int baseIndex, int bufferOffset, int nodeId)
+ private void GenerateBiquadFilterForVoice(ref VoiceInfo voiceInfo, Memory state, int baseIndex, int bufferOffset, int nodeId)
{
- bool supportsOptimizedPath = _rendererContext.BehaviourContext.UseMultiTapBiquadFilterProcessing();
+ bool supportsOptimizedPath = _rendererContext.BehaviourInfo.UseMultiTapBiquadFilterProcessing();
- Span biquadFiltersSpan = voiceState.BiquadFilters.AsSpan();
+ Span biquadFiltersSpan = voiceInfo.BiquadFilters.AsSpan();
if (supportsOptimizedPath && biquadFiltersSpan[0].Enable && biquadFiltersSpan[1].Enable)
{
Memory biquadStateRawMemory = SpanMemoryManager.Cast(state)[..(Unsafe.SizeOf() * Constants.VoiceBiquadFilterCount)];
Memory stateMemory = SpanMemoryManager.Cast(biquadStateRawMemory);
- _commandBuffer.GenerateMultiTapBiquadFilter(baseIndex, biquadFiltersSpan, stateMemory, bufferOffset, bufferOffset, voiceState.BiquadFilterNeedInitialization, nodeId);
+ _commandBuffer.GenerateMultiTapBiquadFilter(baseIndex, biquadFiltersSpan, stateMemory, bufferOffset, bufferOffset, voiceInfo.BiquadFilterNeedInitialization, nodeId);
}
else
{
for (int i = 0; i < biquadFiltersSpan.Length; i++)
{
- ref BiquadFilterParameter filter = ref biquadFiltersSpan[i];
+ ref BiquadFilterParameter2 filter = ref biquadFiltersSpan[i];
if (filter.Enable)
{
@@ -167,7 +170,7 @@ namespace Ryujinx.Audio.Renderer.Server
stateMemory.Slice(i, 1),
bufferOffset,
bufferOffset,
- !voiceState.BiquadFilterNeedInitialization[i],
+ !voiceInfo.BiquadFilterNeedInitialization[i],
nodeId);
}
}
@@ -176,7 +179,7 @@ namespace Ryujinx.Audio.Renderer.Server
private void GenerateVoiceMixWithSplitter(
SplitterDestination destination,
- Memory state,
+ Memory state,
uint bufferOffset,
uint bufferCount,
uint bufferIndex,
@@ -185,8 +188,8 @@ namespace Ryujinx.Audio.Renderer.Server
ReadOnlySpan mixVolumes = destination.MixBufferVolume;
ReadOnlySpan previousMixVolumes = destination.PreviousMixBufferVolume;
- ref BiquadFilterParameter bqf0 = ref destination.GetBiquadFilterParameter(0);
- ref BiquadFilterParameter bqf1 = ref destination.GetBiquadFilterParameter(1);
+ ref BiquadFilterParameter2 bqf0 = ref destination.GetBiquadFilterParameter(0);
+ ref BiquadFilterParameter2 bqf1 = ref destination.GetBiquadFilterParameter(1);
Memory bqfState = _splitterContext.GetBiquadFilterState(destination);
@@ -270,7 +273,7 @@ namespace Ryujinx.Audio.Renderer.Server
private void GenerateVoiceMix(
ReadOnlySpan mixVolumes,
ReadOnlySpan previousMixVolumes,
- Memory state,
+ Memory state,
uint bufferOffset,
uint bufferCount,
uint bufferIndex,
@@ -309,27 +312,27 @@ namespace Ryujinx.Audio.Renderer.Server
}
}
- private void GenerateVoice(ref VoiceState voiceState)
+ private void GenerateVoice(ref VoiceInfo voiceInfo)
{
- int nodeId = voiceState.NodeId;
- uint channelsCount = voiceState.ChannelsCount;
+ int nodeId = voiceInfo.NodeId;
+ uint channelsCount = voiceInfo.ChannelsCount;
- Span channelResourceIdsSpan = voiceState.ChannelResourceIds.AsSpan();
- Span biquadFiltersSpan = voiceState.BiquadFilters.AsSpan();
+ Span channelResourceIdsSpan = voiceInfo.ChannelResourceIds.AsSpan();
+ Span biquadFiltersSpan = voiceInfo.BiquadFilters.AsSpan();
for (int channelIndex = 0; channelIndex < channelsCount; channelIndex++)
{
- Memory dspStateMemory = _voiceContext.GetUpdateStateForDsp(channelResourceIdsSpan[channelIndex]);
+ Memory dspStateMemory = _voiceContext.GetUpdateStateForDsp(channelResourceIdsSpan[channelIndex]);
ref VoiceChannelResource channelResource = ref _voiceContext.GetChannelResource(channelResourceIdsSpan[channelIndex]);
PerformanceDetailType dataSourceDetailType = PerformanceDetailType.Adpcm;
- if (voiceState.SampleFormat == SampleFormat.PcmInt16)
+ if (voiceInfo.SampleFormat == SampleFormat.PcmInt16)
{
dataSourceDetailType = PerformanceDetailType.PcmInt16;
}
- else if (voiceState.SampleFormat == SampleFormat.PcmFloat)
+ else if (voiceInfo.SampleFormat == SampleFormat.PcmFloat)
{
dataSourceDetailType = PerformanceDetailType.PcmFloat;
}
@@ -345,18 +348,18 @@ namespace Ryujinx.Audio.Renderer.Server
GeneratePerformance(ref performanceEntry, PerformanceCommand.Type.Start, nodeId);
}
- GenerateDataSource(ref voiceState, dspStateMemory, channelIndex);
+ GenerateDataSource(ref voiceInfo, dspStateMemory, channelIndex);
if (performanceInitialized)
{
GeneratePerformance(ref performanceEntry, PerformanceCommand.Type.End, nodeId);
}
- if (voiceState.WasPlaying)
+ if (voiceInfo.WasPlaying)
{
- voiceState.PreviousVolume = 0.0f;
+ voiceInfo.PreviousVolume = 0.0f;
}
- else if (voiceState.HasAnyDestination())
+ else if (voiceInfo.HasAnyDestination())
{
performanceInitialized = false;
@@ -367,7 +370,7 @@ namespace Ryujinx.Audio.Renderer.Server
GeneratePerformance(ref performanceEntry, PerformanceCommand.Type.Start, nodeId);
}
- GenerateBiquadFilterForVoice(ref voiceState, dspStateMemory, (int)_rendererContext.MixBufferCount, channelIndex, nodeId);
+ GenerateBiquadFilterForVoice(ref voiceInfo, dspStateMemory, (int)_rendererContext.MixBufferCount, channelIndex, nodeId);
if (performanceInitialized)
{
@@ -384,8 +387,8 @@ namespace Ryujinx.Audio.Renderer.Server
}
_commandBuffer.GenerateVolumeRamp(
- voiceState.PreviousVolume,
- voiceState.Volume,
+ voiceInfo.PreviousVolume,
+ voiceInfo.Volume,
_rendererContext.MixBufferCount + (uint)channelIndex,
nodeId);
@@ -394,17 +397,17 @@ namespace Ryujinx.Audio.Renderer.Server
GeneratePerformance(ref performanceEntry, PerformanceCommand.Type.End, nodeId);
}
- voiceState.PreviousVolume = voiceState.Volume;
+ voiceInfo.PreviousVolume = voiceInfo.Volume;
- if (voiceState.MixId == Constants.UnusedMixId)
+ if (voiceInfo.MixId == Constants.UnusedMixId)
{
- if (voiceState.SplitterId != Constants.UnusedSplitterId)
+ if (voiceInfo.SplitterId != Constants.UnusedSplitterId)
{
int destinationId = channelIndex;
while (true)
{
- SplitterDestination destination = _splitterContext.GetDestination((int)voiceState.SplitterId, destinationId);
+ SplitterDestination destination = _splitterContext.GetDestination((int)voiceInfo.SplitterId, destinationId);
if (destination.IsNull)
{
@@ -419,7 +422,7 @@ namespace Ryujinx.Audio.Renderer.Server
if (mixId < _mixContext.GetCount() && mixId != Constants.UnusedSplitterIdInt)
{
- ref MixState mix = ref _mixContext.GetState(mixId);
+ ref MixInfo mix = ref _mixContext.GetState(mixId);
if (destination.IsBiquadFilterEnabled())
{
@@ -451,7 +454,7 @@ namespace Ryujinx.Audio.Renderer.Server
}
else
{
- ref MixState mix = ref _mixContext.GetState(voiceState.MixId);
+ ref MixInfo mix = ref _mixContext.GetState(voiceInfo.MixId);
performanceInitialized = false;
@@ -479,9 +482,9 @@ namespace Ryujinx.Audio.Renderer.Server
channelResource.UpdateState();
}
- for (int i = 0; i < voiceState.BiquadFilterNeedInitialization.Length; i++)
+ for (int i = 0; i < voiceInfo.BiquadFilterNeedInitialization.Length; i++)
{
- voiceState.BiquadFilterNeedInitialization[i] = biquadFiltersSpan[i].Enable;
+ voiceInfo.BiquadFilterNeedInitialization[i] = biquadFiltersSpan[i].Enable;
}
}
}
@@ -491,11 +494,11 @@ namespace Ryujinx.Audio.Renderer.Server
{
for (int i = 0; i < _voiceContext.GetCount(); i++)
{
- ref VoiceState sortedState = ref _voiceContext.GetSortedState(i);
+ ref VoiceInfo sortedInfo = ref _voiceContext.GetSortedState(i);
- if (!sortedState.ShouldSkip() && sortedState.UpdateForCommandGeneration(_voiceContext))
+ if (!sortedInfo.ShouldSkip() && sortedInfo.UpdateForCommandGeneration(_voiceContext))
{
- int nodeId = sortedState.NodeId;
+ int nodeId = sortedInfo.NodeId;
PerformanceEntryAddresses performanceEntry = new();
@@ -508,7 +511,7 @@ namespace Ryujinx.Audio.Renderer.Server
GeneratePerformance(ref performanceEntry, PerformanceCommand.Type.Start, nodeId);
}
- GenerateVoice(ref sortedState);
+ GenerateVoice(ref sortedInfo);
if (performanceInitialized)
{
@@ -639,9 +642,9 @@ namespace Ryujinx.Audio.Renderer.Server
if (effect.IsEnabled)
{
bool needInitialization = effect.Parameter.Status == UsageState.Invalid ||
- (effect.Parameter.Status == UsageState.New && !_rendererContext.BehaviourContext.IsBiquadFilterEffectStateClearBugFixed());
+ (effect.Parameter.Status == UsageState.New && !_rendererContext.BehaviourInfo.IsBiquadFilterEffectStateClearBugFixed());
- BiquadFilterParameter parameter = new()
+ BiquadFilterParameter2 parameter = new()
{
Enable = true,
};
@@ -683,7 +686,7 @@ namespace Ryujinx.Audio.Renderer.Server
ulong workBuffer = effect.GetWorkBuffer(-1);
- if (_rendererContext.BehaviourContext.IsEffectInfoVersion2Supported())
+ if (_rendererContext.BehaviourInfo.IsEffectInfoVersion2Supported())
{
Memory dspResultState;
@@ -777,7 +780,7 @@ namespace Ryujinx.Audio.Renderer.Server
nodeId);
}
- private void GenerateEffect(ref MixState mix, int effectId, BaseEffect effect)
+ private void GenerateEffect(ref MixInfo mix, int effectId, BaseEffect effect)
{
int nodeId = mix.NodeId;
@@ -807,13 +810,13 @@ namespace Ryujinx.Audio.Renderer.Server
GenerateAuxEffect(mix.BufferOffset, (AuxiliaryBufferEffect)effect, nodeId);
break;
case EffectType.Delay:
- GenerateDelayEffect(mix.BufferOffset, (DelayEffect)effect, nodeId, _rendererContext.BehaviourContext.IsNewEffectChannelMappingSupported());
+ GenerateDelayEffect(mix.BufferOffset, (DelayEffect)effect, nodeId, _rendererContext.BehaviourInfo.IsNewEffectChannelMappingSupported());
break;
case EffectType.Reverb:
- GenerateReverbEffect(mix.BufferOffset, (ReverbEffect)effect, nodeId, mix.IsLongSizePreDelaySupported, _rendererContext.BehaviourContext.IsNewEffectChannelMappingSupported());
+ GenerateReverbEffect(mix.BufferOffset, (ReverbEffect)effect, nodeId, mix.IsLongSizePreDelaySupported, _rendererContext.BehaviourInfo.IsNewEffectChannelMappingSupported());
break;
case EffectType.Reverb3d:
- GenerateReverb3dEffect(mix.BufferOffset, (Reverb3dEffect)effect, nodeId, _rendererContext.BehaviourContext.IsNewEffectChannelMappingSupported());
+ GenerateReverb3dEffect(mix.BufferOffset, (Reverb3dEffect)effect, nodeId, _rendererContext.BehaviourInfo.IsNewEffectChannelMappingSupported());
break;
case EffectType.BiquadFilter:
GenerateBiquadFilterEffect(mix.BufferOffset, (BiquadFilterEffect)effect, nodeId);
@@ -839,7 +842,7 @@ namespace Ryujinx.Audio.Renderer.Server
effect.UpdateForCommandGeneration();
}
- private void GenerateEffects(ref MixState mix)
+ private void GenerateEffects(ref MixInfo mix)
{
ReadOnlySpan effectProcessingOrderArray = mix.EffectProcessingOrderArray;
@@ -875,8 +878,8 @@ namespace Ryujinx.Audio.Renderer.Server
ref bool isFirstMixBuffer,
int nodeId)
{
- ref BiquadFilterParameter bqf0 = ref destination.GetBiquadFilterParameter(0);
- ref BiquadFilterParameter bqf1 = ref destination.GetBiquadFilterParameter(1);
+ ref BiquadFilterParameter2 bqf0 = ref destination.GetBiquadFilterParameter(0);
+ ref BiquadFilterParameter2 bqf1 = ref destination.GetBiquadFilterParameter(1);
Memory bqfState = _splitterContext.GetBiquadFilterState(destination);
@@ -888,7 +891,7 @@ namespace Ryujinx.Audio.Renderer.Server
inputBufferIndex,
outputBufferIndex,
0,
- Memory.Empty,
+ Memory.Empty,
ref bqf0,
ref bqf1,
bqfState[..1],
@@ -912,7 +915,7 @@ namespace Ryujinx.Audio.Renderer.Server
inputBufferIndex,
outputBufferIndex,
0,
- Memory.Empty,
+ Memory.Empty,
ref bqf0,
bqfState[..1],
bqfState.Slice(1, 1),
@@ -931,7 +934,7 @@ namespace Ryujinx.Audio.Renderer.Server
inputBufferIndex,
outputBufferIndex,
0,
- Memory.Empty,
+ Memory.Empty,
ref bqf1,
bqfState[..1],
bqfState.Slice(1, 1),
@@ -946,7 +949,7 @@ namespace Ryujinx.Audio.Renderer.Server
isFirstMixBuffer = false;
}
- private void GenerateMix(ref MixState mix)
+ private void GenerateMix(ref MixInfo mix)
{
if (mix.HasAnyDestination())
{
@@ -975,7 +978,7 @@ namespace Ryujinx.Audio.Renderer.Server
if (mixId < _mixContext.GetCount() && mixId != Constants.UnusedSplitterIdInt)
{
- ref MixState destinationMix = ref _mixContext.GetState(mixId);
+ ref MixInfo destinationMix = ref _mixContext.GetState(mixId);
uint inputBufferIndex = mix.BufferOffset + ((uint)destinationIndex % mix.BufferCount);
@@ -1014,7 +1017,7 @@ namespace Ryujinx.Audio.Renderer.Server
}
else
{
- ref MixState destinationMix = ref _mixContext.GetState(mix.DestinationMixId);
+ ref MixInfo destinationMix = ref _mixContext.GetState(mix.DestinationMixId);
for (uint bufferIndex = 0; bufferIndex < mix.BufferCount; bufferIndex++)
{
@@ -1036,7 +1039,7 @@ namespace Ryujinx.Audio.Renderer.Server
}
}
- private void GenerateSubMix(ref MixState subMix)
+ private void GenerateSubMix(ref MixInfo subMix)
{
_commandBuffer.GenerateDepopForMixBuffers(
_rendererContext.DepopBuffer,
@@ -1072,11 +1075,11 @@ namespace Ryujinx.Audio.Renderer.Server
{
for (int id = 0; id < _mixContext.GetCount(); id++)
{
- ref MixState sortedState = ref _mixContext.GetSortedState(id);
+ ref MixInfo sortedInfo = ref _mixContext.GetSortedState(id);
- if (sortedState.IsUsed && sortedState.MixId != Constants.FinalMixId)
+ if (sortedInfo.IsUsed && sortedInfo.MixId != Constants.FinalMixId)
{
- int nodeId = sortedState.NodeId;
+ int nodeId = sortedInfo.NodeId;
PerformanceEntryAddresses performanceEntry = new();
@@ -1089,7 +1092,7 @@ namespace Ryujinx.Audio.Renderer.Server
GeneratePerformance(ref performanceEntry, PerformanceCommand.Type.Start, nodeId);
}
- GenerateSubMix(ref sortedState);
+ GenerateSubMix(ref sortedInfo);
if (performanceInitialized)
{
@@ -1101,7 +1104,7 @@ namespace Ryujinx.Audio.Renderer.Server
private void GenerateFinalMix()
{
- ref MixState finalMix = ref _mixContext.GetFinalState();
+ ref MixInfo finalMix = ref _mixContext.GetFinalState();
_commandBuffer.GenerateDepopForMixBuffers(
_rendererContext.DepopBuffer,
@@ -1180,16 +1183,16 @@ namespace Ryujinx.Audio.Renderer.Server
}
}
- private void GenerateCircularBuffer(CircularBufferSink sink, ref MixState finalMix)
+ private void GenerateCircularBuffer(CircularBufferSink sink, ref MixInfo finalMix)
{
_commandBuffer.GenerateCircularBuffer(finalMix.BufferOffset, sink, Constants.InvalidNodeId);
}
- private void GenerateDevice(DeviceSink sink, ref MixState finalMix)
+ private void GenerateDevice(DeviceSink sink, ref MixInfo finalMix)
{
- if (_commandBuffer.CommandList.SampleRate != 48000 && sink.UpsamplerState == null)
+ if (_commandBuffer.CommandList.SampleRate != 48000 && sink.UpsamplerInfo == null)
{
- sink.UpsamplerState = _rendererContext.UpsamplerManager.Allocate();
+ sink.UpsamplerInfo = _rendererContext.UpsamplerManager.Allocate();
}
bool useCustomDownMixingCommand = _rendererContext.ChannelCount == 2 && sink.Parameter.DownMixParameterEnabled;
@@ -1216,11 +1219,11 @@ namespace Ryujinx.Audio.Renderer.Server
CommandList commandList = _commandBuffer.CommandList;
- if (sink.UpsamplerState != null)
+ if (sink.UpsamplerInfo != null)
{
_commandBuffer.GenerateUpsample(
finalMix.BufferOffset,
- sink.UpsamplerState,
+ sink.UpsamplerInfo,
sink.Parameter.InputCount,
sink.Parameter.Input.AsSpan(),
commandList.BufferCount,
@@ -1237,7 +1240,7 @@ namespace Ryujinx.Audio.Renderer.Server
Constants.InvalidNodeId);
}
- private void GenerateSink(BaseSink sink, ref MixState finalMix)
+ private void GenerateSink(BaseSink sink, ref MixInfo finalMix)
{
bool performanceInitialized = false;
@@ -1275,7 +1278,7 @@ namespace Ryujinx.Audio.Renderer.Server
public void GenerateSinks()
{
- ref MixState finalMix = ref _mixContext.GetFinalState();
+ ref MixInfo finalMix = ref _mixContext.GetFinalState();
for (int i = 0; i < _sinkContext.GetCount(); i++)
{
diff --git a/src/Ryujinx.Audio/Renderer/Server/CommandProcessingTimeEstimatorVersion1.cs b/src/Ryujinx.Audio/Renderer/Server/CommandProcessingTimeEstimatorVersion1.cs
index cff754b82..8abe81e1f 100644
--- a/src/Ryujinx.Audio/Renderer/Server/CommandProcessingTimeEstimatorVersion1.cs
+++ b/src/Ryujinx.Audio/Renderer/Server/CommandProcessingTimeEstimatorVersion1.cs
@@ -194,5 +194,10 @@ namespace Ryujinx.Audio.Renderer.Server
{
return 0;
}
+
+ public uint Estimate(FillBufferCommand command)
+ {
+ return 0;
+ }
}
}
diff --git a/src/Ryujinx.Audio/Renderer/Server/CommandProcessingTimeEstimatorVersion2.cs b/src/Ryujinx.Audio/Renderer/Server/CommandProcessingTimeEstimatorVersion2.cs
index 1e9b6c53e..85e340393 100644
--- a/src/Ryujinx.Audio/Renderer/Server/CommandProcessingTimeEstimatorVersion2.cs
+++ b/src/Ryujinx.Audio/Renderer/Server/CommandProcessingTimeEstimatorVersion2.cs
@@ -486,5 +486,10 @@ namespace Ryujinx.Audio.Renderer.Server
{
return 0;
}
+
+ public uint Estimate(FillBufferCommand command)
+ {
+ return 0;
+ }
}
}
diff --git a/src/Ryujinx.Audio/Renderer/Server/CommandProcessingTimeEstimatorVersion3.cs b/src/Ryujinx.Audio/Renderer/Server/CommandProcessingTimeEstimatorVersion3.cs
index 85e016019..4b0eec4f3 100644
--- a/src/Ryujinx.Audio/Renderer/Server/CommandProcessingTimeEstimatorVersion3.cs
+++ b/src/Ryujinx.Audio/Renderer/Server/CommandProcessingTimeEstimatorVersion3.cs
@@ -3,7 +3,7 @@ using Ryujinx.Audio.Renderer.Dsp.Command;
using Ryujinx.Audio.Renderer.Parameter.Effect;
using System;
using System.Diagnostics;
-using static Ryujinx.Audio.Renderer.Parameter.VoiceInParameter;
+using Ryujinx.Audio.Renderer.Parameter;
namespace Ryujinx.Audio.Renderer.Server
{
@@ -656,5 +656,10 @@ namespace Ryujinx.Audio.Renderer.Server
{
return 0;
}
+
+ public virtual uint Estimate(FillBufferCommand command)
+ {
+ return 0;
+ }
}
}
diff --git a/src/Ryujinx.Audio/Renderer/Server/CommandProcessingTimeEstimatorVersion5.cs b/src/Ryujinx.Audio/Renderer/Server/CommandProcessingTimeEstimatorVersion5.cs
index fe6103f2b..906065792 100644
--- a/src/Ryujinx.Audio/Renderer/Server/CommandProcessingTimeEstimatorVersion5.cs
+++ b/src/Ryujinx.Audio/Renderer/Server/CommandProcessingTimeEstimatorVersion5.cs
@@ -286,5 +286,10 @@ namespace Ryujinx.Audio.Renderer.Server
return 8683;
}
}
+
+ public override uint Estimate(FillBufferCommand command)
+ {
+ return 0;
+ }
}
}
diff --git a/src/Ryujinx.Audio/Renderer/Server/Effect/BaseEffect.cs b/src/Ryujinx.Audio/Renderer/Server/Effect/BaseEffect.cs
index 77d9b5c29..6324689e4 100644
--- a/src/Ryujinx.Audio/Renderer/Server/Effect/BaseEffect.cs
+++ b/src/Ryujinx.Audio/Renderer/Server/Effect/BaseEffect.cs
@@ -174,6 +174,19 @@ 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 3b3e1021c..f920c6873 100644
--- a/src/Ryujinx.Audio/Renderer/Server/Effect/BiquadFilterEffect.cs
+++ b/src/Ryujinx.Audio/Renderer/Server/Effect/BiquadFilterEffect.cs
@@ -1,4 +1,5 @@
using Ryujinx.Audio.Renderer.Common;
+using Ryujinx.Audio.Renderer.Dsp;
using Ryujinx.Audio.Renderer.Dsp.State;
using Ryujinx.Audio.Renderer.Parameter;
using Ryujinx.Audio.Renderer.Parameter.Effect;
@@ -17,7 +18,7 @@ namespace Ryujinx.Audio.Renderer.Server.Effect
///
/// The biquad filter parameter.
///
- public BiquadFilterEffectParameter Parameter;
+ public BiquadFilterEffectParameter2 Parameter;
///
/// The biquad filter state.
@@ -29,7 +30,7 @@ namespace Ryujinx.Audio.Renderer.Server.Effect
///
public BiquadFilterEffect()
{
- Parameter = new BiquadFilterEffectParameter();
+ Parameter = new BiquadFilterEffectParameter2();
State = new BiquadFilterState[Constants.ChannelCountMax];
}
@@ -44,6 +45,11 @@ 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
{
@@ -51,7 +57,17 @@ namespace Ryujinx.Audio.Renderer.Server.Effect
UpdateParameterBase(in parameter);
- Parameter = MemoryMarshal.Cast(parameter.SpecificData)[0];
+ if (typeof(T) == typeof(EffectInParameterVersion3))
+ {
+ Parameter = MemoryMarshal.Cast(parameter.SpecificData)[0];
+ }
+ else
+ {
+ BiquadFilterEffectParameter1 oldParameter =
+ MemoryMarshal.Cast(parameter.SpecificData)[0];
+ Parameter = BiquadFilterHelper.ToBiquadFilterEffectParameter2(oldParameter);
+ }
+
IsEnabled = parameter.IsEnabled;
updateErrorInfo = new BehaviourParameter.ErrorInfo();
diff --git a/src/Ryujinx.Audio/Renderer/Server/ICommandProcessingTimeEstimator.cs b/src/Ryujinx.Audio/Renderer/Server/ICommandProcessingTimeEstimator.cs
index 9c4312ad6..360241278 100644
--- a/src/Ryujinx.Audio/Renderer/Server/ICommandProcessingTimeEstimator.cs
+++ b/src/Ryujinx.Audio/Renderer/Server/ICommandProcessingTimeEstimator.cs
@@ -38,5 +38,6 @@ namespace Ryujinx.Audio.Renderer.Server
uint Estimate(CompressorCommand command);
uint Estimate(BiquadFilterAndMixCommand command);
uint Estimate(MultiTapBiquadFilterAndMixCommand command);
+ uint Estimate(FillBufferCommand command);
}
}
diff --git a/src/Ryujinx.Audio/Renderer/Server/MemoryPool/AddressInfo.cs b/src/Ryujinx.Audio/Renderer/Server/MemoryPool/AddressInfo.cs
index 3337e44b0..0ae6d518d 100644
--- a/src/Ryujinx.Audio/Renderer/Server/MemoryPool/AddressInfo.cs
+++ b/src/Ryujinx.Audio/Renderer/Server/MemoryPool/AddressInfo.cs
@@ -20,14 +20,14 @@ namespace Ryujinx.Audio.Renderer.Server.MemoryPool
///
public ulong Size;
- private unsafe MemoryPoolState* _memoryPools;
+ private unsafe MemoryPoolInfo* _memoryPools;
///
/// The forced DSP address of the region.
///
public DspAddress ForceMappedDspAddress;
- private readonly unsafe ref MemoryPoolState MemoryPoolState => ref *_memoryPools;
+ private readonly unsafe ref MemoryPoolInfo MemoryPoolInfo => ref *_memoryPools;
public readonly unsafe bool HasMemoryPoolState => (nint)_memoryPools != nint.Zero;
@@ -53,7 +53,7 @@ namespace Ryujinx.Audio.Renderer.Server.MemoryPool
return new AddressInfo
{
CpuAddress = cpuAddress,
- _memoryPools = MemoryPoolState.Null,
+ _memoryPools = MemoryPoolInfo.Null,
Size = size,
ForceMappedDspAddress = 0,
};
@@ -73,19 +73,19 @@ namespace Ryujinx.Audio.Renderer.Server.MemoryPool
unsafe
{
- _memoryPools = MemoryPoolState.Null;
+ _memoryPools = MemoryPoolInfo.Null;
}
}
///
- /// Set the associated.
+ /// Set the associated.
///
- /// The associated.
- public void SetupMemoryPool(Span memoryPoolState)
+ /// The associated.
+ public void SetupMemoryPool(Span memoryPoolState)
{
unsafe
{
- fixed (MemoryPoolState* ptr = &MemoryMarshal.GetReference(memoryPoolState))
+ fixed (MemoryPoolInfo* ptr = &MemoryMarshal.GetReference(memoryPoolState))
{
SetupMemoryPool(ptr);
}
@@ -93,27 +93,27 @@ namespace Ryujinx.Audio.Renderer.Server.MemoryPool
}
///
- /// Set the associated.
+ /// Set the associated.
///
- /// The associated.
- public unsafe void SetupMemoryPool(MemoryPoolState* memoryPoolState)
+ /// The associated.
+ public unsafe void SetupMemoryPool(MemoryPoolInfo* memoryPoolState)
{
_memoryPools = memoryPoolState;
}
///
- /// Check if the is mapped.
+ /// Check if the is mapped.
///
- /// Returns true if the is mapped.
+ /// Returns true if the is mapped.
public readonly bool HasMappedMemoryPool()
{
- return HasMemoryPoolState && MemoryPoolState.IsMapped();
+ return HasMemoryPoolState && MemoryPoolInfo.IsMapped();
}
///
/// Get the DSP address associated to the .
///
- /// If true, mark the as used.
+ /// If true, mark the as used.
/// Returns the DSP address associated to the .
public readonly DspAddress GetReference(bool markUsed)
{
@@ -124,10 +124,10 @@ namespace Ryujinx.Audio.Renderer.Server.MemoryPool
if (markUsed)
{
- MemoryPoolState.IsUsed = true;
+ MemoryPoolInfo.IsUsed = true;
}
- return MemoryPoolState.Translate(CpuAddress, Size);
+ return MemoryPoolInfo.Translate(CpuAddress, Size);
}
}
}
diff --git a/src/Ryujinx.Audio/Renderer/Server/MemoryPool/MemoryPoolState.cs b/src/Ryujinx.Audio/Renderer/Server/MemoryPool/MemoryPoolInfo.cs
similarity index 73%
rename from src/Ryujinx.Audio/Renderer/Server/MemoryPool/MemoryPoolState.cs
rename to src/Ryujinx.Audio/Renderer/Server/MemoryPool/MemoryPoolInfo.cs
index 50153af37..eb0117f50 100644
--- a/src/Ryujinx.Audio/Renderer/Server/MemoryPool/MemoryPoolState.cs
+++ b/src/Ryujinx.Audio/Renderer/Server/MemoryPool/MemoryPoolInfo.cs
@@ -8,62 +8,62 @@ namespace Ryujinx.Audio.Renderer.Server.MemoryPool
/// Server state for a memory pool.
///
[StructLayout(LayoutKind.Sequential, Size = 0x20, Pack = Alignment)]
- public struct MemoryPoolState
+ public struct MemoryPoolInfo
{
public const int Alignment = 0x10;
///
- /// The location of the .
+ /// The location of the .
///
public enum LocationType : uint
{
///
- /// located on the CPU side for user use.
+ /// located on the CPU side for user use.
///
Cpu,
///
- /// located on the DSP side for system use.
+ /// located on the DSP side for system use.
///
Dsp,
}
///
- /// The CPU address associated to the .
+ /// The CPU address associated to the .
///
public CpuAddress CpuAddress;
///
- /// The DSP address associated to the .
+ /// The DSP address associated to the .
///
public DspAddress DspAddress;
///
- /// The size associated to the .
+ /// The size associated to the .
///
public ulong Size;
///
- /// The associated to the .
+ /// The associated to the .
///
public LocationType Location;
///
- /// Set to true if the is used.
+ /// Set to true if the is used.
///
[MarshalAs(UnmanagedType.I1)]
public bool IsUsed;
- public static unsafe MemoryPoolState* Null => (MemoryPoolState*)nint.Zero.ToPointer();
+ public static unsafe MemoryPoolInfo* Null => (MemoryPoolInfo*)nint.Zero.ToPointer();
///
- /// Create a new with the given .
+ /// Create a new with the given .
///
/// The location type to use.
- /// A new with the given .
- public static MemoryPoolState Create(LocationType location)
+ /// A new with the given .
+ public static MemoryPoolInfo Create(LocationType location)
{
- return new MemoryPoolState
+ return new MemoryPoolInfo
{
CpuAddress = 0,
DspAddress = 0,
@@ -73,7 +73,7 @@ namespace Ryujinx.Audio.Renderer.Server.MemoryPool
}
///
- /// Set the and size of the .
+ /// Set the and size of the .
///
/// The .
/// The size.
@@ -84,11 +84,11 @@ namespace Ryujinx.Audio.Renderer.Server.MemoryPool
}
///
- /// Check if the given and size is contains in the .
+ /// Check if the given and size is contains in the .
///
/// The .
/// The size.
- /// True if the is contained inside the .
+ /// True if the is contained inside the .
public readonly bool Contains(CpuAddress targetCpuAddress, ulong size)
{
if (CpuAddress <= targetCpuAddress && size + targetCpuAddress <= Size + CpuAddress)
@@ -118,9 +118,9 @@ namespace Ryujinx.Audio.Renderer.Server.MemoryPool
}
///
- /// Is the mapped on the DSP?
+ /// Is the mapped on the DSP?
///
- /// Returns true if the is mapped on the DSP.
+ /// Returns true if the is mapped on the DSP.
public readonly bool IsMapped()
{
return DspAddress != 0;
diff --git a/src/Ryujinx.Audio/Renderer/Server/MemoryPool/PoolMapper.cs b/src/Ryujinx.Audio/Renderer/Server/MemoryPool/PoolMapper.cs
index 535e2fd79..2b7153b54 100644
--- a/src/Ryujinx.Audio/Renderer/Server/MemoryPool/PoolMapper.cs
+++ b/src/Ryujinx.Audio/Renderer/Server/MemoryPool/PoolMapper.cs
@@ -18,7 +18,7 @@ namespace Ryujinx.Audio.Renderer.Server.MemoryPool
const uint CurrentProcessPseudoHandle = 0xFFFF8001;
///
- /// The result of .
+ /// The result of .
///
public enum UpdateResult : uint
{
@@ -49,9 +49,9 @@ namespace Ryujinx.Audio.Renderer.Server.MemoryPool
private readonly uint _processHandle;
///
- /// The that will be manipulated.
+ /// The that will be manipulated.
///
- private readonly Memory _memoryPools;
+ private readonly Memory _memoryPools;
///
/// If set to true, this will try to force map memory pool even if their state are considered invalid.
@@ -67,7 +67,7 @@ namespace Ryujinx.Audio.Renderer.Server.MemoryPool
{
_processHandle = processHandle;
_isForceMapEnabled = isForceMapEnabled;
- _memoryPools = Memory.Empty;
+ _memoryPools = Memory.Empty;
}
///
@@ -76,7 +76,7 @@ namespace Ryujinx.Audio.Renderer.Server.MemoryPool
/// The handle of the process owning the CPU memory manipulated.
/// The user memory pools.
/// If set to true, this will try to force map memory pool even if their state are considered invalid.
- public PoolMapper(uint processHandle, Memory memoryPool, bool isForceMapEnabled)
+ public PoolMapper(uint processHandle, Memory memoryPool, bool isForceMapEnabled)
{
_processHandle = processHandle;
_memoryPools = memoryPool;
@@ -84,15 +84,15 @@ namespace Ryujinx.Audio.Renderer.Server.MemoryPool
}
///
- /// Initialize the for system use.
+ /// Initialize the for system use.
///
- /// The for system use.
+ /// The for system use.
/// The to assign.
/// The size to assign.
/// Returns true if mapping on the succeeded.
- public bool InitializeSystemPool(ref MemoryPoolState memoryPool, CpuAddress cpuAddress, ulong size)
+ public bool InitializeSystemPool(ref MemoryPoolInfo memoryPool, CpuAddress cpuAddress, ulong size)
{
- if (memoryPool.Location != MemoryPoolState.LocationType.Dsp)
+ if (memoryPool.Location != MemoryPoolInfo.LocationType.Dsp)
{
return false;
}
@@ -101,13 +101,13 @@ namespace Ryujinx.Audio.Renderer.Server.MemoryPool
}
///
- /// Initialize the .
+ /// Initialize the .
///
- /// The .
+ /// The .
/// The to assign.
/// The size to assign.
/// Returns true if mapping on the succeeded.
- public bool InitializePool(ref MemoryPoolState memoryPool, CpuAddress cpuAddress, ulong size)
+ public bool InitializePool(ref MemoryPoolInfo memoryPool, CpuAddress cpuAddress, ulong size)
{
memoryPool.SetCpuAddress(cpuAddress, size);
@@ -115,18 +115,18 @@ namespace Ryujinx.Audio.Renderer.Server.MemoryPool
}
///
- /// Get the process handle associated to the .
+ /// Get the process handle associated to the .
///
- /// The .
- /// Returns the process handle associated to the .
- public uint GetProcessHandle(ref MemoryPoolState memoryPool)
+ /// The .
+ /// Returns the process handle associated to the .
+ public uint GetProcessHandle(ref MemoryPoolInfo memoryPool)
{
- if (memoryPool.Location == MemoryPoolState.LocationType.Cpu)
+ if (memoryPool.Location == MemoryPoolInfo.LocationType.Cpu)
{
return CurrentProcessPseudoHandle;
}
- if (memoryPool.Location == MemoryPoolState.LocationType.Dsp)
+ if (memoryPool.Location == MemoryPoolInfo.LocationType.Dsp)
{
return _processHandle;
}
@@ -135,11 +135,11 @@ namespace Ryujinx.Audio.Renderer.Server.MemoryPool
}
///
- /// Map the on the .
+ /// Map the on the .
///
- /// The to map.
+ /// The to map.
/// Returns the DSP address mapped.
- public DspAddress Map(ref MemoryPoolState memoryPool)
+ public DspAddress Map(ref MemoryPoolInfo memoryPool)
{
DspAddress result = AudioProcessorMemoryManager.Map(GetProcessHandle(ref memoryPool), memoryPool.CpuAddress, memoryPool.Size);
@@ -152,11 +152,11 @@ namespace Ryujinx.Audio.Renderer.Server.MemoryPool
}
///
- /// Unmap the from the .
+ /// Unmap the from the .
///
- /// The to unmap.
+ /// The to unmap.
/// Returns true if unmapped.
- public bool Unmap(ref MemoryPoolState memoryPool)
+ public bool Unmap(ref MemoryPoolInfo memoryPool)
{
if (memoryPool.IsUsed)
{
@@ -172,12 +172,12 @@ namespace Ryujinx.Audio.Renderer.Server.MemoryPool
}
///
- /// Find a associated to the region given.
+ /// Find a associated to the region given.
///
/// The region .
/// The region size.
- /// Returns the found or if not found.
- private Span FindMemoryPool(CpuAddress cpuAddress, ulong size)
+ /// Returns the found or if not found.
+ private Span FindMemoryPool(CpuAddress cpuAddress, ulong size)
{
if (!_memoryPools.IsEmpty && _memoryPools.Length > 0)
{
@@ -190,7 +190,7 @@ namespace Ryujinx.Audio.Renderer.Server.MemoryPool
}
}
- return Span.Empty;
+ return Span.Empty;
}
///
@@ -201,7 +201,7 @@ namespace Ryujinx.Audio.Renderer.Server.MemoryPool
{
if (_isForceMapEnabled)
{
- Span memoryPool = FindMemoryPool(addressInfo.CpuAddress, addressInfo.Size);
+ Span memoryPool = FindMemoryPool(addressInfo.CpuAddress, addressInfo.Size);
if (!memoryPool.IsEmpty)
{
@@ -243,13 +243,13 @@ namespace Ryujinx.Audio.Renderer.Server.MemoryPool
}
///
- /// Update a using user parameters.
+ /// Update a using user parameters.
///
- /// The to update.
+ /// The to update.
/// Input user parameter.
/// Output user parameter.
/// Returns the of the operations performed.
- public UpdateResult Update(ref MemoryPoolState memoryPool, in MemoryPoolInParameter inParameter, ref MemoryPoolOutStatus outStatus)
+ public UpdateResult Update(ref MemoryPoolInfo memoryPool, in MemoryPoolInParameter inParameter, ref MemoryPoolOutStatus outStatus)
{
MemoryPoolUserState inputState = inParameter.State;
@@ -321,7 +321,7 @@ namespace Ryujinx.Audio.Renderer.Server.MemoryPool
if (_memoryPools.Length > 0)
{
- Span memoryPool = FindMemoryPool(addressInfo.CpuAddress, addressInfo.Size);
+ Span memoryPool = FindMemoryPool(addressInfo.CpuAddress, addressInfo.Size);
if (!memoryPool.IsEmpty)
{
@@ -343,7 +343,7 @@ namespace Ryujinx.Audio.Renderer.Server.MemoryPool
{
unsafe
{
- addressInfo.SetupMemoryPool(MemoryPoolState.Null);
+ addressInfo.SetupMemoryPool(MemoryPoolInfo.Null);
}
}
@@ -351,12 +351,12 @@ namespace Ryujinx.Audio.Renderer.Server.MemoryPool
}
///
- /// Remove the usage flag from all the .
+ /// Remove the usage flag from all the .
///
- /// The to reset.
- public static void ClearUsageState(Memory memoryPool)
+ /// The to reset.
+ public static void ClearUsageState(Memory memoryPool)
{
- foreach (ref MemoryPoolState info in memoryPool.Span)
+ foreach (ref MemoryPoolInfo info in memoryPool.Span)
{
info.IsUsed = false;
}
diff --git a/src/Ryujinx.Audio/Renderer/Server/Mix/MixContext.cs b/src/Ryujinx.Audio/Renderer/Server/Mix/MixContext.cs
index 8991ceaf9..cdb6511cb 100644
--- a/src/Ryujinx.Audio/Renderer/Server/Mix/MixContext.cs
+++ b/src/Ryujinx.Audio/Renderer/Server/Mix/MixContext.cs
@@ -17,12 +17,12 @@ namespace Ryujinx.Audio.Renderer.Server.Mix
private uint _mixesCount;
///
- /// Storage for .
+ /// Storage for .
///
- private Memory _mixes;
+ private Memory _mixes;
///
- /// Storage of the sorted indices to .
+ /// Storage of the sorted indices to .
///
private Memory _sortedMixes;
@@ -49,10 +49,10 @@ namespace Ryujinx.Audio.Renderer.Server.Mix
/// Initialize the .
///
/// The storage for sorted indices.
- /// The storage of .
+ /// The storage of .
/// The storage used for the .
/// The storage used for the .
- public void Initialize(Memory sortedMixes, Memory mixes, Memory nodeStatesWorkBuffer, Memory edgeMatrixWorkBuffer)
+ public void Initialize(Memory sortedMixes, Memory mixes, Memory nodeStatesWorkBuffer, Memory edgeMatrixWorkBuffer)
{
_mixesCount = (uint)mixes.Length;
_mixes = mixes;
@@ -82,30 +82,30 @@ namespace Ryujinx.Audio.Renderer.Server.Mix
}
///
- /// Get a reference to the final .
+ /// Get a reference to the final .
///
- /// A reference to the final .
- public ref MixState GetFinalState()
+ /// A reference to the final .
+ public ref MixInfo GetFinalState()
{
return ref GetState(Constants.FinalMixId);
}
///
- /// Get a reference to a at the given .
+ /// Get a reference to a at the given .
///
/// The index to use.
- /// A reference to a at the given .
- public ref MixState GetState(int id)
+ /// A reference to a at the given .
+ public ref MixInfo GetState(int id)
{
return ref SpanIOHelper.GetFromMemory(_mixes, id, _mixesCount);
}
///
- /// Get a reference to a at the given of the sorted mix info.
+ /// Get a reference to a at the given of the sorted mix info.
///
/// The index to use.
- /// A reference to a at the given .
- public ref MixState GetSortedState(int id)
+ /// A reference to a at the given .
+ public ref MixInfo GetSortedState(int id)
{
Debug.Assert(id >= 0 && id < _mixesCount);
@@ -122,18 +122,18 @@ namespace Ryujinx.Audio.Renderer.Server.Mix
}
///
- /// Update the internal distance from the final mix value of every .
+ /// Update the internal distance from the final mix value of every .
///
private void UpdateDistancesFromFinalMix()
{
- foreach (ref MixState mix in _mixes.Span)
+ foreach (ref MixInfo mix in _mixes.Span)
{
mix.ClearDistanceFromFinalMix();
}
for (int i = 0; i < GetCount(); i++)
{
- ref MixState mix = ref GetState(i);
+ ref MixInfo mix = ref GetState(i);
SetSortedState(i, i);
@@ -149,13 +149,13 @@ namespace Ryujinx.Audio.Renderer.Server.Mix
{
if (mixId == Constants.UnusedMixId)
{
- distance = MixState.InvalidDistanceFromFinalMix;
+ distance = MixInfo.InvalidDistanceFromFinalMix;
break;
}
- ref MixState distanceMix = ref GetState(mixId);
+ ref MixInfo distanceMix = ref GetState(mixId);
- if (distanceMix.DistanceFromFinalMix != MixState.InvalidDistanceFromFinalMix)
+ if (distanceMix.DistanceFromFinalMix != MixInfo.InvalidDistanceFromFinalMix)
{
distance = distanceMix.DistanceFromFinalMix + 1;
break;
@@ -171,12 +171,12 @@ namespace Ryujinx.Audio.Renderer.Server.Mix
if (distance > GetCount())
{
- distance = MixState.InvalidDistanceFromFinalMix;
+ distance = MixInfo.InvalidDistanceFromFinalMix;
}
}
else
{
- distance = MixState.InvalidDistanceFromFinalMix;
+ distance = MixInfo.InvalidDistanceFromFinalMix;
}
mix.DistanceFromFinalMix = distance;
@@ -185,13 +185,13 @@ namespace Ryujinx.Audio.Renderer.Server.Mix
}
///
- /// Update the internal mix buffer offset of all .
+ /// Update the internal mix buffer offset of all .
///
private void UpdateMixBufferOffset()
{
uint offset = 0;
- foreach (ref MixState mix in _mixes.Span)
+ foreach (ref MixInfo mix in _mixes.Span)
{
mix.BufferOffset = offset;
@@ -210,10 +210,10 @@ namespace Ryujinx.Audio.Renderer.Server.Mix
Array.Sort(sortedMixesTemp, (a, b) =>
{
- ref MixState stateA = ref GetState(a);
- ref MixState stateB = ref GetState(b);
+ ref MixInfo infoA = ref GetState(a);
+ ref MixInfo infoB = ref GetState(b);
- return stateB.DistanceFromFinalMix.CompareTo(stateA.DistanceFromFinalMix);
+ return infoB.DistanceFromFinalMix.CompareTo(infoA.DistanceFromFinalMix);
});
sortedMixesTemp.AsSpan().CopyTo(_sortedMixes.Span);
diff --git a/src/Ryujinx.Audio/Renderer/Server/Mix/MixState.cs b/src/Ryujinx.Audio/Renderer/Server/Mix/MixInfo.cs
similarity index 93%
rename from src/Ryujinx.Audio/Renderer/Server/Mix/MixState.cs
rename to src/Ryujinx.Audio/Renderer/Server/Mix/MixInfo.cs
index 34b3ed4bd..eae141a66 100644
--- a/src/Ryujinx.Audio/Renderer/Server/Mix/MixState.cs
+++ b/src/Ryujinx.Audio/Renderer/Server/Mix/MixInfo.cs
@@ -15,7 +15,7 @@ namespace Ryujinx.Audio.Renderer.Server.Mix
/// Server state for a mix.
///
[StructLayout(LayoutKind.Sequential, Size = 0x940, Pack = Alignment)]
- public struct MixState
+ public struct MixInfo
{
public const uint InvalidDistanceFromFinalMix = 0x80000000;
@@ -136,11 +136,11 @@ namespace Ryujinx.Audio.Renderer.Server.Mix
}
///
- /// Create a new
+ /// Create a new
///
///
- ///
- public MixState(Memory effectProcessingOrderArray, ref BehaviourContext behaviourContext) : this()
+ ///
+ public MixInfo(Memory effectProcessingOrderArray, ref BehaviourInfo behaviourInfo) : this()
{
MixId = UnusedMixId;
@@ -158,7 +158,7 @@ namespace Ryujinx.Audio.Renderer.Server.Mix
EffectProcessingOrderArrayMaxCount = (uint)effectProcessingOrderArray.Length;
- IsLongSizePreDelaySupported = behaviourContext.IsLongSizePreDelaySupported();
+ IsLongSizePreDelaySupported = behaviourInfo.IsLongSizePreDelaySupported();
ClearEffectProcessingOrder();
}
@@ -257,9 +257,9 @@ namespace Ryujinx.Audio.Renderer.Server.Mix
/// The input parameter of the mix.
/// The effect context.
/// The splitter context.
- /// The behaviour context.
+ /// The behaviour context.
/// Return true if the mix was changed.
- public bool Update(EdgeMatrix edgeMatrix, in MixParameter parameter, EffectContext effectContext, SplitterContext splitterContext, BehaviourContext behaviourContext)
+ public bool Update(EdgeMatrix edgeMatrix, in MixParameter parameter, EffectContext effectContext, SplitterContext splitterContext, BehaviourInfo behaviourInfo)
{
bool isDirty;
@@ -271,7 +271,7 @@ namespace Ryujinx.Audio.Renderer.Server.Mix
NodeId = parameter.NodeId;
parameter.MixBufferVolume.CopyTo(MixBufferVolume);
- if (behaviourContext.IsSplitterSupported())
+ if (behaviourInfo.IsSplitterSupported())
{
isDirty = UpdateConnection(edgeMatrix, in parameter, ref splitterContext);
}
@@ -279,10 +279,7 @@ namespace Ryujinx.Audio.Renderer.Server.Mix
{
isDirty = DestinationMixId != parameter.DestinationMixId;
- if (DestinationMixId != parameter.DestinationMixId)
- {
- DestinationMixId = parameter.DestinationMixId;
- }
+ DestinationMixId = parameter.DestinationMixId;
DestinationSplitterId = UnusedSplitterId;
}
diff --git a/src/Ryujinx.Audio/Renderer/Server/Performance/PerformanceManager.cs b/src/Ryujinx.Audio/Renderer/Server/Performance/PerformanceManager.cs
index da5a0ad45..e430d99c3 100644
--- a/src/Ryujinx.Audio/Renderer/Server/Performance/PerformanceManager.cs
+++ b/src/Ryujinx.Audio/Renderer/Server/Performance/PerformanceManager.cs
@@ -10,11 +10,11 @@ namespace Ryujinx.Audio.Renderer.Server.Performance
/// Get the required size for a single performance frame.
///
/// The audio renderer configuration.
- /// The behaviour context.
+ /// The behaviour context.
/// The required size for a single performance frame.
- public static ulong GetRequiredBufferSizeForPerformanceMetricsPerFrame(ref AudioRendererConfiguration parameter, ref BehaviourContext behaviourContext)
+ public static ulong GetRequiredBufferSizeForPerformanceMetricsPerFrame(ref AudioRendererConfiguration parameter, ref BehaviourInfo behaviourInfo)
{
- uint version = behaviourContext.GetPerformanceMetricsDataFormat();
+ uint version = behaviourInfo.GetPerformanceMetricsDataFormat();
if (version == 2)
{
@@ -81,11 +81,11 @@ namespace Ryujinx.Audio.Renderer.Server.Performance
///
/// The backing memory available for use by the manager.
/// The audio renderer configuration.
- /// The behaviour context;
+ /// The behaviour context;
/// A new .
- public static PerformanceManager Create(Memory performanceBuffer, ref AudioRendererConfiguration parameter, BehaviourContext behaviourContext)
+ public static PerformanceManager Create(Memory performanceBuffer, ref AudioRendererConfiguration parameter, BehaviourInfo behaviourInfo)
{
- uint version = behaviourContext.GetPerformanceMetricsDataFormat();
+ uint version = behaviourInfo.GetPerformanceMetricsDataFormat();
return version switch
{
diff --git a/src/Ryujinx.Audio/Renderer/Server/RendererSystemContext.cs b/src/Ryujinx.Audio/Renderer/Server/RendererSystemContext.cs
index 090850018..fa7a24d09 100644
--- a/src/Ryujinx.Audio/Renderer/Server/RendererSystemContext.cs
+++ b/src/Ryujinx.Audio/Renderer/Server/RendererSystemContext.cs
@@ -1,3 +1,4 @@
+using Ryujinx.Audio.Renderer.Server.Mix;
using Ryujinx.Audio.Renderer.Server.Upsampler;
using System;
@@ -19,7 +20,7 @@ namespace Ryujinx.Audio.Renderer.Server
///
/// The target channel count for sink.
///
- /// See for usage.
+ /// See for usage.
public uint ChannelCount;
///
@@ -28,12 +29,12 @@ namespace Ryujinx.Audio.Renderer.Server
public uint MixBufferCount;
///
- /// Instance of the used to derive bug fixes and features of the current audio renderer revision.
+ /// Instance of the used to derive bug fixes and features of the current audio renderer revision.
///
- public BehaviourContext BehaviourContext;
+ public BehaviourInfo BehaviourInfo;
///
- /// Instance of the used for upsampling (see )
+ /// Instance of the used for upsampling (see )
///
public UpsamplerManager UpsamplerManager;
diff --git a/src/Ryujinx.Audio/Renderer/Server/Sink/DeviceSink.cs b/src/Ryujinx.Audio/Renderer/Server/Sink/DeviceSink.cs
index afe2d4b1b..c590b69d9 100644
--- a/src/Ryujinx.Audio/Renderer/Server/Sink/DeviceSink.cs
+++ b/src/Ryujinx.Audio/Renderer/Server/Sink/DeviceSink.cs
@@ -28,7 +28,7 @@ namespace Ryujinx.Audio.Renderer.Server.Sink
/// The upsampler instance used by this sink.
///
/// Null if no upsampling is needed.
- public UpsamplerState UpsamplerState;
+ public UpsamplerInfo UpsamplerInfo;
///
/// Create a new .
@@ -40,9 +40,9 @@ namespace Ryujinx.Audio.Renderer.Server.Sink
public override void CleanUp()
{
- UpsamplerState?.Release();
+ UpsamplerInfo?.Release();
- UpsamplerState = null;
+ UpsamplerInfo = null;
base.CleanUp();
}
diff --git a/src/Ryujinx.Audio/Renderer/Server/Splitter/SplitterContext.cs b/src/Ryujinx.Audio/Renderer/Server/Splitter/SplitterContext.cs
index 6dddb4315..7d914e137 100644
--- a/src/Ryujinx.Audio/Renderer/Server/Splitter/SplitterContext.cs
+++ b/src/Ryujinx.Audio/Renderer/Server/Splitter/SplitterContext.cs
@@ -55,22 +55,27 @@ namespace Ryujinx.Audio.Renderer.Server.Splitter
/// If set to true, the previous mix volume is explicitly resetted using the input parameter, instead of implicitly on first use.
///
public bool IsSplitterPrevVolumeResetSupported { get; private set; }
+
+ ///
+ /// If set to true, the previous mix volume is explicitly resetted using the input parameter, instead of implicitly on first use.
+ ///
+ public bool IsBiquadFilterParameterFloatSupported { get; private set; }
///
/// Initialize .
///
- /// The behaviour context.
+ /// The behaviour context.
/// The audio renderer configuration.
/// The .
/// Memory to store the biquad filtering state for splitters during processing.
/// Return true if the initialization was successful.
public bool Initialize(
- ref BehaviourContext behaviourContext,
+ ref BehaviourInfo behaviourInfo,
ref AudioRendererConfiguration parameter,
WorkBufferAllocator workBufferAllocator,
Memory splitterBqfStates)
{
- if (!behaviourContext.IsSplitterSupported() || parameter.SplitterCount <= 0 || parameter.SplitterDestinationCount <= 0)
+ if (!behaviourInfo.IsSplitterSupported() || parameter.SplitterCount <= 0 || parameter.SplitterDestinationCount <= 0)
{
Setup(Memory.Empty, Memory.Empty, Memory.Empty, false);
@@ -94,7 +99,7 @@ namespace Ryujinx.Audio.Renderer.Server.Splitter
Memory splitterDestinationsV1 = Memory.Empty;
Memory splitterDestinationsV2 = Memory.Empty;
- if (!behaviourContext.IsBiquadFilterParameterForSplitterEnabled())
+ if (!behaviourInfo.IsBiquadFilterParameterForSplitterEnabled())
{
Version = 1;
@@ -144,11 +149,12 @@ namespace Ryujinx.Audio.Renderer.Server.Splitter
}
}
- IsSplitterPrevVolumeResetSupported = behaviourContext.IsSplitterPrevVolumeResetSupported();
+ IsSplitterPrevVolumeResetSupported = behaviourInfo.IsSplitterPrevVolumeResetSupported();
+ IsBiquadFilterParameterFloatSupported = behaviourInfo.IsBiquadFilterParameterFloatSupported();
SplitterState.InitializeSplitters(splitters.Span);
- Setup(splitters, splitterDestinationsV1, splitterDestinationsV2, behaviourContext.IsSplitterBugFixed());
+ Setup(splitters, splitterDestinationsV1, splitterDestinationsV2, behaviourInfo.IsSplitterBugFixed());
return true;
}
@@ -157,16 +163,16 @@ namespace Ryujinx.Audio.Renderer.Server.Splitter
/// Get the work buffer size while adding the size needed for splitter to operate.
///
/// The current size.
- /// The behaviour context.
+ /// The behaviour context.
/// The renderer configuration.
/// Return the new size taking splitter into account.
- public static ulong GetWorkBufferSize(ulong size, ref BehaviourContext behaviourContext, ref AudioRendererConfiguration parameter)
+ public static ulong GetWorkBufferSize(ulong size, ref BehaviourInfo behaviourInfo, ref AudioRendererConfiguration parameter)
{
- if (behaviourContext.IsSplitterSupported())
+ if (behaviourInfo.IsSplitterSupported())
{
size = WorkBufferAllocator.GetTargetSize(size, parameter.SplitterCount, SplitterState.Alignment);
- if (behaviourContext.IsBiquadFilterParameterForSplitterEnabled())
+ if (behaviourInfo.IsBiquadFilterParameterForSplitterEnabled())
{
size = WorkBufferAllocator.GetTargetSize(size, parameter.SplitterDestinationCount, SplitterDestinationVersion2.Alignment);
}
@@ -175,12 +181,10 @@ namespace Ryujinx.Audio.Renderer.Server.Splitter
size = WorkBufferAllocator.GetTargetSize(size, parameter.SplitterDestinationCount, SplitterDestinationVersion1.Alignment);
}
- if (behaviourContext.IsSplitterBugFixed())
+ if (behaviourInfo.IsSplitterBugFixed())
{
size = WorkBufferAllocator.GetTargetSize(size, parameter.SplitterDestinationCount, 0x10);
}
-
- return size;
}
return size;
@@ -227,7 +231,16 @@ namespace Ryujinx.Audio.Renderer.Server.Splitter
return 0;
}
- int length = _splitterDestinationsV2.IsEmpty ? _splitterDestinationsV1.Length : _splitterDestinationsV2.Length;
+ int length;
+
+ if (_splitterDestinationsV2.IsEmpty)
+ {
+ length = _splitterDestinationsV1.Length;
+ }
+ else
+ {
+ length = _splitterDestinationsV2.Length;
+ }
return length / _splitters.Length;
}
@@ -278,8 +291,17 @@ namespace Ryujinx.Audio.Renderer.Server.Splitter
if (parameter.IsMagicValid())
{
- int length = _splitterDestinationsV2.IsEmpty ? _splitterDestinationsV1.Length : _splitterDestinationsV2.Length;
+ int length;
+ if (_splitterDestinationsV2.IsEmpty)
+ {
+ length = _splitterDestinationsV1.Length;
+ }
+ else
+ {
+ length = _splitterDestinationsV2.Length;
+ }
+
if (parameter.Id >= 0 && parameter.Id < length)
{
SplitterDestination destination = GetDestination(parameter.Id);
@@ -315,9 +337,19 @@ namespace Ryujinx.Audio.Renderer.Server.Splitter
}
else if (Version == 2)
{
- if (!UpdateData(ref input))
+ if (IsBiquadFilterParameterFloatSupported)
{
- break;
+ if (!UpdateData(ref input))
+ {
+ break;
+ }
+ }
+ else
+ {
+ if (!UpdateData(ref input))
+ {
+ break;
+ }
}
}
else
@@ -381,10 +413,8 @@ namespace Ryujinx.Audio.Renderer.Server.Splitter
{
return new SplitterDestination(ref SpanIOHelper.GetFromMemory(_splitterDestinationsV1, id, (uint)_splitterDestinationsV1.Length));
}
- else
- {
- return new SplitterDestination(ref SpanIOHelper.GetFromMemory(_splitterDestinationsV2, id, (uint)_splitterDestinationsV2.Length));
- }
+
+ return new SplitterDestination(ref SpanIOHelper.GetFromMemory(_splitterDestinationsV2, id, (uint)_splitterDestinationsV2.Length));
}
///
diff --git a/src/Ryujinx.Audio/Renderer/Server/Splitter/SplitterDestination.cs b/src/Ryujinx.Audio/Renderer/Server/Splitter/SplitterDestination.cs
index 1a46d41fd..1253e5d2c 100644
--- a/src/Ryujinx.Audio/Renderer/Server/Splitter/SplitterDestination.cs
+++ b/src/Ryujinx.Audio/Renderer/Server/Splitter/SplitterDestination.cs
@@ -31,15 +31,11 @@ namespace Ryujinx.Audio.Renderer.Server.Splitter
{
return 0;
}
- else
- {
- return _v1.Id;
- }
- }
- else
- {
- return _v2.Id;
+
+ return _v1.Id;
}
+
+ return _v2.Id;
}
}
@@ -56,15 +52,11 @@ namespace Ryujinx.Audio.Renderer.Server.Splitter
{
return 0;
}
- else
- {
- return _v1.DestinationId;
- }
- }
- else
- {
- return _v2.DestinationId;
+
+ return _v1.DestinationId;
}
+
+ return _v2.DestinationId;
}
}
@@ -82,15 +74,11 @@ namespace Ryujinx.Audio.Renderer.Server.Splitter
{
return Span.Empty;
}
- else
- {
- return _v1.MixBufferVolume;
- }
- }
- else
- {
- return _v2.MixBufferVolume;
+
+ return _v1.MixBufferVolume;
}
+
+ return _v2.MixBufferVolume;
}
}
@@ -108,15 +96,11 @@ namespace Ryujinx.Audio.Renderer.Server.Splitter
{
return Span.Empty;
}
- else
- {
- return _v1.PreviousMixBufferVolume;
- }
- }
- else
- {
- return _v2.PreviousMixBufferVolume;
+
+ return _v1.PreviousMixBufferVolume;
}
+
+ return _v2.PreviousMixBufferVolume;
}
}
@@ -135,15 +119,11 @@ namespace Ryujinx.Audio.Renderer.Server.Splitter
{
return new SplitterDestination();
}
- else
- {
- return new SplitterDestination(ref _v1.Next);
- }
- }
- else
- {
- return new SplitterDestination(ref _v2.Next);
+
+ return new SplitterDestination(ref _v1.Next);
}
+
+ return new SplitterDestination(ref _v2.Next);
}
}
}
@@ -169,6 +149,7 @@ namespace Ryujinx.Audio.Renderer.Server.Splitter
_v2 = ref v2;
}
+
///
/// Creates a new splitter destination wrapper for the splitter destination data.
///
@@ -233,7 +214,12 @@ namespace Ryujinx.Audio.Renderer.Server.Splitter
/// True if the splitter destination is used and has a destination.
public readonly bool IsConfigured()
{
- return Unsafe.IsNullRef(ref _v2) ? _v1.IsConfigured() : _v2.IsConfigured();
+ if (Unsafe.IsNullRef(ref _v2))
+ {
+ return _v1.IsConfigured();
+ }
+
+ return _v2.IsConfigured();
}
///
@@ -243,7 +229,12 @@ namespace Ryujinx.Audio.Renderer.Server.Splitter
/// The volume for the given destination.
public float GetMixVolume(int destinationIndex)
{
- return Unsafe.IsNullRef(ref _v2) ? _v1.GetMixVolume(destinationIndex) : _v2.GetMixVolume(destinationIndex);
+ if (Unsafe.IsNullRef(ref _v2))
+ {
+ return _v1.GetMixVolume(destinationIndex);
+ }
+
+ return _v2.GetMixVolume(destinationIndex);
}
///
@@ -253,7 +244,12 @@ namespace Ryujinx.Audio.Renderer.Server.Splitter
/// The volume for the given destination.
public float GetMixVolumePrev(int destinationIndex)
{
- return Unsafe.IsNullRef(ref _v2) ? _v1.GetMixVolumePrev(destinationIndex) : _v2.GetMixVolumePrev(destinationIndex);
+ if (Unsafe.IsNullRef(ref _v2))
+ {
+ return _v1.GetMixVolumePrev(destinationIndex);
+ }
+
+ return _v2.GetMixVolumePrev(destinationIndex);
}
///
@@ -280,13 +276,13 @@ namespace Ryujinx.Audio.Renderer.Server.Splitter
if (Unsafe.IsNullRef(ref _v2))
{
Debug.Assert(!Unsafe.IsNullRef(ref next._v1));
-
+
_v1.Link(ref next._v1);
}
else
{
Debug.Assert(!Unsafe.IsNullRef(ref next._v2));
-
+
_v2.Link(ref next._v2);
}
}
@@ -308,6 +304,7 @@ namespace Ryujinx.Audio.Renderer.Server.Splitter
///
/// Checks if any biquad filter is enabled.
+ /// Virtual function at function table + 0x8.
///
/// True if any biquad filter is enabled.
public bool IsBiquadFilterEnabled()
@@ -326,13 +323,14 @@ namespace Ryujinx.Audio.Renderer.Server.Splitter
///
/// Gets the biquad filter parameters.
+ /// /// Virtual function at function table + 0x10.
///
/// Biquad filter index (0 or 1).
/// Biquad filter parameters.
- public ref BiquadFilterParameter GetBiquadFilterParameter(int index)
+ public ref BiquadFilterParameter2 GetBiquadFilterParameter(int index)
{
Debug.Assert(!Unsafe.IsNullRef(ref _v2));
-
+
return ref _v2.GetBiquadFilterParameter(index);
}
diff --git a/src/Ryujinx.Audio/Renderer/Server/Splitter/SplitterDestinationVersion2.cs b/src/Ryujinx.Audio/Renderer/Server/Splitter/SplitterDestinationVersion2.cs
index 3102ccdf0..7fb455241 100644
--- a/src/Ryujinx.Audio/Renderer/Server/Splitter/SplitterDestinationVersion2.cs
+++ b/src/Ryujinx.Audio/Renderer/Server/Splitter/SplitterDestinationVersion2.cs
@@ -1,3 +1,4 @@
+using Ryujinx.Audio.Renderer.Dsp;
using Ryujinx.Audio.Renderer.Parameter;
using Ryujinx.Common.Memory;
using Ryujinx.Common.Utilities;
@@ -11,7 +12,7 @@ namespace Ryujinx.Audio.Renderer.Server.Splitter
///
/// Server state for a splitter destination (version 2).
///
- [StructLayout(LayoutKind.Sequential, Size = 0x110, Pack = Alignment)]
+ [StructLayout(LayoutKind.Sequential, Size = 0x128, Pack = Alignment)]
public struct SplitterDestinationVersion2
{
public const int Alignment = 0x10;
@@ -78,7 +79,7 @@ namespace Ryujinx.Audio.Renderer.Server.Splitter
}
}
- private Array2 _biquadFilters;
+ private Array2 _biquadFilters;
private Array2 _isPreviousBiquadFilterEnabled;
@@ -109,7 +110,7 @@ namespace Ryujinx.Audio.Renderer.Server.Splitter
parameter.MixBufferVolume.CopyTo(MixBufferVolume);
- _biquadFilters = parameter.BiquadFilters;
+ _biquadFilters = parameter.BiquadFilters2;
bool resetPrevVolume = isPrevVolumeResetSupported ? parameter.ResetPrevVolume : !IsUsed && parameter.IsUsed;
if (resetPrevVolume)
@@ -218,7 +219,7 @@ namespace Ryujinx.Audio.Renderer.Server.Splitter
/// True if any biquad filter is enabled.
public bool IsBiquadFilterEnabled()
{
- Span biquadFiltersSpan = _biquadFilters.AsSpan();
+ Span biquadFiltersSpan = _biquadFilters.AsSpan();
return biquadFiltersSpan[0].Enable || biquadFiltersSpan[1].Enable;
}
@@ -236,7 +237,7 @@ namespace Ryujinx.Audio.Renderer.Server.Splitter
///
/// Biquad filter index (0 or 1).
/// Biquad filter parameters.
- public ref BiquadFilterParameter GetBiquadFilterParameter(int index)
+ public ref BiquadFilterParameter2 GetBiquadFilterParameter(int index)
{
return ref _biquadFilters[index];
}
diff --git a/src/Ryujinx.Audio/Renderer/Server/StateUpdater.cs b/src/Ryujinx.Audio/Renderer/Server/StateUpdater.cs
index 27207a90d..a02d70240 100644
--- a/src/Ryujinx.Audio/Renderer/Server/StateUpdater.cs
+++ b/src/Ryujinx.Audio/Renderer/Server/StateUpdater.cs
@@ -27,39 +27,39 @@ namespace Ryujinx.Audio.Renderer.Server
private Memory _output;
private readonly uint _processHandle;
- private BehaviourContext _behaviourContext;
+ private BehaviourInfo _behaviourInfo;
private readonly ref readonly UpdateDataHeader _inputHeader;
private readonly Memory _outputHeader;
private readonly ref UpdateDataHeader OutputHeader => ref _outputHeader.Span[0];
- public StateUpdater(ReadOnlySequence input, Memory output, uint processHandle, BehaviourContext behaviourContext)
+ public StateUpdater(ReadOnlySequence input, Memory output, uint processHandle, BehaviourInfo behaviourInfo)
{
_inputReader = new SequenceReader(input);
_output = output;
_outputOrigin = _output;
_processHandle = processHandle;
- _behaviourContext = behaviourContext;
+ _behaviourInfo = behaviourInfo;
_inputHeader = ref _inputReader.GetRefOrRefToCopy(out _);
_outputHeader = SpanMemoryManager.Cast(_output[..Unsafe.SizeOf()]);
- OutputHeader.Initialize(_behaviourContext.UserRevision);
+ OutputHeader.Initialize(_behaviourInfo.UserRevision);
_output = _output[Unsafe.SizeOf()..];
}
- public ResultCode UpdateBehaviourContext()
+ public ResultCode UpdateBehaviourInfo()
{
ref readonly BehaviourParameter parameter = ref _inputReader.GetRefOrRefToCopy(out _);
- if (!BehaviourContext.CheckValidRevision(parameter.UserRevision) || parameter.UserRevision != _behaviourContext.UserRevision)
+ if (!BehaviourInfo.CheckValidRevision(parameter.UserRevision) || parameter.UserRevision != _behaviourInfo.UserRevision)
{
return ResultCode.InvalidUpdateInfo;
}
- _behaviourContext.ClearError();
- _behaviourContext.UpdateFlags(parameter.Flags);
+ _behaviourInfo.ClearError();
+ _behaviourInfo.UpdateFlags(parameter.Flags);
if (_inputHeader.BehaviourSize != Unsafe.SizeOf())
{
@@ -69,16 +69,16 @@ namespace Ryujinx.Audio.Renderer.Server
return ResultCode.Success;
}
- public ResultCode UpdateMemoryPools(Span memoryPools)
+ public ResultCode UpdateMemoryPools(Span memoryPools)
{
- PoolMapper mapper = new(_processHandle, _behaviourContext.IsMemoryPoolForceMappingEnabled());
+ PoolMapper mapper = new(_processHandle, _behaviourInfo.IsMemoryPoolForceMappingEnabled());
if (memoryPools.Length * Unsafe.SizeOf() != _inputHeader.MemoryPoolsSize)
{
return ResultCode.InvalidUpdateInfo;
}
- foreach (ref MemoryPoolState memoryPool in memoryPools)
+ foreach (ref MemoryPoolInfo memoryPool in memoryPools)
{
ref readonly MemoryPoolInParameter parameter = ref _inputReader.GetRefOrRefToCopy(out _);
@@ -125,10 +125,10 @@ namespace Ryujinx.Audio.Renderer.Server
return ResultCode.Success;
}
-
- public ResultCode UpdateVoices(VoiceContext context, PoolMapper mapper)
+
+ public ResultCode UpdateVoices2(VoiceContext context, PoolMapper mapper)
{
- if (context.GetCount() * Unsafe.SizeOf() != _inputHeader.VoicesSize)
+ if (context.GetCount() * Unsafe.SizeOf() != _inputHeader.VoicesSize)
{
return ResultCode.InvalidUpdateInfo;
}
@@ -140,27 +140,27 @@ namespace Ryujinx.Audio.Renderer.Server
// First make everything not in use.
for (int i = 0; i < context.GetCount(); i++)
{
- ref VoiceState state = ref context.GetState(i);
+ ref VoiceInfo info = ref context.GetState(i);
- state.InUse = false;
+ info.InUse = false;
}
- Memory[] voiceUpdateStatesArray = ArrayPool>.Shared.Rent(Constants.VoiceChannelCountMax);
+ Memory[] voiceStatesArray = ArrayPool>.Shared.Rent(Constants.VoiceChannelCountMax);
- Span> voiceUpdateStates = voiceUpdateStatesArray.AsSpan(0, Constants.VoiceChannelCountMax);
+ Span> voiceStates = voiceStatesArray.AsSpan(0, Constants.VoiceChannelCountMax);
// Start processing
for (int i = 0; i < context.GetCount(); i++)
{
- ref readonly VoiceInParameter parameter = ref _inputReader.GetRefOrRefToCopy(out _);
+ ref readonly VoiceInParameter2 parameter = ref _inputReader.GetRefOrRefToCopy(out _);
- voiceUpdateStates.Fill(Memory.Empty);
+ voiceStates.Fill(Memory.Empty);
ref VoiceOutStatus outStatus = ref SpanIOHelper.GetWriteRef(ref _output)[0];
if (parameter.InUse)
{
- ref VoiceState currentVoiceState = ref context.GetState(i);
+ ref VoiceInfo currentVoiceInfo = ref context.GetState(i);
Span channelResourceIdsSpan = parameter.ChannelResourceIds.AsSpan();
@@ -170,36 +170,123 @@ namespace Ryujinx.Audio.Renderer.Server
Debug.Assert(channelId >= 0 && channelId < context.GetCount());
- voiceUpdateStates[channelResourceIndex] = context.GetUpdateStateForCpu(channelId);
+ voiceStates[channelResourceIndex] = context.GetUpdateStateForCpu(channelId);
}
if (parameter.IsNew)
{
- currentVoiceState.Initialize();
+ currentVoiceInfo.Initialize();
}
- currentVoiceState.UpdateParameters(out ErrorInfo updateParameterError, in parameter, mapper, ref _behaviourContext);
+ currentVoiceInfo.UpdateParameters2(out ErrorInfo updateParameterError, in parameter, mapper, ref _behaviourInfo);
if (updateParameterError.ErrorCode != ResultCode.Success)
{
- _behaviourContext.AppendError(ref updateParameterError);
+ _behaviourInfo.AppendError(ref updateParameterError);
}
- currentVoiceState.UpdateWaveBuffers(out ErrorInfo[] waveBufferUpdateErrorInfos, in parameter, voiceUpdateStates, mapper, ref _behaviourContext);
+ currentVoiceInfo.UpdateWaveBuffers2(out ErrorInfo[] waveBufferUpdateErrorInfos, in parameter, voiceStates, mapper, ref _behaviourInfo);
foreach (ref ErrorInfo errorInfo in waveBufferUpdateErrorInfos.AsSpan())
{
if (errorInfo.ErrorCode != ResultCode.Success)
{
- _behaviourContext.AppendError(ref errorInfo);
+ _behaviourInfo.AppendError(ref errorInfo);
}
}
- currentVoiceState.WriteOutStatus(ref outStatus, in parameter, voiceUpdateStates);
+ currentVoiceInfo.WriteOutStatus2(ref outStatus, in parameter, voiceStates);
}
}
- ArrayPool>.Shared.Return(voiceUpdateStatesArray);
+ ArrayPool>.Shared.Return(voiceStatesArray);
+
+ int currentOutputSize = _output.Length;
+
+ OutputHeader.VoicesSize = (uint)(Unsafe.SizeOf() * context.GetCount());
+ OutputHeader.TotalSize += OutputHeader.VoicesSize;
+
+ Debug.Assert((initialOutputSize - currentOutputSize) == OutputHeader.VoicesSize);
+
+ _inputReader.SetConsumed(initialInputConsumed + _inputHeader.VoicesSize);
+
+ return ResultCode.Success;
+ }
+
+ public ResultCode UpdateVoices1(VoiceContext context, PoolMapper mapper)
+ {
+ if (context.GetCount() * Unsafe.SizeOf() != _inputHeader.VoicesSize)
+ {
+ return ResultCode.InvalidUpdateInfo;
+ }
+
+ int initialOutputSize = _output.Length;
+
+ long initialInputConsumed = _inputReader.Consumed;
+
+ // First make everything not in use.
+ for (int i = 0; i < context.GetCount(); i++)
+ {
+ ref VoiceInfo info = ref context.GetState(i);
+
+ info.InUse = false;
+ }
+
+ Memory[] voiceStatesArray = ArrayPool>.Shared.Rent(Constants.VoiceChannelCountMax);
+
+ Span> voiceStates = voiceStatesArray.AsSpan(0, Constants.VoiceChannelCountMax);
+
+ // Start processing
+ for (int i = 0; i < context.GetCount(); i++)
+ {
+ ref readonly VoiceInParameter1 parameter = ref _inputReader.GetRefOrRefToCopy(out _);
+
+ voiceStates.Fill(Memory.Empty);
+
+ ref VoiceOutStatus outStatus = ref SpanIOHelper.GetWriteRef(ref _output)[0];
+
+ if (parameter.InUse)
+ {
+ ref VoiceInfo currentVoiceInfo = ref context.GetState(i);
+
+ Span channelResourceIdsSpan = parameter.ChannelResourceIds.AsSpan();
+
+ for (int channelResourceIndex = 0; channelResourceIndex < parameter.ChannelCount; channelResourceIndex++)
+ {
+ int channelId = channelResourceIdsSpan[channelResourceIndex];
+
+ Debug.Assert(channelId >= 0 && channelId < context.GetCount());
+
+ voiceStates[channelResourceIndex] = context.GetUpdateStateForCpu(channelId);
+ }
+
+ if (parameter.IsNew)
+ {
+ currentVoiceInfo.Initialize();
+ }
+
+ currentVoiceInfo.UpdateParameters1(out ErrorInfo updateParameterError, in parameter, mapper, ref _behaviourInfo);
+
+ if (updateParameterError.ErrorCode != ResultCode.Success)
+ {
+ _behaviourInfo.AppendError(ref updateParameterError);
+ }
+
+ currentVoiceInfo.UpdateWaveBuffers1(out ErrorInfo[] waveBufferUpdateErrorInfos, in parameter, voiceStates, mapper, ref _behaviourInfo);
+
+ foreach (ref ErrorInfo errorInfo in waveBufferUpdateErrorInfos.AsSpan())
+ {
+ if (errorInfo.ErrorCode != ResultCode.Success)
+ {
+ _behaviourInfo.AppendError(ref errorInfo);
+ }
+ }
+
+ currentVoiceInfo.WriteOutStatus1(ref outStatus, in parameter, voiceStates);
+ }
+ }
+
+ ArrayPool>.Shared.Return(voiceStatesArray);
int currentOutputSize = _output.Length;
@@ -235,7 +322,12 @@ namespace Ryujinx.Audio.Renderer.Server
public ResultCode UpdateEffects(EffectContext context, bool isAudioRendererActive, PoolMapper mapper)
{
- if (_behaviourContext.IsEffectInfoVersion2Supported())
+ if (_behaviourInfo.IsBiquadFilterParameterFloatSupported())
+ {
+ return UpdateEffectsVersion3(context, isAudioRendererActive, mapper);
+ }
+
+ if (_behaviourInfo.IsEffectInfoVersion2Supported())
{
return UpdateEffectsVersion2(context, isAudioRendererActive, mapper);
}
@@ -243,6 +335,60 @@ 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)
{
if (context.GetCount() * Unsafe.SizeOf() != _inputHeader.EffectsSize)
@@ -271,7 +417,7 @@ namespace Ryujinx.Audio.Renderer.Server
if (updateErrorInfo.ErrorCode != ResultCode.Success)
{
- _behaviourContext.AppendError(ref updateErrorInfo);
+ _behaviourInfo.AppendError(ref updateErrorInfo);
}
effect.StoreStatus(ref outStatus, isAudioRendererActive);
@@ -325,7 +471,7 @@ namespace Ryujinx.Audio.Renderer.Server
if (updateErrorInfo.ErrorCode != ResultCode.Success)
{
- _behaviourContext.AppendError(ref updateErrorInfo);
+ _behaviourInfo.AppendError(ref updateErrorInfo);
}
effect.StoreStatus(ref outStatus, isAudioRendererActive);
@@ -384,7 +530,7 @@ namespace Ryujinx.Audio.Renderer.Server
uint inputMixSize;
uint inputSize = 0;
- if (_behaviourContext.IsMixInParameterDirtyOnlyUpdateSupported())
+ if (_behaviourInfo.IsMixInParameterDirtyOnlyUpdateSupported())
{
ref readonly MixInParameterDirtyOnlyUpdate parameter = ref _inputReader.GetRefOrRefToCopy(out _);
@@ -423,12 +569,12 @@ namespace Ryujinx.Audio.Renderer.Server
int mixId = i;
- if (_behaviourContext.IsMixInParameterDirtyOnlyUpdateSupported())
+ if (_behaviourInfo.IsMixInParameterDirtyOnlyUpdateSupported())
{
mixId = parameter.MixId;
}
- ref MixState mix = ref mixContext.GetState(mixId);
+ ref MixInfo mix = ref mixContext.GetState(mixId);
if (parameter.IsUsed != mix.IsUsed)
{
@@ -444,13 +590,13 @@ namespace Ryujinx.Audio.Renderer.Server
if (mix.IsUsed)
{
- isMixContextDirty |= mix.Update(mixContext.EdgeMatrix, in parameter, effectContext, splitterContext, _behaviourContext);
+ isMixContextDirty |= mix.Update(mixContext.EdgeMatrix, in parameter, effectContext, splitterContext, _behaviourInfo);
}
}
if (isMixContextDirty)
{
- if (_behaviourContext.IsSplitterSupported() && splitterContext.UsingSplitter())
+ if (_behaviourInfo.IsSplitterSupported() && splitterContext.UsingSplitter())
{
if (!mixContext.Sort(splitterContext))
{
@@ -507,7 +653,7 @@ namespace Ryujinx.Audio.Renderer.Server
if (updateErrorInfo.ErrorCode != ResultCode.Success)
{
- _behaviourContext.AppendError(ref updateErrorInfo);
+ _behaviourInfo.AppendError(ref updateErrorInfo);
}
}
@@ -555,7 +701,7 @@ namespace Ryujinx.Audio.Renderer.Server
{
ref BehaviourErrorInfoOutStatus outStatus = ref SpanIOHelper.GetWriteRef(ref _output)[0];
- _behaviourContext.CopyErrorInfo(outStatus.ErrorInfos.AsSpan(), out outStatus.ErrorInfosCount);
+ _behaviourInfo.CopyErrorInfo(outStatus.ErrorInfos.AsSpan(), out outStatus.ErrorInfosCount);
OutputHeader.BehaviourSize = (uint)Unsafe.SizeOf();
OutputHeader.TotalSize += OutputHeader.BehaviourSize;
diff --git a/src/Ryujinx.Audio/Renderer/Server/Types/PlayState.cs b/src/Ryujinx.Audio/Renderer/Server/Types/PlayState.cs
index 46aae05ab..4b72274ce 100644
--- a/src/Ryujinx.Audio/Renderer/Server/Types/PlayState.cs
+++ b/src/Ryujinx.Audio/Renderer/Server/Types/PlayState.cs
@@ -1,7 +1,9 @@
+using Ryujinx.Audio.Renderer.Server.Voice;
+
namespace Ryujinx.Audio.Renderer.Server.Types
{
///
- /// The internal play state of a
+ /// The internal play state of a
///
public enum PlayState
{
@@ -24,7 +26,7 @@ namespace Ryujinx.Audio.Renderer.Server.Types
///
///
/// This is changed to the state after command generation.
- ///
+ ///
///
Stopping,
diff --git a/src/Ryujinx.Audio/Renderer/Server/Upsampler/UpsamplerState.cs b/src/Ryujinx.Audio/Renderer/Server/Upsampler/UpsamplerInfo.cs
similarity index 82%
rename from src/Ryujinx.Audio/Renderer/Server/Upsampler/UpsamplerState.cs
rename to src/Ryujinx.Audio/Renderer/Server/Upsampler/UpsamplerInfo.cs
index 39a58c91a..d84d8fa70 100644
--- a/src/Ryujinx.Audio/Renderer/Server/Upsampler/UpsamplerState.cs
+++ b/src/Ryujinx.Audio/Renderer/Server/Upsampler/UpsamplerInfo.cs
@@ -5,7 +5,7 @@ namespace Ryujinx.Audio.Renderer.Server.Upsampler
///
/// Server state for a upsampling.
///
- public class UpsamplerState
+ public class UpsamplerInfo
{
///
/// The output buffer containing the target samples.
@@ -18,7 +18,7 @@ namespace Ryujinx.Audio.Renderer.Server.Upsampler
public uint SampleCount { get; }
///
- /// The index of the . (used to free it)
+ /// The index of the . (used to free it)
///
private readonly int _index;
@@ -43,13 +43,13 @@ namespace Ryujinx.Audio.Renderer.Server.Upsampler
public UpsamplerBufferState[] BufferStates;
///
- /// Create a new .
+ /// Create a new .
///
/// The upsampler manager.
- /// The index of the . (used to free it)
+ /// The index of the . (used to free it)
/// The output buffer used to contain the target samples.
/// The target sample count.
- public UpsamplerState(UpsamplerManager manager, int index, Memory outputBuffer, uint sampleCount)
+ public UpsamplerInfo(UpsamplerManager manager, int index, Memory outputBuffer, uint sampleCount)
{
_manager = manager;
_index = index;
@@ -58,7 +58,7 @@ namespace Ryujinx.Audio.Renderer.Server.Upsampler
}
///
- /// Release the .
+ /// Release the .
///
public void Release()
{
diff --git a/src/Ryujinx.Audio/Renderer/Server/Upsampler/UpsamplerManager.cs b/src/Ryujinx.Audio/Renderer/Server/Upsampler/UpsamplerManager.cs
index 8b3f39439..942345f8d 100644
--- a/src/Ryujinx.Audio/Renderer/Server/Upsampler/UpsamplerManager.cs
+++ b/src/Ryujinx.Audio/Renderer/Server/Upsampler/UpsamplerManager.cs
@@ -22,7 +22,7 @@ namespace Ryujinx.Audio.Renderer.Server.Upsampler
///
/// The upsamplers instances.
///
- private readonly UpsamplerState[] _upsamplers;
+ private readonly UpsamplerInfo[] _upsamplers;
///
/// The count of upsamplers.
@@ -39,14 +39,14 @@ namespace Ryujinx.Audio.Renderer.Server.Upsampler
_upSamplerWorkBuffer = upSamplerWorkBuffer;
_count = count;
- _upsamplers = new UpsamplerState[_count];
+ _upsamplers = new UpsamplerInfo[_count];
}
///
- /// Allocate a new .
+ /// Allocate a new .
///
- /// A new or null if out of memory.
- public UpsamplerState Allocate()
+ /// A new or null if out of memory.
+ public UpsamplerInfo Allocate()
{
int workBufferOffset = 0;
@@ -56,7 +56,7 @@ namespace Ryujinx.Audio.Renderer.Server.Upsampler
{
if (_upsamplers[i] == null)
{
- _upsamplers[i] = new UpsamplerState(this, i, _upSamplerWorkBuffer.Slice(workBufferOffset, Constants.UpSampleEntrySize), Constants.TargetSampleCount);
+ _upsamplers[i] = new UpsamplerInfo(this, i, _upSamplerWorkBuffer.Slice(workBufferOffset, Constants.UpSampleEntrySize), Constants.TargetSampleCount);
return _upsamplers[i];
}
@@ -69,9 +69,9 @@ namespace Ryujinx.Audio.Renderer.Server.Upsampler
}
///
- /// Free a at the given index.
+ /// Free a at the given index.
///
- /// The index of the to free.
+ /// The index of the to free.
public void Free(int index)
{
lock (_lock)
diff --git a/src/Ryujinx.Audio/Renderer/Server/Voice/VoiceContext.cs b/src/Ryujinx.Audio/Renderer/Server/Voice/VoiceContext.cs
index 827d24fe5..5cb334ddd 100644
--- a/src/Ryujinx.Audio/Renderer/Server/Voice/VoiceContext.cs
+++ b/src/Ryujinx.Audio/Renderer/Server/Voice/VoiceContext.cs
@@ -11,14 +11,14 @@ namespace Ryujinx.Audio.Renderer.Server.Voice
public class VoiceContext
{
///
- /// Storage of the sorted indices to .
+ /// Storage of the sorted indices to .
///
private Memory _sortedVoices;
///
- /// Storage for .
+ /// Storage for .
///
- private Memory _voices;
+ private Memory _voices;
///
/// Storage for .
@@ -26,27 +26,27 @@ namespace Ryujinx.Audio.Renderer.Server.Voice
private Memory _voiceChannelResources;
///
- /// Storage for that are used during audio renderer server updates.
+ /// Storage for that are used during audio renderer server updates.
///
- private Memory _voiceUpdateStatesCpu;
+ private Memory _voiceStatesCpu;
///
- /// Storage for for the .
+ /// Storage for for the .
///
- private Memory _voiceUpdateStatesDsp;
+ private Memory _voiceStatesDsp;
///
/// The total voice count.
///
private uint _voiceCount;
- public void Initialize(Memory sortedVoices, Memory voices, Memory voiceChannelResources, Memory voiceUpdateStatesCpu, Memory voiceUpdateStatesDsp, uint voiceCount)
+ public void Initialize(Memory sortedVoices, Memory voices, Memory voiceChannelResources, Memory voiceStatesCpu, Memory voiceStatesDsp, uint voiceCount)
{
_sortedVoices = sortedVoices;
_voices = voices;
_voiceChannelResources = voiceChannelResources;
- _voiceUpdateStatesCpu = voiceUpdateStatesCpu;
- _voiceUpdateStatesDsp = voiceUpdateStatesDsp;
+ _voiceStatesCpu = voiceStatesCpu;
+ _voiceStatesDsp = voiceStatesDsp;
_voiceCount = voiceCount;
}
@@ -70,38 +70,38 @@ namespace Ryujinx.Audio.Renderer.Server.Voice
}
///
- /// Get a at the given .
+ /// Get a at the given .
///
/// The index to use.
- /// A at the given .
- /// The returned should only be used when updating the server state.
- public Memory GetUpdateStateForCpu(int id)
+ /// A at the given .
+ /// The returned should only be used when updating the server state.
+ public Memory GetUpdateStateForCpu(int id)
{
- return SpanIOHelper.GetMemory(_voiceUpdateStatesCpu, id, _voiceCount);
+ return SpanIOHelper.GetMemory(_voiceStatesCpu, id, _voiceCount);
}
///
- /// Get a at the given .
+ /// Get a at the given .
///
/// The index to use.
- /// A at the given .
- /// The returned should only be used in the context of processing on the .
- public Memory GetUpdateStateForDsp(int id)
+ /// A at the given .
+ /// The returned should only be used in the context of processing on the .
+ public Memory GetUpdateStateForDsp(int id)
{
- return SpanIOHelper.GetMemory(_voiceUpdateStatesDsp, id, _voiceCount);
+ return SpanIOHelper.GetMemory(_voiceStatesDsp, id, _voiceCount);
}
///
- /// Get a reference to a at the given .
+ /// Get a reference to a at the given .
///
/// The index to use.
- /// A reference to a at the given .
- public ref VoiceState GetState(int id)
+ /// A reference to a at the given .
+ public ref VoiceInfo GetState(int id)
{
return ref SpanIOHelper.GetFromMemory(_voices, id, _voiceCount);
}
- public ref VoiceState GetSortedState(int id)
+ public ref VoiceInfo GetSortedState(int id)
{
Debug.Assert(id >= 0 && id < _voiceCount);
@@ -113,7 +113,7 @@ namespace Ryujinx.Audio.Renderer.Server.Voice
///
public void UpdateForCommandGeneration()
{
- _voiceUpdateStatesDsp.CopyTo(_voiceUpdateStatesCpu);
+ _voiceStatesDsp.CopyTo(_voiceStatesCpu);
}
///
@@ -130,14 +130,14 @@ namespace Ryujinx.Audio.Renderer.Server.Voice
sortedVoicesTemp.Sort((a, b) =>
{
- ref VoiceState aState = ref GetState(a);
- ref VoiceState bState = ref GetState(b);
+ ref VoiceInfo aInfo = ref GetState(a);
+ ref VoiceInfo bInfo = ref GetState(b);
- int result = aState.Priority.CompareTo(bState.Priority);
+ int result = aInfo.Priority.CompareTo(bInfo.Priority);
if (result == 0)
{
- return aState.SortingOrder.CompareTo(bState.SortingOrder);
+ return aInfo.SortingOrder.CompareTo(bInfo.SortingOrder);
}
return result;
diff --git a/src/Ryujinx.Audio/Renderer/Server/Voice/VoiceState.cs b/src/Ryujinx.Audio/Renderer/Server/Voice/VoiceInfo.cs
similarity index 66%
rename from src/Ryujinx.Audio/Renderer/Server/Voice/VoiceState.cs
rename to src/Ryujinx.Audio/Renderer/Server/Voice/VoiceInfo.cs
index 9fcff199d..ba6158b71 100644
--- a/src/Ryujinx.Audio/Renderer/Server/Voice/VoiceState.cs
+++ b/src/Ryujinx.Audio/Renderer/Server/Voice/VoiceInfo.cs
@@ -1,5 +1,6 @@
using Ryujinx.Audio.Common;
using Ryujinx.Audio.Renderer.Common;
+using Ryujinx.Audio.Renderer.Dsp;
using Ryujinx.Audio.Renderer.Dsp.State;
using Ryujinx.Audio.Renderer.Parameter;
using Ryujinx.Audio.Renderer.Server.MemoryPool;
@@ -9,13 +10,13 @@ using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using static Ryujinx.Audio.Renderer.Common.BehaviourParameter;
-using static Ryujinx.Audio.Renderer.Parameter.VoiceInParameter;
+using static Ryujinx.Audio.Renderer.Parameter.VoiceInParameter1;
using PlayState = Ryujinx.Audio.Renderer.Server.Types.PlayState;
namespace Ryujinx.Audio.Renderer.Server.Voice
{
[StructLayout(LayoutKind.Sequential, Pack = Alignment)]
- public struct VoiceState
+ public struct VoiceInfo
{
public const int Alignment = 0x10;
@@ -102,7 +103,7 @@ namespace Ryujinx.Audio.Renderer.Server.Voice
///
/// Biquad filters to apply to the output of the voice.
///
- public Array2 BiquadFilters;
+ public Array2 BiquadFilters;
///
/// Total count of of the voice.
@@ -185,7 +186,7 @@ namespace Ryujinx.Audio.Renderer.Server.Voice
public Span BiquadFilterNeedInitialization => SpanHelpers.AsSpan(ref _biquadFilterNeedInitialization);
///
- /// Initialize the .
+ /// Initialize the .
///
public void Initialize()
{
@@ -215,7 +216,7 @@ namespace Ryujinx.Audio.Renderer.Server.Voice
}
///
- /// Initialize the in this .
+ /// Initialize the in this .
///
private void InitializeWaveBuffers()
{
@@ -250,13 +251,13 @@ namespace Ryujinx.Audio.Renderer.Server.Voice
{
return MixId != Constants.UnusedMixId || SplitterId != Constants.UnusedSplitterId;
}
-
+
///
/// Indicate if the server voice information needs to be updated.
///
/// The user parameter.
/// Return true, if the server voice information needs to be updated.
- private readonly bool ShouldUpdateParameters(in VoiceInParameter parameter)
+ private readonly bool ShouldUpdateParameters2(in VoiceInParameter2 parameter)
{
if (DataSourceStateAddressInfo.CpuAddress == parameter.DataSourceStateAddress)
{
@@ -268,14 +269,31 @@ namespace Ryujinx.Audio.Renderer.Server.Voice
DataSourceStateUnmapped;
}
+ ///
+ /// Indicate if the server voice information needs to be updated.
+ ///
+ /// The user parameter.
+ /// Return true, if the server voice information needs to be updated.
+ private readonly bool ShouldUpdateParameters1(in VoiceInParameter1 parameter)
+ {
+ if (DataSourceStateAddressInfo.CpuAddress == parameter.DataSourceStateAddress)
+ {
+ return DataSourceStateAddressInfo.Size != parameter.DataSourceStateSize;
+ }
+
+ return DataSourceStateAddressInfo.CpuAddress != parameter.DataSourceStateAddress ||
+ DataSourceStateAddressInfo.Size != parameter.DataSourceStateSize ||
+ DataSourceStateUnmapped;
+ }
+
///
/// Update the internal state from a user parameter.
///
/// The possible that was generated.
/// The user parameter.
/// The mapper to use.
- /// The behaviour context.
- public void UpdateParameters(out ErrorInfo outErrorInfo, in VoiceInParameter parameter, PoolMapper poolMapper, ref BehaviourContext behaviourContext)
+ /// The behaviour context.
+ public void UpdateParameters2(out ErrorInfo outErrorInfo, in VoiceInParameter2 parameter, PoolMapper poolMapper, ref BehaviourInfo behaviourInfo)
{
InUse = parameter.InUse;
Id = parameter.Id;
@@ -296,14 +314,14 @@ namespace Ryujinx.Audio.Renderer.Server.Voice
WaveBuffersCount = parameter.WaveBuffersCount;
WaveBuffersIndex = parameter.WaveBuffersIndex;
- if (behaviourContext.IsFlushVoiceWaveBuffersSupported())
+ if (behaviourInfo.IsFlushVoiceWaveBuffersSupported())
{
FlushWaveBufferCount += parameter.FlushWaveBufferCount;
}
MixId = parameter.MixId;
- if (behaviourContext.IsSplitterSupported())
+ if (behaviourInfo.IsSplitterSupported())
{
SplitterId = parameter.SplitterId;
}
@@ -316,7 +334,7 @@ namespace Ryujinx.Audio.Renderer.Server.Voice
DecodingBehaviour behaviour = DecodingBehaviour.Default;
- if (behaviourContext.IsDecodingBehaviourFlagSupported())
+ if (behaviourInfo.IsDecodingBehaviourFlagSupported())
{
behaviour = parameter.DecodingBehaviourFlags;
}
@@ -328,7 +346,78 @@ namespace Ryujinx.Audio.Renderer.Server.Voice
VoiceDropFlag = false;
}
- if (ShouldUpdateParameters(in parameter))
+ if (ShouldUpdateParameters2(in parameter))
+ {
+ DataSourceStateUnmapped = !poolMapper.TryAttachBuffer(out outErrorInfo, ref DataSourceStateAddressInfo, parameter.DataSourceStateAddress, parameter.DataSourceStateSize);
+ }
+ else
+ {
+ outErrorInfo = new ErrorInfo();
+ }
+ }
+
+ ///
+ /// Update the internal state from a user parameter.
+ ///
+ /// The possible that was generated.
+ /// The user paramter2.
+ /// The mapper to use.
+ /// The behaviour context.
+ public void UpdateParameters1(out ErrorInfo outErrorInfo, in VoiceInParameter1 parameter, PoolMapper poolMapper, ref BehaviourInfo behaviourInfo)
+ {
+ InUse = parameter.InUse;
+ Id = parameter.Id;
+ NodeId = parameter.NodeId;
+
+ UpdatePlayState(parameter.PlayState);
+
+ SrcQuality = parameter.SrcQuality;
+
+ Priority = parameter.Priority;
+ SortingOrder = parameter.SortingOrder;
+ SampleRate = parameter.SampleRate;
+ SampleFormat = parameter.SampleFormat;
+ ChannelsCount = parameter.ChannelCount;
+ Pitch = parameter.Pitch;
+ Volume = parameter.Volume;
+ BiquadFilters[0] = BiquadFilterHelper.ToBiquadFilterParameter2(parameter.BiquadFilters[0]);
+ BiquadFilters[1] = BiquadFilterHelper.ToBiquadFilterParameter2(parameter.BiquadFilters[1]);
+ WaveBuffersCount = parameter.WaveBuffersCount;
+ WaveBuffersIndex = parameter.WaveBuffersIndex;
+
+ if (behaviourInfo.IsFlushVoiceWaveBuffersSupported())
+ {
+ FlushWaveBufferCount += parameter.FlushWaveBufferCount;
+ }
+
+ MixId = parameter.MixId;
+
+ if (behaviourInfo.IsSplitterSupported())
+ {
+ SplitterId = parameter.SplitterId;
+ }
+ else
+ {
+ SplitterId = Constants.UnusedSplitterId;
+ }
+
+ parameter.ChannelResourceIds.AsSpan().CopyTo(ChannelResourceIds.AsSpan());
+
+ DecodingBehaviour behaviour = DecodingBehaviour.Default;
+
+ if (behaviourInfo.IsDecodingBehaviourFlagSupported())
+ {
+ behaviour = parameter.DecodingBehaviourFlags;
+ }
+
+ DecodingBehaviour = behaviour;
+
+ if (parameter.ResetVoiceDropFlag)
+ {
+ VoiceDropFlag = false;
+ }
+
+ if (ShouldUpdateParameters1(in parameter))
{
DataSourceStateUnmapped = !poolMapper.TryAttachBuffer(out outErrorInfo, ref DataSourceStateAddressInfo, parameter.DataSourceStateAddress, parameter.DataSourceStateSize);
}
@@ -375,14 +464,14 @@ namespace Ryujinx.Audio.Renderer.Server.Voice
PlayState = newServerPlayState;
}
-
+
///
/// Write the status of the voice to the given user output.
///
/// The given user output.
/// The user parameter.
- /// The voice states associated to the .
- public void WriteOutStatus(ref VoiceOutStatus outStatus, in VoiceInParameter parameter, ReadOnlySpan> voiceUpdateStates)
+ /// The voice states associated to the .
+ public void WriteOutStatus2(ref VoiceOutStatus outStatus, in VoiceInParameter2 parameter, ReadOnlySpan> voiceStates)
{
#if DEBUG
// Sanity check in debug mode of the internal state
@@ -390,8 +479,8 @@ namespace Ryujinx.Audio.Renderer.Server.Voice
{
for (int i = 1; i < ChannelsCount; i++)
{
- ref VoiceUpdateState stateA = ref voiceUpdateStates[i - 1].Span[0];
- ref VoiceUpdateState stateB = ref voiceUpdateStates[i].Span[0];
+ ref VoiceState stateA = ref voiceStates[i - 1].Span[0];
+ ref VoiceState stateB = ref voiceStates[i].Span[0];
Debug.Assert(stateA.WaveBufferConsumed == stateB.WaveBufferConsumed);
Debug.Assert(stateA.PlayedSampleCount == stateB.PlayedSampleCount);
@@ -412,7 +501,7 @@ namespace Ryujinx.Audio.Renderer.Server.Voice
}
else
{
- ref VoiceUpdateState state = ref voiceUpdateStates[0].Span[0];
+ ref VoiceState state = ref voiceStates[0].Span[0];
outStatus.VoiceDropFlag = VoiceDropFlag;
outStatus.PlayedWaveBuffersCount = state.WaveBufferConsumed;
@@ -421,19 +510,63 @@ namespace Ryujinx.Audio.Renderer.Server.Voice
}
///
- /// Update the internal state of all the of the .
+ /// Write the status of the voice to the given user output.
+ ///
+ /// The given user output.
+ /// The user parameter.
+ /// The voice states associated to the .
+ public void WriteOutStatus1(ref VoiceOutStatus outStatus, in VoiceInParameter1 parameter, ReadOnlySpan> voiceStates)
+ {
+#if DEBUG
+ // Sanity check in debug mode of the internal state
+ if (!parameter.IsNew && !IsNew)
+ {
+ for (int i = 1; i < ChannelsCount; i++)
+ {
+ ref VoiceState stateA = ref voiceStates[i - 1].Span[0];
+ ref VoiceState stateB = ref voiceStates[i].Span[0];
+
+ Debug.Assert(stateA.WaveBufferConsumed == stateB.WaveBufferConsumed);
+ Debug.Assert(stateA.PlayedSampleCount == stateB.PlayedSampleCount);
+ Debug.Assert(stateA.Offset == stateB.Offset);
+ Debug.Assert(stateA.WaveBufferIndex == stateB.WaveBufferIndex);
+ Debug.Assert(stateA.Fraction == stateB.Fraction);
+ Debug.Assert(stateA.IsWaveBufferValid.SequenceEqual(stateB.IsWaveBufferValid));
+ }
+ }
+#endif
+ if (parameter.IsNew || IsNew)
+ {
+ IsNew = true;
+
+ outStatus.VoiceDropFlag = false;
+ outStatus.PlayedWaveBuffersCount = 0;
+ outStatus.PlayedSampleCount = 0;
+ }
+ else
+ {
+ ref VoiceState state = ref voiceStates[0].Span[0];
+
+ outStatus.VoiceDropFlag = VoiceDropFlag;
+ outStatus.PlayedWaveBuffersCount = state.WaveBufferConsumed;
+ outStatus.PlayedSampleCount = state.PlayedSampleCount;
+ }
+ }
+
+ ///
+ /// Update the internal state of all the of the .
///
/// An array of used to report errors when mapping any of the .
/// The user parameter.
- /// The voice states associated to the .
+ /// The voice states associated to the .
/// The mapper to use.
- /// The behaviour context.
- public void UpdateWaveBuffers(
+ /// The behaviour context.
+ public void UpdateWaveBuffers2(
out ErrorInfo[] errorInfos,
- in VoiceInParameter parameter,
- ReadOnlySpan> voiceUpdateStates,
+ in VoiceInParameter2 parameter,
+ ReadOnlySpan> voiceStates,
PoolMapper mapper,
- ref BehaviourContext behaviourContext)
+ ref BehaviourInfo behaviourInfo)
{
errorInfos = new ErrorInfo[Constants.VoiceWaveBufferCount * 2];
@@ -443,23 +576,61 @@ namespace Ryujinx.Audio.Renderer.Server.Voice
for (int i = 0; i < parameter.ChannelCount; i++)
{
- voiceUpdateStates[i].Span[0].IsWaveBufferValid.Clear();
+ voiceStates[i].Span[0].IsWaveBufferValid.Clear();
}
}
- ref VoiceUpdateState voiceUpdateState = ref voiceUpdateStates[0].Span[0];
+ ref VoiceState voiceState = ref voiceStates[0].Span[0];
Span waveBuffersSpan = WaveBuffers.AsSpan();
Span pWaveBuffersSpan = parameter.WaveBuffers.AsSpan();
for (int i = 0; i < Constants.VoiceWaveBufferCount; i++)
{
- UpdateWaveBuffer(errorInfos.AsSpan(i * 2, 2), ref waveBuffersSpan[i], ref pWaveBuffersSpan[i], parameter.SampleFormat, voiceUpdateState.IsWaveBufferValid[i], mapper, ref behaviourContext);
+ UpdateWaveBuffer(errorInfos.AsSpan(i * 2, 2), ref waveBuffersSpan[i], ref pWaveBuffersSpan[i], parameter.SampleFormat, voiceState.IsWaveBufferValid[i], mapper, ref behaviourInfo);
}
}
///
- /// Update the internal state of one of the of the .
+ /// Update the internal state of all the of the .
+ ///
+ /// An array of used to report errors when mapping any of the .
+ /// The user parameter.
+ /// The voice states associated to the .
+ /// The mapper to use.
+ /// The behaviour context.
+ public void UpdateWaveBuffers1(
+ out ErrorInfo[] errorInfos,
+ in VoiceInParameter1 parameter,
+ ReadOnlySpan> voiceStates,
+ PoolMapper mapper,
+ ref BehaviourInfo behaviourInfo)
+ {
+ errorInfos = new ErrorInfo[Constants.VoiceWaveBufferCount * 2];
+
+ if (parameter.IsNew)
+ {
+ InitializeWaveBuffers();
+
+ for (int i = 0; i < parameter.ChannelCount; i++)
+ {
+ voiceStates[i].Span[0].IsWaveBufferValid.Clear();
+ }
+ }
+
+ ref VoiceState voiceState = ref voiceStates[0].Span[0];
+
+ Span waveBuffersSpan = WaveBuffers.AsSpan();
+ Span pWaveBuffersSpan = parameter.WaveBuffers.AsSpan();
+
+ 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);
+ }
+ }
+
+ ///
+ /// Update the internal state of one of the of the .
///
/// A used to report errors when mapping the .
/// The to update.
@@ -467,7 +638,7 @@ namespace Ryujinx.Audio.Renderer.Server.Voice
/// The from the user input.
/// If set to true, the server side wavebuffer is considered valid.
/// The mapper to use.
- /// The behaviour context.
+ /// The behaviour context.
private void UpdateWaveBuffer(
Span errorInfos,
ref WaveBuffer waveBuffer,
@@ -475,7 +646,7 @@ namespace Ryujinx.Audio.Renderer.Server.Voice
SampleFormat sampleFormat,
bool isValid,
PoolMapper mapper,
- ref BehaviourContext behaviourContext)
+ ref BehaviourInfo behaviourInfo)
{
if (!isValid && waveBuffer.IsSendToAudioProcessor && waveBuffer.BufferAddressInfo.CpuAddress != 0)
{
@@ -502,7 +673,7 @@ namespace Ryujinx.Audio.Renderer.Server.Voice
errorInfos[0] = bufferInfoError;
- if (sampleFormat == SampleFormat.Adpcm && behaviourContext.IsAdpcmLoopContextBugFixed() && inputWaveBuffer.ContextAddress != 0)
+ if (sampleFormat == SampleFormat.Adpcm && behaviourInfo.IsAdpcmLoopContextBugFixed() && inputWaveBuffer.ContextAddress != 0)
{
bool adpcmLoopContextMapped = mapper.TryAttachBuffer(out ErrorInfo adpcmLoopContextInfoError,
ref waveBuffer.ContextAddressInfo,
@@ -511,13 +682,13 @@ namespace Ryujinx.Audio.Renderer.Server.Voice
errorInfos[1] = adpcmLoopContextInfoError;
- if (adpcmLoopContextMapped)
+ if (!adpcmLoopContextMapped || BufferInfoUnmapped)
{
- BufferInfoUnmapped = DataSourceStateUnmapped;
+ BufferInfoUnmapped = true;
}
else
{
- BufferInfoUnmapped = true;
+ BufferInfoUnmapped = false;
}
}
else
@@ -534,7 +705,7 @@ namespace Ryujinx.Audio.Renderer.Server.Voice
}
///
- /// Reset the resources associated to this .
+ /// Reset the resources associated to this .
///
/// The voice context.
private void ResetResources(VoiceContext context)
@@ -549,9 +720,9 @@ namespace Ryujinx.Audio.Renderer.Server.Voice
Debug.Assert(voiceChannelResource.IsUsed);
- Memory dspSharedState = context.GetUpdateStateForDsp(channelResourceId);
+ Memory dspSharedState = context.GetUpdateStateForDsp(channelResourceId);
- MemoryMarshal.Cast(dspSharedState.Span).Clear();
+ MemoryMarshal.Cast(dspSharedState.Span).Clear();
voiceChannelResource.UpdateState();
}
@@ -561,9 +732,9 @@ namespace Ryujinx.Audio.Renderer.Server.Voice
/// Flush a certain amount of .
///
/// The amount of wavebuffer to flush.
- /// The voice states associated to the .
+ /// The voice states associated to the .
/// The channel count from user input.
- private void FlushWaveBuffers(uint waveBufferCount, Memory[] voiceUpdateStates, uint channelCount)
+ private void FlushWaveBuffers(uint waveBufferCount, Memory[] voiceStates, uint channelCount)
{
uint waveBufferIndex = WaveBuffersIndex;
@@ -575,12 +746,17 @@ namespace Ryujinx.Audio.Renderer.Server.Voice
for (int j = 0; j < channelCount; j++)
{
- ref VoiceUpdateState voiceUpdateState = ref voiceUpdateStates[j].Span[0];
-
- voiceUpdateState.WaveBufferIndex = (voiceUpdateState.WaveBufferIndex + 1) % Constants.VoiceWaveBufferCount;
- voiceUpdateState.WaveBufferConsumed++;
- voiceUpdateState.IsWaveBufferValid[(int)waveBufferIndex] = false;
+ ref VoiceState voiceState = ref voiceStates[j].Span[0];
+
+ if (!waveBuffersSpan[(int)waveBufferIndex].IsSendToAudioProcessor || voiceState.IsWaveBufferValid[(int)waveBufferIndex])
+ {
+ voiceState.WaveBufferIndex = (voiceState.WaveBufferIndex + 1) % Constants.VoiceWaveBufferCount;
+ voiceState.WaveBufferConsumed++;
+ voiceState.IsWaveBufferValid[(int)waveBufferIndex] = false;
+ }
}
+
+ waveBuffersSpan[(int)waveBufferIndex].IsSendToAudioProcessor = true;
waveBufferIndex = (waveBufferIndex + 1) % Constants.VoiceWaveBufferCount;
}
@@ -589,13 +765,13 @@ namespace Ryujinx.Audio.Renderer.Server.Voice
///
/// Update the internal parameters for command generation.
///
- /// The voice states associated to the .
+ /// The voice states associated to the .
/// Return true if this voice should be played.
- public bool UpdateParametersForCommandGeneration(Memory[] voiceUpdateStates)
+ public bool UpdateParametersForCommandGeneration(Memory[] voiceStates)
{
if (FlushWaveBufferCount != 0)
{
- FlushWaveBuffers(FlushWaveBufferCount, voiceUpdateStates, ChannelsCount);
+ FlushWaveBuffers(FlushWaveBufferCount, voiceStates, ChannelsCount);
FlushWaveBufferCount = 0;
}
@@ -615,9 +791,9 @@ namespace Ryujinx.Audio.Renderer.Server.Voice
{
for (int y = 0; y < ChannelsCount; y++)
{
- Debug.Assert(!voiceUpdateStates[y].Span[0].IsWaveBufferValid[i]);
+ Debug.Assert(!voiceStates[y].Span[0].IsWaveBufferValid[i]);
- voiceUpdateStates[y].Span[0].IsWaveBufferValid[i] = true;
+ voiceStates[y].Span[0].IsWaveBufferValid[i] = true;
}
waveBuffer.IsSendToAudioProcessor = true;
@@ -626,11 +802,11 @@ namespace Ryujinx.Audio.Renderer.Server.Voice
WasPlaying = false;
- ref VoiceUpdateState primaryVoiceUpdateState = ref voiceUpdateStates[0].Span[0];
+ ref VoiceState primaryVoiceState = ref voiceStates[0].Span[0];
- for (int i = 0; i < primaryVoiceUpdateState.IsWaveBufferValid.Length; i++)
+ for (int i = 0; i < primaryVoiceState.IsWaveBufferValid.Length; i++)
{
- if (primaryVoiceUpdateState.IsWaveBufferValid[i])
+ if (primaryVoiceState.IsWaveBufferValid[i])
{
return true;
}
@@ -649,27 +825,27 @@ namespace Ryujinx.Audio.Renderer.Server.Voice
for (int j = 0; j < ChannelsCount; j++)
{
- ref VoiceUpdateState voiceUpdateState = ref voiceUpdateStates[j].Span[0];
+ ref VoiceState voiceState = ref voiceStates[j].Span[0];
- if (voiceUpdateState.IsWaveBufferValid[i])
+ if (voiceState.IsWaveBufferValid[i])
{
- voiceUpdateState.WaveBufferIndex = (voiceUpdateState.WaveBufferIndex + 1) % Constants.VoiceWaveBufferCount;
- voiceUpdateState.WaveBufferConsumed++;
+ voiceState.WaveBufferIndex = (voiceState.WaveBufferIndex + 1) % Constants.VoiceWaveBufferCount;
+ voiceState.WaveBufferConsumed++;
}
- voiceUpdateState.IsWaveBufferValid[i] = false;
+ voiceState.IsWaveBufferValid[i] = false;
}
}
for (int i = 0; i < ChannelsCount; i++)
{
- ref VoiceUpdateState voiceUpdateState = ref voiceUpdateStates[i].Span[0];
+ ref VoiceState voiceState = ref voiceStates[i].Span[0];
- voiceUpdateState.Offset = 0;
- voiceUpdateState.PlayedSampleCount = 0;
- voiceUpdateState.Pitch.AsSpan().Clear();
- voiceUpdateState.Fraction = 0;
- voiceUpdateState.LoopContext = new AdpcmLoopContext();
+ voiceState.Offset = 0;
+ voiceState.PlayedSampleCount = 0;
+ voiceState.Pitch.AsSpan().Clear();
+ voiceState.Fraction = 0;
+ voiceState.LoopContext = new AdpcmLoopContext();
}
PlayState = PlayState.Stopped;
@@ -715,16 +891,16 @@ namespace Ryujinx.Audio.Renderer.Server.Voice
IsNew = false;
}
- Memory[] voiceUpdateStates = new Memory[Constants.VoiceChannelCountMax];
+ Memory[] voiceStates = new Memory[Constants.VoiceChannelCountMax];
Span channelResourceIdsSpan = ChannelResourceIds.AsSpan();
for (int i = 0; i < ChannelsCount; i++)
{
- voiceUpdateStates[i] = context.GetUpdateStateForDsp(channelResourceIdsSpan[i]);
+ voiceStates[i] = context.GetUpdateStateForDsp(channelResourceIdsSpan[i]);
}
- return UpdateParametersForCommandGeneration(voiceUpdateStates);
+ return UpdateParametersForCommandGeneration(voiceStates);
}
}
}
diff --git a/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Common/ISampledDataStruct.cs b/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Common/ISampledDataStruct.cs
index 312075bc4..5a6aab495 100644
--- a/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Common/ISampledDataStruct.cs
+++ b/src/Ryujinx.HLE/HOS/Services/Hid/Types/SharedMemory/Common/ISampledDataStruct.cs
@@ -50,7 +50,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Common
ulong value = BinaryPrimitives.ReadUInt64LittleEndian(byteSpan);
- return value;
+ return value << 1;
}
private static int GetSamplingNumberFieldOffset(ref T sampledDataStruct) where T : unmanaged, ISampledDataStruct
diff --git a/src/Ryujinx.Horizon/Audio/AudioUserIpcServer.cs b/src/Ryujinx.Horizon/Audio/AudioUserIpcServer.cs
index 20c824e1e..1de123f7f 100644
--- a/src/Ryujinx.Horizon/Audio/AudioUserIpcServer.cs
+++ b/src/Ryujinx.Horizon/Audio/AudioUserIpcServer.cs
@@ -33,11 +33,13 @@ namespace Ryujinx.Horizon.Audio
AudioOutManager audioOutManager = new(_managers.AudioOutputManager);
AudioInManager audioInManager = new(_managers.AudioInputManager);
FinalOutputRecorderManager finalOutputRecorderManager = new();
+ AudioSnoopManager audioSnoopManager = new();
_serverManager.RegisterObjectForServer(audioRendererManager, ServiceName.Encode("audren:u"), MaxSessionsCount);
_serverManager.RegisterObjectForServer(audioOutManager, ServiceName.Encode("audout:u"), MaxSessionsCount);
_serverManager.RegisterObjectForServer(audioInManager, ServiceName.Encode("audin:u"), MaxSessionsCount);
_serverManager.RegisterObjectForServer(finalOutputRecorderManager, ServiceName.Encode("audrec:u"), MaxSessionsCount);
+ _serverManager.RegisterObjectForServer(audioSnoopManager, ServiceName.Encode("auddev"), MaxSessionsCount);
}
public void ServiceRequests()
diff --git a/src/Ryujinx.Horizon/Sdk/Audio/Detail/AudioDevice.cs b/src/Ryujinx.Horizon/Sdk/Audio/Detail/AudioDevice.cs
index 583a04de3..4fda4bc61 100644
--- a/src/Ryujinx.Horizon/Sdk/Audio/Detail/AudioDevice.cs
+++ b/src/Ryujinx.Horizon/Sdk/Audio/Detail/AudioDevice.cs
@@ -23,10 +23,10 @@ namespace Ryujinx.Horizon.Sdk.Audio.Detail
{
_registry = registry;
- BehaviourContext behaviourContext = new();
- behaviourContext.SetUserRevision((int)revision);
+ BehaviourInfo behaviourInfo = new();
+ behaviourInfo.SetUserRevision((int)revision);
- _isUsbDeviceSupported = behaviourContext.IsAudioUsbDeviceOutputSupported();
+ _isUsbDeviceSupported = behaviourInfo.IsAudioUsbDeviceOutputSupported();
_sessions = registry.GetSessionByAppletResourceId(appletResourceId.Id);
Os.CreateSystemEvent(out _audioEvent, EventClearMode.AutoClear, interProcess: true);
diff --git a/src/Ryujinx.Horizon/Sdk/Audio/Detail/AudioRendererManager.cs b/src/Ryujinx.Horizon/Sdk/Audio/Detail/AudioRendererManager.cs
index 40cbecc40..e7eedeccd 100644
--- a/src/Ryujinx.Horizon/Sdk/Audio/Detail/AudioRendererManager.cs
+++ b/src/Ryujinx.Horizon/Sdk/Audio/Detail/AudioRendererManager.cs
@@ -61,7 +61,7 @@ namespace Ryujinx.Horizon.Sdk.Audio.Detail
[CmifCommand(1)]
public Result GetWorkBufferSize(out long workBufferSize, AudioRendererParameterInternal parameter)
{
- if (BehaviourContext.CheckValidRevision(parameter.Configuration.Revision))
+ if (BehaviourInfo.CheckValidRevision(parameter.Configuration.Revision))
{
workBufferSize = (long)Ryujinx.Audio.Renderer.Server.AudioRendererManager.GetWorkBufferSize(ref parameter.Configuration);
@@ -73,7 +73,7 @@ namespace Ryujinx.Horizon.Sdk.Audio.Detail
{
workBufferSize = 0;
- Logger.Warning?.Print(LogClass.ServiceAudio, $"Library Revision REV{BehaviourContext.GetRevisionNumber(parameter.Configuration.Revision)} is not supported!");
+ Logger.Warning?.Print(LogClass.ServiceAudio, $"Library Revision REV{BehaviourInfo.GetRevisionNumber(parameter.Configuration.Revision)} is not supported!");
return AudioResult.UnsupportedRevision;
}
diff --git a/src/Ryujinx.Horizon/Sdk/Audio/Detail/AudioSnoopManager.cs b/src/Ryujinx.Horizon/Sdk/Audio/Detail/AudioSnoopManager.cs
index cf1fe3d1d..5eb31a14b 100644
--- a/src/Ryujinx.Horizon/Sdk/Audio/Detail/AudioSnoopManager.cs
+++ b/src/Ryujinx.Horizon/Sdk/Audio/Detail/AudioSnoopManager.cs
@@ -1,30 +1,64 @@
using Ryujinx.Horizon.Common;
using Ryujinx.Horizon.Sdk.Sf;
+using Ryujinx.Horizon.Sdk.Sf.Hipc;
+using System;
namespace Ryujinx.Horizon.Sdk.Audio.Detail
{
partial class AudioSnoopManager : IAudioSnoopManager
{
+ private byte[] _dspStatisticsParameter;
+
// Note: The interface changed completely on firmware 17.0.0, this implementation is for older firmware.
- [CmifCommand(0)]
+ [CmifCommand(0)] // [6.0.0-16.1.0]
public Result EnableDspUsageMeasurement()
{
return Result.Success;
}
- [CmifCommand(1)]
+ [CmifCommand(1)] // [6.0.0-16.1.0]
public Result DisableDspUsageMeasurement()
{
return Result.Success;
}
-
- [CmifCommand(6)]
+
+ [CmifCommand(6)] // [6.0.0-16.1.0]
public Result GetDspUsage(out uint usage)
{
usage = 0;
return Result.Success;
}
+
+ [CmifCommand(0)] // 17.0.0+
+ public Result GetDspStatistics(out uint statistics) => GetDspUsage(out statistics);
+
+ [CmifCommand(1)] // 20.0.0+
+ public Result GetAppletStateSummaries([Buffer(HipcBufferFlags.Out | HipcBufferFlags.MapAlias)] Span summaries)
+ {
+ // Since we do not have any real applets, return empty state summaries.
+ summaries.Clear();
+
+ return Result.Success;
+ }
+
+ [CmifCommand(2)] // 20.0.0+
+ public Result SetDspStatisticsParameter([Buffer(HipcBufferFlags.In | HipcBufferFlags.MapAlias)] ReadOnlySpan parameter)
+ {
+ _dspStatisticsParameter = null;
+ _dspStatisticsParameter = new byte[0x100];
+ parameter.CopyTo(_dspStatisticsParameter);
+
+ return Result.Success;
+ }
+
+ [CmifCommand(3)] // 20.0.0+
+ public Result GetDspStatisticsParameter([Buffer(HipcBufferFlags.Out | HipcBufferFlags.MapAlias)] Span parameter)
+ {
+ _dspStatisticsParameter.CopyTo(parameter);
+
+ return Result.Success;
+ }
}
}
diff --git a/src/Ryujinx.Horizon/Sdk/Audio/Detail/IAudioSnoopManager.cs b/src/Ryujinx.Horizon/Sdk/Audio/Detail/IAudioSnoopManager.cs
index 72853886a..9a52beb30 100644
--- a/src/Ryujinx.Horizon/Sdk/Audio/Detail/IAudioSnoopManager.cs
+++ b/src/Ryujinx.Horizon/Sdk/Audio/Detail/IAudioSnoopManager.cs
@@ -1,5 +1,6 @@
using Ryujinx.Horizon.Common;
using Ryujinx.Horizon.Sdk.Sf;
+using System;
namespace Ryujinx.Horizon.Sdk.Audio.Detail
{
@@ -8,5 +9,10 @@ namespace Ryujinx.Horizon.Sdk.Audio.Detail
Result EnableDspUsageMeasurement();
Result DisableDspUsageMeasurement();
Result GetDspUsage(out uint usage);
+
+ Result GetDspStatistics(out uint statistics);
+ Result GetAppletStateSummaries(Span summaries);
+ Result SetDspStatisticsParameter(ReadOnlySpan parameter);
+ Result GetDspStatisticsParameter(Span parameter);
}
}
diff --git a/src/Ryujinx.Tests/Audio/Renderer/BiquadFilterParameterTests.cs b/src/Ryujinx.Tests/Audio/Renderer/BiquadFilterParameterTests.cs
index 617b52457..76e8a180a 100644
--- a/src/Ryujinx.Tests/Audio/Renderer/BiquadFilterParameterTests.cs
+++ b/src/Ryujinx.Tests/Audio/Renderer/BiquadFilterParameterTests.cs
@@ -9,7 +9,8 @@ namespace Ryujinx.Tests.Audio.Renderer
[Test]
public void EnsureTypeSize()
{
- Assert.AreEqual(0xC, Unsafe.SizeOf());
+ Assert.AreEqual(0xC, Unsafe.SizeOf());
+ Assert.AreEqual(0x18, Unsafe.SizeOf());
}
}
}
diff --git a/src/Ryujinx.Tests/Audio/Renderer/Common/VoiceUpdateStateTests.cs b/src/Ryujinx.Tests/Audio/Renderer/Common/VoiceStateTests.cs
similarity index 68%
rename from src/Ryujinx.Tests/Audio/Renderer/Common/VoiceUpdateStateTests.cs
rename to src/Ryujinx.Tests/Audio/Renderer/Common/VoiceStateTests.cs
index 7b09d18cc..eff982670 100644
--- a/src/Ryujinx.Tests/Audio/Renderer/Common/VoiceUpdateStateTests.cs
+++ b/src/Ryujinx.Tests/Audio/Renderer/Common/VoiceStateTests.cs
@@ -4,12 +4,12 @@ using System.Runtime.CompilerServices;
namespace Ryujinx.Tests.Audio.Renderer.Common
{
- class VoiceUpdateStateTests
+ class VoiceStateTests
{
[Test]
public void EnsureTypeSize()
{
- Assert.LessOrEqual(Unsafe.SizeOf(), 0x100);
+ Assert.LessOrEqual(Unsafe.SizeOf(), 0x100);
}
}
}
diff --git a/src/Ryujinx.Tests/Audio/Renderer/Dsp/ResamplerTests.cs b/src/Ryujinx.Tests/Audio/Renderer/Dsp/ResamplerTests.cs
index f393c971a..b774b74e1 100644
--- a/src/Ryujinx.Tests/Audio/Renderer/Dsp/ResamplerTests.cs
+++ b/src/Ryujinx.Tests/Audio/Renderer/Dsp/ResamplerTests.cs
@@ -8,19 +8,19 @@ namespace Ryujinx.Tests.Audio.Renderer.Dsp
class ResamplerTests
{
[Test]
- [TestCase(VoiceInParameter.SampleRateConversionQuality.Low)]
- [TestCase(VoiceInParameter.SampleRateConversionQuality.Default)]
- [TestCase(VoiceInParameter.SampleRateConversionQuality.High)]
- public void TestResamplerConsistencyUpsampling(VoiceInParameter.SampleRateConversionQuality quality)
+ [TestCase(SampleRateConversionQuality.Low)]
+ [TestCase(SampleRateConversionQuality.Default)]
+ [TestCase(SampleRateConversionQuality.High)]
+ public void TestResamplerConsistencyUpsampling(SampleRateConversionQuality quality)
{
DoResamplingTest(44100, 48000, quality);
}
[Test]
- [TestCase(VoiceInParameter.SampleRateConversionQuality.Low)]
- [TestCase(VoiceInParameter.SampleRateConversionQuality.Default)]
- [TestCase(VoiceInParameter.SampleRateConversionQuality.High)]
- public void TestResamplerConsistencyDownsampling(VoiceInParameter.SampleRateConversionQuality quality)
+ [TestCase(SampleRateConversionQuality.Low)]
+ [TestCase(SampleRateConversionQuality.Default)]
+ [TestCase(SampleRateConversionQuality.High)]
+ public void TestResamplerConsistencyDownsampling(SampleRateConversionQuality quality)
{
DoResamplingTest(48000, 44100, quality);
}
@@ -32,7 +32,7 @@ namespace Ryujinx.Tests.Audio.Renderer.Dsp
/// The input sample rate to test
/// The output sample rate to test
/// The resampler quality to use
- private static void DoResamplingTest(int inputRate, int outputRate, VoiceInParameter.SampleRateConversionQuality quality)
+ private static void DoResamplingTest(int inputRate, int outputRate, SampleRateConversionQuality quality)
{
float inputSampleRate = inputRate;
float outputSampleRate = outputRate;
@@ -61,8 +61,8 @@ namespace Ryujinx.Tests.Audio.Renderer.Dsp
float sumDifference = 0;
int delay = quality switch
{
- VoiceInParameter.SampleRateConversionQuality.High => 3,
- VoiceInParameter.SampleRateConversionQuality.Default => 1,
+ SampleRateConversionQuality.High => 3,
+ SampleRateConversionQuality.Default => 1,
_ => 0,
};
diff --git a/src/Ryujinx.Tests/Audio/Renderer/Parameter/Effect/BiquadFilterEffectParameterTests.cs b/src/Ryujinx.Tests/Audio/Renderer/Parameter/Effect/BiquadFilterEffectParameterTests.cs
index 73c1ea9d3..d76478ed8 100644
--- a/src/Ryujinx.Tests/Audio/Renderer/Parameter/Effect/BiquadFilterEffectParameterTests.cs
+++ b/src/Ryujinx.Tests/Audio/Renderer/Parameter/Effect/BiquadFilterEffectParameterTests.cs
@@ -9,7 +9,8 @@ namespace Ryujinx.Tests.Audio.Renderer.Parameter.Effect
[Test]
public void EnsureTypeSize()
{
- Assert.AreEqual(0x18, Unsafe.SizeOf());
+ Assert.AreEqual(0x18, Unsafe.SizeOf());
+ Assert.AreEqual(0x24, Unsafe.SizeOf());
}
}
}
diff --git a/src/Ryujinx.Tests/Audio/Renderer/Server/AddressInfoTests.cs b/src/Ryujinx.Tests/Audio/Renderer/Server/AddressInfoTests.cs
index 53a662584..6f855d3a4 100644
--- a/src/Ryujinx.Tests/Audio/Renderer/Server/AddressInfoTests.cs
+++ b/src/Ryujinx.Tests/Audio/Renderer/Server/AddressInfoTests.cs
@@ -16,8 +16,8 @@ namespace Ryujinx.Tests.Audio.Renderer.Server
[Test]
public void TestGetReference()
{
- MemoryPoolState[] memoryPoolState = new MemoryPoolState[1];
- memoryPoolState[0] = MemoryPoolState.Create(MemoryPoolState.LocationType.Cpu);
+ MemoryPoolInfo[] memoryPoolState = new MemoryPoolInfo[1];
+ memoryPoolState[0] = MemoryPoolInfo.Create(MemoryPoolInfo.LocationType.Cpu);
memoryPoolState[0].SetCpuAddress(0x1000000, 0x10000);
memoryPoolState[0].DspAddress = 0x4000000;
diff --git a/src/Ryujinx.Tests/Audio/Renderer/Server/BehaviourContextTests.cs b/src/Ryujinx.Tests/Audio/Renderer/Server/BehaviourContextTests.cs
deleted file mode 100644
index 0b0ed7a54..000000000
--- a/src/Ryujinx.Tests/Audio/Renderer/Server/BehaviourContextTests.cs
+++ /dev/null
@@ -1,413 +0,0 @@
-using NUnit.Framework;
-using Ryujinx.Audio.Renderer.Server;
-
-namespace Ryujinx.Tests.Audio.Renderer.Server
-{
- public class BehaviourContextTests
- {
- [Test]
- public void TestCheckFeature()
- {
- int latestRevision = BehaviourContext.BaseRevisionMagic + BehaviourContext.LastRevision;
- int previousRevision = BehaviourContext.BaseRevisionMagic + (BehaviourContext.LastRevision - 1);
- int invalidRevision = BehaviourContext.BaseRevisionMagic + (BehaviourContext.LastRevision + 1);
-
- Assert.IsTrue(BehaviourContext.CheckFeatureSupported(latestRevision, latestRevision));
- Assert.IsFalse(BehaviourContext.CheckFeatureSupported(previousRevision, latestRevision));
- Assert.IsTrue(BehaviourContext.CheckFeatureSupported(latestRevision, previousRevision));
- // In case we get an invalid revision, this is supposed to auto default to REV1 internally.. idk what the hell Nintendo was thinking here..
- Assert.IsTrue(BehaviourContext.CheckFeatureSupported(invalidRevision, latestRevision));
- }
-
- [Test]
- public void TestsMemoryPoolForceMappingEnabled()
- {
- BehaviourContext behaviourContext = new();
-
- behaviourContext.SetUserRevision(BehaviourContext.BaseRevisionMagic + BehaviourContext.Revision1);
-
- Assert.IsFalse(behaviourContext.IsMemoryPoolForceMappingEnabled());
-
- behaviourContext.UpdateFlags(0x1);
-
- Assert.IsTrue(behaviourContext.IsMemoryPoolForceMappingEnabled());
- }
-
- [Test]
- public void TestRevision1()
- {
- BehaviourContext behaviourContext = new();
-
- behaviourContext.SetUserRevision(BehaviourContext.BaseRevisionMagic + BehaviourContext.Revision1);
-
- Assert.IsFalse(behaviourContext.IsAdpcmLoopContextBugFixed());
- Assert.IsFalse(behaviourContext.IsSplitterSupported());
- Assert.IsFalse(behaviourContext.IsLongSizePreDelaySupported());
- Assert.IsFalse(behaviourContext.IsAudioUsbDeviceOutputSupported());
- Assert.IsFalse(behaviourContext.IsFlushVoiceWaveBuffersSupported());
- Assert.IsFalse(behaviourContext.IsSplitterBugFixed());
- Assert.IsFalse(behaviourContext.IsElapsedFrameCountSupported());
- Assert.IsFalse(behaviourContext.IsDecodingBehaviourFlagSupported());
- Assert.IsFalse(behaviourContext.IsBiquadFilterEffectStateClearBugFixed());
- Assert.IsFalse(behaviourContext.IsMixInParameterDirtyOnlyUpdateSupported());
- Assert.IsFalse(behaviourContext.IsWaveBufferVersion2Supported());
- Assert.IsFalse(behaviourContext.IsEffectInfoVersion2Supported());
- Assert.IsFalse(behaviourContext.UseMultiTapBiquadFilterProcessing());
- Assert.IsFalse(behaviourContext.IsNewEffectChannelMappingSupported());
- Assert.IsFalse(behaviourContext.IsBiquadFilterParameterForSplitterEnabled());
- Assert.IsFalse(behaviourContext.IsSplitterPrevVolumeResetSupported());
-
- Assert.AreEqual(0.70f, behaviourContext.GetAudioRendererProcessingTimeLimit());
- Assert.AreEqual(1, behaviourContext.GetCommandProcessingTimeEstimatorVersion());
- Assert.AreEqual(1, behaviourContext.GetPerformanceMetricsDataFormat());
- }
-
- [Test]
- public void TestRevision2()
- {
- BehaviourContext behaviourContext = new();
-
- behaviourContext.SetUserRevision(BehaviourContext.BaseRevisionMagic + BehaviourContext.Revision2);
-
- Assert.IsTrue(behaviourContext.IsAdpcmLoopContextBugFixed());
- Assert.IsTrue(behaviourContext.IsSplitterSupported());
- Assert.IsFalse(behaviourContext.IsLongSizePreDelaySupported());
- Assert.IsFalse(behaviourContext.IsAudioUsbDeviceOutputSupported());
- Assert.IsFalse(behaviourContext.IsFlushVoiceWaveBuffersSupported());
- Assert.IsFalse(behaviourContext.IsSplitterBugFixed());
- Assert.IsFalse(behaviourContext.IsElapsedFrameCountSupported());
- Assert.IsFalse(behaviourContext.IsDecodingBehaviourFlagSupported());
- Assert.IsFalse(behaviourContext.IsBiquadFilterEffectStateClearBugFixed());
- Assert.IsFalse(behaviourContext.IsMixInParameterDirtyOnlyUpdateSupported());
- Assert.IsFalse(behaviourContext.IsWaveBufferVersion2Supported());
- Assert.IsFalse(behaviourContext.IsEffectInfoVersion2Supported());
- Assert.IsFalse(behaviourContext.UseMultiTapBiquadFilterProcessing());
- Assert.IsFalse(behaviourContext.IsNewEffectChannelMappingSupported());
- Assert.IsFalse(behaviourContext.IsBiquadFilterParameterForSplitterEnabled());
- Assert.IsFalse(behaviourContext.IsSplitterPrevVolumeResetSupported());
-
- Assert.AreEqual(0.70f, behaviourContext.GetAudioRendererProcessingTimeLimit());
- Assert.AreEqual(1, behaviourContext.GetCommandProcessingTimeEstimatorVersion());
- Assert.AreEqual(1, behaviourContext.GetPerformanceMetricsDataFormat());
- }
-
- [Test]
- public void TestRevision3()
- {
- BehaviourContext behaviourContext = new();
-
- behaviourContext.SetUserRevision(BehaviourContext.BaseRevisionMagic + BehaviourContext.Revision3);
-
- Assert.IsTrue(behaviourContext.IsAdpcmLoopContextBugFixed());
- Assert.IsTrue(behaviourContext.IsSplitterSupported());
- Assert.IsTrue(behaviourContext.IsLongSizePreDelaySupported());
- Assert.IsFalse(behaviourContext.IsAudioUsbDeviceOutputSupported());
- Assert.IsFalse(behaviourContext.IsFlushVoiceWaveBuffersSupported());
- Assert.IsFalse(behaviourContext.IsSplitterBugFixed());
- Assert.IsFalse(behaviourContext.IsElapsedFrameCountSupported());
- Assert.IsFalse(behaviourContext.IsDecodingBehaviourFlagSupported());
- Assert.IsFalse(behaviourContext.IsBiquadFilterEffectStateClearBugFixed());
- Assert.IsFalse(behaviourContext.IsMixInParameterDirtyOnlyUpdateSupported());
- Assert.IsFalse(behaviourContext.IsWaveBufferVersion2Supported());
- Assert.IsFalse(behaviourContext.IsEffectInfoVersion2Supported());
- Assert.IsFalse(behaviourContext.UseMultiTapBiquadFilterProcessing());
- Assert.IsFalse(behaviourContext.IsNewEffectChannelMappingSupported());
- Assert.IsFalse(behaviourContext.IsBiquadFilterParameterForSplitterEnabled());
- Assert.IsFalse(behaviourContext.IsSplitterPrevVolumeResetSupported());
-
- Assert.AreEqual(0.70f, behaviourContext.GetAudioRendererProcessingTimeLimit());
- Assert.AreEqual(1, behaviourContext.GetCommandProcessingTimeEstimatorVersion());
- Assert.AreEqual(1, behaviourContext.GetPerformanceMetricsDataFormat());
- }
-
- [Test]
- public void TestRevision4()
- {
- BehaviourContext behaviourContext = new();
-
- behaviourContext.SetUserRevision(BehaviourContext.BaseRevisionMagic + BehaviourContext.Revision4);
-
- Assert.IsTrue(behaviourContext.IsAdpcmLoopContextBugFixed());
- Assert.IsTrue(behaviourContext.IsSplitterSupported());
- Assert.IsTrue(behaviourContext.IsLongSizePreDelaySupported());
- Assert.IsTrue(behaviourContext.IsAudioUsbDeviceOutputSupported());
- Assert.IsFalse(behaviourContext.IsFlushVoiceWaveBuffersSupported());
- Assert.IsFalse(behaviourContext.IsSplitterBugFixed());
- Assert.IsFalse(behaviourContext.IsElapsedFrameCountSupported());
- Assert.IsFalse(behaviourContext.IsDecodingBehaviourFlagSupported());
- Assert.IsFalse(behaviourContext.IsBiquadFilterEffectStateClearBugFixed());
- Assert.IsFalse(behaviourContext.IsMixInParameterDirtyOnlyUpdateSupported());
- Assert.IsFalse(behaviourContext.IsWaveBufferVersion2Supported());
- Assert.IsFalse(behaviourContext.IsEffectInfoVersion2Supported());
- Assert.IsFalse(behaviourContext.UseMultiTapBiquadFilterProcessing());
- Assert.IsFalse(behaviourContext.IsNewEffectChannelMappingSupported());
- Assert.IsFalse(behaviourContext.IsBiquadFilterParameterForSplitterEnabled());
- Assert.IsFalse(behaviourContext.IsSplitterPrevVolumeResetSupported());
-
- Assert.AreEqual(0.75f, behaviourContext.GetAudioRendererProcessingTimeLimit());
- Assert.AreEqual(1, behaviourContext.GetCommandProcessingTimeEstimatorVersion());
- Assert.AreEqual(1, behaviourContext.GetPerformanceMetricsDataFormat());
- }
-
- [Test]
- public void TestRevision5()
- {
- BehaviourContext behaviourContext = new();
-
- behaviourContext.SetUserRevision(BehaviourContext.BaseRevisionMagic + BehaviourContext.Revision5);
-
- Assert.IsTrue(behaviourContext.IsAdpcmLoopContextBugFixed());
- Assert.IsTrue(behaviourContext.IsSplitterSupported());
- Assert.IsTrue(behaviourContext.IsLongSizePreDelaySupported());
- Assert.IsTrue(behaviourContext.IsAudioUsbDeviceOutputSupported());
- Assert.IsTrue(behaviourContext.IsFlushVoiceWaveBuffersSupported());
- Assert.IsTrue(behaviourContext.IsSplitterBugFixed());
- Assert.IsTrue(behaviourContext.IsElapsedFrameCountSupported());
- Assert.IsTrue(behaviourContext.IsDecodingBehaviourFlagSupported());
- Assert.IsFalse(behaviourContext.IsBiquadFilterEffectStateClearBugFixed());
- Assert.IsFalse(behaviourContext.IsMixInParameterDirtyOnlyUpdateSupported());
- Assert.IsFalse(behaviourContext.IsWaveBufferVersion2Supported());
- Assert.IsFalse(behaviourContext.IsEffectInfoVersion2Supported());
- Assert.IsFalse(behaviourContext.UseMultiTapBiquadFilterProcessing());
- Assert.IsFalse(behaviourContext.IsNewEffectChannelMappingSupported());
- Assert.IsFalse(behaviourContext.IsBiquadFilterParameterForSplitterEnabled());
- Assert.IsFalse(behaviourContext.IsSplitterPrevVolumeResetSupported());
-
- Assert.AreEqual(0.80f, behaviourContext.GetAudioRendererProcessingTimeLimit());
- Assert.AreEqual(2, behaviourContext.GetCommandProcessingTimeEstimatorVersion());
- Assert.AreEqual(2, behaviourContext.GetPerformanceMetricsDataFormat());
- }
-
- [Test]
- public void TestRevision6()
- {
- BehaviourContext behaviourContext = new();
-
- behaviourContext.SetUserRevision(BehaviourContext.BaseRevisionMagic + BehaviourContext.Revision6);
-
- Assert.IsTrue(behaviourContext.IsAdpcmLoopContextBugFixed());
- Assert.IsTrue(behaviourContext.IsSplitterSupported());
- Assert.IsTrue(behaviourContext.IsLongSizePreDelaySupported());
- Assert.IsTrue(behaviourContext.IsAudioUsbDeviceOutputSupported());
- Assert.IsTrue(behaviourContext.IsFlushVoiceWaveBuffersSupported());
- Assert.IsTrue(behaviourContext.IsSplitterBugFixed());
- Assert.IsTrue(behaviourContext.IsElapsedFrameCountSupported());
- Assert.IsTrue(behaviourContext.IsDecodingBehaviourFlagSupported());
- Assert.IsTrue(behaviourContext.IsBiquadFilterEffectStateClearBugFixed());
- Assert.IsFalse(behaviourContext.IsMixInParameterDirtyOnlyUpdateSupported());
- Assert.IsFalse(behaviourContext.IsWaveBufferVersion2Supported());
- Assert.IsFalse(behaviourContext.IsEffectInfoVersion2Supported());
- Assert.IsFalse(behaviourContext.UseMultiTapBiquadFilterProcessing());
- Assert.IsFalse(behaviourContext.IsNewEffectChannelMappingSupported());
- Assert.IsFalse(behaviourContext.IsBiquadFilterParameterForSplitterEnabled());
- Assert.IsFalse(behaviourContext.IsSplitterPrevVolumeResetSupported());
-
- Assert.AreEqual(0.80f, behaviourContext.GetAudioRendererProcessingTimeLimit());
- Assert.AreEqual(2, behaviourContext.GetCommandProcessingTimeEstimatorVersion());
- Assert.AreEqual(2, behaviourContext.GetPerformanceMetricsDataFormat());
- }
-
- [Test]
- public void TestRevision7()
- {
- BehaviourContext behaviourContext = new();
-
- behaviourContext.SetUserRevision(BehaviourContext.BaseRevisionMagic + BehaviourContext.Revision7);
-
- Assert.IsTrue(behaviourContext.IsAdpcmLoopContextBugFixed());
- Assert.IsTrue(behaviourContext.IsSplitterSupported());
- Assert.IsTrue(behaviourContext.IsLongSizePreDelaySupported());
- Assert.IsTrue(behaviourContext.IsAudioUsbDeviceOutputSupported());
- Assert.IsTrue(behaviourContext.IsFlushVoiceWaveBuffersSupported());
- Assert.IsTrue(behaviourContext.IsSplitterBugFixed());
- Assert.IsTrue(behaviourContext.IsElapsedFrameCountSupported());
- Assert.IsTrue(behaviourContext.IsDecodingBehaviourFlagSupported());
- Assert.IsTrue(behaviourContext.IsBiquadFilterEffectStateClearBugFixed());
- Assert.IsTrue(behaviourContext.IsMixInParameterDirtyOnlyUpdateSupported());
- Assert.IsFalse(behaviourContext.IsWaveBufferVersion2Supported());
- Assert.IsFalse(behaviourContext.IsEffectInfoVersion2Supported());
- Assert.IsFalse(behaviourContext.UseMultiTapBiquadFilterProcessing());
- Assert.IsFalse(behaviourContext.IsNewEffectChannelMappingSupported());
- Assert.IsFalse(behaviourContext.IsBiquadFilterParameterForSplitterEnabled());
- Assert.IsFalse(behaviourContext.IsSplitterPrevVolumeResetSupported());
-
- Assert.AreEqual(0.80f, behaviourContext.GetAudioRendererProcessingTimeLimit());
- Assert.AreEqual(2, behaviourContext.GetCommandProcessingTimeEstimatorVersion());
- Assert.AreEqual(2, behaviourContext.GetPerformanceMetricsDataFormat());
- }
-
- [Test]
- public void TestRevision8()
- {
- BehaviourContext behaviourContext = new();
-
- behaviourContext.SetUserRevision(BehaviourContext.BaseRevisionMagic + BehaviourContext.Revision8);
-
- Assert.IsTrue(behaviourContext.IsAdpcmLoopContextBugFixed());
- Assert.IsTrue(behaviourContext.IsSplitterSupported());
- Assert.IsTrue(behaviourContext.IsLongSizePreDelaySupported());
- Assert.IsTrue(behaviourContext.IsAudioUsbDeviceOutputSupported());
- Assert.IsTrue(behaviourContext.IsFlushVoiceWaveBuffersSupported());
- Assert.IsTrue(behaviourContext.IsSplitterBugFixed());
- Assert.IsTrue(behaviourContext.IsElapsedFrameCountSupported());
- Assert.IsTrue(behaviourContext.IsDecodingBehaviourFlagSupported());
- Assert.IsTrue(behaviourContext.IsBiquadFilterEffectStateClearBugFixed());
- Assert.IsTrue(behaviourContext.IsMixInParameterDirtyOnlyUpdateSupported());
- Assert.IsTrue(behaviourContext.IsWaveBufferVersion2Supported());
- Assert.IsFalse(behaviourContext.IsEffectInfoVersion2Supported());
- Assert.IsFalse(behaviourContext.UseMultiTapBiquadFilterProcessing());
- Assert.IsFalse(behaviourContext.IsNewEffectChannelMappingSupported());
- Assert.IsFalse(behaviourContext.IsBiquadFilterParameterForSplitterEnabled());
- Assert.IsFalse(behaviourContext.IsSplitterPrevVolumeResetSupported());
-
- Assert.AreEqual(0.80f, behaviourContext.GetAudioRendererProcessingTimeLimit());
- Assert.AreEqual(3, behaviourContext.GetCommandProcessingTimeEstimatorVersion());
- Assert.AreEqual(2, behaviourContext.GetPerformanceMetricsDataFormat());
- }
-
- [Test]
- public void TestRevision9()
- {
- BehaviourContext behaviourContext = new();
-
- behaviourContext.SetUserRevision(BehaviourContext.BaseRevisionMagic + BehaviourContext.Revision9);
-
- Assert.IsTrue(behaviourContext.IsAdpcmLoopContextBugFixed());
- Assert.IsTrue(behaviourContext.IsSplitterSupported());
- Assert.IsTrue(behaviourContext.IsLongSizePreDelaySupported());
- Assert.IsTrue(behaviourContext.IsAudioUsbDeviceOutputSupported());
- Assert.IsTrue(behaviourContext.IsFlushVoiceWaveBuffersSupported());
- Assert.IsTrue(behaviourContext.IsSplitterBugFixed());
- Assert.IsTrue(behaviourContext.IsElapsedFrameCountSupported());
- Assert.IsTrue(behaviourContext.IsDecodingBehaviourFlagSupported());
- Assert.IsTrue(behaviourContext.IsBiquadFilterEffectStateClearBugFixed());
- Assert.IsTrue(behaviourContext.IsMixInParameterDirtyOnlyUpdateSupported());
- Assert.IsTrue(behaviourContext.IsWaveBufferVersion2Supported());
- Assert.IsTrue(behaviourContext.IsEffectInfoVersion2Supported());
- Assert.IsFalse(behaviourContext.UseMultiTapBiquadFilterProcessing());
- Assert.IsFalse(behaviourContext.IsNewEffectChannelMappingSupported());
- Assert.IsFalse(behaviourContext.IsBiquadFilterParameterForSplitterEnabled());
- Assert.IsFalse(behaviourContext.IsSplitterPrevVolumeResetSupported());
-
- Assert.AreEqual(0.80f, behaviourContext.GetAudioRendererProcessingTimeLimit());
- Assert.AreEqual(3, behaviourContext.GetCommandProcessingTimeEstimatorVersion());
- Assert.AreEqual(2, behaviourContext.GetPerformanceMetricsDataFormat());
- }
-
- [Test]
- public void TestRevision10()
- {
- BehaviourContext behaviourContext = new();
-
- behaviourContext.SetUserRevision(BehaviourContext.BaseRevisionMagic + BehaviourContext.Revision10);
-
- Assert.IsTrue(behaviourContext.IsAdpcmLoopContextBugFixed());
- Assert.IsTrue(behaviourContext.IsSplitterSupported());
- Assert.IsTrue(behaviourContext.IsLongSizePreDelaySupported());
- Assert.IsTrue(behaviourContext.IsAudioUsbDeviceOutputSupported());
- Assert.IsTrue(behaviourContext.IsFlushVoiceWaveBuffersSupported());
- Assert.IsTrue(behaviourContext.IsSplitterBugFixed());
- Assert.IsTrue(behaviourContext.IsElapsedFrameCountSupported());
- Assert.IsTrue(behaviourContext.IsDecodingBehaviourFlagSupported());
- Assert.IsTrue(behaviourContext.IsBiquadFilterEffectStateClearBugFixed());
- Assert.IsTrue(behaviourContext.IsMixInParameterDirtyOnlyUpdateSupported());
- Assert.IsTrue(behaviourContext.IsWaveBufferVersion2Supported());
- Assert.IsTrue(behaviourContext.IsEffectInfoVersion2Supported());
- Assert.IsTrue(behaviourContext.UseMultiTapBiquadFilterProcessing());
- Assert.IsFalse(behaviourContext.IsNewEffectChannelMappingSupported());
- Assert.IsFalse(behaviourContext.IsBiquadFilterParameterForSplitterEnabled());
- Assert.IsFalse(behaviourContext.IsSplitterPrevVolumeResetSupported());
-
- Assert.AreEqual(0.80f, behaviourContext.GetAudioRendererProcessingTimeLimit());
- Assert.AreEqual(4, behaviourContext.GetCommandProcessingTimeEstimatorVersion());
- Assert.AreEqual(2, behaviourContext.GetPerformanceMetricsDataFormat());
- }
-
- [Test]
- public void TestRevision11()
- {
- BehaviourContext behaviourContext = new();
-
- behaviourContext.SetUserRevision(BehaviourContext.BaseRevisionMagic + BehaviourContext.Revision11);
-
- Assert.IsTrue(behaviourContext.IsAdpcmLoopContextBugFixed());
- Assert.IsTrue(behaviourContext.IsSplitterSupported());
- Assert.IsTrue(behaviourContext.IsLongSizePreDelaySupported());
- Assert.IsTrue(behaviourContext.IsAudioUsbDeviceOutputSupported());
- Assert.IsTrue(behaviourContext.IsFlushVoiceWaveBuffersSupported());
- Assert.IsTrue(behaviourContext.IsSplitterBugFixed());
- Assert.IsTrue(behaviourContext.IsElapsedFrameCountSupported());
- Assert.IsTrue(behaviourContext.IsDecodingBehaviourFlagSupported());
- Assert.IsTrue(behaviourContext.IsBiquadFilterEffectStateClearBugFixed());
- Assert.IsTrue(behaviourContext.IsMixInParameterDirtyOnlyUpdateSupported());
- Assert.IsTrue(behaviourContext.IsWaveBufferVersion2Supported());
- Assert.IsTrue(behaviourContext.IsEffectInfoVersion2Supported());
- Assert.IsTrue(behaviourContext.UseMultiTapBiquadFilterProcessing());
- Assert.IsTrue(behaviourContext.IsNewEffectChannelMappingSupported());
- Assert.IsFalse(behaviourContext.IsBiquadFilterParameterForSplitterEnabled());
- Assert.IsFalse(behaviourContext.IsSplitterPrevVolumeResetSupported());
-
- Assert.AreEqual(0.80f, behaviourContext.GetAudioRendererProcessingTimeLimit());
- Assert.AreEqual(5, behaviourContext.GetCommandProcessingTimeEstimatorVersion());
- Assert.AreEqual(2, behaviourContext.GetPerformanceMetricsDataFormat());
- }
-
- [Test]
- public void TestRevision12()
- {
- BehaviourContext behaviourContext = new();
-
- behaviourContext.SetUserRevision(BehaviourContext.BaseRevisionMagic + BehaviourContext.Revision12);
-
- Assert.IsTrue(behaviourContext.IsAdpcmLoopContextBugFixed());
- Assert.IsTrue(behaviourContext.IsSplitterSupported());
- Assert.IsTrue(behaviourContext.IsLongSizePreDelaySupported());
- Assert.IsTrue(behaviourContext.IsAudioUsbDeviceOutputSupported());
- Assert.IsTrue(behaviourContext.IsFlushVoiceWaveBuffersSupported());
- Assert.IsTrue(behaviourContext.IsSplitterBugFixed());
- Assert.IsTrue(behaviourContext.IsElapsedFrameCountSupported());
- Assert.IsTrue(behaviourContext.IsDecodingBehaviourFlagSupported());
- Assert.IsTrue(behaviourContext.IsBiquadFilterEffectStateClearBugFixed());
- Assert.IsTrue(behaviourContext.IsMixInParameterDirtyOnlyUpdateSupported());
- Assert.IsTrue(behaviourContext.IsWaveBufferVersion2Supported());
- Assert.IsTrue(behaviourContext.IsEffectInfoVersion2Supported());
- Assert.IsTrue(behaviourContext.UseMultiTapBiquadFilterProcessing());
- Assert.IsTrue(behaviourContext.IsNewEffectChannelMappingSupported());
- Assert.IsTrue(behaviourContext.IsBiquadFilterParameterForSplitterEnabled());
- Assert.IsFalse(behaviourContext.IsSplitterPrevVolumeResetSupported());
-
- Assert.AreEqual(0.80f, behaviourContext.GetAudioRendererProcessingTimeLimit());
- Assert.AreEqual(5, behaviourContext.GetCommandProcessingTimeEstimatorVersion());
- Assert.AreEqual(2, behaviourContext.GetPerformanceMetricsDataFormat());
- }
-
- [Test]
- public void TestRevision13()
- {
- BehaviourContext behaviourContext = new();
-
- behaviourContext.SetUserRevision(BehaviourContext.BaseRevisionMagic + BehaviourContext.Revision13);
-
- Assert.IsTrue(behaviourContext.IsAdpcmLoopContextBugFixed());
- Assert.IsTrue(behaviourContext.IsSplitterSupported());
- Assert.IsTrue(behaviourContext.IsLongSizePreDelaySupported());
- Assert.IsTrue(behaviourContext.IsAudioUsbDeviceOutputSupported());
- Assert.IsTrue(behaviourContext.IsFlushVoiceWaveBuffersSupported());
- Assert.IsTrue(behaviourContext.IsSplitterBugFixed());
- Assert.IsTrue(behaviourContext.IsElapsedFrameCountSupported());
- Assert.IsTrue(behaviourContext.IsDecodingBehaviourFlagSupported());
- Assert.IsTrue(behaviourContext.IsBiquadFilterEffectStateClearBugFixed());
- Assert.IsTrue(behaviourContext.IsMixInParameterDirtyOnlyUpdateSupported());
- Assert.IsTrue(behaviourContext.IsWaveBufferVersion2Supported());
- Assert.IsTrue(behaviourContext.IsEffectInfoVersion2Supported());
- Assert.IsTrue(behaviourContext.UseMultiTapBiquadFilterProcessing());
- Assert.IsTrue(behaviourContext.IsNewEffectChannelMappingSupported());
- Assert.IsTrue(behaviourContext.IsBiquadFilterParameterForSplitterEnabled());
- Assert.IsTrue(behaviourContext.IsSplitterPrevVolumeResetSupported());
-
- Assert.AreEqual(0.80f, behaviourContext.GetAudioRendererProcessingTimeLimit());
- Assert.AreEqual(5, behaviourContext.GetCommandProcessingTimeEstimatorVersion());
- Assert.AreEqual(2, behaviourContext.GetPerformanceMetricsDataFormat());
- }
- }
-}
diff --git a/src/Ryujinx.Tests/Audio/Renderer/Server/BehaviourInfoTests.cs b/src/Ryujinx.Tests/Audio/Renderer/Server/BehaviourInfoTests.cs
new file mode 100644
index 000000000..ac85e44b4
--- /dev/null
+++ b/src/Ryujinx.Tests/Audio/Renderer/Server/BehaviourInfoTests.cs
@@ -0,0 +1,413 @@
+using NUnit.Framework;
+using Ryujinx.Audio.Renderer.Server;
+
+namespace Ryujinx.Tests.Audio.Renderer.Server
+{
+ public class BehaviourInfoTests
+ {
+ [Test]
+ public void TestCheckFeature()
+ {
+ int latestRevision = BehaviourInfo.BaseRevisionMagic + BehaviourInfo.LastRevision;
+ int previousRevision = BehaviourInfo.BaseRevisionMagic + (BehaviourInfo.LastRevision - 1);
+ int invalidRevision = BehaviourInfo.BaseRevisionMagic + (BehaviourInfo.LastRevision + 1);
+
+ Assert.IsTrue(BehaviourInfo.CheckFeatureSupported(latestRevision, latestRevision));
+ Assert.IsFalse(BehaviourInfo.CheckFeatureSupported(previousRevision, latestRevision));
+ Assert.IsTrue(BehaviourInfo.CheckFeatureSupported(latestRevision, previousRevision));
+ // In case we get an invalid revision, this is supposed to auto default to REV1 internally.. idk what the hell Nintendo was thinking here..
+ Assert.IsTrue(BehaviourInfo.CheckFeatureSupported(invalidRevision, latestRevision));
+ }
+
+ [Test]
+ public void TestsMemoryPoolForceMappingEnabled()
+ {
+ BehaviourInfo behaviourInfo = new();
+
+ behaviourInfo.SetUserRevision(BehaviourInfo.BaseRevisionMagic + BehaviourInfo.Revision1);
+
+ Assert.IsFalse(behaviourInfo.IsMemoryPoolForceMappingEnabled());
+
+ behaviourInfo.UpdateFlags(0x1);
+
+ Assert.IsTrue(behaviourInfo.IsMemoryPoolForceMappingEnabled());
+ }
+
+ [Test]
+ public void TestRevision1()
+ {
+ BehaviourInfo behaviourInfo = new();
+
+ behaviourInfo.SetUserRevision(BehaviourInfo.BaseRevisionMagic + BehaviourInfo.Revision1);
+
+ Assert.IsFalse(behaviourInfo.IsAdpcmLoopContextBugFixed());
+ Assert.IsFalse(behaviourInfo.IsSplitterSupported());
+ Assert.IsFalse(behaviourInfo.IsLongSizePreDelaySupported());
+ Assert.IsFalse(behaviourInfo.IsAudioUsbDeviceOutputSupported());
+ Assert.IsFalse(behaviourInfo.IsFlushVoiceWaveBuffersSupported());
+ Assert.IsFalse(behaviourInfo.IsSplitterBugFixed());
+ Assert.IsFalse(behaviourInfo.IsElapsedFrameCountSupported());
+ Assert.IsFalse(behaviourInfo.IsDecodingBehaviourFlagSupported());
+ Assert.IsFalse(behaviourInfo.IsBiquadFilterEffectStateClearBugFixed());
+ Assert.IsFalse(behaviourInfo.IsMixInParameterDirtyOnlyUpdateSupported());
+ Assert.IsFalse(behaviourInfo.IsWaveBufferVersion2Supported());
+ Assert.IsFalse(behaviourInfo.IsEffectInfoVersion2Supported());
+ Assert.IsFalse(behaviourInfo.UseMultiTapBiquadFilterProcessing());
+ Assert.IsFalse(behaviourInfo.IsNewEffectChannelMappingSupported());
+ Assert.IsFalse(behaviourInfo.IsBiquadFilterParameterForSplitterEnabled());
+ Assert.IsFalse(behaviourInfo.IsSplitterPrevVolumeResetSupported());
+
+ Assert.AreEqual(0.70f, behaviourInfo.GetAudioRendererProcessingTimeLimit());
+ Assert.AreEqual(1, behaviourInfo.GetCommandProcessingTimeEstimatorVersion());
+ Assert.AreEqual(1, behaviourInfo.GetPerformanceMetricsDataFormat());
+ }
+
+ [Test]
+ public void TestRevision2()
+ {
+ BehaviourInfo behaviourInfo = new();
+
+ behaviourInfo.SetUserRevision(BehaviourInfo.BaseRevisionMagic + BehaviourInfo.Revision2);
+
+ Assert.IsTrue(behaviourInfo.IsAdpcmLoopContextBugFixed());
+ Assert.IsTrue(behaviourInfo.IsSplitterSupported());
+ Assert.IsFalse(behaviourInfo.IsLongSizePreDelaySupported());
+ Assert.IsFalse(behaviourInfo.IsAudioUsbDeviceOutputSupported());
+ Assert.IsFalse(behaviourInfo.IsFlushVoiceWaveBuffersSupported());
+ Assert.IsFalse(behaviourInfo.IsSplitterBugFixed());
+ Assert.IsFalse(behaviourInfo.IsElapsedFrameCountSupported());
+ Assert.IsFalse(behaviourInfo.IsDecodingBehaviourFlagSupported());
+ Assert.IsFalse(behaviourInfo.IsBiquadFilterEffectStateClearBugFixed());
+ Assert.IsFalse(behaviourInfo.IsMixInParameterDirtyOnlyUpdateSupported());
+ Assert.IsFalse(behaviourInfo.IsWaveBufferVersion2Supported());
+ Assert.IsFalse(behaviourInfo.IsEffectInfoVersion2Supported());
+ Assert.IsFalse(behaviourInfo.UseMultiTapBiquadFilterProcessing());
+ Assert.IsFalse(behaviourInfo.IsNewEffectChannelMappingSupported());
+ Assert.IsFalse(behaviourInfo.IsBiquadFilterParameterForSplitterEnabled());
+ Assert.IsFalse(behaviourInfo.IsSplitterPrevVolumeResetSupported());
+
+ Assert.AreEqual(0.70f, behaviourInfo.GetAudioRendererProcessingTimeLimit());
+ Assert.AreEqual(1, behaviourInfo.GetCommandProcessingTimeEstimatorVersion());
+ Assert.AreEqual(1, behaviourInfo.GetPerformanceMetricsDataFormat());
+ }
+
+ [Test]
+ public void TestRevision3()
+ {
+ BehaviourInfo behaviourInfo = new();
+
+ behaviourInfo.SetUserRevision(BehaviourInfo.BaseRevisionMagic + BehaviourInfo.Revision3);
+
+ Assert.IsTrue(behaviourInfo.IsAdpcmLoopContextBugFixed());
+ Assert.IsTrue(behaviourInfo.IsSplitterSupported());
+ Assert.IsTrue(behaviourInfo.IsLongSizePreDelaySupported());
+ Assert.IsFalse(behaviourInfo.IsAudioUsbDeviceOutputSupported());
+ Assert.IsFalse(behaviourInfo.IsFlushVoiceWaveBuffersSupported());
+ Assert.IsFalse(behaviourInfo.IsSplitterBugFixed());
+ Assert.IsFalse(behaviourInfo.IsElapsedFrameCountSupported());
+ Assert.IsFalse(behaviourInfo.IsDecodingBehaviourFlagSupported());
+ Assert.IsFalse(behaviourInfo.IsBiquadFilterEffectStateClearBugFixed());
+ Assert.IsFalse(behaviourInfo.IsMixInParameterDirtyOnlyUpdateSupported());
+ Assert.IsFalse(behaviourInfo.IsWaveBufferVersion2Supported());
+ Assert.IsFalse(behaviourInfo.IsEffectInfoVersion2Supported());
+ Assert.IsFalse(behaviourInfo.UseMultiTapBiquadFilterProcessing());
+ Assert.IsFalse(behaviourInfo.IsNewEffectChannelMappingSupported());
+ Assert.IsFalse(behaviourInfo.IsBiquadFilterParameterForSplitterEnabled());
+ Assert.IsFalse(behaviourInfo.IsSplitterPrevVolumeResetSupported());
+
+ Assert.AreEqual(0.70f, behaviourInfo.GetAudioRendererProcessingTimeLimit());
+ Assert.AreEqual(1, behaviourInfo.GetCommandProcessingTimeEstimatorVersion());
+ Assert.AreEqual(1, behaviourInfo.GetPerformanceMetricsDataFormat());
+ }
+
+ [Test]
+ public void TestRevision4()
+ {
+ BehaviourInfo behaviourInfo = new();
+
+ behaviourInfo.SetUserRevision(BehaviourInfo.BaseRevisionMagic + BehaviourInfo.Revision4);
+
+ Assert.IsTrue(behaviourInfo.IsAdpcmLoopContextBugFixed());
+ Assert.IsTrue(behaviourInfo.IsSplitterSupported());
+ Assert.IsTrue(behaviourInfo.IsLongSizePreDelaySupported());
+ Assert.IsTrue(behaviourInfo.IsAudioUsbDeviceOutputSupported());
+ Assert.IsFalse(behaviourInfo.IsFlushVoiceWaveBuffersSupported());
+ Assert.IsFalse(behaviourInfo.IsSplitterBugFixed());
+ Assert.IsFalse(behaviourInfo.IsElapsedFrameCountSupported());
+ Assert.IsFalse(behaviourInfo.IsDecodingBehaviourFlagSupported());
+ Assert.IsFalse(behaviourInfo.IsBiquadFilterEffectStateClearBugFixed());
+ Assert.IsFalse(behaviourInfo.IsMixInParameterDirtyOnlyUpdateSupported());
+ Assert.IsFalse(behaviourInfo.IsWaveBufferVersion2Supported());
+ Assert.IsFalse(behaviourInfo.IsEffectInfoVersion2Supported());
+ Assert.IsFalse(behaviourInfo.UseMultiTapBiquadFilterProcessing());
+ Assert.IsFalse(behaviourInfo.IsNewEffectChannelMappingSupported());
+ Assert.IsFalse(behaviourInfo.IsBiquadFilterParameterForSplitterEnabled());
+ Assert.IsFalse(behaviourInfo.IsSplitterPrevVolumeResetSupported());
+
+ Assert.AreEqual(0.75f, behaviourInfo.GetAudioRendererProcessingTimeLimit());
+ Assert.AreEqual(1, behaviourInfo.GetCommandProcessingTimeEstimatorVersion());
+ Assert.AreEqual(1, behaviourInfo.GetPerformanceMetricsDataFormat());
+ }
+
+ [Test]
+ public void TestRevision5()
+ {
+ BehaviourInfo behaviourInfo = new();
+
+ behaviourInfo.SetUserRevision(BehaviourInfo.BaseRevisionMagic + BehaviourInfo.Revision5);
+
+ Assert.IsTrue(behaviourInfo.IsAdpcmLoopContextBugFixed());
+ Assert.IsTrue(behaviourInfo.IsSplitterSupported());
+ Assert.IsTrue(behaviourInfo.IsLongSizePreDelaySupported());
+ Assert.IsTrue(behaviourInfo.IsAudioUsbDeviceOutputSupported());
+ Assert.IsTrue(behaviourInfo.IsFlushVoiceWaveBuffersSupported());
+ Assert.IsTrue(behaviourInfo.IsSplitterBugFixed());
+ Assert.IsTrue(behaviourInfo.IsElapsedFrameCountSupported());
+ Assert.IsTrue(behaviourInfo.IsDecodingBehaviourFlagSupported());
+ Assert.IsFalse(behaviourInfo.IsBiquadFilterEffectStateClearBugFixed());
+ Assert.IsFalse(behaviourInfo.IsMixInParameterDirtyOnlyUpdateSupported());
+ Assert.IsFalse(behaviourInfo.IsWaveBufferVersion2Supported());
+ Assert.IsFalse(behaviourInfo.IsEffectInfoVersion2Supported());
+ Assert.IsFalse(behaviourInfo.UseMultiTapBiquadFilterProcessing());
+ Assert.IsFalse(behaviourInfo.IsNewEffectChannelMappingSupported());
+ Assert.IsFalse(behaviourInfo.IsBiquadFilterParameterForSplitterEnabled());
+ Assert.IsFalse(behaviourInfo.IsSplitterPrevVolumeResetSupported());
+
+ Assert.AreEqual(0.80f, behaviourInfo.GetAudioRendererProcessingTimeLimit());
+ Assert.AreEqual(2, behaviourInfo.GetCommandProcessingTimeEstimatorVersion());
+ Assert.AreEqual(2, behaviourInfo.GetPerformanceMetricsDataFormat());
+ }
+
+ [Test]
+ public void TestRevision6()
+ {
+ BehaviourInfo behaviourInfo = new();
+
+ behaviourInfo.SetUserRevision(BehaviourInfo.BaseRevisionMagic + BehaviourInfo.Revision6);
+
+ Assert.IsTrue(behaviourInfo.IsAdpcmLoopContextBugFixed());
+ Assert.IsTrue(behaviourInfo.IsSplitterSupported());
+ Assert.IsTrue(behaviourInfo.IsLongSizePreDelaySupported());
+ Assert.IsTrue(behaviourInfo.IsAudioUsbDeviceOutputSupported());
+ Assert.IsTrue(behaviourInfo.IsFlushVoiceWaveBuffersSupported());
+ Assert.IsTrue(behaviourInfo.IsSplitterBugFixed());
+ Assert.IsTrue(behaviourInfo.IsElapsedFrameCountSupported());
+ Assert.IsTrue(behaviourInfo.IsDecodingBehaviourFlagSupported());
+ Assert.IsTrue(behaviourInfo.IsBiquadFilterEffectStateClearBugFixed());
+ Assert.IsFalse(behaviourInfo.IsMixInParameterDirtyOnlyUpdateSupported());
+ Assert.IsFalse(behaviourInfo.IsWaveBufferVersion2Supported());
+ Assert.IsFalse(behaviourInfo.IsEffectInfoVersion2Supported());
+ Assert.IsFalse(behaviourInfo.UseMultiTapBiquadFilterProcessing());
+ Assert.IsFalse(behaviourInfo.IsNewEffectChannelMappingSupported());
+ Assert.IsFalse(behaviourInfo.IsBiquadFilterParameterForSplitterEnabled());
+ Assert.IsFalse(behaviourInfo.IsSplitterPrevVolumeResetSupported());
+
+ Assert.AreEqual(0.80f, behaviourInfo.GetAudioRendererProcessingTimeLimit());
+ Assert.AreEqual(2, behaviourInfo.GetCommandProcessingTimeEstimatorVersion());
+ Assert.AreEqual(2, behaviourInfo.GetPerformanceMetricsDataFormat());
+ }
+
+ [Test]
+ public void TestRevision7()
+ {
+ BehaviourInfo behaviourInfo = new();
+
+ behaviourInfo.SetUserRevision(BehaviourInfo.BaseRevisionMagic + BehaviourInfo.Revision7);
+
+ Assert.IsTrue(behaviourInfo.IsAdpcmLoopContextBugFixed());
+ Assert.IsTrue(behaviourInfo.IsSplitterSupported());
+ Assert.IsTrue(behaviourInfo.IsLongSizePreDelaySupported());
+ Assert.IsTrue(behaviourInfo.IsAudioUsbDeviceOutputSupported());
+ Assert.IsTrue(behaviourInfo.IsFlushVoiceWaveBuffersSupported());
+ Assert.IsTrue(behaviourInfo.IsSplitterBugFixed());
+ Assert.IsTrue(behaviourInfo.IsElapsedFrameCountSupported());
+ Assert.IsTrue(behaviourInfo.IsDecodingBehaviourFlagSupported());
+ Assert.IsTrue(behaviourInfo.IsBiquadFilterEffectStateClearBugFixed());
+ Assert.IsTrue(behaviourInfo.IsMixInParameterDirtyOnlyUpdateSupported());
+ Assert.IsFalse(behaviourInfo.IsWaveBufferVersion2Supported());
+ Assert.IsFalse(behaviourInfo.IsEffectInfoVersion2Supported());
+ Assert.IsFalse(behaviourInfo.UseMultiTapBiquadFilterProcessing());
+ Assert.IsFalse(behaviourInfo.IsNewEffectChannelMappingSupported());
+ Assert.IsFalse(behaviourInfo.IsBiquadFilterParameterForSplitterEnabled());
+ Assert.IsFalse(behaviourInfo.IsSplitterPrevVolumeResetSupported());
+
+ Assert.AreEqual(0.80f, behaviourInfo.GetAudioRendererProcessingTimeLimit());
+ Assert.AreEqual(2, behaviourInfo.GetCommandProcessingTimeEstimatorVersion());
+ Assert.AreEqual(2, behaviourInfo.GetPerformanceMetricsDataFormat());
+ }
+
+ [Test]
+ public void TestRevision8()
+ {
+ BehaviourInfo behaviourInfo = new();
+
+ behaviourInfo.SetUserRevision(BehaviourInfo.BaseRevisionMagic + BehaviourInfo.Revision8);
+
+ Assert.IsTrue(behaviourInfo.IsAdpcmLoopContextBugFixed());
+ Assert.IsTrue(behaviourInfo.IsSplitterSupported());
+ Assert.IsTrue(behaviourInfo.IsLongSizePreDelaySupported());
+ Assert.IsTrue(behaviourInfo.IsAudioUsbDeviceOutputSupported());
+ Assert.IsTrue(behaviourInfo.IsFlushVoiceWaveBuffersSupported());
+ Assert.IsTrue(behaviourInfo.IsSplitterBugFixed());
+ Assert.IsTrue(behaviourInfo.IsElapsedFrameCountSupported());
+ Assert.IsTrue(behaviourInfo.IsDecodingBehaviourFlagSupported());
+ Assert.IsTrue(behaviourInfo.IsBiquadFilterEffectStateClearBugFixed());
+ Assert.IsTrue(behaviourInfo.IsMixInParameterDirtyOnlyUpdateSupported());
+ Assert.IsTrue(behaviourInfo.IsWaveBufferVersion2Supported());
+ Assert.IsFalse(behaviourInfo.IsEffectInfoVersion2Supported());
+ Assert.IsFalse(behaviourInfo.UseMultiTapBiquadFilterProcessing());
+ Assert.IsFalse(behaviourInfo.IsNewEffectChannelMappingSupported());
+ Assert.IsFalse(behaviourInfo.IsBiquadFilterParameterForSplitterEnabled());
+ Assert.IsFalse(behaviourInfo.IsSplitterPrevVolumeResetSupported());
+
+ Assert.AreEqual(0.80f, behaviourInfo.GetAudioRendererProcessingTimeLimit());
+ Assert.AreEqual(3, behaviourInfo.GetCommandProcessingTimeEstimatorVersion());
+ Assert.AreEqual(2, behaviourInfo.GetPerformanceMetricsDataFormat());
+ }
+
+ [Test]
+ public void TestRevision9()
+ {
+ BehaviourInfo behaviourInfo = new();
+
+ behaviourInfo.SetUserRevision(BehaviourInfo.BaseRevisionMagic + BehaviourInfo.Revision9);
+
+ Assert.IsTrue(behaviourInfo.IsAdpcmLoopContextBugFixed());
+ Assert.IsTrue(behaviourInfo.IsSplitterSupported());
+ Assert.IsTrue(behaviourInfo.IsLongSizePreDelaySupported());
+ Assert.IsTrue(behaviourInfo.IsAudioUsbDeviceOutputSupported());
+ Assert.IsTrue(behaviourInfo.IsFlushVoiceWaveBuffersSupported());
+ Assert.IsTrue(behaviourInfo.IsSplitterBugFixed());
+ Assert.IsTrue(behaviourInfo.IsElapsedFrameCountSupported());
+ Assert.IsTrue(behaviourInfo.IsDecodingBehaviourFlagSupported());
+ Assert.IsTrue(behaviourInfo.IsBiquadFilterEffectStateClearBugFixed());
+ Assert.IsTrue(behaviourInfo.IsMixInParameterDirtyOnlyUpdateSupported());
+ Assert.IsTrue(behaviourInfo.IsWaveBufferVersion2Supported());
+ Assert.IsTrue(behaviourInfo.IsEffectInfoVersion2Supported());
+ Assert.IsFalse(behaviourInfo.UseMultiTapBiquadFilterProcessing());
+ Assert.IsFalse(behaviourInfo.IsNewEffectChannelMappingSupported());
+ Assert.IsFalse(behaviourInfo.IsBiquadFilterParameterForSplitterEnabled());
+ Assert.IsFalse(behaviourInfo.IsSplitterPrevVolumeResetSupported());
+
+ Assert.AreEqual(0.80f, behaviourInfo.GetAudioRendererProcessingTimeLimit());
+ Assert.AreEqual(3, behaviourInfo.GetCommandProcessingTimeEstimatorVersion());
+ Assert.AreEqual(2, behaviourInfo.GetPerformanceMetricsDataFormat());
+ }
+
+ [Test]
+ public void TestRevision10()
+ {
+ BehaviourInfo behaviourInfo = new();
+
+ behaviourInfo.SetUserRevision(BehaviourInfo.BaseRevisionMagic + BehaviourInfo.Revision10);
+
+ Assert.IsTrue(behaviourInfo.IsAdpcmLoopContextBugFixed());
+ Assert.IsTrue(behaviourInfo.IsSplitterSupported());
+ Assert.IsTrue(behaviourInfo.IsLongSizePreDelaySupported());
+ Assert.IsTrue(behaviourInfo.IsAudioUsbDeviceOutputSupported());
+ Assert.IsTrue(behaviourInfo.IsFlushVoiceWaveBuffersSupported());
+ Assert.IsTrue(behaviourInfo.IsSplitterBugFixed());
+ Assert.IsTrue(behaviourInfo.IsElapsedFrameCountSupported());
+ Assert.IsTrue(behaviourInfo.IsDecodingBehaviourFlagSupported());
+ Assert.IsTrue(behaviourInfo.IsBiquadFilterEffectStateClearBugFixed());
+ Assert.IsTrue(behaviourInfo.IsMixInParameterDirtyOnlyUpdateSupported());
+ Assert.IsTrue(behaviourInfo.IsWaveBufferVersion2Supported());
+ Assert.IsTrue(behaviourInfo.IsEffectInfoVersion2Supported());
+ Assert.IsTrue(behaviourInfo.UseMultiTapBiquadFilterProcessing());
+ Assert.IsFalse(behaviourInfo.IsNewEffectChannelMappingSupported());
+ Assert.IsFalse(behaviourInfo.IsBiquadFilterParameterForSplitterEnabled());
+ Assert.IsFalse(behaviourInfo.IsSplitterPrevVolumeResetSupported());
+
+ Assert.AreEqual(0.80f, behaviourInfo.GetAudioRendererProcessingTimeLimit());
+ Assert.AreEqual(4, behaviourInfo.GetCommandProcessingTimeEstimatorVersion());
+ Assert.AreEqual(2, behaviourInfo.GetPerformanceMetricsDataFormat());
+ }
+
+ [Test]
+ public void TestRevision11()
+ {
+ BehaviourInfo behaviourInfo = new();
+
+ behaviourInfo.SetUserRevision(BehaviourInfo.BaseRevisionMagic + BehaviourInfo.Revision11);
+
+ Assert.IsTrue(behaviourInfo.IsAdpcmLoopContextBugFixed());
+ Assert.IsTrue(behaviourInfo.IsSplitterSupported());
+ Assert.IsTrue(behaviourInfo.IsLongSizePreDelaySupported());
+ Assert.IsTrue(behaviourInfo.IsAudioUsbDeviceOutputSupported());
+ Assert.IsTrue(behaviourInfo.IsFlushVoiceWaveBuffersSupported());
+ Assert.IsTrue(behaviourInfo.IsSplitterBugFixed());
+ Assert.IsTrue(behaviourInfo.IsElapsedFrameCountSupported());
+ Assert.IsTrue(behaviourInfo.IsDecodingBehaviourFlagSupported());
+ Assert.IsTrue(behaviourInfo.IsBiquadFilterEffectStateClearBugFixed());
+ Assert.IsTrue(behaviourInfo.IsMixInParameterDirtyOnlyUpdateSupported());
+ Assert.IsTrue(behaviourInfo.IsWaveBufferVersion2Supported());
+ Assert.IsTrue(behaviourInfo.IsEffectInfoVersion2Supported());
+ Assert.IsTrue(behaviourInfo.UseMultiTapBiquadFilterProcessing());
+ Assert.IsTrue(behaviourInfo.IsNewEffectChannelMappingSupported());
+ Assert.IsFalse(behaviourInfo.IsBiquadFilterParameterForSplitterEnabled());
+ Assert.IsFalse(behaviourInfo.IsSplitterPrevVolumeResetSupported());
+
+ Assert.AreEqual(0.80f, behaviourInfo.GetAudioRendererProcessingTimeLimit());
+ Assert.AreEqual(5, behaviourInfo.GetCommandProcessingTimeEstimatorVersion());
+ Assert.AreEqual(2, behaviourInfo.GetPerformanceMetricsDataFormat());
+ }
+
+ [Test]
+ public void TestRevision12()
+ {
+ BehaviourInfo behaviourInfo = new();
+
+ behaviourInfo.SetUserRevision(BehaviourInfo.BaseRevisionMagic + BehaviourInfo.Revision12);
+
+ Assert.IsTrue(behaviourInfo.IsAdpcmLoopContextBugFixed());
+ Assert.IsTrue(behaviourInfo.IsSplitterSupported());
+ Assert.IsTrue(behaviourInfo.IsLongSizePreDelaySupported());
+ Assert.IsTrue(behaviourInfo.IsAudioUsbDeviceOutputSupported());
+ Assert.IsTrue(behaviourInfo.IsFlushVoiceWaveBuffersSupported());
+ Assert.IsTrue(behaviourInfo.IsSplitterBugFixed());
+ Assert.IsTrue(behaviourInfo.IsElapsedFrameCountSupported());
+ Assert.IsTrue(behaviourInfo.IsDecodingBehaviourFlagSupported());
+ Assert.IsTrue(behaviourInfo.IsBiquadFilterEffectStateClearBugFixed());
+ Assert.IsTrue(behaviourInfo.IsMixInParameterDirtyOnlyUpdateSupported());
+ Assert.IsTrue(behaviourInfo.IsWaveBufferVersion2Supported());
+ Assert.IsTrue(behaviourInfo.IsEffectInfoVersion2Supported());
+ Assert.IsTrue(behaviourInfo.UseMultiTapBiquadFilterProcessing());
+ Assert.IsTrue(behaviourInfo.IsNewEffectChannelMappingSupported());
+ Assert.IsTrue(behaviourInfo.IsBiquadFilterParameterForSplitterEnabled());
+ Assert.IsFalse(behaviourInfo.IsSplitterPrevVolumeResetSupported());
+
+ Assert.AreEqual(0.80f, behaviourInfo.GetAudioRendererProcessingTimeLimit());
+ Assert.AreEqual(5, behaviourInfo.GetCommandProcessingTimeEstimatorVersion());
+ Assert.AreEqual(2, behaviourInfo.GetPerformanceMetricsDataFormat());
+ }
+
+ [Test]
+ public void TestRevision13()
+ {
+ BehaviourInfo behaviourInfo = new();
+
+ behaviourInfo.SetUserRevision(BehaviourInfo.BaseRevisionMagic + BehaviourInfo.Revision13);
+
+ Assert.IsTrue(behaviourInfo.IsAdpcmLoopContextBugFixed());
+ Assert.IsTrue(behaviourInfo.IsSplitterSupported());
+ Assert.IsTrue(behaviourInfo.IsLongSizePreDelaySupported());
+ Assert.IsTrue(behaviourInfo.IsAudioUsbDeviceOutputSupported());
+ Assert.IsTrue(behaviourInfo.IsFlushVoiceWaveBuffersSupported());
+ Assert.IsTrue(behaviourInfo.IsSplitterBugFixed());
+ Assert.IsTrue(behaviourInfo.IsElapsedFrameCountSupported());
+ Assert.IsTrue(behaviourInfo.IsDecodingBehaviourFlagSupported());
+ Assert.IsTrue(behaviourInfo.IsBiquadFilterEffectStateClearBugFixed());
+ Assert.IsTrue(behaviourInfo.IsMixInParameterDirtyOnlyUpdateSupported());
+ Assert.IsTrue(behaviourInfo.IsWaveBufferVersion2Supported());
+ Assert.IsTrue(behaviourInfo.IsEffectInfoVersion2Supported());
+ Assert.IsTrue(behaviourInfo.UseMultiTapBiquadFilterProcessing());
+ Assert.IsTrue(behaviourInfo.IsNewEffectChannelMappingSupported());
+ Assert.IsTrue(behaviourInfo.IsBiquadFilterParameterForSplitterEnabled());
+ Assert.IsTrue(behaviourInfo.IsSplitterPrevVolumeResetSupported());
+
+ Assert.AreEqual(0.80f, behaviourInfo.GetAudioRendererProcessingTimeLimit());
+ Assert.AreEqual(5, behaviourInfo.GetCommandProcessingTimeEstimatorVersion());
+ Assert.AreEqual(2, behaviourInfo.GetPerformanceMetricsDataFormat());
+ }
+ }
+}
diff --git a/src/Ryujinx.Tests/Audio/Renderer/Server/MemoryPoolStateTests.cs b/src/Ryujinx.Tests/Audio/Renderer/Server/MemoryPoolInfoTests.cs
similarity index 80%
rename from src/Ryujinx.Tests/Audio/Renderer/Server/MemoryPoolStateTests.cs
rename to src/Ryujinx.Tests/Audio/Renderer/Server/MemoryPoolInfoTests.cs
index c6a2e473e..612df4dc1 100644
--- a/src/Ryujinx.Tests/Audio/Renderer/Server/MemoryPoolStateTests.cs
+++ b/src/Ryujinx.Tests/Audio/Renderer/Server/MemoryPoolInfoTests.cs
@@ -4,18 +4,18 @@ using System.Runtime.CompilerServices;
namespace Ryujinx.Tests.Audio.Renderer.Server
{
- class MemoryPoolStateTests
+ class MemoryPoolInfoTests
{
[Test]
public void EnsureTypeSize()
{
- Assert.AreEqual(Unsafe.SizeOf(), 0x20);
+ Assert.AreEqual(Unsafe.SizeOf(), 0x20);
}
[Test]
public void TestContains()
{
- MemoryPoolState memoryPool = MemoryPoolState.Create(MemoryPoolState.LocationType.Cpu);
+ MemoryPoolInfo memoryPool = MemoryPoolInfo.Create(MemoryPoolInfo.LocationType.Cpu);
memoryPool.SetCpuAddress(0x1000000, 0x1000);
@@ -32,7 +32,7 @@ namespace Ryujinx.Tests.Audio.Renderer.Server
[Test]
public void TestTranslate()
{
- MemoryPoolState memoryPool = MemoryPoolState.Create(MemoryPoolState.LocationType.Cpu);
+ MemoryPoolInfo memoryPool = MemoryPoolInfo.Create(MemoryPoolInfo.LocationType.Cpu);
memoryPool.SetCpuAddress(0x1000000, 0x1000);
@@ -48,7 +48,7 @@ namespace Ryujinx.Tests.Audio.Renderer.Server
[Test]
public void TestIsMapped()
{
- MemoryPoolState memoryPool = MemoryPoolState.Create(MemoryPoolState.LocationType.Cpu);
+ MemoryPoolInfo memoryPool = MemoryPoolInfo.Create(MemoryPoolInfo.LocationType.Cpu);
memoryPool.SetCpuAddress(0x1000000, 0x1000);
diff --git a/src/Ryujinx.Tests/Audio/Renderer/Server/MixStateTests.cs b/src/Ryujinx.Tests/Audio/Renderer/Server/MixInfoTests.cs
similarity index 73%
rename from src/Ryujinx.Tests/Audio/Renderer/Server/MixStateTests.cs
rename to src/Ryujinx.Tests/Audio/Renderer/Server/MixInfoTests.cs
index 6262913b4..dbdc5c343 100644
--- a/src/Ryujinx.Tests/Audio/Renderer/Server/MixStateTests.cs
+++ b/src/Ryujinx.Tests/Audio/Renderer/Server/MixInfoTests.cs
@@ -4,12 +4,12 @@ using System.Runtime.CompilerServices;
namespace Ryujinx.Tests.Audio.Renderer.Server
{
- class MixStateTests
+ class MixInfoTests
{
[Test]
public void EnsureTypeSize()
{
- Assert.AreEqual(0x940, Unsafe.SizeOf());
+ Assert.AreEqual(0x940, Unsafe.SizeOf());
}
}
}
diff --git a/src/Ryujinx.Tests/Audio/Renderer/Server/PoolMapperTests.cs b/src/Ryujinx.Tests/Audio/Renderer/Server/PoolMapperTests.cs
index 941afae6f..5a1256937 100644
--- a/src/Ryujinx.Tests/Audio/Renderer/Server/PoolMapperTests.cs
+++ b/src/Ryujinx.Tests/Audio/Renderer/Server/PoolMapperTests.cs
@@ -16,8 +16,8 @@ namespace Ryujinx.Tests.Audio.Renderer.Server
public void TestInitializeSystemPool()
{
PoolMapper poolMapper = new(DummyProcessHandle, true);
- MemoryPoolState memoryPoolDsp = MemoryPoolState.Create(MemoryPoolState.LocationType.Dsp);
- MemoryPoolState memoryPoolCpu = MemoryPoolState.Create(MemoryPoolState.LocationType.Cpu);
+ MemoryPoolInfo memoryPoolDsp = MemoryPoolInfo.Create(MemoryPoolInfo.LocationType.Dsp);
+ MemoryPoolInfo memoryPoolCpu = MemoryPoolInfo.Create(MemoryPoolInfo.LocationType.Cpu);
const CpuAddress CpuAddress = 0x20000;
const DspAddress DspAddress = CpuAddress; // TODO: DSP LLE
@@ -35,8 +35,8 @@ namespace Ryujinx.Tests.Audio.Renderer.Server
public void TestGetProcessHandle()
{
PoolMapper poolMapper = new(DummyProcessHandle, true);
- MemoryPoolState memoryPoolDsp = MemoryPoolState.Create(MemoryPoolState.LocationType.Dsp);
- MemoryPoolState memoryPoolCpu = MemoryPoolState.Create(MemoryPoolState.LocationType.Cpu);
+ MemoryPoolInfo memoryPoolDsp = MemoryPoolInfo.Create(MemoryPoolInfo.LocationType.Dsp);
+ MemoryPoolInfo memoryPoolCpu = MemoryPoolInfo.Create(MemoryPoolInfo.LocationType.Cpu);
Assert.AreEqual(0xFFFF8001, poolMapper.GetProcessHandle(ref memoryPoolCpu));
Assert.AreEqual(DummyProcessHandle, poolMapper.GetProcessHandle(ref memoryPoolDsp));
@@ -46,8 +46,8 @@ namespace Ryujinx.Tests.Audio.Renderer.Server
public void TestMappings()
{
PoolMapper poolMapper = new(DummyProcessHandle, true);
- MemoryPoolState memoryPoolDsp = MemoryPoolState.Create(MemoryPoolState.LocationType.Dsp);
- MemoryPoolState memoryPoolCpu = MemoryPoolState.Create(MemoryPoolState.LocationType.Cpu);
+ MemoryPoolInfo memoryPoolDsp = MemoryPoolInfo.Create(MemoryPoolInfo.LocationType.Dsp);
+ MemoryPoolInfo memoryPoolCpu = MemoryPoolInfo.Create(MemoryPoolInfo.LocationType.Cpu);
const CpuAddress CpuAddress = 0x20000;
const DspAddress DspAddress = CpuAddress; // TODO: DSP LLE
@@ -77,11 +77,11 @@ namespace Ryujinx.Tests.Audio.Renderer.Server
const int MemoryPoolStateArraySize = 0x10;
const CpuAddress CpuAddressRegionEnding = CpuAddress * MemoryPoolStateArraySize;
- MemoryPoolState[] memoryPoolStateArray = new MemoryPoolState[MemoryPoolStateArraySize];
+ MemoryPoolInfo[] memoryPoolStateArray = new MemoryPoolInfo[MemoryPoolStateArraySize];
for (int i = 0; i < memoryPoolStateArray.Length; i++)
{
- memoryPoolStateArray[i] = MemoryPoolState.Create(MemoryPoolState.LocationType.Cpu);
+ memoryPoolStateArray[i] = MemoryPoolInfo.Create(MemoryPoolInfo.LocationType.Cpu);
memoryPoolStateArray[i].SetCpuAddress(CpuAddress + (ulong)i * CpuSize, CpuSize);
}
diff --git a/src/Ryujinx.Tests/Audio/Renderer/Server/SplitterDestinationTests.cs b/src/Ryujinx.Tests/Audio/Renderer/Server/SplitterDestinationTests.cs
index 80b801336..e85111c9f 100644
--- a/src/Ryujinx.Tests/Audio/Renderer/Server/SplitterDestinationTests.cs
+++ b/src/Ryujinx.Tests/Audio/Renderer/Server/SplitterDestinationTests.cs
@@ -10,7 +10,7 @@ namespace Ryujinx.Tests.Audio.Renderer.Server
public void EnsureTypeSize()
{
Assert.AreEqual(0xE0, Unsafe.SizeOf());
- Assert.AreEqual(0x110, Unsafe.SizeOf());
+ Assert.AreEqual(0x128, Unsafe.SizeOf());
}
}
}
diff --git a/src/Ryujinx.Tests/Audio/Renderer/Server/VoiceStateTests.cs b/src/Ryujinx.Tests/Audio/Renderer/Server/VoiceInfoTests.cs
similarity index 71%
rename from src/Ryujinx.Tests/Audio/Renderer/Server/VoiceStateTests.cs
rename to src/Ryujinx.Tests/Audio/Renderer/Server/VoiceInfoTests.cs
index dbd6eff8f..1382d693c 100644
--- a/src/Ryujinx.Tests/Audio/Renderer/Server/VoiceStateTests.cs
+++ b/src/Ryujinx.Tests/Audio/Renderer/Server/VoiceInfoTests.cs
@@ -4,12 +4,12 @@ using System.Runtime.CompilerServices;
namespace Ryujinx.Tests.Audio.Renderer.Server
{
- class VoiceStateTests
+ class VoiceInfoTests
{
[Test]
public void EnsureTypeSize()
{
- Assert.LessOrEqual(Unsafe.SizeOf(), 0x220);
+ Assert.LessOrEqual(Unsafe.SizeOf(), 0x238);
}
}
}
diff --git a/src/Ryujinx.Tests/Audio/Renderer/VoiceInParameterTests.cs b/src/Ryujinx.Tests/Audio/Renderer/VoiceInParameterTests.cs
index 239da195a..e91675563 100644
--- a/src/Ryujinx.Tests/Audio/Renderer/VoiceInParameterTests.cs
+++ b/src/Ryujinx.Tests/Audio/Renderer/VoiceInParameterTests.cs
@@ -9,7 +9,8 @@ namespace Ryujinx.Tests.Audio.Renderer
[Test]
public void EnsureTypeSize()
{
- Assert.AreEqual(0x170, Unsafe.SizeOf());
+ Assert.AreEqual(0x170, Unsafe.SizeOf());
+ Assert.AreEqual(0x188, Unsafe.SizeOf());
}
}
}
diff --git a/src/Ryujinx.Tests/Memory/PartialUnmaps.cs b/src/Ryujinx.Tests/Memory/PartialUnmaps.cs
index 92b994279..1a01a36bc 100644
--- a/src/Ryujinx.Tests/Memory/PartialUnmaps.cs
+++ b/src/Ryujinx.Tests/Memory/PartialUnmaps.cs
@@ -226,7 +226,7 @@ namespace Ryujinx.Tests.Memory
ref PartialUnmapState state = ref PartialUnmapState.GetRef();
- // Create some state to be used for managing the native writing loop.
+ // Create some info to be used for managing the native writing loop.
int stateSize = Unsafe.SizeOf();
IntPtr statePtr = Marshal.AllocHGlobal(stateSize);
Unsafe.InitBlockUnaligned((void*)statePtr, 0, (uint)stateSize);