Files
music-video-gen/metabolism/README.md
T
Dejvino 16f4b4a805 Metabolism: add README
Project pitch, invariants, quick-start commands, layout, reference
songs, status, and how to read the coupling × residual report.
2026-10-24 08:27:56 +02:00

115 lines
4.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# metabolism
Songs as **substrate**. A music video generator whose outcome is grown, not
mixed: the track is not a parameter set the renderer modulates — it is the
world an agent ecology grows on. Same song + same seed ⇒ the same world,
bit for bit, frame for frame, preview identical to export.
```
song (PCM) ──► analyse ──► score · field · graph · laws ──► species ──► world ──► camera ──► frames
```
The full concept and rationale live in **[DESIGN.md](DESIGN.md)** — read it
before touching the code.
---
## The idea in one paragraph
Most visualisers *modulate* one fixed stage: the song turns knobs, and every
track ends up presenting the same toy in different clothes. Here the song
places the **food** (events land where the track's harmonies point), the **laws**
(each section changes the rules at its boundary), and the **species** (the
seed picks a rule set — built from tempo, noise, brightness and band
correlations — not a parameter vector). Two songs differ like two habitats
differ, not like two skins. `drone` grows a slow tonal weaver with heavy,
lasting ground markings; `runner` grows a fast noisy swarm with jittered
motion and thin ephemeral trails; `dusk` grows a crystalline, slow,
over-clustered world where the sparks reject the builders.
## Invariants
Everything is load-bearing to keep these true:
- **Persistence** — agents and their trails last seconds to tens of seconds.
- **Causality** — every visible event has an audible cause (hits are rings on
the ground) and a visible one.
- **Consequence** — the field is eaten, the trails accumulate; state at `t` is
made of state at `t−1`, never re-rolled.
- **Determinism** — no `Math.random`, no wall clock; tools and browser share
the same `Run`, so preview provably equals export.
---
## Quick start
Requires Node 20+ (for `node --test`) and your usual package manager.
```bash
npm install
# tests: analysis, determinism, world invariants, metrics sanity
npm test
# filmstrips: 12 frames per song, tiled
# (needs the flow-state test bank WAVs at ../flow-state/test/songs)
npm run strip # drone, runner, dusk
npm run strip -- --songs drone --cols 6 --rows 2 --out out
npm run strip -- --songs drone,runner,dusk --combined 1 # comparison sheet
# report: coupling × residual fitness + fingerprint divergence across songs/seeds
npm run report # prints a table, writes out/report.md + report.json
npm run report -- --songs drone,runner,dusk --seeds 999,12345,777777
```
Outputs land in `out/` (gitignored). `npm run dev` serves a Vite root once a
browser demo exists.
## Layout
```
DESIGN.md concept, invariants, build order
src/
audio/ WAV decode, radix-2 FFT, feature table, sectioning, onset score
song/ events (onsets → geometry), species (genome), palette, song assembly
sim/ wells (harmony→food) and world.js (the typed-array ecology)
render/ software framebuffer, trail composer, PNG encoder
camera.js event-reactive cutting, shot-size rhythm, drift-and-push
film.js Run: the single wire-up of sim → camera → framebuffer
metrics.js coupling, residual, fitness, fingerprint, divergence
rng.js seeded PRNGs (the only randomness in the repo)
tools/
load.js WAV → analysis → song (node-only)
strip.js filmstrip renderer
report.js system-level evaluation → markdown table
test/ node:test suites
```
## References
`tools/*` load the synthetic reference tracks from
`../flow-state/test/songs` (`drone`, `runner`, `dusk`) — three 120 s test
signals chosen to cover the axes the species reads: dark/tonal/beatless,
bright/noisy/fast, darkest/all-tonal/mid-tempo. Drop any WAV there and point
`--songs` at it; the species will derive from whatever the track actually says.
## Status
Currently a proof: the simulation is alive, the three songs are measurably
distinct (fingerprint divergence between songs ≫ divergence between seeds),
and the tools verify it. It is **not yet a film** — nothing is muxed to
audio/video, the renderer is a 480 p proof, and the demo page isn't built.
Next milestones: a browser demo, event-reactive cutting tuned to a full real
track, and video export. See DESIGN.md's *Build order & status*.
## Auditing what it grew
The report's **coupling × residual** fitness is the honest score: coupling is
how much the ecology answers the track; residual is the internal dynamics the
track does not explain. A pure visualiser scores ~0 (no residual); a random
walk scores ~0 (no coupling). The fingerprint (occupancy, clustering, trail
fill, class mix) tells you whether two songs grew *different* worlds without
anyone having to opine about it.
<!--- _Note: this README documents the design intent; the full argument for
every mechanism is in DESIGN.md._ -->