123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199 |
- /*
- ----------------------------------------------------------
- MIDI.Plugin : 0.3.4 : 2015-03-26
- ----------------------------------------------------------
- https://github.com/mudcube/MIDI.js
- ----------------------------------------------------------
- Inspired by javax.sound.midi (albeit a super simple version):
- http://docs.oracle.com/javase/6/docs/api/javax/sound/midi/package-summary.html
- ----------------------------------------------------------
- Technologies
- ----------------------------------------------------------
- Web MIDI API - no native support yet (jazzplugin)
- Web Audio API - firefox 25+, chrome 10+, safari 6+, opera 15+
- HTML5 Audio Tag - ie 9+, firefox 3.5+, chrome 4+, safari 4+, opera 9.5+, ios 4+, android 2.3+
- ----------------------------------------------------------
- */
- if (typeof MIDI === 'undefined') MIDI = {};
- MIDI.Soundfont = MIDI.Soundfont || {};
- MIDI.Player = MIDI.Player || {};
- (function(root) { 'use strict';
- root.DEBUG = true;
- root.USE_XHR = true;
- root.soundfontUrl = './soundfont/';
- /*
- MIDI.loadPlugin({
- onsuccess: function() { },
- onprogress: function(state, percent) { },
- targetFormat: 'mp3', // optionally can force to use MP3 (for instance on mobile networks)
- instrument: 'acoustic_grand_piano', // or 1 (default)
- instruments: [ 'acoustic_grand_piano', 'acoustic_guitar_nylon' ] // or multiple instruments
- });
- */
- root.loadPlugin = function(opts) {
- if (typeof opts === 'function') {
- opts = {onsuccess: opts};
- }
- root.soundfontUrl = opts.soundfontUrl || root.soundfontUrl;
- /// Detect the best type of audio to use
- root.audioDetect(function(supports) {
- var hash = window.location.hash;
- var api = '';
- /// use the most appropriate plugin if not specified
- if (supports[opts.api]) {
- api = opts.api;
- } else if (supports[hash.substr(1)]) {
- api = hash.substr(1);
- } else if (supports.webmidi) {
- api = 'webmidi';
- } else if (window.AudioContext) { // Chrome
- api = 'webaudio';
- } else if (window.Audio) { // Firefox
- api = 'audiotag';
- }
- if (connect[api]) {
- /// use audio/ogg when supported
- if (opts.targetFormat) {
- var audioFormat = opts.targetFormat;
- } else { // use best quality
- var audioFormat = supports['audio/ogg'] ? 'ogg' : 'mp3';
- }
- /// load the specified plugin
- root.__api = api;
- root.__audioFormat = audioFormat;
- root.supports = supports;
- root.loadResource(opts);
- }
- });
- };
- /*
- root.loadResource({
- onsuccess: function() { },
- onprogress: function(state, percent) { },
- instrument: 'banjo'
- })
- */
- root.loadResource = function(opts) {
- var instruments = opts.instruments || opts.instrument || 'acoustic_grand_piano';
- ///
- if (typeof instruments !== 'object') {
- if (instruments || instruments === 0) {
- instruments = [instruments];
- } else {
- instruments = [];
- }
- }
- /// convert numeric ids into strings
- for (var i = 0; i < instruments.length; i ++) {
- var instrument = instruments[i];
- if (instrument === +instrument) { // is numeric
- if (root.GM.byId[instrument]) {
- instruments[i] = root.GM.byId[instrument].id;
- }
- }
- }
- ///
- opts.format = root.__audioFormat;
- opts.instruments = instruments;
- ///
- connect[root.__api](opts);
- };
- var connect = {
- webmidi: function(opts) {
- // cant wait for this to be standardized!
- root.WebMIDI.connect(opts);
- },
- audiotag: function(opts) {
- // works ok, kinda like a drunken tuna fish, across the board
- // http://caniuse.com/audio
- requestQueue(opts, 'AudioTag');
- },
- webaudio: function(opts) {
- // works awesome! safari, chrome and firefox support
- // http://caniuse.com/web-audio
- requestQueue(opts, 'WebAudio');
- }
- };
- var requestQueue = function(opts, context) {
- var audioFormat = opts.format;
- var instruments = opts.instruments;
- var onprogress = opts.onprogress;
- var onerror = opts.onerror;
- ///
- var length = instruments.length;
- var pending = length;
- var waitForEnd = function() {
- if (!--pending) {
- onprogress && onprogress('load', 1.0);
- root[context].connect(opts);
- }
- };
- ///
- for (var i = 0; i < length; i ++) {
- var instrumentId = instruments[i];
- if (MIDI.Soundfont[instrumentId]) { // already loaded
- waitForEnd();
- } else { // needs to be requested
- sendRequest(instruments[i], audioFormat, function(evt, progress) {
- var fileProgress = progress / length;
- var queueProgress = (length - pending) / length;
- onprogress && onprogress('load', fileProgress + queueProgress, instrumentId);
- }, function() {
- waitForEnd();
- }, onerror);
- }
- };
- };
- var sendRequest = function(instrumentId, audioFormat, onprogress, onsuccess, onerror) {
- var soundfontPath = root.soundfontUrl + instrumentId + '-' + audioFormat + '.js';
- if (root.USE_XHR) {
- root.util.request({
- url: soundfontPath,
- format: 'text',
- onerror: onerror,
- onprogress: onprogress,
- onsuccess: function(event, responseText) {
- var script = document.createElement('script');
- script.language = 'javascript';
- script.type = 'text/javascript';
- script.text = responseText;
- document.body.appendChild(script);
- ///
- onsuccess();
- }
- });
- } else {
- dom.loadScript.add({
- url: soundfontPath,
- verify: 'MIDI.Soundfont["' + instrumentId + '"]',
- onerror: onerror,
- onsuccess: function() {
- onsuccess();
- }
- });
- }
- };
- root.setDefaultPlugin = function(midi) {
- for (var key in midi) {
- root[key] = midi[key];
- }
- };
- })(MIDI);
|