Skip to main content

WebMidi

The WebMidi object makes it easier to work with the low-level Web MIDI API. Basically, it simplifies sending outgoing MIDI messages and reacting to incoming MIDI messages.

When using the WebMidi.js library, you should know that the WebMidi class has already been instantiated. You cannot instantiate it yourself. If you use the IIFE version, you should simply use the global object called WebMidi. If you use the CJS (CommonJS) or ESM (ES6 module) version, you get an already-instantiated object when you import the module.

Extends: EventEmitter

Fires: connected, disabled, disconnected, enabled, error, midiaccessgranted, portschanged

Constructorโ€‹

The WebMidi class is a singleton and you cannot instantiate it directly. It has already been instantiated for you.


Propertiesโ€‹

.defaultsโ€‹

Type: object

Object containing system-wide default values that can be changed to customize how the library works.

Properties

PropertyTypeDescription
defaults.noteobjectDefault values relating to note
defaults.note.attacknumberA number between 0 and 127 representing the default attack velocity of notes. Initial value is 64.
defaults.note.releasenumberA number between 0 and 127 representing the default release velocity of notes. Initial value is 64.
defaults.note.durationnumberA number representing the default duration of notes (in seconds). Initial value is Infinity.

.enabledโ€‹

Type: boolean
Attributes: read-only

Indicates whether access to the host's MIDI subsystem is active or not.

.eventCountโ€‹

Type: number
Attributes: read-only

The number of unique events that have registered listeners.

Note: this excludes global events registered with EventEmitter.ANY_EVENT because they are not tied to a specific event.

.eventMapโ€‹

Type: Object
Attributes: read-only

An object containing a property for each event with at least one registered listener. Each event property contains an array of all the Listener objects registered for the event.

.eventNamesโ€‹

Type: Array.<string>
Attributes: read-only

An array of all the unique event names for which the emitter has at least one registered listener.

Note: this excludes global events registered with EventEmitter.ANY_EVENT because they are not tied to a specific event.

.eventsSuspendedโ€‹

Type: boolean

Whether or not the execution of callbacks is currently suspended for this emitter.

.inputsโ€‹

Type: Array.<Input>
Attributes: read-only

An array of all currently available MIDI inputs.

.interfaceโ€‹

Type: MIDIAccess
Attributes: read-only

The MIDIAccess instance used to talk to the lower-level Web MIDI API. This should not be used directly unless you know what you are doing.

.octaveOffsetโ€‹

Since: 2.1
Type: number

An integer to offset the octave of notes received from external devices or sent to external devices.

When a MIDI message comes in on an input channel the reported note name will be offset. For example, if the octaveOffset is set to -1 and a "noteon" message with MIDI number 60 comes in, the note will be reported as C3 (instead of C4).

By the same token, when OutputChannel.playNote() is called, the MIDI note number being sent will be offset. If octaveOffset is set to -1, the MIDI note number sent will be 72 (instead of 60).

.outputsโ€‹

Type: Array.<Output>
Attributes: read-only

An array of all currently available MIDI outputs as Output objects.

.supportedโ€‹

Type: boolean
Attributes: read-only

Indicates whether the environment provides support for the Web MIDI API or not.

Note: in environments that do not offer built-in MIDI support, this will report true if the navigator.requestMIDIAccess function is available. For example, if you have installed WebMIDIAPIShim.js but no plugin, this property will be true even though actual support might not be there.

.sysexEnabledโ€‹

Type: boolean
Attributes: read-only

Indicates whether MIDI system exclusive messages have been activated when WebMidi.js was enabled via the enable() method.

.timeโ€‹

Type: DOMHighResTimeStamp
Attributes: read-only

The elapsed time, in milliseconds, since the time origin. Said simply, it is the number of milliseconds that passed since the page was loaded. Being a floating-point number, it has sub-millisecond accuracy. According to the documentation, the time should be accurate to 5 ยตs (microseconds). However, due to various constraints, the browser might only be accurate to one millisecond.

Note: WebMidi.time is simply an alias to performance.now().

.validationโ€‹

Type: boolean

Indicates whether argument validation and backwards-compatibility checks are performed throughout the WebMidi.js library for object methods and property setters.

This is an advanced setting that should be used carefully. Setting validation to false improves performance but should only be done once the project has been thoroughly tested with validation turned on.

.versionโ€‹

Type: string
Attributes: read-only

The version of the library as a semver string.


Methodsโ€‹

.addListener(...)โ€‹

Adds a listener for the specified event. It returns the Listener object that was created and attached to the event.

To attach a global listener that will be triggered for any events, use EventEmitter.ANY_EVENT as the first parameter. Note that a global listener will also be triggered by non-registered events.

Parameters

Signature: addListener(event, callback, [options])

ParameterType(s)DefaultDescription
eventstring
Symbol
The event to listen to.
callbackEventEmitter~callback
The callback function to execute when the event occurs.
[options]Object
{}
[options.context]Object
thisThe value of this in the callback function.
[options.prepend]boolean
falseWhether the listener should be added at the beginning of the listeners array and thus executed first.
[options.duration]number
InfinityThe number of milliseconds before the listener automatically expires.
[options.remaining]number
InfinityThe number of times after which the callback should automatically be removed.
[options.arguments]array
An array of arguments which will be passed separately to the callback function. This array is stored in the arguments property of the Listener object and can be retrieved or modified as desired.

Return Value

Returns: Listener

The newly created Listener object.

Throws:

  • TypeError : The event parameter must be a string or EventEmitter.ANY_EVENT.
  • TypeError : The callback parameter must be a function.

.addOneTimeListener(...)โ€‹

Adds a one-time listener for the specified event. The listener will be executed once and then destroyed. It returns the Listener object that was created and attached to the event.

To attach a global listener that will be triggered for any events, use EventEmitter.ANY_EVENT as the first parameter. Note that a global listener will also be triggered by non-registered events.

Parameters

Signature: addOneTimeListener(event, callback, [options])

ParameterType(s)DefaultDescription
eventstring
Symbol
The event to listen to
callbackEventEmitter~callback
The callback function to execute when the event occurs
[options]Object
{}
[options.context]Object
thisThe context to invoke the callback function in.
[options.prepend]boolean
falseWhether the listener should be added at the beginning of the listeners array and thus executed first.
[options.duration]number
InfinityThe number of milliseconds before the listener automatically expires.
[options.arguments]array
An array of arguments which will be passed separately to the callback function. This array is stored in the arguments property of the Listener object and can be retrieved or modified as desired.

Return Value

Returns: Listener

The newly created Listener object.

Throws:

  • TypeError : The event parameter must be a string or EventEmitter.ANY_EVENT.
  • TypeError : The callback parameter must be a function.

.disable()โ€‹

Since: 2.0.0
Attributes: async

Completely disables WebMidi.js by unlinking the MIDI subsystem's interface and closing all Input and Output objects that may have been opened. This also means that listeners added to Input objects, Output objects or to WebMidi itself are also destroyed.

Return Value

Returns: Promise.<Array>

Throws:

  • Error : The Web MIDI API is not supported by your environment.

.emit(...)โ€‹

Executes the callback function of all the Listener objects registered for a given event. The callback functions are passed the additional arguments passed to emit() (if any) followed by the arguments present in the arguments property of the Listener object (if any).

If the eventsSuspended property is true or the Listener.suspended property is true, the callback functions will not be executed.

This function returns an array containing the return values of each of the callbacks.

It should be noted that the regular listeners are triggered first followed by the global listeners (those added with EventEmitter.ANY_EVENT).

Parameters

Signature: emit(event, ...args)

ParameterType(s)DefaultDescription
eventstring
The event
args*
Arbitrary number of arguments to pass along to the callback functions

Return Value

Returns: Array

An array containing the return value of each of the executed listener functions.

Throws:

  • TypeError : The event parameter must be a string.

.enable(...)โ€‹

Attributes: async

Checks if the Web MIDI API is available in the current environment and then tries to connect to the host's MIDI subsystem. This is an asynchronous operation and it causes a security prompt to be displayed to the user.

To enable the use of MIDI system exclusive messages, the sysex option should be set to true. However, under some environments (e.g. Jazz-Plugin), the sysex option is ignored and system exclusive messages are always enabled. You can check the sysexEnabled property to confirm.

To enable access to software synthesizers available on the host, you would set the software option to true. However, this option is only there to future-proof the library as support for software synths has not yet been implemented in any browser (as of September 2021).

By the way, if you call the enable() method while WebMidi.js is already enabled, the callback function will be executed (if any), the promise will resolve but the events ("midiaccessgranted", "connected" and "enabled") will not be fired.

There are 3 ways to execute code after WebMidi has been enabled:

  • Pass a callback function in the options
  • Listen to the "enabled" event
  • Wait for the promise to resolve

In order, this is what happens towards the end of the enabling process:

  1. "midiaccessgranted" event is triggered once the user has granted access to use MIDI.
  2. "connected" events are triggered (for each available input and output)
  3. "enabled" event is triggered when WebMidi.js is fully ready
  4. specified callback (if any) is executed
  5. promise is resolved and fulfilled with the WebMidi object.

Important note: starting with Chrome v77, a page using Web MIDI API must be hosted on a secure origin (https://, localhost or file:///) and the user will always be prompted to authorize the operation (no matter if the sysex option is true or not).

Exampleโ€‹
// Enabling WebMidi and using the promise
WebMidi.enable().then(() => {
console.log("WebMidi.js has been enabled!");
})

Parameters

Signature: enable([options])

ParameterType(s)DefaultDescription
[options]object
[options.callback]function
A function to execute once the operation completes. This function will receive an Error object if enabling the Web MIDI API failed.
[options.sysex]boolean
falseWhether to enable MIDI system exclusive messages or not.
[options.validation]boolean
trueWhether to enable library-wide validation of method arguments and setter values. This is an advanced setting that should be used carefully. Setting validation to false improves performance but should only be done once the project has been thoroughly tested with validation turned on.
[options.software]boolean
falseWhether to request access to software synthesizers on the host system. This is part of the spec but has not yet been implemented by most browsers as of April 2020.
[options.requestMIDIAccessFunction]function
A custom function to use to return the MIDIAccess object. This is useful if you want to use a polyfill for the Web MIDI API or if you want to use a custom implementation of the Web MIDI API - probably for testing purposes.

Return Value

Returns: Promise.<WebMidi>

The promise is fulfilled with the WebMidi object fro chainability

Throws:

  • Error : The Web MIDI API is not supported in your environment.
  • Error : Jazz-Plugin must be installed to use WebMIDIAPIShim.

.getInputById(...)โ€‹

Since: 2.0.0

Returns the Input object that matches the specified ID string or false if no matching input is found. As per the Web MIDI API specification, IDs are strings (not integers).

Please note that IDs change from one host to another. For example, Chrome does not use the same kind of IDs as Jazz-Plugin.

Parameters

Signature: getInputById(id, [options])

ParameterType(s)DefaultDescription
idstring
The ID string of the input. IDs can be viewed by looking at the WebMidi.inputs array. Even though they sometimes look like integers, IDs are strings.
[options]object
[options.disconnected]boolean
Whether to retrieve a disconnected input

Return Value

Returns: Input

An Input object matching the specified ID string or undefined if no matching input can be found.

Throws:

  • Error : WebMidi is not enabled.

.getInputByName(...)โ€‹

Since: 2.0.0

Returns the first Input object whose name contains the specified string. Note that the port names change from one environment to another. For example, Chrome does not report input names in the same way as the Jazz-Plugin does.

Parameters

Signature: getInputByName(name, [options])

ParameterType(s)DefaultDescription
namestring
The non-empty string to look for within the name of MIDI inputs (such as those visible in the inputs array).
[options]object
[options.disconnected]boolean
Whether to retrieve a disconnected input

Return Value

Returns: Input

The Input that was found or undefined if no input contained the specified name.

Throws:

  • Error : WebMidi is not enabled.

.getListenerCount(...)โ€‹

Returns the number of listeners registered for a specific event.

Please note that global events (those added with EventEmitter.ANY_EVENT) do not count towards the remaining number for a "regular" event. To get the number of global listeners, specifically use EventEmitter.ANY_EVENT as the parameter.

Parameters

Signature: getListenerCount(event)

ParameterType(s)DefaultDescription
eventstring
Symbol
The event which is usually a string but can also be the special EventEmitter.ANY_EVENT symbol.

Return Value

Returns: number

An integer representing the number of listeners registered for the specified event.

.getListeners(...)โ€‹

Returns an array of all the Listener objects that have been registered for a specific event.

Please note that global events (those added with EventEmitter.ANY_EVENT) are not returned for "regular" events. To get the list of global listeners, specifically use EventEmitter.ANY_EVENT as the parameter.

Parameters

Signature: getListeners(event)

ParameterType(s)DefaultDescription
eventstring
Symbol
The event to get listeners for.

Return Value

Returns: Array.<Listener>

An array of Listener objects.

.getOutputById(...)โ€‹

Since: 2.0.0

Returns the Output object that matches the specified ID string or false if no matching output is found. As per the Web MIDI API specification, IDs are strings (not integers).

Please note that IDs change from one host to another. For example, Chrome does not use the same kind of IDs as Jazz-Plugin.

Parameters

Signature: getOutputById(id, [options])

ParameterType(s)DefaultDescription
idstring
The ID string of the port. IDs can be viewed by looking at the WebMidi.outputs array.
[options]object
[options.disconnected]boolean
Whether to retrieve a disconnected output

Return Value

Returns: Output

An Output object matching the specified ID string. If no matching output can be found, the method returns undefined.

Throws:

  • Error : WebMidi is not enabled.

.getOutputByName(...)โ€‹

Since: 2.0.0

Returns the first Output object whose name contains the specified string. Note that the port names change from one environment to another. For example, Chrome does not report input names in the same way as the Jazz-Plugin does.

Parameters

Signature: getOutputByName(name, [options])

ParameterType(s)DefaultDescription
namestring
The non-empty string to look for within the name of MIDI inputs (such as those visible in the outputs array).
[options]object
[options.disconnected]boolean
Whether to retrieve a disconnected output

Return Value

Returns: Output

The Output that was found or undefined if no output matched the specified name.

Throws:

  • Error : WebMidi is not enabled.

.hasListener(...)โ€‹

Returns true if the specified event has at least one registered listener. If no event is specified, the method returns true if any event has at least one listener registered (this includes global listeners registered to EventEmitter.ANY_EVENT).

Note: to specifically check for global listeners added with EventEmitter.ANY_EVENT, use EventEmitter.ANY_EVENT as the parameter.

Parameters

Signature: hasListener([event], [callback])

ParameterType(s)DefaultDescription
[event]string
Symbol
(any event)The event to check
[callback]function
Listener
(any callback)The actual function that was added to the event or the Listener object returned by addListener().

Return Value

Returns: boolean

.removeListener(...)โ€‹

Removes all the listeners that match the specified criterias. If no parameters are passed, all listeners will be removed. If only the event parameter is passed, all listeners for that event will be removed. You can remove global listeners by using EventEmitter.ANY_EVENT as the first parameter.

To use more granular options, you must at least define the event. Then, you can specify the callback to match or one or more of the additional options.

Parameters

Signature: removeListener([event], [callback], [options])

ParameterType(s)DefaultDescription
[event]string
The event name.
[callback]EventEmitter~callback
Only remove the listeners that match this exact callback function.
[options]Object
[options.context]*
Only remove the listeners that have this exact context.
[options.remaining]number
Only remove the listener if it has exactly that many remaining times to be executed.

.suspendEvent(...)โ€‹

Suspends execution of all callbacks functions registered for the specified event type.

You can suspend execution of callbacks registered with EventEmitter.ANY_EVENT by passing EventEmitter.ANY_EVENT to suspendEvent(). Beware that this will not suspend all callbacks but only those registered with EventEmitter.ANY_EVENT. While this may seem counter-intuitive at first glance, it allows the selective suspension of global listeners while leaving other listeners alone. If you truly want to suspends all callbacks for a specific EventEmitter, simply set its eventsSuspended property to true.

Parameters

Signature: suspendEvent(event)

ParameterType(s)DefaultDescription
eventstring
Symbol
The event name (or EventEmitter.ANY_EVENT) for which to suspend execution of all callback functions.

.unsuspendEvent(...)โ€‹

Resumes execution of all suspended callback functions registered for the specified event type.

You can resume execution of callbacks registered with EventEmitter.ANY_EVENT by passing EventEmitter.ANY_EVENT to unsuspendEvent(). Beware that this will not resume all callbacks but only those registered with EventEmitter.ANY_EVENT. While this may seem counter-intuitive, it allows the selective unsuspension of global listeners while leaving other callbacks alone.

Parameters

Signature: unsuspendEvent(event)

ParameterType(s)DefaultDescription
eventstring
Symbol
The event name (or EventEmitter.ANY_EVENT) for which to resume execution of all callback functions.

.waitFor(...)โ€‹

Attributes: async

The waitFor() method is an async function which returns a promise. The promise is fulfilled when the specified event occurs. The event can be a regular event or EventEmitter.ANY_EVENT (if you want to resolve as soon as any event is emitted).

If the duration option is set, the promise will only be fulfilled if the event is emitted within the specified duration. If the event has not been fulfilled after the specified duration, the promise is rejected. This makes it super easy to wait for an event and timeout after a certain time if the event is not triggered.

Parameters

Signature: waitFor(event, [options])

ParameterType(s)DefaultDescription
eventstring
Symbol
The event to wait for
[options]Object
{}
[options.duration]number
InfinityThe number of milliseconds to wait before the promise is automatically rejected.

Eventsโ€‹

connectedโ€‹

Event emitted when an Input or Output becomes available. This event is typically fired whenever a MIDI device is plugged in. Please note that it may fire several times if a device possesses multiple inputs and/or outputs (which is often the case).

Event Properties

PropertyTypeDescription
timestampnumberThe moment (DOMHighResTimeStamp) when the event occurred (in milliseconds since the navigation start of the document).
typestringconnected
targetWebMidiThe object to which the listener was originally added (WebMidi)
portInputThe Input or Output object that triggered the event.

disabledโ€‹

Event emitted once WebMidi has been successfully disabled.

Event Properties

PropertyTypeDescription
timestampDOMHighResTimeStampThe moment when the event occurred (in milliseconds since the navigation start of the document).
targetWebMidiThe object that triggered the event
typestring"disabled"

disconnectedโ€‹

Event emitted when an Input or Output becomes unavailable. This event is typically fired whenever a MIDI device is unplugged. Please note that it may fire several times if a device possesses multiple inputs and/or outputs (which is often the case).

Event Properties

PropertyTypeDescription
timestampDOMHighResTimeStampThe moment when the event occurred (in milliseconds since the navigation start of the document).
typestringdisconnected
targetWebMidiThe object to which the listener was originally added (WebMidi)
portInputThe Input or Output object that triggered the event.

enabledโ€‹

Event emitted once WebMidi has been fully enabled

Event Properties

PropertyTypeDescription
timestampDOMHighResTimeStampThe moment when the event occurred (in milliseconds since the navigation start of the document).
targetWebMidiThe object that triggered the event
typestring"enabled"

errorโ€‹

Event emitted when an error occurs trying to enable WebMidi

Event Properties

PropertyTypeDescription
timestampDOMHighResTimeStampThe moment when the event occurred (in milliseconds since the navigation start of the document).
targetWebMidiThe object that triggered the event
typestringerror
error*Actual error that occurred

midiaccessgrantedโ€‹

Event emitted once the MIDI interface has been successfully created (which implies user has granted access to MIDI).

Event Properties

PropertyTypeDescription
timestampDOMHighResTimeStampThe moment when the event occurred (in milliseconds since the navigation start of the document).
targetWebMidiThe object that triggered the event
typestringmidiaccessgranted

portschangedโ€‹

Event emitted when an Input or Output port is connected or disconnected. This event is typically fired whenever a MIDI device is plugged in or unplugged. Please note that it may fire several times if a device possesses multiple inputs and/or outputs (which is often the case).

Since: 3.0.2

Event Properties

PropertyTypeDescription
timestampnumberThe moment (DOMHighResTimeStamp) when the event occurred (in milliseconds since the navigation start of the document).
typestringportschanged
targetWebMidiThe object to which the listener was originally added (WebMidi)
portInputThe Input or Output object that triggered the event.