mirror of
https://git.743378673.xyz/MeloNX/MeloNX.git
synced 2025-07-28 09:27:10 +02:00
Use a basic cubic interpolation for the audren upsampler (#3129)
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.
This commit is contained in:
parent
62c82f165b
commit
5a7ccb209b
1 changed files with 28 additions and 5 deletions
|
@ -600,19 +600,42 @@ namespace Ryujinx.Audio.Renderer.Dsp
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static void ResampleForUpsampler(Span<float> outputBuffer, ReadOnlySpan<float> inputBuffer, float ratio, ref float fraction, int sampleCount)
|
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 inputBufferIndex = 0;
|
||||||
|
int maxIndex = inputBuffer.Length - 1;
|
||||||
|
int cubicEnd = inputBuffer.Length - 3;
|
||||||
|
|
||||||
for (int i = 0; i < sampleCount; i++)
|
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;
|
fraction += ratio;
|
||||||
inputBufferIndex += (int)MathF.Truncate(fraction);
|
inputBufferIndex += (int)MathF.Truncate(fraction);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue