├── .gitignore
├── js
├── main.js
├── midi-utils.js
├── midi-logger.js
└── WebMIDIAPI.js
├── readme.md
├── styles.css
└── index.html
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
--------------------------------------------------------------------------------
/js/main.js:
--------------------------------------------------------------------------------
1 | var midiLogger = new MidiLogger();
2 | window.addEventListener('load', midiLogger.init);
--------------------------------------------------------------------------------
/readme.md:
--------------------------------------------------------------------------------
1 | #Midi Logger
2 |
3 | Midi logger is a Web Midi tool that simply logs incoming signals to a table. There are a few options to customise how the signals appear. A short and simple little app. To run it on your own system, clone the repo or download the zip file, then simply open the `index.html` file in your browser.
4 |
5 | ###To Do List
6 | * Add a cookie system to remember settings
--------------------------------------------------------------------------------
/js/midi-utils.js:
--------------------------------------------------------------------------------
1 | // Based on Midi Utils Library
2 | // https://github.com/sole/MIDIUtils/blob/master/src/MIDIUtils.js
3 |
4 | var MIDIUtils = {
5 |
6 | noteMap: {},
7 | noteNumberMap: [],
8 | notes: [ "C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B" ],
9 |
10 | init: function(){
11 |
12 | for (var i = 0; i < 127; i++) {
13 |
14 | var index = i,
15 | key = this.notes[index % 12],
16 | octave = ((index / 12) | 0) - 1; // MIDI scale starts at octave = -1
17 |
18 | if(key.length === 1) {
19 | key = key;
20 | }
21 |
22 | key += octave;
23 |
24 | this.noteMap[key] = i;
25 | this.noteNumberMap[i] = key;
26 | }
27 | },
28 |
29 | getBaseLog: function(value, base) {
30 | return Math.log(value) / Math.log(base);
31 | },
32 |
33 | frequencyFromNoteNumber: function(note) {
34 | return 440 * Math.pow(2,(note-57)/12);
35 | },
36 |
37 | noteNumberToName: function(note) {
38 |
39 | return this.noteNumberMap[note];
40 | },
41 |
42 | frequencyToNoteNumber: function(f) {
43 | return Math.round(12.0 * this.getBaseLog(f / 440.0, 2) + 69);
44 | }
45 |
46 | };
47 |
48 | MIDIUtils.init();
--------------------------------------------------------------------------------
/styles.css:
--------------------------------------------------------------------------------
1 | @import url(http://fonts.googleapis.com/css?family=Karla:400,700);
2 | body {
3 | font-family:Karla, sans-serif;
4 | }
5 |
6 | .warning {
7 | color:#F60;
8 | }
9 |
10 | h2 {
11 | font-size: 14px;
12 | margin-bottom: 5px;
13 | }
14 |
15 | table {
16 | border-collapse: collapse;
17 | margin: 0 auto;
18 | }
19 |
20 | th, td{
21 | border:1px solid #ccc;
22 | padding:10px;
23 | text-align:center;
24 | background:#f8f8f8;
25 | }
26 |
27 | .midi-logger-page label {
28 | font-size: 13px;
29 | }
30 |
31 | .midi-log-table {
32 | border-collapse:collapse;
33 | border-spacing:0;
34 | width:100%;
35 | }
36 |
37 | .midi-log-table td {
38 | text-align:left;
39 | font-family:menlo, monospace;
40 | font-size:14px;
41 | padding:10px 5px;
42 | border-style:solid;
43 | border-width:1px;
44 | overflow:hidden;
45 | word-break:normal;
46 | background:#fff;
47 | }
48 | .midi-log-table th {
49 | text-align:left;
50 | font-family: menlo, monospace;
51 | font-size:14px;
52 | font-weight:normal;
53 | padding:10px 5px;
54 | border-style:solid;
55 | border-width:1px;
56 | overflow:hidden;
57 | word-break:normal;
58 | background:#f8f8f8;
59 | }
60 |
61 | .midi-logger-page .page-wrapper{
62 | max-width: 90%;
63 | margin: 0 auto;
64 | width:1000px;
65 | padding: 5% 0 3%;
66 | }
67 |
68 | .midi-logger-page h1 {
69 | text-align: center;
70 | }
71 |
72 |
73 | .hide-time-column .time-column,
74 | .hide-channel-column .channel-column,
75 | .hide-channel-message-column .channel-message-column,
76 | .hide-channel-message-desc-column .channel-message-desc-column,
77 | .hide-data-byte-1-column .data-byte-1-column,
78 | .hide-data-byte-2-column .data-byte-2-column,
79 | .hide-manufacturer-column .manufacturer-column,
80 | .hide-model-column .model-column{
81 | display: none;
82 | }
83 |
84 | .column-visibility-toggles {
85 | margin-bottom: 1em;
86 | }
87 |
88 | .column-visibility-toggles p,
89 | .number-format-choosers p {
90 | margin-bottom: 0;
91 | font-weight: bold;
92 | }
93 |
94 | .column-visibility-toggles,
95 | .number-format-choosers {
96 | padding:5px 0px 5px 18px;
97 | background:#f8f8f8;
98 | }
99 |
100 | .column-visibility-toggles label,
101 | .number-format-choosers label {
102 | padding: 10px 18px 10px 0;
103 | display: inline-block;
104 | }
105 |
106 | .midi-logger-page ul {
107 | max-width:600px;
108 | }
109 |
110 | .midi-logger-page .intro {
111 | margin-bottom: 2em;
112 | }
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Midi Signal Logger
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
Midi Logger
14 |
15 |
16 | This Midi Logger will print any midi input to your browser to the table below, with new signals appearing at the top. This is all possible because of the Web Midi API.
17 |
18 |
19 |
20 | Please note
21 |
22 |
23 | Midi channel messages are zero indexed, but controllers often label channels starting from 1. This means that if your controller has channels labelled 1 to 16, data it sends will be from 0 - 15.
24 |
25 |
26 | If you connect a new Midi device, you may need to restart your browser for it to be detected.
27 |
28 |
29 |
30 |
31 |
32 |
33 |
100 |
101 |
102 |
103 |
104 |
105 | Time
106 | Channel
107 | Channel message
108 | Channel message desc
109 | Data byte 1
110 | Data byte 2
111 | Manufacturer
112 | Model
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
--------------------------------------------------------------------------------
/js/midi-logger.js:
--------------------------------------------------------------------------------
1 | // Thanks to Chris Wilson for the code to get the midi signals
2 | /* Copyright 2013 Chris Wilson
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 |
17 |
18 | var MidiLogger = function(){
19 |
20 | this.maxRows = 100;
21 | this.rowCounter = 0;
22 | this.context = null; // the Web Audio "context" object
23 | this.midiAccess = null; // the MIDIAccess object.
24 | var _this = this;
25 |
26 | this.init = function() {
27 |
28 | if (navigator.requestMIDIAccess){
29 | navigator.requestMIDIAccess().then(
30 | _this.onMIDIInit,
31 | _this.onMIDIReject
32 | );
33 | }
34 |
35 | $(".js-column-toggle").change(function(e){
36 | $(".js-midi-log-table").toggleClass($(this).data("class-to-toggle"));
37 | });
38 |
39 | $("#row-count-switcher").change(function(){
40 | this.maxRows = $(this).val();
41 | this.rowCounter = $(".js-midi-log-table tr").length - 1;
42 |
43 | $(".js-midi-log-table tr").filter(":gt("+$(this).val()+")").remove();
44 | });
45 |
46 | }
47 |
48 | this.hookUpMIDIInput = function() {
49 | var haveAtLeastOneDevice = false;
50 | var inputs = _this.midiAccess.inputs.values();
51 | for (var input = inputs.next(); input && !input.done; input = inputs.next()) {
52 | console.log(input);
53 | input.value.onmidimessage = _this.onMIDIMessage;
54 | haveAtLeastOneDevice = true;
55 | }
56 |
57 |
58 | if (!haveAtLeastOneDevice){
59 | $("#js-warning").html("We weren't able to detect any MIDI devices. Please make sure at least one is connected or try restarting your browser.");
60 | } else {
61 | $("#js-warning").html("");
62 | }
63 |
64 | }
65 |
66 | this.onMIDIInit = function(midi) {
67 | _this.midiAccess = midi;
68 | _this.hookUpMIDIInput();
69 | _this.midiAccess.onstatechange = _this.hookUpMIDIInput;
70 | }
71 |
72 | this.onMIDIReject = function(err) {
73 | $("#js-warning").html("Sadly your browser doesn't support MIDI. Please try again with the latest version of Chrome.");
74 | }
75 |
76 | this.onMIDIMessage = function( event ) {
77 | _this.createTableRowMarkup(event);
78 | }
79 |
80 | this.startLoggingMIDIInput = function( midiAccess, indexOfPort ) {
81 |
82 | _this.midiAccess.inputs.forEach( function(entry) {
83 | entry.onmidimessage = _this.onMIDIMessage;
84 | });
85 | }
86 |
87 |
88 | this.createTableRowMarkup = function(event){
89 | var arrTableMarkup = new Array();
90 | arrTableMarkup.push ( "" );
91 | arrTableMarkup.push ( "" );
92 | arrTableMarkup.push ( event.timeStamp );
93 | arrTableMarkup.push ( " " );
94 | arrTableMarkup.push ( "" );
95 | arrTableMarkup.push ( this.printNumberinBase(((event.data[0] % 16)), $("#channel-message-format").val(), 15).toUpperCase() ); // channel
96 | arrTableMarkup.push ( " " );
97 | arrTableMarkup.push ( "" );
98 | arrTableMarkup.push ( this.printNumberinBase((event.data[0]), $("#channel-message-format").val(), 255).toUpperCase() );
99 | arrTableMarkup.push ( " " );
100 | arrTableMarkup.push ( "" );
101 | arrTableMarkup.push ( this.calculateChannelMessageType(event.data[0]) );
102 | arrTableMarkup.push ( " " );
103 | arrTableMarkup.push ( "" );
104 | if ($("#show-note-name").prop('checked')){
105 | arrTableMarkup.push ( this.midiNumberToNoteName(event.data[1]) );
106 | } else {
107 | arrTableMarkup.push ( this.printNumberinBase((event.data[1]), $("#data-byte-format").val(), 127).toUpperCase() );
108 | }
109 | arrTableMarkup.push ( " " );
110 | arrTableMarkup.push ( "" );
111 | if (typeof event.data[2] !== "undefined"){
112 | arrTableMarkup.push ( this.printNumberinBase((event.data[2]), $("#data-byte-format").val(), 127).toUpperCase() );
113 | }
114 | arrTableMarkup.push ( " " );
115 | arrTableMarkup.push ( "" );
116 | arrTableMarkup.push ( event.currentTarget.manufacturer );
117 | arrTableMarkup.push ( " " );
118 | arrTableMarkup.push ( "" );
119 | arrTableMarkup.push ( event.currentTarget.name );
120 | arrTableMarkup.push ( " " );
121 | arrTableMarkup.push ( " " );
122 |
123 | if (this.rowCounter < this.maxRows){
124 | this.rowCounter++;
125 | } else {
126 | $('.js-midi-log-table tr:last').remove();
127 | }
128 | $(".js-table-head-row").after(arrTableMarkup.join('') );
129 | }
130 |
131 | this.calculateChannelMessageType = function(number){
132 | // http://www.earlevel.com/main/1996/08/14/midi-overview/
133 | switch (Math.floor(number/16)) {
134 | case 8:
135 | return "Note off";
136 | case 9:
137 | return "Note on";
138 | case 10:
139 | return "Polyphonic key pressure";
140 | case 11:
141 | return "Mode change";
142 | case 12:
143 | return "Program change";
144 | case 13:
145 | return "Monophonic key pressure";
146 | case 14:
147 | return "Pitch bend";
148 | }
149 | }
150 |
151 |
152 |
153 | this.printNumberinBase = function(decimalNumber, base, maxValue){
154 | if (base == "dec"){
155 | var maxLength = (maxValue + "").length;
156 | var paddedOutput = this.pad(decimalNumber, maxLength)
157 | return paddedOutput;
158 | } else if (base == "bin"){
159 | var maxLength = maxValue.toString(2).length;
160 | var paddedOutput = this.pad(decimalNumber.toString(2), maxLength)
161 | return paddedOutput;
162 | } else if (base == "hex"){
163 | var maxLength = maxValue.toString(16).length;
164 | var paddedOutput = this.pad(decimalNumber.toString(16), maxLength)
165 | return paddedOutput;
166 | }
167 | }
168 |
169 | this.midiNumberToNoteName = function(midiNumber){
170 | return MIDIUtils.noteNumberToName(midiNumber);
171 |
172 | }
173 |
174 | this.pad = function(num, size) {
175 | var s = num+"";
176 | while (s.length < size) s = "0" + s;
177 | return s;
178 | }
179 | }
180 |
--------------------------------------------------------------------------------
/js/WebMIDIAPI.js:
--------------------------------------------------------------------------------
1 | (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o i)if(isEnum.call(it, key = symbols[i++]))keys.push(key);
361 | }
362 | return keys;
363 | };
364 | },{"./$":30}],15:[function(require,module,exports){
365 | module.exports = function(exec){
366 | try {
367 | return !!exec();
368 | } catch(e){
369 | return true;
370 | }
371 | };
372 | },{}],16:[function(require,module,exports){
373 | var ctx = require('./$.ctx')
374 | , call = require('./$.iter-call')
375 | , isArrayIter = require('./$.is-array-iter')
376 | , anObject = require('./$.an-object')
377 | , toLength = require('./$.to-length')
378 | , getIterFn = require('./core.get-iterator-method');
379 | module.exports = function(iterable, entries, fn, that){
380 | var iterFn = getIterFn(iterable)
381 | , f = ctx(fn, that, entries ? 2 : 1)
382 | , index = 0
383 | , length, step, iterator;
384 | if(typeof iterFn != 'function')throw TypeError(iterable + ' is not iterable!');
385 | // fast case for arrays with default iterator
386 | if(isArrayIter(iterFn))for(length = toLength(iterable.length); length > index; index++){
387 | entries ? f(anObject(step = iterable[index])[0], step[1]) : f(iterable[index]);
388 | } else for(iterator = iterFn.call(iterable); !(step = iterator.next()).done; ){
389 | call(iterator, f, step.value, entries);
390 | }
391 | };
392 | },{"./$.an-object":5,"./$.ctx":11,"./$.is-array-iter":22,"./$.iter-call":24,"./$.to-length":44,"./core.get-iterator-method":48}],17:[function(require,module,exports){
393 | // fallback for IE11 buggy Object.getOwnPropertyNames with iframe and window
394 | var toString = {}.toString
395 | , toIObject = require('./$.to-iobject')
396 | , getNames = require('./$').getNames;
397 |
398 | var windowNames = typeof window == 'object' && Object.getOwnPropertyNames
399 | ? Object.getOwnPropertyNames(window) : [];
400 |
401 | var getWindowNames = function(it){
402 | try {
403 | return getNames(it);
404 | } catch(e){
405 | return windowNames.slice();
406 | }
407 | };
408 |
409 | module.exports.get = function getOwnPropertyNames(it){
410 | if(windowNames && toString.call(it) == '[object Window]')return getWindowNames(it);
411 | return getNames(toIObject(it));
412 | };
413 | },{"./$":30,"./$.to-iobject":43}],18:[function(require,module,exports){
414 | // https://github.com/zloirock/core-js/issues/86#issuecomment-115759028
415 | var UNDEFINED = 'undefined';
416 | var global = module.exports = typeof window != UNDEFINED && window.Math == Math
417 | ? window : typeof self != UNDEFINED && self.Math == Math ? self : Function('return this')();
418 | if(typeof __g == 'number')__g = global; // eslint-disable-line no-undef
419 | },{}],19:[function(require,module,exports){
420 | var hasOwnProperty = {}.hasOwnProperty;
421 | module.exports = function(it, key){
422 | return hasOwnProperty.call(it, key);
423 | };
424 | },{}],20:[function(require,module,exports){
425 | var $ = require('./$')
426 | , createDesc = require('./$.property-desc');
427 | module.exports = require('./$.support-desc') ? function(object, key, value){
428 | return $.setDesc(object, key, createDesc(1, value));
429 | } : function(object, key, value){
430 | object[key] = value;
431 | return object;
432 | };
433 | },{"./$":30,"./$.property-desc":34,"./$.support-desc":40}],21:[function(require,module,exports){
434 | // indexed object, fallback for non-array-like ES3 strings
435 | var cof = require('./$.cof');
436 | module.exports = 0 in Object('z') ? Object : function(it){
437 | return cof(it) == 'String' ? it.split('') : Object(it);
438 | };
439 | },{"./$.cof":7}],22:[function(require,module,exports){
440 | // check on default Array iterator
441 | var Iterators = require('./$.iterators')
442 | , ITERATOR = require('./$.wks')('iterator');
443 | module.exports = function(it){
444 | return (Iterators.Array || Array.prototype[ITERATOR]) === it;
445 | };
446 | },{"./$.iterators":29,"./$.wks":47}],23:[function(require,module,exports){
447 | // http://jsperf.com/core-js-isobject
448 | module.exports = function(it){
449 | return it !== null && (typeof it == 'object' || typeof it == 'function');
450 | };
451 | },{}],24:[function(require,module,exports){
452 | // call something on iterator step with safe closing on error
453 | var anObject = require('./$.an-object');
454 | module.exports = function(iterator, fn, value, entries){
455 | try {
456 | return entries ? fn(anObject(value)[0], value[1]) : fn(value);
457 | // 7.4.6 IteratorClose(iterator, completion)
458 | } catch(e){
459 | var ret = iterator['return'];
460 | if(ret !== undefined)anObject(ret.call(iterator));
461 | throw e;
462 | }
463 | };
464 | },{"./$.an-object":5}],25:[function(require,module,exports){
465 | 'use strict';
466 | var $ = require('./$')
467 | , IteratorPrototype = {};
468 |
469 | // 25.1.2.1.1 %IteratorPrototype%[@@iterator]()
470 | require('./$.hide')(IteratorPrototype, require('./$.wks')('iterator'), function(){ return this; });
471 |
472 | module.exports = function(Constructor, NAME, next){
473 | Constructor.prototype = $.create(IteratorPrototype, {next: require('./$.property-desc')(1,next)});
474 | require('./$.tag')(Constructor, NAME + ' Iterator');
475 | };
476 | },{"./$":30,"./$.hide":20,"./$.property-desc":34,"./$.tag":41,"./$.wks":47}],26:[function(require,module,exports){
477 | 'use strict';
478 | var LIBRARY = require('./$.library')
479 | , $def = require('./$.def')
480 | , $redef = require('./$.redef')
481 | , hide = require('./$.hide')
482 | , has = require('./$.has')
483 | , SYMBOL_ITERATOR = require('./$.wks')('iterator')
484 | , Iterators = require('./$.iterators')
485 | , BUGGY = !([].keys && 'next' in [].keys()) // Safari has buggy iterators w/o `next`
486 | , FF_ITERATOR = '@@iterator'
487 | , KEYS = 'keys'
488 | , VALUES = 'values';
489 | var returnThis = function(){ return this; };
490 | module.exports = function(Base, NAME, Constructor, next, DEFAULT, IS_SET, FORCE){
491 | require('./$.iter-create')(Constructor, NAME, next);
492 | var createMethod = function(kind){
493 | switch(kind){
494 | case KEYS: return function keys(){ return new Constructor(this, kind); };
495 | case VALUES: return function values(){ return new Constructor(this, kind); };
496 | } return function entries(){ return new Constructor(this, kind); };
497 | };
498 | var TAG = NAME + ' Iterator'
499 | , proto = Base.prototype
500 | , _native = proto[SYMBOL_ITERATOR] || proto[FF_ITERATOR] || DEFAULT && proto[DEFAULT]
501 | , _default = _native || createMethod(DEFAULT)
502 | , methods, key;
503 | // Fix native
504 | if(_native){
505 | var IteratorPrototype = require('./$').getProto(_default.call(new Base));
506 | // Set @@toStringTag to native iterators
507 | require('./$.tag')(IteratorPrototype, TAG, true);
508 | // FF fix
509 | if(!LIBRARY && has(proto, FF_ITERATOR))hide(IteratorPrototype, SYMBOL_ITERATOR, returnThis);
510 | }
511 | // Define iterator
512 | if(!LIBRARY || FORCE)hide(proto, SYMBOL_ITERATOR, _default);
513 | // Plug for library
514 | Iterators[NAME] = _default;
515 | Iterators[TAG] = returnThis;
516 | if(DEFAULT){
517 | methods = {
518 | keys: IS_SET ? _default : createMethod(KEYS),
519 | values: DEFAULT == VALUES ? _default : createMethod(VALUES),
520 | entries: DEFAULT != VALUES ? _default : createMethod('entries')
521 | };
522 | if(FORCE)for(key in methods){
523 | if(!(key in proto))$redef(proto, key, methods[key]);
524 | } else $def($def.P + $def.F * BUGGY, NAME, methods);
525 | }
526 | };
527 | },{"./$":30,"./$.def":12,"./$.has":19,"./$.hide":20,"./$.iter-create":25,"./$.iterators":29,"./$.library":32,"./$.redef":35,"./$.tag":41,"./$.wks":47}],27:[function(require,module,exports){
528 | var SYMBOL_ITERATOR = require('./$.wks')('iterator')
529 | , SAFE_CLOSING = false;
530 | try {
531 | var riter = [7][SYMBOL_ITERATOR]();
532 | riter['return'] = function(){ SAFE_CLOSING = true; };
533 | Array.from(riter, function(){ throw 2; });
534 | } catch(e){ /* empty */ }
535 | module.exports = function(exec){
536 | if(!SAFE_CLOSING)return false;
537 | var safe = false;
538 | try {
539 | var arr = [7]
540 | , iter = arr[SYMBOL_ITERATOR]();
541 | iter.next = function(){ safe = true; };
542 | arr[SYMBOL_ITERATOR] = function(){ return iter; };
543 | exec(arr);
544 | } catch(e){ /* empty */ }
545 | return safe;
546 | };
547 | },{"./$.wks":47}],28:[function(require,module,exports){
548 | module.exports = function(done, value){
549 | return {value: value, done: !!done};
550 | };
551 | },{}],29:[function(require,module,exports){
552 | module.exports = {};
553 | },{}],30:[function(require,module,exports){
554 | var $Object = Object;
555 | module.exports = {
556 | create: $Object.create,
557 | getProto: $Object.getPrototypeOf,
558 | isEnum: {}.propertyIsEnumerable,
559 | getDesc: $Object.getOwnPropertyDescriptor,
560 | setDesc: $Object.defineProperty,
561 | setDescs: $Object.defineProperties,
562 | getKeys: $Object.keys,
563 | getNames: $Object.getOwnPropertyNames,
564 | getSymbols: $Object.getOwnPropertySymbols,
565 | each: [].forEach
566 | };
567 | },{}],31:[function(require,module,exports){
568 | var $ = require('./$')
569 | , toIObject = require('./$.to-iobject');
570 | module.exports = function(object, el){
571 | var O = toIObject(object)
572 | , keys = $.getKeys(O)
573 | , length = keys.length
574 | , index = 0
575 | , key;
576 | while(length > index)if(O[key = keys[index++]] === el)return key;
577 | };
578 | },{"./$":30,"./$.to-iobject":43}],32:[function(require,module,exports){
579 | module.exports = false;
580 | },{}],33:[function(require,module,exports){
581 | var $redef = require('./$.redef');
582 | module.exports = function(target, src){
583 | for(var key in src)$redef(target, key, src[key]);
584 | return target;
585 | };
586 | },{"./$.redef":35}],34:[function(require,module,exports){
587 | module.exports = function(bitmap, value){
588 | return {
589 | enumerable : !(bitmap & 1),
590 | configurable: !(bitmap & 2),
591 | writable : !(bitmap & 4),
592 | value : value
593 | };
594 | };
595 | },{}],35:[function(require,module,exports){
596 | // add fake Function#toString
597 | // for correct work wrapped methods / constructors with methods like LoDash isNative
598 | var global = require('./$.global')
599 | , hide = require('./$.hide')
600 | , SRC = require('./$.uid')('src')
601 | , TO_STRING = 'toString'
602 | , $toString = Function[TO_STRING]
603 | , TPL = ('' + $toString).split(TO_STRING);
604 |
605 | require('./$.core').inspectSource = function(it){
606 | return $toString.call(it);
607 | };
608 |
609 | (module.exports = function(O, key, val, safe){
610 | if(typeof val == 'function'){
611 | hide(val, SRC, O[key] ? '' + O[key] : TPL.join(String(key)));
612 | if(!('name' in val))val.name = key;
613 | }
614 | if(O === global){
615 | O[key] = val;
616 | } else {
617 | if(!safe)delete O[key];
618 | hide(O, key, val);
619 | }
620 | })(Function.prototype, TO_STRING, function toString(){
621 | return typeof this == 'function' && this[SRC] || $toString.call(this);
622 | });
623 | },{"./$.core":10,"./$.global":18,"./$.hide":20,"./$.uid":45}],36:[function(require,module,exports){
624 | var global = require('./$.global')
625 | , SHARED = '__core-js_shared__'
626 | , store = global[SHARED] || (global[SHARED] = {});
627 | module.exports = function(key){
628 | return store[key] || (store[key] = {});
629 | };
630 | },{"./$.global":18}],37:[function(require,module,exports){
631 | 'use strict';
632 | var $ = require('./$')
633 | , SPECIES = require('./$.wks')('species');
634 | module.exports = function(C){
635 | if(require('./$.support-desc') && !(SPECIES in C))$.setDesc(C, SPECIES, {
636 | configurable: true,
637 | get: function(){ return this; }
638 | });
639 | };
640 | },{"./$":30,"./$.support-desc":40,"./$.wks":47}],38:[function(require,module,exports){
641 | module.exports = function(it, Constructor, name){
642 | if(!(it instanceof Constructor))throw TypeError(name + ": use the 'new' operator!");
643 | return it;
644 | };
645 | },{}],39:[function(require,module,exports){
646 | // true -> String#at
647 | // false -> String#codePointAt
648 | var toInteger = require('./$.to-integer')
649 | , defined = require('./$.defined');
650 | module.exports = function(TO_STRING){
651 | return function(that, pos){
652 | var s = String(defined(that))
653 | , i = toInteger(pos)
654 | , l = s.length
655 | , a, b;
656 | if(i < 0 || i >= l)return TO_STRING ? '' : undefined;
657 | a = s.charCodeAt(i);
658 | return a < 0xd800 || a > 0xdbff || i + 1 === l
659 | || (b = s.charCodeAt(i + 1)) < 0xdc00 || b > 0xdfff
660 | ? TO_STRING ? s.charAt(i) : a
661 | : TO_STRING ? s.slice(i, i + 2) : (a - 0xd800 << 10) + (b - 0xdc00) + 0x10000;
662 | };
663 | };
664 | },{"./$.defined":13,"./$.to-integer":42}],40:[function(require,module,exports){
665 | // Thank's IE8 for his funny defineProperty
666 | module.exports = !require('./$.fails')(function(){
667 | return Object.defineProperty({}, 'a', {get: function(){ return 7; }}).a != 7;
668 | });
669 | },{"./$.fails":15}],41:[function(require,module,exports){
670 | var has = require('./$.has')
671 | , hide = require('./$.hide')
672 | , TAG = require('./$.wks')('toStringTag');
673 |
674 | module.exports = function(it, tag, stat){
675 | if(it && !has(it = stat ? it : it.prototype, TAG))hide(it, TAG, tag);
676 | };
677 | },{"./$.has":19,"./$.hide":20,"./$.wks":47}],42:[function(require,module,exports){
678 | // 7.1.4 ToInteger
679 | var ceil = Math.ceil
680 | , floor = Math.floor;
681 | module.exports = function(it){
682 | return isNaN(it = +it) ? 0 : (it > 0 ? floor : ceil)(it);
683 | };
684 | },{}],43:[function(require,module,exports){
685 | // to indexed object, toObject with fallback for non-array-like ES3 strings
686 |
687 | var IObject = require('./$.iobject')
688 |
689 | , defined = require('./$.defined');
690 |
691 | module.exports = function(it){
692 |
693 | return IObject(defined(it));
694 |
695 | };
696 | },{"./$.defined":13,"./$.iobject":21}],44:[function(require,module,exports){
697 | // 7.1.15 ToLength
698 | var toInteger = require('./$.to-integer')
699 | , min = Math.min;
700 | module.exports = function(it){
701 | return it > 0 ? min(toInteger(it), 0x1fffffffffffff) : 0; // pow(2, 53) - 1 == 9007199254740991
702 | };
703 | },{"./$.to-integer":42}],45:[function(require,module,exports){
704 | var id = 0
705 | , px = Math.random();
706 | module.exports = function(key){
707 | return 'Symbol('.concat(key === undefined ? '' : key, ')_', (++id + px).toString(36));
708 | };
709 | },{}],46:[function(require,module,exports){
710 | // 22.1.3.31 Array.prototype[@@unscopables]
711 | var UNSCOPABLES = require('./$.wks')('unscopables');
712 | if(!(UNSCOPABLES in []))require('./$.hide')(Array.prototype, UNSCOPABLES, {});
713 | module.exports = function(key){
714 | [][UNSCOPABLES][key] = true;
715 | };
716 | },{"./$.hide":20,"./$.wks":47}],47:[function(require,module,exports){
717 | var store = require('./$.shared')('wks')
718 | , Symbol = require('./$.global').Symbol;
719 | module.exports = function(name){
720 | return store[name] || (store[name] =
721 | Symbol && Symbol[name] || (Symbol || require('./$.uid'))('Symbol.' + name));
722 | };
723 | },{"./$.global":18,"./$.shared":36,"./$.uid":45}],48:[function(require,module,exports){
724 | var classof = require('./$.classof')
725 | , ITERATOR = require('./$.wks')('iterator')
726 | , Iterators = require('./$.iterators');
727 | module.exports = require('./$.core').getIteratorMethod = function(it){
728 | if(it != undefined)return it[ITERATOR] || it['@@iterator'] || Iterators[classof(it)];
729 | };
730 | },{"./$.classof":6,"./$.core":10,"./$.iterators":29,"./$.wks":47}],49:[function(require,module,exports){
731 | 'use strict';
732 | var setUnscope = require('./$.unscope')
733 | , step = require('./$.iter-step')
734 | , Iterators = require('./$.iterators')
735 | , toIObject = require('./$.to-iobject');
736 |
737 | // 22.1.3.4 Array.prototype.entries()
738 | // 22.1.3.13 Array.prototype.keys()
739 | // 22.1.3.29 Array.prototype.values()
740 | // 22.1.3.30 Array.prototype[@@iterator]()
741 | require('./$.iter-define')(Array, 'Array', function(iterated, kind){
742 | this._t = toIObject(iterated); // target
743 | this._i = 0; // next index
744 | this._k = kind; // kind
745 | // 22.1.5.2.1 %ArrayIteratorPrototype%.next()
746 | }, function(){
747 | var O = this._t
748 | , kind = this._k
749 | , index = this._i++;
750 | if(!O || index >= O.length){
751 | this._t = undefined;
752 | return step(1);
753 | }
754 | if(kind == 'keys' )return step(0, index);
755 | if(kind == 'values')return step(0, O[index]);
756 | return step(0, [index, O[index]]);
757 | }, 'values');
758 |
759 | // argumentsList[@@iterator] is %ArrayProto_values% (9.4.4.6, 9.4.4.7)
760 | Iterators.Arguments = Iterators.Array;
761 |
762 | setUnscope('keys');
763 | setUnscope('values');
764 | setUnscope('entries');
765 | },{"./$.iter-define":26,"./$.iter-step":28,"./$.iterators":29,"./$.to-iobject":43,"./$.unscope":46}],50:[function(require,module,exports){
766 | 'use strict';
767 | var strong = require('./$.collection-strong');
768 |
769 | // 23.1 Map Objects
770 | require('./$.collection')('Map', function(get){
771 | return function Map(){ return get(this, arguments[0]); };
772 | }, {
773 | // 23.1.3.6 Map.prototype.get(key)
774 | get: function get(key){
775 | var entry = strong.getEntry(this, key);
776 | return entry && entry.v;
777 | },
778 | // 23.1.3.9 Map.prototype.set(key, value)
779 | set: function set(key, value){
780 | return strong.def(this, key === 0 ? 0 : key, value);
781 | }
782 | }, strong, true);
783 | },{"./$.collection":9,"./$.collection-strong":8}],51:[function(require,module,exports){
784 | 'use strict';
785 | // 19.1.3.6 Object.prototype.toString()
786 | var classof = require('./$.classof')
787 | , test = {};
788 | test[require('./$.wks')('toStringTag')] = 'z';
789 | if(test + '' != '[object z]'){
790 | require('./$.redef')(Object.prototype, 'toString', function toString(){
791 | return '[object ' + classof(this) + ']';
792 | }, true);
793 | }
794 | },{"./$.classof":6,"./$.redef":35,"./$.wks":47}],52:[function(require,module,exports){
795 | 'use strict';
796 | var strong = require('./$.collection-strong');
797 |
798 | // 23.2 Set Objects
799 | require('./$.collection')('Set', function(get){
800 | return function Set(){ return get(this, arguments[0]); };
801 | }, {
802 | // 23.2.3.1 Set.prototype.add(value)
803 | add: function add(value){
804 | return strong.def(this, value = value === 0 ? 0 : value, value);
805 | }
806 | }, strong);
807 | },{"./$.collection":9,"./$.collection-strong":8}],53:[function(require,module,exports){
808 | 'use strict';
809 | var $at = require('./$.string-at')(true);
810 |
811 | // 21.1.3.27 String.prototype[@@iterator]()
812 | require('./$.iter-define')(String, 'String', function(iterated){
813 | this._t = String(iterated); // target
814 | this._i = 0; // next index
815 | // 21.1.5.2.1 %StringIteratorPrototype%.next()
816 | }, function(){
817 | var O = this._t
818 | , index = this._i
819 | , point;
820 | if(index >= O.length)return {value: undefined, done: true};
821 | point = $at(O, index);
822 | this._i += point.length;
823 | return {value: point, done: false};
824 | });
825 | },{"./$.iter-define":26,"./$.string-at":39}],54:[function(require,module,exports){
826 | 'use strict';
827 | // ECMAScript 6 symbols shim
828 | var $ = require('./$')
829 | , global = require('./$.global')
830 | , has = require('./$.has')
831 | , SUPPORT_DESC = require('./$.support-desc')
832 | , $def = require('./$.def')
833 | , $redef = require('./$.redef')
834 | , shared = require('./$.shared')
835 | , setTag = require('./$.tag')
836 | , uid = require('./$.uid')
837 | , wks = require('./$.wks')
838 | , keyOf = require('./$.keyof')
839 | , $names = require('./$.get-names')
840 | , enumKeys = require('./$.enum-keys')
841 | , isObject = require('./$.is-object')
842 | , anObject = require('./$.an-object')
843 | , toIObject = require('./$.to-iobject')
844 | , createDesc = require('./$.property-desc')
845 | , getDesc = $.getDesc
846 | , setDesc = $.setDesc
847 | , _create = $.create
848 | , getNames = $names.get
849 | , $Symbol = global.Symbol
850 | , setter = false
851 | , HIDDEN = wks('_hidden')
852 | , isEnum = $.isEnum
853 | , SymbolRegistry = shared('symbol-registry')
854 | , AllSymbols = shared('symbols')
855 | , useNative = typeof $Symbol == 'function'
856 | , ObjectProto = Object.prototype;
857 |
858 | var setSymbolDesc = SUPPORT_DESC ? function(){ // fallback for old Android
859 | try {
860 | return _create(setDesc({}, HIDDEN, {
861 | get: function(){
862 | return setDesc(this, HIDDEN, {value: false})[HIDDEN];
863 | }
864 | }))[HIDDEN] || setDesc;
865 | } catch(e){
866 | return function(it, key, D){
867 | var protoDesc = getDesc(ObjectProto, key);
868 | if(protoDesc)delete ObjectProto[key];
869 | setDesc(it, key, D);
870 | if(protoDesc && it !== ObjectProto)setDesc(ObjectProto, key, protoDesc);
871 | };
872 | }
873 | }() : setDesc;
874 |
875 | var wrap = function(tag){
876 | var sym = AllSymbols[tag] = _create($Symbol.prototype);
877 | sym._k = tag;
878 | SUPPORT_DESC && setter && setSymbolDesc(ObjectProto, tag, {
879 | configurable: true,
880 | set: function(value){
881 | if(has(this, HIDDEN) && has(this[HIDDEN], tag))this[HIDDEN][tag] = false;
882 | setSymbolDesc(this, tag, createDesc(1, value));
883 | }
884 | });
885 | return sym;
886 | };
887 |
888 | var $defineProperty = function defineProperty(it, key, D){
889 | if(D && has(AllSymbols, key)){
890 | if(!D.enumerable){
891 | if(!has(it, HIDDEN))setDesc(it, HIDDEN, createDesc(1, {}));
892 | it[HIDDEN][key] = true;
893 | } else {
894 | if(has(it, HIDDEN) && it[HIDDEN][key])it[HIDDEN][key] = false;
895 | D = _create(D, {enumerable: createDesc(0, false)});
896 | } return setSymbolDesc(it, key, D);
897 | } return setDesc(it, key, D);
898 | };
899 | var $defineProperties = function defineProperties(it, P){
900 | anObject(it);
901 | var keys = enumKeys(P = toIObject(P))
902 | , i = 0
903 | , l = keys.length
904 | , key;
905 | while(l > i)$defineProperty(it, key = keys[i++], P[key]);
906 | return it;
907 | };
908 | var $create = function create(it, P){
909 | return P === undefined ? _create(it) : $defineProperties(_create(it), P);
910 | };
911 | var $propertyIsEnumerable = function propertyIsEnumerable(key){
912 | var E = isEnum.call(this, key);
913 | return E || !has(this, key) || !has(AllSymbols, key) || has(this, HIDDEN) && this[HIDDEN][key]
914 | ? E : true;
915 | };
916 | var $getOwnPropertyDescriptor = function getOwnPropertyDescriptor(it, key){
917 | var D = getDesc(it = toIObject(it), key);
918 | if(D && has(AllSymbols, key) && !(has(it, HIDDEN) && it[HIDDEN][key]))D.enumerable = true;
919 | return D;
920 | };
921 | var $getOwnPropertyNames = function getOwnPropertyNames(it){
922 | var names = getNames(toIObject(it))
923 | , result = []
924 | , i = 0
925 | , key;
926 | while(names.length > i)if(!has(AllSymbols, key = names[i++]) && key != HIDDEN)result.push(key);
927 | return result;
928 | };
929 | var $getOwnPropertySymbols = function getOwnPropertySymbols(it){
930 | var names = getNames(toIObject(it))
931 | , result = []
932 | , i = 0
933 | , key;
934 | while(names.length > i)if(has(AllSymbols, key = names[i++]))result.push(AllSymbols[key]);
935 | return result;
936 | };
937 |
938 | // 19.4.1.1 Symbol([description])
939 | if(!useNative){
940 | $Symbol = function Symbol(){
941 | if(this instanceof $Symbol)throw TypeError('Symbol is not a constructor');
942 | return wrap(uid(arguments[0]));
943 | };
944 | $redef($Symbol.prototype, 'toString', function toString(){
945 | return this._k;
946 | });
947 |
948 | $.create = $create;
949 | $.isEnum = $propertyIsEnumerable;
950 | $.getDesc = $getOwnPropertyDescriptor;
951 | $.setDesc = $defineProperty;
952 | $.setDescs = $defineProperties;
953 | $.getNames = $names.get = $getOwnPropertyNames;
954 | $.getSymbols = $getOwnPropertySymbols;
955 |
956 | if(SUPPORT_DESC && !require('./$.library')){
957 | $redef(ObjectProto, 'propertyIsEnumerable', $propertyIsEnumerable, true);
958 | }
959 | }
960 |
961 | // MS Edge converts symbol values to JSON as {}
962 | // WebKit converts symbol values in objects to JSON as null
963 | if(!useNative || require('./$.fails')(function(){
964 | return JSON.stringify([{a: $Symbol()}, [$Symbol()]]) != '[{},[null]]';
965 | }))$redef($Symbol.prototype, 'toJSON', function toJSON(){
966 | if(useNative && isObject(this))return this;
967 | });
968 |
969 | var symbolStatics = {
970 | // 19.4.2.1 Symbol.for(key)
971 | 'for': function(key){
972 | return has(SymbolRegistry, key += '')
973 | ? SymbolRegistry[key]
974 | : SymbolRegistry[key] = $Symbol(key);
975 | },
976 | // 19.4.2.5 Symbol.keyFor(sym)
977 | keyFor: function keyFor(key){
978 | return keyOf(SymbolRegistry, key);
979 | },
980 | useSetter: function(){ setter = true; },
981 | useSimple: function(){ setter = false; }
982 | };
983 | // 19.4.2.2 Symbol.hasInstance
984 | // 19.4.2.3 Symbol.isConcatSpreadable
985 | // 19.4.2.4 Symbol.iterator
986 | // 19.4.2.6 Symbol.match
987 | // 19.4.2.8 Symbol.replace
988 | // 19.4.2.9 Symbol.search
989 | // 19.4.2.10 Symbol.species
990 | // 19.4.2.11 Symbol.split
991 | // 19.4.2.12 Symbol.toPrimitive
992 | // 19.4.2.13 Symbol.toStringTag
993 | // 19.4.2.14 Symbol.unscopables
994 | $.each.call((
995 | 'hasInstance,isConcatSpreadable,iterator,match,replace,search,' +
996 | 'species,split,toPrimitive,toStringTag,unscopables'
997 | ).split(','), function(it){
998 | var sym = wks(it);
999 | symbolStatics[it] = useNative ? sym : wrap(sym);
1000 | }
1001 | );
1002 |
1003 | setter = true;
1004 |
1005 | $def($def.G + $def.W, {Symbol: $Symbol});
1006 |
1007 | $def($def.S, 'Symbol', symbolStatics);
1008 |
1009 | $def($def.S + $def.F * !useNative, 'Object', {
1010 | // 19.1.2.2 Object.create(O [, Properties])
1011 | create: $create,
1012 | // 19.1.2.4 Object.defineProperty(O, P, Attributes)
1013 | defineProperty: $defineProperty,
1014 | // 19.1.2.3 Object.defineProperties(O, Properties)
1015 | defineProperties: $defineProperties,
1016 | // 19.1.2.6 Object.getOwnPropertyDescriptor(O, P)
1017 | getOwnPropertyDescriptor: $getOwnPropertyDescriptor,
1018 | // 19.1.2.7 Object.getOwnPropertyNames(O)
1019 | getOwnPropertyNames: $getOwnPropertyNames,
1020 | // 19.1.2.8 Object.getOwnPropertySymbols(O)
1021 | getOwnPropertySymbols: $getOwnPropertySymbols
1022 | });
1023 |
1024 | // 19.4.3.5 Symbol.prototype[@@toStringTag]
1025 | setTag($Symbol, 'Symbol');
1026 | // 20.2.1.9 Math[@@toStringTag]
1027 | setTag(Math, 'Math', true);
1028 | // 24.3.3 JSON[@@toStringTag]
1029 | setTag(global.JSON, 'JSON', true);
1030 | },{"./$":30,"./$.an-object":5,"./$.def":12,"./$.enum-keys":14,"./$.fails":15,"./$.get-names":17,"./$.global":18,"./$.has":19,"./$.is-object":23,"./$.keyof":31,"./$.library":32,"./$.property-desc":34,"./$.redef":35,"./$.shared":36,"./$.support-desc":40,"./$.tag":41,"./$.to-iobject":43,"./$.uid":45,"./$.wks":47}],55:[function(require,module,exports){
1031 | require('./es6.array.iterator');
1032 | var global = require('./$.global')
1033 | , hide = require('./$.hide')
1034 | , Iterators = require('./$.iterators')
1035 | , ITERATOR = require('./$.wks')('iterator')
1036 | , NL = global.NodeList
1037 | , HTC = global.HTMLCollection
1038 | , NLProto = NL && NL.prototype
1039 | , HTCProto = HTC && HTC.prototype
1040 | , ArrayValues = Iterators.NodeList = Iterators.HTMLCollection = Iterators.Array;
1041 | if(NL && !(ITERATOR in NLProto))hide(NLProto, ITERATOR, ArrayValues);
1042 | if(HTC && !(ITERATOR in HTCProto))hide(HTCProto, ITERATOR, ArrayValues);
1043 | },{"./$.global":18,"./$.hide":20,"./$.iterators":29,"./$.wks":47,"./es6.array.iterator":49}],56:[function(require,module,exports){
1044 | // shim for using process in browser
1045 |
1046 | var process = module.exports = {};
1047 | var queue = [];
1048 | var draining = false;
1049 | var currentQueue;
1050 | var queueIndex = -1;
1051 |
1052 | function cleanUpNextTick() {
1053 | draining = false;
1054 | if (currentQueue.length) {
1055 | queue = currentQueue.concat(queue);
1056 | } else {
1057 | queueIndex = -1;
1058 | }
1059 | if (queue.length) {
1060 | drainQueue();
1061 | }
1062 | }
1063 |
1064 | function drainQueue() {
1065 | if (draining) {
1066 | return;
1067 | }
1068 | var timeout = setTimeout(cleanUpNextTick);
1069 | draining = true;
1070 |
1071 | var len = queue.length;
1072 | while(len) {
1073 | currentQueue = queue;
1074 | queue = [];
1075 | while (++queueIndex < len) {
1076 | if (currentQueue) {
1077 | currentQueue[queueIndex].run();
1078 | }
1079 | }
1080 | queueIndex = -1;
1081 | len = queue.length;
1082 | }
1083 | currentQueue = null;
1084 | draining = false;
1085 | clearTimeout(timeout);
1086 | }
1087 |
1088 | process.nextTick = function (fun) {
1089 | var args = new Array(arguments.length - 1);
1090 | if (arguments.length > 1) {
1091 | for (var i = 1; i < arguments.length; i++) {
1092 | args[i - 1] = arguments[i];
1093 | }
1094 | }
1095 | queue.push(new Item(fun, args));
1096 | if (queue.length === 1 && !draining) {
1097 | setTimeout(drainQueue, 0);
1098 | }
1099 | };
1100 |
1101 | // v8 likes predictible objects
1102 | function Item(fun, array) {
1103 | this.fun = fun;
1104 | this.array = array;
1105 | }
1106 | Item.prototype.run = function () {
1107 | this.fun.apply(null, this.array);
1108 | };
1109 | process.title = 'browser';
1110 | process.browser = true;
1111 | process.env = {};
1112 | process.argv = [];
1113 | process.version = ''; // empty string to avoid regexp issues
1114 | process.versions = {};
1115 |
1116 | function noop() {}
1117 |
1118 | process.on = noop;
1119 | process.addListener = noop;
1120 | process.once = noop;
1121 | process.off = noop;
1122 | process.removeListener = noop;
1123 | process.removeAllListeners = noop;
1124 | process.emit = noop;
1125 |
1126 | process.binding = function (name) {
1127 | throw new Error('process.binding is not supported');
1128 | };
1129 |
1130 | process.cwd = function () { return '/' };
1131 | process.chdir = function (dir) {
1132 | throw new Error('process.chdir is not supported');
1133 | };
1134 | process.umask = function() { return 0; };
1135 |
1136 | },{}],57:[function(require,module,exports){
1137 | /*
1138 | Creates instances of the Jazz plugin if necessary. Initially the MIDIAccess creates one main Jazz instance that is used
1139 | to query all initially connected devices, and to track the devices that are being connected or disconnected at runtime.
1140 |
1141 | For every MIDIInput and MIDIOutput that is created, MIDIAccess queries the getJazzInstance() method for a Jazz instance
1142 | that still have an available input or output. Because Jazz only allows one input and one output per instance, we
1143 | need to create new instances if more than one MIDI input or output device gets connected.
1144 |
1145 | Note that an existing Jazz instance doesn't get deleted when both its input and output device are disconnected; instead it
1146 | will be reused if a new device gets connected.
1147 | */
1148 |
1149 | 'use strict';
1150 |
1151 | /*
1152 | The require statements are only needed for Internet Explorer. They have to be put here;
1153 | if you put them at the top entry point (shim.js) it doesn't work (weird quirck in IE?).
1154 |
1155 | Note that you can remove the require statements if you don't need (or want) to support Internet Explorer:
1156 | that will shrink the filesize of the WebMIDIAPIShim to about 50%.
1157 |
1158 | If you are building for Nodejs platform you can comment these lines, then run the buildscript like so:
1159 | 'npm run build-nodejs' -> the build file (approx. 15K) will be saved in the web-midi-api folder
1160 | */
1161 | Object.defineProperty(exports, '__esModule', {
1162 | value: true
1163 | });
1164 | exports.createJazzInstance = createJazzInstance;
1165 | exports.getJazzInstance = getJazzInstance;
1166 |
1167 | var _util = require('./util');
1168 |
1169 | require('babelify/node_modules/babel-core/node_modules/core-js/es6/map');
1170 | require('babelify/node_modules/babel-core/node_modules/core-js/es6/set');
1171 | require('babelify/node_modules/babel-core/node_modules/core-js/es6/symbol');
1172 |
1173 | var jazzPluginInitTime = 100; // milliseconds
1174 |
1175 | var jazzInstanceNumber = 0;
1176 | var jazzInstances = new Map();
1177 |
1178 | function createJazzInstance(callback) {
1179 |
1180 | var id = 'jazz_' + jazzInstanceNumber++ + '' + Date.now();
1181 | var instance = undefined;
1182 | var objRef = undefined,
1183 | activeX = undefined;
1184 |
1185 | if ((0, _util.getDevice)().nodejs === true) {
1186 | objRef = new jazzMidi.MIDI();
1187 | } else {
1188 | var o1 = document.createElement('object');
1189 | o1.id = id + 'ie';
1190 | o1.classid = 'CLSID:1ACE1618-1C7D-4561-AEE1-34842AA85E90';
1191 | activeX = o1;
1192 |
1193 | var o2 = document.createElement('object');
1194 | o2.id = id;
1195 | o2.type = 'audio/x-jazz';
1196 | o1.appendChild(o2);
1197 | objRef = o2;
1198 |
1199 | var e = document.createElement('p');
1200 | e.appendChild(document.createTextNode('This page requires the '));
1201 |
1202 | var a = document.createElement('a');
1203 | a.appendChild(document.createTextNode('Jazz plugin'));
1204 | a.href = 'http://jazz-soft.net/';
1205 |
1206 | e.appendChild(a);
1207 | e.appendChild(document.createTextNode('.'));
1208 | o2.appendChild(e);
1209 |
1210 | var insertionPoint = document.getElementById('MIDIPlugin');
1211 | if (!insertionPoint) {
1212 | // Create hidden element
1213 | insertionPoint = document.createElement('div');
1214 | insertionPoint.id = 'MIDIPlugin';
1215 | insertionPoint.style.position = 'absolute';
1216 | insertionPoint.style.visibility = 'hidden';
1217 | insertionPoint.style.left = '-9999px';
1218 | insertionPoint.style.top = '-9999px';
1219 | document.body.appendChild(insertionPoint);
1220 | }
1221 | insertionPoint.appendChild(o1);
1222 | }
1223 |
1224 | setTimeout(function () {
1225 | if (objRef.isJazz === true) {
1226 | instance = objRef;
1227 | } else if (activeX.isJazz === true) {
1228 | instance = activeX;
1229 | }
1230 | if (instance !== undefined) {
1231 | instance._perfTimeZero = performance.now();
1232 | jazzInstances.set(id, instance);
1233 | }
1234 | callback(instance);
1235 | }, jazzPluginInitTime);
1236 | }
1237 |
1238 | function getJazzInstance(type, callback) {
1239 | var instance = null;
1240 | var key = type === 'input' ? 'inputInUse' : 'outputInUse';
1241 |
1242 | var _iteratorNormalCompletion = true;
1243 | var _didIteratorError = false;
1244 | var _iteratorError = undefined;
1245 |
1246 | try {
1247 | for (var _iterator = jazzInstances.values()[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
1248 | var inst = _step.value;
1249 |
1250 | if (inst[key] !== true) {
1251 | instance = inst;
1252 | break;
1253 | }
1254 | }
1255 | } catch (err) {
1256 | _didIteratorError = true;
1257 | _iteratorError = err;
1258 | } finally {
1259 | try {
1260 | if (!_iteratorNormalCompletion && _iterator['return']) {
1261 | _iterator['return']();
1262 | }
1263 | } finally {
1264 | if (_didIteratorError) {
1265 | throw _iteratorError;
1266 | }
1267 | }
1268 | }
1269 |
1270 | if (instance === null) {
1271 | createJazzInstance(callback);
1272 | } else {
1273 | callback(instance);
1274 | }
1275 | }
1276 |
1277 | },{"./util":64,"babelify/node_modules/babel-core/node_modules/core-js/es6/map":1,"babelify/node_modules/babel-core/node_modules/core-js/es6/set":2,"babelify/node_modules/babel-core/node_modules/core-js/es6/symbol":3}],58:[function(require,module,exports){
1278 | /*
1279 | Creates a MIDIAccess instance:
1280 | - Creates MIDIInput and MIDIOutput instances for the initially connected MIDI devices.
1281 | - Keeps track of newly connected devices and creates the necessary instances of MIDIInput and MIDIOutput.
1282 | - Keeps track of disconnected devices and removes them from the inputs and/or outputs map.
1283 | - Creates a unique id for every device and stores these ids by the name of the device:
1284 | so when a device gets disconnected and reconnected again, it will still have the same id. This
1285 | is in line with the behaviour of the native MIDIAccess object.
1286 |
1287 | */
1288 |
1289 | 'use strict';
1290 |
1291 | Object.defineProperty(exports, '__esModule', {
1292 | value: true
1293 | });
1294 |
1295 | var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
1296 |
1297 | exports.createMIDIAccess = createMIDIAccess;
1298 | exports.dispatchEvent = dispatchEvent;
1299 | exports.closeAllMIDIInputs = closeAllMIDIInputs;
1300 | exports.getMIDIDeviceId = getMIDIDeviceId;
1301 |
1302 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
1303 |
1304 | var _jazz_instance = require('./jazz_instance');
1305 |
1306 | var _midi_input = require('./midi_input');
1307 |
1308 | var _midi_output = require('./midi_output');
1309 |
1310 | var _midiconnection_event = require('./midiconnection_event');
1311 |
1312 | var _util = require('./util');
1313 |
1314 | var midiAccess = undefined;
1315 | var jazzInstance = undefined;
1316 | var midiInputs = new Map();
1317 | var midiOutputs = new Map();
1318 | var midiInputIds = new Map();
1319 | var midiOutputIds = new Map();
1320 | var listeners = new Set();
1321 |
1322 | var MIDIAccess = (function () {
1323 | function MIDIAccess(midiInputs, midiOutputs) {
1324 | _classCallCheck(this, MIDIAccess);
1325 |
1326 | this.sysexEnabled = true;
1327 | this.inputs = midiInputs;
1328 | this.outputs = midiOutputs;
1329 | }
1330 |
1331 | _createClass(MIDIAccess, [{
1332 | key: 'addEventListener',
1333 | value: function addEventListener(type, listener, useCapture) {
1334 | if (type !== 'statechange') {
1335 | return;
1336 | }
1337 | if (listeners.has(listener) === false) {
1338 | listeners.add(listener);
1339 | }
1340 | }
1341 | }, {
1342 | key: 'removeEventListener',
1343 | value: function removeEventListener(type, listener, useCapture) {
1344 | if (type !== 'statechange') {
1345 | return;
1346 | }
1347 | if (listeners.has(listener) === true) {
1348 | listeners['delete'](listener);
1349 | }
1350 | }
1351 | }]);
1352 |
1353 | return MIDIAccess;
1354 | })();
1355 |
1356 | function createMIDIAccess() {
1357 |
1358 | return new Promise(function executor(resolve, reject) {
1359 |
1360 | if (midiAccess !== undefined) {
1361 | resolve(midiAccess);
1362 | return;
1363 | }
1364 |
1365 | if ((0, _util.getDevice)().browser === 'ie9') {
1366 | reject({ message: 'WebMIDIAPIShim supports Internet Explorer 10 and above.' });
1367 | return;
1368 | }
1369 |
1370 | (0, _jazz_instance.createJazzInstance)(function (instance) {
1371 | if (instance === undefined) {
1372 | reject({ message: 'No access to MIDI devices: browser does not support the WebMIDI API and the Jazz plugin is not installed.' });
1373 | return;
1374 | }
1375 |
1376 | jazzInstance = instance;
1377 |
1378 | createMIDIPorts(function () {
1379 | setupListeners();
1380 | midiAccess = new MIDIAccess(midiInputs, midiOutputs);
1381 | resolve(midiAccess);
1382 | });
1383 | });
1384 | });
1385 | }
1386 |
1387 | // create MIDIInput and MIDIOutput instances for all initially connected MIDI devices
1388 | function createMIDIPorts(callback) {
1389 | var inputs = jazzInstance.MidiInList();
1390 | var outputs = jazzInstance.MidiOutList();
1391 | var numInputs = inputs.length;
1392 | var numOutputs = outputs.length;
1393 |
1394 | loopCreateMIDIPort(0, numInputs, 'input', inputs, function () {
1395 | loopCreateMIDIPort(0, numOutputs, 'output', outputs, callback);
1396 | });
1397 | }
1398 |
1399 | function loopCreateMIDIPort(index, max, type, list, callback) {
1400 | if (index < max) {
1401 | var _name = list[index++];
1402 | createMIDIPort(type, _name, function () {
1403 | loopCreateMIDIPort(index, max, type, list, callback);
1404 | });
1405 | } else {
1406 | callback();
1407 | }
1408 | }
1409 |
1410 | function createMIDIPort(type, name, callback) {
1411 | (0, _jazz_instance.getJazzInstance)(type, function (instance) {
1412 | var port = undefined;
1413 | var info = [name, '', ''];
1414 | if (type === 'input') {
1415 | if (instance.Support('MidiInInfo')) {
1416 | info = instance.MidiInInfo(name);
1417 | }
1418 | port = new _midi_input.MIDIInput(info, instance);
1419 | midiInputs.set(port.id, port);
1420 | } else if (type === 'output') {
1421 | if (instance.Support('MidiOutInfo')) {
1422 | info = instance.MidiOutInfo(name);
1423 | }
1424 | port = new _midi_output.MIDIOutput(info, instance);
1425 | midiOutputs.set(port.id, port);
1426 | }
1427 | callback(port);
1428 | });
1429 | }
1430 |
1431 | // lookup function: Jazz gives us the name of the connected/disconnected MIDI devices but we have stored them by id
1432 | function getPortByName(ports, name) {
1433 | var port = undefined;
1434 | var _iteratorNormalCompletion = true;
1435 | var _didIteratorError = false;
1436 | var _iteratorError = undefined;
1437 |
1438 | try {
1439 | for (var _iterator = ports.values()[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
1440 | port = _step.value;
1441 |
1442 | if (port.name === name) {
1443 | break;
1444 | }
1445 | }
1446 | } catch (err) {
1447 | _didIteratorError = true;
1448 | _iteratorError = err;
1449 | } finally {
1450 | try {
1451 | if (!_iteratorNormalCompletion && _iterator['return']) {
1452 | _iterator['return']();
1453 | }
1454 | } finally {
1455 | if (_didIteratorError) {
1456 | throw _iteratorError;
1457 | }
1458 | }
1459 | }
1460 |
1461 | return port;
1462 | }
1463 |
1464 | // keep track of connected/disconnected MIDI devices
1465 | function setupListeners() {
1466 | jazzInstance.OnDisconnectMidiIn(function (name) {
1467 | var port = getPortByName(midiInputs, name);
1468 | if (port !== undefined) {
1469 | port.state = 'disconnected';
1470 | port.close();
1471 | port._jazzInstance.inputInUse = false;
1472 | midiInputs['delete'](port.id);
1473 | dispatchEvent(port);
1474 | }
1475 | });
1476 |
1477 | jazzInstance.OnDisconnectMidiOut(function (name) {
1478 | var port = getPortByName(midiOutputs, name);
1479 | if (port !== undefined) {
1480 | port.state = 'disconnected';
1481 | port.close();
1482 | port._jazzInstance.outputInUse = false;
1483 | midiOutputs['delete'](port.id);
1484 | dispatchEvent(port);
1485 | }
1486 | });
1487 |
1488 | jazzInstance.OnConnectMidiIn(function (name) {
1489 | createMIDIPort('input', name, function (port) {
1490 | dispatchEvent(port);
1491 | });
1492 | });
1493 |
1494 | jazzInstance.OnConnectMidiOut(function (name) {
1495 | createMIDIPort('output', name, function (port) {
1496 | dispatchEvent(port);
1497 | });
1498 | });
1499 | }
1500 |
1501 | // when a device gets connected/disconnected both the port and MIDIAccess dispatch a MIDIConnectionEvent
1502 | // therefor we call the ports dispatchEvent function here as well
1503 |
1504 | function dispatchEvent(port) {
1505 | port.dispatchEvent(new _midiconnection_event.MIDIConnectionEvent(port, port));
1506 |
1507 | var evt = new _midiconnection_event.MIDIConnectionEvent(midiAccess, port);
1508 |
1509 | if (typeof midiAccess.onstatechange === 'function') {
1510 | midiAccess.onstatechange(evt);
1511 | }
1512 | var _iteratorNormalCompletion2 = true;
1513 | var _didIteratorError2 = false;
1514 | var _iteratorError2 = undefined;
1515 |
1516 | try {
1517 | for (var _iterator2 = listeners[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
1518 | var listener = _step2.value;
1519 |
1520 | listener(evt);
1521 | }
1522 | } catch (err) {
1523 | _didIteratorError2 = true;
1524 | _iteratorError2 = err;
1525 | } finally {
1526 | try {
1527 | if (!_iteratorNormalCompletion2 && _iterator2['return']) {
1528 | _iterator2['return']();
1529 | }
1530 | } finally {
1531 | if (_didIteratorError2) {
1532 | throw _iteratorError2;
1533 | }
1534 | }
1535 | }
1536 | }
1537 |
1538 | function closeAllMIDIInputs() {
1539 | midiInputs.forEach(function (input) {
1540 | //input.close();
1541 | input._jazzInstance.MidiInClose();
1542 | });
1543 | }
1544 |
1545 | // check if we have already created a unique id for this device, if so: reuse it, if not: create a new id and store it
1546 |
1547 | function getMIDIDeviceId(name, type) {
1548 | var id = undefined;
1549 | if (type === 'input') {
1550 | id = midiInputIds.get(name);
1551 | if (id === undefined) {
1552 | id = (0, _util.generateUUID)();
1553 | midiInputIds.set(name, id);
1554 | }
1555 | } else if (type === 'output') {
1556 | id = midiOutputIds.get(name);
1557 | if (id === undefined) {
1558 | id = (0, _util.generateUUID)();
1559 | midiOutputIds.set(name, id);
1560 | }
1561 | }
1562 | return id;
1563 | }
1564 |
1565 | },{"./jazz_instance":57,"./midi_input":59,"./midi_output":60,"./midiconnection_event":61,"./util":64}],59:[function(require,module,exports){
1566 | /*
1567 | MIDIInput is a wrapper around an input of a Jazz instance
1568 | */
1569 |
1570 | 'use strict';
1571 |
1572 | Object.defineProperty(exports, '__esModule', {
1573 | value: true
1574 | });
1575 |
1576 | var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
1577 |
1578 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
1579 |
1580 | var _util = require('./util');
1581 |
1582 | var _midimessage_event = require('./midimessage_event');
1583 |
1584 | var _midiconnection_event = require('./midiconnection_event');
1585 |
1586 | var _midi_access = require('./midi_access');
1587 |
1588 | var midiProc = undefined;
1589 | var nodejs = (0, _util.getDevice)().nodejs;
1590 |
1591 | var MIDIInput = (function () {
1592 | function MIDIInput(info, instance) {
1593 | _classCallCheck(this, MIDIInput);
1594 |
1595 | this.id = (0, _midi_access.getMIDIDeviceId)(info[0], 'input');
1596 | this.name = info[0];
1597 | this.manufacturer = info[1];
1598 | this.version = info[2];
1599 | this.type = 'input';
1600 | this.state = 'connected';
1601 | this.connection = 'pending';
1602 |
1603 | this.onstatechange = null;
1604 | this._onmidimessage = null;
1605 | // because we need to implicitly open the device when an onmidimessage handler gets added
1606 | // we define a setter that opens the device if the set value is a function
1607 | Object.defineProperty(this, 'onmidimessage', {
1608 | set: function set(value) {
1609 | this._onmidimessage = value;
1610 | if (typeof value === 'function') {
1611 | this.open();
1612 | }
1613 | }
1614 | });
1615 |
1616 | this._listeners = new Map().set('midimessage', new Set()).set('statechange', new Set());
1617 | this._inLongSysexMessage = false;
1618 | this._sysexBuffer = new Uint8Array();
1619 |
1620 | this._jazzInstance = instance;
1621 | this._jazzInstance.inputInUse = true;
1622 |
1623 | // on Linux opening and closing Jazz instances causes the plugin to crash a lot so we open
1624 | // the device here and don't close it when close() is called, see below
1625 | if ((0, _util.getDevice)().platform === 'linux') {
1626 | this._jazzInstance.MidiInOpen(this.name, midiProc.bind(this));
1627 | }
1628 | }
1629 |
1630 | _createClass(MIDIInput, [{
1631 | key: 'addEventListener',
1632 | value: function addEventListener(type, listener, useCapture) {
1633 | var listeners = this._listeners.get(type);
1634 | if (listeners === undefined) {
1635 | return;
1636 | }
1637 |
1638 | if (listeners.has(listener) === false) {
1639 | listeners.add(listener);
1640 | }
1641 | }
1642 | }, {
1643 | key: 'removeEventListener',
1644 | value: function removeEventListener(type, listener, useCapture) {
1645 | var listeners = this._listeners.get(type);
1646 | if (listeners === undefined) {
1647 | return;
1648 | }
1649 |
1650 | if (listeners.has(listener) === false) {
1651 | listeners['delete'](listener);
1652 | }
1653 | }
1654 | }, {
1655 | key: 'dispatchEvent',
1656 | value: function dispatchEvent(evt) {
1657 | var listeners = this._listeners.get(evt.type);
1658 | listeners.forEach(function (listener) {
1659 | listener(evt);
1660 | });
1661 |
1662 | if (evt.type === 'midimessage') {
1663 | if (this._onmidimessage !== null) {
1664 | this._onmidimessage(evt);
1665 | }
1666 | } else if (evt.type === 'statechange') {
1667 | if (this.onstatechange !== null) {
1668 | this.onstatechange(evt);
1669 | }
1670 | }
1671 | }
1672 | }, {
1673 | key: 'open',
1674 | value: function open() {
1675 | if (this.connection === 'open') {
1676 | return;
1677 | }
1678 | if ((0, _util.getDevice)().platform !== 'linux') {
1679 | this._jazzInstance.MidiInOpen(this.name, midiProc.bind(this));
1680 | }
1681 | this.connection = 'open';
1682 | (0, _midi_access.dispatchEvent)(this); // dispatch MIDIConnectionEvent via MIDIAccess
1683 | }
1684 | }, {
1685 | key: 'close',
1686 | value: function close() {
1687 | if (this.connection === 'closed') {
1688 | return;
1689 | }
1690 | if ((0, _util.getDevice)().platform !== 'linux') {
1691 | this._jazzInstance.MidiInClose();
1692 | }
1693 | this.connection = 'closed';
1694 | (0, _midi_access.dispatchEvent)(this); // dispatch MIDIConnectionEvent via MIDIAccess
1695 | this._onmidimessage = null;
1696 | this.onstatechange = null;
1697 | this._listeners.get('midimessage').clear();
1698 | this._listeners.get('statechange').clear();
1699 | }
1700 | }, {
1701 | key: '_appendToSysexBuffer',
1702 | value: function _appendToSysexBuffer(data) {
1703 | var oldLength = this._sysexBuffer.length;
1704 | var tmpBuffer = new Uint8Array(oldLength + data.length);
1705 | tmpBuffer.set(this._sysexBuffer);
1706 | tmpBuffer.set(data, oldLength);
1707 | this._sysexBuffer = tmpBuffer;
1708 | }
1709 | }, {
1710 | key: '_bufferLongSysex',
1711 | value: function _bufferLongSysex(data, initialOffset) {
1712 | var j = initialOffset;
1713 | while (j < data.length) {
1714 | if (data[j] == 0xF7) {
1715 | // end of sysex!
1716 | j++;
1717 | this._appendToSysexBuffer(data.slice(initialOffset, j));
1718 | return j;
1719 | }
1720 | j++;
1721 | }
1722 | // didn't reach the end; just tack it on.
1723 | this._appendToSysexBuffer(data.slice(initialOffset, j));
1724 | this._inLongSysexMessage = true;
1725 | return j;
1726 | }
1727 | }]);
1728 |
1729 | return MIDIInput;
1730 | })();
1731 |
1732 | exports.MIDIInput = MIDIInput;
1733 |
1734 | midiProc = function (timestamp, data) {
1735 | var length = 0;
1736 | var i = undefined;
1737 | var isSysexMessage = false;
1738 |
1739 | // Jazz sometimes passes us multiple messages at once, so we need to parse them out and pass them one at a time.
1740 |
1741 | for (i = 0; i < data.length; i += length) {
1742 | var isValidMessage = true;
1743 | if (this._inLongSysexMessage) {
1744 | i = this._bufferLongSysex(data, i);
1745 | if (data[i - 1] != 0xf7) {
1746 | // ran off the end without hitting the end of the sysex message
1747 | return;
1748 | }
1749 | isSysexMessage = true;
1750 | } else {
1751 | isSysexMessage = false;
1752 | switch (data[i] & 0xF0) {
1753 | case 0x00:
1754 | // Chew up spurious 0x00 bytes. Fixes a Windows problem.
1755 | length = 1;
1756 | isValidMessage = false;
1757 | break;
1758 |
1759 | case 0x80: // note off
1760 | case 0x90: // note on
1761 | case 0xA0: // polyphonic aftertouch
1762 | case 0xB0: // control change
1763 | case 0xE0:
1764 | // channel mode
1765 | length = 3;
1766 | break;
1767 |
1768 | case 0xC0: // program change
1769 | case 0xD0:
1770 | // channel aftertouch
1771 | length = 2;
1772 | break;
1773 |
1774 | case 0xF0:
1775 | switch (data[i]) {
1776 | case 0xf0:
1777 | // letiable-length sysex.
1778 | i = this._bufferLongSysex(data, i);
1779 | if (data[i - 1] != 0xf7) {
1780 | // ran off the end without hitting the end of the sysex message
1781 | return;
1782 | }
1783 | isSysexMessage = true;
1784 | break;
1785 |
1786 | case 0xF1: // MTC quarter frame
1787 | case 0xF3:
1788 | // song select
1789 | length = 2;
1790 | break;
1791 |
1792 | case 0xF2:
1793 | // song position pointer
1794 | length = 3;
1795 | break;
1796 |
1797 | default:
1798 | length = 1;
1799 | break;
1800 | }
1801 | break;
1802 | }
1803 | }
1804 | if (!isValidMessage) {
1805 | continue;
1806 | }
1807 |
1808 | var evt = {};
1809 | evt.receivedTime = parseFloat(timestamp.toString()) + this._jazzInstance._perfTimeZero;
1810 |
1811 | if (isSysexMessage || this._inLongSysexMessage) {
1812 | evt.data = new Uint8Array(this._sysexBuffer);
1813 | this._sysexBuffer = new Uint8Array(0);
1814 | this._inLongSysexMessage = false;
1815 | } else {
1816 | evt.data = new Uint8Array(data.slice(i, length + i));
1817 | }
1818 |
1819 | if (nodejs) {
1820 | if (this._onmidimessage) {
1821 | this._onmidimessage(evt);
1822 | }
1823 | } else {
1824 | var e = new _midimessage_event.MIDIMessageEvent(this, evt.data, evt.receivedTime);
1825 | this.dispatchEvent(e);
1826 | }
1827 | }
1828 | };
1829 |
1830 | },{"./midi_access":58,"./midiconnection_event":61,"./midimessage_event":62,"./util":64}],60:[function(require,module,exports){
1831 | /*
1832 | MIDIOutput is a wrapper around an output of a Jazz instance
1833 | */
1834 |
1835 | 'use strict';
1836 |
1837 | Object.defineProperty(exports, '__esModule', {
1838 | value: true
1839 | });
1840 |
1841 | var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
1842 |
1843 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
1844 |
1845 | var _util = require('./util');
1846 |
1847 | var _midi_access = require('./midi_access');
1848 |
1849 | var MIDIOutput = (function () {
1850 | function MIDIOutput(info, instance) {
1851 | _classCallCheck(this, MIDIOutput);
1852 |
1853 | this.id = (0, _midi_access.getMIDIDeviceId)(info[0], 'output');
1854 | this.name = info[0];
1855 | this.manufacturer = info[1];
1856 | this.version = info[2];
1857 | this.type = 'output';
1858 | this.state = 'connected';
1859 | this.connection = 'pending';
1860 | this.onmidimessage = null;
1861 | this.onstatechange = null;
1862 |
1863 | this._listeners = new Set();
1864 | this._inLongSysexMessage = false;
1865 | this._sysexBuffer = new Uint8Array();
1866 |
1867 | this._jazzInstance = instance;
1868 | this._jazzInstance.outputInUse = true;
1869 | if ((0, _util.getDevice)().platform === 'linux') {
1870 | this._jazzInstance.MidiOutOpen(this.name);
1871 | }
1872 | }
1873 |
1874 | _createClass(MIDIOutput, [{
1875 | key: 'open',
1876 | value: function open() {
1877 | if (this.connection === 'open') {
1878 | return;
1879 | }
1880 | if ((0, _util.getDevice)().platform !== 'linux') {
1881 | this._jazzInstance.MidiOutOpen(this.name);
1882 | }
1883 | this.connection = 'open';
1884 | (0, _midi_access.dispatchEvent)(this); // dispatch MIDIConnectionEvent via MIDIAccess
1885 | }
1886 | }, {
1887 | key: 'close',
1888 | value: function close() {
1889 | if (this.connection === 'closed') {
1890 | return;
1891 | }
1892 | if ((0, _util.getDevice)().platform !== 'linux') {
1893 | this._jazzInstance.MidiOutClose();
1894 | }
1895 | this.connection = 'closed';
1896 | (0, _midi_access.dispatchEvent)(this); // dispatch MIDIConnectionEvent via MIDIAccess
1897 | this.onstatechange = null;
1898 | this._listeners.clear();
1899 | }
1900 | }, {
1901 | key: 'send',
1902 | value: function send(data, timestamp) {
1903 | var _this = this;
1904 |
1905 | var delayBeforeSend = 0;
1906 |
1907 | if (data.length === 0) {
1908 | return false;
1909 | }
1910 |
1911 | if (timestamp) {
1912 | delayBeforeSend = Math.floor(timestamp - performance.now());
1913 | }
1914 |
1915 | if (timestamp && delayBeforeSend > 1) {
1916 | setTimeout(function () {
1917 | _this._jazzInstance.MidiOutLong(data);
1918 | }, delayBeforeSend);
1919 | } else {
1920 | this._jazzInstance.MidiOutLong(data);
1921 | }
1922 | return true;
1923 | }
1924 | }, {
1925 | key: 'clear',
1926 | value: function clear() {
1927 | // to be implemented
1928 | }
1929 | }, {
1930 | key: 'addEventListener',
1931 | value: function addEventListener(type, listener, useCapture) {
1932 | if (type !== 'statechange') {
1933 | return;
1934 | }
1935 |
1936 | if (this._listeners.has(listener) === false) {
1937 | this._listeners.add(listener);
1938 | }
1939 | }
1940 | }, {
1941 | key: 'removeEventListener',
1942 | value: function removeEventListener(type, listener, useCapture) {
1943 | if (type !== 'statechange') {
1944 | return;
1945 | }
1946 |
1947 | if (this._listeners.has(listener) === false) {
1948 | this._listeners['delete'](listener);
1949 | }
1950 | }
1951 | }, {
1952 | key: 'dispatchEvent',
1953 | value: function dispatchEvent(evt) {
1954 | this._listeners.forEach(function (listener) {
1955 | listener(evt);
1956 | });
1957 |
1958 | if (this.onstatechange !== null) {
1959 | this.onstatechange(evt);
1960 | }
1961 | }
1962 | }]);
1963 |
1964 | return MIDIOutput;
1965 | })();
1966 |
1967 | exports.MIDIOutput = MIDIOutput;
1968 |
1969 | },{"./midi_access":58,"./util":64}],61:[function(require,module,exports){
1970 | 'use strict';
1971 |
1972 | Object.defineProperty(exports, '__esModule', {
1973 | value: true
1974 | });
1975 |
1976 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
1977 |
1978 | var MIDIConnectionEvent = function MIDIConnectionEvent(midiAccess, port) {
1979 | _classCallCheck(this, MIDIConnectionEvent);
1980 |
1981 | this.bubbles = false;
1982 | this.cancelBubble = false;
1983 | this.cancelable = false;
1984 | this.currentTarget = midiAccess;
1985 | this.defaultPrevented = false;
1986 | this.eventPhase = 0;
1987 | this.path = [];
1988 | this.port = port;
1989 | this.returnValue = true;
1990 | this.srcElement = midiAccess;
1991 | this.target = midiAccess;
1992 | this.timeStamp = Date.now();
1993 | this.type = 'statechange';
1994 | };
1995 |
1996 | exports.MIDIConnectionEvent = MIDIConnectionEvent;
1997 |
1998 | },{}],62:[function(require,module,exports){
1999 | 'use strict';
2000 |
2001 | Object.defineProperty(exports, '__esModule', {
2002 | value: true
2003 | });
2004 |
2005 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
2006 |
2007 | var MIDIMessageEvent = function MIDIMessageEvent(port, data, receivedTime) {
2008 | _classCallCheck(this, MIDIMessageEvent);
2009 |
2010 | this.bubbles = false;
2011 | this.cancelBubble = false;
2012 | this.cancelable = false;
2013 | this.currentTarget = port;
2014 | this.data = data;
2015 | this.defaultPrevented = false;
2016 | this.eventPhase = 0;
2017 | this.path = [];
2018 | this.receivedTime = receivedTime;
2019 | this.returnValue = true;
2020 | this.srcElement = port;
2021 | this.target = port;
2022 | this.timeStamp = Date.now();
2023 | this.type = 'midimessage';
2024 | };
2025 |
2026 | exports.MIDIMessageEvent = MIDIMessageEvent;
2027 |
2028 | },{}],63:[function(require,module,exports){
2029 | /*
2030 | Top entry point
2031 | */
2032 |
2033 | 'use strict';
2034 |
2035 | var _midi_access = require('./midi_access');
2036 |
2037 | var _util = require('./util');
2038 |
2039 | var midiAccess = undefined;
2040 |
2041 | (function () {
2042 | if (!navigator.requestMIDIAccess) {
2043 | (0, _util.polyfill)();
2044 | navigator.requestMIDIAccess = function () {
2045 | // singleton-ish, no need to create multiple instances of MIDIAccess
2046 | if (midiAccess === undefined) {
2047 | midiAccess = (0, _midi_access.createMIDIAccess)();
2048 | }
2049 | return midiAccess;
2050 | };
2051 | if ((0, _util.getDevice)().nodejs === true) {
2052 | navigator.close = function () {
2053 | // Need to close MIDI input ports, otherwise Node.js will wait for MIDI input forever.
2054 | (0, _midi_access.closeAllMIDIInputs)();
2055 | };
2056 | }
2057 | }
2058 | })();
2059 |
2060 | },{"./midi_access":58,"./util":64}],64:[function(require,module,exports){
2061 | (function (process,global){
2062 | /*
2063 | A collection of handy util methods
2064 | */
2065 |
2066 | 'use strict';
2067 |
2068 | Object.defineProperty(exports, '__esModule', {
2069 | value: true
2070 | });
2071 | exports.getDevice = getDevice;
2072 | exports.polyfillPerformance = polyfillPerformance;
2073 | exports.generateUUID = generateUUID;
2074 | exports.polyfillPromise = polyfillPromise;
2075 | exports.polyfill = polyfill;
2076 | var device = undefined;
2077 |
2078 | // check on what type of device we are running, note that in this context a device is a computer not a MIDI device
2079 |
2080 | function getDevice() {
2081 |
2082 | if (device !== undefined) {
2083 | return device;
2084 | }
2085 |
2086 | var platform = 'undetected',
2087 | browser = 'undetected',
2088 | nodejs = false;
2089 |
2090 | if (navigator.nodejs) {
2091 | platform = process.platform;
2092 | device = {
2093 | platform: platform,
2094 | nodejs: true,
2095 | mobile: platform === 'ios' || platform === 'android'
2096 | };
2097 | return device;
2098 | }
2099 |
2100 | var ua = navigator.userAgent;
2101 |
2102 | if (ua.match(/(iPad|iPhone|iPod)/g)) {
2103 | platform = 'ios';
2104 | } else if (ua.indexOf('Android') !== -1) {
2105 | platform = 'android';
2106 | } else if (ua.indexOf('Linux') !== -1) {
2107 | platform = 'linux';
2108 | } else if (ua.indexOf('Macintosh') !== -1) {
2109 | platform = 'osx';
2110 | } else if (ua.indexOf('Windows') !== -1) {
2111 | platform = 'windows';
2112 | }
2113 |
2114 | if (ua.indexOf('Chrome') !== -1) {
2115 | // chrome, chromium and canary
2116 | browser = 'chrome';
2117 |
2118 | if (ua.indexOf('OPR') !== -1) {
2119 | browser = 'opera';
2120 | } else if (ua.indexOf('Chromium') !== -1) {
2121 | browser = 'chromium';
2122 | }
2123 | } else if (ua.indexOf('Safari') !== -1) {
2124 | browser = 'safari';
2125 | } else if (ua.indexOf('Firefox') !== -1) {
2126 | browser = 'firefox';
2127 | } else if (ua.indexOf('Trident') !== -1) {
2128 | browser = 'ie';
2129 | if (ua.indexOf('MSIE 9') !== -1) {
2130 | browser = 'ie9';
2131 | }
2132 | }
2133 |
2134 | if (platform === 'ios') {
2135 | if (ua.indexOf('CriOS') !== -1) {
2136 | browser = 'chrome';
2137 | }
2138 | }
2139 |
2140 | device = {
2141 | platform: platform,
2142 | browser: browser,
2143 | mobile: platform === 'ios' || platform === 'android',
2144 | nodejs: false
2145 | };
2146 | return device;
2147 | }
2148 |
2149 | function polyfillPerformance() {
2150 | if (performance === undefined) {
2151 | performance = {};
2152 | }
2153 | Date.now = Date.now || function () {
2154 | return new Date().getTime();
2155 | };
2156 |
2157 | if (performance.now === undefined) {
2158 | (function () {
2159 | var nowOffset = Date.now();
2160 | if (performance.timing !== undefined && performance.timing.navigationStart !== undefined) {
2161 | nowOffset = performance.timing.navigationStart;
2162 | }
2163 | performance.now = function now() {
2164 | return Date.now() - nowOffset;
2165 | };
2166 | })();
2167 | }
2168 | }
2169 |
2170 | function generateUUID() {
2171 | var d = new Date().getTime();
2172 | var uuid = new Array(64).join('x');; //'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx';
2173 | uuid = uuid.replace(/[xy]/g, function (c) {
2174 | var r = (d + Math.random() * 16) % 16 | 0;
2175 | d = Math.floor(d / 16);
2176 | return (c == 'x' ? r : r & 0x3 | 0x8).toString(16).toUpperCase();
2177 | });
2178 | return uuid;
2179 | }
2180 |
2181 | // a very simple implementation of a Promise for Internet Explorer and Nodejs
2182 |
2183 | function polyfillPromise(scope) {
2184 | if (typeof scope.Promise !== 'function') {
2185 |
2186 | scope.Promise = function (executor) {
2187 | this.executor = executor;
2188 | };
2189 |
2190 | scope.Promise.prototype.then = function (accept, reject) {
2191 | if (typeof accept !== 'function') {
2192 | accept = function () {};
2193 | }
2194 | if (typeof reject !== 'function') {
2195 | reject = function () {};
2196 | }
2197 | this.executor(accept, reject);
2198 | };
2199 | }
2200 | }
2201 |
2202 | function polyfill() {
2203 | var device = getDevice();
2204 | if (device.browser === 'ie') {
2205 | polyfillPromise(window);
2206 | } else if (device.nodejs === true) {
2207 | polyfillPromise(global);
2208 | }
2209 | polyfillPerformance();
2210 | }
2211 |
2212 | }).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
2213 |
2214 | },{"_process":56}]},{},[63])
2215 |
--------------------------------------------------------------------------------