Experimental

MIDI Controllers

iHearYouCanCode — by David Stein
Connect hardware keyboards, pads, and knobs to trigger sounds and control parameters
↗ WEBMIDI.js Docs

What is MIDI?

MIDI (Musical Instrument Digital Interface) is a protocol for sending musical control data between devices — not audio itself, but instructions like "play middle C", "release that note", or "turn this knob to 75." Your keyboard, drum pad, or fader box sends these tiny messages; your code decides what they mean musically.

The browser exposes MIDI through the low-level Web MIDI API. This tutorial uses WEBMIDI.js v3, which wraps that API with friendly methods like addListener(), playNote(), and sendControlChange() so you can focus on making sound instead of decoding binary messages.

1. Add these lines to your page

Everything runs in your web browser — nothing to install. Copy these lines into your HTML file. Load them in this order: p5.js, p5.sound, ProControls, then WEBMIDI.js.

<!-- Google icon font (optional — used by ProControls) -->
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined&display=block" rel="stylesheet">

<!-- p5.js -->
<script src="https://cdn.jsdelivr.net/npm/p5@1.11.13/lib/p5.min.js"></script>

<!-- p5.sound (requires p5.js above) -->
<script src="https://cdn.jsdelivr.net/npm/p5@1.11.13/lib/addons/p5.sound.min.js"></script>

<!-- ProControls -->
<script src="https://cdn.jsdelivr.net/gh/dstein-art/proControls4p5js@v0.8.3/ProControls.js"></script>

<!-- WEBMIDI.js v3 (IIFE build) -->
<script src="https://cdn.jsdelivr.net/npm/webmidi@3.1.14/dist/iife/webmidi.iife.min.js"></script>

<!-- Your sketch -->
<script src="sketch.js"></script>
Secure origins only: Web MIDI only works on https://, localhost, or file:// pages. Use Chrome, Edge, or Opera, plug in a MIDI controller (or virtual MIDI port), and allow access when the browser prompts you.

2. Enable MIDI and list your devices

Call WebMidi.enable() after a user click — the same gesture that unlocks audio with userStartAudio(). In v3, enable() returns a promise. Once enabled, WebMidi.inputs lists every connected input port (your keyboard, pad controller, etc.).

Click the preview to enable MIDI. Device names are printed to the openConsolePanel() — a ProControls panel that captures console.log() output.

Connect a MIDI controller, then click the preview

Pick a specific input

If you have multiple MIDI devices, grab one by name or index instead of listening on all of them:

var input = WebMidi.getInputByName("IAC Driver Bus 1");
// or
var input = WebMidi.inputs[0];

3. Trigger a synth with note on and note off

noteon starts a note; noteoff stops it. Use midiToFreq() to turn the MIDI note number into a pitch.

Click preview, then play notes

4. Use velocity for dynamics

Velocity is how hard you press (0–127). In your noteon listener, map it to volume:

osc.amp(e.rawVelocity / 127, 0.01);

5. Map knobs with Control Change (CC)

Knobs and faders send controlchange messages. CC 1 is usually the mod wheel. Use e.rawValue (0–127) to drive a parameter.

Move a knob or mod wheel on your controller

Common CC numbers

To listen for one CC only, check e.controller.number inside the listener.

6. Listen on a specific channel

Keys usually send on channel 1; drum pads often send on channel 10. Use input.channels[10] to listen only on that channel.

Hit drum pads on your controller

7. Combine keys, pads, and knobs

Add the { channels: [1] } option to a listener to target one channel. Keys on channel 1 play a synth; pads on channel 10 trigger a sample.

var input = WebMidi.inputs[0];

input.addListener('noteon', function(e) {
  osc.freq(midiToFreq(e.note.number));
  osc.amp(0.5);
}, { channels: [1] });

input.addListener('noteon', function() {
  clap.play();
}, { channels: [10] });

input.addListener('controlchange', function(e) {
  filter.freq(map(e.rawValue, 0, 127, 300, 6000));
});
Tip: For a full-screen test with your controller, copy any example into the p5.js Editor and add the WEBMIDI.js script tag from section 1.

Going further

WEBMIDI.js can also send MIDI — useful if you want your sketch to drive external hardware. Check out WebMidi.outputs, output.playNote(), and output.sendControlChange() in the WEBMIDI.js basics guide. Combine MIDI input with the Effects and Samples tutorials to build a full performance instrument.