/* 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 += " "; if (typeof(loader) !== "undefined") { loader.message("Downloading: 100%
Processing: "+(index/87 * 100 >> 0)+"%
" + 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.. // POSSIBLE FIX: fade out smoothly using gain and ramping to value root.noteOff = function (channel, note, delay) { var source = sources[channel+""+note]; if (!source) return; source.gain.linearRampToValueAtTime(1, delay); source.gain.linearRampToValueAtTime(0, delay + 0.1); 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