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:
parent
aa25e1dd54
commit
09f7ab13c7
|
@ -215,13 +215,13 @@ int SPU_Init(int coreid, int newBufferSizeBytes)
|
||||||
double b = x*x*(3*x - 5) + 2;
|
double b = x*x*(3*x - 5) + 2;
|
||||||
double c = x*(x*(-3*x + 4) + 1);
|
double c = x*(x*(-3*x + 4) + 1);
|
||||||
double d = x*x*(x - 1);
|
double d = x*x*(x - 1);
|
||||||
catmullrom_lut[i][0] = (u16)(65535 * -0.5*a);
|
catmullrom_lut[i][0] = (u16)floor((1u<<15) * -0.5*a);
|
||||||
catmullrom_lut[i][1] = (u16)(65535 * 0.5*b);
|
catmullrom_lut[i][1] = (u16)floor((1u<<15) * 0.5*b);
|
||||||
catmullrom_lut[i][2] = (u16)(65535 * 0.5*c);
|
catmullrom_lut[i][2] = (u16)floor((1u<<15) * 0.5*c);
|
||||||
catmullrom_lut[i][3] = (u16)(65535 * -0.5*d);
|
catmullrom_lut[i][3] = (u16)floor((1u<<15) * -0.5*d);
|
||||||
}
|
}
|
||||||
for (size_t i = 0; i < COSINE_INTERPOLATION_RESOLUTION; i++)
|
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_core = new SPU_struct((int)ceil(samples_per_hline));
|
||||||
SPU_Reset();
|
SPU_Reset();
|
||||||
|
@ -1056,7 +1056,7 @@ template<SPUInterpolationMode INTERPOLATE_MODE> static FORCEINLINE s32 Interpola
|
||||||
s32 c = pcm16b[SPUCHAN_PCM16B_AT(pcm16bOffs - 1)];
|
s32 c = pcm16b[SPUCHAN_PCM16B_AT(pcm16bOffs - 1)];
|
||||||
s32 d = pcm16b[SPUCHAN_PCM16B_AT(pcm16bOffs - 0)];
|
s32 d = pcm16b[SPUCHAN_PCM16B_AT(pcm16bOffs - 0)];
|
||||||
const u16 *w = catmullrom_lut[subPos >> (32 - CATMULLROM_INTERPOLATION_RESOLUTION_BITS)];
|
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:
|
case SPUInterpolation_Cosine:
|
||||||
|
|
Loading…
Reference in New Issue