From 671cb8b61af37e7a9e72f1727e9aee86cb8eb9d1 Mon Sep 17 00:00:00 2001 From: Michael Deal Date: Wed, 23 Jan 2013 00:46:35 -0800 Subject: [PATCH] add Web MIDI Shim by Chris Wilson --- inc/WebMIDIAPI.js | 418 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 418 insertions(+) create mode 100644 inc/WebMIDIAPI.js diff --git a/inc/WebMIDIAPI.js b/inc/WebMIDIAPI.js new file mode 100644 index 0000000..25e70a7 --- /dev/null +++ b/inc/WebMIDIAPI.js @@ -0,0 +1,418 @@ +/// http://cwilso.github.com/WebMIDIAPIShim + +// Initialize the MIDI library. +(function (global, exports, perf) { + 'use strict'; + var midiIO, + debug = false; + if (debug) { + window.console.warn('Debuggin enabled'); + } + +//init: create plugin + if (!window.navigator.requestMIDIAccess) { + window.navigator.requestMIDIAccess = _requestMIDIAccess; + if (!window.navigator.getMIDIAccess) + window.navigator.getMIDIAccess = _getMIDIAccess; + } + + function _JazzInstance() { + this.inputInUse = false; + this.outputInUse = false; + + // load the Jazz plugin + var o1 = document.createElement("object"); + o1.id = "_Jazz" + Math.random() + "ie"; + o1.classid = "CLSID:1ACE1618-1C7D-4561-AEE1-34842AA85E90"; + + this.activeX = o1; + + var o2 = document.createElement("object"); + o2.id = "_Jazz" + Math.random; + o2.type="audio/x-jazz"; + o1.appendChild(o2); + + this.objRef = o2; + + var e = document.createElement("p"); + e.appendChild(document.createTextNode("This page requires the ")); + + var a = document.createElement("a"); + a.appendChild(document.createTextNode("Jazz plugin")); + a.href = "http://jazz-soft.net/"; + + e.appendChild(a); + e.appendChild(document.createTextNode(".")); + o2.appendChild(e); + + var insertionPoint = document.getElementById("MIDIPlugin"); + if (!insertionPoint) + insertionPoint = document.body; + insertionPoint.appendChild(o1); + + if (this.objRef.isJazz) + this._Jazz = this.objRef; + else if (this.activeX.isJazz) + this._Jazz = this.activeX; + else + this._Jazz = null; + if (this._Jazz) { + this._Jazz._jazzTimeZero = this._Jazz.Time(); + this._Jazz._perfTimeZero = window.performance.now(); + } + } + + function _requestMIDIAccess( successCallback, errorCallback ) { + new MIDIAccess( successCallback, errorCallback ); + } + + function _getMIDIAccess( successCallback, errorCallback ) { + var message = "getMIDIAccess has been renamed to requestMIDIAccess. Please update your code."; + + if (console.warn) + console.warn( message ); + else + console.log( message ); + new MIDIAccess( successCallback, errorCallback ); + } + + // API Methods + + function MIDIAccess( successCallback, errorCallback ) { + this._jazzInstances = new Array(); + this._jazzInstances.push( new _JazzInstance() ); + + if (this._jazzInstances[0]._Jazz) { + this._Jazz = this._jazzInstances[0]._Jazz; + this._successCallback = successCallback; + window.setTimeout( _onReady.bind(this), 3 ); + } else { + if (errorCallback) + errorCallback( { code: 1 } ); + } + } + + function _onReady() { + if (this._successCallback) + this._successCallback( this ); + } + + MIDIAccess.prototype.getInputs = function( ) { + if (!this._Jazz) + return null; + var list=this._Jazz.MidiInList(); + var inputs = new Array( list.length ); + + for ( var i=0; i1)) { + var sendObj = new Object; + sendObj.jazz = this._jazzInstance; + sendObj.data = data; + + window.setTimeout( _sendLater.bind(sendObj), delayBeforeSend ); + } else { + this._jazzInstance.MidiOutLong( data ); + } + return true; + } + +}(window)); + +// Polyfill window.performance.now() if necessary. +(function (exports) { + var perf = {}, + props; + + function findAlt() { + var prefix = "moz,webkit,opera,ms".split(","), + i = prefix.length, + //worst case, we use Date.now() + props = { + value: function (start) { + return function () { + return Date.now() - start; + } + }(Date.now()) + }; + + //seach for vendor prefixed version + for (; i >= 0; i--) { + if ((prefix[i] + "Now") in exports.performance) { + props.value = function (method) { + return function () { + exports.performance[method](); + } + }(prefix[i] + "Now"); + return props; + } + } + + //otherwise, try to use connectionStart + if ("timing" in exports.performance && + "connectStart" in exports.performance.timing) { + //this pretty much approximates performance.now() to the millisecond + props.value = function (start) { + return function(){Date.now() - start;} + }(exports.performance.timing.connectStart); + } + return props; + } + + //if already defined, bail + if (("performance" in exports) && ("now" in exports.performance)) { + return; + } + if (!("performance" in exports)) { + Object.defineProperty(exports, "performance", { + get: function () { + return perf; + } + }); + //otherwise, perforance is there, but not "now()" + } + props = findAlt(); + Object.defineProperty(exports.performance, "now", props); +}(window)); + + +