Skip to content

Flags

Performance is flags, not fast typing. A flag is a named, typed value that a MIDI pad or knob can drive. Section bodies branch on it; patterns can read it live. The controller is the performance surface; the code is the composition.

Declare flags at composition time with song.flag(name, binding):

song.flag("ratchet", { kind: "pad", note: 36, mode: "toggle" });
song.flag("drive", { kind: "cc", cc: 1, range: [0, 1], smooth: 0.4 });
song.flag("doubleKick", { kind: "constant", value: false });

pad — a MIDI note that sets a boolean. mode chooses the behavior:

  • "toggle" — flips on each press.
  • "trigger" / "gate" — momentary.
  • "latchBar" — sets true immediately and auto-clears at the next bar boundary, so exactly one section-body run sees the latch.

cc — a continuous controller (mod wheel, knob). range maps the raw 0..127 into your domain; smooth applies EMA smoothing so a knob doesn’t zipper.

constant — no hardware: a value you flip in code. Useful for arrangement switches you toggle by editing.

There are two views, by design:

  • t.flags in a section body is a snapshot taken at the bar boundary — quantized on purpose, so a flag flip lands musically on the next bar.
  • ctx.flags in Pattern.query reads the live value, for continuous, sub-beat control (a filter sweep that tracks the knob mid-bar).
song.section("drop1", bars(16), (t) => {
const drive = Number(t.flags.drive ?? 0); // cc snapshot, quantized to the bar
kick.play(straightKick);
// a boolean pad swaps which pattern plays:
hats.play(t.flags.ratchet === true ? ratchetHats : tickHats).gain(0.85);
// a knob scales gain and gates a layer:
stab.play(stabsA).gain(0.5 + 0.3 * drive);
if (drive > 0.5) perc.play(scatter).gain(drive * 0.8); // earn the knob
});

For the live, sub-beat read inside a pattern, see the RatchetPattern in Custom patterns — it reads ctx.flags.drive at query time so turning the knob makes rolls more likely mid-bar.

Both views derive from one store; because JavaScript is single-threaded there are no races — only the snapshot-versus-live distinction, which is intentional.

The studio’s flag panel gives you live software controls for every flag, so you can perform without hardware connected; bind a MIDI controller and the same flags become physical.