aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.Audio/Renderer/Dsp/ResamplerHelper.cs
diff options
context:
space:
mode:
authorriperiperi <rhy3756547@hotmail.com>2022-02-17 19:19:29 +0000
committerGitHub <noreply@github.com>2022-02-17 20:19:29 +0100
commit7e9011673b1593aa2b318e312e0b31379e2e57e4 (patch)
tree634311915913a4f2a91820ed9d5b380631a01e34 /Ryujinx.Audio/Renderer/Dsp/ResamplerHelper.cs
parent741db8e43df4b3b3d66042ada6057df72ec236ff (diff)
Use a basic cubic interpolation for the audren upsampler (#3129)1.1.33
Before, it was selecting nearest neighbour, which sounded terrible. This is likely temporary til the upsampling algorithm used by the switch is reversed. Fixes bad audio in Skyward Sword HD.
Diffstat (limited to 'Ryujinx.Audio/Renderer/Dsp/ResamplerHelper.cs')
-rw-r--r--Ryujinx.Audio/Renderer/Dsp/ResamplerHelper.cs33
1 files changed, 28 insertions, 5 deletions
diff --git a/Ryujinx.Audio/Renderer/Dsp/ResamplerHelper.cs b/Ryujinx.Audio/Renderer/Dsp/ResamplerHelper.cs
index d40da412..d9e4c824 100644
--- a/Ryujinx.Audio/Renderer/Dsp/ResamplerHelper.cs
+++ b/Ryujinx.Audio/Renderer/Dsp/ResamplerHelper.cs
@@ -600,19 +600,42 @@ namespace Ryujinx.Audio.Renderer.Dsp
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void ResampleForUpsampler(Span<float> outputBuffer, ReadOnlySpan<float> inputBuffer, float ratio, ref float fraction, int sampleCount)
{
- // TODO: use a bandwidth filter to have better resampling.
+ // Currently a simple cubic interpolation, assuming duplicated values at edges.
+ // TODO: Discover and use algorithm that the switch uses.
+
int inputBufferIndex = 0;
+ int maxIndex = inputBuffer.Length - 1;
+ int cubicEnd = inputBuffer.Length - 3;
for (int i = 0; i < sampleCount; i++)
{
- float outputData = inputBuffer[inputBufferIndex];
+ float s0, s1, s2, s3;
- if (fraction > 1.0f)
+ s1 = inputBuffer[inputBufferIndex];
+
+ if (inputBufferIndex == 0 || inputBufferIndex > cubicEnd)
{
- outputData = inputBuffer[inputBufferIndex + 1];
+ // Clamp interplation values at the ends of the input buffer.
+ s0 = inputBuffer[Math.Max(0, inputBufferIndex - 1)];
+ s2 = inputBuffer[Math.Min(maxIndex, inputBufferIndex + 1)];
+ s3 = inputBuffer[Math.Min(maxIndex, inputBufferIndex + 2)];
+ }
+ else
+ {
+ s0 = inputBuffer[inputBufferIndex - 1];
+ s2 = inputBuffer[inputBufferIndex + 1];
+ s3 = inputBuffer[inputBufferIndex + 2];
}
- outputBuffer[i] = outputData;
+ float a = s3 - s2 - s0 + s1;
+ float b = s0 - s1 - a;
+ float c = s2 - s0;
+ float d = s1;
+
+ float f2 = fraction * fraction;
+ float f3 = f2 * fraction;
+
+ outputBuffer[i] = a * f3 + b * f2 + c * fraction + d;
fraction += ratio;
inputBufferIndex += (int)MathF.Truncate(fraction);