diff --git a/docs/latest/classes/Input.html b/docs/latest/classes/Input.html index 0f003d95e..580c724bd 100644 --- a/docs/latest/classes/Input.html +++ b/docs/latest/classes/Input.html @@ -17,7 +17,7 @@

- API Docs for: 2.0.0-rc.8 + API Docs for: 2.0.0-rc.9
@@ -83,7 +83,7 @@

Input Class

- Defined in: src/webmidi.js:1140 + Defined in: src/webmidi.js:1141
@@ -293,7 +293,7 @@

_initializeUserHandlers

Defined in - src/webmidi.js:1499 + src/webmidi.js:1500

@@ -324,7 +324,7 @@

_onMidiMessage

Defined in - src/webmidi.js:1519 + src/webmidi.js:1520

@@ -361,7 +361,7 @@

_parseChannelEvent

Defined in - src/webmidi.js:1533 + src/webmidi.js:1534

@@ -409,7 +409,7 @@

_parseSystemEvent

Defined in - src/webmidi.js:1865 + src/webmidi.js:1866

@@ -455,7 +455,7 @@

addListener

Defined in - src/webmidi.js:1234 + src/webmidi.js:1235

@@ -585,7 +585,7 @@

getCcNameByNumber

Defined in - src/webmidi.js:1805 + src/webmidi.js:1806

@@ -661,7 +661,7 @@

getChannelModeByNumber

Defined in - src/webmidi.js:1836 + src/webmidi.js:1837

@@ -743,7 +743,7 @@

hasListener

Defined in - src/webmidi.js:1354 + src/webmidi.js:1355

@@ -837,7 +837,7 @@

on

Defined in - src/webmidi.js:1345 + src/webmidi.js:1346

@@ -886,7 +886,7 @@

removeListener

Defined in - src/webmidi.js:1414 + src/webmidi.js:1415

@@ -985,7 +985,7 @@

connection

Defined in - src/webmidi.js:1161 + src/webmidi.js:1162

@@ -1010,7 +1010,7 @@

id

Defined in - src/webmidi.js:1174 + src/webmidi.js:1175

@@ -1037,7 +1037,7 @@

manufacturer

Defined in - src/webmidi.js:1189 + src/webmidi.js:1190

@@ -1062,7 +1062,7 @@

name

Defined in - src/webmidi.js:1202 + src/webmidi.js:1203

@@ -1087,7 +1087,7 @@

state

Defined in - src/webmidi.js:1215 + src/webmidi.js:1216

@@ -1118,7 +1118,7 @@

activesensing

Defined in - src/webmidi.js:2072 + src/webmidi.js:2073

@@ -1213,7 +1213,7 @@

channelaftertouch

Defined in - src/webmidi.js:1747 + src/webmidi.js:1748

@@ -1329,7 +1329,7 @@

channelmode

Defined in - src/webmidi.js:1696 + src/webmidi.js:1697

@@ -1472,7 +1472,7 @@

clock

Defined in - src/webmidi.js:1996 + src/webmidi.js:1997

@@ -1568,7 +1568,7 @@

continue

Defined in - src/webmidi.js:2034 + src/webmidi.js:2035

@@ -1664,7 +1664,7 @@

controlchange

Defined in - src/webmidi.js:1664 + src/webmidi.js:1665

@@ -1807,7 +1807,7 @@

keyaftertouch

Defined in - src/webmidi.js:1630 + src/webmidi.js:1631

@@ -1958,7 +1958,7 @@

noteoff

Defined in - src/webmidi.js:1562 + src/webmidi.js:1563

@@ -2120,7 +2120,7 @@

noteon

Defined in - src/webmidi.js:1596 + src/webmidi.js:1597

@@ -2282,7 +2282,7 @@

pitchbend

Defined in - src/webmidi.js:1769 + src/webmidi.js:1770

@@ -2398,7 +2398,7 @@

programchange

Defined in - src/webmidi.js:1725 + src/webmidi.js:1726

@@ -2514,7 +2514,7 @@

reset

Defined in - src/webmidi.js:2090 + src/webmidi.js:2091

@@ -2609,7 +2609,7 @@

songposition

Defined in - src/webmidi.js:1937 + src/webmidi.js:1938

@@ -2704,7 +2704,7 @@

songselect

Defined in - src/webmidi.js:1957 + src/webmidi.js:1958

@@ -2809,7 +2809,7 @@

start

Defined in - src/webmidi.js:2015 + src/webmidi.js:2016

@@ -2905,7 +2905,7 @@

stop

Defined in - src/webmidi.js:2053 + src/webmidi.js:2054

@@ -3001,7 +3001,7 @@

sysex

Defined in - src/webmidi.js:1882 + src/webmidi.js:1883

@@ -3111,7 +3111,7 @@

timecode

Defined in - src/webmidi.js:1917 + src/webmidi.js:1918

@@ -3206,7 +3206,7 @@

tuningrequest

Defined in - src/webmidi.js:1977 + src/webmidi.js:1978

@@ -3302,7 +3302,7 @@

unknownsystemmessage

Defined in - src/webmidi.js:2108 + src/webmidi.js:2109

diff --git a/docs/latest/classes/Output.html b/docs/latest/classes/Output.html index e765b1bc5..9a3a153c1 100644 --- a/docs/latest/classes/Output.html +++ b/docs/latest/classes/Output.html @@ -17,7 +17,7 @@

- API Docs for: 2.0.0-rc.8 + API Docs for: 2.0.0-rc.9
@@ -83,7 +83,7 @@

Output Class

- Defined in: src/webmidi.js:2137 + Defined in: src/webmidi.js:2138
@@ -320,7 +320,7 @@

_convertChannelToArray

Defined in - src/webmidi.js:4080 + src/webmidi.js:4081

@@ -377,7 +377,7 @@

_convertNoteToArray

Defined in - src/webmidi.js:4058 + src/webmidi.js:4059

@@ -439,7 +439,7 @@

_deselectRegisteredParameter

Defined in - src/webmidi.js:3186 + src/webmidi.js:3187

@@ -507,7 +507,7 @@

_onMidiMessage

Defined in - src/webmidi.js:4110 + src/webmidi.js:4111

@@ -547,7 +547,7 @@

_parseTimeParameter

Defined in - src/webmidi.js:4028 + src/webmidi.js:4029

@@ -624,7 +624,7 @@

_selectNonRegisteredParameter

Defined in - src/webmidi.js:3111 + src/webmidi.js:3112

@@ -717,7 +717,7 @@

_selectRegisteredParameter

Defined in - src/webmidi.js:3074 + src/webmidi.js:3075

@@ -810,7 +810,7 @@

_setCurrentRegisteredParameter

Defined in - src/webmidi.js:3148 + src/webmidi.js:3149

@@ -900,7 +900,7 @@

decrementRegisteredParameter

Defined in - src/webmidi.js:3448 + src/webmidi.js:3449

@@ -1052,7 +1052,7 @@

incrementRegisteredParameter

Defined in - src/webmidi.js:3375 + src/webmidi.js:3376

@@ -1196,7 +1196,7 @@

playNote

Defined in - src/webmidi.js:2733 + src/webmidi.js:2734

@@ -1378,7 +1378,7 @@

send

Defined in - src/webmidi.js:2223 + src/webmidi.js:2224

@@ -1490,7 +1490,7 @@

sendActiveSensing

Defined in - src/webmidi.js:2591 + src/webmidi.js:2592

@@ -1584,7 +1584,7 @@

sendChannelAftertouch

Defined in - src/webmidi.js:3925 + src/webmidi.js:3926

@@ -1707,7 +1707,7 @@

sendChannelMode

Defined in - src/webmidi.js:3794 + src/webmidi.js:3795

@@ -1851,7 +1851,7 @@

sendClock

Defined in - src/webmidi.js:2490 + src/webmidi.js:2491

@@ -1938,7 +1938,7 @@

sendContinue

Defined in - src/webmidi.js:2540 + src/webmidi.js:2541

@@ -2035,7 +2035,7 @@

sendControlChange

Defined in - src/webmidi.js:2937 + src/webmidi.js:2938

@@ -2246,7 +2246,7 @@

sendKeyAftertouch

Defined in - src/webmidi.js:2869 + src/webmidi.js:2870

@@ -2391,7 +2391,7 @@

sendPitchBend

Defined in - src/webmidi.js:3974 + src/webmidi.js:3975

@@ -2518,7 +2518,7 @@

sendProgramChange

Defined in - src/webmidi.js:3875 + src/webmidi.js:3876

@@ -2638,7 +2638,7 @@

sendReset

Defined in - src/webmidi.js:2621 + src/webmidi.js:2622

@@ -2728,7 +2728,7 @@

sendSongPosition

Defined in - src/webmidi.js:2380 + src/webmidi.js:2381

@@ -2832,7 +2832,7 @@

sendSongSelect

Defined in - src/webmidi.js:2419 + src/webmidi.js:2420

@@ -2930,7 +2930,7 @@

sendStart

Defined in - src/webmidi.js:2515 + src/webmidi.js:2516

@@ -3017,7 +3017,7 @@

sendStop

Defined in - src/webmidi.js:2566 + src/webmidi.js:2567

@@ -3110,7 +3110,7 @@

sendSysex

Defined in - src/webmidi.js:2282 + src/webmidi.js:2283

@@ -3239,7 +3239,7 @@

sendTimecodeQuarterFrame

Defined in - src/webmidi.js:2352 + src/webmidi.js:2353

@@ -3338,7 +3338,7 @@

sendTuningRequest

Defined in - src/webmidi.js:2458 + src/webmidi.js:2459

@@ -3433,7 +3433,7 @@

setMasterTuning

Defined in - src/webmidi.js:3638 + src/webmidi.js:3639

@@ -3571,7 +3571,7 @@

setModulationRange

Defined in - src/webmidi.js:3580 + src/webmidi.js:3581

@@ -3716,7 +3716,7 @@

setNonRegisteredParameter

Defined in - src/webmidi.js:3297 + src/webmidi.js:3298

@@ -3869,7 +3869,7 @@

setPitchBendRange

Defined in - src/webmidi.js:3521 + src/webmidi.js:3522

@@ -4015,7 +4015,7 @@

setRegisteredParameter

Defined in - src/webmidi.js:3214 + src/webmidi.js:3215

@@ -4178,7 +4178,7 @@

setTuningBank

Defined in - src/webmidi.js:3748 + src/webmidi.js:3749

@@ -4305,7 +4305,7 @@

setTuningProgram

Defined in - src/webmidi.js:3702 + src/webmidi.js:3703

@@ -4432,7 +4432,7 @@

stopNote

Defined in - src/webmidi.js:2646 + src/webmidi.js:2647

@@ -4570,7 +4570,7 @@

connection

Defined in - src/webmidi.js:2154 + src/webmidi.js:2155

@@ -4595,7 +4595,7 @@

id

Defined in - src/webmidi.js:2167 + src/webmidi.js:2168

@@ -4620,7 +4620,7 @@

manufacturer

Defined in - src/webmidi.js:2180 + src/webmidi.js:2181

@@ -4645,7 +4645,7 @@

name

Defined in - src/webmidi.js:2193 + src/webmidi.js:2194

@@ -4670,7 +4670,7 @@

state

Defined in - src/webmidi.js:2206 + src/webmidi.js:2207

diff --git a/docs/latest/classes/WebMidi.html b/docs/latest/classes/WebMidi.html index df685536a..c4adb2432 100644 --- a/docs/latest/classes/WebMidi.html +++ b/docs/latest/classes/WebMidi.html @@ -17,7 +17,7 @@

- API Docs for: 2.0.0-rc.8 + API Docs for: 2.0.0-rc.9
@@ -350,7 +350,7 @@

_createInput

Defined in - src/webmidi.js:1014 + src/webmidi.js:1015

@@ -382,7 +382,7 @@

_createOutput

Defined in - src/webmidi.js:1025 + src/webmidi.js:1026

@@ -414,7 +414,7 @@

_onInterfaceStateChange

Defined in - src/webmidi.js:1036 + src/webmidi.js:1037

@@ -446,7 +446,7 @@

_processStateChange

Defined in - src/webmidi.js:1059 + src/webmidi.js:1060

@@ -478,7 +478,7 @@

_resetInterfaceUserHandlers

Defined in - src/webmidi.js:1127 + src/webmidi.js:1128

@@ -510,7 +510,7 @@

_updateInputs

Defined in - src/webmidi.js:920 + src/webmidi.js:921

@@ -542,7 +542,7 @@

_updateInputsAndOutputs

Defined in - src/webmidi.js:910 + src/webmidi.js:911

@@ -574,7 +574,7 @@

_updateOutputs

Defined in - src/webmidi.js:967 + src/webmidi.js:968

@@ -618,7 +618,7 @@

addListener

Defined in - src/webmidi.js:539 + src/webmidi.js:540

@@ -834,7 +834,7 @@

getInputById

Defined in - src/webmidi.js:682 + src/webmidi.js:683

@@ -906,7 +906,7 @@

getInputByName

Defined in - src/webmidi.js:746 + src/webmidi.js:747

@@ -986,7 +986,7 @@

getOctave

Defined in - src/webmidi.js:780 + src/webmidi.js:781

@@ -1056,7 +1056,7 @@

getOutputById

Defined in - src/webmidi.js:714 + src/webmidi.js:715

@@ -1128,7 +1128,7 @@

getOutputByName

Defined in - src/webmidi.js:802 + src/webmidi.js:803

@@ -1208,7 +1208,7 @@

guessNoteNumber

Defined in - src/webmidi.js:835 + src/webmidi.js:836

@@ -1289,7 +1289,7 @@

hasListener

Defined in - src/webmidi.js:585 + src/webmidi.js:586

@@ -1378,7 +1378,7 @@

noteNameToNumber

Defined in - src/webmidi.js:867 + src/webmidi.js:868

@@ -1463,7 +1463,7 @@

removeListener

Defined in - src/webmidi.js:628 + src/webmidi.js:629

@@ -1858,7 +1858,7 @@

connected

Defined in - src/webmidi.js:1072 + src/webmidi.js:1073

@@ -1964,7 +1964,7 @@

disconnected

Defined in - src/webmidi.js:1088 + src/webmidi.js:1089

diff --git a/docs/latest/data.json b/docs/latest/data.json index 6212c5e93..23899848c 100644 --- a/docs/latest/data.json +++ b/docs/latest/data.json @@ -1,7 +1,7 @@ { "project": { "name": "WebMidi", - "version": "2.0.0-rc.8", + "version": "2.0.0-rc.9", "description": "WebMidi.js helps you tame the Web MIDI API. Send and receive MIDI messages with ease. Control instruments with user-friendly functions (playNote, sendPitchBend, etc.). React to MIDI input with simple event listeners (noteon, pitchbend, controlchange, etc.).", "url": "", "logo": "http://cotejp.github.io/webmidi/images/webmidijs-logo-small.png" @@ -63,7 +63,7 @@ "plugin_for": [], "extension_for": [], "file": "src/webmidi.js", - "line": 1140, + "line": 1141, "description": "The `Input` object represents a MIDI input port on the host system. This object is created by\nthe MIDI subsystem and cannot be instantiated directly.\n\nYou will find all available `Input` objects in the `WebMidi.inputs` array.", "params": [ { @@ -82,7 +82,7 @@ "plugin_for": [], "extension_for": [], "file": "src/webmidi.js", - "line": 2137, + "line": 2138, "description": "The `Output` object represents a MIDI output port on the host system. This object is created by\nthe MIDI subsystem and cannot be instantiated directly.\n\nYou will find all available `Output` objects in the `WebMidi.outputs` array.", "params": [ { @@ -249,7 +249,7 @@ }, { "file": "src/webmidi.js", - "line": 539, + "line": 540, "description": "Adds an event listener on the `WebMidi` object that will trigger a function callback when the\nspecified event happens.\n\nWebMidi must be enabled before adding event listeners.\n\nCurrently, only one event is being dispatched by the `WebMidi` object:\n\n * {{#crossLink \"WebMidi/statechange:event\"}}statechange{{/crossLink}}", "itemtype": "method", "name": "addListener", @@ -279,7 +279,7 @@ }, { "file": "src/webmidi.js", - "line": 585, + "line": 586, "description": "Checks if the specified event type is already defined to trigger the specified listener\nfunction.", "itemtype": "method", "name": "hasListener", @@ -308,7 +308,7 @@ }, { "file": "src/webmidi.js", - "line": 628, + "line": 629, "description": "Removes the specified listener(s). If the `listener` parameter is left undefined, all listeners\nfor the specified `type` will be removed. If both the `listener` and the `type` parameters are\nomitted, all listeners attached to the `WebMidi` object will be removed.", "itemtype": "method", "name": "removeListener", @@ -340,7 +340,7 @@ }, { "file": "src/webmidi.js", - "line": 682, + "line": 683, "description": "Returns an `Input` object representing the input port with the specified id.\nPlease note that the IDs change from one host to another. For example, Chrome does not use the\n same kind of IDs as the Jazz-Plugin.", "itemtype": "method", "name": "getInputById", @@ -361,7 +361,7 @@ }, { "file": "src/webmidi.js", - "line": 714, + "line": 715, "description": "Returns an `Output` object representing the output port matching the specified id.\nPlease note that the IDs change from one host to another. For example, Chrome does not use the\n same kind of IDs as the Jazz-Plugin.", "itemtype": "method", "name": "getOutputById", @@ -382,7 +382,7 @@ }, { "file": "src/webmidi.js", - "line": 746, + "line": 747, "description": "Returns the first MIDI `Input` whose name *contains* the specified string.\n\nPlease note that the port names change from one host to another. For example, Chrome does\nnot report port names in the same way as the Jazz-Plugin does.", "itemtype": "method", "name": "getInputByName", @@ -406,7 +406,7 @@ }, { "file": "src/webmidi.js", - "line": 780, + "line": 781, "description": "Returns the octave number for the specified MIDI note number. The returned value will be\nbetween -2 and 8.", "itemtype": "method", "name": "getOctave", @@ -427,7 +427,7 @@ }, { "file": "src/webmidi.js", - "line": 802, + "line": 803, "description": "Returns the first MIDI `Output` that matches the specified name.\n\nPlease note that the port names change from one host to another. For example, Chrome does\nnot report port names in the same way as the Jazz-Plugin does.", "itemtype": "method", "name": "getOutputByName", @@ -451,7 +451,7 @@ }, { "file": "src/webmidi.js", - "line": 835, + "line": 836, "description": "Returns a valid MIDI note number given the specified input. The input can be a note name (C3,\nF#4, D-2, G8, etc.) or an int between 0 and 127.", "itemtype": "method", "name": "guessNoteNumber", @@ -475,7 +475,7 @@ }, { "file": "src/webmidi.js", - "line": 867, + "line": 868, "description": "Returns a MIDI note number matching the note name passed in the form of a string parameter. The\nnote name must include the octave number which should be between -2 and 8. The name can also\noptionally include a sharp \"#\" or double sharp \"##\" symbol and a flat \"b\" or double flat \"bb\"\nsymbol: C5, G4, D#-1, F0, Gb7, Eb-1, Abb4, B##6, etc.\n\nThe lowest note is C-2 (MIDI note number 0) and the highest note is G8 (MIDI note number 127).", "itemtype": "method", "name": "noteNameToNumber", @@ -499,7 +499,7 @@ }, { "file": "src/webmidi.js", - "line": 910, + "line": 911, "itemtype": "method", "name": "_updateInputsAndOutputs", "static": 1, @@ -509,7 +509,7 @@ }, { "file": "src/webmidi.js", - "line": 920, + "line": 921, "itemtype": "method", "name": "_updateInputs", "static": 1, @@ -519,7 +519,7 @@ }, { "file": "src/webmidi.js", - "line": 967, + "line": 968, "itemtype": "method", "name": "_updateOutputs", "static": 1, @@ -529,7 +529,7 @@ }, { "file": "src/webmidi.js", - "line": 1014, + "line": 1015, "itemtype": "method", "name": "_createInput", "static": 1, @@ -539,7 +539,7 @@ }, { "file": "src/webmidi.js", - "line": 1025, + "line": 1026, "itemtype": "method", "name": "_createOutput", "static": 1, @@ -549,7 +549,7 @@ }, { "file": "src/webmidi.js", - "line": 1036, + "line": 1037, "itemtype": "method", "name": "_onInterfaceStateChange", "static": 1, @@ -559,7 +559,7 @@ }, { "file": "src/webmidi.js", - "line": 1059, + "line": 1060, "itemtype": "method", "name": "_processStateChange", "static": 1, @@ -569,7 +569,7 @@ }, { "file": "src/webmidi.js", - "line": 1072, + "line": 1073, "description": "Event emitted when a MIDI port becomes available. This event is typically fired whenever a\nMIDI device is plugged in. Please note that it may fire several times if a device possesses\nmultiple input/output ports.", "itemtype": "event", "name": "connected", @@ -616,7 +616,7 @@ }, { "file": "src/webmidi.js", - "line": 1088, + "line": 1089, "description": "Event emitted when a MIDI port becomes unavailable. This event is typically fired whenever a\nMIDI device is unplugged. Please note that it may fire several times if a device possesses\nmultiple input/output ports.", "itemtype": "event", "name": "disconnected", @@ -663,7 +663,7 @@ }, { "file": "src/webmidi.js", - "line": 1127, + "line": 1128, "itemtype": "method", "name": "_resetInterfaceUserHandlers", "static": 1, @@ -673,7 +673,7 @@ }, { "file": "src/webmidi.js", - "line": 1161, + "line": 1162, "description": "[read-only] Status of the MIDI port's connection (`pending`, `open` or `closed`)", "itemtype": "property", "name": "connection", @@ -682,7 +682,7 @@ }, { "file": "src/webmidi.js", - "line": 1174, + "line": 1175, "description": "[read-only] ID string of the MIDI port. The ID is host-specific. Do not expect the same ID\non different platforms. For example, Google Chrome and the Jazz-Plugin report completely\ndifferent IDs for the same port.", "itemtype": "property", "name": "id", @@ -691,7 +691,7 @@ }, { "file": "src/webmidi.js", - "line": 1189, + "line": 1190, "description": "[read-only] Name of the manufacturer of the device that makes this port available.", "itemtype": "property", "name": "manufacturer", @@ -700,7 +700,7 @@ }, { "file": "src/webmidi.js", - "line": 1202, + "line": 1203, "description": "[read-only] Name of the MIDI port", "itemtype": "property", "name": "name", @@ -709,7 +709,7 @@ }, { "file": "src/webmidi.js", - "line": 1215, + "line": 1216, "description": "[read-only] State of the MIDI port (`connected` or `disconnected`)", "itemtype": "property", "name": "state", @@ -718,7 +718,7 @@ }, { "file": "src/webmidi.js", - "line": 1234, + "line": 1235, "description": "Adds an event listener to the `Input` that will trigger a function callback when the specified\nevent happens on the specified channel(s). Here is a list of events that are dispatched by\n`Input` objects and that can be listened to.\n\nChannel-specific MIDI events:\n\n * {{#crossLink \"Input/noteoff:event\"}}noteoff{{/crossLink}}\n * {{#crossLink \"Input/noteon:event\"}}noteon{{/crossLink}}\n * {{#crossLink \"Input/keyaftertouch:event\"}}keyaftertouch{{/crossLink}}\n * {{#crossLink \"Input/controlchange:event\"}}controlchange{{/crossLink}}\n * {{#crossLink \"Input/channelmode:event\"}}channelmode{{/crossLink}}\n * {{#crossLink \"Input/programchange:event\"}}programchange{{/crossLink}}\n * {{#crossLink \"Input/channelaftertouch:event\"}}channelaftertouch{{/crossLink}}\n * {{#crossLink \"Input/pitchbend:event\"}}pitchbend{{/crossLink}}\n\nDevice-wide MIDI events:\n\n * {{#crossLink \"Input/sysex:event\"}}sysex{{/crossLink}}\n * {{#crossLink \"Input/timecode:event\"}}timecode{{/crossLink}}\n * {{#crossLink \"Input/songposition:event\"}}songposition{{/crossLink}}\n * {{#crossLink \"Input/songselect:event\"}}songselect{{/crossLink}}\n * {{#crossLink \"Input/tuningrequest:event\"}}tuningrequest{{/crossLink}}\n * {{#crossLink \"Input/clock:event\"}}clock{{/crossLink}}\n * {{#crossLink \"Input/start:event\"}}start{{/crossLink}}\n * {{#crossLink \"Input/continue:event\"}}continue{{/crossLink}}\n * {{#crossLink \"Input/stop:event\"}}stop{{/crossLink}}\n * {{#crossLink \"Input/activesensing:event\"}}activesensing{{/crossLink}}\n * {{#crossLink \"Input/reset:event\"}}reset{{/crossLink}}\n * {{#crossLink \"Input/unknownsystemmessage:event\"}}unknownsystemmessage{{/crossLink}}\n\nFor device-wide events, the `channel` parameter will be silently ignored. You can simply use\n`undefined` in that case.", "itemtype": "method", "name": "addListener", @@ -752,7 +752,7 @@ }, { "file": "src/webmidi.js", - "line": 1345, + "line": 1346, "description": "This is an alias to the {{#crossLink \"Input/addListener\"}}Input.addListener(){{/crossLink}}\nfunction.", "itemtype": "method", "name": "on", @@ -761,7 +761,7 @@ }, { "file": "src/webmidi.js", - "line": 1354, + "line": 1355, "description": "Checks if the specified event type is already defined to trigger the listener function on the\nspecified channel(s). If more than one channel is specified, the function will return `true`\nonly if all channels have the listener defined.\n\nFor device-wide events (`sysex`, `start`, etc.), the `channel` parameter is silently ignored.\nWe suggest you use `undefined` in such cases.", "itemtype": "method", "name": "hasListener", @@ -794,7 +794,7 @@ }, { "file": "src/webmidi.js", - "line": 1414, + "line": 1415, "description": "Removes the specified listener from the specified channel(s). If the `listener` parameter is\nleft undefined, all listeners for the specified `type` will be removed from all channels. If\nthe `channel` is also omitted, all listeners of the specified type will be removed from all\nchannels. If no parameters are defined, all listeners attached to any channel of the `Input`\nwill be removed.\n\nFor device-wide events (`sysex`, `start`, etc.), the `channel` parameter is silently ignored.\nYou can use `undefined` in such cases.", "itemtype": "method", "name": "removeListener", @@ -831,7 +831,7 @@ }, { "file": "src/webmidi.js", - "line": 1499, + "line": 1500, "itemtype": "method", "name": "_initializeUserHandlers", "access": "protected", @@ -840,7 +840,7 @@ }, { "file": "src/webmidi.js", - "line": 1519, + "line": 1520, "itemtype": "method", "name": "_onMidiMessage", "access": "protected", @@ -849,7 +849,7 @@ }, { "file": "src/webmidi.js", - "line": 1533, + "line": 1534, "itemtype": "method", "name": "_parseChannelEvent", "params": [ @@ -864,7 +864,7 @@ }, { "file": "src/webmidi.js", - "line": 1562, + "line": 1563, "description": "Event emitted when a note off MIDI message has been received on a specific device and\nchannel.", "itemtype": "event", "name": "noteoff", @@ -943,7 +943,7 @@ }, { "file": "src/webmidi.js", - "line": 1596, + "line": 1597, "description": "Event emitted when a note on MIDI message has been received on a specific device and\nchannel.", "itemtype": "event", "name": "noteon", @@ -1022,7 +1022,7 @@ }, { "file": "src/webmidi.js", - "line": 1630, + "line": 1631, "description": "Event emitted when a key-specific aftertouch MIDI message has been received on a specific\ndevice and channel.", "itemtype": "event", "name": "keyaftertouch", @@ -1096,7 +1096,7 @@ }, { "file": "src/webmidi.js", - "line": 1664, + "line": 1665, "description": "Event emitted when a control change MIDI message has been received on a specific device and\nchannel.", "itemtype": "event", "name": "controlchange", @@ -1165,7 +1165,7 @@ }, { "file": "src/webmidi.js", - "line": 1696, + "line": 1697, "description": "Event emitted when a channel mode MIDI message has been received on a specific device and\nchannel.", "itemtype": "event", "name": "channelmode", @@ -1234,7 +1234,7 @@ }, { "file": "src/webmidi.js", - "line": 1725, + "line": 1726, "description": "Event emitted when a program change MIDI message has been received on a specific device and\nchannel.", "itemtype": "event", "name": "programchange", @@ -1286,7 +1286,7 @@ }, { "file": "src/webmidi.js", - "line": 1747, + "line": 1748, "description": "Event emitted when a channel-wide aftertouch MIDI message has been received on a specific\ndevice and channel.", "itemtype": "event", "name": "channelaftertouch", @@ -1338,7 +1338,7 @@ }, { "file": "src/webmidi.js", - "line": 1769, + "line": 1770, "description": "Event emitted when a pitch bend MIDI message has been received on a specific device and\nchannel.", "itemtype": "event", "name": "pitchbend", @@ -1390,7 +1390,7 @@ }, { "file": "src/webmidi.js", - "line": 1805, + "line": 1806, "description": "Returns the name of a control change message matching the specified number. If no match is\nfound, the function returns `undefined`.", "itemtype": "method", "name": "getCcNameByNumber", @@ -1413,7 +1413,7 @@ }, { "file": "src/webmidi.js", - "line": 1836, + "line": 1837, "description": "Returns the channel mode name matching the specified number. If no match is found, the function\nreturns `undefined`.", "itemtype": "method", "name": "getChannelModeByNumber", @@ -1436,7 +1436,7 @@ }, { "file": "src/webmidi.js", - "line": 1865, + "line": 1866, "itemtype": "method", "name": "_parseSystemEvent", "access": "protected", @@ -1445,7 +1445,7 @@ }, { "file": "src/webmidi.js", - "line": 1882, + "line": 1883, "description": "Event emitted when a system exclusive MIDI message has been received. You should note that,\nto receive `sysex` events, you must call the `WebMidi.enable()` method with a second\nparameter set to `true`:\n\n WebMidi.enable(function(err) {\n\n if (err) {\n console.log(\"WebMidi could not be enabled.\");\n }\n\n var input = WebMidi.inputs[0];\n\n input.addListener('sysex', \"all\", function (e) {\n console.log(e);\n });\n\n }, true);", "itemtype": "event", "name": "sysex", @@ -1487,7 +1487,7 @@ }, { "file": "src/webmidi.js", - "line": 1917, + "line": 1918, "description": "Event emitted when a system MIDI time code quarter frame message has been received.", "itemtype": "event", "name": "timecode", @@ -1529,7 +1529,7 @@ }, { "file": "src/webmidi.js", - "line": 1937, + "line": 1938, "description": "Event emitted when a system song position pointer MIDI message has been received.", "itemtype": "event", "name": "songposition", @@ -1571,7 +1571,7 @@ }, { "file": "src/webmidi.js", - "line": 1957, + "line": 1958, "description": "Event emitted when a system song select MIDI message has been received.", "itemtype": "event", "name": "songselect", @@ -1618,7 +1618,7 @@ }, { "file": "src/webmidi.js", - "line": 1977, + "line": 1978, "description": "Event emitted when a system tune request MIDI message has been received.", "itemtype": "event", "name": "tuningrequest", @@ -1660,7 +1660,7 @@ }, { "file": "src/webmidi.js", - "line": 1996, + "line": 1997, "description": "Event emitted when a system timing clock MIDI message has been received.", "itemtype": "event", "name": "clock", @@ -1702,7 +1702,7 @@ }, { "file": "src/webmidi.js", - "line": 2015, + "line": 2016, "description": "Event emitted when a system start MIDI message has been received.", "itemtype": "event", "name": "start", @@ -1744,7 +1744,7 @@ }, { "file": "src/webmidi.js", - "line": 2034, + "line": 2035, "description": "Event emitted when a system continue MIDI message has been received.", "itemtype": "event", "name": "continue", @@ -1786,7 +1786,7 @@ }, { "file": "src/webmidi.js", - "line": 2053, + "line": 2054, "description": "Event emitted when a system stop MIDI message has been received.", "itemtype": "event", "name": "stop", @@ -1828,7 +1828,7 @@ }, { "file": "src/webmidi.js", - "line": 2072, + "line": 2073, "description": "Event emitted when a system active sensing MIDI message has been received.", "itemtype": "event", "name": "activesensing", @@ -1870,7 +1870,7 @@ }, { "file": "src/webmidi.js", - "line": 2090, + "line": 2091, "description": "Event emitted when a system reset MIDI message has been received.", "itemtype": "event", "name": "reset", @@ -1912,7 +1912,7 @@ }, { "file": "src/webmidi.js", - "line": 2108, + "line": 2109, "description": "Event emitted when an unknown system MIDI message has been received. It could be, for\nexample, one of the undefined/reserved messages.", "itemtype": "event", "name": "unknownsystemmessage", @@ -1954,7 +1954,7 @@ }, { "file": "src/webmidi.js", - "line": 2154, + "line": 2155, "description": "[read-only] Status of the MIDI port's connection", "itemtype": "property", "name": "connection", @@ -1963,7 +1963,7 @@ }, { "file": "src/webmidi.js", - "line": 2167, + "line": 2168, "description": "[read-only] ID string of the MIDI port", "itemtype": "property", "name": "id", @@ -1972,7 +1972,7 @@ }, { "file": "src/webmidi.js", - "line": 2180, + "line": 2181, "description": "[read-only] Manufacturer of the device to which this port belongs", "itemtype": "property", "name": "manufacturer", @@ -1981,7 +1981,7 @@ }, { "file": "src/webmidi.js", - "line": 2193, + "line": 2194, "description": "[read-only] Name of the MIDI port", "itemtype": "property", "name": "name", @@ -1990,7 +1990,7 @@ }, { "file": "src/webmidi.js", - "line": 2206, + "line": 2207, "description": "[read-only] State of the MIDI port", "itemtype": "property", "name": "state", @@ -1999,7 +1999,7 @@ }, { "file": "src/webmidi.js", - "line": 2223, + "line": 2224, "description": "Sends a MIDI message on the MIDI output port, at the scheduled timestamp.\n\nUnless, you are familiar with the details of the MIDI message format, you should not use this\nmethod directly. Instead, use one of the simpler helper methods: `playNote()`, `stopNote()`,\n`sendControlChange()`, `sendSystemMessage()`, etc.\n\nDetails on the format of MIDI messages are available in the\nsummary of MIDI messages of the\nMIDI Manufacturers Association.", "itemtype": "method", "name": "send", @@ -2037,7 +2037,7 @@ }, { "file": "src/webmidi.js", - "line": 2282, + "line": 2283, "description": "Sends a MIDI *system exclusive* message. The generated message will automatically be prepended\nwith the *SysEx* byte (0xF0) and terminated with the *End of SysEx* byte (0xF7).\n\nFor example, if you want to send a SysEx message to a Korg device connected to the first\noutput, you would use the following code:\n\n WebMidi.outputs[0].sendSysex(0x42, [1, 2, 3, 4, 5]);\n\nThe above code sends the byte values 1, 2, 3, 4 and 5 to Korg (ID 0x42) devices. Some\nmanufacturers are identified using 3 bytes. In this case, you would use a 3-position array as\nthe first parameter. For example, to send the same SysEx message to a *Native Instruments*\ndevice:\n\n WebMidi.outputs[0].sendSysex([0x00, 0x21, 0x09], [1, 2, 3, 4, 5]);\n\nThere is no limit for the length of the data array. However, it is generally suggested to keep\nsystem exclusive messages to 64Kb or less.", "itemtype": "method", "name": "sendSysex", @@ -2081,7 +2081,7 @@ }, { "file": "src/webmidi.js", - "line": 2352, + "line": 2353, "description": "Sends a *MIDI Timecode Quarter Frame* message. Please note that no processing is being done on\nthe data. It is up to the developer to format the data according to the\n[MIDI Timecode](https://en.wikipedia.org/wiki/MIDI_timecode) format.", "itemtype": "method", "name": "sendTimecodeQuarterFrame", @@ -2117,7 +2117,7 @@ }, { "file": "src/webmidi.js", - "line": 2380, + "line": 2381, "description": "Sends a *Song Position* MIDI message. The value is expressed in MIDI beats (between 0 and\n16383) which are 16th note. Position 0 is always the start of the song.", "itemtype": "method", "name": "sendSongPosition", @@ -2155,7 +2155,7 @@ }, { "file": "src/webmidi.js", - "line": 2419, + "line": 2420, "description": "Sends a *Song Select* MIDI message. Beware that some devices will display position 0 as\nposition 1 for user-friendlyness.", "itemtype": "method", "name": "sendSongSelect", @@ -2192,7 +2192,7 @@ }, { "file": "src/webmidi.js", - "line": 2458, + "line": 2459, "description": "Sends a *MIDI tuning request* real-time message.\n\nNote: there is currently a bug in Chrome's MIDI implementation. If you try to use this\nfunction, Chrome will actually throw a \"Message is incomplete\" error. The bug is\n[scheduled to be fixed](https://bugs.chromium.org/p/chromium/issues/detail?id=610116).", "itemtype": "method", "name": "sendTuningRequest", @@ -2223,7 +2223,7 @@ }, { "file": "src/webmidi.js", - "line": 2490, + "line": 2491, "description": "Sends a *MIDI Clock* real-time message. According to the standard, there are 24 MIDI Clocks\nfor every quarter note.", "itemtype": "method", "name": "sendClock", @@ -2254,7 +2254,7 @@ }, { "file": "src/webmidi.js", - "line": 2515, + "line": 2516, "description": "Sends a *Start* real-time message. A MIDI Start message starts the playback of the current\nsong at beat 0. To start playback elsewhere in the song, use the `sendContinue()` function.", "itemtype": "method", "name": "sendStart", @@ -2285,7 +2285,7 @@ }, { "file": "src/webmidi.js", - "line": 2540, + "line": 2541, "description": "Sends a *Continue* real-time message. This resumes song playback where it was previously\nstopped or where it was last cued with a song position message. To start playback from the\nstart, use the `sendStart()` function.", "itemtype": "method", "name": "sendContinue", @@ -2316,7 +2316,7 @@ }, { "file": "src/webmidi.js", - "line": 2566, + "line": 2567, "description": "Sends a *Stop* real-time message. This tells the device connected to this port to stop playback\nimmediately (or at the scheduled time).", "itemtype": "method", "name": "sendStop", @@ -2347,7 +2347,7 @@ }, { "file": "src/webmidi.js", - "line": 2591, + "line": 2592, "description": "Sends an *Active Sensing* real-time message. This tells the device connected to this port that\nthe connection is still good. Active sensing messages should be sent every 300 ms if there was\nno other activity on the MIDI port.", "itemtype": "method", "name": "sendActiveSensing", @@ -2378,7 +2378,7 @@ }, { "file": "src/webmidi.js", - "line": 2621, + "line": 2622, "description": "Sends *Reset* real-time message. This tells the device connected to this port that is should\nreset itself to a default state.", "itemtype": "method", "name": "sendReset", @@ -2409,7 +2409,7 @@ }, { "file": "src/webmidi.js", - "line": 2646, + "line": 2647, "description": "Sends a MIDI **note off** message to the specified channel(s) for a single note or multiple\nsimultaneous notes (chord). You can delay the execution of the **note off** command by using\nthe `time` property of the `options` parameter (in milliseconds).", "itemtype": "method", "name": "stopNote", @@ -2466,7 +2466,7 @@ }, { "file": "src/webmidi.js", - "line": 2733, + "line": 2734, "description": "Requests the playback of a single note or multiple notes on the specified channel(s). You can\ndelay the execution of the **note on** command by using the `time` property of the `options`\nparameter (milliseconds).\n\nIf no duration is specified in the `options`, the note will play until a matching **note off**\nis sent. If a duration is specified, a **note off** will be automatically sent after said\nduration.\n\nNote: As per the MIDI standard, a **note on** event with a velocity of `0` is considered to be\na **note off**.", "itemtype": "method", "name": "playNote", @@ -2537,7 +2537,7 @@ }, { "file": "src/webmidi.js", - "line": 2869, + "line": 2870, "description": "Sends a MIDI `key aftertouch` message to the specified channel(s) at the scheduled time. This\nis a key-specific aftertouch. For a channel-wide aftertouch message, use\n{{#crossLink \"WebMidi/sendChannelAftertouch:method\"}}sendChannelAftertouch(){{/crossLink}}.", "itemtype": "method", "name": "sendKeyAftertouch", @@ -2591,7 +2591,7 @@ }, { "file": "src/webmidi.js", - "line": 2937, + "line": 2938, "description": "Sends a MIDI `control change` message to the specified channel(s) at the scheduled time. The\ncontrol change message to send can be specified numerically or by using one of the following\ncommon names:\n\n * `bankselectcoarse` (#0)\n * `modulationwheelcoarse` (#1)\n * `breathcontrollercoarse` (#2)\n * `footcontrollercoarse` (#4)\n * `portamentotimecoarse` (#5)\n * `dataentrycoarse` (#6)\n * `volumecoarse` (#7)\n * `balancecoarse` (#8)\n * `pancoarse` (#10)\n * `expressioncoarse` (#11)\n * `effectcontrol1coarse` (#12)\n * `effectcontrol2coarse` (#13)\n * `generalpurposeslider1` (#16)\n * `generalpurposeslider2` (#17)\n * `generalpurposeslider3` (#18)\n * `generalpurposeslider4` (#19)\n * `bankselectfine` (#32)\n * `modulationwheelfine` (#33)\n * `breathcontrollerfine` (#34)\n * `footcontrollerfine` (#36)\n * `portamentotimefine` (#37)\n * `dataentryfine` (#38)\n * `volumefine` (#39)\n * `balancefine` (#40)\n * `panfine` (#42)\n * `expressionfine` (#43)\n * `effectcontrol1fine` (#44)\n * `effectcontrol2fine` (#45)\n * `holdpedal` (#64)\n * `portamento` (#65)\n * `sustenutopedal` (#66)\n * `softpedal` (#67)\n * `legatopedal` (#68)\n * `hold2pedal` (#69)\n * `soundvariation` (#70)\n * `resonance` (#71)\n * `soundreleasetime` (#72)\n * `soundattacktime` (#73)\n * `brightness` (#74)\n * `soundcontrol6` (#75)\n * `soundcontrol7` (#76)\n * `soundcontrol8` (#77)\n * `soundcontrol9` (#78)\n * `soundcontrol10` (#79)\n * `generalpurposebutton1` (#80)\n * `generalpurposebutton2` (#81)\n * `generalpurposebutton3` (#82)\n * `generalpurposebutton4` (#83)\n * `reverblevel` (#91)\n * `tremololevel` (#92)\n * `choruslevel` (#93)\n * `celestelevel` (#94)\n * `phaserlevel` (#95)\n * `databuttonincrement` (#96)\n * `databuttondecrement` (#97)\n * `nonregisteredparametercoarse` (#98)\n * `nonregisteredparameterfine` (#99)\n * `registeredparametercoarse` (#100)\n * `registeredparameterfine` (#101)\n\nNote: as you can see above, not all control change message have a matching common name. This\ndoes not mean you cannot use the others. It simply means you will need to use their number\ninstead of their name.\n\nTo view a list of all available `control change` messages, please consult \"Table 3 - Control\nChange Messages\" from the\n[MIDI Messages](https://www.midi.org/specifications/item/table-3-control-change-messages-data-bytes-2)\nspecification.", "itemtype": "method", "name": "sendControlChange", @@ -2645,7 +2645,7 @@ }, { "file": "src/webmidi.js", - "line": 3074, + "line": 3075, "description": "Selects a MIDI registered parameter so it is affected by data entry, data increment and data\ndecrement messages.", "itemtype": "method", "name": "_selectRegisteredParameter", @@ -2674,7 +2674,7 @@ }, { "file": "src/webmidi.js", - "line": 3111, + "line": 3112, "description": "Selects a MIDI non-registered parameter so it is affected by data entry, data increment and\ndata decrement messages.", "itemtype": "method", "name": "_selectNonRegisteredParameter", @@ -2703,7 +2703,7 @@ }, { "file": "src/webmidi.js", - "line": 3148, + "line": 3149, "description": "Sets the value of the currently selected MIDI registered parameter.", "itemtype": "method", "name": "_setCurrentRegisteredParameter", @@ -2732,7 +2732,7 @@ }, { "file": "src/webmidi.js", - "line": 3186, + "line": 3187, "description": "Deselects the currently active MIDI registered parameter so it is no longer affected by data\nentry, data increment and data decrement messages.\n\nCurrent best practice recommends doing that after each call to\n`_setCurrentRegisteredParameter()`.", "itemtype": "method", "name": "_deselectRegisteredParameter", @@ -2756,7 +2756,7 @@ }, { "file": "src/webmidi.js", - "line": 3214, + "line": 3215, "description": "Sets the specified MIDI registered parameter to the desired value. The value is defined with\nup to two bytes of data that each can go from 0 to 127.\n\n>Unless you are very familiar with the MIDI standard you probably should favour one of the\n>simpler to use functions such as: `setPitchbendRange()`, `setModulationRange()`,\n>`setMasterTuning()`, etc.\n\nMIDI registered parameters extend the original list of control change messages. Currently,\nthere are only a limited number of them. Here are the original registered parameters with the\nidentifier that can be used as the first parameter of this function:\n\n * Pitchbend Range (0x00, 0x00): `pitchbendrange`\n * Channel Fine Tuning (0x00, 0x01): `channelfinetuning`\n * Channel Coarse Tuning (0x00, 0x02): `channelcoarsetuning`\n * Tuning Program (0x00, 0x03): `tuningprogram`\n * Tuning Bank (0x00, 0x04): `tuningbank`\n * Modulation Range (0x00, 0x05): `modulationrange`\n\nNote that the **Tuning Program** and **Tuning Bank** parameters are part of the *MIDI Tuning\nStandard*, which is not widely implemented.\n\nAnother set of extra parameters have been later added for 3D sound controllers. They are:\n\n * Azimuth Angle (0x3D, 0x00): `azimuthangle`\n * Elevation Angle (0x3D, 0x01): `elevationangle`\n * Gain (0x3D, 0x02): `gain`\n * Distance Ratio (0x3D, 0x03): `distanceratio`\n * Maximum Distance (0x3D, 0x04): `maximumdistance`\n * Maximum Distance Gain (0x3D, 0x05): `maximumdistancegain`\n * Reference Distance Ratio (0x3D, 0x06): `referencedistanceratio`\n * Pan Spread Angle (0x3D, 0x07): `panspreadangle`\n * Roll Angle (0x3D, 0x08): `rollangle`", "itemtype": "method", "name": "setRegisteredParameter", @@ -2806,7 +2806,7 @@ }, { "file": "src/webmidi.js", - "line": 3297, + "line": 3298, "description": "Sets a non-registered parameter to the specified value. The NRPN is selected by passing in a\ntwo-position array specifying the values of the two control bytes. The value is specified by\npassing in an single integer (most cases) or an array of two integers.\n\nNRPNs are not standardized in any way. Each manufacturer is free to implement them any way\nthey see fit. For example, according to the Roland GS specification, you can control the\n**vibrato rate** using NRPN (1, 8). Therefore, to set the **vibrato rate** value to **123** you\nwould use:\n\n WebMidi.outputs[0].setNonRegisteredParameter([1, 8], 123);\n\nObviously, you should select a channel so the message is not sent to all channels. For\ninstance, to send to channel 1 of the first output port, you would use:\n\n WebMidi.outputs[0].setNonRegisteredParameter([1, 8], 123, 1);\n\nIn some rarer cases, you need to send two values with your NRPN messages. In such cases, you\nwould use a 2-position array. For example, for its **ClockBPM** parameter (2, 63), Novation\nuses a 14-bit value that combines an MSB and an LSB (7-bit values). So, for example, if the\nvalue to send was 10, you could use:\n\n WebMidi.outputs[0].setNonRegisteredParameter([2, 63], [0, 10]);\n\nFor further implementation details, refer to the manufacturer's documentation.", "itemtype": "method", "name": "setNonRegisteredParameter", @@ -2856,7 +2856,7 @@ }, { "file": "src/webmidi.js", - "line": 3375, + "line": 3376, "description": "Increments the specified MIDI registered parameter by 1. For more specific MIDI usage\ninformation, check out [RP-18](http://dev.midi.org/techspecs/rp18.php) regarding the usage of\nincrement and decrement controllers.\n\n>Unless you are very familiar with the MIDI standard you probably should favour one of the\n>simpler to use functions such as: `setPitchbendRange()`, `setModulationRange()`,\n>`setMasterTuning()`, etc.\n\nHere is the full list of parameter names that can be used with this function:\n\n * Pitchbend Range (0x00, 0x00): `pitchbendrange`\n * Channel Fine Tuning (0x00, 0x01): `channelfinetuning`\n * Channel Coarse Tuning (0x00, 0x02): `channelcoarsetuning`\n * Tuning Program (0x00, 0x03): `tuningprogram`\n * Tuning Bank (0x00, 0x04): `tuningbank`\n * Modulation Range (0x00, 0x05): `modulationrange`\n * Azimuth Angle (0x3D, 0x00): `azimuthangle`\n * Elevation Angle (0x3D, 0x01): `elevationangle`\n * Gain (0x3D, 0x02): `gain`\n * Distance Ratio (0x3D, 0x03): `distanceratio`\n * Maximum Distance (0x3D, 0x04): `maximumdistance`\n * Maximum Distance Gain (0x3D, 0x05): `maximumdistancegain`\n * Reference Distance Ratio (0x3D, 0x06): `referencedistanceratio`\n * Pan Spread Angle (0x3D, 0x07): `panspreadangle`\n * Roll Angle (0x3D, 0x08): `rollangle`", "itemtype": "method", "name": "incrementRegisteredParameter", @@ -2899,7 +2899,7 @@ }, { "file": "src/webmidi.js", - "line": 3448, + "line": 3449, "description": "Decrements the specified MIDI registered parameter by 1. For more specific MIDI usage\ninformation, check out [RP-18](http://dev.midi.org/techspecs/rp18.php) regarding the usage of\nincrement and decrement controllers.\n\n>Unless you are very familiar with the MIDI standard you probably should favour one of the\n>simpler to use functions such as: `setPitchbendRange()`, `setModulationRange()`,\n>`setMasterTuning()`, etc.\n\nHere is the full list of parameter names that can be used with this function:\n\n * Pitchbend Range (0x00, 0x00): `pitchbendrange`\n * Channel Fine Tuning (0x00, 0x01): `channelfinetuning`\n * Channel Coarse Tuning (0x00, 0x02): `channelcoarsetuning`\n * Tuning Program (0x00, 0x03): `tuningprogram`\n * Tuning Bank (0x00, 0x04): `tuningbank`\n * Modulation Range (0x00, 0x05): `modulationrange`\n * Azimuth Angle (0x3D, 0x00): `azimuthangle`\n * Elevation Angle (0x3D, 0x01): `elevationangle`\n * Gain (0x3D, 0x02): `gain`\n * Distance Ratio (0x3D, 0x03): `distanceratio`\n * Maximum Distance (0x3D, 0x04): `maximumdistance`\n * Maximum Distance Gain (0x3D, 0x05): `maximumdistancegain`\n * Reference Distance Ratio (0x3D, 0x06): `referencedistanceratio`\n * Pan Spread Angle (0x3D, 0x07): `panspreadangle`\n * Roll Angle (0x3D, 0x08): `rollangle`", "itemtype": "method", "name": "decrementRegisteredParameter", @@ -2945,7 +2945,7 @@ }, { "file": "src/webmidi.js", - "line": 3521, + "line": 3522, "description": "Sends a pitch bend range message to the specified channel(s) at the scheduled time so that they\nadjust the range used by their pitch bend lever. The range can be specified with the `semitones`\nparameter, the `cents` parameter or by specifying both parameters at the same time.", "itemtype": "method", "name": "setPitchBendRange", @@ -3001,7 +3001,7 @@ }, { "file": "src/webmidi.js", - "line": 3580, + "line": 3581, "description": "Sends a modulation depth range message to the specified channel(s) so that they adjust the\ndepth of their modulation wheel's range. The range can be specified with the `semitones`\nparameter, the `cents` parameter or by specifying both parameters at the same time.", "itemtype": "method", "name": "setModulationRange", @@ -3057,7 +3057,7 @@ }, { "file": "src/webmidi.js", - "line": 3638, + "line": 3639, "description": "Sends a master tuning message to the specified channel(s). The value is decimal and must be\nlarger than -65 semitones and smaller than 64 semitones.\n\n>Because of the way the MIDI specification works, the decimal portion of the value will be\n>encoded with a resolution of 14bit. The integer portion must be between -64 and 63\n>inclusively. For those familiar with the MIDI protocol, this function actually generates\n>**Master Coarse Tuning** and **Master Fine Tuning** RPN messages.", "itemtype": "method", "name": "setMasterTuning", @@ -3106,7 +3106,7 @@ }, { "file": "src/webmidi.js", - "line": 3702, + "line": 3703, "description": "Sets the MIDI tuning program to use. Note that the **Tuning Program** parameter is part of the\n*MIDI Tuning Standard*, which is not widely implemented.", "itemtype": "method", "name": "setTuningProgram", @@ -3153,7 +3153,7 @@ }, { "file": "src/webmidi.js", - "line": 3748, + "line": 3749, "description": "Sets the MIDI tuning bank to use. Note that the **Tuning Bank** parameter is part of the\n*MIDI Tuning Standard*, which is not widely implemented.", "itemtype": "method", "name": "setTuningBank", @@ -3200,7 +3200,7 @@ }, { "file": "src/webmidi.js", - "line": 3794, + "line": 3795, "description": "Sends a MIDI `channel mode` message to the specified channel(s). The channel mode message to send can be specified\nnumerically or by using one of the following common names:\n\n * `allsoundoff` (#120)\n * `resetallcontrollers` (#121)\n * `localcontrol` (#122)\n * `allnotesoff` (#123)\n * `omnimodeoff` (#124)\n * `omnimodeon` (#125)\n * `monomodeon` (#126)\n * `polymodeon` (#127)\n\nIt should be noted that, per the MIDI specification, only `localcontrol` and `monomodeon` may require a value\nthat's not zero. For that reason, the `value` parameter is optional and defaults to 0.", "itemtype": "method", "name": "sendChannelMode", @@ -3254,7 +3254,7 @@ }, { "file": "src/webmidi.js", - "line": 3875, + "line": 3876, "description": "Sends a MIDI `program change` message to the specified channel(s) at the scheduled time.", "itemtype": "method", "name": "sendProgramChange", @@ -3301,7 +3301,7 @@ }, { "file": "src/webmidi.js", - "line": 3925, + "line": 3926, "description": "Sends a MIDI `channel aftertouch` message to the specified channel(s). For key-specific\naftertouch, you should instead use `sendKeyAftertouch()`.", "itemtype": "method", "name": "sendChannelAftertouch", @@ -3346,7 +3346,7 @@ }, { "file": "src/webmidi.js", - "line": 3974, + "line": 3975, "description": "Sends a MIDI `pitch bend` message to the specified channel(s) at the scheduled time.", "itemtype": "method", "name": "sendPitchBend", @@ -3393,7 +3393,7 @@ }, { "file": "src/webmidi.js", - "line": 4028, + "line": 4029, "description": "Returns a timestamp, relative to the navigation start of the document, derived from the `time`\nparameter. If the parameter is a string starting with the \"+\" sign and followed by a number,\nthe resulting value will be the sum of the current timestamp plus that number. Otherwise, the\nvalue will be returned as is.\n\nIf the calculated return value is 0, less than zero or an otherwise invalid value, `undefined`\nwill be returned.", "itemtype": "method", "name": "_parseTimeParameter", @@ -3414,7 +3414,7 @@ }, { "file": "src/webmidi.js", - "line": 4058, + "line": 4059, "description": "Converts an input value (which can be a uint, a string or an array of the previous two) to an\narray of MIDI note numbers.", "itemtype": "method", "name": "_convertNoteToArray", @@ -3432,7 +3432,7 @@ }, { "file": "src/webmidi.js", - "line": 4080, + "line": 4081, "description": "Converts an input value (which can be an int, an array or the value \"all\" to an array of valid\nMIDI channels. If `undefined` is provided as the channel, an array of all channels will be\nreturned.", "itemtype": "method", "name": "_convertChannelToArray", @@ -3450,7 +3450,7 @@ }, { "file": "src/webmidi.js", - "line": 4110, + "line": 4111, "itemtype": "method", "name": "_onMidiMessage", "access": "protected", @@ -3461,79 +3461,79 @@ "warnings": [ { "message": "replacing incorrect tag: returns with return", - "line": " src/webmidi.js:682" + "line": " src/webmidi.js:683" }, { "message": "replacing incorrect tag: returns with return", - "line": " src/webmidi.js:714" + "line": " src/webmidi.js:715" }, { "message": "replacing incorrect tag: returns with return", - "line": " src/webmidi.js:746" + "line": " src/webmidi.js:747" }, { "message": "replacing incorrect tag: returns with return", - "line": " src/webmidi.js:780" + "line": " src/webmidi.js:781" }, { "message": "replacing incorrect tag: returns with return", - "line": " src/webmidi.js:802" + "line": " src/webmidi.js:803" }, { "message": "replacing incorrect tag: returns with return", - "line": " src/webmidi.js:835" + "line": " src/webmidi.js:836" }, { "message": "replacing incorrect tag: returns with return", - "line": " src/webmidi.js:1805" + "line": " src/webmidi.js:1806" }, { "message": "replacing incorrect tag: returns with return", - "line": " src/webmidi.js:1836" + "line": " src/webmidi.js:1837" }, { "message": "unknown tag: throw", - "line": " src/webmidi.js:2282" + "line": " src/webmidi.js:2283" }, { "message": "unknown tag: throw", - "line": " src/webmidi.js:2282" + "line": " src/webmidi.js:2283" }, { "message": "unknown tag: throw", - "line": " src/webmidi.js:2419" + "line": " src/webmidi.js:2420" }, { "message": "replacing incorrect tag: returns with return", - "line": " src/webmidi.js:3074" + "line": " src/webmidi.js:3075" }, { "message": "replacing incorrect tag: returns with return", - "line": " src/webmidi.js:3111" + "line": " src/webmidi.js:3112" }, { "message": "replacing incorrect tag: returns with return", - "line": " src/webmidi.js:3148" + "line": " src/webmidi.js:3149" }, { "message": "replacing incorrect tag: returns with return", - "line": " src/webmidi.js:3186" + "line": " src/webmidi.js:3187" }, { "message": "replacing incorrect tag: returns with return", - "line": " src/webmidi.js:3214" + "line": " src/webmidi.js:3215" }, { "message": "replacing incorrect tag: returns with return", - "line": " src/webmidi.js:3297" + "line": " src/webmidi.js:3298" }, { "message": "replacing incorrect tag: returns with return", - "line": " src/webmidi.js:3375" + "line": " src/webmidi.js:3376" }, { "message": "replacing incorrect tag: returns with return", - "line": " src/webmidi.js:3448" + "line": " src/webmidi.js:3449" } ] } \ No newline at end of file diff --git a/docs/latest/files/src_webmidi.js.html b/docs/latest/files/src_webmidi.js.html index 706d46cb9..f95279272 100644 --- a/docs/latest/files/src_webmidi.js.html +++ b/docs/latest/files/src_webmidi.js.html @@ -17,7 +17,7 @@

- API Docs for: 2.0.0-rc.8 + API Docs for: 2.0.0-rc.9
@@ -613,6 +613,7 @@

File: src/webmidi.js

throw new Error("The Web MIDI API is not supported by your browser."); } + this.interface.onstatechange = undefined; this.interface = undefined; // also resets enabled, sysexEnabled this._inputs = []; this._outputs = []; @@ -1028,7 +1029,7 @@

File: src/webmidi.js

} - // Check for items to add in the existing inputs array because they jsut appeared in the MIDI + // Check for items to add in the existing inputs array because they just appeared in the MIDI // back-end inputs list. this.interface.inputs.forEach(function (nInput) { diff --git a/docs/latest/index.html b/docs/latest/index.html index 499cc01ec..11349d0cf 100644 --- a/docs/latest/index.html +++ b/docs/latest/index.html @@ -17,7 +17,7 @@

- API Docs for: 2.0.0-rc.8 + API Docs for: 2.0.0-rc.9
diff --git a/webmidi.min.js b/webmidi.min.js index 59d7b4a67..2c8fb3ab5 100644 --- a/webmidi.min.js +++ b/webmidi.min.js @@ -1,6 +1,6 @@ /* -WebMidi v2.0.0-rc.8 +WebMidi v2.0.0-rc.9 WebMidi.js helps you tame the Web MIDI API. Send and receive MIDI messages with ease. Control instruments with user-friendly functions (playNote, sendPitchBend, etc.). React to MIDI input with simple event listeners (noteon, pitchbend, controlchange, etc.). https://github.com/cotejp/webmidi @@ -27,5 +27,5 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -!function(scope){"use strict";function WebMidi(){if(WebMidi.prototype._singleton)throw new Error("WebMidi is a singleton, it cannot be instantiated directly.");WebMidi.prototype._singleton=this,this._inputs=[],this._outputs=[],this._userHandlers={},this._stateChangeQueue=[],this._processingStateChange=!1,this._midiInterfaceEvents=["connected","disconnected"],this._notes=["C","C#","D","D#","E","F","F#","G","G#","A","A#","B"],this._semitones={C:0,D:2,E:4,F:5,G:7,A:9,B:11},Object.defineProperties(this,{MIDI_SYSTEM_MESSAGES:{value:{sysex:240,timecode:241,songposition:242,songselect:243,tuningrequest:246,sysexend:247,clock:248,start:250,"continue":251,stop:252,activesensing:254,reset:255,unknownsystemmessage:-1},writable:!1,enumerable:!0,configurable:!1},MIDI_CHANNEL_MESSAGES:{value:{noteoff:8,noteon:9,keyaftertouch:10,controlchange:11,channelmode:11,programchange:12,channelaftertouch:13,pitchbend:14},writable:!1,enumerable:!0,configurable:!1},MIDI_REGISTERED_PARAMETER:{value:{pitchbendrange:[0,0],channelfinetuning:[0,1],channelcoarsetuning:[0,2],tuningprogram:[0,3],tuningbank:[0,4],modulationrange:[0,5],azimuthangle:[61,0],elevationangle:[61,1],gain:[61,2],distanceratio:[61,3],maximumdistance:[61,4],maximumdistancegain:[61,5],referencedistanceratio:[61,6],panspreadangle:[61,7],rollangle:[61,8]},writable:!1,enumerable:!0,configurable:!1},MIDI_CONTROL_CHANGE_MESSAGES:{value:{bankselectcoarse:0,modulationwheelcoarse:1,breathcontrollercoarse:2,footcontrollercoarse:4,portamentotimecoarse:5,dataentrycoarse:6,volumecoarse:7,balancecoarse:8,pancoarse:10,expressioncoarse:11,effectcontrol1coarse:12,effectcontrol2coarse:13,generalpurposeslider1:16,generalpurposeslider2:17,generalpurposeslider3:18,generalpurposeslider4:19,bankselectfine:32,modulationwheelfine:33,breathcontrollerfine:34,footcontrollerfine:36,portamentotimefine:37,dataentryfine:38,volumefine:39,balancefine:40,panfine:42,expressionfine:43,effectcontrol1fine:44,effectcontrol2fine:45,holdpedal:64,portamento:65,sustenutopedal:66,softpedal:67,legatopedal:68,hold2pedal:69,soundvariation:70,resonance:71,soundreleasetime:72,soundattacktime:73,brightness:74,soundcontrol6:75,soundcontrol7:76,soundcontrol8:77,soundcontrol9:78,soundcontrol10:79,generalpurposebutton1:80,generalpurposebutton2:81,generalpurposebutton3:82,generalpurposebutton4:83,reverblevel:91,tremololevel:92,choruslevel:93,celestelevel:94,phaserlevel:95,databuttonincrement:96,databuttondecrement:97,nonregisteredparametercoarse:98,nonregisteredparameterfine:99,registeredparametercoarse:100,registeredparameterfine:101},writable:!1,enumerable:!0,configurable:!1},MIDI_CHANNEL_MODE_MESSAGES:{value:{allsoundoff:120,resetallcontrollers:121,localcontrol:122,allnotesoff:123,omnimodeoff:124,omnimodeon:125,monomodeon:126,polymodeon:127},writable:!1,enumerable:!0,configurable:!1}}),Object.defineProperties(this,{supported:{enumerable:!0,get:function(){return"requestMIDIAccess"in navigator}},enabled:{enumerable:!0,get:function(){return void 0!==this["interface"]}.bind(this)},inputs:{enumerable:!0,get:function(){return this._inputs}.bind(this)},outputs:{enumerable:!0,get:function(){return this._outputs}.bind(this)},sysexEnabled:{enumerable:!0,get:function(){return!(!this["interface"]||!this["interface"].sysexEnabled)}.bind(this)},time:{enumerable:!0,get:function(){return performance.now()}}})}function Input(midiInput){var that=this;this._userHandlers={channel:{},system:{}},this._midiInput=midiInput,Object.defineProperties(this,{connection:{enumerable:!0,get:function(){return that._midiInput.connection}},id:{enumerable:!0,get:function(){return that._midiInput.id}},manufacturer:{enumerable:!0,get:function(){return that._midiInput.manufacturer}},name:{enumerable:!0,get:function(){return that._midiInput.name}},state:{enumerable:!0,get:function(){return that._midiInput.state}}}),this._initializeUserHandlers()}function Output(midiOutput){var that=this;this._midiOutput=midiOutput,Object.defineProperties(this,{connection:{enumerable:!0,get:function(){return that._midiOutput.connection}},id:{enumerable:!0,get:function(){return that._midiOutput.id}},manufacturer:{enumerable:!0,get:function(){return that._midiOutput.manufacturer}},name:{enumerable:!0,get:function(){return that._midiOutput.name}},state:{enumerable:!0,get:function(){return that._midiOutput.state}}})}var wm=new WebMidi;WebMidi.prototype.enable=function(callback,sysex){return this.enabled?void 0:this.supported?void navigator.requestMIDIAccess({sysex:sysex}).then(function(midiAccess){this["interface"]=midiAccess,this._resetInterfaceUserHandlers(),this["interface"].onstatechange=this._onInterfaceStateChange.bind(this),this._onInterfaceStateChange(null),"function"==typeof callback&&callback.call(this)}.bind(this),function(err){"function"==typeof callback&&callback.call(this,err)}.bind(this)):void("function"==typeof callback&&callback(new Error("The Web MIDI API is not supported by your browser.")))},WebMidi.prototype.disable=function(){if(!this.supported)throw new Error("The Web MIDI API is not supported by your browser.");this["interface"]=void 0,this._inputs=[],this._outputs=[],this._resetInterfaceUserHandlers()},WebMidi.prototype.addListener=function(type,listener){if(!this.enabled)throw new Error("WebMidi must be enabled before adding event listeners.");if("function"!=typeof listener)throw new TypeError("The 'listener' parameter must be a function.");if(!(this._midiInterfaceEvents.indexOf(type)>=0))throw new TypeError("The specified event type is not supported.");return this._userHandlers[type].push(listener),this},WebMidi.prototype.hasListener=function(type,listener){if(!this.enabled)throw new Error("WebMidi must be enabled before checking event listeners.");if("function"!=typeof listener)throw new TypeError("The 'listener' parameter must be a function.");if(!(this._midiInterfaceEvents.indexOf(type)>=0))throw new TypeError("The specified event type is not supported.");for(var o=0;o=0)if(listener)for(var o=0;o=0&&127>=number?Math.floor(parseInt(number)/12-1)-1:void 0},WebMidi.prototype.getOutputByName=function(name){if(!this.enabled)throw new Error("WebMidi is not enabled.");for(var i=0;i=0&&127>=input?output=Math.round(input):parseInt(input)>=0&&parseInt(input)<=127?output=parseInt(input):("string"==typeof input||input instanceof String)&&(output=this.noteNameToNumber(input)),output===!1)throw new Error("Invalid note number ("+input+").");return output},WebMidi.prototype.noteNameToNumber=function(name){"string"!=typeof name&&(name="");var matches=name.match(/([CDEFGAB])(#{0,2}|b{0,2})(-?\d+)/i);if(!matches)throw new RangeError("Invalid note name.");var semitones=wm._semitones[matches[1].toUpperCase()],octave=parseInt(matches[3]),result=12*(octave+2)+semitones;if(matches[2].toLowerCase().indexOf("b")>-1?result-=matches[2].length:matches[2].toLowerCase().indexOf("#")>-1&&(result+=matches[2].length),0>semitones||-2>octave||octave>8||0>result||result>127)throw new RangeError("Invalid note name or note outside valid range.");return result},WebMidi.prototype._updateInputsAndOutputs=function(){this._updateInputs(),this._updateOutputs()},WebMidi.prototype._updateInputs=function(){for(var i=0;i0;)this._processStateChange(this._stateChangeQueue.shift());this._processingStateChange=!1}},WebMidi.prototype._processStateChange=function(e){if(this._updateInputsAndOutputs(),null!==e){var event={timestamp:e.timeStamp,type:e.port.state,id:e.port.id,manufacturer:e.port.manufacturer,name:e.port.name};"connected"===e.port.state&&("output"===e.port.type?event.output=this.getOutputById(e.port.id):"input"===e.port.type&&(event.input=this.getInputById(e.port.id))),this._userHandlers[e.port.state].forEach(function(handler){handler(event)})}},WebMidi.prototype._resetInterfaceUserHandlers=function(){for(var i=0;i=1&&16>=item))throw new RangeError("The 'channel' parameter is invalid.")}),"function"!=typeof listener)throw new TypeError("The 'listener' parameter must be a function.");if(wm.MIDI_SYSTEM_MESSAGES[type])this._userHandlers.system[type]||(this._userHandlers.system[type]=[]),this._userHandlers.system[type].push(listener);else{if(!wm.MIDI_CHANNEL_MESSAGES[type])throw new TypeError("The specified event type is not supported.");if(channel.indexOf("all")>-1){channel=[];for(var j=1;16>=j;j++)channel.push(j)}this._userHandlers.channel[type]||(this._userHandlers.channel[type]=[]),channel.forEach(function(ch){that._userHandlers.channel[type][ch]||(that._userHandlers.channel[type][ch]=[]),that._userHandlers.channel[type][ch].push(listener)})}return this},Input.prototype.on=Input.prototype.addListener,Input.prototype.hasListener=function(type,channel,listener){var that=this;if("function"!=typeof listener)throw new TypeError("The 'listener' parameter must be a function.");if(void 0===channel&&(channel="all"),channel.constructor!==Array&&(channel=[channel]),wm.MIDI_SYSTEM_MESSAGES[type]){for(var o=0;o-1){channel=[];for(var j=1;16>=j;j++)channel.push(j)}return this._userHandlers.channel[type]?channel.every(function(chNum){var listeners=that._userHandlers.channel[type][chNum];return listeners&&listeners.indexOf(listener)>-1}):!1}return!1},Input.prototype.removeListener=function(type,channel,listener){var that=this;if(void 0!==listener&&"function"!=typeof listener)throw new TypeError("The 'listener' parameter must be a function.");if(void 0===channel&&(channel="all"),channel.constructor!==Array&&(channel=[channel]),wm.MIDI_SYSTEM_MESSAGES[type])if(void 0===listener)this._userHandlers.system[type]=[];else for(var o=0;o-1){channel=[];for(var j=1;16>=j;j++)channel.push(j)}if(!this._userHandlers.channel[type])return this;channel.forEach(function(chNum){var listeners=that._userHandlers.channel[type][chNum];if(listeners)if(void 0===listener)that._userHandlers.channel[type][chNum]=[];else for(var l=0;l>4,channel=(15&e.data[0])+1;e.data.length>1&&(data1=e.data[1],data2=e.data.length>2?e.data[2]:void 0);var event={target:this,data:e.data,timestamp:e.timeStamp,channel:channel};command===wm.MIDI_CHANNEL_MESSAGES.noteoff||command===wm.MIDI_CHANNEL_MESSAGES.noteon&&0===data2?(event.type="noteoff",event.note={number:data1,name:wm._notes[data1%12],octave:wm.getOctave(data1)},event.velocity=data2/127,event.rawVelocity=data2):command===wm.MIDI_CHANNEL_MESSAGES.noteon?(event.type="noteon",event.note={number:data1,name:wm._notes[data1%12],octave:wm.getOctave(data1)},event.velocity=data2/127,event.rawVelocity=data2):command===wm.MIDI_CHANNEL_MESSAGES.keyaftertouch?(event.type="keyaftertouch",event.note={number:data1,name:wm._notes[data1%12],octave:wm.getOctave(data1)},event.value=data2/127):command===wm.MIDI_CHANNEL_MESSAGES.controlchange&&data1>=0&&119>=data1?(event.type="controlchange",event.controller={number:data1,name:this.getCcNameByNumber(data1)},event.value=data2):command===wm.MIDI_CHANNEL_MESSAGES.channelmode&&data1>=120&&127>=data1?(event.type="channelmode",event.controller={number:data1,name:this.getChannelModeByNumber(data1)},event.value=data2):command===wm.MIDI_CHANNEL_MESSAGES.programchange?(event.type="programchange",event.value=data1):command===wm.MIDI_CHANNEL_MESSAGES.channelaftertouch?(event.type="channelaftertouch",event.value=data1/127):command===wm.MIDI_CHANNEL_MESSAGES.pitchbend?(event.type="pitchbend",event.value=((data2<<7)+data1-8192)/8192):event.type="unknownchannelmessage",this._userHandlers.channel[event.type]&&this._userHandlers.channel[event.type][channel]&&this._userHandlers.channel[event.type][channel].forEach(function(callback){callback(event)})},Input.prototype.getCcNameByNumber=function(number){if(number=parseInt(number),!(number>=0&&119>=number))throw new RangeError("The control change number must be between 0 and 119.");for(var cc in wm.MIDI_CONTROL_CHANGE_MESSAGES)if(number===wm.MIDI_CONTROL_CHANGE_MESSAGES[cc])return cc;return void 0},Input.prototype.getChannelModeByNumber=function(number){if(number=parseInt(number),!(number>=120&&status<=127))throw new RangeError("The control change number must be between 120 and 127.");for(var cm in wm.MIDI_CHANNEL_MODE_MESSAGES)if(number===wm.MIDI_CHANNEL_MODE_MESSAGES[cm])return cm},Input.prototype._parseSystemEvent=function(e){var command=e.data[0],event={target:this,data:e.data,timestamp:e.timeStamp};command===wm.MIDI_SYSTEM_MESSAGES.sysex?event.type="sysex":command===wm.MIDI_SYSTEM_MESSAGES.timecode?event.type="timecode":command===wm.MIDI_SYSTEM_MESSAGES.songposition?event.type="songposition":command===wm.MIDI_SYSTEM_MESSAGES.songselect?(event.type="songselect",event.song=e.data[1]):command===wm.MIDI_SYSTEM_MESSAGES.tuningrequest?event.type="tuningrequest":command===wm.MIDI_SYSTEM_MESSAGES.clock?event.type="clock":command===wm.MIDI_SYSTEM_MESSAGES.start?event.type="start":command===wm.MIDI_SYSTEM_MESSAGES["continue"]?event.type="continue":command===wm.MIDI_SYSTEM_MESSAGES.stop?event.type="stop":command===wm.MIDI_SYSTEM_MESSAGES.activesensing?event.type="activesensing":command===wm.MIDI_SYSTEM_MESSAGES.reset?event.type="reset":event.type="unknownsystemmessage",this._userHandlers.system[event.type]&&this._userHandlers.system[event.type].forEach(function(callback){callback(event)})},Output.prototype.send=function(status,data,timestamp){if(!(status>=128&&255>=status))throw new RangeError("The status byte must be an integer between 128 (0x80) and 255 (0xFF).");Array.isArray(data)||(data=parseInt(data)>=0&&parseInt(data)<=127?[parseInt(data)]:[]);var message=[status];return data.forEach(function(item){if(!(item>=0&&255>=item))throw new RangeError("The data bytes must be integers between 0 (0x00) and 255 (0xFF).");message.push(item)}),this._midiOutput.send(message,parseFloat(timestamp)||0),this},Output.prototype.sendSysex=function(manufacturer,data,options){if(!wm.sysexEnabled)throw new Error("SysEx message support must first be activated.");return options=options||{},manufacturer=[].concat(manufacturer),data.forEach(function(item){if(0>item||item>127)throw new RangeError("The data bytes of a SysEx message must be integers between 0 (0x00) and 127 (0x7F).")}),data=manufacturer.concat(data,wm.MIDI_SYSTEM_MESSAGES.sysexend),this.send(wm.MIDI_SYSTEM_MESSAGES.sysex,data,this._parseTimeParameter(options.time)),this},Output.prototype.sendTimecodeQuarterFrame=function(value,options){return options=options||{},this.send(wm.MIDI_SYSTEM_MESSAGES.timecode,value,this._parseTimeParameter(options.time)),this},Output.prototype.sendSongPosition=function(value,options){value=parseInt(value)||0,options=options||{};var msb=value>>7&127,lsb=127&value;return this.send(wm.MIDI_SYSTEM_MESSAGES.songposition,[msb,lsb],this._parseTimeParameter(options.time)),this},Output.prototype.sendSongSelect=function(value,options){if(value=parseInt(value),options=options||{},!(value>=0&&127>=value))throw new RangeError("The song number must be between 0 and 127.");return this.send(wm.MIDI_SYSTEM_MESSAGES.songselect,[value],this._parseTimeParameter(options.time)),this},Output.prototype.sendTuningRequest=function(options){return options=options||{},this.send(wm.MIDI_SYSTEM_MESSAGES.tuningrequest,void 0,this._parseTimeParameter(options.time)),this},Output.prototype.sendClock=function(options){return options=options||{},this.send(wm.MIDI_SYSTEM_MESSAGES.clock,void 0,this._parseTimeParameter(options.time)),this},Output.prototype.sendStart=function(options){return options=options||{},this.send(wm.MIDI_SYSTEM_MESSAGES.start,void 0,this._parseTimeParameter(options.time)),this},Output.prototype.sendContinue=function(options){return options=options||{},this.send(wm.MIDI_SYSTEM_MESSAGES["continue"],void 0,this._parseTimeParameter(options.time)),this},Output.prototype.sendStop=function(options){return options=options||{},this.send(wm.MIDI_SYSTEM_MESSAGES.stop,void 0,this._parseTimeParameter(options.time)),this},Output.prototype.sendActiveSensing=function(options){return options=options||{},this.send(wm.MIDI_SYSTEM_MESSAGES.activesensing,void 0,this._parseTimeParameter(options.time)),this},Output.prototype.sendReset=function(options){return options=options||{},this.send(wm.MIDI_SYSTEM_MESSAGES.reset,void 0,this._parseTimeParameter(options.time)),this},Output.prototype.stopNote=function(note,channel,options){if("all"===note)return this.sendChannelMode("allnotesoff",0,channel,options);var nVelocity=64;return options=options||{},options.velocity=parseFloat(options.velocity),options.rawVelocity?!isNaN(options.velocity)&&options.velocity>=0&&options.velocity<=127&&(nVelocity=options.velocity):!isNaN(options.velocity)&&options.velocity>=0&&options.velocity<=1&&(nVelocity=127*options.velocity),this._convertNoteToArray(note).forEach(function(item){this._convertChannelToArray(channel).forEach(function(ch){this.send((wm.MIDI_CHANNEL_MESSAGES.noteoff<<4)+(ch-1),[item,Math.round(nVelocity)],this._parseTimeParameter(options.time))}.bind(this))}.bind(this)),this},Output.prototype.playNote=function(note,channel,options){var nVelocity=64;if(options=options||{},options.velocity=parseFloat(options.velocity),options.rawVelocity?!isNaN(options.velocity)&&options.velocity>=0&&options.velocity<=127&&(nVelocity=options.velocity):!isNaN(options.velocity)&&options.velocity>=0&&options.velocity<=1&&(nVelocity=127*options.velocity),options.time=this._parseTimeParameter(options.time),this._convertNoteToArray(note).forEach(function(item){this._convertChannelToArray(channel).forEach(function(ch){this.send((wm.MIDI_CHANNEL_MESSAGES.noteon<<4)+(ch-1),[item,Math.round(nVelocity)],options.time)}.bind(this))}.bind(this)),options.duration=parseFloat(options.duration),options.duration){options.duration<=0&&(options.duration=0);var nRelease=64;options.release=parseFloat(options.release),options.rawVelocity?!isNaN(options.release)&&options.release>=0&&options.release<=127&&(nRelease=options.release):!isNaN(options.release)&&options.release>=0&&options.release<=1&&(nRelease=127*options.release),this._convertNoteToArray(note).forEach(function(item){this._convertChannelToArray(channel).forEach(function(ch){this.send((wm.MIDI_CHANNEL_MESSAGES.noteoff<<4)+(ch-1),[item,Math.round(nRelease)],(options.time||wm.time)+options.duration)}.bind(this))}.bind(this))}return this},Output.prototype.sendKeyAftertouch=function(note,channel,pressure,options){var that=this;if(options=options||{},1>channel||channel>16)throw new RangeError("The channel must be between 1 and 16.");pressure=parseFloat(pressure),(isNaN(pressure)||0>pressure||pressure>1)&&(pressure=.5);var nPressure=Math.round(127*pressure);return this._convertNoteToArray(note).forEach(function(item){that._convertChannelToArray(channel).forEach(function(ch){that.send((wm.MIDI_CHANNEL_MESSAGES.keyaftertouch<<4)+(ch-1),[item,nPressure],that._parseTimeParameter(options.time))})}),this},Output.prototype.sendControlChange=function(controller,value,channel,options){if(options=options||{},"string"==typeof controller){if(controller=wm.MIDI_CONTROL_CHANGE_MESSAGES[controller],!controller)throw new TypeError("Invalid controller name.")}else if(controller=parseInt(controller),!(controller>=0&&119>=controller))throw new RangeError("Controller numbers must be between 0 and 119.");if(value=parseInt(value)||0,!(value>=0&&127>=value))throw new RangeError("Controller value must be between 0 and 127.");return this._convertChannelToArray(channel).forEach(function(ch){this.send((wm.MIDI_CHANNEL_MESSAGES.controlchange<<4)+(ch-1),[controller,value],this._parseTimeParameter(options.time))}.bind(this)),this},Output.prototype._selectRegisteredParameter=function(parameter,channel,time){var that=this;if(parameter[0]=parseInt(parameter[0]),!(parameter[0]>=0&¶meter[0]<=127))throw new RangeError("The control65 value must be between 0 and 127");if(parameter[1]=parseInt(parameter[1]),!(parameter[1]>=0&¶meter[1]<=127))throw new RangeError("The control64 value must be between 0 and 127");return this._convertChannelToArray(channel).forEach(function(ch){that.sendControlChange(101,parameter[0],channel,{time:time}),that.sendControlChange(100,parameter[1],channel,{time:time})}),this},Output.prototype._selectNonRegisteredParameter=function(parameter,channel,time){var that=this;if(parameter[0]=parseInt(parameter[0]),!(parameter[0]>=0&¶meter[0]<=127))throw new RangeError("The control63 value must be between 0 and 127");if(parameter[1]=parseInt(parameter[1]),!(parameter[1]>=0&¶meter[1]<=127))throw new RangeError("The control62 value must be between 0 and 127");return this._convertChannelToArray(channel).forEach(function(ch){that.sendControlChange(99,parameter[0],channel,{time:time}),that.sendControlChange(98,parameter[1],channel,{time:time})}),this},Output.prototype._setCurrentRegisteredParameter=function(data,channel,time){var that=this;if(data=[].concat(data),data[0]=parseInt(data[0]),!(data[0]>=0&&data[0]<=127))throw new RangeError("The msb value must be between 0 and 127");return this._convertChannelToArray(channel).forEach(function(ch){that.sendControlChange(6,data[0],channel,{time:time})}),data[1]=parseInt(data[1]),data[1]>=0&&data[1]<=127&&this._convertChannelToArray(channel).forEach(function(ch){that.sendControlChange(38,data[1],channel,{time:time})}),this},Output.prototype._deselectRegisteredParameter=function(channel,time){var that=this;return this._convertChannelToArray(channel).forEach(function(ch){that.sendControlChange(101,127,channel,{time:time}),that.sendControlChange(100,127,channel,{time:time})}),this},Output.prototype.setRegisteredParameter=function(parameter,data,channel,options){var that=this;if(options=options||{},!Array.isArray(parameter)){if(!wm.MIDI_REGISTERED_PARAMETER[parameter])throw new Error("The specified parameter is not available.");parameter=wm.MIDI_REGISTERED_PARAMETER[parameter]}return this._convertChannelToArray(channel).forEach(function(ch){that._selectRegisteredParameter(parameter,channel,options.time),that._setCurrentRegisteredParameter(data,channel,options.time),that._deselectRegisteredParameter(channel,options.time)}),this},Output.prototype.setNonRegisteredParameter=function(parameter,data,channel,options){var that=this;if(options=options||{},!(parameter[0]>=0&¶meter[0]<=127&¶meter[1]>=0&¶meter[1]<=127))throw new Error("Position 0 and 1 of the 2-position parameter array must both be between 0 and 127.");return data=[].concat(data),this._convertChannelToArray(channel).forEach(function(ch){that._selectNonRegisteredParameter(parameter,channel,options.time),that._setCurrentRegisteredParameter(data,channel,options.time),that._deselectRegisteredParameter(channel,options.time)}),this},Output.prototype.incrementRegisteredParameter=function(parameter,channel,options){var that=this;if(options=options||{},!Array.isArray(parameter)){if(!wm.MIDI_REGISTERED_PARAMETER[parameter])throw new Error("The specified parameter is not available.");parameter=wm.MIDI_REGISTERED_PARAMETER[parameter]}return this._convertChannelToArray(channel).forEach(function(ch){that._selectRegisteredParameter(parameter,channel,options.time),that.sendControlChange(96,0,channel,{time:options.time}),that._deselectRegisteredParameter(channel,options.time)}),this},Output.prototype.decrementRegisteredParameter=function(parameter,channel,options){if(options=options||{},!Array.isArray(parameter)){if(!wm.MIDI_REGISTERED_PARAMETER[parameter])throw new TypeError("The specified parameter is not available.");parameter=wm.MIDI_REGISTERED_PARAMETER[parameter]}return this._convertChannelToArray(channel).forEach(function(ch){this._selectRegisteredParameter(parameter,channel,options.time),this.sendControlChange(97,0,channel,{time:options.time}),this._deselectRegisteredParameter(channel,options.time)}.bind(this)),this},Output.prototype.setPitchBendRange=function(semitones,cents,channel,options){var that=this;if(options=options||{},semitones=parseInt(semitones)||0,!(semitones>=0&&127>=semitones))throw new RangeError("The semitones value must be between 0 and 127");if(cents=parseInt(cents)||0,!(cents>=0&&127>=cents))throw new RangeError("The cents value must be between 0 and 127");return this._convertChannelToArray(channel).forEach(function(ch){that.setRegisteredParameter("pitchbendrange",[semitones,cents],channel,{time:options.time})}),this},Output.prototype.setModulationRange=function(semitones,cents,channel,options){var that=this;if(options=options||{},semitones=parseInt(semitones)||0,!(semitones>=0&&127>=semitones))throw new RangeError("The semitones value must be between 0 and 127");if(cents=parseInt(cents)||0,!(cents>=0&&127>=cents))throw new RangeError("The cents value must be between 0 and 127");return this._convertChannelToArray(channel).forEach(function(ch){that.setRegisteredParameter("modulationrange",[semitones,cents],channel,{time:options.time})}),this},Output.prototype.setMasterTuning=function(value,channel,options){var that=this;if(options=options||{},value=parseFloat(value)||0,-65>=value||value>=64)throw new RangeError("The value must be a decimal number larger than -65 and smaller than 64.");var coarse=parseInt(value)+64,fine=value-parseInt(value);fine=Math.round((fine+1)/2*16383);var msb=fine>>7&127,lsb=127&fine;return this._convertChannelToArray(channel).forEach(function(ch){that.setRegisteredParameter("channelcoarsetuning",coarse,channel,{time:options.time}),that.setRegisteredParameter("channelfinetuning",[msb,lsb],channel,{time:options.time})}),this},Output.prototype.setTuningProgram=function(value,channel,options){var that=this;if(options=options||{},value=parseInt(value)||0,!(value>=0&&127>=value))throw new RangeError("The program value must be between 0 and 127");return this._convertChannelToArray(channel).forEach(function(ch){that.setRegisteredParameter("tuningprogram",value,channel,{time:options.time})}),this},Output.prototype.setTuningBank=function(value,channel,options){var that=this;if(options=options||{},value=parseInt(value)||0,!(value>=0&&127>=value))throw new RangeError("The bank value must be between 0 and 127");return this._convertChannelToArray(channel).forEach(function(ch){that.setRegisteredParameter("tuningbank",value,channel,{time:options.time})}),this},Output.prototype.sendChannelMode=function(command,value,channel,options){if(options=options||{},"string"==typeof command){if(command=wm.MIDI_CHANNEL_MODE_MESSAGES[command],!command)throw new TypeError("Invalid channel mode message name.")}else if(command=parseInt(command),!(command>=120&&127>=command))throw new RangeError("Channel mode numerical identifiers must be between 120 and 127.");if(value=parseInt(value)||0,0>value||value>127)throw new RangeError("Value must be an integer between 0 and 127.");return this._convertChannelToArray(channel).forEach(function(ch){this.send((wm.MIDI_CHANNEL_MESSAGES.channelmode<<4)+(ch-1),[command,value],this._parseTimeParameter(options.time))}.bind(this)),this},Output.prototype.sendProgramChange=function(program,channel,options){var that=this;if(options=options||{},program=parseInt(program),isNaN(program)||0>program||program>127)throw new RangeError("Program numbers must be between 0 and 127.");return this._convertChannelToArray(channel).forEach(function(ch){that.send((wm.MIDI_CHANNEL_MESSAGES.programchange<<4)+(ch-1),[program],that._parseTimeParameter(options.time))}),this},Output.prototype.sendChannelAftertouch=function(pressure,channel,options){var that=this;options=options||{},pressure=parseFloat(pressure),(isNaN(pressure)||0>pressure||pressure>1)&&(pressure=.5);var nPressure=Math.round(127*pressure);return this._convertChannelToArray(channel).forEach(function(ch){that.send((wm.MIDI_CHANNEL_MESSAGES.channelaftertouch<<4)+(ch-1),[nPressure],that._parseTimeParameter(options.time))}),this},Output.prototype.sendPitchBend=function(bend,channel,options){ +!function(scope){"use strict";function WebMidi(){if(WebMidi.prototype._singleton)throw new Error("WebMidi is a singleton, it cannot be instantiated directly.");WebMidi.prototype._singleton=this,this._inputs=[],this._outputs=[],this._userHandlers={},this._stateChangeQueue=[],this._processingStateChange=!1,this._midiInterfaceEvents=["connected","disconnected"],this._notes=["C","C#","D","D#","E","F","F#","G","G#","A","A#","B"],this._semitones={C:0,D:2,E:4,F:5,G:7,A:9,B:11},Object.defineProperties(this,{MIDI_SYSTEM_MESSAGES:{value:{sysex:240,timecode:241,songposition:242,songselect:243,tuningrequest:246,sysexend:247,clock:248,start:250,"continue":251,stop:252,activesensing:254,reset:255,unknownsystemmessage:-1},writable:!1,enumerable:!0,configurable:!1},MIDI_CHANNEL_MESSAGES:{value:{noteoff:8,noteon:9,keyaftertouch:10,controlchange:11,channelmode:11,programchange:12,channelaftertouch:13,pitchbend:14},writable:!1,enumerable:!0,configurable:!1},MIDI_REGISTERED_PARAMETER:{value:{pitchbendrange:[0,0],channelfinetuning:[0,1],channelcoarsetuning:[0,2],tuningprogram:[0,3],tuningbank:[0,4],modulationrange:[0,5],azimuthangle:[61,0],elevationangle:[61,1],gain:[61,2],distanceratio:[61,3],maximumdistance:[61,4],maximumdistancegain:[61,5],referencedistanceratio:[61,6],panspreadangle:[61,7],rollangle:[61,8]},writable:!1,enumerable:!0,configurable:!1},MIDI_CONTROL_CHANGE_MESSAGES:{value:{bankselectcoarse:0,modulationwheelcoarse:1,breathcontrollercoarse:2,footcontrollercoarse:4,portamentotimecoarse:5,dataentrycoarse:6,volumecoarse:7,balancecoarse:8,pancoarse:10,expressioncoarse:11,effectcontrol1coarse:12,effectcontrol2coarse:13,generalpurposeslider1:16,generalpurposeslider2:17,generalpurposeslider3:18,generalpurposeslider4:19,bankselectfine:32,modulationwheelfine:33,breathcontrollerfine:34,footcontrollerfine:36,portamentotimefine:37,dataentryfine:38,volumefine:39,balancefine:40,panfine:42,expressionfine:43,effectcontrol1fine:44,effectcontrol2fine:45,holdpedal:64,portamento:65,sustenutopedal:66,softpedal:67,legatopedal:68,hold2pedal:69,soundvariation:70,resonance:71,soundreleasetime:72,soundattacktime:73,brightness:74,soundcontrol6:75,soundcontrol7:76,soundcontrol8:77,soundcontrol9:78,soundcontrol10:79,generalpurposebutton1:80,generalpurposebutton2:81,generalpurposebutton3:82,generalpurposebutton4:83,reverblevel:91,tremololevel:92,choruslevel:93,celestelevel:94,phaserlevel:95,databuttonincrement:96,databuttondecrement:97,nonregisteredparametercoarse:98,nonregisteredparameterfine:99,registeredparametercoarse:100,registeredparameterfine:101},writable:!1,enumerable:!0,configurable:!1},MIDI_CHANNEL_MODE_MESSAGES:{value:{allsoundoff:120,resetallcontrollers:121,localcontrol:122,allnotesoff:123,omnimodeoff:124,omnimodeon:125,monomodeon:126,polymodeon:127},writable:!1,enumerable:!0,configurable:!1}}),Object.defineProperties(this,{supported:{enumerable:!0,get:function(){return"requestMIDIAccess"in navigator}},enabled:{enumerable:!0,get:function(){return void 0!==this["interface"]}.bind(this)},inputs:{enumerable:!0,get:function(){return this._inputs}.bind(this)},outputs:{enumerable:!0,get:function(){return this._outputs}.bind(this)},sysexEnabled:{enumerable:!0,get:function(){return!(!this["interface"]||!this["interface"].sysexEnabled)}.bind(this)},time:{enumerable:!0,get:function(){return performance.now()}}})}function Input(midiInput){var that=this;this._userHandlers={channel:{},system:{}},this._midiInput=midiInput,Object.defineProperties(this,{connection:{enumerable:!0,get:function(){return that._midiInput.connection}},id:{enumerable:!0,get:function(){return that._midiInput.id}},manufacturer:{enumerable:!0,get:function(){return that._midiInput.manufacturer}},name:{enumerable:!0,get:function(){return that._midiInput.name}},state:{enumerable:!0,get:function(){return that._midiInput.state}}}),this._initializeUserHandlers()}function Output(midiOutput){var that=this;this._midiOutput=midiOutput,Object.defineProperties(this,{connection:{enumerable:!0,get:function(){return that._midiOutput.connection}},id:{enumerable:!0,get:function(){return that._midiOutput.id}},manufacturer:{enumerable:!0,get:function(){return that._midiOutput.manufacturer}},name:{enumerable:!0,get:function(){return that._midiOutput.name}},state:{enumerable:!0,get:function(){return that._midiOutput.state}}})}var wm=new WebMidi;WebMidi.prototype.enable=function(callback,sysex){return this.enabled?void 0:this.supported?void navigator.requestMIDIAccess({sysex:sysex}).then(function(midiAccess){this["interface"]=midiAccess,this._resetInterfaceUserHandlers(),this["interface"].onstatechange=this._onInterfaceStateChange.bind(this),this._onInterfaceStateChange(null),"function"==typeof callback&&callback.call(this)}.bind(this),function(err){"function"==typeof callback&&callback.call(this,err)}.bind(this)):void("function"==typeof callback&&callback(new Error("The Web MIDI API is not supported by your browser.")))},WebMidi.prototype.disable=function(){if(!this.supported)throw new Error("The Web MIDI API is not supported by your browser.");this["interface"].onstatechange=void 0,this["interface"]=void 0,this._inputs=[],this._outputs=[],this._resetInterfaceUserHandlers()},WebMidi.prototype.addListener=function(type,listener){if(!this.enabled)throw new Error("WebMidi must be enabled before adding event listeners.");if("function"!=typeof listener)throw new TypeError("The 'listener' parameter must be a function.");if(!(this._midiInterfaceEvents.indexOf(type)>=0))throw new TypeError("The specified event type is not supported.");return this._userHandlers[type].push(listener),this},WebMidi.prototype.hasListener=function(type,listener){if(!this.enabled)throw new Error("WebMidi must be enabled before checking event listeners.");if("function"!=typeof listener)throw new TypeError("The 'listener' parameter must be a function.");if(!(this._midiInterfaceEvents.indexOf(type)>=0))throw new TypeError("The specified event type is not supported.");for(var o=0;o=0)if(listener)for(var o=0;o=0&&127>=number?Math.floor(parseInt(number)/12-1)-1:void 0},WebMidi.prototype.getOutputByName=function(name){if(!this.enabled)throw new Error("WebMidi is not enabled.");for(var i=0;i=0&&127>=input?output=Math.round(input):parseInt(input)>=0&&parseInt(input)<=127?output=parseInt(input):("string"==typeof input||input instanceof String)&&(output=this.noteNameToNumber(input)),output===!1)throw new Error("Invalid note number ("+input+").");return output},WebMidi.prototype.noteNameToNumber=function(name){"string"!=typeof name&&(name="");var matches=name.match(/([CDEFGAB])(#{0,2}|b{0,2})(-?\d+)/i);if(!matches)throw new RangeError("Invalid note name.");var semitones=wm._semitones[matches[1].toUpperCase()],octave=parseInt(matches[3]),result=12*(octave+2)+semitones;if(matches[2].toLowerCase().indexOf("b")>-1?result-=matches[2].length:matches[2].toLowerCase().indexOf("#")>-1&&(result+=matches[2].length),0>semitones||-2>octave||octave>8||0>result||result>127)throw new RangeError("Invalid note name or note outside valid range.");return result},WebMidi.prototype._updateInputsAndOutputs=function(){this._updateInputs(),this._updateOutputs()},WebMidi.prototype._updateInputs=function(){for(var i=0;i0;)this._processStateChange(this._stateChangeQueue.shift());this._processingStateChange=!1}},WebMidi.prototype._processStateChange=function(e){if(this._updateInputsAndOutputs(),null!==e){var event={timestamp:e.timeStamp,type:e.port.state,id:e.port.id,manufacturer:e.port.manufacturer,name:e.port.name};"connected"===e.port.state&&("output"===e.port.type?event.output=this.getOutputById(e.port.id):"input"===e.port.type&&(event.input=this.getInputById(e.port.id))),this._userHandlers[e.port.state].forEach(function(handler){handler(event)})}},WebMidi.prototype._resetInterfaceUserHandlers=function(){for(var i=0;i=1&&16>=item))throw new RangeError("The 'channel' parameter is invalid.")}),"function"!=typeof listener)throw new TypeError("The 'listener' parameter must be a function.");if(wm.MIDI_SYSTEM_MESSAGES[type])this._userHandlers.system[type]||(this._userHandlers.system[type]=[]),this._userHandlers.system[type].push(listener);else{if(!wm.MIDI_CHANNEL_MESSAGES[type])throw new TypeError("The specified event type is not supported.");if(channel.indexOf("all")>-1){channel=[];for(var j=1;16>=j;j++)channel.push(j)}this._userHandlers.channel[type]||(this._userHandlers.channel[type]=[]),channel.forEach(function(ch){that._userHandlers.channel[type][ch]||(that._userHandlers.channel[type][ch]=[]),that._userHandlers.channel[type][ch].push(listener)})}return this},Input.prototype.on=Input.prototype.addListener,Input.prototype.hasListener=function(type,channel,listener){var that=this;if("function"!=typeof listener)throw new TypeError("The 'listener' parameter must be a function.");if(void 0===channel&&(channel="all"),channel.constructor!==Array&&(channel=[channel]),wm.MIDI_SYSTEM_MESSAGES[type]){for(var o=0;o-1){channel=[];for(var j=1;16>=j;j++)channel.push(j)}return this._userHandlers.channel[type]?channel.every(function(chNum){var listeners=that._userHandlers.channel[type][chNum];return listeners&&listeners.indexOf(listener)>-1}):!1}return!1},Input.prototype.removeListener=function(type,channel,listener){var that=this;if(void 0!==listener&&"function"!=typeof listener)throw new TypeError("The 'listener' parameter must be a function.");if(void 0===channel&&(channel="all"),channel.constructor!==Array&&(channel=[channel]),wm.MIDI_SYSTEM_MESSAGES[type])if(void 0===listener)this._userHandlers.system[type]=[];else for(var o=0;o-1){channel=[];for(var j=1;16>=j;j++)channel.push(j)}if(!this._userHandlers.channel[type])return this;channel.forEach(function(chNum){var listeners=that._userHandlers.channel[type][chNum];if(listeners)if(void 0===listener)that._userHandlers.channel[type][chNum]=[];else for(var l=0;l>4,channel=(15&e.data[0])+1;e.data.length>1&&(data1=e.data[1],data2=e.data.length>2?e.data[2]:void 0);var event={target:this,data:e.data,timestamp:e.timeStamp,channel:channel};command===wm.MIDI_CHANNEL_MESSAGES.noteoff||command===wm.MIDI_CHANNEL_MESSAGES.noteon&&0===data2?(event.type="noteoff",event.note={number:data1,name:wm._notes[data1%12],octave:wm.getOctave(data1)},event.velocity=data2/127,event.rawVelocity=data2):command===wm.MIDI_CHANNEL_MESSAGES.noteon?(event.type="noteon",event.note={number:data1,name:wm._notes[data1%12],octave:wm.getOctave(data1)},event.velocity=data2/127,event.rawVelocity=data2):command===wm.MIDI_CHANNEL_MESSAGES.keyaftertouch?(event.type="keyaftertouch",event.note={number:data1,name:wm._notes[data1%12],octave:wm.getOctave(data1)},event.value=data2/127):command===wm.MIDI_CHANNEL_MESSAGES.controlchange&&data1>=0&&119>=data1?(event.type="controlchange",event.controller={number:data1,name:this.getCcNameByNumber(data1)},event.value=data2):command===wm.MIDI_CHANNEL_MESSAGES.channelmode&&data1>=120&&127>=data1?(event.type="channelmode",event.controller={number:data1,name:this.getChannelModeByNumber(data1)},event.value=data2):command===wm.MIDI_CHANNEL_MESSAGES.programchange?(event.type="programchange",event.value=data1):command===wm.MIDI_CHANNEL_MESSAGES.channelaftertouch?(event.type="channelaftertouch",event.value=data1/127):command===wm.MIDI_CHANNEL_MESSAGES.pitchbend?(event.type="pitchbend",event.value=((data2<<7)+data1-8192)/8192):event.type="unknownchannelmessage",this._userHandlers.channel[event.type]&&this._userHandlers.channel[event.type][channel]&&this._userHandlers.channel[event.type][channel].forEach(function(callback){callback(event)})},Input.prototype.getCcNameByNumber=function(number){if(number=parseInt(number),!(number>=0&&119>=number))throw new RangeError("The control change number must be between 0 and 119.");for(var cc in wm.MIDI_CONTROL_CHANGE_MESSAGES)if(number===wm.MIDI_CONTROL_CHANGE_MESSAGES[cc])return cc;return void 0},Input.prototype.getChannelModeByNumber=function(number){if(number=parseInt(number),!(number>=120&&status<=127))throw new RangeError("The control change number must be between 120 and 127.");for(var cm in wm.MIDI_CHANNEL_MODE_MESSAGES)if(number===wm.MIDI_CHANNEL_MODE_MESSAGES[cm])return cm},Input.prototype._parseSystemEvent=function(e){var command=e.data[0],event={target:this,data:e.data,timestamp:e.timeStamp};command===wm.MIDI_SYSTEM_MESSAGES.sysex?event.type="sysex":command===wm.MIDI_SYSTEM_MESSAGES.timecode?event.type="timecode":command===wm.MIDI_SYSTEM_MESSAGES.songposition?event.type="songposition":command===wm.MIDI_SYSTEM_MESSAGES.songselect?(event.type="songselect",event.song=e.data[1]):command===wm.MIDI_SYSTEM_MESSAGES.tuningrequest?event.type="tuningrequest":command===wm.MIDI_SYSTEM_MESSAGES.clock?event.type="clock":command===wm.MIDI_SYSTEM_MESSAGES.start?event.type="start":command===wm.MIDI_SYSTEM_MESSAGES["continue"]?event.type="continue":command===wm.MIDI_SYSTEM_MESSAGES.stop?event.type="stop":command===wm.MIDI_SYSTEM_MESSAGES.activesensing?event.type="activesensing":command===wm.MIDI_SYSTEM_MESSAGES.reset?event.type="reset":event.type="unknownsystemmessage",this._userHandlers.system[event.type]&&this._userHandlers.system[event.type].forEach(function(callback){callback(event)})},Output.prototype.send=function(status,data,timestamp){if(!(status>=128&&255>=status))throw new RangeError("The status byte must be an integer between 128 (0x80) and 255 (0xFF).");Array.isArray(data)||(data=parseInt(data)>=0&&parseInt(data)<=127?[parseInt(data)]:[]);var message=[status];return data.forEach(function(item){if(!(item>=0&&255>=item))throw new RangeError("The data bytes must be integers between 0 (0x00) and 255 (0xFF).");message.push(item)}),this._midiOutput.send(message,parseFloat(timestamp)||0),this},Output.prototype.sendSysex=function(manufacturer,data,options){if(!wm.sysexEnabled)throw new Error("SysEx message support must first be activated.");return options=options||{},manufacturer=[].concat(manufacturer),data.forEach(function(item){if(0>item||item>127)throw new RangeError("The data bytes of a SysEx message must be integers between 0 (0x00) and 127 (0x7F).")}),data=manufacturer.concat(data,wm.MIDI_SYSTEM_MESSAGES.sysexend),this.send(wm.MIDI_SYSTEM_MESSAGES.sysex,data,this._parseTimeParameter(options.time)),this},Output.prototype.sendTimecodeQuarterFrame=function(value,options){return options=options||{},this.send(wm.MIDI_SYSTEM_MESSAGES.timecode,value,this._parseTimeParameter(options.time)),this},Output.prototype.sendSongPosition=function(value,options){value=parseInt(value)||0,options=options||{};var msb=value>>7&127,lsb=127&value;return this.send(wm.MIDI_SYSTEM_MESSAGES.songposition,[msb,lsb],this._parseTimeParameter(options.time)),this},Output.prototype.sendSongSelect=function(value,options){if(value=parseInt(value),options=options||{},!(value>=0&&127>=value))throw new RangeError("The song number must be between 0 and 127.");return this.send(wm.MIDI_SYSTEM_MESSAGES.songselect,[value],this._parseTimeParameter(options.time)),this},Output.prototype.sendTuningRequest=function(options){return options=options||{},this.send(wm.MIDI_SYSTEM_MESSAGES.tuningrequest,void 0,this._parseTimeParameter(options.time)),this},Output.prototype.sendClock=function(options){return options=options||{},this.send(wm.MIDI_SYSTEM_MESSAGES.clock,void 0,this._parseTimeParameter(options.time)),this},Output.prototype.sendStart=function(options){return options=options||{},this.send(wm.MIDI_SYSTEM_MESSAGES.start,void 0,this._parseTimeParameter(options.time)),this},Output.prototype.sendContinue=function(options){return options=options||{},this.send(wm.MIDI_SYSTEM_MESSAGES["continue"],void 0,this._parseTimeParameter(options.time)),this},Output.prototype.sendStop=function(options){return options=options||{},this.send(wm.MIDI_SYSTEM_MESSAGES.stop,void 0,this._parseTimeParameter(options.time)),this},Output.prototype.sendActiveSensing=function(options){return options=options||{},this.send(wm.MIDI_SYSTEM_MESSAGES.activesensing,void 0,this._parseTimeParameter(options.time)),this},Output.prototype.sendReset=function(options){return options=options||{},this.send(wm.MIDI_SYSTEM_MESSAGES.reset,void 0,this._parseTimeParameter(options.time)),this},Output.prototype.stopNote=function(note,channel,options){if("all"===note)return this.sendChannelMode("allnotesoff",0,channel,options);var nVelocity=64;return options=options||{},options.velocity=parseFloat(options.velocity),options.rawVelocity?!isNaN(options.velocity)&&options.velocity>=0&&options.velocity<=127&&(nVelocity=options.velocity):!isNaN(options.velocity)&&options.velocity>=0&&options.velocity<=1&&(nVelocity=127*options.velocity),this._convertNoteToArray(note).forEach(function(item){this._convertChannelToArray(channel).forEach(function(ch){this.send((wm.MIDI_CHANNEL_MESSAGES.noteoff<<4)+(ch-1),[item,Math.round(nVelocity)],this._parseTimeParameter(options.time))}.bind(this))}.bind(this)),this},Output.prototype.playNote=function(note,channel,options){var nVelocity=64;if(options=options||{},options.velocity=parseFloat(options.velocity),options.rawVelocity?!isNaN(options.velocity)&&options.velocity>=0&&options.velocity<=127&&(nVelocity=options.velocity):!isNaN(options.velocity)&&options.velocity>=0&&options.velocity<=1&&(nVelocity=127*options.velocity),options.time=this._parseTimeParameter(options.time),this._convertNoteToArray(note).forEach(function(item){this._convertChannelToArray(channel).forEach(function(ch){this.send((wm.MIDI_CHANNEL_MESSAGES.noteon<<4)+(ch-1),[item,Math.round(nVelocity)],options.time)}.bind(this))}.bind(this)),options.duration=parseFloat(options.duration),options.duration){options.duration<=0&&(options.duration=0);var nRelease=64;options.release=parseFloat(options.release),options.rawVelocity?!isNaN(options.release)&&options.release>=0&&options.release<=127&&(nRelease=options.release):!isNaN(options.release)&&options.release>=0&&options.release<=1&&(nRelease=127*options.release),this._convertNoteToArray(note).forEach(function(item){this._convertChannelToArray(channel).forEach(function(ch){this.send((wm.MIDI_CHANNEL_MESSAGES.noteoff<<4)+(ch-1),[item,Math.round(nRelease)],(options.time||wm.time)+options.duration)}.bind(this))}.bind(this))}return this},Output.prototype.sendKeyAftertouch=function(note,channel,pressure,options){var that=this;if(options=options||{},1>channel||channel>16)throw new RangeError("The channel must be between 1 and 16.");pressure=parseFloat(pressure),(isNaN(pressure)||0>pressure||pressure>1)&&(pressure=.5);var nPressure=Math.round(127*pressure);return this._convertNoteToArray(note).forEach(function(item){that._convertChannelToArray(channel).forEach(function(ch){that.send((wm.MIDI_CHANNEL_MESSAGES.keyaftertouch<<4)+(ch-1),[item,nPressure],that._parseTimeParameter(options.time))})}),this},Output.prototype.sendControlChange=function(controller,value,channel,options){if(options=options||{},"string"==typeof controller){if(controller=wm.MIDI_CONTROL_CHANGE_MESSAGES[controller],!controller)throw new TypeError("Invalid controller name.")}else if(controller=parseInt(controller),!(controller>=0&&119>=controller))throw new RangeError("Controller numbers must be between 0 and 119.");if(value=parseInt(value)||0,!(value>=0&&127>=value))throw new RangeError("Controller value must be between 0 and 127.");return this._convertChannelToArray(channel).forEach(function(ch){this.send((wm.MIDI_CHANNEL_MESSAGES.controlchange<<4)+(ch-1),[controller,value],this._parseTimeParameter(options.time))}.bind(this)),this},Output.prototype._selectRegisteredParameter=function(parameter,channel,time){var that=this;if(parameter[0]=parseInt(parameter[0]),!(parameter[0]>=0&¶meter[0]<=127))throw new RangeError("The control65 value must be between 0 and 127");if(parameter[1]=parseInt(parameter[1]),!(parameter[1]>=0&¶meter[1]<=127))throw new RangeError("The control64 value must be between 0 and 127");return this._convertChannelToArray(channel).forEach(function(ch){that.sendControlChange(101,parameter[0],channel,{time:time}),that.sendControlChange(100,parameter[1],channel,{time:time})}),this},Output.prototype._selectNonRegisteredParameter=function(parameter,channel,time){var that=this;if(parameter[0]=parseInt(parameter[0]),!(parameter[0]>=0&¶meter[0]<=127))throw new RangeError("The control63 value must be between 0 and 127");if(parameter[1]=parseInt(parameter[1]),!(parameter[1]>=0&¶meter[1]<=127))throw new RangeError("The control62 value must be between 0 and 127");return this._convertChannelToArray(channel).forEach(function(ch){that.sendControlChange(99,parameter[0],channel,{time:time}),that.sendControlChange(98,parameter[1],channel,{time:time})}),this},Output.prototype._setCurrentRegisteredParameter=function(data,channel,time){var that=this;if(data=[].concat(data),data[0]=parseInt(data[0]),!(data[0]>=0&&data[0]<=127))throw new RangeError("The msb value must be between 0 and 127");return this._convertChannelToArray(channel).forEach(function(ch){that.sendControlChange(6,data[0],channel,{time:time})}),data[1]=parseInt(data[1]),data[1]>=0&&data[1]<=127&&this._convertChannelToArray(channel).forEach(function(ch){that.sendControlChange(38,data[1],channel,{time:time})}),this},Output.prototype._deselectRegisteredParameter=function(channel,time){var that=this;return this._convertChannelToArray(channel).forEach(function(ch){that.sendControlChange(101,127,channel,{time:time}),that.sendControlChange(100,127,channel,{time:time})}),this},Output.prototype.setRegisteredParameter=function(parameter,data,channel,options){var that=this;if(options=options||{},!Array.isArray(parameter)){if(!wm.MIDI_REGISTERED_PARAMETER[parameter])throw new Error("The specified parameter is not available.");parameter=wm.MIDI_REGISTERED_PARAMETER[parameter]}return this._convertChannelToArray(channel).forEach(function(ch){that._selectRegisteredParameter(parameter,channel,options.time),that._setCurrentRegisteredParameter(data,channel,options.time),that._deselectRegisteredParameter(channel,options.time)}),this},Output.prototype.setNonRegisteredParameter=function(parameter,data,channel,options){var that=this;if(options=options||{},!(parameter[0]>=0&¶meter[0]<=127&¶meter[1]>=0&¶meter[1]<=127))throw new Error("Position 0 and 1 of the 2-position parameter array must both be between 0 and 127.");return data=[].concat(data),this._convertChannelToArray(channel).forEach(function(ch){that._selectNonRegisteredParameter(parameter,channel,options.time),that._setCurrentRegisteredParameter(data,channel,options.time),that._deselectRegisteredParameter(channel,options.time)}),this},Output.prototype.incrementRegisteredParameter=function(parameter,channel,options){var that=this;if(options=options||{},!Array.isArray(parameter)){if(!wm.MIDI_REGISTERED_PARAMETER[parameter])throw new Error("The specified parameter is not available.");parameter=wm.MIDI_REGISTERED_PARAMETER[parameter]}return this._convertChannelToArray(channel).forEach(function(ch){that._selectRegisteredParameter(parameter,channel,options.time),that.sendControlChange(96,0,channel,{time:options.time}),that._deselectRegisteredParameter(channel,options.time)}),this},Output.prototype.decrementRegisteredParameter=function(parameter,channel,options){if(options=options||{},!Array.isArray(parameter)){if(!wm.MIDI_REGISTERED_PARAMETER[parameter])throw new TypeError("The specified parameter is not available.");parameter=wm.MIDI_REGISTERED_PARAMETER[parameter]}return this._convertChannelToArray(channel).forEach(function(ch){this._selectRegisteredParameter(parameter,channel,options.time),this.sendControlChange(97,0,channel,{time:options.time}),this._deselectRegisteredParameter(channel,options.time)}.bind(this)),this},Output.prototype.setPitchBendRange=function(semitones,cents,channel,options){var that=this;if(options=options||{},semitones=parseInt(semitones)||0,!(semitones>=0&&127>=semitones))throw new RangeError("The semitones value must be between 0 and 127");if(cents=parseInt(cents)||0,!(cents>=0&&127>=cents))throw new RangeError("The cents value must be between 0 and 127");return this._convertChannelToArray(channel).forEach(function(ch){that.setRegisteredParameter("pitchbendrange",[semitones,cents],channel,{time:options.time})}),this},Output.prototype.setModulationRange=function(semitones,cents,channel,options){var that=this;if(options=options||{},semitones=parseInt(semitones)||0,!(semitones>=0&&127>=semitones))throw new RangeError("The semitones value must be between 0 and 127");if(cents=parseInt(cents)||0,!(cents>=0&&127>=cents))throw new RangeError("The cents value must be between 0 and 127");return this._convertChannelToArray(channel).forEach(function(ch){that.setRegisteredParameter("modulationrange",[semitones,cents],channel,{time:options.time})}),this},Output.prototype.setMasterTuning=function(value,channel,options){var that=this;if(options=options||{},value=parseFloat(value)||0,-65>=value||value>=64)throw new RangeError("The value must be a decimal number larger than -65 and smaller than 64.");var coarse=parseInt(value)+64,fine=value-parseInt(value);fine=Math.round((fine+1)/2*16383);var msb=fine>>7&127,lsb=127&fine;return this._convertChannelToArray(channel).forEach(function(ch){that.setRegisteredParameter("channelcoarsetuning",coarse,channel,{time:options.time}),that.setRegisteredParameter("channelfinetuning",[msb,lsb],channel,{time:options.time})}),this},Output.prototype.setTuningProgram=function(value,channel,options){var that=this;if(options=options||{},value=parseInt(value)||0,!(value>=0&&127>=value))throw new RangeError("The program value must be between 0 and 127");return this._convertChannelToArray(channel).forEach(function(ch){that.setRegisteredParameter("tuningprogram",value,channel,{time:options.time})}),this},Output.prototype.setTuningBank=function(value,channel,options){var that=this;if(options=options||{},value=parseInt(value)||0,!(value>=0&&127>=value))throw new RangeError("The bank value must be between 0 and 127");return this._convertChannelToArray(channel).forEach(function(ch){that.setRegisteredParameter("tuningbank",value,channel,{time:options.time})}),this},Output.prototype.sendChannelMode=function(command,value,channel,options){if(options=options||{},"string"==typeof command){if(command=wm.MIDI_CHANNEL_MODE_MESSAGES[command],!command)throw new TypeError("Invalid channel mode message name.")}else if(command=parseInt(command),!(command>=120&&127>=command))throw new RangeError("Channel mode numerical identifiers must be between 120 and 127.");if(value=parseInt(value)||0,0>value||value>127)throw new RangeError("Value must be an integer between 0 and 127.");return this._convertChannelToArray(channel).forEach(function(ch){this.send((wm.MIDI_CHANNEL_MESSAGES.channelmode<<4)+(ch-1),[command,value],this._parseTimeParameter(options.time))}.bind(this)),this},Output.prototype.sendProgramChange=function(program,channel,options){var that=this;if(options=options||{},program=parseInt(program),isNaN(program)||0>program||program>127)throw new RangeError("Program numbers must be between 0 and 127.");return this._convertChannelToArray(channel).forEach(function(ch){that.send((wm.MIDI_CHANNEL_MESSAGES.programchange<<4)+(ch-1),[program],that._parseTimeParameter(options.time))}),this},Output.prototype.sendChannelAftertouch=function(pressure,channel,options){var that=this;options=options||{},pressure=parseFloat(pressure),(isNaN(pressure)||0>pressure||pressure>1)&&(pressure=.5);var nPressure=Math.round(127*pressure);return this._convertChannelToArray(channel).forEach(function(ch){that.send((wm.MIDI_CHANNEL_MESSAGES.channelaftertouch<<4)+(ch-1),[nPressure],that._parseTimeParameter(options.time))}),this},Output.prototype.sendPitchBend=function(bend,channel,options){ var that=this;if(options=options||{},bend=parseFloat(bend),isNaN(bend)||-1>bend||bend>1)throw new RangeError("Pitch bend value must be between -1 and 1.");var nLevel=Math.round((bend+1)/2*16383),msb=nLevel>>7&127,lsb=127&nLevel;return this._convertChannelToArray(channel).forEach(function(ch){that.send((wm.MIDI_CHANNEL_MESSAGES.pitchbend<<4)+(ch-1),[lsb,msb],that._parseTimeParameter(options.time))}),this},Output.prototype._parseTimeParameter=function(time){var parsed,value;return"string"==typeof time&&"+"===time.substring(0,1)?(parsed=parseFloat(time),parsed&&parsed>0&&(value=wm.time+parsed)):(parsed=parseFloat(time),parsed>wm.time&&(value=parsed)),value},Output.prototype._convertNoteToArray=function(note){var notes=[];return Array.isArray(note)||(note=[note]),note.forEach(function(item){notes.push(wm.guessNoteNumber(item))}),notes},Output.prototype._convertChannelToArray=function(channel){if(("all"===channel||void 0===channel)&&(channel=["all"]),Array.isArray(channel)||(channel=[channel]),channel.indexOf("all")>-1){channel=[];for(var i=1;16>=i;i++)channel.push(i)}return channel.forEach(function(ch){if(!(ch>=1&&16>=ch))throw new RangeError("MIDI channels must be between 1 and 16.")}),channel},Output.prototype._onMidiMessage=function(e){},"function"==typeof define&&"object"==typeof define.amd?define([],function(){return wm}):"undefined"!=typeof module&&module.exports?module.exports=wm:scope.WebMidi||(scope.WebMidi=wm)}(this); \ No newline at end of file