Fundamentals
Export Targets
Code Export
Patcher UI
Special Topics
RNBO Raspberry Pi OSCQuery Runner
Sending and Receiving MIDI
@rnbo/js exposes the MIDIEvent class for scheduling MIDI events in your RNBO Patch. Like Message events, you call the scheduleEvent function to schedule a MIDI Event.
@rnbo/js
exposes the MIDIEvent class for scheduling MIDI events in your RNBO Patch. Like Message events, you call the scheduleEvent
function to schedule a MIDI Event. The following example demonstrates how to play a note lasting 250 milliseconds.
const { MIDIEvent } = require("@rnbo/js");
// Assuming a device and audioContext are defined...
function playNote(pitch) {
let midiChannel = 0;
// Format a MIDI message payload, this constructs a MIDI note-on event
let noteOnMessage = [
144 + midiChannel, // Code for a note on: 10010000 & MIDI channel (0-15)
pitch, // MIDI Note
100 // MIDI Velocity
];
let noteOffMessage = [
128 + midiChannel, // Code for a note off: 10000000 & MIDI channel (0-15)
pitch, // MIDI Note
0 // MIDI Velocity
];
let midiPort = 0;
let noteDurationMs = 250;
// When scheduling an event, use the current audio context time
// multiplied by 1000 (converting seconds to milliseconds)
let noteOnEvent = new MIDIEvent(audioContext.currentTime * 1000, midiPort, noteOnMessage);
let noteOffEvent = new MIDIEvent(audioContext.currentTime * 1000 + noteDurationMs, midiPort, noteOffMessage);
device.scheduleEvent(noteOnEvent);
device.scheduleEvent(noteOffEvent);
}
MIDI Payloads and Other MIDI Events
RNBO MIDI payloads consist of three parts: a command byte followed by 1 or 2 parameters. For example, to construct a note on
event, we combine the value for a note on command (0x90 in hex, or 144 in decimal form), with the midi channel on which we want to send the message.
const { MIDIEvent, TimeNow } = require("@rnbo/js");
// Constructing a note-on event
let midiChannel = 0;
let pitch = 60;
let noteOnMessage = [
144 + midiChannel, // Code for a note on: 10010000 & MIDI channel (0-15)
pitch, // MIDI Note
100 // MIDI Velocity
];
let midiPort = 0;
let noteOnEvent = new MIDIEvent(TimeNow, midiPort, noteOnMessage);
Using the same approach, it's possible to schedule MIDI Control Change, Pitch Bend, and other events. See https://ccrma.stanford.edu/~craig/articles/linuxmidi/misc/essenmidi.html for a more thorough overview of the essentials.
Receiving MIDI Events
The RNBO Device class uses an EventSubject for all emitted events. See the example below on how to subscribe to outgoing MIDI events, and visit the JS API Reference for more information about the MIDIEvent class.
const { MIDIEvent } = require("@rnbo/js");
// ev is of type MIDIEvent
device.midiEvent.subscribe((ev) => {
// Handle the outgoing MIDIEvent
let type = ev.data[0];
// Test for note on
if (type >> 4 === 9) {
let pitch = ev.data[1];
let velocity = ev.data[2];
console.log(`Received MIDI note on with pitch ${pitch} and velocity ${velocity}`);
}
});