Wave channel anti-spike fix

Discussion of programming and development for the original Game Boy and Game Boy Color.
Post Reply
Posts: 3
Joined: Sat Jan 28, 2023 1:23 pm

Wave channel anti-spike fix

Post by cheepsmb »

nitro2k01 says to disable the $FF25 register before stopping + refreshing the wave ram.

What I'm curious is does this glitch affect most software, meaning some partially audible buzz or distortion? Is there any legit reason to *not* disable FF25 and just halt + update + resume wave channel? Seems like it would be a useful QoL emulator hack option to auto-disable wave channel because of the spike buzzing.
User avatar
Posts: 342
Joined: Thu Dec 09, 2021 12:29 pm

Re: Wave channel anti-spike fix

Post by jeffythedragonslayer »

I can't seem to recall many audio issues in GBC or GBA games, if any at all. How badly do you want to know?
Posts: 243
Joined: Sat Aug 28, 2010 9:01 am

Re: Wave channel anti-spike fix

Post by nitro2k01 »

Nice to see that this trick is still making the rounds. Let me try to explain a few things about it.

First off, the trick is intended for programs that are doing sample playback, ie periodically refilling the wave buffer to play an audio sample. It does not really (negatively) affect games using the wave channel "normally" to play a single waveform. (Explained closer below.) Most GB games do not do sample playback, and would not be affected by the buzzing. Additionally, not all games that do sample playback, use the wave channel for wave playback, but instead use some other methods that are not affected by the buzzing on GBA. Games that do use sample playback often do it for one shot sounds, for example in the title screen, or when finishing a level.

So over all the impact of this issue is fairly low. The games that are the worst affected are those that use sample playback musically for drums or other instruments, so the buzzing would be heard repeatedly. In particular, music making software that's offering sample playback is highly affected. When I figured out how to fix this on GBA, I submitted it to the author of LSDj who adopted it. I also made a patch for Pocket Music. Pocket Music locks out the user from using it on GBA by default, likely for this exact reason.

On a technical level, the actual issue is that the waveform level immediately returns to a certain level on GBA. (I think the center amplitude level, but I'm not sure now.) So if you do sample playback and say refill the wave buffer 6 times per frame, you get a buzz tone of roughly 60*6=360 Hz whenever a sample is playing, which sounds very obnoxious.

If on the other hand you'd use the wave channel "normally" (like the majority of games) you'd reload the waveform at most once per not triggered, or maybe even only when changing the instrument. You'd then get a small audio click/pop at most every time you trigger a new note. So two things come into play here compared to the case of sample playback:
1) You're likely killing the previous note at a random phase position in the middle of the waveform cycle, as opposed to killing it after exactly one cycle to reload the next portion of a continuous waveform. This already creates a click on its own, which masks the the effect of the click from the waveform reload.
2) Even so, since you're creating a small click sound only at the start of a note, you're creating a sound that accentuates the note and may even be considered musically useful, instead of obnoxious.
cheepsmb wrote: Fri Feb 03, 2023 9:14 amIs there any legit reason to *not* disable FF25 and just halt + update + resume wave channel?
If you're asking why people didn't do it previously, then the answer is simply put: why would you? FF25 is the register that you normally use to pan individual channels left/right/center. How would you come up with the idea of using it to temporarily disable a channel form being output, unless you were actively trying everything you could think of to troubleshoot an issue like I did? While the antispike method does provide a marginal improvement even on pre-GBA hardware, it's nowhere near as bad without it on pre-GBA hardware.

If you're asking if this is a recommended practice for new code, my recommendation is "yes" for sample playback code, and "don't bother with the extra complexity" for other code.
cheepsmb wrote: Fri Feb 03, 2023 9:14 am Seems like it would be a useful QoL emulator hack option to auto-disable wave channel because of the spike buzzing.
Again, as described above the real world scope of this issue (in the licensed game library) is fairly small. Additionally, I believe most emulators do not actually emulate a "GBA" in this regard, or if they do (like Sameboy) only when you specifically set the hardware model to GBA.

This is a long answer, but I hope it brought some clarity to the whole issue.
Post Reply