VOGONS


First post, by erwin_t6

User metadata
Rank Newbie
Rank
Newbie

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

Reply 2 of 10, by erwin_t6

User metadata
Rank Newbie
Rank
Newbie

Many midi's sound better. The default GUS striving.mid for example. The piano's dont sound clean. Check the attached midi for a good example. The high pitched instrument on channel 1 sounds much cleaner.

Attachments

  • Filename
    Colonize.zip
    File size
    64.58 KiB
    Downloads
    169 downloads
    File license
    Fair use/fair dealing exception

Reply 3 of 10, by wd

User metadata
Rank DOSBox Author
Rank
DOSBox Author

Hm i can't hear a difference, though it definitely sounds different when
comparing gus sampling against sb sampling (might be correct though).

Was using cubic player, and don't have good speakers here, but what
midi player did you use?

Reply 4 of 10, by erwin_t6

User metadata
Rank Newbie
Rank
Newbie

Check the attached audio example (taken from the midi from the previous post), sampled at 44khz. Please ignore the small offset in the start. The midi playing program (karados) does that for some reason.

Take a closer look to the ending notes in the last few seconds of the files. This is exactly a good note to explain the difference. Skipping samples without interpolation is evil, and produces tonal differences, which are very easily audible, and sound 'jerky'.

Attachments

  • Filename
    old.mp3
    File size
    1.43 MiB
    Downloads
    488 downloads
    File license
    Fair use/fair dealing exception
  • Filename
    new.mp3
    File size
    1.43 MiB
    Downloads
    493 downloads
    File license
    Fair use/fair dealing exception

Reply 5 of 10, by wd

User metadata
Rank DOSBox Author
Rank
DOSBox Author

> Skipping samples without interpolation is evil

Yes, but looking at your changes i just wondered why interpolating
between [x] and [x+1] would be any better then, as the interval
might be larger than 1 (though this might be just wrong, i have
no idea how that gus sampling really works).

Reply 6 of 10, by Jiri

User metadata
Rank Member
Rank
Member

This GUS thread reminded me problems I had in some games Where do i get a list of games supporting GUS?
I tried the latest CVS and "clicking" is still there. I noticed it in these games:
Blue Ice
Bud Tucker in Double Trouble
Discworld 2
D
Callahan Crosstime Saloon
Gene Machine

Here is a sample from Callahan Crosstime Saloon.

Attachments

  • Filename
    Saloon.mp3
    File size
    189.29 KiB
    Downloads
    273 downloads
    File license
    Fair use/fair dealing exception

Reply 7 of 10, by erwin_t6

User metadata
Rank Newbie
Rank
Newbie
wd wrote:
> Skipping samples without interpolation is evil […]
Show full quote

> Skipping samples without interpolation is evil

Yes, but looking at your changes i just wondered why interpolating
between [x] and [x+1] would be any better then, as the interval
might be larger than 1 (though this might be just wrong, i have
no idea how that gus sampling really works).

Ideally we would sample all the skipped samples as well, however i have no idea if an actual GUS does that. Seems to me it doesnt, since arbitrary pitching would then require a variable amount of work to be done. In hardwere terms this seems complicated. Especially considering the fact that an actual GUS samples at a lower freq with more channels enabled, which gives a very strong hint that its mixing/interpolation throughput is quite limited.

However, this ideal situation would only be mathematically different in the case of >= double frequency. This shouldnt happen too often, because it generally sounds not too good anyway.

It would, however, also introduce problems with looping (both normal and bi-directional). I didnt want to bother with this situation, because it requires more advanced methods, including changing the parameters the function takes.

I wanted a fix that solves this interpolation issue, because it sounded bad. When you look at the actual math more closely you will find that this easy solution is actually not so bad. And since its probably what the GUS internally does, it seems to be sufficient.

Reply 8 of 10, by erwin_t6

User metadata
Rank Newbie
Rank
Newbie
Jiri wrote:
This GUS thread reminded me problems I had in some games Where do i get a list of games supporting GUS? I tried the latest CVS a […]
Show full quote

This GUS thread reminded me problems I had in some games Where do i get a list of games supporting GUS?
I tried the latest CVS and "clicking" is still there. I noticed it in these games:
Blue Ice
Bud Tucker in Double Trouble
Discworld 2
D
Callahan Crosstime Saloon
Gene Machine

Here is a sample from Callahan Crosstime Saloon.

This doesnt seem related to me, because the frequency of the ticking in your sample is quite low.

Reply 9 of 10, by canadacow

User metadata
Rank Member
Rank
Member
erwin_t6 wrote:
I noticed the GetSample function (gus.cpp) only linearly interpolates sampling data, when upsampling, and not when downsampling. […]
Show full quote

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.
It would be nice to have this integrated into the new codebase.

Regards
Erwin

Interpolation is not what should be done when downsampling as this will still produce artifacts as has been demonstrated. What really needs to happen is that samples should be skipped and then put through a low-pass filter equal to the sampling rate presently used for output. Including a variable low-pass filter will solve the clicking/aliasing but also introduce a great deal of complexity to the GUS playback.

Reply 10 of 10, by wd

User metadata
Rank DOSBox Author
Rank
DOSBox Author

> as this will still produce artifacts as has been demonstrated.

But it sounds better, at least with the sound clips provided, so would
this be a simple way to get it a bit better, or does it create unwanted
side effects?