diff --git a/js/MIDI/Plugin.js b/js/MIDI/Plugin.js index a6cbf7d..1076d40 100644 --- a/js/MIDI/Plugin.js +++ b/js/MIDI/Plugin.js @@ -1,17 +1,17 @@ /* - ------------------------------------- + -------------------------------------------- MIDI.Plugin : 0.3 : 11/20/2012 - ------------------------------------- + -------------------------------------------- https://github.com/mudx/MIDI.js - ------------------------------------- + -------------------------------------------- MIDI.WebAudioAPI MIDI.Flash MIDI.HTML5 - MIDI.instruments + MIDI.GeneralMIDI MIDI.channels MIDI.keyToNote MIDI.noteToKey - ------------------------------------- + -------------------------------------------- setMute? getInstruments? @@ -23,9 +23,11 @@ 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 = {}; @@ -38,14 +40,17 @@ if (window.AudioContext || window.webkitAudioContext) (function () { var sources = {}; var masterVolume = 1; var audioBuffers = {}; - var audioLoader = function (urlList, index, bufferList, oncomplete) { + var audioLoader = function (instrument, urlList, index, bufferList, callback) { + var synth = MIDI.GeneralMIDI.byName[instrument]; + var instrumentId = synth.number; var url = urlList[index]; - var base64 = MIDI.Soundfont[url].split(",")[1]; + var base64 = MIDI.Soundfont[instrument][url].split(",")[1]; var buffer = Base64Binary.decodeArrayBuffer(base64); ctx.decodeAudioData(buffer, function (buffer) { - var msg = url; while(msg.length < 3) msg += " "; - if (typeof(loader) !== "undefined") { - loader.message("Downloading: 100%
Processing: "+(index/87 * 100 >> 0)+"%
" + msg); + var msg = url; + while (msg.length < 3) msg += " "; + if (typeof (loader) !== "undefined") { + loader.message(synth.instrument + "
Processing: " + (index / 87 * 100 >> 0) + "%
" + msg); } buffer.id = url; bufferList[index] = buffer; @@ -53,10 +58,11 @@ if (window.AudioContext || window.webkitAudioContext) (function () { if (bufferList.length === urlList.length) { while (bufferList.length) { buffer = bufferList.pop(); + if (!buffer) continue; var nodeId = MIDI.keyToNote[buffer.id]; - audioBuffers[nodeId] = buffer; + audioBuffers[instrumentId + "" + nodeId] = buffer; } - oncomplete(); + callback(instrument); } }); }; @@ -65,19 +71,21 @@ if (window.AudioContext || window.webkitAudioContext) (function () { masterVolume = n; }; - root.programChange = function (instrument) { - + root.programChange = function (channel, program) { + MIDI.channels[channel].instrument = program; }; root.noteOn = function (channel, note, velocity, delay) { /// check whether the note exists - if (!audioBuffers[note]) return; + if (!MIDI.channels[channel]) return; + var instrument = MIDI.channels[channel].instrument; + if (!audioBuffers[instrument + "" + 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.buffer = audioBuffers[instrument + "" + note]; source.connect(ctx.destination); /// var gainNode = ctx.createGainNode(); @@ -92,7 +100,7 @@ if (window.AudioContext || window.webkitAudioContext) (function () { root.chordOn = function (channel, chord, velocity, delay) { var ret = {}, note; - for (var n = 0, length = chord.length; n < length; n ++) { + for (var n = 0, length = chord.length; n < length; n++) { ret[note = chord[n]] = root.noteOn(channel, note, velocity, delay); } return ret; @@ -102,7 +110,7 @@ if (window.AudioContext || window.webkitAudioContext) (function () { // POSSIBLE FIX: fade out smoothly using gain and ramping to value root.noteOff = function (channel, note, delay) { delay = delay || 0; - var source = sources[channel+""+note]; + var source = sources[channel + "" + note]; if (!source) return; source.gain.linearRampToValueAtTime(1, delay); source.gain.linearRampToValueAtTime(0, delay + 0.75); @@ -111,11 +119,14 @@ if (window.AudioContext || window.webkitAudioContext) (function () { }; root.chordOff = function (channel, chord, delay) { - + var ret = {}, note; + for (var n = 0, length = chord.length; n < length; n++) { + ret[note = chord[n]] = root.noteOff(channel, note, delay); + } + return ret; }; root.connect = function (callback) { - MIDI.lang = 'WebAudioAPI'; MIDI.setVolume = root.setVolume; MIDI.programChange = root.programChange; @@ -130,80 +141,93 @@ if (window.AudioContext || window.webkitAudioContext) (function () { 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); + var pending = {}; + var oncomplete = function(instrument) { + delete pending[instrument]; + for (var key in pending) break; + if (!key) callback(); + }; + for (var instrument in MIDI.Soundfont) { + pending[instrument] = true; + for (var i = 0; i < urlList.length; i++) { + audioLoader(instrument, urlList, i, bufferList, oncomplete); + } } }; })(); /* - HTML5