Learn Sending and Receiving MIDI

Getting Started

Welcome to RNBO

Quickstart

RNBO Basics

Key Differences

Why We Made RNBO

Coding Resources

Fundamentals

Audio IO

Messages to rnbo~

Using Parameters

MIDI in RNBO

Messages and Ports

Polyphony and Voice Control

Audio Files in RNBO

Using Buffers

Using the FFT

Export Targets

Export Targets Overview

VST/AudioUnit
Max External Target
Raspberry Pi Target
The Web Export Target
The C++ Source Code Target

Code Export

Working with JavaScript
Working with C++

Special Topics

Sample Accurate Patching
Scala and Custom Tuning

RNBO and Max for Live

RNBO Raspberry Pi OSCQuery Runner

Metadata

Export Description

Raspberry Pi GPIO

Updating the RNBO Package

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}`);
    }
});