The core Jump is built on. Patterns, mini-notation, clocks and quantise grids, with no dependencies and nothing about audio or games.
Patterns
A Pattern<T> answers one question: what happens in this span of time? Time is in cycles, and one cycle is one bar.
import { mini, seq, pure, stack, euclid } from "@chop-jump/jump";
const p = mini("kick ~ kick [~ kick]");
p.cycle(0); // events that start in bar 0
p.onsets(4, 4.5); // events that start in the first half of bar 4
Each event is a Hap: { whole: { begin, end }, value }.
Mini-notation
| Write | Meaning |
|---|---|
"a b c d" |
four steps in one cycle |
"a ~ b ~" |
~ is a rest (- works too) |
"a [b c]" |
brackets subdivide a step |
"a*4", "a/2" |
repeat a step faster, or spread it over cycles |
"<a b c>" |
one per cycle, in turn |
"a, b c" |
layers, at the top level or inside brackets |
"a!3", "a ! b" |
replicate a step |
"a _ b" |
stretch the previous step by one step |
"a@3 b" |
weight a step |
"a?", "a?0.8" |
drop at random, deterministically (same result every time) |
"x(3,8)", "x(3,8,2)" |
Euclidean rhythm, optional rotation |
Words can carry an argument after a colon, like "rock:L" or "c:minor". word("rock:L") returns { name: "rock", arg: "L" }.
Syntax errors throw a MiniSyntaxError with the position.
Combinators
pure(v), seq(...), stack(...), slowcat(...), timecat([[w, p], ...]), euclid(p, k, n, rot) and silence() build patterns. Methods transform them: fast, slow, late, early, every(n, f), degradeBy(p, seed), rev, compress(b, e), fmap, filter.
Clocks
import { Clock } from "@chop-jump/jump";
const clock = new Clock({ bpm: 126, now: () => audio.currentTime, origin: startedAt });
clock.beat(); // beats since the origin, now
clock.cycle(); // bars since the origin, now
clock.timeOfCycle(16); // seconds at bar 16
clock.next("16n"); // the next sixteenth-note line, in seconds
clock.next("4n", t, 0.03); // a hit up to 30 ms late counts as on the beat it aimed at
clock.offGrid("4n", t); // how far t is from the nearest beat
Grids are written in music notation: "16n", "8n", "4n", "2n", "8t" (eighth-note triplet), "1m", "2m", "4m", "8m", or a number of beats.
Chop's trackClock and Jump's default tempo clock are both Clocks. The origin is beat 0, the first downbeat.
Music helpers
noteToMidi("eb2"), midiToFreq, parseKey("a:minor"), keyName, degreeToMidi(key, degree, octave), chord(key, degree), and SCALES.
Randomness
mulberry32(seed) returns a seeded random function, and hashString(s) turns a name into a seed. Both are used to keep games deterministic.