diff options
author | riperiperi <rhy3756547@hotmail.com> | 2022-02-17 19:19:29 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-02-17 20:19:29 +0100 |
commit | 7e9011673b1593aa2b318e312e0b31379e2e57e4 (patch) | |
tree | 634311915913a4f2a91820ed9d5b380631a01e34 | |
parent | 741db8e43df4b3b3d66042ada6057df72ec236ff (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.cs | 33 |
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); |