You can write programs that wait on MIDI events and deliver them to Anodes for performance.
Here's program that opens a MIDI device and logs the first 30 MIDI events (notes or CCs). If you have a MIDI device, this is a great way to learn more about MIDI.
let port = 0;
let midiInput = new MidiIn(port);
let ok = await midiInput.Open();
console.log("midiInput.open returned " + ok);
for(let i=0;i<30;i++)
{
    let data = await midiInput.Recv(); // "blocks" until activity
    console.log(`${i}: ${data}`);
}
console.log("midiInput.close");
midiInput.Close();
| Function | Description | 
|---|---|
async Midi.Probe() | 
Probes your system's MIDI devices. Returns an object describing available input and output devices. | 
Midi.Parse(msg) | 
Parses the MIDI msg and returns an object describing its contents. | 
Midi.Perform(anode, msg, pws, verbose, clapExpr) | 
Parses the MIDI msg and converts it to anode method calls. pws is PitchWheel semitones. Set clapExpr to true if your anode prefers that. | 
MidiIn is a class used to listen to live MIDI events from an invididual MIDI device.
| Method | Description | 
|---|---|
constructor(port || object | 
returns a MidiIn instance defined by the port or returns by Midi.Probe() | 
async Open() | 
returns a promise that resolves to "ok" on success. | 
Close() | 
removes MidiIn instance subscription to MIDI events. | 
Perform(anode, msg) | 
invokes Midi.Perform (above). | 
Subscribe(callback) | 
clients can subscribe to MIDI events. When they occur the msg is passed to callback. | 
async Recv() | 
clients can wait on MIDI activity. Recv returns a promise that resolves to msg. | 
MidiFile is a class used to perform MIDI files.
| Method | Description | 
|---|---|
async Load(midiFile) | 
returns a promise that resolves to 0 on success, non-zero on error. | 
GetFormat() | 
returns a number 0,1,2 representing the MIDI file format. | 
GetNumTracks() | 
returns the number of tracks in the MIDI file. | 
async *Perform(scene, notehandle, startTime, cfg) * | 
This is an async generator which can be iterated over to perform a file. | 
async *PerformTrack(itrk, scene, notehandler, startTime, cfg) * | 
This is an async generator which can be iterated over to perform a track. | 
Dump() | 
Logs the contents of the loaded file. NB: output is copious. | 
* Perform Cfg | 
Description | 
|---|---|
speed | 
1 | 
setTempo | 
"once", "never", "always" | 
programChange | 
"allow" | 
programMapper | 
function(oldProg, trk) | 
dumpTrack | 
false, logs the contents of the loaded file (noisey). | 
dumpJoin | 
only relevent when dumpTrack is true, true: means combine events across tracks. | 
MidiOut is a NoteHandler that converts NoteHandler rmessage to MIDI messages.
| Method | Description | 
|---|---|
constructor(port || object) | 
returns a MidiOut instance defined by the port or returns by Midi.Probe() | 
async Open() | 
returns a promise that resolves to "ok" on success. | 
Close() | 
Closes MidiOut. | 
ProgramChange(newpgr) | 
Request a MIDI program change event. | 
ControlChange(cc, val) | 
Request a MIDI control change event. | 
async Note(key, velocity, dur) | 
Play a Note on MIDI key with velocity and duration in milliseconds. | 
NoteOn(key, velocity) | 
Request a NoteOn event on MIDI key with velocity. | 
NoteOff(key, velocity) | 
Request a NoteOff event on MIDI key with velocity. | 
NoteExpression(clapexpr, value) | 
Request a NoteExpression desribed the the clap event. | 
You can quickly probe for MIDI devices using Hz's command-line interface (CLI).
% Hz --midi:help
midi options:
    --midi:probe (exits)
    --midi:getinputport:name (case-sensitive, exits)
    --midi:help (this message, exits)
Here's a typical result from probing the MIDI. Your results obviously depend on your MIDI and System configuration. Currently the small integer index associated with a device is required to open it (below).
% Hz --midi:probe
m info --- MIDI APIs -------------------------------             (Hz 08:30:01)
m info  Windows MultiMedia -----
m info   3 input sources:
m info     0: 3- A-Series Keyboard 0
m info     1: loopMIDI Port 1
m info     2: loopMIDI Port 1 2
m info   5 outputs:
m info     0: Microsoft GS Wavetable Synth 0
m info     1: 3- A-Series Keyboard 1
m info     2: 3- A-Series Keyboard MIDI OUT 2
m info     3: loopMIDI Port 3
m info     4: loopMIDI Port 1 4