# Soundtrack — industrial metal loop Endless survival loop played from the first frame, at `-11 dB`, independent of gameplay state. ## Source Generated locally (2026-10-10) with **YuE2-3B Q8_0** through the audio.cpp CUDA build for the Tesla V100 (`~/dev/audio.cpp`, `cmake -DCMAKE_CUDA_ARCHITECTURES=70`), seed 31337, 16 steps, `cot=melody` + an external ABC score written for this track (K:Em Phrygian, `Q:1/4=168`, 96 bars; the model rendered it at a perceived 112.5 BPM). Style prompt: instrumental industrial metal, Nine Inch Nails meets the Quake 2 soundtrack, machine drums, palm-muted downtuned guitars, atonal synth stabs, no vocals. `--lyrics "[instrumental]"` does **not** suppress singing (verified: male shouts 0:52-1:17 and 1:37-2:35). The instrumental was therefore obtained by **HTDemucs** vocal removal (`--task sep --family htdemucs`, input resampled to 44.1 kHz, RTF 0.049) and remixed as `drums + bass + other`. Working files: `~/yue2-out/zombie-industrial/`. ## Loop construction The track has a structural repeat (bars 24-30 ≈ 46-52, spectral similarity 0.95), so the loop splices at matching material instead of cutting arbitrarily: - region 51.37 s → 108.97 s of the instrumental master = 27 bars (bar = 2.1333 s, 112.5 BPM); - rotation by one tail segment plus a **0.60 s** equal-power crossfade; - result: **57.60 s**, seam dip ≤ 1.6 dB in 20 ms windows, sample step 0.04 (inaudible); - perceptual check on a 3 s + 3 s excerpt around the seam: no click, no level hole, natural continuation. A longer variant (132 s) was rejected: its crossfade cancels (a -48 dB hole) because the two overlapped sections are out of phase. ## Asset and import `assets/audio/music/zombie_industrial_loop.ogg` — Ogg Vorbis q6, 48 kHz stereo, 1.0 MB, -14 LUFS / -1.0 dBTP. Import: `loop=true`, `bpm=112.5`, `beat_count=108`, `bar_beats=4`. The Web staging step (`tools/prepare_web.py`) copies the asset but ignores `*.import`, and the staging import regenerates it with `loop=false`. `main.gd` therefore sets `stream.loop = true` at runtime: keep that line, it is what makes the browser build loop. ## Runtime wiring `scripts/main.gd`: `_setup_music()` creates the `AudioStreamPlayer` named `Music` (group `music`), `_start_music()` starts it once, `_restart_music()` restarts it if the loop flag is ever absent. On Web the start is deferred to the click that captures the mouse, because browsers only allow audio after a user gesture. Music keeps playing while the player is dead; `R` reloads the scene and the track restarts with it. ## Verification ``` godot --headless --path . --script res://tools/test_music.gd godot --display-driver headless --audio-driver PulseAudio --path . --script res://tools/test_music.gd godot --headless --path . -- --smoke ``` Both runs PASS: node present, `loop=true`, length 57.60 s, volume -11 dB, playback advancing (confirmed on the real PulseAudio device, not only the Dummy driver), music still playing after player death. Grenade, wave, death and damage-feedback tests also pass unchanged. ## License YuE2-3B weights are **CC BY-NC 4.0** (non-commercial): this track is for personal/experimental use. It is an AI-generated render, not a recording of a third-party work.