thecodingidiot.com

g01c-the-developer-acoustic

Who Wants to Be a Game Developer? Acoustic

THE SCORE

In f03c/04 you wired a passive piezo buzzer to the 6502 breadboard and toggled a pin at 440 Hz. The clicks merged into a tone. That was the irreducible minimum of electronic audio: a voltage, switched fast enough that a speaker cone interprets the switching as sound.

Real game hardware from the same era was more sophisticated. The Atari 2600's TIA chip had two audio channels — AUDC set the distortion type, AUDF set the frequency, AUDV set the volume. Write to those registers and the chip oscillated at your chosen frequency.

The Commodore 64 went further. Its SID chip — MOS Technology 6581, 1982 — had three independent oscillators, ADSR envelope generators, a programmable filter, and a ring modulator. Not a tone generator: a synthesizer, integrated into a single chip so an eight-bit computer could produce music that sounded like music.

The WWTBAM score — composed by Matthew Stiff for the 1998 ITV broadcast — is not SID output. It is a full orchestral recording, played back as a digital audio file. By 1998, PC sound cards had DACs — Digital-to-Analog Converters — that accepted digital samples and produced the analog signal a speaker needs. The path from our game code to the speaker is:

game code → fork → exec(aplay) → ALSA → sound card DAC → speaker

That is the same path the buzzer sat at the end of. The level of abstraction changed. The destination did not.

Who Wants to Be a Millionaire (2000) — Studio

The show's score was engineered in layers. Quiet strings in the opening questions. The arrangement thickened as the prize climbed. Past the first safe level, a different cue entirely — the kind that made the studio audience hold their breath. The music was not decorative. It told the audience how scared to be, question by question.

In g01a the game already knows its tier: level, safe_level, the prize strings in PRIZES[]. What it lacks is a mechanism to play audio while the game loop continues in the foreground. That mechanism is fork() and exec() — the same tools c05 used to build a multi-process pipeline.

A child process replaces itself with aplay. The parent continues running the game loop. When the tier changes, the parent sends SIGTERM to the child, reaps it with waitpid, and spawns a new child with the next WAV file. The code change is small. The effect is not.

The implementation pages add a music.c module to the g01a terminal game: the audio design and API, the start_music implementation using fork and execlp, the stop_music implementation using kill and waitpid, and the integration into the game loop. Start at Setup.

Implementation

Setup

Begin Implementation
  1. 0Setup
  2. 1The Audio Design
  3. 2Starting Music
  4. 3Stopping Music
  5. 4Integration
  6. 5Ship It