update to latest libraries

This commit is contained in:
Michael Deal 2012-10-09 22:59:04 -07:00
parent 61f1a05ebe
commit eb21d1f743
31 changed files with 2935 additions and 1227 deletions

282
js/MIDI/Player.js Normal file
View file

@ -0,0 +1,282 @@
/*
MIDI.Player : 0.3
-------------------------------------
https://github.com/mudcube/MIDI.js
-------------------------------------
requires jasmid
*/
if (typeof (MIDI) === "undefined") var MIDI = {};
if (typeof (MIDI.Player) === "undefined") MIDI.Player = {};
(function() { "use strict";
var root = MIDI.Player;
root.callback = undefined; // your custom callback goes here!
root.currentTime = 0;
root.endTime = 0;
root.restart = 0;
root.playing = false;
root.timeWarp = 1;
//
root.start =
root.resume = function () {
if (root.currentTime < -1) root.currentTime = -1;
startAudio(root.currentTime);
};
root.pause = function () {
var tmp = root.restart;
stopAudio();
root.restart = tmp;
};
root.stop = function () {
stopAudio();
root.restart = 0;
root.currentTime = 0;
};
root.addListener = function(callback) {
onMidiEvent = callback;
};
root.removeListener = function() {
onMidiEvent = undefined;
};
root.clearAnimation = function() {
if (root.interval) {
window.clearInterval(root.interval);
}
};
root.setAnimation = function(config) {
var callback = (typeof(config) === "function") ? config : config.callback;
var interval = config.interval || 30;
var currentTime = 0;
var tOurTime = 0;
var tTheirTime = 0;
//
root.clearAnimation();
root.interval = window.setInterval(function () {
if (root.endTime === 0) return;
if (root.playing) {
currentTime = (tTheirTime === root.currentTime) ? tOurTime - (new Date).getTime() : 0;
if (root.currentTime === 0) {
currentTime = 0;
} else {
currentTime = root.currentTime - currentTime;
}
if (tTheirTime !== root.currentTime) {
tOurTime = (new Date).getTime();
tTheirTime = root.currentTime;
}
} else { // paused
currentTime = root.currentTime;
}
var endTime = root.endTime;
var percent = currentTime / endTime;
var total = currentTime / 1000;
var minutes = total / 60;
var seconds = total - (minutes * 60);
var t1 = minutes * 60 + seconds;
var t2 = (endTime / 1000);
if (t2 - t1 < -1) return;
callback({
now: t1,
end: t2,
events: noteRegistrar
});
}, interval);
};
// helpers
root.loadMidiFile = function() { // reads midi into javascript array of events
root.replayer = new Replayer(MidiFile(root.currentData), root.timeWarp);
root.data = root.replayer.getData();
root.endTime = getLength();
};
root.loadFile = function (file, callback) {
root.stop();
if (file.indexOf("base64,") !== -1) {
var data = window.atob(file.split(",")[1]);
root.currentData = data;
root.loadMidiFile();
if (callback) callback(data);
return;
}
///
var title = file.split(" - ")[1] || file;
document.getElementById("playback-title").innerHTML = title.replace(".mid","");
///
var fetch = new XMLHttpRequest();
fetch.open('GET', file);
fetch.overrideMimeType("text/plain; charset=x-user-defined");
fetch.onreadystatechange = function () {
if (this.readyState === 4 && this.status === 200) {
var t = this.responseText || "";
var ff = [];
var mx = t.length;
var scc = String.fromCharCode;
for (var z = 0; z < mx; z++) {
ff[z] = scc(t.charCodeAt(z) & 255);
}
var data = ff.join("");
root.currentData = data;
root.loadMidiFile();
if (callback) callback(data);
}
};
fetch.send();
};
// Playing the audio
var eventQueue = []; // hold events to be triggered
var queuedTime; //
var startTime = 0; // to measure time elapse
var noteRegistrar = {}; // get event for requested note
var onMidiEvent = undefined; // listener callback
var scheduleTracking = function (channel, note, currentTime, offset, message, velocity) {
var interval = window.setTimeout(function () {
var data = {
channel: channel,
note: note,
now: currentTime,
end: root.endTime,
message: message,
velocity: velocity
};
//
if (message === 128) {
delete noteRegistrar[note];
} else {
noteRegistrar[note] = data;
}
if (onMidiEvent) {
onMidiEvent(data);
}
root.currentTime = currentTime;
if (root.currentTime === queuedTime && queuedTime < root.endTime) { // grab next sequence
startAudio(queuedTime, true);
}
}, currentTime - offset);
return interval;
};
var getContext = function() {
if (MIDI.lang === 'WebAudioAPI') {
return MIDI.Player.ctx;
} else if (!root.ctx) {
root.ctx = { currentTime: 0 };
}
return root.ctx;
};
var getLength = function() {
var data = root.data;
var length = data.length;
var totalTime = 0.5;
for (var n = 0; n < length; n++) {
totalTime += data[n][1];
}
return totalTime;
};
var startAudio = function (currentTime, fromCache) {
if (!root.replayer) return;
if (!fromCache) {
if (typeof (currentTime) === "undefined") currentTime = root.restart;
if (root.playing) stopAudio();
root.playing = true;
root.data = root.replayer.getData();
root.endTime = getLength();
}
var note;
var offset = 0;
var messages = 0;
var data = root.data;
var ctx = getContext();
var length = data.length;
//
queuedTime = 0.5;
startTime = ctx.currentTime;
//
for (var n = 0; n < length && messages < 100; n++) {
queuedTime += data[n][1];
if (queuedTime <= currentTime) {
offset = queuedTime;
continue;
}
currentTime = queuedTime - offset;
var event = data[n][0].event;
if (event.type !== "channel") continue;
var channel = event.channel;
switch (event.subtype) {
case 'noteOn':
if (MIDI.channels[channel].mute) break;
note = event.noteNumber - (root.MIDIOffset || 0);
eventQueue.push({
event: event,
source: MIDI.noteOn(channel, event.noteNumber, event.velocity, currentTime / 1000 + ctx.currentTime),
interval: scheduleTracking(channel, note, queuedTime, offset, 144, event.velocity)
});
messages ++;
break;
case 'noteOff':
if (MIDI.channels[channel].mute) break;
note = event.noteNumber - (root.MIDIOffset || 0);
eventQueue.push({
event: event,
source: MIDI.noteOff(channel, event.noteNumber, currentTime / 1000 + ctx.currentTime),
interval: scheduleTracking(channel, note, queuedTime, offset - 10, 128)
});
break;
default:
break;
}
}
};
var stopAudio = function () {
var ctx = getContext();
root.playing = false;
root.restart += (ctx.currentTime - startTime) * 1000;
// stop the audio, and intervals
while (eventQueue.length) {
var o = eventQueue.pop();
window.clearInterval(o.interval);
if (!o.source) continue; // is not webaudio
if (typeof(o.source) === "number") {
window.clearTimeout(o.source);
} else { // webaudio
var source = o.source;
source.disconnect(0);
source.noteOff(0);
}
}
// run callback to cancel any notes still playing
for (var key in noteRegistrar) {
var o = noteRegistrar[key]
if (noteRegistrar[key].message === 144 && onMidiEvent) {
onMidiEvent({
channel: o.channel,
note: o.note,
now: o.now,
end: o.end,
message: 128,
velocity: o.velocity
});
}
}
// reset noteRegistrar
noteRegistrar = {};
};
})();

486
js/MIDI/Plugin.js Normal file
View file

@ -0,0 +1,486 @@
/*
MIDI.Plugin : 0.3
-------------------------------------
https://github.com/mudx/MIDI.js
-------------------------------------
MIDI.WebAudioAPI
MIDI.Flash
MIDI.HTML5
MIDI.instruments
MIDI.channels
MIDI.keyToNote
MIDI.noteToKey
setMute?
getInstruments?
*/
if (typeof (MIDI) === "undefined") var MIDI = {};
if (typeof (MIDI.Plugin) === "undefined") MIDI.Plugin = {};
(function() { "use strict";
/*
Web Audio API - OGG or MPEG Soundbank
--------------------------------------
https://dvcs.w3.org/hg/audio/raw-file/tip/webaudio/specification.html
*/
if (typeof (MIDI.WebAudioAPI) === "undefined") MIDI.WebAudioAPI = {};
if (window.AudioContext || window.webkitAudioContext) (function () {
var AudioContext = window.AudioContext || window.webkitAudioContext;
var root = MIDI.WebAudioAPI;
var ctx;
var sources = {};
var masterVolume = 1;
var audioBuffers = {};
var audioLoader = function (urlList, index, bufferList, oncomplete) {
var url = urlList[index];
var base64 = MIDI.Soundfont[url].split(",")[1];
var buffer = Base64Binary.decodeArrayBuffer(base64);
ctx.decodeAudioData(buffer, function (buffer) {
var msg = url; while(msg.length < 3) msg += "&nbsp;";
if (typeof(loader) !== "undefined") {
loader.message("Downloading: 100%<br>Processing: "+(index/87 * 100 >> 0)+"%<br>" + msg);
}
buffer.id = url;
bufferList[index] = buffer;
//
if (bufferList.length === urlList.length) {
while (bufferList.length) {
buffer = bufferList.pop();
var nodeId = MIDI.keyToNote[buffer.id];
audioBuffers[nodeId] = buffer;
}
oncomplete();
}
});
};
root.setVolume = function (n) {
masterVolume = n;
};
root.programChange = function (instrument) {
};
root.noteOn = function (channel, note, velocity, delay) {
/// check whether the note exists
if (!audioBuffers[note]) return;
/// convert relative delay to absolute delay
if (delay < ctx.currentTime) delay += ctx.currentTime;
/// crate audio buffer
var source = ctx.createBufferSource();
sources[channel + "" + note] = source;
source.buffer = audioBuffers[note];
source.connect(ctx.destination);
//
var gainNode = ctx.createGainNode();
var value = -0.5 + (velocity / 100) * 2;
var minus = (1 - masterVolume) * 2;
gainNode.connect(ctx.destination);
gainNode.gain.value = Math.max(-1, value - minus);
source.connect(gainNode);
//
// source.playbackRate.value = 2;
///
source.noteOn(delay || 0);
return source;
};
root.chordOn = function (channel, chord, velocity, delay) {
var ret = {}, note;
for (var n = 0, length = chord.length; n < length; n ++) {
ret[note = chord[n]] = root.noteOn(channel, note, velocity, delay);
}
return ret;
};
// FIX: needs some way to fade out smoothly..
root.noteOff = function (channel, note, delay) {
// var source = sources[channel+""+note];
// if (!source) return;
// source.noteOff(delay || 0);
// return source;
};
root.chordOff = function (channel, chord, delay) {
};
root.connect = function (callback) {
MIDI.lang = 'WebAudioAPI';
MIDI.setVolume = root.setVolume;
MIDI.programChange = root.programChange;
MIDI.noteOn = root.noteOn;
MIDI.noteOff = root.noteOff;
MIDI.chordOn = root.chordOn;
MIDI.chordOff = root.chordOff;
//
MIDI.Player.ctx = ctx = new AudioContext();
///
var urlList = [];
var keyToNote = MIDI.keyToNote;
for (var key in keyToNote) urlList.push(key);
var bufferList = [];
for (var i = 0; i < urlList.length; i++) {
audioLoader(urlList, i, bufferList, callback);
}
};
})();
/*
HTML5 <audio> - OGG or MPEG Soundbank
--------------------------------------
http://dev.w3.org/html5/spec/Overview.html#the-audio-element
*/
if (window.Audio) (function () {
var root = MIDI.HTML5 = {};
var note2id = {};
var volume = 1; // floating point
var channel_nid = -1; // current channel
var channel_map = {}; // map to current playing <audio> elements
var channels = []; // the audio channels
var notes = {}; // the piano keys
for (var nid = 0; nid < 12; nid++) {
channels[nid] = new Audio();
}
var playChannel = function (id) {
var note = notes[id];
if (!note) return;
var nid = (channel_nid + 1) % channels.length;
var time = (new Date()).getTime();
var audio = channels[nid];
channel_map[note.id] = audio;
audio.src = MIDI.Soundfont[note.id];
audio.volume = volume;
audio.play();
channel_nid = nid;
};
root.programChange = function () {
};
root.setVolume = function (n) {
volume = n;
};
root.noteOn = function (channel, note, velocity, delay) {
var id = note2id[note];
if (!notes[id]) return;
if (delay) {
var interval = window.setTimeout(function() {
playChannel(id);
}, delay * 1000);
return interval;
} else {
playChannel(id);
}
};
root.noteOff = function (channel, note, delay) {
// var nid = note2id[note];
// channel_map[nid].pause();
};
root.chordOn = function (channel, chord, velocity, delay) {
for (var key in chord) {
var n = chord[key];
var id = note2id[n];
if (!notes[id]) continue;
playChannel(id);
}
};
root.chordOff = function (channel, chord, delay) {
};
root.stopAllNotes = function () {
for (var nid = 0, length = channels.length; nid < length; nid++) {
channels[nid].pause();
}
};
root.connect = function (callback) {
var loading = {};
for (var key in MIDI.keyToNote) {
note2id[MIDI.keyToNote[key]] = key;
notes[key] = {
id: key
};
}
MIDI.lang = 'HTML5';
MIDI.setVolume = root.setVolume;
MIDI.programChange = root.programChange;
MIDI.noteOn = root.noteOn;
MIDI.noteOff = root.noteOff;
MIDI.chordOn = root.chordOn;
MIDI.chordOff = root.chordOff;
//
if (callback) callback();
//
};
})();
/*
Flash - MP3 Soundbank
----------------------
http://www.schillmania.com/projects/soundmanager2/
*/
(function () {
var root = MIDI.Flash = {};
var noteReverse = {};
var notes = {};
root.programChange = function () {
};
root.setVolume = function (channel, note) {
};
root.noteOn = function (channel, note, velocity, delay) {
var id = noteReverse[note];
if (!notes[id]) return;
if (delay) {
var interval = window.setTimeout(function() {
notes[id].play({ volume: velocity * 2 });
}, delay * 1000);
return interval;
} else {
notes[id].play({ volume: velocity * 2 });
}
};
root.noteOff = function (channel, note, delay) {
};
root.chordOn = function (channel, chord, velocity, delay) {
for (var key in chord) {
var n = chord[key];
var id = noteReverse[n];
if (notes[id]) {
notes[id].play({ volume: velocity * 2 });
}
}
};
root.chordOff = function (channel, chord, delay) {
};
root.stopAllNotes = function () {
};
root.connect = function (callback) {
soundManager.flashVersion = 9;
soundManager.useHTML5Audio = true;
soundManager.url = '../inc/SoundManager2/swf/';
soundManager.useHighPerformance = true;
soundManager.wmode = 'transparent';
soundManager.flashPollingInterval = 1;
soundManager.debugMode = false;
soundManager.onload = function () {
var loaded = [];
var onload = function () {
loaded.push(this.sID);
if (typeof (loader) === "undefined") return;
loader.message("Processing: " + this.sID);
};
for (var i = 0; i < 88; i++) {
var id = noteReverse[i + 21];
notes[id] = soundManager.createSound({
id: id,
url: './soundfont/mp3/' + id + '.mp3',
multiShot: true,
autoLoad: true,
onload: onload
});
}
MIDI.lang = 'Flash';
MIDI.setVolume = root.setVolume;
MIDI.programChange = root.programChange;
MIDI.noteOn = root.noteOn;
MIDI.noteOff = root.noteOff;
MIDI.chordOn = root.chordOn;
MIDI.chordOff = root.chordOff;
//
var interval = window.setInterval(function () {
if (loaded.length !== 88) return;
window.clearInterval(interval);
if (callback) callback();
}, 25);
};
soundManager.onerror = function () {
};
for (var key in MIDI.keyToNote) {
noteReverse[MIDI.keyToNote[key]] = key;
}
};
})();
/*
Java - Native Soundbank
----------------------------
https://github.com/abudaan/midibridge-js
http://java.sun.com/products/java-media/sound/soundbanks.html
*/
(function () {
var root = MIDI.Java = {};
root.connect = function (callback) {
// deferred loading of <applet>
MIDI.Plugin = false;
if (!window.navigator.javaEnabled()) {
MIDI.Flash.connect(callback);
return;
}
MIDI.Java.callback = callback;
var iframe = document.createElement('iframe');
iframe.name = 'MIDIFrame';
iframe.src = 'inc/midibridge/index.html';
iframe.width = 1;
iframe.height = 1;
document.body.appendChild(iframe);
};
root.confirm = function (plugin) {
MIDI.programChange = function (program) {
plugin.sendMidiEvent(0xC0, 0, program, 0);
};
MIDI.setVolume = function (n) {
};
MIDI.noteOn = function (channel, note, velocity, delay) {
if (delay) {
var interval = window.setTimeout(function() {
plugin.sendMidiEvent(0x90, channel, note, velocity);
}, delay * 1000);
return interval;
} else {
plugin.sendMidiEvent(0x90, channel, note, velocity);
}
};
MIDI.noteOff = function (channel, note, delay) {
if (delay) {
var interval = window.setTimeout(function() {
plugin.sendMidiEvent(0x80, channel, note, 0);
}, delay * 1000);
return interval;
} else {
plugin.sendMidiEvent(0x80, channel, note, 0);
}
};
MIDI.chordOn = function (channel, chord, velocity, delay) {
for (var key in chord) {
var n = chord[key];
plugin.sendMidiEvent(0x90, channel, n, 100);
}
};
MIDI.chordOff = function (channel, chord, delay) {
for (var key in chord) {
var n = chord[key];
plugin.sendMidiEvent(0x80, channel, n, 100);
}
};
MIDI.stopAllNotes = function () {
};
MIDI.getInstruments = function() {
return [];
};
///
if (plugin.ready) {
MIDI.lang = "Java";
if (MIDI.Java.callback) {
MIDI.Java.callback();
}
} else {
MIDI.Flash.connect(MIDI.Java.callback);
}
};
})();
/*
helper functions
*/
// instrument-tracker
MIDI.instruments = (function (arr) {
var instruments = {};
for (var key in arr) {
var list = arr[key];
for (var n = 0, length = list.length; n < length; n++) {
var instrument = list[n];
if (!instrument) continue;
var num = parseInt(instrument.substr(0, instrument.indexOf(" ")), 10);
instrument = instrument.replace(num + " ", "");
instruments[--num] = {
instrument: instrument,
category: key
};
instruments[instrument] = {
number: num,
category: key
};
}
}
return instruments;
})({
'Piano': ['1 Acoustic Grand Piano', '2 Bright Acoustic Piano', '3 Electric Grand Piano', '4 Honky-tonk Piano', '5 Electric Piano 1', '6 Electric Piano 2', '7 Harpsichord', '8 Clavinet'],
'Chromatic Percussion': ['9 Celesta', '10 Glockenspiel', '11 Music Box', '12 Vibraphone', '13 Marimba', '14 Xylophone', '15 Tubular Bells', '16 Dulcimer'],
'Organ': ['17 Drawbar Organ', '18 Percussive Organ', '19 Rock Organ', '20 Church Organ', '21 Reed Organ', '22 Accordion', '23 Harmonica', '24 Tango Accordion'],
'Guitar': ['25 Acoustic Guitar (nylon)', '26 Acoustic Guitar (steel)', '27 Electric Guitar (jazz)', '28 Electric Guitar (clean)', '29 Electric Guitar (muted)', '30 Overdriven Guitar', '31 Distortion Guitar', '32 Guitar Harmonics'],
'Bass': ['33 Acoustic Bass', '34 Electric Bass (finger)', '35 Electric Bass (pick)', '36 Fretless Bass', '37 Slap Bass 1', '38 Slap Bass 2', '39 Synth Bass 1', '40 Synth Bass 2'],
'Strings': ['41 Violin', '42 Viola', '43 Cello', '44 Contrabass', '45 Tremolo Strings', '46 Pizzicato Strings', '47 Orchestral Harp', '48 Timpani'],
'Ensemble': ['49 String Ensemble 1', '50 String Ensemble 2', '51 Synth Strings 1', '52 Synth Strings 2', '53 Choir Aahs', '54 Voice Oohs', '55 Synth Choir', '56 Orchestra Hit'],
'Brass': ['57 Trumpet', '58 Trombone', '59 Tuba', '60 Muted Trumpet', '61 French Horn', '62 Brass Section', '63 Synth Brass 1', '64 Synth Brass 2'],
'Reed': ['65 Soprano Sax', '66 Alto Sax', '67 Tenor Sax', '68 Baritone Sax', '69 Oboe', '70 English Horn', '71 Bassoon', '72 Clarinet'],
'Pipe': ['73 Piccolo', '74 Flute', '75 Recorder', '76 Pan Flute', '77 Blown Bottle', '78 Shakuhachi', '79 Whistle', '80 Ocarina'],
'Synth Lead': ['81 Lead 1 (square)', '82 Lead 2 (sawtooth)', '83 Lead 3 (calliope)', '84 Lead 4 (chiff)', '85 Lead 5 (charang)', '86 Lead 6 (voice)', '87 Lead 7 (fifths)', '88 Lead 8 (bass + lead)'],
'Synth Pad': ['89 Pad 1 (new age)', '90 Pad 2 (warm)', '91 Pad 3 (polysynth)', '92 Pad 4 (choir)', '93 Pad 5 (bowed)', '94 Pad 6 (metallic)', '95 Pad 7 (halo)', '96 Pad 8 (sweep)'],
'Synth Effects': ['97 FX 1 (rain)', '98 FX 2 (soundtrack)', '99 FX 3 (crystal)', '100 FX 4 (atmosphere)', '101 FX 5 (brightness)', '102 FX 6 (goblins)', '103 FX 7 (echoes)', '104 FX 8 (sci-fi)'],
'Ethnic': ['105 Sitar', '106 Banjo', '107 Shamisen', '108 Koto', '109 Kalimba', '110 Bagpipe', '111 Fiddle', '112 Shanai'],
'Percussive': ['113 Tinkle Bell', '114 Agogo', '115 Steel Drums', '116 Woodblock', '117 Taiko Drum', '118 Melodic Tom', '119 Synth Drum'],
'Sound effects': ['120 Reverse Cymbal', '121 Guitar Fret Noise', '122 Breath Noise', '123 Seashore', '124 Bird Tweet', '125 Telephone Ring', '126 Helicopter', '127 Applause', '128 Gunshot']
});
// channel-tracker
MIDI.channels = (function () { // 0 - 15 channels
var channels = {};
for (var n = 0; n < 16; n++) {
channels[n] = { // default values
instrument: 0,
// Acoustic Grand Piano
mute: false,
mono: false,
omni: false,
solo: false
};
}
return channels;
})();
// note conversions
MIDI.keyToNote = {}; // C8 == 108
MIDI.noteToKey = {}; // 108 == C8
(function () {
var A0 = 0x15; // first note
var C8 = 0x6C; // last note
var number2key = ["C", "Db", "D", "Eb", "E", "F", "Gb", "G", "Ab", "A", "Bb", "B"];
for (var n = A0; n <= C8; n++) {
var octave = (n - 12) / 12 >> 0;
var name = number2key[n % 12] + octave;
MIDI.keyToNote[name] = n;
MIDI.noteToKey[n] = name;
}
})();
})();
MIDI.pianoKeyOffset = 21;

63
js/MIDI/audioDetect.js Normal file
View file

@ -0,0 +1,63 @@
/*
MIDI.audioDetect : 0.3
-------------------------------------
https://github.com/mudx/MIDI.js
-------------------------------------
Probably, Maybe, No... Absolutely!
-------------------------------------
Test to see what types of <audio> MIME types are playable by the browser.
*/
if (typeof(MIDI) === "undefined") var MIDI = {};
(function() { "use strict";
var supports = {};
var canPlayThrough = function (src) {
var audio = new Audio();
var mime = src.split(";")[0];
audio.id = "audio";
audio.setAttribute("preload", "auto");
audio.setAttribute("audiobuffer", true);
audio.addEventListener("canplaythrough", function() {
supports[mime] = true;
}, false);
audio.src = "data:" + src;
document.body.appendChild(audio);
};
MIDI.audioDetect = function(callback) {
// check whether <audio> tag is supported
if (typeof(Audio) === "undefined") return callback({});
// check whether canPlayType is supported
var audio = new Audio();
if (typeof(audio.canPlayType) === "undefined") return callback(supports);
// see what we can learn from the browser
var vorbis = audio.canPlayType('audio/ogg; codecs="vorbis"');
vorbis = (vorbis === "probably" || vorbis === "maybe");
var mpeg = audio.canPlayType('audio/mpeg');
mpeg = (mpeg === "probably" || mpeg === "maybe");
// maybe nothing is supported
if (!vorbis && !mpeg) {
callback(supports);
return;
}
// or maybe something is supported
if (vorbis) canPlayThrough("audio/ogg;base64,T2dnUwACAAAAAAAAAADqnjMlAAAAAOyyzPIBHgF2b3JiaXMAAAAAAUAfAABAHwAAQB8AAEAfAACZAU9nZ1MAAAAAAAAAAAAA6p4zJQEAAAANJGeqCj3//////////5ADdm9yYmlzLQAAAFhpcGguT3JnIGxpYlZvcmJpcyBJIDIwMTAxMTAxIChTY2hhdWZlbnVnZ2V0KQAAAAABBXZvcmJpcw9CQ1YBAAABAAxSFCElGVNKYwiVUlIpBR1jUFtHHWPUOUYhZBBTiEkZpXtPKpVYSsgRUlgpRR1TTFNJlVKWKUUdYxRTSCFT1jFloXMUS4ZJCSVsTa50FkvomWOWMUYdY85aSp1j1jFFHWNSUkmhcxg6ZiVkFDpGxehifDA6laJCKL7H3lLpLYWKW4q91xpT6y2EGEtpwQhhc+211dxKasUYY4wxxsXiUyiC0JBVAAABAABABAFCQ1YBAAoAAMJQDEVRgNCQVQBABgCAABRFcRTHcRxHkiTLAkJDVgEAQAAAAgAAKI7hKJIjSZJkWZZlWZameZaouaov+64u667t6roOhIasBACAAAAYRqF1TCqDEEPKQ4QUY9AzoxBDDEzGHGNONKQMMogzxZAyiFssLqgQBKEhKwKAKAAAwBjEGGIMOeekZFIi55iUTkoDnaPUUcoolRRLjBmlEluJMYLOUeooZZRCjKXFjFKJscRUAABAgAMAQICFUGjIigAgCgCAMAYphZRCjCnmFHOIMeUcgwwxxiBkzinoGJNOSuWck85JiRhjzjEHlXNOSuekctBJyaQTAAAQ4AAAEGAhFBqyIgCIEwAwSJKmWZomipamiaJniqrqiaKqWp5nmp5pqqpnmqpqqqrrmqrqypbnmaZnmqrqmaaqiqbquqaquq6nqrZsuqoum65q267s+rZru77uqapsm6or66bqyrrqyrbuurbtS56nqqKquq5nqq6ruq5uq65r25pqyq6purJtuq4tu7Js664s67pmqq5suqotm64s667s2rYqy7ovuq5uq7Ks+6os+75s67ru2rrwi65r66os674qy74x27bwy7ouHJMnqqqnqq7rmarrqq5r26rr2rqmmq5suq4tm6or26os67Yry7aumaosm64r26bryrIqy77vyrJui67r66Ys67oqy8Lu6roxzLat+6Lr6roqy7qvyrKuu7ru+7JuC7umqrpuyrKvm7Ks+7auC8us27oxuq7vq7It/KosC7+u+8Iy6z5jdF1fV21ZGFbZ9n3d95Vj1nVhWW1b+V1bZ7y+bgy7bvzKrQvLstq2scy6rSyvrxvDLux8W/iVmqratum6um7Ksq/Lui60dd1XRtf1fdW2fV+VZd+3hV9pG8OwjK6r+6os68Jry8ov67qw7MIvLKttK7+r68ow27qw3L6wLL/uC8uq277v6rrStXVluX2fsSu38QsAABhwAAAIMKEMFBqyIgCIEwBAEHIOKQahYgpCCKGkEEIqFWNSMuakZM5JKaWUFEpJrWJMSuaclMwxKaGUlkopqYRSWiqlxBRKaS2l1mJKqcVQSmulpNZKSa2llGJMrcUYMSYlc05K5pyUklJrJZXWMucoZQ5K6iCklEoqraTUYuacpA46Kx2E1EoqMZWUYgupxFZKaq2kFGMrMdXUWo4hpRhLSrGVlFptMdXWWqs1YkxK5pyUzDkqJaXWSiqtZc5J6iC01DkoqaTUYiopxco5SR2ElDLIqJSUWiupxBJSia20FGMpqcXUYq4pxRZDSS2WlFosqcTWYoy1tVRTJ6XFklKMJZUYW6y5ttZqDKXEVkqLsaSUW2sx1xZjjqGkFksrsZWUWmy15dhayzW1VGNKrdYWY40x5ZRrrT2n1mJNMdXaWqy51ZZbzLXnTkprpZQWS0oxttZijTHmHEppraQUWykpxtZara3FXEMpsZXSWiypxNhirLXFVmNqrcYWW62ltVprrb3GVlsurdXcYqw9tZRrrLXmWFNtBQAADDgAAASYUAYKDVkJAEQBAADGMMYYhEYpx5yT0ijlnHNSKucghJBS5hyEEFLKnINQSkuZcxBKSSmUklJqrYVSUmqttQIAAAocAAACbNCUWByg0JCVAEAqAIDBcTRNFFXVdX1fsSxRVFXXlW3jVyxNFFVVdm1b+DVRVFXXtW3bFn5NFFVVdmXZtoWiqrqybduybgvDqKqua9uybeuorqvbuq3bui9UXVmWbVu3dR3XtnXd9nVd+Bmzbeu2buu+8CMMR9/4IeTj+3RCCAAAT3AAACqwYXWEk6KxwEJDVgIAGQAAgDFKGYUYM0gxphhjTDHGmAAAgAEHAIAAE8pAoSErAoAoAADAOeecc84555xzzjnnnHPOOeecc44xxhhjjDHGGGOMMcYYY4wxxhhjjDHGGGOMMcYYY0wAwE6EA8BOhIVQaMhKACAcAABACCEpKaWUUkoRU85BSSmllFKqFIOMSkoppZRSpBR1lFJKKaWUIqWgpJJSSimllElJKaWUUkoppYw6SimllFJKKaWUUkoppZRSSimllFJKKaWUUkoppZRSSimllFJKKaWUUkoppZRSSimllFJKKaWUUkoppZRSSimllFJKKaVUSimllFJKKaWUUkoppRQAYPLgAACVYOMMK0lnhaPBhYasBAByAwAAhRiDEEJpraRUUkolVc5BKCWUlEpKKZWUUqqYgxBKKqmlklJKKbXSQSihlFBKKSWUUkooJYQQSgmhlFRCK6mEUkoHoYQSQimhhFRKKSWUzkEoIYUOQkmllNRCSB10VFIpIZVSSiklpZQ6CKGUklJLLZVSWkqpdBJSKamV1FJqqbWSUgmhpFZKSSWl0lpJJbUSSkklpZRSSymFVFJJJYSSUioltZZaSqm11lJIqZWUUkqppdRSSiWlkEpKqZSSUmollZRSaiGVlEpJKaTUSimlpFRCSamlUlpKLbWUSkmptFRSSaWUlEpJKaVSSksppRJKSqmllFpJKYWSUkoplZJSSyW1VEoKJaWUUkmptJRSSymVklIBAEAHDgAAAUZUWoidZlx5BI4oZJiAAgAAQABAgAkgMEBQMApBgDACAQAAAADAAAAfAABHARAR0ZzBAUKCwgJDg8MDAAAAAAAAAAAAAACAT2dnUwAEAAAAAAAAAADqnjMlAgAAADzQPmcBAQA=");
if (mpeg) canPlayThrough("audio/mpeg;base64,/+MYxAAAAANIAUAAAASEEB/jwOFM/0MM/90b/+RhST//w4NFwOjf///PZu////9lns5GFDv//l9GlUIEEIAAAgIg8Ir/JGq3/+MYxDsLIj5QMYcoAP0dv9HIjUcH//yYSg+CIbkGP//8w0bLVjUP///3Z0x5QCAv/yLjwtGKTEFNRTMuOTeqqqqqqqqqqqqq/+MYxEkNmdJkUYc4AKqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq");
// lets find out!
var time = (new Date()).getTime();
var interval = window.setInterval(function() {
for (var key in supports) {}
var now = (new Date()).getTime();
var maxExecution = now - time > 5000;
if (key || maxExecution) {
window.clearInterval(interval);
callback(supports);
}
}, 1);
};
})();

95
js/MIDI/loadPlugin.js Normal file
View file

@ -0,0 +1,95 @@
/*
MIDI.loadPlugin(callback, type);
-------------------------------------
https://github.com/mudx/MIDI.js
-------------------------------------
*/
if (typeof (MIDI) === "undefined") var MIDI = {};
if (typeof (MIDI.Soundfont) === "undefined") MIDI.Soundfont = {};
(function() { "use strict";
var plugins = { "#webaudio": true, "#html5": true, "#java": true, "#flash": true };
MIDI.loadPlugin = function(callback, instrument) {
var type = "";
var instrument = instrument || "";
MIDI.audioDetect(function(types) {
// use the most appropriate plugin if not specified
if (typeof(type) === 'undefined') {
if (plugins[window.location.hash]) {
type = window.location.hash;
} else {
type = "";
}
}
if (type === "") {
if (window.webkitAudioContext) { // Chrome
type = "#webaudio";
} else if (window.Audio) { // Firefox
type = "#html5";
} else { // Internet Explorer
type = "#flash";
}
}
if (typeof(loader) === "undefined") var loader;
// use audio/ogg when supported
var filetype = types["audio/ogg"] ? "ogg" : "mp3";
// load the specified plugin
switch (type) {
case "#java":
// works well cross-browser, and highly featured, but required Java machine to startup
if (loader) loader.message("Soundfont (500KB)<br>Java Interface...");
MIDI.Java.connect(callback);
break;
case "#flash":
// fairly quick, but requires loading of individual MP3s
if (loader) loader.message("Soundfont (2MB)<br>Flash Interface...");
DOMLoader.script.add({
src: "./inc/SoundManager2/script/soundmanager2.js",
verify: "SoundManager",
callback: function () {
MIDI.Flash.connect(callback);
}
});
break;
case "#html5":
// works well in Firefox
DOMLoader.sendRequest({
url: "./soundfont/soundfont-" + filetype + instrument + ".js",
callback: function (response) {
MIDI.Soundfont = JSON.parse(response.responseText);
if (loader) loader.message("Downloading: 100%<br>Processing...");
MIDI.HTML5.connect(callback);
},
progress: function (evt) {
var percent = evt.loaded / 1719931 * 100 >> 0;
if (loader) loader.message("Downloading: " + (percent + "%"));
}
});
break;
case "#webaudio":
// works well in Chrome
DOMLoader.sendRequest({
url: "./soundfont/soundfont-" + filetype + instrument + ".js",
callback: function(response) {
MIDI.Soundfont = JSON.parse(response.responseText);
if (loader) loader.message("Downloading: 100%<br>Processing...");
MIDI.WebAudioAPI.connect(callback);
},
progress: function (evt) {
var percent = evt.loaded / 1719931 * 100 >> 0;
if (loader) loader.message("Downloading: " + (percent + "%"));
}
});
break;
default:
break;
}
});
};
})();