Sound effects and game audio
What it is#
The other half of a game soundtrack: short, non-musical events — a shot, a jump, an explosion, the "Game Over" — fired by the game code, on the same three voices the music is using. It was most of the paid work. charles-deenen's own credit list is sound effects only on the famous jeroen-tel titles (cybernoid, Cybernoid 2, Rubicon, Savage, Turbo Outrun, Golden Axe…), with music on a much shorter list (source: s-c64com-charles-deenen-interview), and Tel describes the division as the founding idea of maniacs-of-noise: "I composed the music; he created the sound effects that was the concept" (source: s-domination01-jeroen-tel-interview).
The chip was designed for it. The sid's own datasheet calls it a "3-voice electronic music synthesizer/sound effects generator" (source: s-mos-6581-datasheet) — but it gives no separate effects channel, which is the whole problem.
Why it is hard#
- No spare voice. Effects have to take one of the three the music is already using.
- No spare memory. "Some companies only gave us six to eight kilobyte of memory for music and sound effects. Those naturally became a challenge" (source: s-c64com-charles-deenen-interview).
- No spare time. "We were only paid $200-$1000, and so we worked on them for two to six days. Sometimes we only had two days to compose the music and do the sound effects" (same source; s-vgmpf-maniacs-of-noise gives £100–£1000 for the same two-to-six-day window). At rainbow-arts the sound designer came last in the pipeline, once everything else stood (source: s-64er-rainbow-arts-feature).
- The music has to survive them. matt-gray on Quedex: the in-game tunes "needed to be written in such a way that if a sound effect played, it didn't destroy the music too much" (source: s-c64com-matt-gray-interview). It is not a popular part of the job — on Dominator, "several tracks for this & the dreaded SFX", while last-ninja-2 was "great to just do what I felt was right and not have to do any SFX. A dream project really" (source: s-retrogamesmaster-matt-gray-interview).
The design every driver converges on: an effect is an instrument plus a pitch#
Read four C64 drivers and the same answer appears in each. An effect is not a note — it is an instrument program with a frequency, and no note and no duration, because the instrument's own table decides when it is finished.
- martin-galway, Arkanoid (Tognon's reverse-engineering): "a sound effect is activated by compiling an effect instrument table, and then activating the same methods (
makeTimbreVx) used by the engine. The sound instruments table is a perfect copy of the instrument table, but with two extra bytes at the end: the low/high value of the frequency to use." No note byte, no duration — "the duration is taken according by the timbre effect the instrument table is executing" — and "all the 3 voices can be used for generating the sound effect" (source: s-sidin04-galway-arkanoid). In the listing that is 12 effects stored as 31-byte blocks, three per effect, one per voice, at$2000; 1116 bytes of effects against ≈ 2.5 KB of music, and the file's 20 "songs" are two tunes, six jingles and twelve effects (source: s-realdmx-galway-arkanoid-player). - fred-gray, Mutants (inside Ocean's driver): a resident effect engine of 32 rows × 8 bytes —
instrument, start pitch, target note (bit 7 = glide), AD, timer × 4 frames, next effect— where the game writes an effect number into a per-voice slot and the driver chains one row to the next. Note bytes carry the note in bits 0–5, a glide-from-previous-pitch flag in bit 7, and$00means keep sounding. About 3.8 KB at$e000–$eeb5(source: s-realdmx-fredgray-kimmel-whittaker). Thenext effectbyte is the interesting part: an effect can be a sequence of instrument programs. - maniacs-of-noise: a separate driver, not a mode of the music player — "Deenen programmed a music driver ('Musicfile') and a sound effects driver in Turbo Ass" (source: s-vgmpf-maniacs-of-noise); the SFX half survives as a 958-line source (source: s-realdmx-sid-players).
- JCH: likewise a separate SFX player, and the reason is stated plainly — it "could do a lot more sound effect tricks than the music player". Per-game sound-effect lists survive for Brubaker, Harald Hårdtand, Skærmtrolden Hugo, Orcus and Su-Sweet (source: s-chordian-player-editor-notes). Orcus went furthest: a separate SFX player and editor, with ring modulation imitating speech for "Get Ready" and "Game Over" (source: s-chordian-my-computer-chronicles; ring-modulation-and-sync).
- Martin Walker, Hunter's Moon — the fullest documented example, and the smallest.
InitEngineclears the 25 SID registers, sets volume$0Fand zeroes the per-voice indexes; an effect is started by storing a table index intoindexInTable(+0, +7, +14 for the three voices) — "That's all." A once-per-frameplaySoundloads every register from thirteen 32-entry tables —tableAD,tableSR,tableWave(pulse width packedXY→$0YX0),tableFreqLo/Hi,tableControlRegand a second control register written when the loop counter runs out,tableLoopValue,tableFreqLoStep/HiStep, and two effect selectors — then keeps the effect alive. Sixteen named effects (explosion, bell, drill, plonk, fire, bonus, stage start…) are each just one to three stored indexes, so one-voice effects overlap freely:soundFire=$12on voice 1 alone;soundBell=$16, $16, $17across all three (source: s-sidin14-hunters-moon). About 250 lines for the whole engine.
rob-hubbard shipped the whole bundle as one deliverable — "a block containing both the player and the sound data, typically with several tunes and jingles as well as an array of sound effects" (source: s-chordian-sid-musicians).
Sharing three voices#
- Steal a note. The commonest answer: "usually effects steal notes (Thing on a Spring, Commando)". The Human Race used two voices for music and kept the third for effects; Delta let the player choose music or effects (source: s-newman-driving-the-sid-chip).
- Reserve one voice, and write for two. If voice 3 is the effects channel, the music is a two-voice arrangement — which is exactly why channel-interleaving matters: matt-gray on KGB Superspy, "trying to maximise any rhythm elements without using a whole channel to do it" (source: s-retrogamesmaster-matt-gray-interview).
- Or give up the music. Walker's engine uses "up to all three voices per effect", which Tognon reads as the reason Hunter's Moon plays no music during the game: "He uses even more SID voices for some effects … and maybe this is why music is not played during game play" (source: s-sidin14-hunters-moon). Budgeting by voice count — one-voice effects overlap, three-voice effects are exclusive — is a design decision made before the first note is written.
- Multiplex both. For Chase HQ II / Special Criminal Investigation, Link composed and JCH "multiplexed two voices of SFX with two of music" (source: s-chordian-my-computer-chronicles).
- Write the music to be interrupted. Put the material that matters on the voices the effects will not take, and keep the melody's rests where an effect can land (melody-writing).
Recipes: realism from register games, not samples#
Walker's engine is the counter-example to the idea that convincing effects need sampled audio. Tognon's verdict after reverse-engineering it: "I was sure it was a very complicated engine as the sound is the most realistic you can find into a game. But the engine is simple and the secret is just how the sid is manipulated in a convenient way" (source: s-sidin14-hunters-moon). The tricks, all of them one table byte:
- Pitch-ramp modes as a single selector: 1 add, 2 subtract, 3 looped add, 4 looped subtract, 5 add while looping then subtract, 6 subtract then add. Modes 5 and 6 are a triangle LFO written as one number (vibrato).
- Byte swap. The fire effect (AD
$00, SR$30, control$11→$10, loop 6, frequency$E0F0) sets its second effect selector to 1, which swaps the frequency low and high bytes each frame — "a triangle sound that change frequency from two fixed value". - EOR scrambles. Selector 2 subtracts the step then
EOR #$DF; selector 3 subtracts andEOR #$12— deterministic noise in the pitch, for free. - Borrow the chip's own randomness. Selector 4 adds
$D41B AND $0F— the top nibble of oscillator 3's noise output — to the frequency high byte (randomization-and-probability). - Ring-modulated pairs. The plonk is two voices: voice 2 at index
$07with control$15(triangle + ring), SR$98, frequency$F400, high-byte step$0Dand ramp mode 5 — "a vibrato like sound, but is uses ring modulation" — against voice 3 at index$04, a silent triangle ($10) at$2011stepping$01in mode 6, the opposite direction (ring-modulation-and-sync). - The two-control-register trick: one waveform byte at the start, a second (usually gate-off) written when the loop counter expires — the same idea as an instrument's gate-off frame (instrument-design).
- Lock out interruptions for the big ones. Explosion and star cell set a flag; the next frame a 50-frame (
$32) counter clears voices 2–3's indexes every frame so nothing can cut the effect short.
How to do it today#
SID-Wizard#
The exported tune is an API with an effects entry point. Call LoadAddress + 12 with X = note, Y = instrument, A = length; SFX plays on channel 3 (sources: s-witchmaster-creating-chiptunes-with-sid-wizard, s-sid-wizard-manual). That is the same instrument-plus-pitch triple the 1980s drivers used, exposed as three registers — so any of the tune's 36 instruments can be a sound effect, and designing effects becomes ordinary instrument-design and wavetable-programming.
DUET#
duet takes the same road explicitly: duet_engine_note_on fires an instrument by family — a PCM instrument, or a SID-Wizard instrument from the project's pool routed through a chip — with jam = 1 building a chip on demand, no pattern needed. The docs call it "a game's instruments-as-sound-effects road" (source: s-duet-docs-libduet).
Tips & pitfalls#
- Retriggering an effect runs straight into the ADSR bug. The canonical Lemon64 thread starts with a game coder who cannot retrigger a sound effect, and lasse-oorni explaining why: the envelope generator has to be gated off and reset before the new note or the attack is lost. Effects fire at arbitrary times, so they need hard-restart more than music does (source: s-lemon64-hard-restart-threads).
- An effect overwrites the voice's instrument state. Because it is an instrument program, whatever ADSR, waveform, pulse width and filter routing it writes stay written; drivers that survive this keep a running per-voice copy of the instrument and restore from it, as Galway's does (source: s-sidin04-galway-arkanoid).
- Noise effects can lock the oscillator. Combining noise with another waveform silences it and locks the noise generator until the test bit is set — a laser sweep that ends on a combined waveform will leave the voice mute for the next effect. Set the test bit at the start of every effect (source: s-chordian-sf2-instruments; ring-modulation-and-sync).
- Budget the effects like patterns. Galway's twelve effects cost 1116 bytes against 2.5 KB of music, and Fred Gray's whole engine 3.8 KB — in an 6–8 KB allocation, effects are a third to a half of it (sources: s-realdmx-galway-arkanoid-player, s-realdmx-fredgray-kimmel-whittaker, s-c64com-charles-deenen-interview).
- Jingles are a third category. Neither music nor effect: Arkanoid stores six of them beside twelve effects and two tunes in the same file, and Hubbard's delivery block did the same (sources: s-realdmx-galway-arkanoid-player, s-chordian-sid-musicians).
Related#
channel-interleaving · hard-restart · instrument-design · wavetable-programming · sid-player-routine · commercial-tracking · ring-modulation-and-sync · arrangement
Sources#
s-mos-6581-datasheet · s-sidin04-galway-arkanoid · s-realdmx-galway-arkanoid-player · s-realdmx-fredgray-kimmel-whittaker · s-sidin14-hunters-moon · s-realdmx-sid-players · s-vgmpf-maniacs-of-noise · s-chordian-player-editor-notes · s-chordian-my-computer-chronicles · s-chordian-sid-musicians · s-chordian-sf2-instruments · s-c64com-charles-deenen-interview · s-domination01-jeroen-tel-interview · s-c64com-matt-gray-interview · s-retrogamesmaster-matt-gray-interview · s-newman-driving-the-sid-chip · s-lemon64-hard-restart-threads · s-witchmaster-creating-chiptunes-with-sid-wizard · s-sid-wizard-manual · s-64er-rainbow-arts-feature · s-duet-docs-libduet