Skip to content

Receiving MIDI

Inbound MIDI messages arrive on MIDIInput as standard MIDIMessageEvent objects. Two subscription styles are available.

import { requestMIDIAccess } from "react-native-midi-api";
import type { MIDIMessageEvent } from "react-native-midi-api";
const midi = await requestMIDIAccess();
for (const input of midi.inputs.values()) {
input.onmidimessage = (event: MIDIMessageEvent) => {
const data = event.data; // Uint8Array
const statusByte = data[0];
const type = statusByte & 0xf0;
const channel = statusByte & 0x0f;
switch (type) {
case 0x90: // Note On
console.log(`Note On ch=${channel + 1} note=${data[1]} vel=${data[2]}`);
break;
case 0x80: // Note Off
console.log(`Note Off ch=${channel + 1} note=${data[1]}`);
break;
case 0xb0: // Control Change
console.log(`CC ch=${channel + 1} cc=${data[1]} val=${data[2]}`);
break;
}
};
}
input.addEventListener("midimessage", (event: MIDIMessageEvent) => {
console.log("MIDI bytes:", Array.from(event.data));
});

event.receivedTime is a DOMHighResTimeStamp (milliseconds, same domain as performance.now()) representing when the message was received:

input.onmidimessage = (event: MIDIMessageEvent) => {
const latencyMs = performance.now() - event.receivedTime;
console.log(`Received at ${event.receivedTime.toFixed(2)} ms, latency ${latencyMs.toFixed(2)} ms`);
};
const handler = (event: MIDIMessageEvent) => { /* … */ };
input.addEventListener("midimessage", handler);
// Later:
input.removeEventListener("midimessage", handler);
// Or clear the shorthand:
input.onmidimessage = null;