Skip to content

MIDI Messages

Byte values are hexadecimal. Channels are numbered 1–16 in code and 0–15 in the status byte. Every message carries its own status byte; resonon never sends running status. The functions named here are in the MIDI reference.

FactValue
Note-on9n note velocity
Note-off8n note 00. A note-on with velocity 0 is never sent.
Note numberRounded, and clamped to 0–127
Velocity0–127. Default 100. A ^v in a pattern wins over the track’s .set_velocity().
Velocity from a signalRead when the note starts; rounded, and clamped to 1–127
Incoming note-on with velocity 0Read as a note-off
FactValue
MessageBn controller value
Controller0–127
Value0–127, rounded and clamped, from a number, pattern or signal
From a signalSent only when the value changes, at most 30 times a second, or the rate set with .set_send_rate()
FactValue
MessageEn lsb msb, 14 bits; centre 8192 (00 40)
Range.set_tuning() ±2 semitones; .set_mpe() ±48; either takes 0 < range ≤ 96
Range messageRPN 0: Bn 65 00, Bn 64 00, Bn 06 semitones, Bn 26 00 — before the first note on a channel when the range is not 2, and again whenever it changes
Beyond the rangeClamped
OrderBend before the note-on; back to centre right after the note-off, on the same sample

Two microtonal notes that overlap on one channel, outside MPE, share one bend: resonon prints a warning.

.set_mpe(range, lo, hi): a lower zone with member channels lo–hi, default 2–16.

FactValue
Zone messageOn the first MPE note of a port: RPN 6 on channel 1, B0 65 00, B0 64 06, B0 06 members, B0 26 00, where members is the number of member channels
Bend rangeRPN 0 with the range on every member channel, sent with the zone message
Channel for a noteThe next member channel in turn; when all are busy, the one whose note ends soonest
Per-note expression sentPitch bend only: no channel pressure, no CC 74

Sent when set_midi_clock_send(true) is on and the port’s entry has send_clock.

MessageByteSent
Timing clockF824 per quarter note, from the audio thread
StartFAPlayback starts from the very top: PLAY or RECORD from stopped, a SEEK to 0 while playing
ContinueFBPlayback starts anywhere else: PLAY or RECORD from paused, a SEEK while playing, a port that starts receiving clock while playing
StopFCPAUSE, STOP; a SEEK while playing, before the new position
Song positionF2 lsb msbBefore every Continue: the first sixteenth at or after the play head. In sixteenths; it wraps at 16384

In each audio buffer, transport messages go first, then clock ticks, then notes. Transport messages go out at the top of the buffer the play head starts, stops or lands in. Each tick is sent on the sample the play head reaches it, the rule notes follow, so a tick on a beat lands with that beat’s notes. A tempo change bends the ticks with the music, with no burst and no gap. The first tick after Continue is the sixteenth its song position names.

set_midi_clock_source("alias") follows the clock of an input port:

Message receivedWhat resonon does
StartMoves to the start, and plays from the next clock tick
StopPauses
Song positionKeeps it for the next Continue
ContinueMoves to the kept position exactly, if there is one, and plays from the next clock tick
Clock tickTempo; and the play head’s phase, which is steered onto the source by up to ±0.5 % in speed, never by a jump
EventSent
PAUSE, STOP, the start of playbackA note-off for every note resonon started that is still sounding, and pitch bend back to centre on every channel it bent
SEEK, playing or paused; section.play(); PLAY after the audio device has been awayThe same
The third STOP in a rowThe same
An output port closed or unpluggedThe note-offs, then on all 16 channels CC 64 0 (sustain off) and CC 123 (all notes off), then pitch bend centre
An input port disconnectedCC 123 on the output channel of every track playing it through

CC 120 (all sound off) is never sent.

FactValue
TimestampsEvery message is scheduled for when the audio it belongs with reaches the converter (set_midi_latency("auto"), the default), plus the port’s trim_ms — and for clock, clock_trim_ms
Trims−500 to 500 ms; a value outside is ignored
Off macOSMessages are sent when the audio callback reaches them; the timestamp is not passed to the driver
PortsAt most 32 per session
ThruMore than 2000 messages in 100 ms stops thru on that input for 1 second
System exclusiveNot read or forwarded
FactValue
Resolution480 ticks per quarter note; a cycle is 4 quarter notes
midi_export(pattern, …)A type 0 file
midi_export(track, …), midi_export(#[tracks], …)A type 1 file; the tempo is in the first track
Default pathrenders/<name>_<date>_<time>/export.mid, or <track>.mid for one track