aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Ryujinx.Audio/Renderer/Dsp/Command/DelayCommand.cs7
-rw-r--r--Ryujinx.Audio/Renderer/Dsp/Command/Reverb3dCommand.cs9
-rw-r--r--Ryujinx.Audio/Renderer/Dsp/Command/ReverbCommand.cs9
-rw-r--r--Ryujinx.Audio/Renderer/Dsp/DataSourceHelper.cs34
-rw-r--r--Ryujinx.Audio/Renderer/Dsp/State/Reverb3dState.cs4
-rw-r--r--Ryujinx.Audio/Renderer/Dsp/State/ReverbState.cs4
-rw-r--r--Ryujinx.Audio/Renderer/Server/AudioRenderSystem.cs3
-rw-r--r--Ryujinx.Audio/Renderer/Server/BehaviourContext.cs24
-rw-r--r--Ryujinx.Audio/Renderer/Server/CommandBuffer.cs15
-rw-r--r--Ryujinx.Audio/Renderer/Server/CommandGenerator.cs18
-rw-r--r--Ryujinx.Audio/Renderer/Server/CommandProcessingTimeEstimatorVersion3.cs6
-rw-r--r--Ryujinx.Audio/Renderer/Server/CommandProcessingTimeEstimatorVersion5.cs253
12 files changed, 358 insertions, 28 deletions
diff --git a/Ryujinx.Audio/Renderer/Dsp/Command/DelayCommand.cs b/Ryujinx.Audio/Renderer/Dsp/Command/DelayCommand.cs
index ace0f274..8d416cc3 100644
--- a/Ryujinx.Audio/Renderer/Dsp/Command/DelayCommand.cs
+++ b/Ryujinx.Audio/Renderer/Dsp/Command/DelayCommand.cs
@@ -45,7 +45,7 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
private const int FixedPointPrecision = 14;
- public DelayCommand(uint bufferOffset, DelayParameter parameter, Memory<DelayState> state, bool isEnabled, ulong workBuffer, int nodeId)
+ public DelayCommand(uint bufferOffset, DelayParameter parameter, Memory<DelayState> state, bool isEnabled, ulong workBuffer, int nodeId, bool newEffectChannelMappingSupported)
{
Enabled = true;
NodeId = nodeId;
@@ -63,6 +63,11 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
InputBufferIndices[i] = (ushort)(bufferOffset + Parameter.Input[i]);
OutputBufferIndices[i] = (ushort)(bufferOffset + Parameter.Output[i]);
}
+
+ // NOTE: We do the opposite as Nintendo here for now to restore previous behaviour
+ // TODO: Update delay processing and remove this to use RemapLegacyChannelEffectMappingToChannelResourceMapping.
+ DataSourceHelper.RemapChannelResourceMappingToLegacy(newEffectChannelMappingSupported, InputBufferIndices);
+ DataSourceHelper.RemapChannelResourceMappingToLegacy(newEffectChannelMappingSupported, OutputBufferIndices);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
diff --git a/Ryujinx.Audio/Renderer/Dsp/Command/Reverb3dCommand.cs b/Ryujinx.Audio/Renderer/Dsp/Command/Reverb3dCommand.cs
index 7da9804e..5cbc1060 100644
--- a/Ryujinx.Audio/Renderer/Dsp/Command/Reverb3dCommand.cs
+++ b/Ryujinx.Audio/Renderer/Dsp/Command/Reverb3dCommand.cs
@@ -63,7 +63,7 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
private Reverb3dParameter _parameter;
- public Reverb3dCommand(uint bufferOffset, Reverb3dParameter parameter, Memory<Reverb3dState> state, bool isEnabled, ulong workBuffer, int nodeId)
+ public Reverb3dCommand(uint bufferOffset, Reverb3dParameter parameter, Memory<Reverb3dState> state, bool isEnabled, ulong workBuffer, int nodeId, bool newEffectChannelMappingSupported)
{
Enabled = true;
IsEffectEnabled = isEnabled;
@@ -80,6 +80,11 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
InputBufferIndices[i] = (ushort)(bufferOffset + Parameter.Input[i]);
OutputBufferIndices[i] = (ushort)(bufferOffset + Parameter.Output[i]);
}
+
+ // NOTE: We do the opposite as Nintendo here for now to restore previous behaviour
+ // TODO: Update reverb 3d processing and remove this to use RemapLegacyChannelEffectMappingToChannelResourceMapping.
+ DataSourceHelper.RemapChannelResourceMappingToLegacy(newEffectChannelMappingSupported, InputBufferIndices);
+ DataSourceHelper.RemapChannelResourceMappingToLegacy(newEffectChannelMappingSupported, OutputBufferIndices);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
@@ -194,7 +199,7 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
if (isSurround)
{
- *((float*)outputBuffers[4] + sampleIndex) += (outputValues[4] + state.BackLeftDelayLine.Update((values[2] - values[3]) * 0.5f) + channelInput[4] * state.DryGain);
+ *((float*)outputBuffers[4] + sampleIndex) += (outputValues[4] + state.FrontCenterDelayLine.Update((values[2] - values[3]) * 0.5f) + channelInput[4] * state.DryGain);
}
}
}
diff --git a/Ryujinx.Audio/Renderer/Dsp/Command/ReverbCommand.cs b/Ryujinx.Audio/Renderer/Dsp/Command/ReverbCommand.cs
index 1da9c81b..15c67f17 100644
--- a/Ryujinx.Audio/Renderer/Dsp/Command/ReverbCommand.cs
+++ b/Ryujinx.Audio/Renderer/Dsp/Command/ReverbCommand.cs
@@ -66,7 +66,7 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
private const int FixedPointPrecision = 14;
- public ReverbCommand(uint bufferOffset, ReverbParameter parameter, Memory<ReverbState> state, bool isEnabled, ulong workBuffer, int nodeId, bool isLongSizePreDelaySupported)
+ public ReverbCommand(uint bufferOffset, ReverbParameter parameter, Memory<ReverbState> state, bool isEnabled, ulong workBuffer, int nodeId, bool isLongSizePreDelaySupported, bool newEffectChannelMappingSupported)
{
Enabled = true;
IsEffectEnabled = isEnabled;
@@ -85,6 +85,11 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
}
IsLongSizePreDelaySupported = isLongSizePreDelaySupported;
+
+ // NOTE: We do the opposite as Nintendo here for now to restore previous behaviour
+ // TODO: Update reverb processing and remove this to use RemapLegacyChannelEffectMappingToChannelResourceMapping.
+ DataSourceHelper.RemapChannelResourceMappingToLegacy(newEffectChannelMappingSupported, InputBufferIndices);
+ DataSourceHelper.RemapChannelResourceMappingToLegacy(newEffectChannelMappingSupported, OutputBufferIndices);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
@@ -214,7 +219,7 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
if (isSurround)
{
- outputValues[4] += state.BackLeftDelayLine.Update((feedbackOutputValues[2] - feedbackOutputValues[3]) * 0.5f);
+ outputValues[4] += state.FrontCenterDelayLine.Update((feedbackOutputValues[2] - feedbackOutputValues[3]) * 0.5f);
}
for (int channelIndex = 0; channelIndex < Parameter.ChannelCount; channelIndex++)
diff --git a/Ryujinx.Audio/Renderer/Dsp/DataSourceHelper.cs b/Ryujinx.Audio/Renderer/Dsp/DataSourceHelper.cs
index 4732f504..5c413ee1 100644
--- a/Ryujinx.Audio/Renderer/Dsp/DataSourceHelper.cs
+++ b/Ryujinx.Audio/Renderer/Dsp/DataSourceHelper.cs
@@ -445,5 +445,39 @@ namespace Ryujinx.Audio.Renderer.Dsp
ToIntSlow(output, input, sampleCount);
}
}
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static void RemapLegacyChannelEffectMappingToChannelResourceMapping(bool isSupported, Span<ushort> bufferIndices)
+ {
+ if (!isSupported && bufferIndices.Length == 6)
+ {
+ ushort backLeft = bufferIndices[2];
+ ushort backRight = bufferIndices[3];
+ ushort frontCenter = bufferIndices[4];
+ ushort lowFrequency = bufferIndices[5];
+
+ bufferIndices[2] = frontCenter;
+ bufferIndices[3] = lowFrequency;
+ bufferIndices[4] = backLeft;
+ bufferIndices[5] = backRight;
+ }
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static void RemapChannelResourceMappingToLegacy(bool isSupported, Span<ushort> bufferIndices)
+ {
+ if (isSupported && bufferIndices.Length == 6)
+ {
+ ushort frontCenter = bufferIndices[2];
+ ushort lowFrequency = bufferIndices[3];
+ ushort backLeft = bufferIndices[4];
+ ushort backRight = bufferIndices[5];
+
+ bufferIndices[2] = backLeft;
+ bufferIndices[3] = backRight;
+ bufferIndices[4] = frontCenter;
+ bufferIndices[5] = lowFrequency;
+ }
+ }
}
}
diff --git a/Ryujinx.Audio/Renderer/Dsp/State/Reverb3dState.cs b/Ryujinx.Audio/Renderer/Dsp/State/Reverb3dState.cs
index be0f9734..dc7d6efe 100644
--- a/Ryujinx.Audio/Renderer/Dsp/State/Reverb3dState.cs
+++ b/Ryujinx.Audio/Renderer/Dsp/State/Reverb3dState.cs
@@ -34,7 +34,7 @@ namespace Ryujinx.Audio.Renderer.Dsp.State
public DecayDelay[] DecayDelays1 { get; }
public DecayDelay[] DecayDelays2 { get; }
public IDelayLine PreDelayLine { get; }
- public IDelayLine BackLeftDelayLine { get; }
+ public IDelayLine FrontCenterDelayLine { get; }
public float DryGain { get; private set; }
public uint[] EarlyDelayTime { get; private set; }
public float PreviousPreDelayValue { get; set; }
@@ -69,7 +69,7 @@ namespace Ryujinx.Audio.Renderer.Dsp.State
}
PreDelayLine = new DelayLine3d(sampleRate, 400);
- BackLeftDelayLine = new DelayLine3d(sampleRate, 5);
+ FrontCenterDelayLine = new DelayLine3d(sampleRate, 5);
UpdateParameter(ref parameter);
}
diff --git a/Ryujinx.Audio/Renderer/Dsp/State/ReverbState.cs b/Ryujinx.Audio/Renderer/Dsp/State/ReverbState.cs
index c75bdce2..fc0c6539 100644
--- a/Ryujinx.Audio/Renderer/Dsp/State/ReverbState.cs
+++ b/Ryujinx.Audio/Renderer/Dsp/State/ReverbState.cs
@@ -97,7 +97,7 @@ namespace Ryujinx.Audio.Renderer.Dsp.State
public DelayLine[] FdnDelayLines { get; }
public DecayDelay[] DecayDelays { get; }
public DelayLine PreDelayLine { get; }
- public DelayLine BackLeftDelayLine { get; }
+ public DelayLine FrontCenterDelayLine { get; }
public uint[] EarlyDelayTime { get; }
public float[] EarlyGain { get; }
public uint PreDelayLineDelayTime { get; private set; }
@@ -149,7 +149,7 @@ namespace Ryujinx.Audio.Renderer.Dsp.State
}
PreDelayLine = new DelayLine(sampleRate, preDelayTimeMax);
- BackLeftDelayLine = new DelayLine(sampleRate, 5.0f);
+ FrontCenterDelayLine = new DelayLine(sampleRate, 5.0f);
UpdateParameter(ref parameter);
}
diff --git a/Ryujinx.Audio/Renderer/Server/AudioRenderSystem.cs b/Ryujinx.Audio/Renderer/Server/AudioRenderSystem.cs
index 277c2474..0c41909e 100644
--- a/Ryujinx.Audio/Renderer/Server/AudioRenderSystem.cs
+++ b/Ryujinx.Audio/Renderer/Server/AudioRenderSystem.cs
@@ -363,6 +363,9 @@ namespace Ryujinx.Audio.Renderer.Server
case 4:
_commandProcessingTimeEstimator = new CommandProcessingTimeEstimatorVersion4(_sampleCount, _mixBufferCount);
break;
+ case 5:
+ _commandProcessingTimeEstimator = new CommandProcessingTimeEstimatorVersion5(_sampleCount, _mixBufferCount);
+ break;
default:
throw new NotImplementedException($"Unsupported processing time estimator version {_behaviourContext.GetCommandProcessingTimeEstimatorVersion()}.");
}
diff --git a/Ryujinx.Audio/Renderer/Server/BehaviourContext.cs b/Ryujinx.Audio/Renderer/Server/BehaviourContext.cs
index d3a65b72..cf9cda0b 100644
--- a/Ryujinx.Audio/Renderer/Server/BehaviourContext.cs
+++ b/Ryujinx.Audio/Renderer/Server/BehaviourContext.cs
@@ -108,9 +108,17 @@ namespace Ryujinx.Audio.Renderer.Server
public const int Revision10 = 10 << 24;
/// <summary>
+ /// REV11:
+ /// The "legacy" effects (Delay, Reverb and Reverb 3D) were updated to match the standard channel mapping used by the audio renderer.
+ /// A new version of the command estimator was added to address timing changes caused by the legacy effects changes.
+ /// </summary>
+ /// <remarks>This was added in system update 14.0.0</remarks>
+ public const int Revision11 = 11 << 24;
+
+ /// <summary>
/// Last revision supported by the implementation.
/// </summary>
- public const int LastRevision = Revision10;
+ public const int LastRevision = Revision11;
/// <summary>
/// Target revision magic supported by the implementation.
@@ -367,11 +375,25 @@ namespace Ryujinx.Audio.Renderer.Server
}
/// <summary>
+ /// Check if the audio renderer should support new channel resource mapping for 5.1 on Delay, Reverb and Reverb 3D effects.
+ /// </summary>
+ /// <returns>True if the audio renderer support new channel resource mapping for 5.1.</returns>
+ public bool IsNewEffectChannelMappingSupported()
+ {
+ return CheckFeatureSupported(UserRevision, BaseRevisionMagic + Revision11);
+ }
+
+ /// <summary>
/// Get the version of the <see cref="ICommandProcessingTimeEstimator"/>.
/// </summary>
/// <returns>The version of the <see cref="ICommandProcessingTimeEstimator"/>.</returns>
public int GetCommandProcessingTimeEstimatorVersion()
{
+ if (CheckFeatureSupported(UserRevision, BaseRevisionMagic + Revision11))
+ {
+ return 5;
+ }
+
if (CheckFeatureSupported(UserRevision, BaseRevisionMagic + Revision10))
{
return 4;
diff --git a/Ryujinx.Audio/Renderer/Server/CommandBuffer.cs b/Ryujinx.Audio/Renderer/Server/CommandBuffer.cs
index 0e74c301..c3aae96d 100644
--- a/Ryujinx.Audio/Renderer/Server/CommandBuffer.cs
+++ b/Ryujinx.Audio/Renderer/Server/CommandBuffer.cs
@@ -336,11 +336,12 @@ namespace Ryujinx.Audio.Renderer.Server
/// <param name="workBuffer">The work buffer to use for processing.</param>
/// <param name="nodeId">The node id associated to this command.</param>
/// <param name="isLongSizePreDelaySupported">If set to true, the long size pre-delay is supported.</param>
- public void GenerateReverbEffect(uint bufferOffset, ReverbParameter parameter, Memory<ReverbState> state, bool isEnabled, CpuAddress workBuffer, int nodeId, bool isLongSizePreDelaySupported)
+ /// <param name="newEffectChannelMappingSupported">If set to true, the new effect channel mapping for 5.1 is supported.</param>
+ public void GenerateReverbEffect(uint bufferOffset, ReverbParameter parameter, Memory<ReverbState> state, bool isEnabled, CpuAddress workBuffer, int nodeId, bool isLongSizePreDelaySupported, bool newEffectChannelMappingSupported)
{
if (parameter.IsChannelCountValid())
{
- ReverbCommand command = new ReverbCommand(bufferOffset, parameter, state, isEnabled, workBuffer, nodeId, isLongSizePreDelaySupported);
+ ReverbCommand command = new ReverbCommand(bufferOffset, parameter, state, isEnabled, workBuffer, nodeId, isLongSizePreDelaySupported, newEffectChannelMappingSupported);
command.EstimatedProcessingTime = _commandProcessingTimeEstimator.Estimate(command);
@@ -357,11 +358,12 @@ namespace Ryujinx.Audio.Renderer.Server
/// <param name="isEnabled">Set to true if the effect should be active.</param>
/// <param name="workBuffer">The work buffer to use for processing.</param>
/// <param name="nodeId">The node id associated to this command.</param>
- public void GenerateReverb3dEffect(uint bufferOffset, Reverb3dParameter parameter, Memory<Reverb3dState> state, bool isEnabled, CpuAddress workBuffer, int nodeId)
+ /// <param name="newEffectChannelMappingSupported">If set to true, the new effect channel mapping for 5.1 is supported.</param>
+ public void GenerateReverb3dEffect(uint bufferOffset, Reverb3dParameter parameter, Memory<Reverb3dState> state, bool isEnabled, CpuAddress workBuffer, int nodeId, bool newEffectChannelMappingSupported)
{
if (parameter.IsChannelCountValid())
{
- Reverb3dCommand command = new Reverb3dCommand(bufferOffset, parameter, state, isEnabled, workBuffer, nodeId);
+ Reverb3dCommand command = new Reverb3dCommand(bufferOffset, parameter, state, isEnabled, workBuffer, nodeId, newEffectChannelMappingSupported);
command.EstimatedProcessingTime = _commandProcessingTimeEstimator.Estimate(command);
@@ -379,11 +381,12 @@ namespace Ryujinx.Audio.Renderer.Server
/// <param name="isEnabled">Set to true if the effect should be active.</param>
/// <param name="workBuffer">The work buffer to use for processing.</param>
/// <param name="nodeId">The node id associated to this command.</param>
- public void GenerateDelayEffect(uint bufferOffset, DelayParameter parameter, Memory<DelayState> state, bool isEnabled, CpuAddress workBuffer, int nodeId)
+ /// <param name="newEffectChannelMappingSupported">If set to true, the new effect channel mapping for 5.1 is supported.</param>
+ public void GenerateDelayEffect(uint bufferOffset, DelayParameter parameter, Memory<DelayState> state, bool isEnabled, CpuAddress workBuffer, int nodeId, bool newEffectChannelMappingSupported)
{
if (parameter.IsChannelCountValid())
{
- DelayCommand command = new DelayCommand(bufferOffset, parameter, state, isEnabled, workBuffer, nodeId);
+ DelayCommand command = new DelayCommand(bufferOffset, parameter, state, isEnabled, workBuffer, nodeId, newEffectChannelMappingSupported);
command.EstimatedProcessingTime = _commandProcessingTimeEstimator.Estimate(command);
diff --git a/Ryujinx.Audio/Renderer/Server/CommandGenerator.cs b/Ryujinx.Audio/Renderer/Server/CommandGenerator.cs
index 85c019c2..8194ebf1 100644
--- a/Ryujinx.Audio/Renderer/Server/CommandGenerator.cs
+++ b/Ryujinx.Audio/Renderer/Server/CommandGenerator.cs
@@ -483,31 +483,31 @@ namespace Ryujinx.Audio.Renderer.Server
}
}
- private void GenerateDelayEffect(uint bufferOffset, DelayEffect effect, int nodeId)
+ private void GenerateDelayEffect(uint bufferOffset, DelayEffect effect, int nodeId, bool newEffectChannelMappingSupported)
{
Debug.Assert(effect.Type == EffectType.Delay);
ulong workBuffer = effect.GetWorkBuffer(-1);
- _commandBuffer.GenerateDelayEffect(bufferOffset, effect.Parameter, effect.State, effect.IsEnabled, workBuffer, nodeId);
+ _commandBuffer.GenerateDelayEffect(bufferOffset, effect.Parameter, effect.State, effect.IsEnabled, workBuffer, nodeId, newEffectChannelMappingSupported);
}
- private void GenerateReverbEffect(uint bufferOffset, ReverbEffect effect, int nodeId, bool isLongSizePreDelaySupported)
+ private void GenerateReverbEffect(uint bufferOffset, ReverbEffect effect, int nodeId, bool isLongSizePreDelaySupported, bool newEffectChannelMappingSupported)
{
Debug.Assert(effect.Type == EffectType.Reverb);
ulong workBuffer = effect.GetWorkBuffer(-1);
- _commandBuffer.GenerateReverbEffect(bufferOffset, effect.Parameter, effect.State, effect.IsEnabled, workBuffer, nodeId, isLongSizePreDelaySupported);
+ _commandBuffer.GenerateReverbEffect(bufferOffset, effect.Parameter, effect.State, effect.IsEnabled, workBuffer, nodeId, isLongSizePreDelaySupported, newEffectChannelMappingSupported);
}
- private void GenerateReverb3dEffect(uint bufferOffset, Reverb3dEffect effect, int nodeId)
+ private void GenerateReverb3dEffect(uint bufferOffset, Reverb3dEffect effect, int nodeId, bool newEffectChannelMappingSupported)
{
Debug.Assert(effect.Type == EffectType.Reverb3d);
ulong workBuffer = effect.GetWorkBuffer(-1);
- _commandBuffer.GenerateReverb3dEffect(bufferOffset, effect.Parameter, effect.State, effect.IsEnabled, workBuffer, nodeId);
+ _commandBuffer.GenerateReverb3dEffect(bufferOffset, effect.Parameter, effect.State, effect.IsEnabled, workBuffer, nodeId, newEffectChannelMappingSupported);
}
private void GenerateBiquadFilterEffect(uint bufferOffset, BiquadFilterEffect effect, int nodeId)
@@ -650,13 +650,13 @@ namespace Ryujinx.Audio.Renderer.Server
GenerateAuxEffect(mix.BufferOffset, (AuxiliaryBufferEffect)effect, nodeId);
break;
case EffectType.Delay:
- GenerateDelayEffect(mix.BufferOffset, (DelayEffect)effect, nodeId);
+ GenerateDelayEffect(mix.BufferOffset, (DelayEffect)effect, nodeId, _rendererContext.BehaviourContext.IsNewEffectChannelMappingSupported());
break;
case EffectType.Reverb:
- GenerateReverbEffect(mix.BufferOffset, (ReverbEffect)effect, nodeId, mix.IsLongSizePreDelaySupported);
+ GenerateReverbEffect(mix.BufferOffset, (ReverbEffect)effect, nodeId, mix.IsLongSizePreDelaySupported, _rendererContext.BehaviourContext.IsNewEffectChannelMappingSupported());
break;
case EffectType.Reverb3d:
- GenerateReverb3dEffect(mix.BufferOffset, (Reverb3dEffect)effect, nodeId);
+ GenerateReverb3dEffect(mix.BufferOffset, (Reverb3dEffect)effect, nodeId, _rendererContext.BehaviourContext.IsNewEffectChannelMappingSupported());
break;
case EffectType.BiquadFilter:
GenerateBiquadFilterEffect(mix.BufferOffset, (BiquadFilterEffect)effect, nodeId);
diff --git a/Ryujinx.Audio/Renderer/Server/CommandProcessingTimeEstimatorVersion3.cs b/Ryujinx.Audio/Renderer/Server/CommandProcessingTimeEstimatorVersion3.cs
index 75d3d05b..d9afdfb0 100644
--- a/Ryujinx.Audio/Renderer/Server/CommandProcessingTimeEstimatorVersion3.cs
+++ b/Ryujinx.Audio/Renderer/Server/CommandProcessingTimeEstimatorVersion3.cs
@@ -198,7 +198,7 @@ namespace Ryujinx.Audio.Renderer.Server
return (uint)1853.2f;
}
- public uint Estimate(DelayCommand command)
+ public virtual uint Estimate(DelayCommand command)
{
Debug.Assert(_sampleCount == 160 || _sampleCount == 240);
@@ -272,7 +272,7 @@ namespace Ryujinx.Audio.Renderer.Server
}
}
- public uint Estimate(ReverbCommand command)
+ public virtual uint Estimate(ReverbCommand command)
{
Debug.Assert(_sampleCount == 160 || _sampleCount == 240);
@@ -346,7 +346,7 @@ namespace Ryujinx.Audio.Renderer.Server
}
}
- public uint Estimate(Reverb3dCommand command)
+ public virtual uint Estimate(Reverb3dCommand command)
{
Debug.Assert(_sampleCount == 160 || _sampleCount == 240);
diff --git a/Ryujinx.Audio/Renderer/Server/CommandProcessingTimeEstimatorVersion5.cs b/Ryujinx.Audio/Renderer/Server/CommandProcessingTimeEstimatorVersion5.cs
new file mode 100644
index 00000000..6b55a909
--- /dev/null
+++ b/Ryujinx.Audio/Renderer/Server/CommandProcessingTimeEstimatorVersion5.cs
@@ -0,0 +1,253 @@
+//
+// Copyright (c) 2019-2022 Ryujinx
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with this program. If not, see <https://www.gnu.org/licenses/>.
+//
+
+using Ryujinx.Audio.Renderer.Dsp.Command;
+using System;
+using System.Diagnostics;
+
+namespace Ryujinx.Audio.Renderer.Server
+{
+ /// <summary>
+ /// <see cref="ICommandProcessingTimeEstimator"/> version 5. (added with REV11)
+ /// </summary>
+ public class CommandProcessingTimeEstimatorVersion5 : CommandProcessingTimeEstimatorVersion4
+ {
+ public CommandProcessingTimeEstimatorVersion5(uint sampleCount, uint bufferCount) : base(sampleCount, bufferCount) { }
+
+ public override uint Estimate(DelayCommand command)
+ {
+ Debug.Assert(_sampleCount == 160 || _sampleCount == 240);
+
+ if (_sampleCount == 160)
+ {
+ if (command.Enabled)
+ {
+ switch (command.Parameter.ChannelCount)
+ {
+ case 1:
+ return 8929;
+ case 2:
+ return 25501;
+ case 4:
+ return 47760;
+ case 6:
+ return 82203;
+ default:
+ throw new NotImplementedException($"{command.Parameter.ChannelCount}");
+ }
+ }
+ else
+ {
+ switch (command.Parameter.ChannelCount)
+ {
+ case 1:
+ return (uint)1295.20f;
+ case 2:
+ return (uint)1213.60f;
+ case 4:
+ return (uint)942.03f;
+ case 6:
+ return (uint)1001.6f;
+ default:
+ throw new NotImplementedException($"{command.Parameter.ChannelCount}");
+ }
+ }
+ }
+
+ if (command.Enabled)
+ {
+ switch (command.Parameter.ChannelCount)
+ {
+ case 1:
+ return 11941;
+ case 2:
+ return 37197;
+ case 4:
+ return 69750;
+ case 6:
+ return 12004;
+ default:
+ throw new NotImplementedException($"{command.Parameter.ChannelCount}");
+ }
+ }
+ else
+ {
+ switch (command.Parameter.ChannelCount)
+ {
+ case 1:
+ return (uint)997.67f;
+ case 2:
+ return (uint)977.63f;
+ case 4:
+ return (uint)792.31f;
+ case 6:
+ return (uint)875.43f;
+ default:
+ throw new NotImplementedException($"{command.Parameter.ChannelCount}");
+ }
+ }
+ }
+
+ public override uint Estimate(ReverbCommand command)
+ {
+ Debug.Assert(_sampleCount == 160 || _sampleCount == 240);
+
+ if (_sampleCount == 160)
+ {
+ if (command.Enabled)
+ {
+ switch (command.Parameter.ChannelCount)
+ {
+ case 1:
+ return 81475;
+ case 2:
+ return 84975;
+ case 4:
+ return 91625;
+ case 6:
+ return 95332;
+ default:
+ throw new NotImplementedException($"{command.Parameter.ChannelCount}");
+ }
+ }
+ else
+ {
+ switch (command.Parameter.ChannelCount)
+ {
+ case 1:
+ return (uint)536.30f;
+ case 2:
+ return (uint)588.80f;
+ case 4:
+ return (uint)643.70f;
+ case 6:
+ return (uint)706.0f;
+ default:
+ throw new NotImplementedException($"{command.Parameter.ChannelCount}");
+ }
+ }
+ }
+
+ if (command.Enabled)
+ {
+ switch (command.Parameter.ChannelCount)
+ {
+ case 1:
+ return 120170;
+ case 2:
+ return 125260;
+ case 4:
+ return 135750;
+ case 6:
+ return 141130;
+ default:
+ throw new NotImplementedException($"{command.Parameter.ChannelCount}");
+ }
+ }
+ else
+ {
+ switch (command.Parameter.ChannelCount)
+ {
+ case 1:
+ return (uint)617.64f;
+ case 2:
+ return (uint)659.54f;
+ case 4:
+ return (uint)711.44f;
+ case 6:
+ return (uint)778.07f;
+ default:
+ throw new NotImplementedException($"{command.Parameter.ChannelCount}");
+ }
+ }
+ }
+
+ public override uint Estimate(Reverb3dCommand command)
+ {
+ Debug.Assert(_sampleCount == 160 || _sampleCount == 240);
+
+ if (_sampleCount == 160)
+ {
+ if (command.Enabled)
+ {
+ switch (command.Parameter.ChannelCount)
+ {
+ case 1:
+ return 116750;
+ case 2:
+ return 125910;
+ case 4:
+ return 146340;
+ case 6:
+ return 165810;
+ default:
+ throw new NotImplementedException($"{command.Parameter.ChannelCount}");
+ }
+ }
+ else
+ {
+ switch (command.Parameter.ChannelCount)
+ {
+ case 1:
+ return 735;
+ case 2:
+ return (uint)766.62f;
+ case 4:
+ return (uint)834.07f;
+ case 6:
+ return (uint)875.44f;
+ default:
+ throw new NotImplementedException($"{command.Parameter.ChannelCount}");
+ }
+ }
+ }
+
+ if (command.Enabled)
+ {
+ switch (command.Parameter.ChannelCount)
+ {
+ case 1:
+ return 170290;
+ case 2:
+ return 183880;
+ case 4:
+ return 214700;
+ case 6:
+ return 243850;
+ default:
+ throw new NotImplementedException($"{command.Parameter.ChannelCount}");
+ }
+ }
+ else
+ {
+ switch (command.Parameter.ChannelCount)
+ {
+ case 1:
+ return (uint)508.47f;
+ case 2:
+ return (uint)582.45f;
+ case 4:
+ return (uint)626.42f;
+ case 6:
+ return (uint)682.47f;
+ default:
+ throw new NotImplementedException($"{command.Parameter.ChannelCount}");
+ }
+ }
+ }
+ }
+}