W3docs

JavaScript Web MIDI API

The Web MIDI API in JavaScript is a powerful tool that enables web developers to interact with musical instruments directly from the browser. This guide will

The Web MIDI API in JavaScript is a powerful tool that enables web developers to interact with musical instruments directly from the browser. This guide will introduce the basics of the Web MIDI API, demonstrate how to access and manipulate MIDI devices, and provide practical examples to integrate music into web applications.

Introduction to Web MIDI API

The Web MIDI API facilitates communication between web applications and MIDI-enabled devices like keyboards and drum machines, allowing for the creation of interactive musical experiences.

Key Features of the Web MIDI API:

  • Device Connectivity: Connects directly to MIDI instruments from the web browser.
  • Real-Time Interaction: Enables dynamic music creation and manipulation in real-time.

Using the Web MIDI API

MIDI messages are composed of status bytes and data bytes. The status byte defines the message type and channel (e.g., 0x90 for Note On, 0x80 or 0x90 with velocity 0 for Note Off), while data bytes carry parameters like note number and velocity.

Accessing MIDI Devices


// Requesting access to MIDI devices
// Browsers automatically prompt the user for permission on first access
async function initMIDI() {
  try {
    const midiAccess = await navigator.requestMIDIAccess();
    console.log('MIDI access obtained', midiAccess);

    // Handle devices connecting or disconnecting dynamically
    midiAccess.onstatechange = (e) => {
      console.log('Device state changed:', e.port.name, e.port.state);
    };

    // Attach the message handler to all available MIDI inputs
    midiAccess.inputs.forEach((input) => {
      input.onmidimessage = onMIDIMessage;
    });
  } catch (err) {
    console.error('Could not access MIDI devices', err);
  }
}
initMIDI();
// This code snippet requests MIDI access, handles dynamic device changes, and attaches the input handler to all connected devices.

Handling MIDI Input


// Handling incoming MIDI messages
function onMIDIMessage(message) {
  // MIDI messages vary in length; standard channel messages are typically 3 bytes
  if (message.data.length < 2) return;
  const [command, note, velocity] = message.data;
  console.log(`MIDI message received: Command=${command}, Note=${note}, Velocity=${velocity}`);
}
// This function logs each MIDI message received, detailing the command, note, and velocity.

Sending MIDI Output


// Getting an output port and sending a note
async function sendNoteOnExample(midiAccess) {
  const outputs = midiAccess.outputs;
  if (outputs.size === 0) {
    console.log('No MIDI outputs available');
    return;
  }
  const midiOutput = Array.from(midiAccess.outputs.values())[0]; // Select the first available port

  midiOutput.send([0x90, 60, 100]); // Note on (0x90 represents channel 1)
  // Note: In production apps, track active notes to send 'note off' when the key is released,
  // rather than using setTimeout, to prevent stuck notes.
  setTimeout(() => {
    midiOutput.send([0x90, 60, 0]); // Note off (0x90 with velocity 0 ensures broader hardware compatibility)
  }, 500);
}
// This function retrieves a connected MIDI output port, sends a 'note on' message, and turns it off after 500 milliseconds.

Conclusion

The Web MIDI API opens up a realm of possibilities for web developers interested in music technology. By leveraging this API, developers can create engaging, interactive web applications that interact with musical instruments, enhancing the user's musical experience. Note: Always check for navigator.requestMIDIAccess availability before use, as browser support varies across older versions.

Practice

Practice

What are the capabilities of the JavaScript Web MIDI API?