MIDI Setup
Aether connects to MIDI input hardware and software via virtual devices - abstract routing slots that nodes bind against. A virtual device routes one or more physical MIDI input ports into the graph; the indirection lets a graph keep working when hardware is swapped, as long as the virtual device stays in place.
0.1.0 is input-only. There is no MIDI output node or MIDI-out routing in this release; Aether does not send MIDI to external hardware or act as a clock source. MIDI is consumed, not produced.
Virtual Devices
Virtual devices are created and managed from the Project Explorer panel (under the MIDI Device resource type), not a dedicated MIDI panel. Each has:
- A name - human-readable, used in bindings.
- One or more physical ports - the hardware or software input ports routed into this device.
- Slots - named MIDI event sources captured via Learn on a downstream node. Learn captures either a CC (controller number) or a Note (pitch number); other message types (pitchbend, aftertouch, program change) are not learnable in 0.1.0.
To create one: in the Project Explorer, switch to the MIDI Device resource type and click New Device. Click Refresh Ports after plugging in hardware if its ports don't appear immediately. Right-click a device entry to Delete it; deletion removes the device and its bindings.
Renaming a device is available via the command palette or a Rhai rename_midi_device() call - there's no inline-rename UI on the device row in 0.1.0. Individual slots inside a device can be renamed inline from the properties panel.
Routing Hardware In
Plug a MIDI controller, then select the virtual device in the Project Explorer. The Properties panel shows the device with an Add Port dropdown - pick the controller's physical port from the list. Messages from that port now flow through this virtual device.
Aether registers hot-plug events via CoreMIDI on macOS: plugging or unplugging a controller while Aether is running updates the port list essentially immediately. Click Refresh Ports if a newly-connected device needs an explicit re-scan.
Caveat: changing audio device settings does require a restart (see Audio Device Setup). MIDI is independent and hot-swappable.
MIDI Learn
Numeric and boolean properties on a node can be bound to a MIDI CC (or a note) via Learn. Properties of type Float, Int, Bool, or Normalized expose a Learn indicator; enums, strings, envelopes, curves, colours, and read-only properties do not.
Each learnable property row in the node's properties panel has a small circular MIDI indicator to the right of its control. Click it to enter learn mode - the next CC or note-on received from any routed virtual device is captured and bound to that property. The indicator is a small dot that changes colour: dim means unbound, amber means learning, blue means bound. Hover it for a tooltip describing the current state.
The detailed binding label (source device + slot name) appears in a MIDI binding section on the node's properties panel below the property rows, not on the indicator itself.
Click a bound indicator to unbind. To re-learn, unbind first, then click again to start a new learn session. Multiple properties can bind to the same CC - one knob controls several things.
Pickup (Soft Takeover)
Bindings use pickup by default: when a graph loads or reconnects, the controller's current value does not snap to the property until the knob crosses the saved value. This prevents jumps when a controller's physical knob position does not match the loaded project.
Note Input
Many nodes expose a MIDI In port that accepts a MIDI stream - Polysynth, Keyboard, Arpeggiator, MidiSampleHold, Oscillator, and more; the node reference lists every port. Wire a virtual device's MIDI stream (or another node's MIDI Out) into the MIDI In of the receiver and notes route through.
Note: the Sequencer playback node does not have a MIDI In port; it's configured via a Config In data port from a SequencerEditor (or via Rhai). Sequencer emits MIDI, it doesn't consume it.
The stream carries note-on and note-off with velocity and channel information. Polyphonic allocation happens inside the receiving node - Polysynth caps simultaneous voices at its max_voices config (8 by default, not exposed as a user-editable property in 0.1.0); when all voices are busy, the oldest active voice is stolen.
The Keyboard node is dual-purpose: its 88-key display both visualises incoming MIDI (from any node wired into its MIDI In) and lets you click keys on the canvas to emit note-on / note-off events downstream. Clicks and pass-through notes both light up the same key strip.
Where Bindings Live
Bindings are stored per-project in the .aether file, not globally. A saved project reopens with its MIDI bindings intact - subject to the device names matching. If the virtual device was renamed between sessions the binding may not rebind automatically; re-learn on the affected property to recover.
Related
- Audio Device Setup - audio I/O configuration, separate from MIDI.
- No Audio - sometimes reported as a MIDI issue when the actual problem is audio routing.