YOU'VE GOT JEV — 2-step garage, 132bpm, 64 bars as written; Jev arranges up to 24 four-bar sections. Spec: SPEC.md Start from STOPPED so the song begins at bar 1 (re-running it mid-play keeps the cycle count).
── Jev: two of them, in TypeSafe's own shape (SPEC.md, "Jev in the booth") ── formJev picks the next section; djJev, asked once that is decided (questions in one request cannot see each other), says how much of each part plays it, how the song moves into it, and how hard. Every 4 bars. The form's rules (walk, at the bottom) narrow the sections Jev may pick and end the song; without Jev it plays as written.
12const song = { 13 title: 'YOU’VE GOT JEV', 14 what: '2-step garage about Jev routing support mail: AOL dials in, a ticket arrives, and Jev routes it in a blink with no human in the loop', 15 tempo: '132 bpm, 4/4, swung, 4 bars a section', 16 key: 'C minor', 17 chords: 'Cm9 – Fm9 – Bbmaj7 – Abmaj7, two bars each (an 8-bar cycle), under the stabs and the sub', 18 lyrics: { 19 verse1a: 'New ticket in / Billing, bug, or refund', 20 verse1b: 'Choice: billing / Point nine three', 21 hook1: 'You’ve got mail / You’ve got Jev / You’ve got mail / You’ve got Jev', 22 verse2a: 'No human in the loop / Routed in a blink', 23 verse2b: 'Nobody had to read it / You’ve got Jev', 24 hook2: 'You’ve got mail / You’ve got Jev / You’ve got mail / You’ve got Jev', 25 outro: 'Goodbye', 26 }, 27}
29const formJev = jev({ 30 state: song, 31 questions: { 32 section: choice('Pick the section of the song that plays next, from those allowed. The outro ends the song: choose it once the song has built to its peak and made its point, before it drags', { 33 modem: 'a dial-up modem alone: the dial tone, the number dialed, the answer tone', 34 handshake: 'the modem handshake screech chopped into a rhythm, hats and muffled stabs coming in', 35 verse1a: 'verse 1, first half: 2-step drums, swung stabs, the warbly sub, vocoded lines', 36 verse1b: 'verse 1, second half', 37 hook1: 'the hook: AOL asks and the vocoder answers', 38 drop1a: 'drop 1: instrumental, open hi-hats, a crash', 39 drop1b: 'drop 1 continues', 40 drop1c: 'drop 1, last four bars', 41 verse2a: 'verse 2, first half', 42 verse2b: 'verse 2, second half', 43 hook2: 'the hook again, into the big drop', 44 drop2a: 'drop 2, the peak: the screech chops return over the full groove, a crash', 45 drop2b: 'drop 2 continues', 46 drop2c: 'drop 2 continues', 47 drop2d: 'drop 2, last four bars', 48 outro: 'a last hit and a ringing chord, then AOL says goodbye: the end', 49 }), 50 }, 51})
how much of each part the section decidedThisSection has: out, back or full
54const level = (part) => score('How much of ' + part + ' should the next section (decidedThisSection) have? Drop parts to build tension or make space, pull them back to let others speak, and bring them in full for the payoff; keep what defines the section', [ 55 'out: silent for the section', 56 'back: under the rest of the mix', 57 'full: as written', 58]) 59const djJev = jev({ 60 state: song, 61 questions: { 62 modem: level('the modem (a dial-up modem dialing in alone for the first four bars, the handshake screech chopped into a rhythm in the next four, and the chops again over drop 2)'), 63 drums: level('the drums (the 2-step kick and snare from verse 1 on, swung hi-hats from bar 5, open hats on the off-beats and crashes in the drops)'), 64 stabs: level('the stabs (short swung organ-style chord stabs, muffled at the end of the handshake, then from verse 1 to the outro)'), 65 sub: level('the sub (the warbly sub bass on the chord roots, the floor from verse 1 to the outro)'), 66 vocals: level('the vocals (the vocoded ticket lines in the verses, and AOL asking and the vocoder answering in the hooks; the drops are instrumental as written)'), 67 into: choice('How should the song move into the next section (decidedThisSection)? It plays over the last bar of the section before it', { 68 cut: 'straight in, no transition', 69 fill: 'a snare and clap roll in sixteenths, swelling into the downbeat, over the last half bar', 70 riser: 'the modem handshake screech, chopped into sixteenths, its filter sweeping up over the last half bar', 71 dropout: 'everything stops for the last beat, a gap before the section hits', 72 }), 73 energy: score('How intense should the next section be? Shape the energy of the whole song, following its history, how it measured and how the listener reacted', [ 74 'held back: quieter', 75 'steady: under full', 76 'driving: nearly full', 77 'all out: full volume', 78 ]), 79 }, 80})
a little chance in the form: the section is drawn from Jev's probabilities
83const { section } = formJev.every(4, { sample: 0.7 }) 84const dj = djJev.every(4, { 85 after: { section }, 86 forget: ['into'], 87 // the intro builds from the modem alone, so the handshake always cuts in 88 allow: { into: ({ section: next }) => (next === 'handshake' ? ['cut'] : ['cut', 'fill', 'riser', 'dropout']) }, 89 fallback: { modem: 2, drums: 2, stabs: 2, sub: 2, vocals: 2, into: 'cut', energy: 3 }, 90})
Jev's most probable level. A score's probabilities are keyed by level, "0", "1", … (docs.typesafe.ai/primitives/score); a fallback has none, so it plays the level its score names.
95const mostLikely = (p, score) => { 96 const levels = Object.entries(p ?? {}) 97 return levels.length ? Number(levels.reduce((a, b) => (b[1] > a[1] ? b : a))[0]) : Math.round(score) 98} 99const fromAnswer = (answer, f) => answer.score.fmap((score) => (p) => f(p ?? {}, score)).appLeft(answer.probabilities)
A part's gain: silent when "out" is Jev's most probable level; otherwise Jev's probability-weighted mix of back (0.5) and full (1).
A part at Jev's level. Each part has its own orbit, named for its question, so the meter hears it alone (measuredSound).
bars: 1-4 modem | 5-8 chopped handshake | 9-16 verse 1 | 17-20 hook | 21-32 DROP 1 33-40 verse 2 | 41-44 hook | 45-60 DROP 2 | 61-64 outro (each mask = 64 steps)
117const modemOn = "<1 0!63>" 118const chopIn = "<0!4 1!4 0!56>" 119const stabIn = "<0!6 1!2 0!56>" 120const groove = "<0!8 1!52 0!4>" 121const verse1 = "<0!8 1!8 0!48>" 122const verse2 = "<0!32 1!8 0!24>" 123const hooks = "<0!16 1!4 0!20 1!4 0!20>" 124const drops = "<0!20 1!12 0!12 1!16 0!4>" 125const drop2 = "<0!44 1!16 0!4>" 126const crash = "<0!20 1 0!23 1 0!19>" 127const lastHit = "<0!60 1 0!3>" 128const bye = "<0!61 1 0!2>"
two bars per chord: Cm9 Cm9 Fm9 Fm9 Bbmaj7 Bbmaj7 Abmaj7 Abmaj7, voiced close so the stabs move by step (each keeps the pitch classes its vocoded lines were rendered on)
133const cm9 = "[c3,eb3,g3,bb3,d4]" 134const fm9 = "[f3,g3,ab3,c4,eb4]" 135const bbmaj7 = "[bb2,f3,a3,d4]" 136const abmaj7 = "[ab2,eb3,g3,c4]" 137const chords = cat(cm9, cm9, fm9, fm9, bbmaj7, bbmaj7, abmaj7, abmaj7) // a chord a bar 138const roots = "<36!2 29!2 34!2 32!2>" // C2 F1 Bb1 Ab1, as MIDI numbers 139const chops = "<[0 ~ 4 ~ 8 2 ~ 12] [~ 6 ~ 14 0 ~ 10 3]>"
── parts ─────────────────────────────────────────
142const modem = stack( 143 // bars 1-4: the modem dialing in, alone (first 7.27 s of 7.45) 144 s("modem").end(.976).gain(.9).mask(modemOn), 145 // the handshake screech, chopped into a fixed rhythm 146 s("screech").slice(16, chops).hpf(300).gain(.55).mask(chopIn), 147 // drop 2: the chops return at the intro's level 148 s("screech").slice(16, chops).hpf(300).gain(.55).pan(.3).mask(drop2) 149)
drums: 2-step
152const drums = stack( 153 s("[bd:3,808bd:1]").struct("x ~ ~ ~ ~ ~ ~ ~ ~ ~ x ~ ~ ~ ~ ~").gain(.4).mask(groove), 154 s("[sn:3,cp]").struct("~ ~ ~ ~ x ~ ~ ~ ~ ~ ~ ~ x ~ ~ ~").room(.2).gain(.3).mask(groove), 155 s("sn:1").struct("~ ~ ~ ~ ~ ~ ~ x ~ ~ ~ ~ ~ ~ ~ x").swingBy(1/3, 8).gain(.1).mask(groove), 156 s("hh*16").gain(".32 .12 .22 .12").swingBy(1/3, 8).mask("<0!4 1!56 0!4>"), 157 // open hats on the off-beats in the drops 158 s("808oh").struct("~ x ~ x ~ x ~ x").gain(.2).mask(drops), 159 // hh27:1 is a crash; `cr` is a ride (songs/CLAUDE.md) 160 s("hh27:1").gain(1).mask(crash) 161)
organ-style stabs, short and swung
164const stabs = stack( 165 // the filter opens in the drops: 3000 in drop 1, 4000 in drop 2 166 note(chords).struct("~ ~ x ~ ~ x ~ ~ ~ x ~ ~ x ~ ~ ~").swingBy(1/3, 8) 167 .s("sawtooth").lpf("<1700!20 3000!12 1700!12 4000!16 1700!4>").decay(.16).sustain(0).room(.3).gain(.45).mask(groove), 168 note(chords).struct("~ ~ x ~ ~ x ~ ~ ~ x ~ ~ x ~ ~ ~").swingBy(1/3, 8) 169 .s("sawtooth").lpf(600).decay(.16).sustain(0).gain(.12).mask(stabIn) 170)
warbly sub: garage push rhythm, a slow vibrato a fifth of a semitone deep. subClipped is the same line with the note on step 10 cut to two steps, for a section's last bar when a dropout follows, so the sub stops for the gap.
180const vox = stack( 181 // verses: vocoder, one line per 2 bars, each sung on its chord 182 s("<newticket ~ billingbug ~ choicebilling ~ ninetythree ~>").gain(1.25).room(.2).mask(verse1), 183 s("<nohuman ~ routedblink ~ nobodyread ~ gotjevab ~>").gain("<1.25!4 1.5!2 1.25!2>").room(.2).mask(verse2), 184 // hook: AOL asks, the vocoder answers on the hook's chords 185 s("<mail gotjevcm mail gotjevfm>").gain(1.35).room(.25).mask(hooks) 186)
the end: the last hit, a ringing Cm9 over a C2 sub, and AOL's goodbye. It always plays.
189const ending = stack( 190 s("[bd:3,808bd:1]").room(.5).gain(.4).mask(lastHit), 191 s("hh27:1").room(.5).gain(1).mask(lastHit), 192 note(cm9).s("sawtooth").lpf(1400).decay(1.5).sustain(0).room(.6).gain(.45).mask(lastHit), 193 note("c2").s("sine").vib(.5).vibmod(.2).release(.3).gain(.7).mask(lastHit), 194 s("goodbye").gain(1.2).room(.5).mask(bye) 195)
197const once = (p) => p.mask("<1!64 0!936>") // play once, then silence
── the form, as rules in code: which sections may follow which ──
at is where each starts as written; an empty next ends the song. The
written order is always allowed, and is what plays without Jev. Nothing
leads back into a hook, so each plays once; and every move goes to a
section starting 4 bars off in the 8-bar chord cycle, so the two halves of
the progression alternate.
times: each drop's loop goes round once more at most (SPEC.md, "Loops end").
206const form = walk(section, { 207 max: 24, 208 sections: { 209 modem: { at: 0, next: ['handshake'] }, 210 handshake: { at: 4, next: ['verse1a'] }, 211 verse1a: { at: 8, next: ['verse1b'] }, 212 verse1b: { at: 12, next: ['hook1'] }, 213 hook1: { at: 16, next: ['drop1a', 'drop1c'] }, 214 drop1a: { at: 20, next: ['drop1b'] }, 215 drop1b: { at: 24, next: ['drop1c'], times: 2 }, 216 drop1c: { at: 28, next: ['verse2a', 'drop1b'] }, 217 verse2a: { at: 32, next: ['verse2b'] }, 218 verse2b: { at: 36, next: ['hook2'] }, 219 hook2: { at: 40, next: ['drop2a'] }, 220 drop2a: { at: 44, next: ['drop2b'], times: 2 }, 221 drop2b: { at: 48, next: ['drop2c', 'outro'], times: 2 }, 222 drop2c: { at: 52, next: ['drop2d', 'drop2b'] }, 223 drop2d: { at: 56, next: ['outro', 'drop2a'] }, 224 outro: { at: 60, next: [] }, 225 }, 226})
── into the next section: over the last bar of each, the next one's answer ── Past the last section there is no next one, so nothing plays there.
fill and riser build over the second half of the bar, clear of the line on its downbeat
234const transition = into.pick({ 235 cut: silence, 236 fill: s("~ [sn:3,cp]*8").room(.2).gain(saw.fast(2).range(.12, .34)).orbit('drums'), 237 riser: s("screech").slice(16, "~ [8 9 10 11 12 13 14 15]") 238 .hpf(saw.fast(2).range(300, 5000)).gain(saw.fast(2).range(.15, .45)).orbit('modem'), 239 dropout: silence, 240}).mask("<0!3 [0 1]>")
dropout: the parts stop for the section's last beat
the sub's last bar: clipped when a dropout follows, so it stops for the gap
── the song: Jev's section, parts and energy, composed ── Each section plays its own bars, each part at the level Jev chose; the energy, Jev's most probable step, scales every part's velocity together, so the mix keeps its balance. The ending always plays.
255const parts = form.arrange(once(stack( 256 part('modem', modem), 257 part('drums', drums), 258 part('stabs', stabs), 259 part('vocals', vox), 260))) 261const subPart = stack( 262 form.arrange(once(part('sub', sub))).mask(notDropoutBar), 263 form.arrange(once(part('sub', subClipped))).mask(dropoutBar), 264) 265const energy = fromAnswer(dj.energy, mostLikely)