mirror of
https://git.naxdy.org/Mirror/Ryujinx.git
synced 2025-03-14 22:40:18 +00:00
amadeus: Update to REV11
This should implement all ABI changes from REV11 on 14.0.0 As Nintendo changed the channel disposition for "legacy" effects (Delay, Reverb and Reverb 3D) to match the standard channel mapping, I took the liberty to just remap to the old disposition for now. The proper changes will be handled at a later date with a complete rewriting of those 3 effects to be more readable (see https://github.com/Ryujinx/Ryujinx/pull/3205 for the first iteration of it).
This commit is contained in:
parent
ba0171d054
commit
5545297ea6
12 changed files with 358 additions and 28 deletions
|
@ -45,7 +45,7 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
|
||||||
|
|
||||||
private const int FixedPointPrecision = 14;
|
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;
|
Enabled = true;
|
||||||
NodeId = nodeId;
|
NodeId = nodeId;
|
||||||
|
@ -63,6 +63,11 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
|
||||||
InputBufferIndices[i] = (ushort)(bufferOffset + Parameter.Input[i]);
|
InputBufferIndices[i] = (ushort)(bufferOffset + Parameter.Input[i]);
|
||||||
OutputBufferIndices[i] = (ushort)(bufferOffset + Parameter.Output[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)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
|
|
@ -63,7 +63,7 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
|
||||||
|
|
||||||
private Reverb3dParameter _parameter;
|
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;
|
Enabled = true;
|
||||||
IsEffectEnabled = isEnabled;
|
IsEffectEnabled = isEnabled;
|
||||||
|
@ -80,6 +80,11 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
|
||||||
InputBufferIndices[i] = (ushort)(bufferOffset + Parameter.Input[i]);
|
InputBufferIndices[i] = (ushort)(bufferOffset + Parameter.Input[i]);
|
||||||
OutputBufferIndices[i] = (ushort)(bufferOffset + Parameter.Output[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)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
@ -194,7 +199,7 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
|
||||||
|
|
||||||
if (isSurround)
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -66,7 +66,7 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
|
||||||
|
|
||||||
private const int FixedPointPrecision = 14;
|
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;
|
Enabled = true;
|
||||||
IsEffectEnabled = isEnabled;
|
IsEffectEnabled = isEnabled;
|
||||||
|
@ -85,6 +85,11 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
|
||||||
}
|
}
|
||||||
|
|
||||||
IsLongSizePreDelaySupported = isLongSizePreDelaySupported;
|
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)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
@ -214,7 +219,7 @@ namespace Ryujinx.Audio.Renderer.Dsp.Command
|
||||||
|
|
||||||
if (isSurround)
|
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++)
|
for (int channelIndex = 0; channelIndex < Parameter.ChannelCount; channelIndex++)
|
||||||
|
|
|
@ -445,5 +445,39 @@ namespace Ryujinx.Audio.Renderer.Dsp
|
||||||
ToIntSlow(output, input, sampleCount);
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,7 +34,7 @@ namespace Ryujinx.Audio.Renderer.Dsp.State
|
||||||
public DecayDelay[] DecayDelays1 { get; }
|
public DecayDelay[] DecayDelays1 { get; }
|
||||||
public DecayDelay[] DecayDelays2 { get; }
|
public DecayDelay[] DecayDelays2 { get; }
|
||||||
public IDelayLine PreDelayLine { get; }
|
public IDelayLine PreDelayLine { get; }
|
||||||
public IDelayLine BackLeftDelayLine { get; }
|
public IDelayLine FrontCenterDelayLine { get; }
|
||||||
public float DryGain { get; private set; }
|
public float DryGain { get; private set; }
|
||||||
public uint[] EarlyDelayTime { get; private set; }
|
public uint[] EarlyDelayTime { get; private set; }
|
||||||
public float PreviousPreDelayValue { get; set; }
|
public float PreviousPreDelayValue { get; set; }
|
||||||
|
@ -69,7 +69,7 @@ namespace Ryujinx.Audio.Renderer.Dsp.State
|
||||||
}
|
}
|
||||||
|
|
||||||
PreDelayLine = new DelayLine3d(sampleRate, 400);
|
PreDelayLine = new DelayLine3d(sampleRate, 400);
|
||||||
BackLeftDelayLine = new DelayLine3d(sampleRate, 5);
|
FrontCenterDelayLine = new DelayLine3d(sampleRate, 5);
|
||||||
|
|
||||||
UpdateParameter(ref parameter);
|
UpdateParameter(ref parameter);
|
||||||
}
|
}
|
||||||
|
|
|
@ -97,7 +97,7 @@ namespace Ryujinx.Audio.Renderer.Dsp.State
|
||||||
public DelayLine[] FdnDelayLines { get; }
|
public DelayLine[] FdnDelayLines { get; }
|
||||||
public DecayDelay[] DecayDelays { get; }
|
public DecayDelay[] DecayDelays { get; }
|
||||||
public DelayLine PreDelayLine { get; }
|
public DelayLine PreDelayLine { get; }
|
||||||
public DelayLine BackLeftDelayLine { get; }
|
public DelayLine FrontCenterDelayLine { get; }
|
||||||
public uint[] EarlyDelayTime { get; }
|
public uint[] EarlyDelayTime { get; }
|
||||||
public float[] EarlyGain { get; }
|
public float[] EarlyGain { get; }
|
||||||
public uint PreDelayLineDelayTime { get; private set; }
|
public uint PreDelayLineDelayTime { get; private set; }
|
||||||
|
@ -149,7 +149,7 @@ namespace Ryujinx.Audio.Renderer.Dsp.State
|
||||||
}
|
}
|
||||||
|
|
||||||
PreDelayLine = new DelayLine(sampleRate, preDelayTimeMax);
|
PreDelayLine = new DelayLine(sampleRate, preDelayTimeMax);
|
||||||
BackLeftDelayLine = new DelayLine(sampleRate, 5.0f);
|
FrontCenterDelayLine = new DelayLine(sampleRate, 5.0f);
|
||||||
|
|
||||||
UpdateParameter(ref parameter);
|
UpdateParameter(ref parameter);
|
||||||
}
|
}
|
||||||
|
|
|
@ -363,6 +363,9 @@ namespace Ryujinx.Audio.Renderer.Server
|
||||||
case 4:
|
case 4:
|
||||||
_commandProcessingTimeEstimator = new CommandProcessingTimeEstimatorVersion4(_sampleCount, _mixBufferCount);
|
_commandProcessingTimeEstimator = new CommandProcessingTimeEstimatorVersion4(_sampleCount, _mixBufferCount);
|
||||||
break;
|
break;
|
||||||
|
case 5:
|
||||||
|
_commandProcessingTimeEstimator = new CommandProcessingTimeEstimatorVersion5(_sampleCount, _mixBufferCount);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
throw new NotImplementedException($"Unsupported processing time estimator version {_behaviourContext.GetCommandProcessingTimeEstimatorVersion()}.");
|
throw new NotImplementedException($"Unsupported processing time estimator version {_behaviourContext.GetCommandProcessingTimeEstimatorVersion()}.");
|
||||||
}
|
}
|
||||||
|
|
|
@ -107,10 +107,18 @@ namespace Ryujinx.Audio.Renderer.Server
|
||||||
/// <remarks>This was added in system update 13.0.0</remarks>
|
/// <remarks>This was added in system update 13.0.0</remarks>
|
||||||
public const int Revision10 = 10 << 24;
|
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>
|
/// <summary>
|
||||||
/// Last revision supported by the implementation.
|
/// Last revision supported by the implementation.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public const int LastRevision = Revision10;
|
public const int LastRevision = Revision11;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Target revision magic supported by the implementation.
|
/// Target revision magic supported by the implementation.
|
||||||
|
@ -366,12 +374,26 @@ namespace Ryujinx.Audio.Renderer.Server
|
||||||
return CheckFeatureSupported(UserRevision, BaseRevisionMagic + Revision10);
|
return CheckFeatureSupported(UserRevision, BaseRevisionMagic + Revision10);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <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>
|
/// <summary>
|
||||||
/// Get the version of the <see cref="ICommandProcessingTimeEstimator"/>.
|
/// Get the version of the <see cref="ICommandProcessingTimeEstimator"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>The version of the <see cref="ICommandProcessingTimeEstimator"/>.</returns>
|
/// <returns>The version of the <see cref="ICommandProcessingTimeEstimator"/>.</returns>
|
||||||
public int GetCommandProcessingTimeEstimatorVersion()
|
public int GetCommandProcessingTimeEstimatorVersion()
|
||||||
{
|
{
|
||||||
|
if (CheckFeatureSupported(UserRevision, BaseRevisionMagic + Revision11))
|
||||||
|
{
|
||||||
|
return 5;
|
||||||
|
}
|
||||||
|
|
||||||
if (CheckFeatureSupported(UserRevision, BaseRevisionMagic + Revision10))
|
if (CheckFeatureSupported(UserRevision, BaseRevisionMagic + Revision10))
|
||||||
{
|
{
|
||||||
return 4;
|
return 4;
|
||||||
|
|
|
@ -336,11 +336,12 @@ namespace Ryujinx.Audio.Renderer.Server
|
||||||
/// <param name="workBuffer">The work buffer to use for processing.</param>
|
/// <param name="workBuffer">The work buffer to use for processing.</param>
|
||||||
/// <param name="nodeId">The node id associated to this command.</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>
|
/// <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())
|
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);
|
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="isEnabled">Set to true if the effect should be active.</param>
|
||||||
/// <param name="workBuffer">The work buffer to use for processing.</param>
|
/// <param name="workBuffer">The work buffer to use for processing.</param>
|
||||||
/// <param name="nodeId">The node id associated to this command.</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())
|
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);
|
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="isEnabled">Set to true if the effect should be active.</param>
|
||||||
/// <param name="workBuffer">The work buffer to use for processing.</param>
|
/// <param name="workBuffer">The work buffer to use for processing.</param>
|
||||||
/// <param name="nodeId">The node id associated to this command.</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())
|
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);
|
command.EstimatedProcessingTime = _commandProcessingTimeEstimator.Estimate(command);
|
||||||
|
|
||||||
|
|
|
@ -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);
|
Debug.Assert(effect.Type == EffectType.Delay);
|
||||||
|
|
||||||
ulong workBuffer = effect.GetWorkBuffer(-1);
|
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);
|
Debug.Assert(effect.Type == EffectType.Reverb);
|
||||||
|
|
||||||
ulong workBuffer = effect.GetWorkBuffer(-1);
|
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);
|
Debug.Assert(effect.Type == EffectType.Reverb3d);
|
||||||
|
|
||||||
ulong workBuffer = effect.GetWorkBuffer(-1);
|
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)
|
private void GenerateBiquadFilterEffect(uint bufferOffset, BiquadFilterEffect effect, int nodeId)
|
||||||
|
@ -650,13 +650,13 @@ namespace Ryujinx.Audio.Renderer.Server
|
||||||
GenerateAuxEffect(mix.BufferOffset, (AuxiliaryBufferEffect)effect, nodeId);
|
GenerateAuxEffect(mix.BufferOffset, (AuxiliaryBufferEffect)effect, nodeId);
|
||||||
break;
|
break;
|
||||||
case EffectType.Delay:
|
case EffectType.Delay:
|
||||||
GenerateDelayEffect(mix.BufferOffset, (DelayEffect)effect, nodeId);
|
GenerateDelayEffect(mix.BufferOffset, (DelayEffect)effect, nodeId, _rendererContext.BehaviourContext.IsNewEffectChannelMappingSupported());
|
||||||
break;
|
break;
|
||||||
case EffectType.Reverb:
|
case EffectType.Reverb:
|
||||||
GenerateReverbEffect(mix.BufferOffset, (ReverbEffect)effect, nodeId, mix.IsLongSizePreDelaySupported);
|
GenerateReverbEffect(mix.BufferOffset, (ReverbEffect)effect, nodeId, mix.IsLongSizePreDelaySupported, _rendererContext.BehaviourContext.IsNewEffectChannelMappingSupported());
|
||||||
break;
|
break;
|
||||||
case EffectType.Reverb3d:
|
case EffectType.Reverb3d:
|
||||||
GenerateReverb3dEffect(mix.BufferOffset, (Reverb3dEffect)effect, nodeId);
|
GenerateReverb3dEffect(mix.BufferOffset, (Reverb3dEffect)effect, nodeId, _rendererContext.BehaviourContext.IsNewEffectChannelMappingSupported());
|
||||||
break;
|
break;
|
||||||
case EffectType.BiquadFilter:
|
case EffectType.BiquadFilter:
|
||||||
GenerateBiquadFilterEffect(mix.BufferOffset, (BiquadFilterEffect)effect, nodeId);
|
GenerateBiquadFilterEffect(mix.BufferOffset, (BiquadFilterEffect)effect, nodeId);
|
||||||
|
|
|
@ -198,7 +198,7 @@ namespace Ryujinx.Audio.Renderer.Server
|
||||||
return (uint)1853.2f;
|
return (uint)1853.2f;
|
||||||
}
|
}
|
||||||
|
|
||||||
public uint Estimate(DelayCommand command)
|
public virtual uint Estimate(DelayCommand command)
|
||||||
{
|
{
|
||||||
Debug.Assert(_sampleCount == 160 || _sampleCount == 240);
|
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);
|
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);
|
Debug.Assert(_sampleCount == 160 || _sampleCount == 240);
|
||||||
|
|
||||||
|
|
|
@ -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}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue