Signatur
Beschreibung
Die Eigenschaft data eines MIDIMessageEvent enthält die Bytes genau einer MIDI-Nachricht, die über einen MIDIInput-Port empfangen wurde. Der Wert ist ein Uint8Array. Das erste Byte ist das Statusbyte. Die oberen 4 Bits geben den Nachrichtentyp an, z. B. 0x90 für Note On, 0x80 für Note Off, 0xB0 für Control Change und 0xE0 für Pitch Bend. Die unteren 4 Bits enthalten den MIDI-Kanal (0–15). Danach folgen je nach Typ 0 bis 2 Datenbytes mit Werten von 0 bis 127.
Du brauchst data, wenn du Eingaben von Keyboards, Pad-Controllern, Fadern oder anderen MIDI-Geräten im Browser auswerten willst, etwa für Synthesizer auf Basis der Web Audio API, für Visualisierungen oder für DAW-ähnliche Anwendungen. Das Event kommt über MIDIInput.onmidimessage oder addEventListener("midimessage", …) an.
Wichtig: Eine Note On-Nachricht mit Velocity 0 ist nach MIDI-Standard gleichbedeutend mit Note Off. Viele Geräte nutzen das. System-Exclusive-Nachrichten (SysEx, beginnend mit 0xF0) können beliebig lang sein. Du empfängst sie nur, wenn der Zugriff mit { sysex: true } angefordert wurde.
Rückgabewert
Beispiele
Rohbytes eingehender Nachrichten protokollieren
const access = await navigator.requestMIDIAccess();
for (const input of access.inputs.values()) {
input.addEventListener('midimessage', (event) => {
// Bytes als Hex-Werte ausgeben
const hex = Array.from(event.data, (b) => b.toString(16).padStart(2, '0'));
console.log(`${input.name}: ${hex.join(' ')}`);
});
}
Note On / Note Off auswerten
const handleMessage = ({ data }) => {
const [status, note, velocity] = data;
const command = status & 0xf0; // Nachrichtentyp
const channel = status & 0x0f; // Kanal 0–15
if (command === 0x90 && velocity > 0) {
console.log(`Note On: ${note}, Velocity ${velocity}, Kanal ${channel + 1}`);
} else if (command === 0x80 || (command === 0x90 && velocity === 0)) {
console.log(`Note Off: ${note}, Kanal ${channel + 1}`);
}
};
const access = await navigator.requestMIDIAccess();
access.inputs.forEach((input) => {
input.onmidimessage = handleMessage;
});
Control Change und Pitch Bend lesen
const onMidi = ({ data }) => {
const command = data[0] & 0xf0;
switch (command) {
case 0xb0: {
// Control Change: Controller-Nummer + Wert
const [, controller, value] = data;
console.log(`CC ${controller} = ${value}`);
break;
}
case 0xe0: {
// Pitch Bend: 14-Bit-Wert aus LSB (data[1]) und MSB (data[2])
const bend = (data[2] << 7) | data[1]; // 0–16383, Mitte 8192
console.log(`Pitch Bend: ${bend - 8192}`);
break;
}
}
};
const access = await navigator.requestMIDIAccess();
access.inputs.forEach((input) => input.addEventListener('midimessage', onMidi));
// Wichtig · Fallstricke
- Browser-Kompatibilität: Die Web MIDI API gibt es in Chromium-Browsern und seit Version 108 auch in Firefox. Safari unterstützt sie nicht. Prüfe deshalb vorher mit
'requestMIDIAccess' in navigator, ob sie verfügbar ist. - Sicherer Kontext:
navigator.requestMIDIAccess()funktioniert nur über HTTPS (oderlocalhost) und kann eine Nutzerberechtigung erfordern. Für SysEx ist{ sysex: true }nötig, was meist eine ausdrückliche Zustimmung verlangt. - Velocity 0: Note On mit Velocity
0bedeutet Note Off. Werte beide Fälle aus, sonst bleiben Töne hängen. - Running Status: Der Browser liefert immer vollständige Nachrichten mit Statusbyte. Du musst Running Status also nicht selbst auflösen.
- Nachrichtenlänge: Die Länge von
datahängt vom Nachrichtentyp ab. Echtzeitnachrichten wie Timing Clock (0xF8) bestehen nur aus 1 Byte. Kommen solche Nachrichten sehr häufig, halte den Handler schlank. - Die Eigenschaft ist schreibgeschützt. Den Inhalt des Arrays zu verändern, hat keinen Einfluss auf das Gerät. Zum Senden verwendest du
MIDIOutput.send().