Skip to content

Events & Notes

A pattern doesn’t store sound, and it doesn’t store a list of notes either. It answers a question: what plays, and when? The answer comes back as a stream of events. Understanding what an event actually carries — and how the note, chord, and degree literals you write become events — is the mental model that ties patterns, keys, and instruments together.

An event is a value over a span of time. The span is a half-open window [start, end): the event begins at start and releases at end. That window is everything time-related about the event — when a note sounds and how long it holds are the same fact. There’s no separate “duration” field; the gate is the span.

When you write [C4 D4 E4 F4], querying one cycle hands back four events, each a note value over one quarter of the cycle. Add a fifth note and every span shrinks to fit — the events divide the cycle, as covered in Cycles & Time.

Here’s the data model in action — a melody, a chord, and a key-relative line, all played on the same melodic sampler:

use "std/instruments" { SamplerMelodic, Kit };
let keys = AudioTrack("keys");
keys.load_instrument(SamplerMelodic(Kit("keys")));
keys << [C4 E4 G4 60]; // note names and a plain MIDI number
keys << [C4:maj _ A3:min7 _]; // chords
keys << [^1 ^3 ^5 ^8].in_key(Key(C4, "major")); // scale degrees, resolved
PLAY;

Three patterns, three flavours of the same event stream. Every element resolves to the same underlying thing: a pitch (plus a velocity) over a span.

Strip an event down and you find three pieces of information:

  • Pitch — what to play
  • Velocity — how hard (optional; falls back to the track default)
  • Span — when it starts and ends

The interesting part is pitch, because Resonon accepts several kinds and resolves them at different times:

You writeKindResolves to
C4, f#3, Bb2Note nameA MIDI pitch
60, 67NumberA MIDI pitch (the number is the note)
bd, sd, hhSampleA named hit on the track’s sampler
^1, ^5, ^-2Scale degreeA pitch, once anchored to a key
C4:maj, ^1:min7ChordSeveral simultaneous pitches

Note names and plain numbers are the same thing under the hood. A note’s MIDI value is (octave + 1) × 12 + semitone, so C4 is 60, A4 is 69. Writing 60 is just writing that pitch directly — handy for drum maps and arithmetic, and you can mix the two styles freely in one pattern.

Pitches are fractional, not just integers: 60.5 is a quarter-tone above C4. That’s how Resonon plays microtonal scales — a non-integer pitch is rendered via pitch bend when a track has tuning() or mpe() enabled.

Attach a velocity to any note, number, sample, or chord with ^ followed by a value from 0–127:

keys << [C4^120 E4^80 G4^100 C5^60];

If an event has no ^ velocity of its own, it inherits the track’s default (track.velocity(v), which itself defaults to 100). A per-note ^ always wins over the track default.

A chord literal like C4:maj or ^1:min7 is not one event with three pitches — it expands into a stack of single-pitch events that all share the same span. They sound simultaneous because their time windows are identical. This is why a chord behaves exactly like writing the notes with commas: [C4:maj] and [C4, E4, G4] produce the same three overlapping events. The chord qualities (maj, min7, sus4, …) and the chord() builder live in Music Theory.

A scale degree like ^1 or ^-2 is deliberately unresolved. It carries a degree number, not a pitch — ^1 doesn’t know whether it’s C or F♯ until you give it a key. You anchor it in one of two ways:

  • Per pattern with .in_key(key), as in the example above.
  • Per track with track.key(...), after which every degree on that track resolves automatically and absolute notes are quantized into the scale.

This late binding is the whole point: write a melody once in degrees, then change the key under it and the same pattern transposes and re-harmonizes itself. A Key is a Scale rooted at a note; both, along with diatonic chords on degrees (^1:), are covered in Music Theory.

When the scheduler queries a pattern, it gets these events and turns each one into output at its destination:

  • On a MIDI track, an event becomes a note-on at the span’s start and a note-off at its end. A fractional pitch adds a pitch-bend message.
  • On an audio track, an event triggers a voice on the loaded instrument — a sampler hit, a plugin note, or a DSP voice — gated by the same span.

Either way, the span’s end is what releases the note. The event is the contract; the instrument decides how to make it audible.