Lab

sequencer

The step sequencer's controller from @audio-ui/core: a pattern of steps and their velocities, held or controlled, painted by pointer, toggled from the keyboard, with one tab stop in the grid.

pnpm add @audio-ui/core
import { createSequencerController, cellAtPoint, cellKey, DEFAULT_VELOCITY, isOn, /* … */ } from "@audio-ui/core/sequencer";
Adapters@audio-ui/react/sequencer, @audio-ui/elements/sequencer
ExportKindWhat it is
createSequencerControllerfunctionA sequencer's behavior with no view attached: its pattern and velocities, held or controlled, its tab stop, and every way of painting them.
SequencerCellNodestypeWhich element a pointer gesture reads its cells from: a map of the cell elements by key.
SequencerControllerinterfaceWhat createSequencerController returns: the snapshot to draw from, and the presses, paint strokes, keys and focus moves that edit the grid.
SequencerOptionsinterfaceThe options of createSequencerController: the pattern and the velocities, each held or controlled, and the callbacks.
SequencerSnapshotinterfaceWhat a view draws the sequencer from.
SequencerValueChangeEventDetailstypeWhat onValueChange receives with each change to the pattern: the reason ("press", "paint" or "keyboard"), the event, and cancel() to refuse it.
SequencerValueCommitEventDetailstypeWhat onValueCommitted receives once a gesture on the pattern ends: the reason and the event.
SequencerVelocityChangeEventDetailstypeWhat onVelocityChange receives with each change to the velocities: the reason ("drag", "keyboard", "input-change" or "reset"), the event, and cancel() to refuse it.
SequencerVelocityCommitEventDetailstypeWhat onVelocityCommitted receives once a gesture on the velocities ends: the reason and the event.
CellAddressinterfaceA cell of the grid: its row and its step.
cellAtPointfunctionThe cell whose box holds the point, from the boxes of every cell.
cellKeyconstA cell's address as a string key, "row:step".
DEFAULT_VELOCITYconstWhat a step plays at until it is set.
isOnfunctionWhether pattern has the cell on.
moveFocusfunctionWhere an arrow, Home or End key takes the focus from from, kept inside the grid.
PatterntypeWhich steps are on: a row per sound, a cell per step.
setCellfunctionpattern with one cell set; the same pattern when it already is.
setVelocityfunctionvelocities with one step set, grown to rows × steps; the same values when it already is.
VelocitiestypeLoudness per step, 0…1: a row per sound, like the pattern.
velocityAtfunctionThe velocity of one step.
velocityAtYfunctionThe velocity a press at clientY sets on a bar: its bottom is silent, its top full.

Usage

A pattern is a row of steps per sound, each on or off, and the velocities are a number from 0 to 1 per step, in the same shape:

import { createSequencerController } from "@audio-ui/core/sequencer";

const sequencer = createSequencerController({
  defaultValue: [
    [true, false, false, false, true, false, false, false],
    [false, false, true, false, false, false, true, false],
  ],
  onValueCommitted: (pattern) => save(pattern),
  onVelocityCommitted: (velocities) => saveVelocities(velocities),
});

A press on a cell, pressCell(cell, event, root, nodes), switches it and paints the same state across every cell the pointer then crosses, so one drag fills a row. nodes maps each cell's key (cellKey) to its element, which is how the gesture finds the cell under the pointer. pressVelocity draws the velocity bars the same way: the bottom of a bar is silent and its top full. A step reads DEFAULT_VELOCITY (1) until it is set.

From the keyboard, moveFocusFrom(cell, event) moves the focus with the arrows, Home and End, toggleCell(cell, event) switches the focused cell, and setVelocity sets a step's velocity from a key or a field. The snapshot holds the pattern, the velocities, its size, the tab stop and whether a drag is painting.

setCell, setVelocity, isOn and velocityAt are the same edits as plain functions on a pattern, for an engine that keeps the pattern itself.

The Sequencer draws this controller in React.

Built by Ouest Labs, the source code is available on GitHub.
RSS