aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.Audio/Renderer/Dsp/UpsamplerHelper.cs
diff options
context:
space:
mode:
authorLogan Stromberg <loganstromberg@gmail.com>2023-02-21 02:44:57 -0800
committerGitHub <noreply@github.com>2023-02-21 11:44:57 +0100
commitedfd4d70c0f38d41c6ebb31508127b14727017bd (patch)
treecf379010089a72cf1b33387e4ce664f51c8557d1 /Ryujinx.Audio/Renderer/Dsp/UpsamplerHelper.cs
parentfc43aecbbd37a83ebd03f8cfe8fbc033ce2bda7d (diff)
Use SIMD acceleration for audio upsampler (#4410)
* Use SIMD acceleration for audio upsampler filter kernel for a moderate speedup * Address formatting. Implement AVX2 fast path for high quality resampling in ResamplerHelper * now really, are we really getting the benefit of inlining 50+ line methods? * adding unit tests for resampler + upsampler. The upsampler ones fail for some reason * Fixing upsampler test. Apparently this algo only works at specific ratios --------- Co-authored-by: Logan Stromberg <lostromb@microsoft.com>
Diffstat (limited to 'Ryujinx.Audio/Renderer/Dsp/UpsamplerHelper.cs')
-rw-r--r--Ryujinx.Audio/Renderer/Dsp/UpsamplerHelper.cs23
1 files changed, 20 insertions, 3 deletions
diff --git a/Ryujinx.Audio/Renderer/Dsp/UpsamplerHelper.cs b/Ryujinx.Audio/Renderer/Dsp/UpsamplerHelper.cs
index 847acec2..6cdab5a7 100644
--- a/Ryujinx.Audio/Renderer/Dsp/UpsamplerHelper.cs
+++ b/Ryujinx.Audio/Renderer/Dsp/UpsamplerHelper.cs
@@ -2,6 +2,7 @@ using Ryujinx.Audio.Renderer.Server.Upsampler;
using Ryujinx.Common.Memory;
using System;
using System.Diagnostics;
+using System.Numerics;
using System.Runtime.CompilerServices;
namespace Ryujinx.Audio.Renderer.Dsp
@@ -70,16 +71,32 @@ namespace Ryujinx.Audio.Renderer.Dsp
return;
}
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
float DoFilterBank(ref UpsamplerBufferState state, in Array20<float> bank)
{
float result = 0.0f;
Debug.Assert(state.History.Length == HistoryLength);
Debug.Assert(bank.Length == FilterBankLength);
- for (int j = 0; j < FilterBankLength; j++)
+
+ int curIdx = 0;
+ if (Vector.IsHardwareAccelerated)
+ {
+ // Do SIMD-accelerated block operations where possible.
+ // Only about a 2x speedup since filter bank length is short
+ int stopIdx = FilterBankLength - (FilterBankLength % Vector<float>.Count);
+ while (curIdx < stopIdx)
+ {
+ result += Vector.Dot(
+ new Vector<float>(bank.AsSpan().Slice(curIdx, Vector<float>.Count)),
+ new Vector<float>(state.History.AsSpan().Slice(curIdx, Vector<float>.Count)));
+ curIdx += Vector<float>.Count;
+ }
+ }
+
+ while (curIdx < FilterBankLength)
{
- result += bank[j] * state.History[j];
+ result += bank[curIdx] * state.History[curIdx];
+ curIdx++;
}
return result;