MIDI Input
This content is for v0.7. Switch to the latest version for up-to-date documentation.
Route MIDI from external keyboards, controllers, and instruments into Resonon tracks.
Listing Input Ports
Section titled “Listing Input Ports”midi_input_ports() returns an array of available MIDI input port names:
let in_ports = midi_input_ports();PRINT in_ports;// ["IAC Driver Resonon", "USB MIDI Keyboard"]Connecting an Input Port
Section titled “Connecting an Input Port”midi_input_connect(port, alias) opens a connection and assigns it an alias for later reference:
midi_input_connect("IAC Driver Resonon", "iac");The alias is a short name you choose. Use it when routing input to tracks.
Substring matching
Section titled “Substring matching”The port name does not need to be exact. Resonon tries an exact match first, then falls back to substring matching:
// Full port name is "Arturia KeyStep 37"midi_input_connect("KeyStep", "kb");If multiple ports contain the substring, the first match is used. Use a more specific substring or the full name to avoid ambiguity.
Alias uniqueness
Section titled “Alias uniqueness”Each alias must be unique. Connecting a second port with the same alias produces an error:
Input port alias 'kb' already connectedDisconnect the existing alias first if you need to reuse it.
Routing Input to Tracks
Section titled “Routing Input to Tracks”All channels
Section titled “All channels”.input(alias) routes all MIDI channels from the named input to the track:
let keys = MidiTrack(1, 100).input("iac");Specific channel
Section titled “Specific channel”.input(alias, channel) filters to a single MIDI channel:
let bass = MidiTrack(2, 100).input("iac", 1);All connected ports
Section titled “All connected ports”The special alias "all" listens to every connected input port:
let omni = MidiTrack(3, 80).input("all");Monitor Modes
Section titled “Monitor Modes”Monitor mode controls whether incoming MIDI is passed through to the track’s output.
| Mode | Behavior |
|---|---|
"off" | No pass-through (default) |
"in" | Always pass input through to output |
"auto" | Pass through only when no pattern is playing |
// Always hear the keyboardlet keys = MidiTrack(1, 100).input("iac").monitor("in");
// Hear keyboard only when the track is idlelet keys_auto = MidiTrack(1, 100).input("iac").monitor("auto");
// Silent monitoring (record only)let keys_off = MidiTrack(1, 100).input("iac").monitor("off");Thru-Play Behavior
Section titled “Thru-Play Behavior”When monitor mode is "in" or "auto", incoming MIDI events are forwarded to the track’s output port. Several things happen during thru-play:
Channel remapping
Section titled “Channel remapping”Incoming MIDI is remapped to the track’s output channel. If your keyboard sends on channel 1 but the track outputs on channel 5, the forwarded notes arrive on channel 5. This keeps thru-play consistent with pattern output.
Feedback detection
Section titled “Feedback detection”If an input port and output port form a loop (for example, both connected to the same IAC bus), events can circulate endlessly. Resonon detects this automatically: if thru-play exceeds the rate limit, it is temporarily suppressed. You will see a warning in the console:
[resonon] MIDI feedback loop detected on ch1 — thru-play suppressed (will retry after 1000ms cooldown)After a brief cooldown, thru-play re-enables automatically. To avoid feedback loops, use separate ports for input and output, or set monitor mode to "off".
CC value capture
Section titled “CC value capture”Incoming CC messages are automatically captured and made available as Cc() signal sources. For example, if your controller sends CC 1 (mod wheel), that value is immediately usable in patterns and modulation. See MIDI CC for details on using CC signals.
Full Chain with Builder Pattern
Section titled “Full Chain with Builder Pattern”Chain .with_input(), .with_monitor(), and .with_output() in a single expression for a complete input-to-output routing:
let thru = MidiTrack(1, 100) .with_input("iac") .with_monitor("in") .with_output("iac");This creates a track that receives from the "iac" input, monitors everything, and sends to the "iac" output.
MIDI Clock & Timing
Section titled “MIDI Clock & Timing”Clock Send (Master Mode)
Section titled “Clock Send (Master Mode)”midi_clock_send(true) enables 24 PPQ clock output to all connected MIDI output ports. Resonon becomes the clock master, sending Start, Stop, and Continue transport messages alongside clock ticks.
midi_connect("IAC Driver Bus 1", "daw");midi_clock_send(true);setbpm(120);PLAY;Disable with midi_clock_send(false).
Clock send and clock follow are mutually exclusive — enabling one disables the other.
Clock Follow (Follower Mode)
Section titled “Clock Follow (Follower Mode)”midi_clock_follow(alias) syncs Resonon’s tempo and transport to an external MIDI clock source arriving on the named input port:
midi_input_connect("DAW Output", "daw");midi_clock_follow("daw");When clock follow is active:
- Tempo is derived by averaging 24 ticks (one quarter note)
- Start resets playback to the beginning
- Stop pauses playback
- Continue resumes from the current position
- A soft PLL applies phase correction (up to ~1ms per quarter note) to stay tightly locked
Disable clock follow by passing false:
midi_clock_follow(false);MIDI Output Delay
Section titled “MIDI Output Delay”midi_delay(ms) adds a global delay (in milliseconds) to all outgoing MIDI — notes and clock. This is useful for compensating audio output latency so that MIDI and audio stay aligned.
midi_delay(15); // delay all MIDI output by 15msPRINT midi_delay(); // getter: prints 15Clock Offset
Section titled “Clock Offset”midi_clock_offset(ms) adds an offset (in milliseconds) applied only to clock ticks. Positive values delay ticks, negative values send them earlier.
midi_clock_offset(-5); // send clock ticks 5ms earlyPRINT midi_clock_offset(); // getter: prints -5Clock offset is independent of midi_delay(). The total delay on clock ticks is midi_delay() + midi_clock_offset():
midi_delay(15); // all MIDI delayed 15msmidi_clock_offset(-5); // clock ticks shifted 5ms earlier// Effective clock delay: 15 + (-5) = 10ms// Effective note delay: 15msClock & Timing Summary
Section titled “Clock & Timing Summary”| Function | Description |
|---|---|
midi_clock_send(true) | Enable 24 PPQ clock output (master mode) |
midi_clock_send(false) | Disable clock output |
midi_clock_follow(alias) | Sync to external clock on input port |
midi_clock_follow(false) | Disable clock follow |
midi_delay(ms) | Set global MIDI output delay (notes + clock) |
midi_delay() | Get current output delay in ms |
midi_clock_offset(ms) | Set clock-only offset (positive = later, negative = earlier) |
midi_clock_offset() | Get current clock offset in ms |
Inspecting Routing
Section titled “Inspecting Routing”midi_routing() prints a summary of all MIDI connections, active slots, and clock state:
midi_routing();Example output:
MIDI Routing
Output Ports: "daw" -> "IAC Driver Bus 1" "synth" -> "Prophet Rev2"
Input Ports: "kb" -> "Arturia KeyStep 37"
Active Slots: ch1 -> "daw" (ch 1) synth:ch1 -> "synth" (ch 1)
Clock: mode: follower (from "kb")In master mode, the clock section shows the send state:
Clock: mode: master (sending)If nothing is connected, it shows (no MIDI connections).
Disconnecting
Section titled “Disconnecting”midi_input_disconnect(alias) closes the named input connection:
midi_input_disconnect("iac");On disconnect, Resonon sends All Notes Off (CC 123) to any output ports that were receiving thru-play from the disconnected input. This prevents stuck notes when you unplug or disconnect a controller mid-performance.
Complete Example
Section titled “Complete Example”A full workflow: list ports, connect with substring matching, create a track with input and monitoring, inspect routing, play, and clean up:
// List available portsPRINT midi_input_ports();PRINT midi_ports();
// Connect ports (substring match)midi_input_connect("KeyStep", "kb");midi_connect("IAC Driver Bus 1", "daw");
// Create a pass-through tracklet keys = MidiTrack("keys", 1, 100) .with_input("kb") .with_monitor("in") .with_output("daw");
// Check the routingmidi_routing();
PLAY;
// ... play your MIDI keyboard ...
PAUSE;
// Clean upmidi_input_disconnect("kb");midi_disconnect("daw");Debugging and Introspection
Section titled “Debugging and Introspection”Common errors
Section titled “Common errors”| Error | Cause | Fix |
|---|---|---|
Input port alias '...' already connected | Alias already in use | Disconnect the alias first, or choose a different alias |
No MIDI input connected with alias '...' | Clock follow with unrecognized alias | Connect the input port with midi_input_connect() first |
| Port not found | Port name not recognized | Check midi_input_ports() for available names |
MIDI feedback loop detected on ch... | Thru-play forming a loop | Use separate ports for input and output, or set monitor to "off" |
Introspection calls
Section titled “Introspection calls”// List available input portsPRINT midi_input_ports();
// Show full MIDI routing statemidi_routing();See Also
Section titled “See Also”- MIDI Tracks — send patterns to MIDI outputs
- MIDI CC — use CC messages as modulation sources
- MIDI Setup — configure MIDI ports