Start · Sprachen · JavaScript · Referenz · MIDIMessageEvent

MIDIMessageEvent

Schnittstelle

Ereignisobjekt der Web MIDI API, das beim <code>midimessage</code>-Ereignis eines <code>MIDIInput</code> die empfangenen MIDI-Rohdaten in <code>data</code> bereitstellt.

seit JavaScript Web MIDI API — Chromium-Browser (Chrome/Edge/Opera Kategorie: webapi

Signatur

interface MIDIMessageEvent extends Event

Beschreibung

Ein MIDIMessageEvent wird immer dann ausgelöst, wenn ein angeschlossenes MIDI-Eingabegerät (Keyboard, Controller, Drum-Pad, DAW-Software über einen virtuellen Port) eine Nachricht sendet. Das Ereignis wird am jeweiligen MIDIInput-Objekt als midimessage ausgelöst und lässt sich per addEventListener("midimessage", …) oder über die Eigenschaft onmidimessage abfangen.

Die wichtigste Eigenschaft ist data, ein Uint8Array mit den Rohbytes einer vollständigen MIDI-Nachricht. Das erste Byte ist das Statusbyte: Die oberen 4 Bit geben den Nachrichtentyp an (z. B. 0x90 = Note On, 0x80 = Note Off, 0xB0 = Control Change, 0xE0 = Pitch Bend), die unteren 4 Bit den MIDI-Kanal (0–15). Die folgenden Datenbytes (0–127) enthalten z. B. Notennummer und Anschlagstärke. Zusätzlich erbt das Ereignis timeStamp von Event, das den Empfangszeitpunkt als DOMHighResTimeStamp (vergleichbar mit performance.now()) angibt.

Typische Anwendungsfälle sind Web-Synthesizer mit der Web Audio API, Lernanwendungen für Klavier, Lichtsteuerungen oder das Mappen von Hardware-Reglern auf UI-Elemente. Den Zugriff auf die Geräte erhält man zuvor über navigator.requestMIDIAccess(). Für Tests lässt sich ein Ereignis auch selbst mit dem Konstruktor new MIDIMessageEvent(type, { data }) erzeugen.

Parameter

Name Typ Default Beschreibung
$type Pflicht string Name des Ereignisses, in der Praxis immer "midimessage" (nur beim Konstruktor relevant).
$options object {} Konstruktor-Optionen: data (Uint8Array, die MIDI-Bytes) sowie die üblichen EventInit-Felder bubbles, cancelable, composed.
$data Uint8Array Schreibgeschützte Instanz-Eigenschaft: Rohbytes der MIDI-Nachricht (Statusbyte + Datenbytes).

Rückgabewert

Typ
MIDIMessageEvent
Beschreibung
Der Konstruktor liefert ein neues MIDIMessageEvent; im Handler erhält man das vom Browser erzeugte Ereignisobjekt mit data und timeStamp.

Beispiele

Alle Eingänge abhören und Note-On/Off auswerten

const noteName = (n) => ['C','C#','D','D#','E','F','F#','G','G#','A','A#','B'][n % 12] + (Math.floor(n / 12) - 1);

const handleMessage = (event) => {
  const [status, note, velocity] = event.data;
  const command = status & 0xf0;
  const channel = (status & 0x0f) + 1;

  if (command === 0x90 && velocity > 0) {
    console.log(`Note On  ${noteName(note)} Kanal ${channel} Velocity ${velocity}`);
  } else if (command === 0x80 || (command === 0x90 && velocity === 0)) {
    console.log(`Note Off ${noteName(note)} Kanal ${channel}`);
  }
};

const init = async () => {
  try {
    const access = await navigator.requestMIDIAccess();
    for (const input of access.inputs.values()) {
      input.addEventListener('midimessage', handleMessage);
    }
  } catch (err) {
    console.error('MIDI-Zugriff verweigert:', err);
  }
};

init();
Note On C4 Kanal 1 Velocity 100 Note Off C4 Kanal 1

Drehregler (Control Change) per onmidimessage auf einen Slider mappen

const slider = document.querySelector('#volume');

const access = await navigator.requestMIDIAccess();
const [input] = access.inputs.values();

if (input) {
  input.onmidimessage = ({ data, timeStamp }) => {
    const [status, controller, value] = data;
    // Control Change, Controller 7 = Kanal-Lautstärke
    if ((status & 0xf0) === 0xb0 && controller === 7) {
      slider.value = Math.round((value / 127) * 100);
      console.log(`Lautstärke ${slider.value} % @ ${timeStamp.toFixed(1)} ms`);
    }
  };
}

// Später wieder abmelden:
// input.onmidimessage = null;
Lautstärke 50 % @ 10432.7 ms

Ereignis für Tests manuell erzeugen und wieder entfernen

const target = new EventTarget();

const logger = (e) => console.log(e instanceof MIDIMessageEvent, Array.from(e.data));
target.addEventListener('midimessage', logger);

const fake = new MIDIMessageEvent('midimessage', {
  data: new Uint8Array([0x90, 60, 127])
});
target.dispatchEvent(fake);

target.removeEventListener('midimessage', logger);
target.dispatchEvent(fake); // keine Ausgabe mehr
true [144, 60, 127]

// Wichtig · Fallstricke

  • Browser-Kompatibilität: Unterstützt in Chrome, Edge, Opera und Firefox (ab 108); Safari unterstützt die Web MIDI API nicht. Vorher mit 'requestMIDIAccess' in navigator prüfen.
  • Sicherer Kontext & Berechtigung: Nur über HTTPS (oder localhost) verfügbar; der Nutzer muss den Zugriff bestätigen. In iframes ist die Permissions-Policy midi nötig.
  • Note On mit Velocity 0: Viele Geräte senden statt Note Off (0x80) ein Note On (0x90) mit Velocity 0 – beide Fälle behandeln.
  • Nachrichtenlänge variiert: data kann 1 Byte (z. B. Timing Clock 0xF8, bis zu 24× pro Viertelnote!), 2, 3 oder bei SysEx beliebig viele Bytes enthalten. Clock-/Active-Sensing-Nachrichten (0xF8, 0xFE) früh herausfiltern, um den Handler nicht zu überlasten.
  • SysEx: System-Exclusive-Nachrichten (0xF0) kommen nur an, wenn mit requestMIDIAccess({ sysex: true }) angefragt wurde – das löst eine gesonderte Berechtigungsabfrage aus.
  • Die veraltete Eigenschaft receivedTime existiert nicht mehr; stattdessen event.timeStamp verwenden.
  • Ein Listener per addEventListener öffnet den Port implizit; onmidimessage ebenso.