Class: MIDIController

MIDIController(options)

Main controller for browser-based MIDI operations. Provides APIs for: - Device management (connect/disconnect, enumerate devices) - Control binding (DOM elements <-> MIDI CC) - MIDI messaging (send/receive CC, Note, SysEx) - Patch management (save/load presets) - Event handling (MIDI messages, connection changes, errors)

Constructor

new MIDIController(options)

Parameters:
Name Type Description
options Object
Properties
Name Type Attributes Default Description
inputChannel number <optional>
1 Input MIDI channel (1-16)
outputChannel number <optional>
1 Output MIDI channel (1-16)
output string | number <optional>
MIDI output device
input string | number <optional>
MIDI input device
sysex boolean <optional>
false Request SysEx access
autoConnect boolean <optional>
true Auto-connect to first available output
onReady function <optional>
Callback when MIDI is ready
onError function <optional>
Error handler
Source:
Examples
// Basic initialization
const midi = new MIDIController({ inputChannel: 1, outputChannel: 1 });
await midi.init();
// Bind UI controls to MIDI CCs
const volumeSlider = document.getElementById("volume");
midi.bind(volumeSlider, { cc: 7 }); // Bind CC 7 (volume)
// Send MIDI messages
midi.channel.sendCC(74, 64); // Send CC 74 (filter cutoff) value 64
midi.channel.sendNoteOn(60, 100); // Play middle C with velocity 100
midi.channel.sendNoteOff(60); // Stop middle C
// Listen for MIDI events
midi.on(CONTROLLER_EVENTS.CH_CC_RECV, ({ cc, value, channel }) => {
  console.log(`CC ${cc} received: ${value}`);
});
// Save and load patches
const patch = midi.patch.get("My Patch");
midi.patch.save("My Patch");
midi.patch.load("My Patch");

Extends

Classes

MIDIController

Namespaces

channel
device
patch
system

Methods

bind(element, config, optionsopt) → {function}

Bind a DOM element to a MIDI CC for bidirectional control. Automatically handles value normalization based on element type (slider, knob, etc.) and MIDI range (0-127). Sends initial MIDI value when binding if controller is initialized.
Parameters:
Name Type Attributes Default Description
element HTMLElement DOM element to bind (e.g., input range, number input)
config Object Binding configuration
Properties
Name Type Attributes Default Description
cc number CC number (0-127, e.g., 7 for volume, 74 for filter cutoff)
min number <optional>
0 Minimum input value (auto-detected from element if available)
max number <optional>
127 Maximum input value (auto-detected from element if available)
channel number <optional>
MIDI channel (defaults to controller's default channel)
invert boolean <optional>
false Invert the value mapping
is14Bit boolean <optional>
false Use 14-bit CC (MSB + LSB, requires msb/lsb config)
msb number <optional>
MSB CC number for 14-bit control
lsb number <optional>
LSB CC number for 14-bit control
onInput function <optional>
Optional callback for value updates (receives normalized element value)
options Object <optional>
{} Additional options
Properties
Name Type Attributes Default Description
debounce number <optional>
0 Debounce delay in ms for high-frequency updates
Source:
Returns:
Unbind function - Call to remove binding and cleanup event listeners
Type
function
Examples
// Basic slider binding
const volumeSlider = document.getElementById("volume");
const unbindVolume = midi.bind(volumeSlider, { cc: 7 }); // CC 7 = Channel Volume
// Binding with custom range and inversion
const filterKnob = document.getElementById("filter");
midi.bind(filterKnob, {
  cc: 74,        // CC 74 = Filter Cutoff
  min: 0,        // Knob minimum value
  max: 127,      // Knob maximum value
  invert: true   // Invert value (useful for cutoff - higher CC = brighter)
});
// 14-bit high-resolution control
const fineTune = document.getElementById("fine-tune");
midi.bind(fineTune, {
  is14Bit: true,
  msb: 0,    // CC 0 = MSB
  lsb: 32    // CC 32 = LSB
});
// With debouncing for high-frequency updates
const lfoRate = document.getElementById("lfo-rate");
midi.bind(lfoRate, { cc: 76 }, { debounce: 50 }); // 50ms debounce
// Using callback to update display
const pitchSlider = document.getElementById("pitch");
const pitchDisplay = document.getElementById("pitch-value");
midi.bind(pitchSlider, {
  cc: 75,
  onInput: (value) => {
    pitchDisplay.textContent = Math.round(value);
  }
});

(async) destroy() → {Promise.<void>}

Clean up resources
Source:
Returns:
Type
Promise.<void>

emit(event, data)

Emit an event
Parameters:
Name Type Description
event string Event name
data * Event data
Overrides:
Source:

(async) init() → {Promise.<void>}

Initialize MIDI access. Requests browser permission and connects to devices. Emits "ready" event on success, "error" event on failure.
Source:
Fires:
  • CONTROLLER_EVENTS.event:READY - When initialization succeeds
  • CONTROLLER_EVENTS.event:ERROR - When initialization fails
Throws:
If MIDI access is denied or browser doesn't support Web MIDI
Type
MIDIAccessError
Returns:
Type
Promise.<void>
Examples
// Basic initialization
const midi = new MIDIController();
await midi.init();
// Initialization with custom options
const midi = new MIDIController({
  channel: 2,
  sysex: true,
  autoConnect: false
});
await midi.init();
// With event listeners
const midi = new MIDIController();
midi.on(CONTROLLER_EVENTS.READY, (controller) => {
  console.log("MIDI ready!");
});
midi.on(CONTROLLER_EVENTS.ERROR, (error) => {
  console.error("MIDI error:", error);
});
await midi.init();

off(event, handler)

Remove an event listener
Parameters:
Name Type Description
event string Event name
handler function Event handler function
Overrides:
Source:

on(event, handler) → {function}

Register an event listener
Parameters:
Name Type Description
event string Event name
handler function Event handler function
Overrides:
Source:
Returns:
Unsubscribe function
Type
function

once(event, handler)

Register a one-time event listener
Parameters:
Name Type Description
event string Event name
handler function Event handler function
Overrides:
Source:

removeAllListeners(eventopt)

Remove all event listeners
Parameters:
Name Type Attributes Description
event string <optional>
Optional event name to clear specific event
Overrides:
Source:

send(data)

Send raw MIDI data
Parameters:
Name Type Description
data Array.<number> MIDI message bytes
Source:

unbind(element)

Unbind a control
Parameters:
Name Type Description
element HTMLElement
Source:

Type Definitions

ChannelData

Channel-specific MIDI data
Type:
  • Object
Properties:
Name Type Attributes Description
ccs Object.<number, number> Control Change values indexed by CC number (0-127)
notes Object.<number, number> Note on/off states indexed by note number (0-127)
program number <optional>
Program change value for the channel (0-127)
pitchBend number <optional>
Pitch bend value for the channel (0-16383, center=8192)
monoPressure number <optional>
Channel pressure/aftertouch value (0-127)
polyPressure Object.<number, number> <optional>
Polyphonic pressure values indexed by note number
Source:

PatchData

Complete patch data structure for saving/loading controller state
Type:
  • Object
Properties:
Name Type Description
name string Patch/preset name
device string | null Output device name (if saved with device)
timestamp string ISO timestamp when patch was created
version string Patch format version (e.g., "1.0")
channels Object.<number, ChannelData> Channel data indexed by channel number (1-16)
settings Object.<string, SettingData> Control settings indexed by control key
Source:
Example
const patch = {
  name: "My Synth Patch",
  device: "My MIDI Keyboard",
  timestamp: "2024-01-15T10:30:00.000Z",
  version: "1.0",
  channels: {
    1: {
      ccs: { 7: 100, 74: 64 },
      program: 5,
      pitchBend: 8192
    }
  },
  settings: {
    cc7: { min: 0, max: 127, invert: false, is14Bit: false, label: "Volume" }
  }
};

SettingData

Control binding settings
Type:
  • Object
Properties:
Name Type Description
min number Minimum input value
max number Maximum input value
invert boolean Whether to invert the value mapping
is14Bit boolean Whether this is a 14-bit CC control
label string | null Optional display label
elementId string | null Associated DOM element ID
onInput function | null Optional callback for value updates
Source: