First post, by erwin_t6
Hi,
When playing some midi files i noticed imperfections in the audio output in the GUS emulation, so i got the sourcecode, and checked out what's wrong.
I noticed the GetSample function (gus.cpp) only linearly interpolates sampling data, when upsampling, and not when downsampling. This causes high pitched samples to sound aliased, especially sine-like sounds. Rewriting the code was quite easy:
static INLINE Bit32s GetSample(Bit32u Delta, Bit32u CurAddr, bool eightbit){
Bit32u useAddr;
Bit32u holdAddr;
useAddr = CurAddr >> WAVE_FRACT;
Bit32s w1, w2;
if (eightbit){
w1 = ((Bit8s)GUSRam[useAddr+0]) << 8;
w2 = ((Bit8s)GUSRam[useAddr+1]) << 8;
}
else{
holdAddr = useAddr & 0xc0000L;
useAddr = useAddr & 0x1ffffL;
useAddr = useAddr << 1;
useAddr = (holdAddr | useAddr);
w1 = (GUSRam[useAddr+0] | (((Bit8s)GUSRam[useAddr+1]) << 8));
w2 = (GUSRam[useAddr+2] | (((Bit8s)GUSRam[useAddr+3]) << 8));
}
Bit32s diff = w2 - w1;
return (w1+((diff*(Bit32s)(CurAddr&WAVE_FRACT_MASK ))>>WAVE_FRACT));
}
I'm also wondering though, about the quality of this function in case of (bi-directional) looping. IMO the +1 offset in this case should be changed in a -1 offset. Something similar applies to normal looping, in which case a % with the boundary of the sample should be added.
Although this new function always performs 2 lookups, with a linear interpolation between the 2, i still expect it to be faster than the original, because one conditional jump was removed.
It would be nice to have this integrated into the new codebase.
Regards
Erwin