fix overflow problems

Catmull-Rom can give outputs greater than 16bit, so we must use 15bit precision. Also, ensure to use floor() to force a round-down regardless of host rounding behaviour.
This commit is contained in:
Aikku93 2022-06-13 16:44:24 +10:00
parent aa25e1dd54
commit 09f7ab13c7
1 changed files with 6 additions and 6 deletions

View File

@ -215,13 +215,13 @@ int SPU_Init(int coreid, int newBufferSizeBytes)
double b = x*x*(3*x - 5) + 2;
double c = x*(x*(-3*x + 4) + 1);
double d = x*x*(x - 1);
catmullrom_lut[i][0] = (u16)(65535 * -0.5*a);
catmullrom_lut[i][1] = (u16)(65535 * 0.5*b);
catmullrom_lut[i][2] = (u16)(65535 * 0.5*c);
catmullrom_lut[i][3] = (u16)(65535 * -0.5*d);
catmullrom_lut[i][0] = (u16)floor((1u<<15) * -0.5*a);
catmullrom_lut[i][1] = (u16)floor((1u<<15) * 0.5*b);
catmullrom_lut[i][2] = (u16)floor((1u<<15) * 0.5*c);
catmullrom_lut[i][3] = (u16)floor((1u<<15) * -0.5*d);
}
for (size_t i = 0; i < COSINE_INTERPOLATION_RESOLUTION; i++)
cos_lut[i] = (u16)((1u<<16) * ((1.0 - cos(((double)i/(double)COSINE_INTERPOLATION_RESOLUTION) * M_PI)) * 0.5));
cos_lut[i] = (u16)floor((1u<<16) * ((1.0 - cos(((double)i/(double)COSINE_INTERPOLATION_RESOLUTION) * M_PI)) * 0.5));
SPU_core = new SPU_struct((int)ceil(samples_per_hline));
SPU_Reset();
@ -1056,7 +1056,7 @@ template<SPUInterpolationMode INTERPOLATE_MODE> static FORCEINLINE s32 Interpola
s32 c = pcm16b[SPUCHAN_PCM16B_AT(pcm16bOffs - 1)];
s32 d = pcm16b[SPUCHAN_PCM16B_AT(pcm16bOffs - 0)];
const u16 *w = catmullrom_lut[subPos >> (32 - CATMULLROM_INTERPOLATION_RESOLUTION_BITS)];
return (-a*(s32)w[0] + b*(s32)w[1] + c*(s32)w[2] - d*(s32)w[3]) >> 16;
return (-a*(s32)w[0] + b*(s32)w[1] + c*(s32)w[2] - d*(s32)w[3]) >> 15;
}
case SPUInterpolation_Cosine: