/*
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..
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