gen-audio: prompt assembly system (sonic palette + category templates + asset descriptions), SAO generation workflow, post-processing pipeline, manual synthesis guide for sub-200ms insert-tech sounds. Rename asset-gen to gen-image for consistent gen-* naming. Add audio connector permissions to settings. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
6.8 KiB
name, description
| name | description |
|---|---|
| gen-audio | Generate audio assets for The Settled Reach using the Stable Audio Open API (self-hosted Gradio app at tower-of-joy:11500). Use when generating any game audio: ambient loops, SFX, UI sounds, monologue chimes, footsteps, or any sound asset from docs/assets/audio/. Also use when the user asks about audio generation, sound design pipeline, or audio asset iteration. Triggers on: "generate audio", "make sounds", "create ambient", "audio pipeline", "generate sfx", "stable audio", "gen audio", "sound design". |
Audio Generation — The Settled Reach
Generate sonically consistent audio assets using the Stable Audio Open API via
wrapper scripts at db/connectors/audio-*.
Asset descriptions, filenames, bus routing, and design intent are documented in
docs/assets/audio/. This skill provides the prompt system, generation
workflow, and quality validation.
API Access
Never call the API directly. Use the wrapper scripts:
# Check API health
db/connectors/audio-health
# Generate audio
db/connectors/audio-generate "prompt text" \
--duration 10 \
--steps 100 \
--cfg 7 \
--output path/to/output.wav \
--timeout 600
Parameters
| Parameter | Default | Range | Notes |
|---|---|---|---|
--duration |
10 | 0-47s | Max 47s per generation. For longer loops, generate 45s with crossfade overlap. |
--steps |
100 | 10-200 | More steps = better quality, slower. Use 50 for quick previews, 100-150 for final. |
--cfg |
7 | 1-15 | Classifier-free guidance. Higher = more prompt-adherent but less natural. 5-9 is the sweet spot. |
--output |
auto | — | Output file path. Auto-names from prompt if omitted. |
--timeout |
600 | — | Max wait in seconds. Generation can take 2-5 minutes on 11GB VRAM. |
Critical Constraints
- NEVER parallelize requests. The server has 11GB VRAM and runs one generation at a time. Always wait for a generation to complete before starting the next. Sequential only.
- Generation takes 2-5 minutes per clip depending on duration and steps. Be patient. The timeout default (600s) is generous.
- Max 47 seconds per generation. For 60-90s ambient loops, generate 45s clips and crossfade-stitch in post-processing.
- Output is WAV at 44.1kHz stereo. Convert to .ogg for Godot import:
ffmpeg -i input.wav -c:a libvorbis -q:a 6 output.ogg
Prompt Assembly
Every generation uses three parts:
[SONIC FAMILY PREFIX] + [CATEGORY TEMPLATE] + [ASSET DESCRIPTION from docs/assets/audio/]
Never call the API with just the asset description. Always prepend the sonic family prefix and matching category template.
- Sonic palette and families: Read
references/sonic-palette.md - Category templates: Read
references/category-templates.mdand match by asset type (ambient, sfx, ui) - Asset description: Look up the specific asset in
docs/assets/audio/{category}.md
Single Asset Workflow
- Find the asset in
docs/assets/audio/{ambient,sfx,ui}.md— note filename, duration, bus, method, and design intent. - Read
references/sonic-palette.mdfor the sonic family prefix. - Read
references/category-templates.mdfor the matching template. - Assemble the full prompt.
- Run
db/connectors/audio-healthto verify the API is up. - Run
db/connectors/audio-generatewith the assembled prompt. One request at a time. Wait for completion. - Listen to the output (or describe it based on file size/duration).
- If acceptable, convert to .ogg and place in
client/assets/audio/. - Update the asset status in
docs/assets/audio/{category}.md.
Iteration Workflow
For each asset, generate 4-6 candidates:
- Generate candidates — vary the prompt slightly (add/remove descriptors, adjust CFG between 5-9). Run each generation sequentially — never in parallel.
- Solo test — does each candidate sound right alone?
- Stack test — play the candidate alongside other layers. Does it mask or clash?
- Fatigue test (loops only) — can you listen for 5+ minutes without a jarring repeat?
- Close-your-eyes test — does it create a mental image or sensation?
- Select the best candidate, trim, normalize, convert.
Post-Processing
After selecting the best generation:
# Trim silence from start/end
ffmpeg -i input.wav -af "silenceremove=start_periods=1:start_silence=0.1:start_threshold=-50dB,areverse,silenceremove=start_periods=1:start_silence=0.1:start_threshold=-50dB,areverse" trimmed.wav
# LUFS normalize to -16 LUFS (broadcast standard, good for game audio)
ffmpeg -i trimmed.wav -af loudnorm=I=-16:LRA=11:TP=-1 normalized.wav
# Convert to .ogg for Godot
ffmpeg -i normalized.wav -c:a libvorbis -q:a 6 output.ogg
# For loops: verify loop point
ffplay -loop 0 output.ogg
For ambient loops, create crossfade overlap:
# Create a 45s loop with 3s crossfade overlap
# (manual: export 48s, crossfade first 3s with last 3s in Audacity)
Manual Synthesis (Insert-Tech Sounds)
For sounds under 200ms (cursor hover, weapon aim), Stable Audio Open cannot produce meaningful output. Use manual synthesis instead:
# Example: 50ms cursor hover tick
import numpy as np
import wave
sr = 44100
duration = 0.05 # 50ms
t = np.linspace(0, duration, int(sr * duration), endpoint=False)
freq = 3200 # Hz
signal = np.sin(2 * np.pi * freq * t)
envelope = np.exp(-t * 80) # exponential decay
audio = (signal * envelope * 32767).astype(np.int16)
with wave.open("cursor_hover.wav", "w") as f:
f.setnchannels(1)
f.setsampwidth(2)
f.setframerate(sr)
f.writeframes(audio.tobytes())
Quality Checklist
After generating, verify:
- Sound matches the sonic family (insert-tech = synthetic/precise, organic = warm/natural)
- Frequency range doesn't mask other layers (check docs/assets/audio/palette.md)
- Duration matches spec
- No unwanted artifacts (clicks, pops, digital noise at start/end)
- Loop point is clean (ambient loops only)
- Volume sits well relative to other assets (LUFS normalized)
- Passes the close-your-eyes test
File Placement
Generated assets go to client/assets/audio/ with exact filenames from the
asset docs:
client/assets/audio/
amb_station_base.ogg # Ambient bus
amb_workplace_layer.ogg # Ambient bus
amb_bar_layer.ogg # Ambient bus
amb_corridor_layer.ogg # Ambient bus
sfx_footstep_metal.ogg # Player Actions bus
sfx_footstep_metal_run.ogg # Player Actions bus
cursor_hover.ogg # UI Sounds bus
implant_open.ogg # UI Sounds bus
fog_recognition.ogg # UI Sounds bus
weapon_aim.ogg # UI Sounds bus
sfx_monologue_chime.ogg # UI Sounds bus
sfx_monologue_chime_urgent.ogg # UI Sounds bus
AudioManager discovers these by directory scan — filenames must match exactly.