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
Property | Type | Description |
---|---|---|
defaults.note | object | Default values relating to note |
defaults.note.attack | number | A number between 0 and 127 representing the default attack velocity of notes. Initial value is 64. |
defaults.note.release | number | A number between 0 and 127 representing the default release velocity of notes. Initial value is 64. |
defaults.note.duration | number | A 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])
Parameter | Type(s) | Default | Description |
---|---|---|---|
event | string Symbol | The event to listen to. | |
callback | EventEmitter~callback | The callback function to execute when the event occurs. | |
[options ] | Object | {} | |
[options.context ] | Object | this | The value of this in the callback function. |
[options.prepend ] | boolean | false | Whether the listener should be added at the beginning of the listeners array and thus executed first. |
[options.duration ] | number | Infinity | The number of milliseconds before the listener automatically expires. |
[options.remaining ] | number | Infinity | The 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
: Theevent
parameter must be a string orEventEmitter.ANY_EVENT
.TypeError
: Thecallback
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])
Parameter | Type(s) | Default | Description |
---|---|---|---|
event | string Symbol | The event to listen to | |
callback | EventEmitter~callback | The callback function to execute when the event occurs | |
[options ] | Object | {} | |
[options.context ] | Object | this | The context to invoke the callback function in. |
[options.prepend ] | boolean | false | Whether the listener should be added at the beginning of the listeners array and thus executed first. |
[options.duration ] | number | Infinity | The 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
: Theevent
parameter must be a string orEventEmitter.ANY_EVENT
.TypeError
: Thecallback
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)
Parameter | Type(s) | Default | Description |
---|---|---|---|
event | string | 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
: Theevent
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:
"midiaccessgranted"
event is triggered once the user has granted access to use MIDI."connected"
events are triggered (for each available input and output)"enabled"
event is triggered when WebMidi.js is fully ready- specified callback (if any) is executed
- 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])
Parameter | Type(s) | Default | Description |
---|---|---|---|
[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 | false | Whether to enable MIDI system exclusive messages or not. |
[options.validation ] | boolean | true | Whether 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 | false | Whether 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])
Parameter | Type(s) | Default | Description |
---|---|---|---|
id | string | 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])
Parameter | Type(s) | Default | Description |
---|---|---|---|
name | string | 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)
Parameter | Type(s) | Default | Description |
---|---|---|---|
event | string 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)
Parameter | Type(s) | Default | Description |
---|---|---|---|
event | string 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])
Parameter | Type(s) | Default | Description |
---|---|---|---|
id | string | 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])
Parameter | Type(s) | Default | Description |
---|---|---|---|
name | string | 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])
Parameter | Type(s) | Default | Description |
---|---|---|---|
[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])
Parameter | Type(s) | Default | Description |
---|---|---|---|
[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)
Parameter | Type(s) | Default | Description |
---|---|---|---|
event | string 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)
Parameter | Type(s) | Default | Description |
---|---|---|---|
event | string 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])
Parameter | Type(s) | Default | Description |
---|---|---|---|
event | string Symbol | The event to wait for | |
[options ] | Object | {} | |
[options.duration ] | number | Infinity | The 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
Property | Type | Description |
---|---|---|
timestamp | number | The moment (DOMHighResTimeStamp) when the event occurred (in milliseconds since the navigation start of the document). |
type | string | connected |
target | WebMidi | The object to which the listener was originally added (WebMidi ) |
port | Input | The Input or Output object that triggered the event. |
disabled
โ
Event emitted once WebMidi
has been successfully disabled.
Event Properties
Property | Type | Description |
---|---|---|
timestamp | DOMHighResTimeStamp | The moment when the event occurred (in milliseconds since the navigation start of the document). |
target | WebMidi | The object that triggered the event |
type | string | "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
Property | Type | Description |
---|---|---|
timestamp | DOMHighResTimeStamp | The moment when the event occurred (in milliseconds since the navigation start of the document). |
type | string | disconnected |
target | WebMidi | The object to which the listener was originally added (WebMidi ) |
port | Input | The Input or Output object that triggered the event. |
enabled
โ
Event emitted once WebMidi
has been fully enabled
Event Properties
Property | Type | Description |
---|---|---|
timestamp | DOMHighResTimeStamp | The moment when the event occurred (in milliseconds since the navigation start of the document). |
target | WebMidi | The object that triggered the event |
type | string | "enabled" |
error
โ
Event emitted when an error occurs trying to enable WebMidi
Event Properties
Property | Type | Description |
---|---|---|
timestamp | DOMHighResTimeStamp | The moment when the event occurred (in milliseconds since the navigation start of the document). |
target | WebMidi | The object that triggered the event |
type | string | error |
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
Property | Type | Description |
---|---|---|
timestamp | DOMHighResTimeStamp | The moment when the event occurred (in milliseconds since the navigation start of the document). |
target | WebMidi | The object that triggered the event |
type | string | midiaccessgranted |
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
Property | Type | Description |
---|---|---|
timestamp | number | The moment (DOMHighResTimeStamp) when the event occurred (in milliseconds since the navigation start of the document). |
type | string | portschanged |
target | WebMidi | The object to which the listener was originally added (WebMidi ) |
port | Input | The Input or Output object that triggered the event. |