Rewrite the linear interpolation SRC to give the exact same results as the one in AXWii
This commit is contained in:
parent
9776f135e2
commit
bad4f7f790
|
@ -307,38 +307,60 @@ void GetInputSamples(PB_TYPE& pb, s16* samples, const s16* coeffs)
|
||||||
// samples.
|
// samples.
|
||||||
u32 curr_pos = pb.src.cur_addr_frac;
|
u32 curr_pos = pb.src.cur_addr_frac;
|
||||||
|
|
||||||
// These are the two samples between which we interpolate. The initial
|
// This is the circular buffer containing samples to use for the
|
||||||
// values are stored in the PB, and we update them when resampling the
|
// interpolation. It is initialized with the values from the PB, and it
|
||||||
// input data.
|
// will be stored back to the PB at the end.
|
||||||
s16 curr0 = pb.src.last_samples[2];
|
s16 temp[4];
|
||||||
s16 curr1 = pb.src.last_samples[3];
|
u32 idx = 0;
|
||||||
|
|
||||||
|
temp[idx++ & 3] = pb.src.last_samples[0];
|
||||||
|
temp[idx++ & 3] = pb.src.last_samples[1];
|
||||||
|
temp[idx++ & 3] = pb.src.last_samples[2];
|
||||||
|
temp[idx++ & 3] = pb.src.last_samples[3];
|
||||||
|
|
||||||
for (u32 i = 0; i < SAMPLES_PER_FRAME; ++i)
|
for (u32 i = 0; i < SAMPLES_PER_FRAME; ++i)
|
||||||
{
|
{
|
||||||
// Get our current fractional position, used to know how much of
|
|
||||||
// curr0 and how much of curr1 the output sample should be.
|
|
||||||
s32 curr_frac_pos = curr_pos & 0xFFFF;
|
|
||||||
|
|
||||||
// Linear interpolation: s1 + (s2 - s1) * pos
|
|
||||||
s16 sample = curr0 + (s16)(((curr1 - curr0) * (s32)curr_frac_pos) >> 16);
|
|
||||||
samples[i] = sample;
|
|
||||||
|
|
||||||
curr_pos += ratio;
|
curr_pos += ratio;
|
||||||
|
|
||||||
// While our current position is >= 1.0, shift to the next 2
|
// While our current position is >= 1.0, push new samples to the
|
||||||
// samples for interpolation.
|
// circular buffer.
|
||||||
while ((curr_pos >> 16) != 0)
|
while (curr_pos >= 0x10000)
|
||||||
{
|
{
|
||||||
curr0 = curr1;
|
temp[idx++ & 3] = AcceleratorGetSample();
|
||||||
curr1 = AcceleratorGetSample();
|
|
||||||
curr_pos -= 0x10000;
|
curr_pos -= 0x10000;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get our current fractional position, used to know how much of
|
||||||
|
// curr0 and how much of curr1 the output sample should be.
|
||||||
|
u16 curr_frac = curr_pos & 0xFFFF;
|
||||||
|
u16 inv_curr_frac = -curr_frac;
|
||||||
|
|
||||||
|
// Interpolate! If curr_frac is 0, we can simply take the last
|
||||||
|
// sample without any multiplying.
|
||||||
|
s16 sample;
|
||||||
|
if (curr_frac)
|
||||||
|
{
|
||||||
|
s32 s0 = temp[idx++ & 3];
|
||||||
|
s32 s1 = temp[idx++ & 3];
|
||||||
|
|
||||||
|
sample = ((s0 * inv_curr_frac) + (s1 * curr_frac)) >> 16;
|
||||||
|
idx += 2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sample = temp[idx++ & 3];
|
||||||
|
idx += 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update the two last_samples values in the PB as well as the current
|
samples[i] = sample;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update the four last_samples values in the PB as well as the current
|
||||||
// position.
|
// position.
|
||||||
pb.src.last_samples[2] = curr0;
|
pb.src.last_samples[3] = temp[--idx & 3];
|
||||||
pb.src.last_samples[3] = curr1;
|
pb.src.last_samples[2] = temp[--idx & 3];
|
||||||
|
pb.src.last_samples[1] = temp[--idx & 3];
|
||||||
|
pb.src.last_samples[0] = temp[--idx & 3];
|
||||||
pb.src.cur_addr_frac = curr_pos & 0xFFFF;
|
pb.src.cur_addr_frac = curr_pos & 0xFFFF;
|
||||||
}
|
}
|
||||||
else // SRCTYPE_NEAREST
|
else // SRCTYPE_NEAREST
|
||||||
|
|
Loading…
Reference in New Issue