MIDI
MIDI tracks are the hardware counterpart of audio tracks: instead of playing an instrument inside Resonon, a MidiTrack sends notes to an external synth, DAW, or plugin host. Patterns are assigned with the same track << pattern statement. MidiTrack and all midi_* functions are built into the language — no import needed — and every example here runs without connected hardware.
For guided walkthroughs, see the chapters on MIDI output, input & CC, clock sync, and export & MPE.
| MidiTrack method | Returns | Meaning |
|---|---|---|
output(alias, channel?) | MidiTrack | Route to an output port (and channel) |
input(port, channel?) | MidiTrack | Listen to an input port, or "all" |
monitor(mode) | MidiTrack | Thru-play: "off", "in", "auto" |
velocity(v) | MidiTrack | Default velocity: number, signal, or pattern |
cc(number) | CcOutput | Handle for CC automation via << |
tuning(bend_range?) | MidiTrack | Microtonal output via pitch bend |
mpe(bend_range?, zone_lo?, zone_hi?) | MidiTrack | MPE per-note channels |
scale(scale, root) | MidiTrack | Per-track scale for degrees & quantization |
| Function | Returns | Meaning |
|---|---|---|
midi_ports() | Array | List available output ports |
midi_connect(port, alias?) | Boolean | Connect an output port |
midi_disconnect(alias?) | Nul | Disconnect an output |
midi_connected() | varies | Current output connections |
midi_input_ports() | Array | List available input ports |
midi_input_connect(port, alias) | Boolean | Connect an input port |
midi_input_disconnect(alias) | Nul | Disconnect an input |
midi_clock_send(enabled) | Boolean | Send MIDI clock as master |
midi_clock_follow(alias | false) | Boolean | Follow external MIDI clock |
midi_delay(ms?) | Number | Get/set global MIDI output delay |
midi_clock_offset(ms?) | Number | Get/set clock-only timing offset |
midi_clock_status() | Nul | Print clock source, BPM, transport |
midi_routing() | Nul | Print the full MIDI routing overview |
midi_export(subject, cycles, path?) | String | Write a Standard MIDI File |
Creating MIDI Tracks
Section titled “Creating MIDI Tracks”MidiTrack(channel, velocity?, port_alias?, name?)
Section titled “MidiTrack(channel, velocity?, port_alias?, name?)”Create a MIDI track. Only the channel is required.
| Parameter | Range / type | Default |
|---|---|---|
channel | 1–16 | — |
velocity | 0–127 | 100 |
port_alias | String | "default" |
name | String (for logs; duplicates auto-numbered) | "unnamed" |
use "std/signals" { Sine };
let bass = MidiTrack(1);let lead = MidiTrack(2, 110, "default", "lead");bass << [C2 E2 G2 C3];Track Methods
Section titled “Track Methods”output(alias, channel?)
Section titled “output(alias, channel?)”Route the track to a different output port by alias (see midi_connect()), optionally changing the channel too. A warning is logged if the alias isn’t connected yet — notes flow once it is.
lead.output("default");lead.output("default", 3);input(port, channel?)
Section titled “input(port, channel?)”Listen to a connected MIDI input: pass an input alias, or "all" for every connected input. The optional channel (1–16) filters incoming messages; without it, all channels pass.
lead.input("all");lead.input("all", 2);monitor(mode)
Section titled “monitor(mode)”Control thru-play of the track’s input: "off" (never), "in" (always forward input to the output), or "auto".
lead.monitor("in");lead.monitor("off");velocity(v)
Section titled “velocity(v)”Set the track’s default velocity (0–127). Also accepts a Signal or a Pattern for moving dynamics. Per-note @ velocity in mini-notation always wins over the track default.
bass.velocity(90);bass.velocity(Sine(0.5).range(60, 127));tuning(bend_range?)
Section titled “tuning(bend_range?)”Enable microtonal output: fractional note values are rendered with pitch-bend messages. bend_range is in semitones and defaults to 2 — match it to the bend range configured on the receiving synth.
lead.tuning();lead.tuning(12);mpe(bend_range?, zone_lo?, zone_hi?)
Section titled “mpe(bend_range?, zone_lo?, zone_hi?)”Enable MPE: each voice gets its own member channel for independent pitch bend. bend_range defaults to 48 semitones; the member-channel zone defaults to channels 2–16. The MPE Configuration Message is sent automatically before the first note.
lead.mpe();lead.mpe(48, 2, 8);scale(scale, root)
Section titled “scale(scale, root)”Attach a scale to the track, anchored at a root note: degree notation in patterns resolves through it, and out-of-scale notes are quantized. Accepts a scale name string, a Scale value (including microtonal scales), or an interval array.
lead.scale("minor", C3);lead.scale(Scale(#[0, 2, 3.5, 5, 7, 8.5, 10]), C3);CC Output
Section titled “CC Output”cc(number)
Section titled “cc(number)”Return a CcOutput handle for a controller number (0–127) on the track’s channel and port. Bind a Signal or Pattern to it with <<; values are rounded and clamped to 0–127, so scale signals into that range. Repeated values are deduplicated before sending.
lead.cc(74) << Sine(0.25).range(20, 120); // filter sweeplead.cc(1) << [0 32 64 127]; // stepped mod wheelFor reading CC from a controller, see Cc() and Cc_learn() in the signals reference.
send_rate(hz)
Section titled “send_rate(hz)”Set how often a CC binding samples its signal, in messages per second (above 0, at most 1000; default 30). Returns a new CcOutput, so chain it at bind time.
lead.cc(74).send_rate(60) << Sine(2).range(0, 127);Output Connections
Section titled “Output Connections”Connections map physical ports to aliases; tracks refer to aliases, so a set re-runs cleanly even when port names change. The implicit alias "default" is where every track sends unless told otherwise.
midi_ports()
Section titled “midi_ports()”List the names of all available MIDI output ports.
PRINT midi_ports();midi_connect(port_name, alias?)
Section titled “midi_connect(port_name, alias?)”Connect an output port. The name matches by substring, so "IAC" finds "IAC Driver Bus 1". Without an alias, the connection becomes "default". Returns true on success; errors if no port matches.
midi_connect("IAC Driver Bus 1"); // becomes "default"midi_connect("Elektron", "digitone"); // named aliasmidi_disconnect(alias?)
Section titled “midi_disconnect(alias?)”Disconnect an output by alias ("default" if omitted). Safe to call when nothing is connected.
midi_disconnect();midi_disconnect("digitone");midi_connected()
Section titled “midi_connected()”Query current output connections: false when nothing is connected, the port name string when only "default" is connected, or a dict of alias → port name for multiple connections.
PRINT midi_connected();Input Connections
Section titled “Input Connections”midi_input_ports()
Section titled “midi_input_ports()”List the names of all available MIDI input ports.
PRINT midi_input_ports();midi_input_connect(port_name, alias)
Section titled “midi_input_connect(port_name, alias)”Connect an input port under a unique alias (substring matching as with outputs). Returns true on success. Tracks subscribe via input(); signals read controllers via Cc().
midi_input_connect("Launchkey", "keys");midi_input_disconnect(alias)
Section titled “midi_input_disconnect(alias)”Disconnect an input by alias. All Notes Off is sent to the outputs first, so nothing hangs.
midi_input_disconnect("keys");Clock & Timing
Section titled “Clock & Timing”midi_clock_send(enabled)
Section titled “midi_clock_send(enabled)”Act as clock master: send 24-PPQ MIDI clock plus Start/Stop/Continue to all connected output ports. Mutually exclusive with clock follow.
midi_clock_send(true);midi_clock_send(false);midi_clock_follow(alias | false)
Section titled “midi_clock_follow(alias | false)”Sync Resonon’s tempo to incoming MIDI clock from a connected input alias; a soft PLL smooths the incoming tempo. Pass false to stop following. Mutually exclusive with clock send.
midi_input_connect("DAW out", "daw");midi_clock_follow("daw");midi_clock_follow(false);midi_delay(ms?)
Section titled “midi_delay(ms?)”Get or set a global delay applied to all MIDI output (notes and clock) — use it to line up external synths with Resonon’s internal audio.
midi_delay(12);PRINT midi_delay(); // 12midi_clock_offset(ms?)
Section titled “midi_clock_offset(ms?)”Get or set a timing offset applied to clock messages only, independent of midi_delay(). Positive values delay the clock; negative values send it earlier.
midi_clock_offset(-5);PRINT midi_clock_offset(); // -5midi_clock_status()
Section titled “midi_clock_status()”Print the current clock state: source (internal, sending, or following), BPM, transport state, and PLL diagnostics when following.
midi_clock_status();Routing Overview
Section titled “Routing Overview”midi_routing()
Section titled “midi_routing()”Print the complete MIDI picture: output ports, input ports, active track/CC slots, and the clock mode.
midi_routing();Export
Section titled “Export”midi_export(subject, cycles, path?)
Section titled “midi_export(subject, cycles, path?)”Render a pattern or MIDI track set to a Standard MIDI File and return the written path. Without a path, the file lands in the project output directory. Notes, velocities, CC automation, channels, tempo, and track names are exported.
| Subject | File type |
|---|---|
| Pattern | Type 0, single track |
| Timeline | Type 0, single track |
| MidiTrack | Type 1, conductor + track |
| Array of MidiTracks | Type 1, multi-track |
midi_export([C4 E4 G4 C5], 4); // pattern, default pathmidi_export([C4 E4 G4 C5], 4, "melody.mid");
let synth = MidiTrack(2, 100);synth << [C4 E4 G4 C5];synth.cc(74) << Sine(0.25).range(20, 120);midi_export(synth, 8, "synth.mid"); // includes CC automation
let bass = MidiTrack(1, 90);bass << [C2 E2 G2 C3];midi_export(#[bass, synth], 8, "multi_track.mid"); // multi-track SMFSee Also
Section titled “See Also”- MIDI Output · Input & CC · Clock Sync · Export & MPE — guided chapters
- Signals —
Cc()andCc_learn()input signals - Transport — PLAY, STOP, and tempo
- Configuration — preconfiguring MIDI ports