Metabolism: song as substrate, ecology grown from the track
A new top-level section building the metabolism concept: the track supplies the food field, event impulses and per-section laws; the seed picks the species (a rule set, not a parameter vector). Same song + seed => bit-identical frames; different songs => different worlds. - analysis: single FFT pass -> per-frame feature table; score (onsets folded into world geometry via voice ring + pitch-class sector), wells (food placed by the harmony), graph (band correlations -> interaction matrix), laws (per-section regimes) - sim: typed-array world, 3 castes (builder/orbit, forager/commute, spark/orbit-wide) with causality rings, persistence trails, consequence field; fully deterministic - lens: software framebuffer renderer (PNG in node, ImageData in browser) + event-reactive camera (cuts on activity change, alternating shot sizes, drift-and-push) - metrics: coupling x residual fitness (not per-frame descriptors) plus a grown-structure fingerprint; report + strip tools; 15 tests green - DESIGN.md captures the concept, invariants and build order 3 reference test signals (drone/runner/dusk) grow measurably distinct worlds while seeds of one song stay in the same biome.
This commit is contained in:
@@ -0,0 +1,16 @@
|
||||
// Node-only: WAV -> analysis -> song. The browser does the same with a
|
||||
// decoded AudioBuffer; this keeps the tools honest about the same pipeline.
|
||||
|
||||
import { readFileSync } from 'node:fs';
|
||||
import { decodeWav, mono } from '../src/audio/wav.js';
|
||||
import { analyse } from '../src/audio/analyse.js';
|
||||
import { buildSong } from '../src/song/song.js';
|
||||
|
||||
export function loadSong(path, { fps = 30, seed = 12345 } = {}) {
|
||||
const wav = decodeWav(readFileSync(path));
|
||||
if (!wav) throw new Error(`not a WAV: ${path}`);
|
||||
const pcm = mono(wav.channels);
|
||||
const analysis = analyse(pcm, wav.sampleRate, { fps });
|
||||
const song = buildSong(analysis, seed);
|
||||
return { pcm, sampleRate: wav.sampleRate, analysis, song, name: path.split('/').pop().replace(/\.wav$/i, '') };
|
||||
}
|
||||
Reference in New Issue
Block a user