Created
December 12, 2012 23:57
-
-
Save marcoscaceres/4272845 to your computer and use it in GitHub Desktop.
Rewrite of Chris' implementation of Web MIDI API.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(function(exports, global, perf) { | |
'use strict'; | |
var jazzInstances = []; | |
if ('getMIDIAccess' in exports) { | |
return; // namespace is taken already, bail! | |
} | |
exports.getMIDIAccess = getMIDIAccess; | |
function getMIDIAccess(successCallback, errorCallback) { | |
if (typeof successCallback !== 'function') { | |
throw new TypeError('expected function'); | |
} | |
new MIDIAccess(successCallback, errorCallback); | |
} | |
//creates instances of the Jazz plugin (http://jazz-soft.net/) | |
function JazzInstance() { | |
if (!this instanceof JazzInstance) { | |
return new JazzInstance(); | |
} | |
var jazz = loadPlugin(), | |
timeZero = 0, | |
perfTimeZero = perf.now(), | |
interfaces = { | |
timeZero: { | |
get: function() { | |
return timeZero; | |
} | |
}, | |
perfTimeZero: { | |
get: function() { | |
return perfTimeZero; | |
} | |
}, | |
time: { | |
get: function() { | |
return jazz.Time(); | |
} | |
} | |
}; | |
//loads the Jazz plugin by creating an <object> | |
function loadPlugin(id, classid) { | |
var plugin, | |
msg = 'Failed to initialize. Maybe missing Jazz plugin? http://jazz-soft.net/', | |
elemId = '_Jazz' + Math.random(), | |
objElem = document.createElement('object'), | |
fallbackObj = objElem.cloneNode(); | |
objElem.id = elemId + 'ie'; | |
objElem.classid = 'CLSID:1ACE1618-1C7D-4561-AEE1-34842AA85E90'; | |
fallbackObj.id = elemId; | |
fallbackObj.type = 'audio/x-jazz'; | |
objElem.appendChild(fallbackObj); | |
document.documentElement.appendChild(objElem); | |
plugin = (fallbackObj.isJazz === true) ? fallbackObj : objElem; | |
if (!plugin instanceof window.HTMLObjectElement || !(plugin.isJazz)) { | |
window.console.error(msg); | |
return null; | |
} | |
return plugin; | |
} | |
Object.defineProperties(this, interfaces); | |
jazzInstances.push(jazz); | |
} | |
/** | |
interface MIDIPort : EventListener { | |
readonly attribute DOMString id; | |
readonly attribute DOMString? manufacturer; | |
readonly attribute DOMString? name; | |
readonly attribute MIDIPortType type; | |
readonly attribute DOMString? version; | |
attribute EventHandler onmessage; | |
} | |
*/ | |
function MIDIPort(jazz, type) { | |
var dispatcher = document.createElement('x-eventDispatcher'), | |
id, | |
manufacturer = null, | |
version = null, | |
interfaces = { | |
id: { | |
get: function() { | |
return id; | |
} | |
}, | |
type: { | |
get: function() { | |
return type; | |
} | |
}, | |
version: { | |
get: function() { | |
return version; | |
} | |
}, | |
//EventListener | |
addEventListener: { | |
value: function(type, listener, useCapture) { | |
dispatcher.addEventListener(type, listener, useCapture); | |
} | |
}, | |
removeEventListener: { | |
value: function(type, listener, useCapture) { | |
dispatcher.removeEventListener(type, listener, useCapture); | |
} | |
}, | |
dispatchEvent: { | |
value: function(evt) { | |
dispatcher.dispatchEvent(evt); | |
} | |
} | |
}; | |
Object.defineProperties(this, interfaces); | |
} | |
function MIDIAccess(successCallback, errorCallback) { | |
var jazz = new JazzInstance(), | |
interfaces = { | |
enumerateInputs: { | |
value: function() { | |
return enumerateList(this, jazz, 'input'); | |
} | |
}, | |
enumerateOutputs: { | |
value: function() { | |
return enumerateList(this, jazz, 'output'); | |
} | |
}, | |
getInput: { | |
value: function(target) { | |
return getInput(this, target); | |
} | |
}, | |
getOutput: { | |
value: function(target) { | |
getOutput(this, target); | |
} | |
}, | |
toString: { | |
value: function() { | |
toString.call(this); | |
} | |
}, | |
send: { | |
value: function(data, timestamp) { | |
send(data, timestamp, jazz); | |
} | |
} | |
}; | |
Object.defineProperties(this, interfaces); | |
function enumerateList(midiAccess, jazz, list, type) { | |
for (var items = [], i = 0, l = list.length; i < l; i++) { | |
items[i] = new MIDIPort(midiAccess, list[i], i, type); | |
} | |
return items; | |
} | |
function getInput(midiAccess, target) { | |
return (!! target) ? null : new MIDIInput(midiAccess, target); | |
} | |
function getOutput(midiAccess, target) { | |
return (!! target) ? null : new MIDIOutput(midiAccess, target); | |
} | |
function toString(midiAccess) { | |
var info = 'type: ' + midiAccess.type + "name: '" + midiAccess.name + "' manufacturer: '" + midiAccess.manufacturer + "' version: " + midiAccess.version + " fingerprint: '" + midiAccess.fingerprint + "'"; | |
return info; | |
} | |
function mideProc(jazz, timestamp, data) { | |
var evt = new global.CustomEvent('message'), | |
t = timestamp - jazz._timeZero; | |
evt.timestamp = parseFloat(timestamp.toString()) + jazz.perfTimeZero; | |
evt.data = new Uint8Array(data); | |
dispatcher.dispatchEvent(evt); | |
} | |
function send(data, timestamp, jazz) { | |
var delayBeforeSend = (timestamp) ? Math.floor(timestamp - perf.now()) : 0; | |
if (!! (data) || data.length === 0) { | |
return false; | |
} | |
if (timestamp && (delayBeforeSend > 1)) { | |
window.setTimeout(send(data, timestamp, jazz), delayBeforeSend); | |
} else { | |
jazz.MidiOutLong(data); | |
} | |
return true; | |
} | |
} | |
}(window, window.navigator, window.performance)); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment