Not sure if this is the correct place to post this, sorry new to the forum first post, I have been looking through the DSP code for the gamecube and before I start I would just like to say thanks to everyone that worked on the dsp HLE code. For me it was like a C guide to the dsp assembler awesome work guys. Anyway the POLYPHASE and LINEAR functions dont look quite right to me I dont have time to check that the below code actually works it should do its closer to the current reversed functions
// If DSP DROM coefficients are available, support polyphase resampling.
if (0) // if (coeffs && srctype == SRCTYPE_POLYPHASE)
{
s16 temp[4];
temp[0] = last_samples[0];
temp[1] = last_samples[1];
temp[2] = last_samples[2];
temp[3] = last_samples[3];
for (u32 i = 0; i < count; ++i)
{
curr_pos += ratio;
while (curr_pos >= 0x10000)
{
temp[0] = temp[1];
temp[1] = temp[2];
temp[2] = temp[3];
temp[3] = input_callback(read_samples_count++);
curr_pos -= 0x10000;
}
u16 curr_pos_frac = ((curr_pos & 0xFFFF) >> 9) << 2;
const s16* c = &coeffs[curr_pos_frac];
s64 t0 = temp[0];
s64 t1 = temp[1];
s64 t2 = temp[2];
s64 t3 = temp[3];
s64 samp = (t0 * c[0] + t1 * c[1] + t2 * c[2] + t3 * c[3]) >> 15;
output[i] = (s16)samp;
}
/* we need to read ahead four samples so the next loop starts */
/* at the right point in the wave form */
last_samples[0] = input_callback(read_samples_count++);
last_samples[1] = input_callback(read_samples_count++);
last_samples[2] = input_callback(read_samples_count++);
last_samples[3] = input_callback(read_samples_count++);
}
else if (srctype == SRCTYPE_LINEAR || srctype == SRCTYPE_POLYPHASE)
{
/* holds the last two input samples read , it is */
/* initialized with the values from the PB */
s16 temp[2];
temp[0] = last_samples[2];
temp[1] = last_samples[3];
for (u32 i = 0; i < count; ++i)
{
curr_pos += ratio;
/* While our current position is >= 1.0, push new samples to the buffer */
while (curr_pos >= 0x10000)
{
temp[0] = temp[1];
temp[1] = input_callback(read_samples_count++);
curr_pos -= 0x10000;
}
/* get our current fractional position, used to know how much of */
/* s0 and how much of s1 the output sample should be. */
u16 curr_frac = curr_pos & 0xFFFF;
s16 sample;
s32 s0 = temp[0];
s32 s1 = temp[1];
/* if curr_frac is 0, we can simply take the last sample s0 */
/* example s0 = 1 and s1 = 2 and curr_frac = 0.5 (0x8000) */
/* then we have sample = 1.5 half way between the two samples */
sample = s0 + (((s1 - s0) * curr_frac) >> 16);
output[i] = sample;
}
/* Update the four last_samples values. */
last_samples[0] = temp[0];
last_samples[1] = temp[1];
/* we need to read ahead two samples so the next loop starts */
/* at the right point in the wave form */
last_samples[2] = input_callback(read_samples_count++);
last_samples[3] = input_callback(read_samples_count++);
}
anyway if someone has time to test it see if it any better that would be great hopefully it fixes the polyphase issues.
// If DSP DROM coefficients are available, support polyphase resampling.
if (0) // if (coeffs && srctype == SRCTYPE_POLYPHASE)
{
s16 temp[4];
temp[0] = last_samples[0];
temp[1] = last_samples[1];
temp[2] = last_samples[2];
temp[3] = last_samples[3];
for (u32 i = 0; i < count; ++i)
{
curr_pos += ratio;
while (curr_pos >= 0x10000)
{
temp[0] = temp[1];
temp[1] = temp[2];
temp[2] = temp[3];
temp[3] = input_callback(read_samples_count++);
curr_pos -= 0x10000;
}
u16 curr_pos_frac = ((curr_pos & 0xFFFF) >> 9) << 2;
const s16* c = &coeffs[curr_pos_frac];
s64 t0 = temp[0];
s64 t1 = temp[1];
s64 t2 = temp[2];
s64 t3 = temp[3];
s64 samp = (t0 * c[0] + t1 * c[1] + t2 * c[2] + t3 * c[3]) >> 15;
output[i] = (s16)samp;
}
/* we need to read ahead four samples so the next loop starts */
/* at the right point in the wave form */
last_samples[0] = input_callback(read_samples_count++);
last_samples[1] = input_callback(read_samples_count++);
last_samples[2] = input_callback(read_samples_count++);
last_samples[3] = input_callback(read_samples_count++);
}
else if (srctype == SRCTYPE_LINEAR || srctype == SRCTYPE_POLYPHASE)
{
/* holds the last two input samples read , it is */
/* initialized with the values from the PB */
s16 temp[2];
temp[0] = last_samples[2];
temp[1] = last_samples[3];
for (u32 i = 0; i < count; ++i)
{
curr_pos += ratio;
/* While our current position is >= 1.0, push new samples to the buffer */
while (curr_pos >= 0x10000)
{
temp[0] = temp[1];
temp[1] = input_callback(read_samples_count++);
curr_pos -= 0x10000;
}
/* get our current fractional position, used to know how much of */
/* s0 and how much of s1 the output sample should be. */
u16 curr_frac = curr_pos & 0xFFFF;
s16 sample;
s32 s0 = temp[0];
s32 s1 = temp[1];
/* if curr_frac is 0, we can simply take the last sample s0 */
/* example s0 = 1 and s1 = 2 and curr_frac = 0.5 (0x8000) */
/* then we have sample = 1.5 half way between the two samples */
sample = s0 + (((s1 - s0) * curr_frac) >> 16);
output[i] = sample;
}
/* Update the four last_samples values. */
last_samples[0] = temp[0];
last_samples[1] = temp[1];
/* we need to read ahead two samples so the next loop starts */
/* at the right point in the wave form */
last_samples[2] = input_callback(read_samples_count++);
last_samples[3] = input_callback(read_samples_count++);
}
anyway if someone has time to test it see if it any better that would be great hopefully it fixes the polyphase issues.