aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.Audio/Renderer/Server/Effect
diff options
context:
space:
mode:
authorMary <me@thog.eu>2021-05-25 19:01:09 +0200
committerGitHub <noreply@github.com>2021-05-25 19:01:09 +0200
commitf3b0b4831c323a20393aa0388f947317354372b7 (patch)
tree478412fd3a8c2de6eab5e54dd47944f59bf1a836 /Ryujinx.Audio/Renderer/Server/Effect
parent54ea2285f05ef6f59a6f1c63df4a7bdd77d7b883 (diff)
amadeus: Update to REV9 (#2309)
* amadeus: Update to REV9 This implements all the changes made with REV9 on 12.0.0. * Address Ac_k's comments
Diffstat (limited to 'Ryujinx.Audio/Renderer/Server/Effect')
-rw-r--r--Ryujinx.Audio/Renderer/Server/Effect/AuxiliaryBufferEffect.cs12
-rw-r--r--Ryujinx.Audio/Renderer/Server/Effect/BaseEffect.cs46
-rw-r--r--Ryujinx.Audio/Renderer/Server/Effect/BiquadFilterEffect.cs12
-rw-r--r--Ryujinx.Audio/Renderer/Server/Effect/BufferMixEffect.cs12
-rw-r--r--Ryujinx.Audio/Renderer/Server/Effect/DelayEffect.cs12
-rw-r--r--Ryujinx.Audio/Renderer/Server/Effect/EffectContext.cs60
-rw-r--r--Ryujinx.Audio/Renderer/Server/Effect/LimiterEffect.cs112
-rw-r--r--Ryujinx.Audio/Renderer/Server/Effect/Reverb3dEffect.cs12
-rw-r--r--Ryujinx.Audio/Renderer/Server/Effect/ReverbEffect.cs12
9 files changed, 274 insertions, 16 deletions
diff --git a/Ryujinx.Audio/Renderer/Server/Effect/AuxiliaryBufferEffect.cs b/Ryujinx.Audio/Renderer/Server/Effect/AuxiliaryBufferEffect.cs
index df82945b..eac1708e 100644
--- a/Ryujinx.Audio/Renderer/Server/Effect/AuxiliaryBufferEffect.cs
+++ b/Ryujinx.Audio/Renderer/Server/Effect/AuxiliaryBufferEffect.cs
@@ -50,7 +50,17 @@ namespace Ryujinx.Audio.Renderer.Server.Effect
return WorkBuffers[index].GetReference(true);
}
- public override void Update(out BehaviourParameter.ErrorInfo updateErrorInfo, ref EffectInParameter parameter, PoolMapper mapper)
+ public override void Update(out BehaviourParameter.ErrorInfo updateErrorInfo, ref EffectInParameterVersion1 parameter, PoolMapper mapper)
+ {
+ Update(out updateErrorInfo, ref parameter, mapper);
+ }
+
+ public override void Update(out BehaviourParameter.ErrorInfo updateErrorInfo, ref EffectInParameterVersion2 parameter, PoolMapper mapper)
+ {
+ Update(out updateErrorInfo, ref parameter, mapper);
+ }
+
+ public void Update<T>(out BehaviourParameter.ErrorInfo updateErrorInfo, ref T parameter, PoolMapper mapper) where T : unmanaged, IEffectInParameter
{
Debug.Assert(IsTypeValid(ref parameter));
diff --git a/Ryujinx.Audio/Renderer/Server/Effect/BaseEffect.cs b/Ryujinx.Audio/Renderer/Server/Effect/BaseEffect.cs
index 7529f894..c7b06e7a 100644
--- a/Ryujinx.Audio/Renderer/Server/Effect/BaseEffect.cs
+++ b/Ryujinx.Audio/Renderer/Server/Effect/BaseEffect.cs
@@ -98,7 +98,7 @@ namespace Ryujinx.Audio.Renderer.Server.Effect
/// </summary>
/// <param name="parameter">The user parameter.</param>
/// <returns>Returns true if the <see cref="EffectType"/> sent by the user matches the internal <see cref="EffectType"/>.</returns>
- public bool IsTypeValid(ref EffectInParameter parameter)
+ public bool IsTypeValid<T>(ref T parameter) where T: unmanaged, IEffectInParameter
{
return parameter.Type == TargetEffectType;
}
@@ -115,7 +115,7 @@ namespace Ryujinx.Audio.Renderer.Server.Effect
/// Update the internal common parameters from a user parameter.
/// </summary>
/// <param name="parameter">The user parameter.</param>
- protected void UpdateParameterBase(ref EffectInParameter parameter)
+ protected void UpdateParameterBase<T>(ref T parameter) where T : unmanaged, IEffectInParameter
{
MixId = parameter.MixId;
ProcessingOrder = parameter.ProcessingOrder;
@@ -154,12 +154,38 @@ namespace Ryujinx.Audio.Renderer.Server.Effect
}
/// <summary>
- /// Update the internal state from a user parameter.
+ /// Initialize the given <paramref name="state"/> result state.
+ /// </summary>
+ /// <param name="state">The state to initalize</param>
+ public virtual void InitializeResultState(ref EffectResultState state) {}
+
+ /// <summary>
+ /// Update the <paramref name="destState"/> result state with <paramref name="srcState"/>.
+ /// </summary>
+ /// <param name="destState">The destination result state</param>
+ /// <param name="srcState">The source result state</param>
+ public virtual void UpdateResultState(ref EffectResultState destState, ref EffectResultState srcState) {}
+
+ /// <summary>
+ /// Update the internal state from a user version 1 parameter.
+ /// </summary>
+ /// <param name="updateErrorInfo">The possible <see cref="ErrorInfo"/> that was generated.</param>
+ /// <param name="parameter">The user parameter.</param>
+ /// <param name="mapper">The mapper to use.</param>
+ public virtual void Update(out ErrorInfo updateErrorInfo, ref EffectInParameterVersion1 parameter, PoolMapper mapper)
+ {
+ Debug.Assert(IsTypeValid(ref parameter));
+
+ updateErrorInfo = new ErrorInfo();
+ }
+
+ /// <summary>
+ /// Update the internal state from a user version 2 parameter.
/// </summary>
/// <param name="updateErrorInfo">The possible <see cref="ErrorInfo"/> that was generated.</param>
/// <param name="parameter">The user parameter.</param>
/// <param name="mapper">The mapper to use.</param>
- public virtual void Update(out ErrorInfo updateErrorInfo, ref EffectInParameter parameter, PoolMapper mapper)
+ public virtual void Update(out ErrorInfo updateErrorInfo, ref EffectInParameterVersion2 parameter, PoolMapper mapper)
{
Debug.Assert(IsTypeValid(ref parameter));
@@ -206,26 +232,26 @@ namespace Ryujinx.Audio.Renderer.Server.Effect
/// </summary>
/// <param name="outStatus">The given user output.</param>
/// <param name="isAudioRendererActive">If set to true, the <see cref="AudioRenderSystem"/> is active.</param>
- public void StoreStatus(ref EffectOutStatus outStatus, bool isAudioRendererActive)
+ public void StoreStatus<T>(ref T outStatus, bool isAudioRendererActive) where T: unmanaged, IEffectOutStatus
{
if (isAudioRendererActive)
{
if (UsageState == UsageState.Disabled)
{
- outStatus.State = EffectOutStatus.EffectState.Disabled;
+ outStatus.State = EffectState.Disabled;
}
else
{
- outStatus.State = EffectOutStatus.EffectState.Enabled;
+ outStatus.State = EffectState.Enabled;
}
}
else if (UsageState == UsageState.New)
{
- outStatus.State = EffectOutStatus.EffectState.Enabled;
+ outStatus.State = EffectState.Enabled;
}
else
{
- outStatus.State = EffectOutStatus.EffectState.Disabled;
+ outStatus.State = EffectState.Disabled;
}
}
@@ -249,6 +275,8 @@ namespace Ryujinx.Audio.Renderer.Server.Effect
return PerformanceDetailType.Reverb3d;
case EffectType.BufferMix:
return PerformanceDetailType.Mix;
+ case EffectType.Limiter:
+ return PerformanceDetailType.Limiter;
default:
throw new NotImplementedException($"{Type}");
}
diff --git a/Ryujinx.Audio/Renderer/Server/Effect/BiquadFilterEffect.cs b/Ryujinx.Audio/Renderer/Server/Effect/BiquadFilterEffect.cs
index 35ba8a0d..6c91b607 100644
--- a/Ryujinx.Audio/Renderer/Server/Effect/BiquadFilterEffect.cs
+++ b/Ryujinx.Audio/Renderer/Server/Effect/BiquadFilterEffect.cs
@@ -52,7 +52,17 @@ namespace Ryujinx.Audio.Renderer.Server.Effect
public override EffectType TargetEffectType => EffectType.BiquadFilter;
- public override void Update(out BehaviourParameter.ErrorInfo updateErrorInfo, ref EffectInParameter parameter, PoolMapper mapper)
+ public override void Update(out BehaviourParameter.ErrorInfo updateErrorInfo, ref EffectInParameterVersion1 parameter, PoolMapper mapper)
+ {
+ Update(out updateErrorInfo, ref parameter, mapper);
+ }
+
+ public override void Update(out BehaviourParameter.ErrorInfo updateErrorInfo, ref EffectInParameterVersion2 parameter, PoolMapper mapper)
+ {
+ Update(out updateErrorInfo, ref parameter, mapper);
+ }
+
+ public void Update<T>(out BehaviourParameter.ErrorInfo updateErrorInfo, ref T parameter, PoolMapper mapper) where T : unmanaged, IEffectInParameter
{
Debug.Assert(IsTypeValid(ref parameter));
diff --git a/Ryujinx.Audio/Renderer/Server/Effect/BufferMixEffect.cs b/Ryujinx.Audio/Renderer/Server/Effect/BufferMixEffect.cs
index 14ed3950..05cccad9 100644
--- a/Ryujinx.Audio/Renderer/Server/Effect/BufferMixEffect.cs
+++ b/Ryujinx.Audio/Renderer/Server/Effect/BufferMixEffect.cs
@@ -36,7 +36,17 @@ namespace Ryujinx.Audio.Renderer.Server.Effect
public override EffectType TargetEffectType => EffectType.BufferMix;
- public override void Update(out BehaviourParameter.ErrorInfo updateErrorInfo, ref EffectInParameter parameter, PoolMapper mapper)
+ public override void Update(out BehaviourParameter.ErrorInfo updateErrorInfo, ref EffectInParameterVersion1 parameter, PoolMapper mapper)
+ {
+ Update(out updateErrorInfo, ref parameter, mapper);
+ }
+
+ public override void Update(out BehaviourParameter.ErrorInfo updateErrorInfo, ref EffectInParameterVersion2 parameter, PoolMapper mapper)
+ {
+ Update(out updateErrorInfo, ref parameter, mapper);
+ }
+
+ public void Update<T>(out BehaviourParameter.ErrorInfo updateErrorInfo, ref T parameter, PoolMapper mapper) where T : unmanaged, IEffectInParameter
{
Debug.Assert(IsTypeValid(ref parameter));
diff --git a/Ryujinx.Audio/Renderer/Server/Effect/DelayEffect.cs b/Ryujinx.Audio/Renderer/Server/Effect/DelayEffect.cs
index df3e5ee7..a5b3dbc5 100644
--- a/Ryujinx.Audio/Renderer/Server/Effect/DelayEffect.cs
+++ b/Ryujinx.Audio/Renderer/Server/Effect/DelayEffect.cs
@@ -54,7 +54,17 @@ namespace Ryujinx.Audio.Renderer.Server.Effect
return GetSingleBuffer();
}
- public override void Update(out BehaviourParameter.ErrorInfo updateErrorInfo, ref EffectInParameter parameter, PoolMapper mapper)
+ public override void Update(out BehaviourParameter.ErrorInfo updateErrorInfo, ref EffectInParameterVersion1 parameter, PoolMapper mapper)
+ {
+ Update(out updateErrorInfo, ref parameter, mapper);
+ }
+
+ public override void Update(out BehaviourParameter.ErrorInfo updateErrorInfo, ref EffectInParameterVersion2 parameter, PoolMapper mapper)
+ {
+ Update(out updateErrorInfo, ref parameter, mapper);
+ }
+
+ public void Update<T>(out BehaviourParameter.ErrorInfo updateErrorInfo, ref T parameter, PoolMapper mapper) where T : unmanaged, IEffectInParameter
{
Debug.Assert(IsTypeValid(ref parameter));
diff --git a/Ryujinx.Audio/Renderer/Server/Effect/EffectContext.cs b/Ryujinx.Audio/Renderer/Server/Effect/EffectContext.cs
index ff6051ae..074f4375 100644
--- a/Ryujinx.Audio/Renderer/Server/Effect/EffectContext.cs
+++ b/Ryujinx.Audio/Renderer/Server/Effect/EffectContext.cs
@@ -15,6 +15,9 @@
// along with this program. If not, see <https://www.gnu.org/licenses/>.
//
+using Ryujinx.Audio.Renderer.Parameter;
+using Ryujinx.Audio.Renderer.Utils;
+using System;
using System.Diagnostics;
namespace Ryujinx.Audio.Renderer.Server.Effect
@@ -34,6 +37,9 @@ namespace Ryujinx.Audio.Renderer.Server.Effect
/// </summary>
private uint _effectCount;
+ private EffectResultState[] _resultStatesCpu;
+ private EffectResultState[] _resultStatesDsp;
+
/// <summary>
/// Create a new <see cref="EffectContext"/>.
/// </summary>
@@ -47,7 +53,8 @@ namespace Ryujinx.Audio.Renderer.Server.Effect
/// Initialize the <see cref="EffectContext"/>.
/// </summary>
/// <param name="effectCount">The total effect count.</param>
- public void Initialize(uint effectCount)
+ /// <param name="resultStateCount">The total result state count.</param>
+ public void Initialize(uint effectCount, uint resultStateCount)
{
_effectCount = effectCount;
_effects = new BaseEffect[effectCount];
@@ -56,6 +63,9 @@ namespace Ryujinx.Audio.Renderer.Server.Effect
{
_effects[i] = new BaseEffect();
}
+
+ _resultStatesCpu = new EffectResultState[resultStateCount];
+ _resultStatesDsp = new EffectResultState[resultStateCount];
}
/// <summary>
@@ -78,5 +88,53 @@ namespace Ryujinx.Audio.Renderer.Server.Effect
return ref _effects[index];
}
+
+ /// <summary>
+ /// Get a reference to a <see cref="EffectResultState"/> at the given <paramref name="index"/>.
+ /// </summary>
+ /// <param name="index">The index to use.</param>
+ /// <returns>A reference to a <see cref="EffectResultState"/> at the given <paramref name="index"/>.</returns>
+ /// <remarks>The returned <see cref="EffectResultState"/> should only be used when updating the server state.</remarks>
+ public ref EffectResultState GetState(int index)
+ {
+ Debug.Assert(index >= 0 && index < _resultStatesCpu.Length);
+
+ return ref _resultStatesCpu[index];
+ }
+
+ /// <summary>
+ /// Get a reference to a <see cref="EffectResultState"/> at the given <paramref name="index"/>.
+ /// </summary>
+ /// <param name="index">The index to use.</param>
+ /// <returns>A reference to a <see cref="EffectResultState"/> at the given <paramref name="index"/>.</returns>
+ /// <remarks>The returned <see cref="EffectResultState"/> should only be used in the context of processing on the <see cref="Dsp.AudioProcessor"/>.</remarks>
+ public ref EffectResultState GetDspState(int index)
+ {
+ Debug.Assert(index >= 0 && index < _resultStatesDsp.Length);
+
+ return ref _resultStatesDsp[index];
+ }
+
+ /// <summary>
+ /// Get a memory instance to a <see cref="EffectResultState"/> at the given <paramref name="index"/>.
+ /// </summary>
+ /// <param name="index">The index to use.</param>
+ /// <returns>A memory instance to a <see cref="EffectResultState"/> at the given <paramref name="index"/>.</returns>
+ /// <remarks>The returned <see cref="Memory{EffectResultState}"/> should only be used in the context of processing on the <see cref="Dsp.AudioProcessor"/>.</remarks>
+ public Memory<EffectResultState> GetDspStateMemory(int index)
+ {
+ return SpanIOHelper.GetMemory(_resultStatesDsp.AsMemory(), index, (uint)_resultStatesDsp.Length);
+ }
+
+ /// <summary>
+ /// Update internal state during command generation.
+ /// </summary>
+ public void UpdateResultStateForCommandGeneration()
+ {
+ for (int index = 0; index < _resultStatesCpu.Length; index++)
+ {
+ _effects[index].UpdateResultState(ref _resultStatesCpu[index], ref _resultStatesDsp[index]);
+ }
+ }
}
}
diff --git a/Ryujinx.Audio/Renderer/Server/Effect/LimiterEffect.cs b/Ryujinx.Audio/Renderer/Server/Effect/LimiterEffect.cs
new file mode 100644
index 00000000..fa04c027
--- /dev/null
+++ b/Ryujinx.Audio/Renderer/Server/Effect/LimiterEffect.cs
@@ -0,0 +1,112 @@
+//
+// Copyright (c) 2019-2021 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.Common;
+using Ryujinx.Audio.Renderer.Dsp.State;
+using Ryujinx.Audio.Renderer.Parameter;
+using Ryujinx.Audio.Renderer.Parameter.Effect;
+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 limiter effect.
+ /// </summary>
+ public class LimiterEffect : BaseEffect
+ {
+ /// <summary>
+ /// The limiter parameter.
+ /// </summary>
+ public LimiterParameter Parameter;
+
+ /// <summary>
+ /// The limiter state.
+ /// </summary>
+ public Memory<LimiterState> State { get; }
+
+ /// <summary>
+ /// Create a new <see cref="LimiterEffect"/>.
+ /// </summary>
+ public LimiterEffect()
+ {
+ State = new LimiterState[1];
+ }
+
+ public override EffectType TargetEffectType => EffectType.Limiter;
+
+ public override ulong GetWorkBuffer(int index)
+ {
+ return GetSingleBuffer();
+ }
+
+ public override void Update(out BehaviourParameter.ErrorInfo updateErrorInfo, ref EffectInParameterVersion1 parameter, PoolMapper mapper)
+ {
+ Update(out updateErrorInfo, ref parameter, mapper);
+ }
+
+ public override void Update(out BehaviourParameter.ErrorInfo updateErrorInfo, ref EffectInParameterVersion2 parameter, PoolMapper mapper)
+ {
+ Update(out updateErrorInfo, ref parameter, mapper);
+ }
+
+ public void Update<T>(out BehaviourParameter.ErrorInfo updateErrorInfo, ref T parameter, PoolMapper mapper) where T : unmanaged, IEffectInParameter
+ {
+ Debug.Assert(IsTypeValid(ref parameter));
+
+ ref LimiterParameter limiterParameter = ref MemoryMarshal.Cast<byte, LimiterParameter>(parameter.SpecificData)[0];
+
+ updateErrorInfo = new BehaviourParameter.ErrorInfo();
+
+ UpdateParameterBase(ref parameter);
+
+ Parameter = limiterParameter;
+
+ IsEnabled = parameter.IsEnabled;
+
+ if (BufferUnmapped || parameter.IsNew)
+ {
+ UsageState = UsageState.New;
+ Parameter.Status = UsageState.Invalid;
+
+ BufferUnmapped = !mapper.TryAttachBuffer(out updateErrorInfo, ref WorkBuffers[0], parameter.BufferBase, parameter.BufferSize);
+ }
+ }
+
+ public override void UpdateForCommandGeneration()
+ {
+ UpdateUsageStateForCommandGeneration();
+
+ Parameter.Status = UsageState.Enabled;
+ Parameter.StatisticsReset = false;
+ }
+
+ public override void InitializeResultState(ref EffectResultState state)
+ {
+ ref LimiterStatistics statistics = ref MemoryMarshal.Cast<byte, LimiterStatistics>(state.SpecificData)[0];
+
+ statistics.Reset();
+ }
+
+ public override void UpdateResultState(ref EffectResultState destState, ref EffectResultState srcState)
+ {
+ destState = srcState;
+ }
+ }
+}
diff --git a/Ryujinx.Audio/Renderer/Server/Effect/Reverb3dEffect.cs b/Ryujinx.Audio/Renderer/Server/Effect/Reverb3dEffect.cs
index d9f23799..7b8fd6c4 100644
--- a/Ryujinx.Audio/Renderer/Server/Effect/Reverb3dEffect.cs
+++ b/Ryujinx.Audio/Renderer/Server/Effect/Reverb3dEffect.cs
@@ -53,7 +53,17 @@ namespace Ryujinx.Audio.Renderer.Server.Effect
return GetSingleBuffer();
}
- public override void Update(out BehaviourParameter.ErrorInfo updateErrorInfo, ref EffectInParameter parameter, PoolMapper mapper)
+ public override void Update(out BehaviourParameter.ErrorInfo updateErrorInfo, ref EffectInParameterVersion1 parameter, PoolMapper mapper)
+ {
+ Update(out updateErrorInfo, ref parameter, mapper);
+ }
+
+ public override void Update(out BehaviourParameter.ErrorInfo updateErrorInfo, ref EffectInParameterVersion2 parameter, PoolMapper mapper)
+ {
+ Update(out updateErrorInfo, ref parameter, mapper);
+ }
+
+ public void Update<T>(out BehaviourParameter.ErrorInfo updateErrorInfo, ref T parameter, PoolMapper mapper) where T: unmanaged, IEffectInParameter
{
Debug.Assert(IsTypeValid(ref parameter));
diff --git a/Ryujinx.Audio/Renderer/Server/Effect/ReverbEffect.cs b/Ryujinx.Audio/Renderer/Server/Effect/ReverbEffect.cs
index 4c81f729..30908396 100644
--- a/Ryujinx.Audio/Renderer/Server/Effect/ReverbEffect.cs
+++ b/Ryujinx.Audio/Renderer/Server/Effect/ReverbEffect.cs
@@ -56,7 +56,17 @@ namespace Ryujinx.Audio.Renderer.Server.Effect
return GetSingleBuffer();
}
- public override void Update(out BehaviourParameter.ErrorInfo updateErrorInfo, ref EffectInParameter parameter, PoolMapper mapper)
+ public override void Update(out BehaviourParameter.ErrorInfo updateErrorInfo, ref EffectInParameterVersion1 parameter, PoolMapper mapper)
+ {
+ Update(out updateErrorInfo, ref parameter, mapper);
+ }
+
+ public override void Update(out BehaviourParameter.ErrorInfo updateErrorInfo, ref EffectInParameterVersion2 parameter, PoolMapper mapper)
+ {
+ Update(out updateErrorInfo, ref parameter, mapper);
+ }
+
+ public void Update<T>(out BehaviourParameter.ErrorInfo updateErrorInfo, ref T parameter, PoolMapper mapper) where T : unmanaged, IEffectInParameter
{
Debug.Assert(IsTypeValid(ref parameter));