Skip to content

Pattern Basics

Patterns are the heart of music-making in Resonon. They describe sequences of notes, rests, and samples that repeat over time — think of a pattern as one looping bar in a DAW, written as text.

Let’s start with a complete example you can run, then take it apart:

use "std/instruments" { Sampler, Kit };
let drums = AudioTrack("drums");
drums.load_instrument(Sampler(Kit("CR-78")));
drums << [bd sd bd sd];
PLAY;

The first three lines set up an audio track with a drum sampler — that part you know from Hello, Sound. The interesting line is this one:

drums << [bd sd bd sd];

[bd sd bd sd] is a pattern: four drum hits in square brackets. The << operator sends it to the track, and PLAY starts the transport. The pattern loops forever until you PAUSE or replace it.

Patterns fit into cycles. A cycle is the fundamental unit of time in Resonon — every pattern repeats once per cycle, like a bar looping in a DAW. Cycle duration is set by the tempo:

setbpm(120); // 120 BPM, default 4 beats per cycle
setbpm(140, 8); // 140 BPM, 8 beats per cycle

The relationship between BPM, beats per cycle, and cycle duration:

cycle_duration = beats_per_cycle * 60 / bpm
BPMBeats/CycleCycle Duration
12042.0 s
12084.0 s
1404~1.71 s

Use the second argument to setbpm when your patterns span more (or fewer) than 4 beats.

Elements within a pattern divide the cycle evenly:

let whole = [C4]; // One note fills the whole cycle
let halves = [C4 D4]; // Each note gets 1/2 of the cycle
let quarters = [C4 D4 E4 F4]; // Each note gets 1/4 of the cycle

The more elements you put in a pattern, the faster they play — four elements play as quarter notes, eight as eighth notes, and so on. There is no fixed grid: a three-element pattern divides the cycle into exact thirds.

Use _ (underscore) for silent steps. A rest occupies time just like a note:

let offbeat = [C4 _ E4 _]; // Play, rest, play, rest
let sparse = [bd _ _ sd]; // Kick on 1, snare on 4

Note names combine a letter, optional accidental, and octave: C4, f#3, Bb2. Plain numbers are interpreted as MIDI note values (0–127), and you can mix both freely:

let named = [C4 D4 E4 F4];
let numeric = [60 62 64 65]; // Same melody as above
let mixed = [C4 62 E4 67];

Numbers are handy for drum programming with General MIDI note maps:

// GM drum map: 36=kick, 38=snare, 42=closed hh
let gm_beat = [36 42 38 42];

The bracket syntax determines what kind of pattern you get:

SyntaxTypeBehavior
[C4 D4 E4]SequenceElements divide the cycle evenly
[C4, E4, G4]StackAll elements play simultaneously
<C4 D4 E4>AlternatingOne element per cycle, rotating

Sequence is the workhorse — elements play one after another. Stack layers everything at once, giving you chords or parallel rhythms. Alternating picks one element per cycle and rotates through them, so the pattern evolves over time.

Sample patterns like [bd sd hh] are ordinary sequences; the identifiers resolve as sample names when the pattern reaches an audio track with a sampler loaded.

All three types are explored in depth in Mini-Notation in Depth.

You can also build patterns with constructor functions, which is useful when the contents come from variables or arrays:

let s = Sequence(C4, E4, G4); // Same as [C4 E4 G4]
let st = Stack(C4, E4, G4); // Same as [C4, E4, G4]
let alt = Alternating(C4, E4, G4); // Same as <C4 E4 G4>
// All three also accept an array
let notes = #[C4, D4, E4, F4, G4];
let melody = Sequence(notes);

Patterns are lazy — they compute events on demand, not upfront. Think of a pattern as a recipe, not a recording:

  • On-demand: the scheduler queries one cycle at a time, computing only what it needs right now
  • Stateless: each query is independent — any cycle can be asked for in any order
  • Infinite by default: patterns repeat forever without storing infinite data

This has a practical consequence: transformations like .fast(2) or .reverse() adjust how the pattern is queried, not the data itself. Chaining many transformations costs nothing until the scheduler actually asks for events.

Now that you know how patterns divide time, dive into the notation that makes them expressive.