Files
agent-tools/sfx-maker
claude e7ac31b5c8 sfx-maker: sfxc - sfxr-style .sfx text presets -> 16-bit WAV synthesis
- waves: square (duty), saw, sine, triangle, pitched noise (seeded, deterministic)
- envelope attack/sustain/decay, freq slide, vibrato, arpeggio jump,
  one-pole low/high-pass filters, clamped output
- presets blip/coin/explosion/hurt/jump/laser/powerup with seeded variants;
  preset writes editable .sfx or renders .wav directly
- go tests: parse/validate, determinism, per-preset RMS, WAV header roundtrip

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MmdG9GqfSWCzts7AkDwRDh
2026-07-14 07:08:04 +02:00
..

sfx-maker (sfxc)

Synthesizes retro game sound effects (sfxr-style) from .sfx text files and writes 16-bit mono WAV. Sound design becomes text an agent can read, tweak and reason about — no DAW needed. Go, zero dependencies, single static binary.

Build

# Arch/Garuda: sudo pacman -S go
cd sfx-maker
go build -o build/sfxc .        # or the VS Code task "build sfx-maker"
go test ./...

Quick start

sfxc preset jump -o jump.sfx      # editable text preset
sfxc build jump.sfx               # -> jump.wav
mpv jump.wav                      # listen (or aplay/ffplay)

sfxc preset coin -o coin.wav      # straight to WAV
sfxc preset coin --seed 3 -o coin3.wav    # deterministic variant
sfxc info laser.sfx               # validate + summary

Presets: blip, coin, explosion, hurt, jump, laser, powerup. --seed 0 is the canonical sound; any other seed nudges pitch/length deterministically — ask for three seeds, keep the one that sounds best.

The .sfx format

# comment
sfx: jump            name
wave: square         square | saw | sine | triangle | noise
volume: 0.7          0..1
attack: 0.01         seconds: fade in
sustain: 0.08        hold at full volume
decay: 0.18          fade out (total length = a+s+d, max 10 s)
freq: 330            start pitch, Hz
freq-slide: 900      Hz/second (positive = rising, negative = falling)
duty: 0.5            square pulse width 0.05..0.95 (thinner = buzzier)
vibrato-depth: 25    pitch wobble, Hz
vibrato-rate: 9      wobbles per second
arpeggio: 1.335      multiply pitch by this...
arpeggio-time: 0.06  ...after this many seconds (classic coin blip)
lowpass: 2200        cutoff Hz (muffle: explosions, thuds)
highpass: 300        cutoff Hz (thin out: lasers, clicks)
sample-rate: 44100   8000-96000
seed: 1              noise randomness — same seed = same sound

Unknown keys are errors, so typos surface immediately. Everything is deterministic: same file → byte-identical WAV.

Recipe intuition for agents

  • Jump: square wave + rising freq-slide.
  • Coin/pickup: square + arpeggio > 1 shortly after the start.
  • Laser: saw + steep negative freq-slide + highpass.
  • Explosion: noise + lowpass ~2 kHz + long decay.
  • Hurt: saw, low pitch, quick fall.
  • Power-up: rising slide + vibrato.

examples/ contains all presets as .sfx + rendered .wav.