Learn Routing MIDI Between Devices

Getting Started

Welcome to RNBO

Quickstart

RNBO Basics

Key Differences

Why We Made RNBO

Fundamentals

Audio IO

Messages to rnbo~

Using Parameters

MIDI in RNBO

Messages and Ports

Polyphony and Voice Control

Audio Files in RNBO

Using Buffers

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

Raspberry Pi Debug Interface

Metadata

Raspberry Pi GPIO

Updating the RNBO Package

Routing MIDI Between Devices

When working with multiple RNBO devices in a single web page, you can think of each device is essentially its own little world. Connecting devices together using device.node.connect will tell WebAudio to do the work of calling into a device, fetching its output audio, and then sending that audio to the next device as input.

The WebAudio engine will handle moving audio buffers between different processing nodes for you. As of now, there is no equivalent mechanism in WebAudio for moving MIDI events between nodes. Suppose you have two RNBO devices—one a MIDI sequencer and one a MIDI synthesizer. To connect the two, you'll need to forward the MIDI events from one device to the other.

const { createDevice } = require("@rnbo.js");

// Create AudioContext
const WAContext = window.AudioContext || window.webkitAudioContext;
const context = new WAContext();

// Create a gain node and connect it to audio output
const outputNode = context.createGain();
outputNode.connect(context.destination);
    
// Fetch both the MIDI patcher and the synth patcher
let response = await fetch("export/midi-maker.export.json");
let midiPatcher = await response.json();
response = await fetch("export/simple-synth.export.json");
let synthPatcher = await response.json();

// Create the devices
const midiDevice = await createDevice({ context, patcher: midiPatcher });
const synthDevice = await createDevice({ context, patcher: synthPatcher });

// Connect the device to the web audio graph
synthDevice.node.connect(outputNode);

// Forward MIDI events from the MIDI device to the synth device
// ev is of type MIDIEvent
midiDevice.midiEvent.subscribe((ev) => {
    synthDevice.scheduleEvent(ev);
});

You should be aware that when chaining devices in this way, events are passed from RNBO back to the browser's JavaScript engine. This means that precise timing information will be lost. If sample accurate timing is critical, you can use an audio channel to represent events instead.

Materials in this article

  • Chaining MIDI Patch