A piano to hack on while going to/from work.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

167 lines
4.5 KiB

if (typeof (MIDI) === "undefined") var MIDI = {};
if (typeof (MIDI.Soundfont) === "undefined") MIDI.Soundfont = {};
(function() { "use strict";
var USE_JAZZMIDI = false; // Turn on to support JazzMIDI Plugin
MIDI.loadPlugin = function(conf) {
if (typeof(conf) === "function") conf = {
callback: conf
};
/// Get the instrument name.
var instruments = conf.instruments || conf.instrument || "acoustic_grand_piano";
if (typeof(instruments) !== "object") instruments = [ instruments ];
///
for (var n = 0; n < instruments.length; n ++) {
var instrument = instruments[n];
if (typeof(instrument) === "number") {
instruments[n] = MIDI.GeneralMIDI.byId[instrument];
}
};
///
MIDI.soundfontUrl = conf.soundfontUrl || MIDI.soundfontUrl || "./soundfont/";
/// Detect the best type of audio to use.
MIDI.audioDetect(function(types) {
var api = "";
// use the most appropriate plugin if not specified
if (apis[conf.api]) {
api = conf.api;
} else if (apis[window.location.hash.substr(1)]) {
api = window.location.hash.substr(1);
} else if (USE_JAZZMIDI && navigator.requestMIDIAccess) {
api = "webmidi";
} else if (window.webkitAudioContext || window.AudioContext) { // Chrome
api = "webaudio";
} else if (window.Audio) { // Firefox
api = "audiotag";
} else { // Internet Explorer
api = "flash";
}
///
if (!connect[api]) return;
// use audio/ogg when supported
if (conf.targetFormat) {
var filetype = conf.targetFormat;
} else { // use best quality
var filetype = types["audio/ogg"] ? "ogg" : "mp3";
}
// load the specified plugin
MIDI.lang = api;
MIDI.supports = types;
connect[api](filetype, instruments, conf);
});
};
///
var connect = {};
connect.webmidi = function(filetype, instruments, conf) {
if (MIDI.loader) MIDI.loader.message("Web MIDI API...");
MIDI.WebMIDI.connect(conf);
};
connect.flash = function(filetype, instruments, conf) {
// fairly quick, but requires loading of individual MP3s (more http requests).
if (MIDI.loader) MIDI.loader.message("Flash API...");
DOMLoader.script.add({
src: conf.soundManagerUrl || "./inc/SoundManager2/script/soundmanager2.js",
verify: "SoundManager",
callback: function () {
MIDI.Flash.connect(instruments, conf);
}
});
};
connect.audiotag = function(filetype, instruments, conf) {
if (MIDI.loader) MIDI.loader.message("HTML5 Audio API...");
// works ok, kinda like a drunken tuna fish, across the board.
var queue = createQueue({
items: instruments,
getNext: function(instrumentId) {
DOMLoader.sendRequest({
url: MIDI.soundfontUrl + instrumentId + "-" + filetype + ".js",
onprogress: getPercent,
onload: function (response) {
addSoundfont(response.responseText);
if (MIDI.loader) MIDI.loader.update(null, "Downloading", 100);
queue.getNext();
}
});
},
onComplete: function() {
MIDI.AudioTag.connect(conf);
}
});
};
connect.webaudio = function(filetype, instruments, conf) {
if (MIDI.loader) MIDI.loader.message("Web Audio API...");
// works awesome! safari, chrome and firefox support.
var queue = createQueue({
items: instruments,
getNext: function(instrumentId) {
DOMLoader.sendRequest({
url: MIDI.soundfontUrl + instrumentId + "-" + filetype + ".js",
onprogress: getPercent,
onload: function(response) {
addSoundfont(response.responseText);
if (MIDI.loader) MIDI.loader.update(null, "Downloading...", 100);
queue.getNext();
}
});
},
onComplete: function() {
MIDI.WebAudio.connect(conf);
}
});
};
/// Helpers
var apis = {
"webmidi": true,
"webaudio": true,
"audiotag": true,
"flash": true
};
var addSoundfont = function(text) {
var script = document.createElement("script");
script.language = "javascript";
script.type = "text/javascript";
script.text = text;
document.body.appendChild(script);
};
var getPercent = function(event) {
if (!this.totalSize) {
if (this.getResponseHeader("Content-Length-Raw")) {
this.totalSize = parseInt(this.getResponseHeader("Content-Length-Raw"));
} else {
this.totalSize = event.total;
}
}
///
var percent = this.totalSize ? Math.round(event.loaded / this.totalSize * 100) : "";
if (MIDI.loader) MIDI.loader.update(null, "Downloading...", percent);
};
var createQueue = function(conf) {
var self = {};
self.queue = [];
for (var key in conf.items) {
if (conf.items.hasOwnProperty(key)) {
self.queue.push(conf.items[key]);
}
}
self.getNext = function() {
if (!self.queue.length) return conf.onComplete();
conf.getNext(self.queue.shift());
};
setTimeout(self.getNext, 1);
return self;
};
})();