aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.Audio/Renderer/Server
diff options
context:
space:
mode:
Diffstat (limited to 'Ryujinx.Audio/Renderer/Server')
-rw-r--r--Ryujinx.Audio/Renderer/Server/BehaviourContext.cs3
-rw-r--r--Ryujinx.Audio/Renderer/Server/CommandBuffer.cs12
-rw-r--r--Ryujinx.Audio/Renderer/Server/CommandGenerator.cs14
-rw-r--r--Ryujinx.Audio/Renderer/Server/CommandProcessingTimeEstimatorVersion1.cs5
-rw-r--r--Ryujinx.Audio/Renderer/Server/CommandProcessingTimeEstimatorVersion2.cs5
-rw-r--r--Ryujinx.Audio/Renderer/Server/CommandProcessingTimeEstimatorVersion3.cs5
-rw-r--r--Ryujinx.Audio/Renderer/Server/CommandProcessingTimeEstimatorVersion5.cs74
-rw-r--r--Ryujinx.Audio/Renderer/Server/Effect/BaseEffect.cs2
-rw-r--r--Ryujinx.Audio/Renderer/Server/Effect/CompressorEffect.cs67
-rw-r--r--Ryujinx.Audio/Renderer/Server/ICommandProcessingTimeEstimator.cs1
-rw-r--r--Ryujinx.Audio/Renderer/Server/StateUpdater.cs4
11 files changed, 191 insertions, 1 deletions
diff --git a/Ryujinx.Audio/Renderer/Server/BehaviourContext.cs b/Ryujinx.Audio/Renderer/Server/BehaviourContext.cs
index adf5294e..821947a9 100644
--- a/Ryujinx.Audio/Renderer/Server/BehaviourContext.cs
+++ b/Ryujinx.Audio/Renderer/Server/BehaviourContext.cs
@@ -44,7 +44,7 @@ namespace Ryujinx.Audio.Renderer.Server
/// <see cref="Parameter.RendererInfoOutStatus"/> 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.
/// Additionally, the rendering limit percent was incremented to 80%.
- ///
+ ///
/// </summary>
/// <remarks>This was added in system update 6.0.0</remarks>
public const int Revision5 = 5 << 24;
@@ -93,6 +93,7 @@ namespace Ryujinx.Audio.Renderer.Server
/// <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 effect was added: Compressor. This effect is effectively implemented with a DRC.
/// A new version of the command estimator was added to address timing changes caused by the legacy effects changes.
/// A voice drop parameter was added in 15.0.0: This allows an application to amplify or attenuate the estimated time of DSP commands.
/// </summary>
diff --git a/Ryujinx.Audio/Renderer/Server/CommandBuffer.cs b/Ryujinx.Audio/Renderer/Server/CommandBuffer.cs
index e0741cc6..905cb205 100644
--- a/Ryujinx.Audio/Renderer/Server/CommandBuffer.cs
+++ b/Ryujinx.Audio/Renderer/Server/CommandBuffer.cs
@@ -469,6 +469,18 @@ namespace Ryujinx.Audio.Renderer.Server
}
}
+ public void GenerateCompressorEffect(uint bufferOffset, CompressorParameter parameter, Memory<CompressorState> state, bool isEnabled, int nodeId)
+ {
+ if (parameter.IsChannelCountValid())
+ {
+ CompressorCommand command = new CompressorCommand(bufferOffset, parameter, state, isEnabled, nodeId);
+
+ command.EstimatedProcessingTime = _commandProcessingTimeEstimator.Estimate(command);
+
+ AddCommand(command);
+ }
+ }
+
/// <summary>
/// Generate a new <see cref="VolumeCommand"/>.
/// </summary>
diff --git a/Ryujinx.Audio/Renderer/Server/CommandGenerator.cs b/Ryujinx.Audio/Renderer/Server/CommandGenerator.cs
index 87e5c77f..afc1e39b 100644
--- a/Ryujinx.Audio/Renderer/Server/CommandGenerator.cs
+++ b/Ryujinx.Audio/Renderer/Server/CommandGenerator.cs
@@ -606,6 +606,17 @@ namespace Ryujinx.Audio.Renderer.Server
}
}
+ private void GenerateCompressorEffect(uint bufferOffset, CompressorEffect effect, int nodeId)
+ {
+ Debug.Assert(effect.Type == EffectType.Compressor);
+
+ _commandBuffer.GenerateCompressorEffect(bufferOffset,
+ effect.Parameter,
+ effect.State,
+ effect.IsEnabled,
+ nodeId);
+ }
+
private void GenerateEffect(ref MixState mix, int effectId, BaseEffect effect)
{
int nodeId = mix.NodeId;
@@ -650,6 +661,9 @@ namespace Ryujinx.Audio.Renderer.Server
case EffectType.CaptureBuffer:
GenerateCaptureEffect(mix.BufferOffset, (CaptureBufferEffect)effect, nodeId);
break;
+ case EffectType.Compressor:
+ GenerateCompressorEffect(mix.BufferOffset, (CompressorEffect)effect, nodeId);
+ break;
default:
throw new NotImplementedException($"Unsupported effect type {effect.Type}");
}
diff --git a/Ryujinx.Audio/Renderer/Server/CommandProcessingTimeEstimatorVersion1.cs b/Ryujinx.Audio/Renderer/Server/CommandProcessingTimeEstimatorVersion1.cs
index 32c52dc4..63dc9ca9 100644
--- a/Ryujinx.Audio/Renderer/Server/CommandProcessingTimeEstimatorVersion1.cs
+++ b/Ryujinx.Audio/Renderer/Server/CommandProcessingTimeEstimatorVersion1.cs
@@ -179,5 +179,10 @@ namespace Ryujinx.Audio.Renderer.Server
{
return 0;
}
+
+ public uint Estimate(CompressorCommand command)
+ {
+ return 0;
+ }
}
} \ No newline at end of file
diff --git a/Ryujinx.Audio/Renderer/Server/CommandProcessingTimeEstimatorVersion2.cs b/Ryujinx.Audio/Renderer/Server/CommandProcessingTimeEstimatorVersion2.cs
index 15800c99..7ee491cd 100644
--- a/Ryujinx.Audio/Renderer/Server/CommandProcessingTimeEstimatorVersion2.cs
+++ b/Ryujinx.Audio/Renderer/Server/CommandProcessingTimeEstimatorVersion2.cs
@@ -543,5 +543,10 @@ namespace Ryujinx.Audio.Renderer.Server
{
return 0;
}
+
+ public uint Estimate(CompressorCommand command)
+ {
+ return 0;
+ }
}
} \ No newline at end of file
diff --git a/Ryujinx.Audio/Renderer/Server/CommandProcessingTimeEstimatorVersion3.cs b/Ryujinx.Audio/Renderer/Server/CommandProcessingTimeEstimatorVersion3.cs
index 6c6e2828..b79ca136 100644
--- a/Ryujinx.Audio/Renderer/Server/CommandProcessingTimeEstimatorVersion3.cs
+++ b/Ryujinx.Audio/Renderer/Server/CommandProcessingTimeEstimatorVersion3.cs
@@ -747,5 +747,10 @@ namespace Ryujinx.Audio.Renderer.Server
{
return 0;
}
+
+ public virtual uint Estimate(CompressorCommand command)
+ {
+ return 0;
+ }
}
} \ No newline at end of file
diff --git a/Ryujinx.Audio/Renderer/Server/CommandProcessingTimeEstimatorVersion5.cs b/Ryujinx.Audio/Renderer/Server/CommandProcessingTimeEstimatorVersion5.cs
index 961d92aa..2ed7e6a5 100644
--- a/Ryujinx.Audio/Renderer/Server/CommandProcessingTimeEstimatorVersion5.cs
+++ b/Ryujinx.Audio/Renderer/Server/CommandProcessingTimeEstimatorVersion5.cs
@@ -232,5 +232,79 @@ namespace Ryujinx.Audio.Renderer.Server
}
}
}
+
+ public override uint Estimate(CompressorCommand command)
+ {
+ Debug.Assert(_sampleCount == 160 || _sampleCount == 240);
+
+ if (_sampleCount == 160)
+ {
+ if (command.Enabled)
+ {
+ switch (command.Parameter.ChannelCount)
+ {
+ case 1:
+ return 34431;
+ case 2:
+ return 44253;
+ case 4:
+ return 63827;
+ case 6:
+ return 83361;
+ default:
+ throw new NotImplementedException($"{command.Parameter.ChannelCount}");
+ }
+ }
+ else
+ {
+ switch (command.Parameter.ChannelCount)
+ {
+ case 1:
+ return (uint)630.12f;
+ case 2:
+ return (uint)638.27f;
+ case 4:
+ return (uint)705.86f;
+ case 6:
+ return (uint)782.02f;
+ default:
+ throw new NotImplementedException($"{command.Parameter.ChannelCount}");
+ }
+ }
+ }
+
+ if (command.Enabled)
+ {
+ switch (command.Parameter.ChannelCount)
+ {
+ case 1:
+ return 51095;
+ case 2:
+ return 65693;
+ case 4:
+ return 95383;
+ case 6:
+ return 124510;
+ default:
+ throw new NotImplementedException($"{command.Parameter.ChannelCount}");
+ }
+ }
+ else
+ {
+ switch (command.Parameter.ChannelCount)
+ {
+ case 1:
+ return (uint)840.14f;
+ case 2:
+ return (uint)826.1f;
+ case 4:
+ return (uint)901.88f;
+ case 6:
+ return (uint)965.29f;
+ default:
+ throw new NotImplementedException($"{command.Parameter.ChannelCount}");
+ }
+ }
+ }
}
} \ No newline at end of file
diff --git a/Ryujinx.Audio/Renderer/Server/Effect/BaseEffect.cs b/Ryujinx.Audio/Renderer/Server/Effect/BaseEffect.cs
index 35314aca..825b3bf7 100644
--- a/Ryujinx.Audio/Renderer/Server/Effect/BaseEffect.cs
+++ b/Ryujinx.Audio/Renderer/Server/Effect/BaseEffect.cs
@@ -262,6 +262,8 @@ namespace Ryujinx.Audio.Renderer.Server.Effect
return PerformanceDetailType.Limiter;
case EffectType.CaptureBuffer:
return PerformanceDetailType.CaptureBuffer;
+ case EffectType.Compressor:
+ return PerformanceDetailType.Compressor;
default:
throw new NotImplementedException($"{Type}");
}
diff --git a/Ryujinx.Audio/Renderer/Server/Effect/CompressorEffect.cs b/Ryujinx.Audio/Renderer/Server/Effect/CompressorEffect.cs
new file mode 100644
index 00000000..f4e5ae82
--- /dev/null
+++ b/Ryujinx.Audio/Renderer/Server/Effect/CompressorEffect.cs
@@ -0,0 +1,67 @@
+using Ryujinx.Audio.Renderer.Common;
+using Ryujinx.Audio.Renderer.Dsp.State;
+using Ryujinx.Audio.Renderer.Parameter.Effect;
+using Ryujinx.Audio.Renderer.Parameter;
+using Ryujinx.Audio.Renderer.Server.MemoryPool;
+using System;
+using System.Diagnostics;
+using System.Runtime.InteropServices;
+
+namespace Ryujinx.Audio.Renderer.Server.Effect
+{
+ /// <summary>
+ /// Server state for a compressor effect.
+ /// </summary>
+ public class CompressorEffect : BaseEffect
+ {
+ /// <summary>
+ /// The compressor parameter.
+ /// </summary>
+ public CompressorParameter Parameter;
+
+ /// <summary>
+ /// The compressor state.
+ /// </summary>
+ public Memory<CompressorState> State { get; }
+
+ /// <summary>
+ /// Create a new <see cref="CompressorEffect"/>.
+ /// </summary>
+ public CompressorEffect()
+ {
+ State = new CompressorState[1];
+ }
+
+ public override EffectType TargetEffectType => EffectType.Compressor;
+
+ public override ulong GetWorkBuffer(int index)
+ {
+ return GetSingleBuffer();
+ }
+
+ public override void Update(out BehaviourParameter.ErrorInfo updateErrorInfo, ref EffectInParameterVersion1 parameter, PoolMapper mapper)
+ {
+ // Nintendo doesn't do anything here but we still require updateErrorInfo to be initialised.
+ updateErrorInfo = new BehaviourParameter.ErrorInfo();
+ }
+
+ public override void Update(out BehaviourParameter.ErrorInfo updateErrorInfo, ref EffectInParameterVersion2 parameter, PoolMapper mapper)
+ {
+ Debug.Assert(IsTypeValid(ref parameter));
+
+ UpdateParameterBase(ref parameter);
+
+ Parameter = MemoryMarshal.Cast<byte, CompressorParameter>(parameter.SpecificData)[0];
+ IsEnabled = parameter.IsEnabled;
+
+ updateErrorInfo = new BehaviourParameter.ErrorInfo();
+ }
+
+ public override void UpdateForCommandGeneration()
+ {
+ UpdateUsageStateForCommandGeneration();
+
+ Parameter.Status = UsageState.Enabled;
+ }
+ }
+}
diff --git a/Ryujinx.Audio/Renderer/Server/ICommandProcessingTimeEstimator.cs b/Ryujinx.Audio/Renderer/Server/ICommandProcessingTimeEstimator.cs
index e365a86c..4872ddb3 100644
--- a/Ryujinx.Audio/Renderer/Server/ICommandProcessingTimeEstimator.cs
+++ b/Ryujinx.Audio/Renderer/Server/ICommandProcessingTimeEstimator.cs
@@ -35,5 +35,6 @@ namespace Ryujinx.Audio.Renderer.Server
uint Estimate(LimiterCommandVersion2 command);
uint Estimate(GroupedBiquadFilterCommand command);
uint Estimate(CaptureBufferCommand command);
+ uint Estimate(CompressorCommand command);
}
} \ No newline at end of file
diff --git a/Ryujinx.Audio/Renderer/Server/StateUpdater.cs b/Ryujinx.Audio/Renderer/Server/StateUpdater.cs
index 0c2cfa7e..0446cd8c 100644
--- a/Ryujinx.Audio/Renderer/Server/StateUpdater.cs
+++ b/Ryujinx.Audio/Renderer/Server/StateUpdater.cs
@@ -240,6 +240,10 @@ namespace Ryujinx.Audio.Renderer.Server
case EffectType.CaptureBuffer:
effect = new CaptureBufferEffect();
break;
+ case EffectType.Compressor:
+ effect = new CompressorEffect();
+ break;
+
default:
throw new NotImplementedException($"EffectType {parameter.Type} not implemented!");
}