# imab — "i'm a butterfly" · the dance track The club cousin of the flutterbap family (`pop/marimba/`). Where flutterbap skips through the park, imab goes out at night: a four-on-the-floor dance record sung around one hook — *i'm a butterfly* — with the "i-MAB" stamp as its chant. Built bottom-up from AC instruments (marimba modal synth, perc synth, the clubber360 floor recipes) — never generated wholesale. Vocals ship aesthetivoxed, never raw. ## musicality (locked unless we relock it) - **BPM 124** — the flutterbap family tempo; beat ≈ 0.4839 s, bar ≈ 1.9355 s. - **Key: A minor verses / C major hook** (relative pair). The hook quotes flutterbap's opening cell (E5 G5 C6) exactly. - **Hook progression:** `Am | Am | G | G | C | C | F | G` (8-bar loop). Bass roots A2 A2 G2 G2 C3 C3 F2 G2. ### the hook, syllable by syllable (CAPS = held) One line per bar; beats in parentheses. Score doc: `imab.np`. ``` 1 i'm(E5 @1) a(G5 @1.5) BUT(C6 @2, 1.5 beats) ter(B5 @3.5) fly(G5 @4) 2 …rest… i(A4 @4) MAB(E5 @4.5) ← pickup 3 i'm(D5 @1) a(G5 @1.5) BUT(B5 @2, 1.5 beats) ter(A5 @3.5) fly(G5 @4) 4 …rest… i(A4 @4) MAB(E5 @4.5) 5 i'm(E5 @1) a(G5 @1.5) BUT(C6 @2, 1.5 beats) ter(D6 @3.5) fly(E6 @4) ← the lift 6 FLY(E6 @1, 2 beats) → (C6 @3, 1.5 beats) 7 no(E6 @1) thing(D6 @1.5) holds(C6 @2) me(G5 @2.5) DOWN(A5 @3, 1.5 beats) 8 i(A4 @1) MAB(E5 @1.5, held) i(A4 @3) MAB(E5 @3.5, held) ← the chant ``` Lineage: bars 1/5 = flutterbap bar 1 (E5 G5 C6); bar 3 = flutterbap bar 3 (D5 G5 B5); bar 7 = "nothing holds me" from lately-when-i-fly (E6 D6 C6 G5). ## tools ```bash node pop/imab/bin/hitbaker.mjs # the CHART arrangement (single-study calibrated): # 104-bar verse/pre/chorus form, G-pedal break, # terminal-lift finale → out/imab-hitbaker-demo1 # vocal doors: choruses at bars 24 / 56 / 76 (A = 24) node pop/imab/bin/fetch-real-kit.mjs # CC0 Freesound drum one-shots → samples/real/ # (hitbaker prefers these; provenance in # kit-real.json + the pop menu sample registry) node pop/imab/bin/gen-click.mjs # click + guide → out/ (juke-sync picks mp3s up) node pop/imab/bin/gen-kit.mjs # one-shot sample kit → samples/kit/ node pop/imab/bin/lyrictrack.mjs # canonical lyric timing: drawn boundaries → # stem + floor JSONs + grid-fit proof mp4 pop/.venv/bin/python pop/imab/bin/lyricscroll.py # the scrolling review clip: alignment-video # chassis over the real floor mix, lyric # ribbon underneath (needs lyrictrack first) pop/.venv/bin/python pop/imab/bin/melodyproof.py [take…] # DOES HE SING WHAT WE WROTE? every syllable's # sung pitch vs melody.json, per take, two # stages: SET (vocalset's note-locked render — # proves the render) and RAW (the demucs stem — # the verdict). Register fitted per take in # cents; boundaries from drawn / dtw / notealign. # → out/melodyproof.html (?only=) # also writes boundaries-dtw-.json (the # lead's hand warped onto each take) for the wizard node pop/imab/bin/syllawizard.mjs # draw syllable rectangles on THIS take's # spectrogram (takes// in the cache; seeds # from processed → drawn → dtw boundaries) pop/.venv/bin/python pop/imab/bin/notealign.py # forced alignment: the written melody DTW'd onto # the f0 track → syllable spans (a proposal) node pop/imab/bin/setalign.mjs # every set retimed onto the lead's syllable # onsets → out/imab-set--aligned.wav + # imab-sets-successive.mp3 (no layering) open pop/imab/review.html # scroll-through of every demo, take and spine ``` ### boundary files — which timebase - `processed-boundaries-.json` — @jeffrey's hand on the **SET** (vocalset's stretched, note-locked wav; the wizard's `takes//spec.png`). Feeds vocalset. - `boundaries-drawn-.json` — @jeffrey's hand on the **RAW** stem. The lead's (Sep 1) carries the a/but mislabel that `lyric-overrides.json` drawnFix corrects; 7427's (Sep 9, drawn on neo) is clean. - `boundaries-dtw-.json` — melodyproof's warp of the lead's SET hand onto another take's SET, by MFCC+RMS DTW. A seed, not a truth. - `melody.json` — the notepat ground truth, one note per syllable. Edit here, not in the scripts. ### where the work lives The raw takes (`toolchain/whistlegraph/downloads/whistlegraph-.wav`), their demucs stems and the full `~/.cache/ac/imab` work dir live on **neo**; blueberry holds copies of the six stems + wavs as of 2026-09-13. Uncommitted lane work has stranded on both machines before — `git status pop/imab` on each before assuming a fix "already happened". - **out/imab-click-124** — 2-bar count-in, then 64 bars. Beat 1 accented, brighter door tick at every 8-bar phrase start. - **out/imab-guide-124** — the same click with the hook melody (xylophone) and bass roots looping, for practicing and cutting takes. ## recording performances 1. Record at 48 kHz against the click or guide (one ear). 2. Drop files in `performances/` named `imab-take-NN-.wav`. 3. Log every take in `performances/manifest.json` immediately — a take that isn't logged doesn't exist. Fields: `{ id, file, date, kind (vocal|whistle|clap|beatbox|other), content, clickUsed, keeper, notes }`. 4. Raw takes never ship: vocal comps go through the aesthetivox chain (`pop/bin/autotune.py`, A minor) before they touch a mix. ## aesthetivox-alignment-video `bin/aesthetivox-alignment-video.py` — the named feature: a piano-roll study mp4 (syllable blocks at sung pitch with their own waveform envelopes printed inside, numbered bars, per-beat tinted grid, kick floor, scrolling waveform, fixed playhead) over the click+kick+vocal study audio. The alignment scrutiny instrument for every aesthetivox vocal. Display latency is calibrated with loner's synccal.mp4; set SYNC_MS to the value that locks. ## samples `samples/kit/` — sample-free one-shots rendered from the AC engines (perc kit, bass-perc, xylophone hook notes, click ticks), manifest in `kit.json`. Chops of logged performances go in `samples/perf/` with their own manifest, named after the take they came from. ## the dance track (build plan) Carrying the loner/clubber360 learnings: - everything on ONE grid; stretches only at exact 0.5×/0.25× ratios - rhythmic narrative as a palindrome — the floor assembles act by act, reduces to a seed in the kickless break, returns whole at the drop, peels in reverse; kick turn-figures before doors; click-rush doors - sidechain pump on melodic layers keyed to the kick; phrase rests (last half-bar of each 8-bar phrase floors the decorative layers — kick, bass and the voice are never gated) - vocal-keyed wub swelling only in the gaps the voice leaves - master: cut-wax material chain posture; MEASURE → one static dB → true-peak limit; −11.5 juke print, −13.5 release - build pipeline lives in `bin/` in the repo, work dir in `~/.cache/ac/imab` — never in a scratchpad