1
0
Fork 0
mirror of https://github.com/noerw/leaflet-playback synced 2025-03-13 19:30:27 +01:00
leaflet-playback/examples/lib/webmidi.min.js
noerw 11ebcaea06 update readme & change file structure
readme contains now api docs
2016-04-20 01:46:24 +02:00

30 lines
No EOL
19 KiB
JavaScript

/*
WebMidi v1.0.0-beta.13
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
The MIT License (MIT)
Copyright (c) 2015, Jean-Philippe Côté
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
associated documentation files (the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge, publish, distribute,
sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial
portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES
OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
!function(a){"use strict";function b(){Object.defineProperties(this,{supported:{enumerable:!0,get:function(){return"requestMIDIAccess"in navigator}},connected:{enumerable:!0,get:function(){return void 0!==this["interface"]}},inputs:{enumerable:!0,get:function(){var a=[];if(this.connected)for(var b=this["interface"].inputs.values(),c=b.next();c&&!c.done;c=b.next())a.push(c.value);return a}},outputs:{enumerable:!0,get:function(){var a=[];if(this.connected)for(var b=this["interface"].outputs.values(),c=b.next();c&&!c.done;c=b.next())a.push(c.value);return a}},sysexEnabled:{enumerable:!0,get:function(){return this["interface"]&&this["interface"].sysexEnabled}},time:{enumerable:!0,get:function(){return window.performance.now()}}}),c()}function c(){h.system.statechange=[];for(var a in i)i.hasOwnProperty(a)&&(h.channel[a]={});for(var b in j)j.hasOwnProperty(b)&&(h.system[b]=[])}function d(a){h.system.statechange.forEach(function(b){b(a)})}function e(a){var b,c,d=a.data[0]>>4,e=(15&a.data[0])+1;a.data.length>1&&(b=a.data[1],c=a.data.length>2?a.data[2]:void 0);var f={device:a.currentTarget,data:a.data,receivedTime:a.receivedTime,timeStamp:a.timeStamp,channel:e};d===i.noteoff||d===i.noteon&&0===c?(f.type="noteoff",f.note={number:b,name:k[b%12],octave:Math.floor(b/12-1)-3},f.velocity=c/127):d===i.noteon?(f.type="noteon",f.note={number:b,name:k[b%12],octave:Math.floor(b/12-1)-3},f.velocity=c/127):d===i.keyaftertouch?(f.type="keyaftertouch",f.note={number:b,name:k[b%12],octave:Math.floor(b/12-1)-3},f.value=c/127):d===i.controlchange&&b>=0&&119>=b?(f.type="controlchange",f.controller={number:b,name:""},f.value=c):d===i.channelmode&&b>=120&&127>=b?(f.type="channelmode",f.controller={number:b,name:""},f.value=c):d===i.programchange?(f.type="programchange",f.value=b):d===i.channelaftertouch?(f.type="channelaftertouch",f.value=b/127):d===i.pitchbend?(f.type="pitchbend",f.value=((c<<7)+b-8192)/8192):f.type="unknownchannelmessage",h.channel[f.type][f.device.id]&&h.channel[f.type][f.device.id][e]&&h.channel[f.type][f.device.id][e].forEach(function(a){a(f)})}function f(a){var b=a.data[0],c={device:a.currentTarget,data:a.data,receivedTime:a.receivedTime,timeStamp:a.timeStamp};b===j.sysex?c.type="sysex":b===j.timecode?c.type="timecode":b===j.songposition?c.type="songposition":b===j.songselect?(c.type="songselect",c.song=a.data[1]):b===j.tuningrequest?c.type="tuningrequest":b===j.clock?c.type="clock":b===j.start?c.type="start":b===j["continue"]?c.type="continue":b===j.stop?c.type="stop":b===j.activesensing?c.type="activesensing":b===j.reset?c.type="reset":c.type="unknownsystemmessage",h.system[c.type]&&h.system[c.type].forEach(function(a){a(c)})}function g(a){a.data[0]<240?e(a):a.data[0]<=255&&f(a)}var h={channel:{},system:{}},i={noteoff:8,noteon:9,keyaftertouch:10,controlchange:11,channelmode:11,programchange:12,channelaftertouch:13,pitchbend:14},j={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},k=["C","C#","D","D#","E","F","F#","G","G#","A","A#","B"],l={C:0,D:2,E:4,F:5,G:7,A:9,B:11},m={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]};b.prototype.enable=function(a,b,c){var e=this;if(a&&"function"!=typeof a||b&&"function"!=typeof b)throw new TypeError("The success and error handlers must be functions.");return!this.supported&&b?void b("The Web MIDI API is not supported by your browser."):void navigator.requestMIDIAccess({sysex:c}).then(function(b){e["interface"]=b,e["interface"].onstatechange=d,e.inputs.forEach(function(a){a.onmidimessage=g}),a&&a()},b)},b.prototype.addListener=function(a,b,c){if(!this.connected)throw new Error("WebMidi must be connected before adding event listeners.");if(c=c||{},void 0===c.channel&&(c.channel="all"),c.channel.constructor!==Array&&(c.channel=[c.channel]),c.input=c.input||this.inputs,c.input.constructor!==Array&&(c.input=[c.input]),c.input.forEach(function(a){if(!(a instanceof MIDIInput))throw new ReferenceError("There is no such input device.")}),c.channel.forEach(function(a){if("all"!==a&&!(a>=1&&16>=a))throw new RangeError("The channel must be an integer between 1 and 16 or the value 'all'.")}),"function"!=typeof b)throw new TypeError("The 'listener' parameter must be a function.");if("statechange"===a||j[a])h.system[a].push(b);else{if(!i[a])throw new TypeError("The specified event type is not supported.");if(c.channel.indexOf("all")>-1){c.channel=[];for(var d=1;16>=d;d++)c.channel.push(d)}h.channel[a]||(h.channel[a]=[]),c.input.forEach(function(d){h.channel[a][d.id]||(h.channel[a][d.id]=[]),c.channel.forEach(function(c){h.channel[a][d.id][c]||(h.channel[a][d.id][c]=[]),h.channel[a][d.id][c].push(b)})})}return this},b.prototype.getDeviceById=function(a,b){for(var c="output"===b?this.outputs:this.inputs,d=0;d<c.length;d++)if(c[d].id===a)return c[d];return!1},b.prototype.getDeviceIndexById=function(a,b){for(var c="output"===b?this.outputs:this.inputs,d=0;d<c.length;d++)if(c[d].id===a)return d;return!1},b.prototype.hasListener=function(a,b,c){if(!this.connected)throw new Error("WebMidi must be connected before checking event listeners.");if("function"!=typeof b)throw new TypeError("The 'listener' parameter must be a function.");if(c=c||{},c.input=c.input||this.inputs,c.input.constructor!==Array&&(c.input=[c.input]),void 0===c.channel&&(c.channel="all"),c.channel.constructor!==Array&&(c.channel=[c.channel]),"statechange"===a||j[a]){for(var d=0;d<h.system[a].length;d++)if(h.system[a][d]===b)return!0}else if(i[a]){if(c.channel.indexOf("all")>-1){c.channel=[];for(var e=1;16>=e;e++)c.channel.push(e)}return h.channel[a]?c.input.every(function(d){return h.channel[a][d.id]?c.channel.every(function(c){var e=h.channel[a][d.id][c];return e&&e.indexOf(b)>-1}):!1}):!1}return!1},b.prototype.removeListener=function(a,b,c){if(!this.connected)throw new Error("WebMidi must be connected before removing event listeners.");if(c=c||{},c.input=c.input||this.inputs,c.input.constructor!==Array&&(c.input=[c.input]),void 0===c.channel&&(c.channel="all"),c.channel.constructor!==Array&&(c.channel=[c.channel]),"statechange"===a||j[a])for(var d=0;d<h.system[a].length;d++)h.system[a][d]===b&&h.system[a].splice(d,1);else if(i[a]){if(c.channel.indexOf("all")>-1){c.channel=[];for(var e=1;16>=e;e++)c.channel.push(e)}if(!h.channel[a])return!1;c.input.forEach(function(d){h.channel[a][d.id]&&c.channel.forEach(function(c){var e=h.channel[a][d.id][c];if(e)for(var f=0;f<e.length;f++)e[f]===b&&e.splice(f,1)})})}return this},b.prototype.send=function(a,b,c,d){if(!this.connected)throw new Error("WebMidi must be connected before sending messages.");if(!(a>=128&&255>=a))throw new RangeError("The status byte must be an integer between 128 (0x80) and 255 (0xFF).");Array.isArray(b)||(b=parseInt(b)>=0&&parseInt(b)<=127?[parseInt(b)]:[]),c=c||this.outputs,c.constructor!==Array&&(c=[c]),c.forEach(function(a){if(!(a instanceof MIDIOutput))throw new ReferenceError("There is no such output device.")});var e=[a];return b.forEach(function(a){if(!(a>=0&&255>=a))throw new RangeError("The data bytes must be integers between 0 (0x00) and 255 (0xFF).");e.push(a)}),c.forEach(function(a){a.send(e,parseFloat(d)||0)}),this},b.prototype.sendSysex=function(a,b,c,d){if(!this.sysexEnabled)throw new Error("SysEx message support must first be activated.");return a=[].concat(a),b.forEach(function(a){if(0>a||a>127)throw new RangeError("The data bytes of a SysEx message must be integers between 0 (0x00) and 127 (0x7F).")}),b=a.concat(b,j.sysexend),this.send(j.sysex,b,c,d),this},b.prototype.sendTimecodeQuarterFrame=function(a,b,c){return this.send(j.timecode,a,b,c),this},b.prototype.sendSongPosition=function(a,b,c){a=parseInt(a)||0;var d=a>>7&127,e=127&a;return this.send(j.songposition,[d,e],b,c),this},b.prototype.sendSongSelect=function(a,b,c){if(a=parseInt(a),!(a>=0&&127>=a))throw new RangeError("The song number must be between 0 and 127.");return this.send(j.songselect,[a],b,c),this},b.prototype.sendTuningRequest=function(a,b){return this.send(j.tuningrequest,void 0,a,b),this},b.prototype.sendClock=function(a,b){return this.send(j.clock,void 0,a,b),this},b.prototype.sendStart=function(a,b){return this.send(j.start,void 0,a,b),this},b.prototype.sendContinue=function(a,b){return this.send(j["continue"],void 0,a,b),this},b.prototype.sendStop=function(a,b){return this.send(j.stop,void 0,a,b),this},b.prototype.sendActiveSensing=function(a,b){return this.send(j.activesensing,void 0,a,b),this},b.prototype.sendReset=function(a,b){return this.send(j.reset,void 0,a,b),this},b.prototype.stopNote=function(a,b,c,d,e){var f=this;b=parseFloat(b),(isNaN(b)||0>b||b>1)&&(b=.5);var g=Math.round(127*b);return this._convertNoteToArray(a).forEach(function(a){f._convertChannelToArray(d).forEach(function(b){f.send((i.noteoff<<4)+(b-1),[a,g],c,f._parseTimeParameter(e))})}),this},b.prototype.playNote=function(a,b,c,d,e,f){var g=this;b=parseFloat(b),(isNaN(b)||0>b||b>1)&&(b=.5);var h=Math.round(127*b);return f=g._parseTimeParameter(f)||0,this._convertNoteToArray(a).forEach(function(a){g._convertChannelToArray(e).forEach(function(b){g.send((i.noteon<<4)+(b-1),[a,h],d,f)})}),void 0!==c&&this._convertNoteToArray(a).forEach(function(a){g._convertChannelToArray(e).forEach(function(b){g.send((i.noteoff<<4)+(b-1),[a,64],d,f+c)})}),this},b.prototype.sendKeyAftertouch=function(a,b,c,d,e){var f=this;if(1>d||d>16)throw new RangeError("The channel must be between 1 and 16.");b=parseFloat(b),(isNaN(b)||0>b||b>1)&&(b=.5);var g=Math.round(127*b);return this._convertNoteToArray(a).forEach(function(a){f._convertChannelToArray(d).forEach(function(b){f.send((i.keyaftertouch<<4)+(b-1),[a,g],c,f._parseTimeParameter(e))})}),this},b.prototype.sendControlChange=function(a,b,c,d,e){var f=this;if(a=parseInt(a),!(a>=0&&119>=a))throw new RangeError("Controller numbers must be between 0 and 119.");if(b=parseInt(b)||0,!(b>=0&&127>=b))throw new RangeError("Controller value must be between 0 and 127.");return this._convertChannelToArray(d).forEach(function(d){f.send((i.controlchange<<4)+(d-1),[a,b],c,f._parseTimeParameter(e))}),this},b.prototype._selectRegisteredParameter=function(a,b,c,d){var e=this;if(a[0]=parseInt(a[0]),!(a[0]>=0&&a[0]<=127))throw new RangeError("The control65 value must be between 0 and 127");if(a[1]=parseInt(a[1]),!(a[1]>=0&&a[1]<=127))throw new RangeError("The control64 value must be between 0 and 127");return this._convertChannelToArray(c).forEach(function(f){e.sendControlChange(101,a[0],b,c,d),e.sendControlChange(100,a[1],b,c,d)}),this},b.prototype._selectNonRegisteredParameter=function(a,b,c,d){var e=this;if(a[0]=parseInt(a[0]),!(a[0]>=0&&a[0]<=127))throw new RangeError("The control63 value must be between 0 and 127");if(a[1]=parseInt(a[1]),!(a[1]>=0&&a[1]<=127))throw new RangeError("The control62 value must be between 0 and 127");return this._convertChannelToArray(c).forEach(function(f){e.sendControlChange(99,a[0],b,c,d),e.sendControlChange(98,a[1],b,c,d)}),this},b.prototype._setCurrentRegisteredParameter=function(a,b,c,d){var e=this;if(a=[].concat(a),a[0]=parseInt(a[0]),!(a[0]>=0&&a[0]<=127))throw new RangeError("The msb value must be between 0 and 127");return this._convertChannelToArray(c).forEach(function(f){e.sendControlChange(6,a[0],b,c,d)}),a[1]=parseInt(a[1]),a[1]>=0&&a[1]<=127&&this._convertChannelToArray(c).forEach(function(f){e.sendControlChange(38,a[1],b,c,d)}),this},b.prototype._deselectRegisteredParameter=function(a,b,c){var d=this;return this._convertChannelToArray(b).forEach(function(e){d.sendControlChange(101,127,a,b,c),d.sendControlChange(100,127,a,b,c)}),this},b.prototype.setRegisteredParameter=function(a,b,c,d,e){var f=this;if(!Array.isArray(a)){if(!m[a])throw new Error("The specified parameter is not available.");a=m[a]}return this._convertChannelToArray(d).forEach(function(g){f._selectRegisteredParameter(a,c,d,e),f._setCurrentRegisteredParameter(b,c,d,e),f._deselectRegisteredParameter(c,d,e)}),this},b.prototype.setNonRegisteredParameter=function(a,b,c,d,e){var f=this;if(!(a[0]>=0&&a[0]<=127&&a[1]>=0&&a[1]<=127))throw new Error("Position 0 and 1 of the 2-position parameter array must both be between 0 and 127.");return b=[].concat(b),this._convertChannelToArray(d).forEach(function(g){f._selectNonRegisteredParameter(a,c,d,e),f._setCurrentRegisteredParameter(b,c,d,e),f._deselectRegisteredParameter(c,d,e)}),this},b.prototype.incrementRegisteredParameter=function(a,b,c,d){var e=this;if(!Array.isArray(a)){if(!m[a])throw new Error("The specified parameter is not available.");a=m[a]}return this._convertChannelToArray(c).forEach(function(f){e._selectRegisteredParameter(a,b,c,d),e.sendControlChange(96,0,b,c,d),e._deselectRegisteredParameter(b,c,d)}),this},b.prototype.decrementRegisteredParameter=function(a,b,c,d){var e=this;if(!Array.isArray(a)){if(!m[a])throw new Error("The specified parameter is not available.");a=m[a]}return this._convertChannelToArray(c).forEach(function(f){e._selectRegisteredParameter(a,b,c,d),e.sendControlChange(97,0,b,c,d),e._deselectRegisteredParameter(b,c,d)}),this},b.prototype.setPitchBendRange=function(a,b,c,d,e){var f=this;if(a=parseInt(a)||0,!(a>=0&&127>=a))throw new RangeError("The semitones value must be between 0 and 127");if(b=parseInt(b)||0,!(b>=0&&127>=b))throw new RangeError("The cents value must be between 0 and 127");return this._convertChannelToArray(d).forEach(function(g){f.setRegisteredParameter("pitchbendrange",[a,b],c,d,e)}),this},b.prototype.setModulationRange=function(a,b,c,d,e){var f=this;if(a=parseInt(a)||0,!(a>=0&&127>=a))throw new RangeError("The semitones value must be between 0 and 127");if(b=parseInt(b)||0,!(b>=0&&127>=b))throw new RangeError("The cents value must be between 0 and 127");return this._convertChannelToArray(d).forEach(function(g){f.setRegisteredParameter("modulationrange",[a,b],c,d,e)}),this},b.prototype.setMasterTuning=function(a,b,c,d){var e=this;if(a=parseFloat(a)||0,-65>=a||a>=64)throw new RangeError("The value must be a decimal number larger than -65 and smaller than 64.");var f=parseInt(a)+64,g=a-parseInt(a);g=Math.round((g+1)/2*16383);var h=g>>7&127,i=127&g;return this._convertChannelToArray(c).forEach(function(a){e.setRegisteredParameter("channelcoarsetuning",f,b,c,d),e.setRegisteredParameter("channelfinetuning",[h,i],b,c,d)}),this},b.prototype.setTuningProgram=function(a,b,c,d){var e=this;if(a=parseInt(a)||0,!(a>=0&&127>=a))throw new RangeError("The program value must be between 0 and 127");return this._convertChannelToArray(c).forEach(function(f){e.setRegisteredParameter("tuningprogram",a,b,c,d)}),this},b.prototype.setTuningBank=function(a,b,c,d){var e=this;if(a=parseInt(a)||0,!(a>=0&&127>=a))throw new RangeError("The bank value must be between 0 and 127");return this._convertChannelToArray(c).forEach(function(f){e.setRegisteredParameter("tuningbank",a,b,c,d)}),this},b.prototype.sendChannelMode=function(a,b,c,d,e){var f=this;if(a=parseInt(a),isNaN(a)||120>a||a>127)throw new RangeError("Channel mode commands must be between 120 and 127.");if(b=parseInt(b),isNaN(b)||0>b||b>127)throw new RangeError("Value must be integers between 0 and 127.");return this._convertChannelToArray(d).forEach(function(d){f.send((i.channelmode<<4)+(d-1),[a,b],c,f._parseTimeParameter(e))}),this},b.prototype.sendProgramChange=function(a,b,c,d){var e=this;if(a=parseInt(a),isNaN(a)||0>a||a>127)throw new RangeError("Program numbers must be between 0 and 127.");return this._convertChannelToArray(c).forEach(function(c){e.send((i.programchange<<4)+(c-1),[a],b,e._parseTimeParameter(d))}),this},b.prototype.sendChannelAftertouch=function(a,b,c,d){var e=this;a=parseFloat(a),(isNaN(a)||0>a||a>1)&&(a=.5);var f=Math.round(127*a);return this._convertChannelToArray(c).forEach(function(a){e.send((i.channelaftertouch<<4)+(a-1),[f],b,e._parseTimeParameter(d))}),this},b.prototype.sendPitchBend=function(a,b,c,d){var e=this;if(a=parseFloat(a),isNaN(a)||-1>a||a>1)throw new RangeError("Pitch bend value must be between -1 and 1.");var f=Math.round((a+1)/2*16383),g=f>>7&127,h=127&f;return this._convertChannelToArray(c).forEach(function(a){e.send((i.pitchbend<<4)+(a-1),[h,g],b,e._parseTimeParameter(d))}),this},b.prototype.guessNoteNumber=function(a){var b=!1;if(a&&a.toFixed&&a>=0&&127>=a?b=a:parseInt(a)>=0&&parseInt(a)<=127?b=parseInt(a):("string"==typeof a||a instanceof String)&&(b=this.noteNameToNumber(a)),b===!1)throw new Error("Invalid note number ("+a+").");return b},b.prototype.noteNameToNumber=function(a){var b=a.match(/([CDEFGAB])(#{0,2}|b{0,2})(-?\d+)/i);if(!b)throw new RangeError("Invalid note name.");var c=l[b[1].toUpperCase()],d=parseInt(b[3]),e=12*(d+2)+c;if(b[2].toLowerCase().indexOf("b")>-1?e-=b[2].length:b[2].toLowerCase().indexOf("#")>-1&&(e+=b[2].length),0>c||-2>d||d>8||0>e||e>127)throw new RangeError("Invalid note name or note outside valid range.");return e},b.prototype._convertNoteToArray=function(a){var b=this,c=[];return Array.isArray(a)||(a=[a]),a.forEach(function(a){c.push(b.guessNoteNumber(a))}),c},b.prototype._convertChannelToArray=function(a){if(("all"===a||void 0===a)&&(a=["all"]),Array.isArray(a)||(a=[a]),a.indexOf("all")>-1){a=[];for(var b=1;16>=b;b++)a.push(b)}return a.forEach(function(a){if(!(a>=1&&16>=a))throw new RangeError("MIDI channels must be between 1 and 16.")}),a},b.prototype._parseTimeParameter=function(a){return a&&a.substring&&"+"===a.substring(0,1)?parseFloat(a)+this.time||void 0:parseFloat(a)||void 0},"function"==typeof define&&"object"==typeof define.amd?define([],function(){return new b}):"undefined"!=typeof module&&module.exports?module.exports=b:a.WebMidi||(a.WebMidi=new b)}(this);