Hackaday.io — RetroChallenge 2019: Gameboy Audiohacks (channelhacking, splitting pulse waves)

author Quint, with utz (advice from nitro2k01)
date 2019-04-01
article project logs 1 (Channelhacking the Gameboy, 2019-03-14) and 2 (Splitting pulse waves, 2019-04-01)
created 2026-08-31 · updated 2026-08-31

Two project logs from a coder pair (Quint and utz) who spent RetroChallenge 2019 getting more than four voices out of a DMG-01 in software. Useful to this wiki for two things: an outside definition of the ghost-channel, and the negative result that says why the same idea cannot be automated on the wave channel.

Key claims#

  • The ghost channel, defined from outside the LSDj scene: "a technique for modifying wave data in LSDj to sound like a bass note and a much higher note are playing simultaneously by composing around the limitation that the higher note must be a harmonic of the lower one, so as to fit in the same amount of space in the wave sample. Through other clever composition tricks, like playing each note independently every so often, it can be a convincing technique, but it's ultimately limited by the relationship required between the notes being played."
  • The dead end: they tried to escape that limit by pre-computing a wave buffer of several summed software waves and swapping it in as the playback cursor reached the end. Three reasons it failed — "the WAV channel is buggy as hell, and produces large clicks when swapping out waves … at the frequencies we'd be writing to the wave sample buffer, it will sound like a constant, out of tune note whose pitch varies based on how hard the CPU is working"; wave-channel timing "must be incredibly precise, and there's not so much documentation"; and it costs a lot of CPU.
  • What they did instead — splitting the pulse channels. Set both pulse channels to the lowest frequency and the highest duty cycle so the output stays high as long as possible, then reset the PWM position before it can fall. During that window an interrupt increments one counter per software voice (self-modifying code), each counter indexes a sine table, and the sums are written to the channel's amplitude. Two counters per channel gives "a total of four software wave channels: two for each of the two pulse channels".
  • The price, stated plainly: "we go from 15 possible amplitudes (excluding zero …) to a measly 7, since we have to be able to add the results without overflowing" — the same headroom tax the ghost channel pays inside 4-bit wave RAM, here in the pulse channel's 4-bit envelope. Their demo runs six voices at once (two on PU1, one on PU2, wave, noise).
  • Part 1's framing of ordinary Game Boy practice: "Clever composers evoke the feeling of multiple notes by quickly switching between pitches to make arpeggios that sound convincingly like chords, or switch between very different sound parameters to allow two different 'instruments' to share the same channel" — the two classic answers (chord-arpeggio, channel-interleaving) that the ghost channel is an alternative to.
  • Part 1 on the wave channel's character: it "can play arbitrary waveforms, though it has many limitations including very low sample quality (four bits) and hardware bugs that cause pops and hissing".
  • Part 1 on the fifth channel: the cartridge analog input, "mixed with the rest of the audio channels as if it were generated by the Gameboy itself. No game ever used this channel, but the GB303 homebrew hardware synthesizer … uses this channel alone to produce sound."

Practical takeaways#

  • Additive tricks on the Game Boy always cost amplitude resolution: two voices summed into one 4-bit level means roughly half the steps each, whether the sum happens in wave RAM or in a pulse channel's volume register.
  • Rewriting wave RAM under a playing note is not a musician-level workaround — the channel clicks, and the click's pitch follows CPU load.
  • The harmonic constraint on the ghost note is not an LSDj limitation but a consequence of fitting both waves into the same 32-sample period.

Notable quotes#

"The WAV channel is buggy as hell, and produces large clicks when swapping out waves."

"We only get 7 discrete amplitude levels per channel, as opposed to the 15 available levels we'd get if we didn't combine two waves together."

Relevance to the wiki#

Independent confirmation and explanation of the ghost channel's central constraint, plus a documented failure mode for wave-RAM rewriting that belongs on game-boy-apu.

Pages touched#

ghost-channel · game-boy-apu · channel-interleaving · chord-arpeggio · nitro2k01 · levels-and-headroom

source file wiki/summaries/s-hackaday-gameboy-channelhacking.md · graph