aboutsummaryrefslogtreecommitdiff
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
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.
-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);