From e7ac31b5c80ad48d4b49895d2f885aabbb269015 Mon Sep 17 00:00:00 2001 From: claude Date: Tue, 14 Jul 2026 07:08:04 +0200 Subject: [PATCH] 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 Claude-Session: https://claude.ai/code/session_01MmdG9GqfSWCzts7AkDwRDh --- sfx-maker/README.md | 68 ++++++++++ sfx-maker/examples/blip.sfx | 9 ++ sfx-maker/examples/blip.wav | Bin 0 -> 7276 bytes sfx-maker/examples/coin.sfx | 10 ++ sfx-maker/examples/coin.wav | Bin 0 -> 29590 bytes sfx-maker/examples/explosion.sfx | 9 ++ sfx-maker/examples/explosion.wav | Bin 0 -> 62666 bytes sfx-maker/examples/hurt.sfx | 9 ++ sfx-maker/examples/hurt.wav | Bin 0 -> 16360 bytes sfx-maker/examples/jump.sfx | 9 ++ sfx-maker/examples/jump.wav | Bin 0 -> 23858 bytes sfx-maker/examples/laser.sfx | 10 ++ sfx-maker/examples/laser.wav | Bin 0 -> 15478 bytes sfx-maker/examples/powerup.sfx | 12 ++ sfx-maker/examples/powerup.wav | Bin 0 -> 45026 bytes sfx-maker/go.mod | 3 + sfx-maker/main.go | 212 +++++++++++++++++++++++++++++ sfx-maker/sfx/params.go | 223 +++++++++++++++++++++++++++++++ sfx-maker/sfx/presets.go | 114 ++++++++++++++++ sfx-maker/sfx/sfx_test.go | 164 +++++++++++++++++++++++ sfx-maker/sfx/synth.go | 122 +++++++++++++++++ sfx-maker/sfx/wav.go | 54 ++++++++ 22 files changed, 1028 insertions(+) create mode 100644 sfx-maker/README.md create mode 100644 sfx-maker/examples/blip.sfx create mode 100644 sfx-maker/examples/blip.wav create mode 100644 sfx-maker/examples/coin.sfx create mode 100644 sfx-maker/examples/coin.wav create mode 100644 sfx-maker/examples/explosion.sfx create mode 100644 sfx-maker/examples/explosion.wav create mode 100644 sfx-maker/examples/hurt.sfx create mode 100644 sfx-maker/examples/hurt.wav create mode 100644 sfx-maker/examples/jump.sfx create mode 100644 sfx-maker/examples/jump.wav create mode 100644 sfx-maker/examples/laser.sfx create mode 100644 sfx-maker/examples/laser.wav create mode 100644 sfx-maker/examples/powerup.sfx create mode 100644 sfx-maker/examples/powerup.wav create mode 100644 sfx-maker/go.mod create mode 100644 sfx-maker/main.go create mode 100644 sfx-maker/sfx/params.go create mode 100644 sfx-maker/sfx/presets.go create mode 100644 sfx-maker/sfx/sfx_test.go create mode 100644 sfx-maker/sfx/synth.go create mode 100644 sfx-maker/sfx/wav.go diff --git a/sfx-maker/README.md b/sfx-maker/README.md new file mode 100644 index 0000000..e4fa142 --- /dev/null +++ b/sfx-maker/README.md @@ -0,0 +1,68 @@ +# 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 + +```bash +# 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 + +```bash +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/`](examples/) contains all presets as `.sfx` + rendered `.wav`. diff --git a/sfx-maker/examples/blip.sfx b/sfx-maker/examples/blip.sfx new file mode 100644 index 0000000..31f3856 --- /dev/null +++ b/sfx-maker/examples/blip.sfx @@ -0,0 +1,9 @@ +# blip preset (seed 0) — edit freely, then: sfxc build examples/blip.sfx +sfx: blip +wave: square +volume: 0.7 +attack: 0.002 +sustain: 0.03 +decay: 0.05 +freq: 660 +duty: 0.4 diff --git a/sfx-maker/examples/blip.wav b/sfx-maker/examples/blip.wav new file mode 100644 index 0000000000000000000000000000000000000000..0878f1b906825efd7e7414e189ebb7016038a5a7 GIT binary patch literal 7276 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 literal 0 HcmV?d00001 diff --git a/sfx-maker/examples/coin.sfx b/sfx-maker/examples/coin.sfx new file mode 100644 index 0000000..073fc6a --- /dev/null +++ b/sfx-maker/examples/coin.sfx @@ -0,0 +1,10 @@ +# coin preset (seed 0) — edit freely, then: sfxc build examples/coin.sfx +sfx: coin +wave: square +volume: 0.7 +attack: 0.005 +sustain: 0.08 +decay: 0.25 +freq: 988 +arpeggio: 1.335 +arpeggio-time: 0.06 diff --git a/sfx-maker/examples/coin.wav b/sfx-maker/examples/coin.wav new file mode 100644 index 0000000000000000000000000000000000000000..6ca802f864192a069721a7235c1ef04600a62ec0 GIT binary patch literal 29590 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 H%$WZJ=5UKB literal 0 HcmV?d00001 diff --git a/sfx-maker/examples/explosion.sfx b/sfx-maker/examples/explosion.sfx new file mode 100644 index 0000000..20ba723 --- /dev/null +++ b/sfx-maker/examples/explosion.sfx @@ -0,0 +1,9 @@ +# explosion preset (seed 0) — edit freely, then: sfxc build examples/explosion.sfx +sfx: explosion +wave: noise +volume: 0.7 +attack: 0.01 +sustain: 0.15 +decay: 0.55 +freq-slide: -600 +lowpass: 2200 diff --git a/sfx-maker/examples/explosion.wav b/sfx-maker/examples/explosion.wav new file mode 100644 index 0000000000000000000000000000000000000000..9582dc54ae3fb6952eafd7b12d33215c72c58e7d GIT binary patch literal 62666 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 literal 0 HcmV?d00001 diff --git a/sfx-maker/examples/jump.sfx b/sfx-maker/examples/jump.sfx new file mode 100644 index 0000000..dc1d57c --- /dev/null +++ b/sfx-maker/examples/jump.sfx @@ -0,0 +1,9 @@ +# jump preset (seed 0) — edit freely, then: sfxc build examples/jump.sfx +sfx: jump +wave: square +volume: 0.7 +attack: 0.01 +sustain: 0.08 +decay: 0.18 +freq: 330 +freq-slide: 900 diff --git a/sfx-maker/examples/jump.wav b/sfx-maker/examples/jump.wav new file mode 100644 index 0000000000000000000000000000000000000000..0e37b14400e7d0aec70484d80cfcc590531209f3 GIT binary patch literal 23858 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 literal 0 HcmV?d00001 diff --git a/sfx-maker/examples/laser.sfx b/sfx-maker/examples/laser.sfx new file mode 100644 index 0000000..a7ecb79 --- /dev/null +++ b/sfx-maker/examples/laser.sfx @@ -0,0 +1,10 @@ +# laser preset (seed 0) — edit freely, then: sfxc build examples/laser.sfx +sfx: laser +wave: saw +volume: 0.7 +attack: 0.005 +sustain: 0.05 +decay: 0.12 +freq: 1400 +freq-slide: -6000 +highpass: 300 diff --git a/sfx-maker/examples/laser.wav b/sfx-maker/examples/laser.wav new file mode 100644 index 0000000000000000000000000000000000000000..62cffe95c0e2c7c3c0ee04c7a1368ee926f1f761 GIT binary patch literal 15478 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 j2RaU2gl4WMM%I literal 0 HcmV?d00001 diff --git a/sfx-maker/examples/powerup.sfx b/sfx-maker/examples/powerup.sfx new file mode 100644 index 0000000..18740ae --- /dev/null +++ b/sfx-maker/examples/powerup.sfx @@ -0,0 +1,12 @@ +# powerup preset (seed 0) — edit freely, then: sfxc build examples/powerup.sfx +sfx: powerup +wave: square +volume: 0.7 +attack: 0.01 +sustain: 0.25 +decay: 0.25 +freq: 220 +freq-slide: 700 +duty: 0.4 +vibrato-depth: 25 +vibrato-rate: 9 diff --git a/sfx-maker/examples/powerup.wav b/sfx-maker/examples/powerup.wav new file mode 100644 index 0000000000000000000000000000000000000000..f568e4aae8902e50380e46c3c65ae229388fe280 GIT binary patch literal 45026 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 Ddy><_ literal 0 HcmV?d00001 diff --git a/sfx-maker/go.mod b/sfx-maker/go.mod new file mode 100644 index 0000000..9de6866 --- /dev/null +++ b/sfx-maker/go.mod @@ -0,0 +1,3 @@ +module gitea.brasse-pc.eu/brasse/agent-tools/sfx-maker + +go 1.24 diff --git a/sfx-maker/main.go b/sfx-maker/main.go new file mode 100644 index 0000000..c0f21bb --- /dev/null +++ b/sfx-maker/main.go @@ -0,0 +1,212 @@ +// sfxc synthesizes retro game sound effects from .sfx text files +// (sfxr-style parameters) and writes 16-bit mono WAV. +package main + +import ( + "flag" + "fmt" + "os" + "path/filepath" + "strings" + + "gitea.brasse-pc.eu/brasse/agent-tools/sfx-maker/sfx" +) + +var version = "dev" + +const usage = `sfxc - sound effect maker for agents + +Usage: + sfxc build [-o out.wav] synthesize a .sfx file to WAV + sfxc preset [-o out.sfx|out.wav] [--seed n] + write a preset (editable .sfx text, + or straight to .wav) + sfxc info validate + print parameters + sfxc version + +Presets: blip, coin, explosion, hurt, jump, laser, powerup +--seed 0 (default) is the canonical sound; other seeds give variants. + +The .sfx format (all keys optional, '#' comments): + 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 + decay: 0.18 fade out + freq: 330 start pitch, Hz + freq-slide: 900 Hz per second (negative = falling) + duty: 0.5 square pulse width 0.05..0.95 + vibrato-depth: 25 Hz + vibrato-rate: 9 Hz + arpeggio: 1.335 pitch multiplier that kicks in at... + arpeggio-time: 0.06 ...this many seconds + lowpass: 2200 filter cutoff Hz + highpass: 300 filter cutoff Hz + sample-rate: 44100 + seed: 1 noise randomness (deterministic) + +Play the result with e.g.: mpv out.wav or aplay out.wav +` + +func main() { + if len(os.Args) < 2 { + fmt.Print(usage) + os.Exit(2) + } + switch os.Args[1] { + case "build": + cmdBuild(os.Args[2:]) + case "preset": + cmdPreset(os.Args[2:]) + case "info": + cmdInfo(os.Args[2:]) + case "version", "--version", "-v": + fmt.Println("sfxc", version) + case "help", "--help", "-h": + fmt.Print(usage) + default: + die("unknown command %q — run 'sfxc help'", os.Args[1]) + } +} + +// parseInterspersed lets flags appear before or after positional args. +func parseInterspersed(fs *flag.FlagSet, args []string) { + var flags, pos []string + for i := 0; i < len(args); i++ { + a := args[i] + if len(a) > 1 && a[0] == '-' { + flags = append(flags, a) + name := strings.TrimLeft(a, "-") + if !strings.Contains(name, "=") { + f := fs.Lookup(name) + isBool := false + if f != nil { + if bv, ok := f.Value.(interface{ IsBoolFlag() bool }); ok && bv.IsBoolFlag() { + isBool = true + } + } + if !isBool && i+1 < len(args) { + i++ + flags = append(flags, args[i]) + } + } + } else { + pos = append(pos, a) + } + } + fs.Parse(append(flags, pos...)) +} + +func writeWAVFile(path string, p *sfx.Params) error { + samples := sfx.Render(p) + f, err := os.Create(path) + if err != nil { + return err + } + defer f.Close() + if err := sfx.WriteWAV(f, samples, p.SampleRate); err != nil { + return err + } + return f.Close() +} + +func cmdBuild(args []string) { + fs := flag.NewFlagSet("build", flag.ExitOnError) + out := fs.String("o", "", "output .wav (default: input name with .wav)") + parseInterspersed(fs, args) + if fs.NArg() != 1 { + die("build takes exactly one .sfx file") + } + p, err := sfx.ParseFile(fs.Arg(0)) + if err != nil { + die("%v", err) + } + path := *out + if path == "" { + path = strings.TrimSuffix(fs.Arg(0), filepath.Ext(fs.Arg(0))) + ".wav" + } + if err := writeWAVFile(path, p); err != nil { + die("%v", err) + } + fmt.Printf("%s (%s, %.2fs, %d Hz)\n", path, p.Wave, p.Duration(), p.SampleRate) +} + +func cmdPreset(args []string) { + fs := flag.NewFlagSet("preset", flag.ExitOnError) + out := fs.String("o", "", "output file: .sfx (editable text) or .wav (rendered)") + seed := fs.Int64("seed", 0, "0 = canonical, other values = variants") + parseInterspersed(fs, args) + if fs.NArg() != 1 { + die("preset takes exactly one preset name (%s)", sfx.PresetNames()) + } + name := fs.Arg(0) + p, err := sfx.Preset(name, *seed) + if err != nil { + die("%v", err) + } + path := *out + if path == "" { + path = name + ".sfx" + } + switch strings.ToLower(filepath.Ext(path)) { + case ".wav": + if err := writeWAVFile(path, p); err != nil { + die("%v", err) + } + fmt.Printf("%s (%s preset, seed %d, %.2fs)\n", path, name, *seed, p.Duration()) + case ".sfx": + f, err := os.Create(path) + if err != nil { + die("%v", err) + } + defer f.Close() + comment := fmt.Sprintf("%s preset (seed %d) — edit freely, then: sfxc build %s", name, *seed, path) + if err := p.Write(f, comment); err != nil { + die("%v", err) + } + fmt.Printf("%s (%s preset, seed %d — edit then 'sfxc build')\n", path, name, *seed) + default: + die("-o must end in .sfx or .wav") + } +} + +func cmdInfo(args []string) { + if len(args) != 1 { + die("info takes exactly one .sfx file") + } + p, err := sfx.ParseFile(args[0]) + if err != nil { + die("%v", err) + } + fmt.Printf("sfx: %s\n", p.Name) + fmt.Printf("wave: %s\n", p.Wave) + fmt.Printf("duration: %.3fs (attack %.3g + sustain %.3g + decay %.3g)\n", + p.Duration(), p.Attack, p.Sustain, p.Decay) + if p.Wave != "noise" { + fmt.Printf("freq: %g Hz", p.Freq) + if p.FreqSlide != 0 { + fmt.Printf(" (slide %+g Hz/s)", p.FreqSlide) + } + fmt.Println() + } + if p.ArpFactor != 0 { + fmt.Printf("arpeggio: x%g at %gs\n", p.ArpFactor, p.ArpTime) + } + if p.VibratoDepth > 0 { + fmt.Printf("vibrato: ±%g Hz at %g Hz\n", p.VibratoDepth, p.VibratoRate) + } + if p.LowPass > 0 { + fmt.Printf("lowpass: %g Hz\n", p.LowPass) + } + if p.HighPass > 0 { + fmt.Printf("highpass: %g Hz\n", p.HighPass) + } + fmt.Printf("volume: %g\nsamplerate:%d\n", p.Volume, p.SampleRate) + fmt.Println("valid: yes") +} + +func die(format string, a ...any) { + fmt.Fprintf(os.Stderr, "sfxc: "+format+"\n", a...) + os.Exit(1) +} diff --git a/sfx-maker/sfx/params.go b/sfx-maker/sfx/params.go new file mode 100644 index 0000000..cbfc4f8 --- /dev/null +++ b/sfx-maker/sfx/params.go @@ -0,0 +1,223 @@ +// Package sfx synthesizes retro game sound effects (sfxr-style) from +// text parameter files and renders them to 16-bit mono WAV. +package sfx + +import ( + "bufio" + "fmt" + "io" + "os" + "path/filepath" + "strconv" + "strings" +) + +// Params describes one sound effect. Zero values mean "off" for the +// optional effects; Defaults() fills the required fields. +type Params struct { + Name string + Wave string // square | saw | sine | triangle | noise + + Volume float64 // 0..1 master gain + + // envelope, seconds + Attack float64 // 0 -> Volume + Sustain float64 // hold at Volume + Decay float64 // Volume -> 0 + + Freq float64 // start frequency, Hz + FreqSlide float64 // Hz per second, may be negative + FreqMin float64 // clamp; sound stops below this (default 20 Hz) + + Duty float64 // square wave duty cycle 0.05..0.95 (default 0.5) + + VibratoDepth float64 // Hz + VibratoRate float64 // Hz + + ArpFactor float64 // frequency multiplier applied at ArpTime (0 = off) + ArpTime float64 // seconds + + LowPass float64 // cutoff Hz (0 = off) + HighPass float64 // cutoff Hz (0 = off) + + SampleRate int // default 44100 + Seed int64 // noise seed (default 1) +} + +// Defaults returns a Params with sensible base values. +func Defaults() Params { + return Params{ + Wave: "square", + Volume: 0.7, + Attack: 0.01, + Sustain: 0.1, + Decay: 0.15, + Freq: 440, + FreqMin: 20, + Duty: 0.5, + SampleRate: 44100, + Seed: 1, + } +} + +// Duration is the total length of the sound in seconds. +func (p *Params) Duration() float64 { return p.Attack + p.Sustain + p.Decay } + +// Validate checks ranges and returns a helpful error. +func (p *Params) Validate() error { + switch p.Wave { + case "square", "saw", "sine", "triangle", "noise": + default: + return fmt.Errorf("wave %q must be square, saw, sine, triangle or noise", p.Wave) + } + if p.Volume < 0 || p.Volume > 1 { + return fmt.Errorf("volume %g out of range 0-1", p.Volume) + } + if p.Attack < 0 || p.Sustain < 0 || p.Decay < 0 { + return fmt.Errorf("attack/sustain/decay must be >= 0") + } + if p.Duration() <= 0 { + return fmt.Errorf("total duration is 0 — set attack, sustain and/or decay") + } + if p.Duration() > 10 { + return fmt.Errorf("total duration %.2fs is too long (max 10s)", p.Duration()) + } + if p.Wave != "noise" && (p.Freq <= 0 || p.Freq > 20000) { + return fmt.Errorf("freq %g out of range 1-20000 Hz", p.Freq) + } + if p.Duty < 0.05 || p.Duty > 0.95 { + return fmt.Errorf("duty %g out of range 0.05-0.95", p.Duty) + } + if p.SampleRate < 8000 || p.SampleRate > 96000 { + return fmt.Errorf("sample-rate %d out of range 8000-96000", p.SampleRate) + } + return nil +} + +// ParseFile reads a .sfx file; the name defaults to the file name. +func ParseFile(path string) (*Params, error) { + f, err := os.Open(path) + if err != nil { + return nil, err + } + defer f.Close() + p, err := Parse(f) + if err != nil { + return nil, fmt.Errorf("%s: %w", path, err) + } + if p.Name == "" { + p.Name = strings.TrimSuffix(filepath.Base(path), filepath.Ext(path)) + } + return p, nil +} + +// Parse reads the .sfx text format: one "key: value" per line, +// '#' comments. Unknown keys are errors so typos surface immediately. +func Parse(r io.Reader) (*Params, error) { + p := Defaults() + sc := bufio.NewScanner(r) + lineNo := 0 + for sc.Scan() { + lineNo++ + line := strings.TrimSpace(sc.Text()) + if line == "" || strings.HasPrefix(line, "#") { + continue + } + i := strings.Index(line, ":") + if i < 0 { + return nil, fmt.Errorf("line %d: want 'key: value', got %q", lineNo, line) + } + key := strings.ToLower(strings.TrimSpace(line[:i])) + val := strings.TrimSpace(line[i+1:]) + if j := strings.Index(val, " #"); j >= 0 { // trailing comment + val = strings.TrimSpace(val[:j]) + } + var err error + switch key { + case "sfx", "name": + p.Name = val + case "wave": + p.Wave = strings.ToLower(val) + case "volume": + p.Volume, err = strconv.ParseFloat(val, 64) + case "attack": + p.Attack, err = strconv.ParseFloat(val, 64) + case "sustain": + p.Sustain, err = strconv.ParseFloat(val, 64) + case "decay": + p.Decay, err = strconv.ParseFloat(val, 64) + case "freq": + p.Freq, err = strconv.ParseFloat(val, 64) + case "freq-slide": + p.FreqSlide, err = strconv.ParseFloat(val, 64) + case "freq-min": + p.FreqMin, err = strconv.ParseFloat(val, 64) + case "duty": + p.Duty, err = strconv.ParseFloat(val, 64) + case "vibrato-depth": + p.VibratoDepth, err = strconv.ParseFloat(val, 64) + case "vibrato-rate": + p.VibratoRate, err = strconv.ParseFloat(val, 64) + case "arpeggio": + p.ArpFactor, err = strconv.ParseFloat(val, 64) + case "arpeggio-time": + p.ArpTime, err = strconv.ParseFloat(val, 64) + case "lowpass": + p.LowPass, err = strconv.ParseFloat(val, 64) + case "highpass": + p.HighPass, err = strconv.ParseFloat(val, 64) + case "sample-rate": + p.SampleRate, err = strconv.Atoi(val) + case "seed": + p.Seed, err = strconv.ParseInt(val, 10, 64) + default: + return nil, fmt.Errorf("line %d: unknown key %q", lineNo, key) + } + if err != nil { + return nil, fmt.Errorf("line %d: %s: bad value %q", lineNo, key, val) + } + } + if err := sc.Err(); err != nil { + return nil, err + } + if err := p.Validate(); err != nil { + return nil, err + } + return &p, nil +} + +// Write renders the params back to the .sfx text format (used by the +// preset generator so agents get an editable file). +func (p *Params) Write(w io.Writer, comment string) error { + bw := bufio.NewWriter(w) + if comment != "" { + fmt.Fprintf(bw, "# %s\n", comment) + } + fmt.Fprintf(bw, "sfx: %s\nwave: %s\nvolume: %g\n", p.Name, p.Wave, p.Volume) + fmt.Fprintf(bw, "attack: %g\nsustain: %g\ndecay: %g\n", p.Attack, p.Sustain, p.Decay) + if p.Wave != "noise" { + fmt.Fprintf(bw, "freq: %g\n", p.Freq) + } + if p.FreqSlide != 0 { + fmt.Fprintf(bw, "freq-slide: %g\n", p.FreqSlide) + } + if p.Wave == "square" && p.Duty != 0.5 { + fmt.Fprintf(bw, "duty: %g\n", p.Duty) + } + if p.VibratoDepth > 0 && p.VibratoRate > 0 { + fmt.Fprintf(bw, "vibrato-depth: %g\nvibrato-rate: %g\n", p.VibratoDepth, p.VibratoRate) + } + if p.ArpFactor != 0 { + fmt.Fprintf(bw, "arpeggio: %g\narpeggio-time: %g\n", p.ArpFactor, p.ArpTime) + } + if p.LowPass > 0 { + fmt.Fprintf(bw, "lowpass: %g\n", p.LowPass) + } + if p.HighPass > 0 { + fmt.Fprintf(bw, "highpass: %g\n", p.HighPass) + } + if p.Seed != 1 { + fmt.Fprintf(bw, "seed: %d\n", p.Seed) + } + return bw.Flush() +} diff --git a/sfx-maker/sfx/presets.go b/sfx-maker/sfx/presets.go new file mode 100644 index 0000000..b085596 --- /dev/null +++ b/sfx-maker/sfx/presets.go @@ -0,0 +1,114 @@ +package sfx + +import ( + "fmt" + "math/rand" + "sort" +) + +// Preset returns ready-made parameters for classic game sounds. +// seed 0 gives the canonical version; other seeds vary it slightly so +// agents can generate alternatives ("give me three coin variants"). +func Preset(name string, seed int64) (*Params, error) { + p := Defaults() + p.Name = name + switch name { + case "jump": + p.Wave = "square" + p.Duty = 0.5 + p.Freq = 330 + p.FreqSlide = 900 + p.Attack = 0.01 + p.Sustain = 0.08 + p.Decay = 0.18 + case "coin": + p.Wave = "square" + p.Duty = 0.5 + p.Freq = 988 + p.ArpFactor = 1.335 // up a fourth: B5 -> E6 + p.ArpTime = 0.06 + p.Attack = 0.005 + p.Sustain = 0.08 + p.Decay = 0.25 + case "laser": + p.Wave = "saw" + p.Freq = 1400 + p.FreqSlide = -6000 + p.Attack = 0.005 + p.Sustain = 0.05 + p.Decay = 0.12 + p.HighPass = 300 + case "explosion": + p.Wave = "noise" + p.Freq = 900 + p.FreqSlide = -600 + p.Attack = 0.01 + p.Sustain = 0.15 + p.Decay = 0.55 + p.LowPass = 2200 + case "hurt": + p.Wave = "saw" + p.Freq = 300 + p.FreqSlide = -700 + p.Attack = 0.005 + p.Sustain = 0.04 + p.Decay = 0.14 + case "powerup": + p.Wave = "square" + p.Duty = 0.4 + p.Freq = 220 + p.FreqSlide = 700 + p.VibratoDepth = 25 + p.VibratoRate = 9 + p.Attack = 0.01 + p.Sustain = 0.25 + p.Decay = 0.25 + case "blip": + p.Wave = "square" + p.Duty = 0.4 + p.Freq = 660 + p.Attack = 0.002 + p.Sustain = 0.03 + p.Decay = 0.05 + default: + return nil, fmt.Errorf("unknown preset %q (available: %s)", name, PresetNames()) + } + if seed != 0 { + vary(&p, seed) + } + if err := p.Validate(); err != nil { + return nil, fmt.Errorf("preset %s (seed %d): %w", name, seed, err) + } + return &p, nil +} + +// vary nudges the tonal parameters deterministically from the seed. +func vary(p *Params, seed int64) { + rng := rand.New(rand.NewSource(seed)) + jitter := func(v, amount float64) float64 { + return v * (1 + amount*(rng.Float64()*2-1)) + } + p.Freq = jitter(p.Freq, 0.15) + p.FreqSlide = jitter(p.FreqSlide, 0.25) + p.Sustain = jitter(p.Sustain, 0.2) + p.Decay = jitter(p.Decay, 0.2) + if p.ArpFactor != 0 { + p.ArpFactor = jitter(p.ArpFactor, 0.05) + } + p.Seed = seed // noise variation too +} + +var presetNames = []string{"blip", "coin", "explosion", "hurt", "jump", "laser", "powerup"} + +// PresetNames lists the available presets, sorted. +func PresetNames() string { + sort.Strings(presetNames) + out := "" + for i, n := range presetNames { + if i > 0 { + out += ", " + } + out += n + } + return out +} diff --git a/sfx-maker/sfx/sfx_test.go b/sfx-maker/sfx/sfx_test.go new file mode 100644 index 0000000..ac3576a --- /dev/null +++ b/sfx-maker/sfx/sfx_test.go @@ -0,0 +1,164 @@ +package sfx + +import ( + "bytes" + "math" + "strings" + "testing" +) + +func TestParseAndValidate(t *testing.T) { + src := ` +# a jump +sfx: jump +wave: square +freq: 330 +freq-slide: 900 +attack: 0.01 +sustain: 0.08 +decay: 0.18 +duty: 0.4 +` + p, err := Parse(strings.NewReader(src)) + if err != nil { + t.Fatal(err) + } + if p.Name != "jump" || p.Wave != "square" || p.Freq != 330 || p.Duty != 0.4 { + t.Errorf("parsed wrong: %+v", p) + } + if math.Abs(p.Duration()-0.27) > 1e-9 { + t.Errorf("duration = %g, want 0.27", p.Duration()) + } +} + +func TestParseErrors(t *testing.T) { + cases := map[string]string{ + "unknown key": "wat: 3\n", + "bad wave": "wave: wobble\n", + "bad value": "freq: abc\n", + "zero length": "attack: 0\nsustain: 0\ndecay: 0\n", + "volume range": "volume: 2\n", + "duty range": "duty: 0.99\n", + } + for name, src := range cases { + if _, err := Parse(strings.NewReader(src)); err == nil { + t.Errorf("%s: expected error", name) + } + } +} + +func TestRenderBasics(t *testing.T) { + p := Defaults() + p.Wave = "sine" + p.Attack, p.Sustain, p.Decay = 0.01, 0.05, 0.05 + samples := Render(&p) + want := int(0.11 * 44100) + if len(samples) != want { + t.Errorf("samples = %d, want %d", len(samples), want) + } + var peak float64 + for _, s := range samples { + if math.Abs(s) > peak { + peak = math.Abs(s) + } + if s > 1 || s < -1 { + t.Fatalf("sample %g out of range", s) + } + } + if peak < 0.5 { + t.Errorf("peak %g suspiciously quiet", peak) + } + // end of decay should be silent-ish + tail := samples[len(samples)-10:] + for _, s := range tail { + if math.Abs(s) > 0.1 { + t.Errorf("tail sample %g not decayed", s) + } + } +} + +func TestRenderDeterministic(t *testing.T) { + p := Defaults() + p.Wave = "noise" + p.Seed = 42 + a := Render(&p) + b := Render(&p) + for i := range a { + if a[i] != b[i] { + t.Fatalf("noise render not deterministic at sample %d", i) + } + } +} + +func TestAllWavesAndPresets(t *testing.T) { + for _, w := range []string{"square", "saw", "sine", "triangle", "noise"} { + p := Defaults() + p.Wave = w + if s := Render(&p); len(s) == 0 { + t.Errorf("wave %s rendered nothing", w) + } + } + for _, name := range []string{"blip", "coin", "explosion", "hurt", "jump", "laser", "powerup"} { + p, err := Preset(name, 0) + if err != nil { + t.Errorf("preset %s: %v", name, err) + continue + } + s := Render(p) + var sum float64 + for _, v := range s { + sum += v * v + } + rms := math.Sqrt(sum / float64(len(s))) + if rms < 0.01 { + t.Errorf("preset %s is nearly silent (rms %g)", name, rms) + } + // variants stay valid + if _, err := Preset(name, 7); err != nil { + t.Errorf("preset %s seed 7: %v", name, err) + } + } + if _, err := Preset("nope", 0); err == nil { + t.Error("unknown preset should error") + } +} + +func TestWAVRoundTrip(t *testing.T) { + p := Defaults() + samples := Render(&p) + var buf bytes.Buffer + if err := WriteWAV(&buf, samples, p.SampleRate); err != nil { + t.Fatal(err) + } + sr, bits, ch, dataBytes, err := ReadWAVHeader(&buf) + if err != nil { + t.Fatal(err) + } + if sr != 44100 || bits != 16 || ch != 1 { + t.Errorf("header: sr=%d bits=%d ch=%d", sr, bits, ch) + } + if dataBytes != len(samples)*2 { + t.Errorf("dataBytes = %d, want %d", dataBytes, len(samples)*2) + } + if buf.Len() != dataBytes { + t.Errorf("body length %d != declared %d", buf.Len(), dataBytes) + } +} + +func TestParamsWriteRoundTrip(t *testing.T) { + p, err := Preset("coin", 3) + if err != nil { + t.Fatal(err) + } + var buf bytes.Buffer + if err := p.Write(&buf, "test"); err != nil { + t.Fatal(err) + } + back, err := Parse(&buf) + if err != nil { + t.Fatalf("re-parse of written .sfx failed: %v\n%s", err, buf.String()) + } + if back.Freq != p.Freq || back.ArpFactor != p.ArpFactor || back.Seed != p.Seed { + t.Errorf("roundtrip mismatch: %+v vs %+v", back, p) + } +} diff --git a/sfx-maker/sfx/synth.go b/sfx-maker/sfx/synth.go new file mode 100644 index 0000000..e739f32 --- /dev/null +++ b/sfx-maker/sfx/synth.go @@ -0,0 +1,122 @@ +package sfx + +import ( + "math" + "math/rand" +) + +// Render synthesizes the effect into float64 samples in [-1, 1]. +func Render(p *Params) []float64 { + sr := float64(p.SampleRate) + n := int(p.Duration() * sr) + out := make([]float64, n) + rng := rand.New(rand.NewSource(p.Seed)) + + phase := 0.0 + noiseVal := 0.0 + noiseCounter := 0.0 + + // one-pole filter states + lpState := 0.0 + hpState := 0.0 + hpPrevIn := 0.0 + dt := 1 / sr + lpAlpha := 0.0 + if p.LowPass > 0 { + rc := 1 / (2 * math.Pi * p.LowPass) + lpAlpha = dt / (rc + dt) + } + hpAlpha := 0.0 + if p.HighPass > 0 { + rc := 1 / (2 * math.Pi * p.HighPass) + hpAlpha = rc / (rc + dt) + } + + for i := 0; i < n; i++ { + t := float64(i) / sr + + f := p.Freq + p.FreqSlide*t + if p.ArpFactor != 0 && p.ArpTime > 0 && t >= p.ArpTime { + f *= p.ArpFactor + } + if p.VibratoDepth > 0 && p.VibratoRate > 0 { + f += p.VibratoDepth * math.Sin(2*math.Pi*p.VibratoRate*t) + } + if f < p.FreqMin { + f = p.FreqMin + } + + var s float64 + if p.Wave == "noise" { + // pitched noise: new random value f*4 times per second + noiseCounter += f * 4 * dt + if noiseCounter >= 1 || i == 0 { + noiseCounter = math.Mod(noiseCounter, 1) + noiseVal = rng.Float64()*2 - 1 + } + s = noiseVal + } else { + phase += f * dt + ph := math.Mod(phase, 1) + switch p.Wave { + case "square": + if ph < p.Duty { + s = 1 + } else { + s = -1 + } + case "saw": + s = 2*ph - 1 + case "triangle": + if ph < 0.5 { + s = 4*ph - 1 + } else { + s = 3 - 4*ph + } + case "sine": + s = math.Sin(2 * math.Pi * ph) + } + } + + s *= envelope(p, t) + + if lpAlpha > 0 { + lpState += lpAlpha * (s - lpState) + s = lpState + } + if hpAlpha > 0 { + hpState = hpAlpha * (hpState + s - hpPrevIn) + hpPrevIn = s + s = hpState + } + + s *= p.Volume + if s > 1 { + s = 1 + } else if s < -1 { + s = -1 + } + out[i] = s + } + return out +} + +// envelope is a linear attack / sustain / decay gain in 0..1. +func envelope(p *Params, t float64) float64 { + switch { + case t < p.Attack: + return t / p.Attack + case t < p.Attack+p.Sustain: + return 1 + default: + d := t - p.Attack - p.Sustain + if p.Decay <= 0 { + return 0 + } + g := 1 - d/p.Decay + if g < 0 { + g = 0 + } + return g + } +} diff --git a/sfx-maker/sfx/wav.go b/sfx-maker/sfx/wav.go new file mode 100644 index 0000000..704e49a --- /dev/null +++ b/sfx-maker/sfx/wav.go @@ -0,0 +1,54 @@ +package sfx + +import ( + "encoding/binary" + "fmt" + "io" + "math" +) + +// WriteWAV encodes samples ([-1,1] floats) as a 16-bit mono PCM WAV. +func WriteWAV(w io.Writer, samples []float64, sampleRate int) error { + dataLen := len(samples) * 2 + var hdr [44]byte + copy(hdr[0:4], "RIFF") + binary.LittleEndian.PutUint32(hdr[4:8], uint32(36+dataLen)) + copy(hdr[8:12], "WAVE") + copy(hdr[12:16], "fmt ") + binary.LittleEndian.PutUint32(hdr[16:20], 16) // fmt chunk size + binary.LittleEndian.PutUint16(hdr[20:22], 1) // PCM + binary.LittleEndian.PutUint16(hdr[22:24], 1) // mono + binary.LittleEndian.PutUint32(hdr[24:28], uint32(sampleRate)) // sample rate + binary.LittleEndian.PutUint32(hdr[28:32], uint32(sampleRate*2)) // byte rate + binary.LittleEndian.PutUint16(hdr[32:34], 2) // block align + binary.LittleEndian.PutUint16(hdr[34:36], 16) // bits per sample + copy(hdr[36:40], "data") + binary.LittleEndian.PutUint32(hdr[40:44], uint32(dataLen)) + if _, err := w.Write(hdr[:]); err != nil { + return err + } + buf := make([]byte, 2*len(samples)) + for i, s := range samples { + v := int16(math.Round(s * 32767)) + binary.LittleEndian.PutUint16(buf[i*2:], uint16(v)) + } + _, err := w.Write(buf) + return err +} + +// ReadWAVHeader sanity-parses a WAV header (used in tests and info). +func ReadWAVHeader(r io.Reader) (sampleRate, bits, channels, dataBytes int, err error) { + var hdr [44]byte + if _, err = io.ReadFull(r, hdr[:]); err != nil { + return + } + if string(hdr[0:4]) != "RIFF" || string(hdr[8:12]) != "WAVE" { + err = fmt.Errorf("not a WAV file") + return + } + channels = int(binary.LittleEndian.Uint16(hdr[22:24])) + sampleRate = int(binary.LittleEndian.Uint32(hdr[24:28])) + bits = int(binary.LittleEndian.Uint16(hdr[34:36])) + dataBytes = int(binary.LittleEndian.Uint32(hdr[40:44])) + return +}