update to latest libraries

This commit is contained in:
Michael Deal 2012-10-09 22:59:04 -07:00
parent 61f1a05ebe
commit eb21d1f743
31 changed files with 2935 additions and 1227 deletions

View file

@ -1,154 +0,0 @@
/*
Color.Space : 0.3 : mudcu.be
-----------------------------
STRING <-> HEX <-> RGB <-> HSL
-----------------------------
var HEX = 0xFF0000;
var HSL = Color.Space(HEX, "HEX>RGB>HSL");
*/
if (!window.Color) Color = {};
if (!window.Color.Space) Color.Space = {};
(function () {
var DEG_RAD = Math.PI / 180;
var RAD_DEG = 1 / DEG_RAD;
var shortcuts = { };
var root = Color.Space = function(color, route) {
if (shortcuts[route]) {
route = shortcuts[route];
}
var arr = route.split(">");
var key = "";
for (var n = 0; n < arr.length; n ++) {
if (n > 1) {
key = key.split("_");
key.shift();
key = key.join("_");
}
key += (n == 0 ? "" : "_") + arr[n];
if (n > 0) color = root[key](color);
}
return color;
};
// STRING = 'FFFFFF' | 'FFFFFFFF'
root.STRING_HEX = function (o) {
return parseInt('0x' + o);
};
// HEX = 0x000000 -> 0xFFFFFF
root.HEX_STRING = function (o, maxLength) {
if (!maxLength) maxLength = 6;
if (!o) o = 0;
var z = o.toString(16);
// when string is lesser than maxLength
var n = z.length;
while (n < maxLength) {
z = '0' + z;
n++;
}
// when string is greater than maxLength
var n = z.length;
while (n > maxLength) {
z = z.substr(1);
n--;
}
return z;
};
root.HEX_RGB = function (o) {
return {
R: (o >> 16),
G: (o >> 8) & 0xFF,
B: o & 0xFF
};
};
// RGB = R: Red / G: Green / B: Blue
root.RGB_HEX = function (o) {
if (o.R < 0) o.R = 0;
if (o.G < 0) o.G = 0;
if (o.B < 0) o.B = 0;
if (o.R > 255) o.R = 255;
if (o.G > 255) o.G = 255;
if (o.B > 255) o.B = 255;
return o.R << 16 | o.G << 8 | o.B;
};
root.RGB_HSL = function (o) { // RGB from 0 to 1
// http://www.easyrgb.com/index.php?X=MATH&H=18#text18
var _R = o.R / 255,
_G = o.G / 255,
_B = o.B / 255,
min = Math.min(_R, _G, _B),
max = Math.max(_R, _G, _B),
D = max - min,
H,
S,
L = (max + min) / 2;
if (D == 0) { // No chroma
H = 0;
S = 0;
} else { // Chromatic data
if (L < 0.5) S = D / (max + min);
else S = D / (2 - max - min);
var DR = (((max - _R) / 6) + (D / 2)) / D;
var DG = (((max - _G) / 6) + (D / 2)) / D;
var DB = (((max - _B) / 6) + (D / 2)) / D;
if (_R == max) H = DB - DG;
else if (_G == max) H = (1 / 3) + DR - DB;
else if (_B == max) H = (2 / 3) + DG - DR;
if (H < 0) H += 1;
if (H > 1) H -= 1;
}
return {
H: H * 360,
S: S * 100,
L: L * 100
};
};
// HSL (1978) = H: Hue / S: Saturation / L: Lightess
root.HSL_RGB = function (o) {
// http://www.easyrgb.com/index.php?X=MATH&H=19
var H = o.H / 360,
S = o.S / 100,
L = o.L / 100,
R, G, B, _1, _2;
function Hue_2_RGB(v1, v2, vH) {
if (vH < 0) vH += 1;
if (vH > 1) vH -= 1;
if ((6 * vH) < 1) return v1 + (v2 - v1) * 6 * vH;
if ((2 * vH) < 1) return v2;
if ((3 * vH) < 2) return v1 + (v2 - v1) * ((2 / 3) - vH) * 6;
return v1;
}
if (S == 0) { // HSL from 0 to 1
R = L * 255;
G = L * 255;
B = L * 255;
} else {
if (L < 0.5) _2 = L * (1 + S);
else _2 = (L + S) - (S * L);
_1 = 2 * L - _2;
R = 255 * Hue_2_RGB(_1, _2, H + (1 / 3));
G = 255 * Hue_2_RGB(_1, _2, H);
B = 255 * Hue_2_RGB(_1, _2, H - (1 / 3));
}
return {
R: R,
G: G,
B: B
};
};
})();

439
js/Color/Space.js Normal file
View file

@ -0,0 +1,439 @@
/*
----------------------------------------------------
Color Space : 1.2 : 2012.09.01 : http://mudcu.be
----------------------------------------------------
RGBA <-> HSLA <-> W3
RGBA <-> HSVA
RGBA <-> CMY <-> CMYK
RGBA <-> HEX24 <-> W3
RGBA <-> HEX32
RGBA <-> W3
----------------------------------------------------
Examples
----------------------------------------------------
Color.Space(0x99ff0000, "HEX32>RGBA>HSLA>W3"); // outputs "hsla(60,100%,17%,0.6)"
Color.Space(0xFF0000, "HEX24>RGB>HSL"); // convert hex24 to HSL object.
----------------------------------------------------
W3 values
----------------------------------------------------
rgb(255,0,0)
rgba(255,0,0,1)
rgb(100%,0%,0%)
rgba(100%,0%,0%,1)
hsl(120, 100%, 50%)
hsla(120, 100%, 50%, 1)
#000000
*/
if (typeof(Color) === "undefined") Color = {};
if (typeof(Color.Space) === "undefined") Color.Space = {};
(function () {
var functions = {
// holds generated cached conversion functions.
};
var shortcuts = {
"HEX24>HSL": "HEX24>RGB>HSL",
"HEX32>HSLA": "HEX32>RGBA>HSLA",
"HEX24>CMYK": "HEX24>RGB>CMY>CMYK",
"RGB>CMYK": "RGB>CMY>CMYK"
};
var root = Color.Space = function(color, route) {
if (shortcuts[route]) { // shortcut available
route = shortcuts[route];
}
var r = route.split(">");
// check whether color is an [], if so, convert to {}
if (typeof(color) === "object" && color[0] >= 0) { // array
var type = r[0];
var tmp = {};
for(var i = 0; i < type.length; i ++) {
var str = type.substr(i, 1);
tmp[str] = color[i];
}
color = tmp;
}
if (functions[route]) { // cached function available
return functions[route](color);
}
var f = "color";
for (var pos = 1, key = r[0]; pos < r.length; pos ++) {
if (pos > 1) { // recycle previous
key = key.substr(key.indexOf("_") + 1);
}
key += (pos === 0 ? "" : "_") + r[pos];
color = root[key](color);
f = "Color.Space."+key+"("+f+")";
}
functions[route] = eval("(function(color) { return "+f+" })");
return color;
};
// W3C - RGB + RGBA
root.RGB_W3 = function(o) {
return "rgb(" + (o.R >> 0) + "," + (o.G >> 0) + "," + (o.B >> 0) + ")";
};
root.RGBA_W3 = function(o) {
var alpha = typeof(o.A) === "number" ? o.A / 255 : 1;
return "rgba(" + (o.R >> 0) + "," + (o.G >> 0) + "," + (o.B >> 0) + "," + alpha + ")";
};
root.W3_RGB = function(o) {
var o = o.substr(4, o.length - 5).split(",");
return {
R: parseInt(o[0]),
G: parseInt(o[1]),
B: parseInt(o[2])
}
};
root.W3_RGBA = function(o) {
var o = o.substr(5, o.length - 6).split(",");
return {
R: parseInt(o[0]),
G: parseInt(o[1]),
B: parseInt(o[2]),
A: parseFloat(o[3]) * 255
}
};
// W3C - HSL + HSLA
root.HSL_W3 = function(o) {
return "hsl(" + ((o.H + 0.5) >> 0) + "," + ((o.S + 0.5) >> 0) + "%," + ((o.L + 0.5) >> 0) + "%)";
};
root.HSLA_W3 = function(o) {
var alpha = typeof(o.A) === "number" ? o.A / 255 : 1;
return "hsla(" + ((o.H + 0.5) >> 0) + "," + ((o.S + 0.5) >> 0) + "%," + ((o.L + 0.5) >> 0) + "%," + alpha + ")";
};
root.W3_HSL = function(o) {
var o = o.substr(4, o.length - 5).split(",");
return {
H: parseInt(o[0]),
S: parseInt(o[1]),
L: parseInt(o[2])
}
};
root.W3_HSLA = function(o) {
var o = o.substr(5, o.length - 6).split(",");
return {
H: parseInt(o[0]),
S: parseInt(o[1]),
L: parseInt(o[2]),
A: parseFloat(o[3]) * 255
}
};
// W3 HEX = "FFFFFF" | "FFFFFFFF"
root.W3_HEX =
root.W3_HEX24 = function (o) {
if (o.substr(0, 1) === "#") o = o.substr(1);
if (o.length === 3) o = o[0] + o[0] + o[1] + o[1] + o[2] + o[2];
return parseInt("0x" + o);
};
root.W3_HEX32 = function (o) {
if (o.substr(0, 1) === "#") o = o.substr(1);
if (o.length === 6) {
return parseInt("0xFF" + o);
} else {
return parseInt("0x" + o);
}
};
// HEX = 0x000000 -> 0xFFFFFF
root.HEX_W3 =
root.HEX24_W3 = function (o, maxLength) {
if (!maxLength) maxLength = 6;
if (!o) o = 0;
var z = o.toString(16);
// when string is lesser than maxLength
var n = z.length;
while (n < maxLength) {
z = "0" + z;
n++;
}
// when string is greater than maxLength
var n = z.length;
while (n > maxLength) {
z = z.substr(1);
n--;
}
return "#" + z;
};
root.HEX32_W3 = function(o) {
return root.HEX_W3(o, 8);
};
root.HEX_RGB =
root.HEX24_RGB = function (o) {
return {
R: (o >> 16),
G: (o >> 8) & 0xFF,
B: o & 0xFF
};
};
// HEX32 = 0x00000000 -> 0xFFFFFFFF
root.HEX32_RGBA = function (o) {
return {
R: o >>> 16 & 0xFF,
G: o >>> 8 & 0xFF,
B: o & 0xFF,
A: o >>> 24
};
};
// RGBA = R: Red / G: Green / B: Blue / A: Alpha
root.RGBA_HEX32 = function (o) {
return (o.A << 24 | o.R << 16 | o.G << 8 | o.B) >>> 0;
};
// RGB = R: Red / G: Green / B: Blue
root.RGB_HEX24 =
root.RGB_HEX = function (o) {
if (o.R < 0) o.R = 0;
if (o.G < 0) o.G = 0;
if (o.B < 0) o.B = 0;
if (o.R > 255) o.R = 255;
if (o.G > 255) o.G = 255;
if (o.B > 255) o.B = 255;
return o.R << 16 | o.G << 8 | o.B;
};
root.RGB_CMY = function (o) {
return {
C: 1 - (o.R / 255),
M: 1 - (o.G / 255),
Y: 1 - (o.B / 255)
};
};
root.RGBA_HSLA =
root.RGB_HSL = function (o) { // RGB from 0 to 1
var _R = o.R / 255,
_G = o.G / 255,
_B = o.B / 255,
min = Math.min(_R, _G, _B),
max = Math.max(_R, _G, _B),
D = max - min,
H,
S,
L = (max + min) / 2;
if (D === 0) { // No chroma
H = 0;
S = 0;
} else { // Chromatic data
if (L < 0.5) S = D / (max + min);
else S = D / (2 - max - min);
var DR = (((max - _R) / 6) + (D / 2)) / D;
var DG = (((max - _G) / 6) + (D / 2)) / D;
var DB = (((max - _B) / 6) + (D / 2)) / D;
if (_R === max) H = DB - DG;
else if (_G === max) H = (1 / 3) + DR - DB;
else if (_B === max) H = (2 / 3) + DG - DR;
if (H < 0) H += 1;
if (H > 1) H -= 1;
}
return {
H: H * 360,
S: S * 100,
L: L * 100,
A: o.A
};
};
root.RGBA_HSVA =
root.RGB_HSV = function (o) { //- RGB from 0 to 255
var _R = o.R / 255,
_G = o.G / 255,
_B = o.B / 255,
min = Math.min(_R, _G, _B),
max = Math.max(_R, _G, _B),
D = max - min,
H,
S,
V = max;
if (D === 0) { // No chroma
H = 0;
S = 0;
} else { // Chromatic data
S = D / max;
var DR = (((max - _R) / 6) + (D / 2)) / D;
var DG = (((max - _G) / 6) + (D / 2)) / D;
var DB = (((max - _B) / 6) + (D / 2)) / D;
if (_R === max) H = DB - DG;
else if (_G === max) H = (1 / 3) + DR - DB;
else if (_B === max) H = (2 / 3) + DG - DR;
if (H < 0) H += 1;
if (H > 1) H -= 1;
}
return {
H: H * 360,
S: S * 100,
V: V * 100,
A: o.A
};
};
// CMY = C: Cyan / M: Magenta / Y: Yellow
root.CMY_RGB = function (o) {
return {
R: Math.max(0, (1 - o.C) * 255),
G: Math.max(0, (1 - o.M) * 255),
B: Math.max(0, (1 - o.Y) * 255)
};
};
root.CMY_CMYK = function (o) {
var C = o.C;
var M = o.M;
var Y = o.Y;
var K = Math.min(Y, Math.min(M, Math.min(C, 1)));
C = Math.round((C - K) / (1 - K) * 100);
M = Math.round((M - K) / (1 - K) * 100);
Y = Math.round((Y - K) / (1 - K) * 100);
K = Math.round(K * 100);
return {
C: C,
M: M,
Y: Y,
K: K
};
};
// CMYK = C: Cyan / M: Magenta / Y: Yellow / K: Key (black)
root.CMYK_CMY = function (o) {
return {
C: (o.C * (1 - o.K) + o.K),
M: (o.M * (1 - o.K) + o.K),
Y: (o.Y * (1 - o.K) + o.K)
};
};
// HSL (1978) = H: Hue / S: Saturation / L: Lightess
// en.wikipedia.org/wiki/HSL_and_HSV
root.HSLA_RGBA =
root.HSL_RGB = function (o) {
var H = o.H / 360;
var S = o.S / 100;
var L = o.L / 100;
var R, G, B;
var temp1, temp2, temp3;
if (S === 0) {
R = G = B = L;
} else {
if (L < 0.5) temp2 = L * (1 + S);
else temp2 = (L + S) - (S * L);
temp1 = 2 * L - temp2;
// calculate red
temp3 = H + (1 / 3);
if (temp3 < 0) temp3 += 1;
if (temp3 > 1) temp3 -= 1;
if ((6 * temp3) < 1) R = temp1 + (temp2 - temp1) * 6 * temp3;
else if ((2 * temp3) < 1) R = temp2;
else if ((3 * temp3) < 2) R = temp1 + (temp2 - temp1) * ((2 / 3) - temp3) * 6;
else R = temp1;
// calculate green
temp3 = H;
if (temp3 < 0) temp3 += 1;
if (temp3 > 1) temp3 -= 1;
if ((6 * temp3) < 1) G = temp1 + (temp2 - temp1) * 6 * temp3;
else if ((2 * temp3) < 1) G = temp2;
else if ((3 * temp3) < 2) G = temp1 + (temp2 - temp1) * ((2 / 3) - temp3) * 6;
else G = temp1;
// calculate blue
temp3 = H - (1 / 3);
if (temp3 < 0) temp3 += 1;
if (temp3 > 1) temp3 -= 1;
if ((6 * temp3) < 1) B = temp1 + (temp2 - temp1) * 6 * temp3;
else if ((2 * temp3) < 1) B = temp2;
else if ((3 * temp3) < 2) B = temp1 + (temp2 - temp1) * ((2 / 3) - temp3) * 6;
else B = temp1;
}
return {
R: R * 255,
G: G * 255,
B: B * 255,
A: o.A
};
};
// HSV (1978) = H: Hue / S: Saturation / V: Value
// en.wikipedia.org/wiki/HSL_and_HSV
root.HSVA_RGBA =
root.HSV_RGB = function (o) {
var H = o.H / 360;
var S = o.S / 100;
var V = o.V / 100;
var R, G, B;
if (S === 0) {
R = G = B = Math.round(V * 255);
} else {
if (H >= 1) H = 0;
H = 6 * H;
D = H - Math.floor(H);
A = Math.round(255 * V * (1 - S));
B = Math.round(255 * V * (1 - (S * D)));
C = Math.round(255 * V * (1 - (S * (1 - D))));
V = Math.round(255 * V);
switch (Math.floor(H)) {
case 0:
R = V;
G = C;
B = A;
break;
case 1:
R = B;
G = V;
B = A;
break;
case 2:
R = A;
G = V;
B = C;
break;
case 3:
R = A;
G = B;
B = V;
break;
case 4:
R = C;
G = A;
B = V;
break;
case 5:
R = V;
G = A;
B = B;
break;
}
}
return {
R: R,
G: G,
B: B,
A: o.A
};
};
})();

View file

@ -1,155 +0,0 @@
/*
Event.Mouse : 0.3.1 : mudcu.be
-------------------------------------
Event.add(document, "mousedown", function(event) {
Event.drag({
type: "absolute",
event: event,
element: document,
callback: function (event, coords, state, self) {
Event.stopPropagation(event);
Event.preventDefault(event);
console.log(coords);
}
});
});
// this does the same thing
Event.drag({
type: "absolute",
element: document,
callback: function (event, coords, state, self) {
console.log(coords);
}
});
/// easier mousewheel events
Event.mousewheel(window, function(event, state, wheelData, self) {
self.stop.prevent.remove();
});
*/
if (typeof(Event) === "undefined") var Event = {};
Event.drag =
Event.dragElement = function(props) {
var el = props.element || document.body;
var doc = el.ownerDocument; // could be within an iframe
if (typeof(props.event) === "undefined") { // create event
Event.add(el, "mousedown", function(event) {
props.event = event;
Event.dragElement(props);
Event.preventDefault(event);
Event.stopPropagation(event);
});
return;
}
// functions accessible externally
var self = {
cancel: function() {
Event.remove(doc, "mousemove", mouseMove);
Event.remove(doc, "mouseup", mouseUp);
}
};
// event move
var mouseMove = function (event, state) {
if (typeof(state) === "undefined") state = "move";
var coord = Event.coords(event);
switch (props.type) {
case "move": // move
props.callback(event, {
x: coord.x + oX - eX,
y: coord.y + oY - eY
}, state, self);
break;
case "difference": // relative, from position within element
props.callback(event, {
x: coord.x - oX,
y: coord.y - oY
}, state, self);
break;
case "relative": // eveything is relative from origin
props.callback(event, {
x: coord.x - eX,
y: coord.y - eY
}, state, self);
break;
default: // "absolute", origin is 0x0
props.callback(event, {
x: coord.x,
y: coord.y
}, state, self);
break;
}
};
// event up
var mouseUp = function(event) {
self.cancel();
mouseMove(event, "up");
};
// current element position
var origin = abPos(el);
var oX = origin.x;
var oY = origin.y;
// current mouse position
var event = props.event;
var coord = Event.coords(event);
var eX = coord.x;
var eY = coord.y;
// events
Event.add(doc, "mousemove", mouseMove);
Event.add(doc, "mouseup", mouseUp);
mouseMove(event, "down"); // run mouse-down
//
return self;
};
Event.coords = (function() {
if (window.ActiveXObject) {
return function(event) {
return {
x: event.clientX + document.documentElement.scrollLeft,
y: event.clientY + document.documentElement.scrollTop
};
};
} else {
return function(event) {
return {
x: event.pageX,
y: event.pageY
};
};
}
})();
//////////////// MouseWheel ////////////////
Event.mousewheel = function(target, listener, timeout) {
var interval = 0;
var self = Event(target, "mousewheel", function(event) {
event = event || window.event;
var wheelData = event.detail ? event.detail * -1 : event.wheelDelta / 40;
listener(event, "wheel", wheelData);
window.clearInterval(interval);
interval = window.setInterval(function() {
window.clearInterval(interval);
listener(event, "wheelup", wheelData, self);
}, timeout || 150);
});
return self;
};
///// DOM.absPos
var abPos = function(o) {
o = typeof(o) === 'object' ? o : document.getElementById(o);
var offset = { x: 0, y: 0 };
while(o != null) {
offset.x += o.offsetLeft;
offset.y += o.offsetTop;
o = o.offsetParent;
};
return offset;
};

File diff suppressed because it is too large Load diff

View file

@ -2,7 +2,7 @@
MIDI.Player : 0.3
-------------------------------------
https://github.com/mudx/MIDI.js
https://github.com/mudcube/MIDI.js
-------------------------------------
requires jasmid
@ -56,23 +56,23 @@ root.clearAnimation = function() {
root.setAnimation = function(config) {
var callback = (typeof(config) === "function") ? config : config.callback;
var delay = config.delay || 24;
var interval = config.interval || 30;
var currentTime = 0;
var tOurTime = 0;
var tTheirTime = 0;
//
root.clearAnimation();
root.interval = window.setInterval(function (){
root.interval = window.setInterval(function () {
if (root.endTime === 0) return;
if (root.playing) {
currentTime = (tTheirTime == root.currentTime) ? tOurTime-(new Date()).getTime() : 0;
currentTime = (tTheirTime === root.currentTime) ? tOurTime - (new Date).getTime() : 0;
if (root.currentTime === 0) {
currentTime = 0;
} else {
currentTime = root.currentTime - currentTime;
}
if (tTheirTime != root.currentTime) {
tOurTime = (new Date()).getTime();
if (tTheirTime !== root.currentTime) {
tOurTime = (new Date).getTime();
tTheirTime = root.currentTime;
}
} else { // paused
@ -91,7 +91,7 @@ root.setAnimation = function(config) {
end: t2,
events: noteRegistrar
});
}, delay);
}, interval);
};
// helpers
@ -111,6 +111,10 @@ root.loadFile = function (file, callback) {
if (callback) callback(data);
return;
}
///
var title = file.split(" - ")[1] || file;
document.getElementById("playback-title").innerHTML = title.replace(".mid","");
///
var fetch = new XMLHttpRequest();
fetch.open('GET', file);
fetch.overrideMimeType("text/plain; charset=x-user-defined");
@ -123,7 +127,7 @@ root.loadFile = function (file, callback) {
for (var z = 0; z < mx; z++) {
ff[z] = scc(t.charCodeAt(z) & 255);
}
var data = ff.join("");
var data = ff.join("");
root.currentData = data;
root.loadMidiFile();
if (callback) callback(data);
@ -140,8 +144,7 @@ var startTime = 0; // to measure time elapse
var noteRegistrar = {}; // get event for requested note
var onMidiEvent = undefined; // listener callback
var scheduleTracking = function (channel, note, currentTime, offset, message, velocity) {
var interval = window.setInterval(function () {
window.clearInterval(interval);
var interval = window.setTimeout(function () {
var data = {
channel: channel,
note: note,

View file

@ -225,7 +225,11 @@ if (typeof(MusicTheory.Synesthesia) === "undefined") MusicTheory.Synesthesia = {
9: [ 29, 94, 52 ],
10: [ 62, 78, 74 ],
11: [ 60, 90, 60 ]
}
},
'Circle of Fifths (2012)': {
ref: "Stuart Wheatman", // http://www.valleysfamilychurch.org/
english: [],
data: ['#122400', '#2E002E', '#002914', '#470000', '#002142', '#2E2E00', '#290052', '#003D00', '#520029', '#003D3D', '#522900', '#000080', '#244700', '#570057', '#004D26', '#7A0000', '#003B75', '#4C4D00', '#47008F', '#006100', '#850042', '#005C5C', '#804000', '#0000C7', '#366B00', '#80007F', '#00753B', '#B80000', '#0057AD', '#6B6B00', '#6600CC', '#008A00', '#B8005C', '#007F80', '#B35900', '#2424FF', '#478F00', '#AD00AD', '#00994D', '#F00000', '#0073E6', '#8F8F00', '#8A14FF', '#00AD00', '#EB0075', '#00A3A3', '#E07000', '#6B6BFF', '#5CB800', '#DB00DB', '#00C261', '#FF5757', '#3399FF', '#ADAD00', '#B56BFF', '#00D600', '#FF57AB', '#00C7C7', '#FF9124', '#9999FF', '#6EDB00', '#FF29FF', '#00E070', '#FF9999', '#7ABDFF', '#D1D100', '#D1A3FF', '#00FA00', '#FFA3D1', '#00E5E6', '#FFC285', '#C2C2FF', '#80FF00', '#FFA8FF', '#00E070', '#FFCCCC', '#C2E0FF', '#F0F000', '#EBD6FF', '#ADFFAD', '#FFD6EB', '#8AFFFF', '#FFEBD6', '#EBEBFF', '#E0FFC2', '#FFEBFF', '#E5FFF2', '#FFF5F5'] }
};
root.map = function(type) {
@ -240,18 +244,28 @@ if (typeof(MusicTheory.Synesthesia) === "undefined") MusicTheory.Synesthesia = {
var syn = root.data;
var colors = syn[type] || syn["D. D. Jameson (1844)"];
for (var note = 0; note <= 88; note ++) { // creates mapping for 88 notes
var clr = colors[(note + 9) % 12];
if (clr[0] == clr[1] && clr[1] == clr[2]) {
clr = blend(parray, colors[(note + 10) % 12]);
}
var amount = clr[2] / 10;
var octave = note / 12 >> 0;
var octaveLum = clr[2] + amount * octave - 3 * amount; // map luminance to octave
data[note] = {
hsl: 'hsla(' + clr[0] + ',' + clr[1] + '%,' + octaveLum + '%, 1)',
hex: Color.Space({H:clr[0], S:clr[1], L:octaveLum}, "HSL>RGB>HEX>STRING")
};
var parray = clr;
if (colors.data) {
data[note] = {
hsl: colors.data[note],
hex: colors.data[note]
}
} else {
var clr = colors[(note + 9) % 12];
var H = clr.H || clr[0];
var S = clr.S || clr[1];
var L = clr.L || clr[2];
if (H == S && S == L) {
clr = blend(parray, colors[(note + 10) % 12]);
}
var amount = L / 10;
var octave = note / 12 >> 0;
var octaveLum = L + amount * octave - 3 * amount; // map luminance to octave
data[note] = {
hsl: 'hsla(' + H + ',' + S + '%,' + octaveLum + '%, 1)',
hex: Color.Space({H:H, S:S, L:octaveLum}, "HSL>RGB>HEX>W3")
};
var parray = clr;
}
}
return data;
};

View file

@ -1,205 +0,0 @@
/*
var loader = new widgets.Loader({ message: "loading: New loading message..." });
-----
var loader = new widgets.Loader({
id: "loader",
bars: 12,
radius: 20,
lineWidth: 3,
lineHeight: 10
});
loader.stop();
loader.message("loading: New loading message...");
*/
if (typeof(widgets) === "undefined") widgets = {};
(function(root) {
var PI = Math.PI;
var defaultConfig = {
id: "loader",
bars: 12,
radius: 0,
lineWidth: 20,
lineHeight: 70
};
var getWindowSize = function() {
if (window.innerWidth && window.innerHeight) {
var width = window.innerWidth;
var height = window.innerHeight;
} else if (document.body && document.body.offsetWidth) {
var width = window.innerWidth = document.body.offsetWidth;
var height = window.innerHeight = document.body.offsetHeight;
} else if (document.compatMode === 'CSS1Compat' && document.documentElement && document.documentElement.offsetWidth) {
var width = window.innerWidth = document.documentElement.offsetWidth;
var height = window.innerHeight = document.documentElement.offsetHeight;
}
return {
width: width,
height: height
};
};
root.Loader = function (config) {
var that = this;
if (!document.body) return;
if (!config) config = {};
for (var key in defaultConfig) {
if (typeof(config[key]) === "undefined") {
config[key] = defaultConfig[key];
}
}
//
var canvas = document.getElementById(config.id);
if (!canvas) {
var div = document.createElement("div");
div.style.cssText = "color: #fff; pointer-events: none; -webkit-transition-property: opacity; -webkit-transition-duration: .5s; position: fixed; left: 0; top: 0; width: 100%; height: 100%; z-index: 10000; background: rgba(0,0,0,0.5); opacity: 1";
if (config.message) {
var span = document.createElement("span");
span.style.cssText = "font-family: courier; opacity: 1; display: inline-block;background: rgba(0,0,0,0.65); border-radius: 10px; padding: 10px; width: 200px; text-align: center; position: absolute; z-index: 1000;";
div.appendChild(span);
that.span = span;
}
var canvas = document.createElement("canvas");
document.body.appendChild(canvas);
canvas.id = config.id;
canvas.style.cssText = "opacity: 1; position: absolute; z-index: 1000;";
div.appendChild(canvas);
document.body.appendChild(div);
} else {
that.span = canvas.parentNode.getElementsByTagName("span")[0];
}
//
var max = config.lineHeight + 20;
var size = max * 2 + config.radius;
var windowSize = getWindowSize();
var width = windowSize.width - size;
var height = windowSize.height - size;
canvas.width = size;
canvas.height = size;
canvas.style.left = (width / 2) + "px";
canvas.style.top = (height / 2) + "px";
if (config.message) {
that.span.style.left = ((width + size) / 2 - that.span.offsetWidth/2) + "px";
that.span.style.top = (height / 2 + size - 10) + "px";
}
var that = this;
var interval = 0;
var offset = 0;
var delay = config.delay;
var bars = config.bars;
var radius = config.radius;
var ctx = canvas.getContext('2d');
ctx.globalCompositeOperation = "lighter";
ctx.shadowOffsetX = 1;
ctx.shadowOffsetY = 1;
ctx.shadowBlur = 1;
ctx.shadowColor = 'rgba(0, 0, 0, 0.5)';
//
function animate() {
var windowSize = getWindowSize();
var width = windowSize.width - size;
var height = windowSize.height - size;
//
canvas.style.left = (width / 2) + "px";
canvas.style.top = (height / 2) + "px";
if (config.message) {
that.span.style.left = ((width + size) / 2 - that.span.offsetWidth/2) + "px";
that.span.style.top = (height / 2 + size - 10) + "px";
}
//
ctx.save();
ctx.clearRect(0, 0, size, size);
ctx.translate(size / 2, size / 2);
var hues = 360 - 360 / bars;
for (var i = 0; i < bars; i++) {
var angle = (i / bars * 2 * PI) + offset;
ctx.save();
ctx.translate(radius * Math.sin(-angle), radius * Math.cos(-angle));
ctx.rotate(angle);
// round-rect properties
var x = -config.lineWidth / 2;
var y = 0;
var width = config.lineWidth;
var height = config.lineHeight;
var curve = width / 2;
// round-rect path
ctx.beginPath();
ctx.moveTo(x + curve, y);
ctx.lineTo(x + width - curve, y);
ctx.quadraticCurveTo(x + width, y, x + width, y + curve);
ctx.lineTo(x + width, y + height - curve);
ctx.quadraticCurveTo(x + width, y + height, x + width - curve, y + height);
ctx.lineTo(x + curve, y + height);
ctx.quadraticCurveTo(x, y + height, x, y + height - curve);
ctx.lineTo(x, y + curve);
ctx.quadraticCurveTo(x, y, x + curve, y);
// round-rect fill
var hue = ((i / (bars - 1)) * hues);
ctx.fillStyle = "hsla(" + hue + ", 100%, 50%, 0.85)";
ctx.fill();
ctx.restore();
}
ctx.restore();
offset += 0.07;
//
if (config.messageAnimate) {
var iteration = offset / 0.07 >> 0;
if (iteration % 10 === 0) {
var length = config.messageAnimate.length;
var n = iteration / 10 % length;
that.span.innerHTML = config.message + config.messageAnimate[n];
}
}
};
//
this.message = function(message) {
if (!interval) this.start();
config.message = message;
if (message.substr(-3) === "...") {
config.message = message.substr(0, message.length - 3);
config.messageAnimate = [ ".&nbsp;&nbsp;","..&nbsp;","..." ].reverse();
} else {
config.messageAnimate = false;
}
that.span.innerHTML = config.message + (config.messageAnimate[0] || "");
};
//
this.stop = function () {
if (interval) {
window.clearInterval(interval);
interval = 0;
}
if (canvas && canvas.style) {
canvas.parentNode.style.opacity = 0;
window.setTimeout(function () {
canvas.parentNode.style.display = "none";
ctx.clearRect(0, 0, size, size);
}, 500);
}
};
//
this.start = function (max) {
if (interval) return;
canvas.parentNode.style.top = document.body.scrollTop + "px";
canvas.parentNode.style.opacity = 1;
canvas.parentNode.style.display = "block";
canvas.style.left = (width / 2) + "px";
canvas.style.top = (height / 2) + "px";
if (!config.delay) animate();
interval = window.setInterval(animate, 30);
if (config.message) {
this.message(config.message);
}
};
//
this.start(30 * 1000);
//
return this;
};
})(widgets);

250
js/Widgets/Loader.js Normal file
View file

@ -0,0 +1,250 @@
/*
----------------------------------------------------
Loader.js : 0.3 : 2012/04/12
----------------------------------------------------
https://github.com/mudcube/Loader.js
----------------------------------------------------
var loader = new widgets.Loader({ message: "loading: New loading message..." });
----------------------------------------------------
var loader = new widgets.Loader({
id: "loader",
bars: 12,
radius: 0,
lineWidth: 20,
lineHeight: 70,
background: "rgba(0,0,0,0.5)",
message: "loading...",
callback: function() {
// call function once loader has started
}
});
loader.stop();
----------------------------------------------------
loader.message("loading: New loading message...", function() {
// call function once loader has started
});
*/
if (typeof(widgets) === "undefined") var widgets = {};
widgets.Loader = (function(root) {
var PI = Math.PI;
var defaultConfig = {
id: "loader",
bars: 12,
radius: 0,
lineWidth: 20,
lineHeight: 70,
display: true
};
var getWindowSize = function() {
if (window.innerWidth && window.innerHeight) {
var width = window.innerWidth;
var height = window.innerHeight;
} else if (document.compatMode === 'CSS1Compat' && document.documentElement && document.documentElement.offsetWidth) {
var width = document.documentElement.offsetWidth;
var height = document.documentElement.offsetHeight;
} else if (document.body && document.body.offsetWidth) {
var width = document.body.offsetWidth;
var height = document.body.offsetHeight;
}
return {
width: width,
height: height
};
};
return function (conf) {
var that = this;
if (!document.createElement("canvas").getContext) return;
var that = this;
if (!document.body) return;
if (typeof(conf) === "string") conf = { message: conf };
if (typeof(conf) === "undefined") conf = {};
if (typeof(conf) === "boolean") conf = { display: false };
for (var key in defaultConfig) {
if (typeof(conf[key]) === "undefined") {
conf[key] = defaultConfig[key];
}
}
//
function centerSpan() {
if (conf.message) {
var windowSize = getWindowSize();
var width = windowSize.width - size;
var height = windowSize.height - size;
that.span.style.left = ((width + size) / 2 - that.span.offsetWidth/2) + "px";
that.span.style.top = (height / 2 + size - 10) + "px";
}
};
///
var canvas = document.getElementById(conf.id);
var timeout = 1;
if (!canvas) {
var div = document.createElement("div");
var span = document.createElement("span");
div.appendChild(span);
that.span = span;
that.div = div;
var canvas = document.createElement("canvas");
document.body.appendChild(canvas);
canvas.id = conf.id;
canvas.style.cssText = "opacity: 1; position: absolute; z-index: 10000;";
div.appendChild(canvas);
document.body.appendChild(div);
} else {
that.span = canvas.parentNode.getElementsByTagName("span")[0];
}
//
var delay = conf.delay;
var bars = conf.bars;
var radius = conf.radius;
var max = conf.lineHeight + 20;
var size = max * 2 + conf.radius * 2;
var windowSize = getWindowSize();
var width = windowSize.width - size;
var height = windowSize.height - size;
///
canvas.width = size;
canvas.height = size;
canvas.style.left = (width / 2) + "px";
canvas.style.top = (height / 2) + "px";
///
centerSpan();
///
var offset = 0;
var ctx = canvas.getContext('2d');
ctx.globalCompositeOperation = "lighter";
ctx.shadowOffsetX = 1;
ctx.shadowOffsetY = 1;
ctx.shadowBlur = 1;
ctx.shadowColor = 'rgba(0, 0, 0, 0.5)';
//
function animate() {
var windowSize = getWindowSize();
var width = windowSize.width - size;
var height = windowSize.height - size;
//
canvas.style.left = (width / 2) + "px";
canvas.style.top = (height / 2) + "px";
centerSpan();
//
ctx.save();
ctx.clearRect(0, 0, size, size);
ctx.translate(size / 2, size / 2);
var hues = 360 - 360 / bars;
for (var i = 0; i < bars; i++) {
var angle = (i / bars * 2 * PI) + offset;
ctx.save();
ctx.translate(radius * Math.sin(-angle), radius * Math.cos(-angle));
ctx.rotate(angle);
// round-rect properties
var x = -conf.lineWidth / 2;
var y = 0;
var width = conf.lineWidth;
var height = conf.lineHeight;
var curve = width / 2;
// round-rect path
ctx.beginPath();
ctx.moveTo(x + curve, y);
ctx.lineTo(x + width - curve, y);
ctx.quadraticCurveTo(x + width, y, x + width, y + curve);
ctx.lineTo(x + width, y + height - curve);
ctx.quadraticCurveTo(x + width, y + height, x + width - curve, y + height);
ctx.lineTo(x + curve, y + height);
ctx.quadraticCurveTo(x, y + height, x, y + height - curve);
ctx.lineTo(x, y + curve);
ctx.quadraticCurveTo(x, y, x + curve, y);
// round-rect fill
var hue = ((i / (bars - 1)) * hues);
ctx.fillStyle = "hsla(" + hue + ", 100%, 50%, 0.85)";
ctx.fill();
ctx.restore();
}
ctx.restore();
offset += 0.07;
//
if (conf.messageAnimate) {
var iteration = offset / 0.07 >> 0;
if (iteration % 10 === 0) {
var length = conf.messageAnimate.length;
var n = iteration / 10 % length;
that.span.innerHTML = conf.message + conf.messageAnimate[n];
}
}
};
this.css = function() {
var background = conf.background ? conf.background : "rgba(0,0,0,0.65)";
span.style.cssText = "font-family: monospace; font-size: 14px; opacity: 1; display: none; background: "+background+"; border-radius: 10px; padding: 10px; width: 200px; text-align: center; position: absolute; z-index: 10000;";
div.style.cssText = "color: #fff; -webkit-transition-property: opacity; -webkit-transition-duration: " + timeout + "s; position: fixed; left: 0; top: 0; width: 100%; height: 100%; z-index: 100000; opacity: 0; display: none";
if (this.stopPropagation) {
div.style.cssText += "background: rgba(0,0,0,0.25);";
} else {
div.style.cssText += "pointer-events: none;";
}
};
this.stop = function () {
setTimeout(function() {
window.clearInterval(that.interval);
delete that.interval;
}, 50);
if (canvas && canvas.style) {
div.style.cssText += "pointer-events: none;";
canvas.parentNode.style.opacity = 0;
window.setTimeout(function () {
that.stopPropagation = false;
canvas.parentNode.style.display = "none";
ctx.clearRect(0, 0, size, size);
}, timeout * 1000);
}
};
this.start = function (callback) {
this.css();
var windowSize = getWindowSize();
var width = windowSize.width - size;
var height = windowSize.height - size;
canvas.parentNode.style.opacity = 1;
canvas.parentNode.style.display = "block";
that.span.style.display = conf.message ? "block" : "none";
if (conf.background) that.div.style.background = conf.backgrond;
canvas.style.left = (width / 2) + "px";
canvas.style.top = (height / 2) + "px";
if (!conf.delay) animate();
window.clearInterval(this.interval);
this.interval = window.setInterval(animate, 30);
if (conf.message) {
compileMessage(conf.message, callback);
}
};
this.message = function(message, callback) {
conf.message = message;
if (!this.interval) return this.start(callback);
if (conf.background) that.span.style.background = conf.backgrond;
compileMessage(conf.message, callback);
that.span.style.display = conf.message ? "block" : "none";
};
var compileMessage = function(message, callback) {
if (message.substr(-3) === "...") {
conf.message = message.substr(0, message.length - 3);
conf.messageAnimate = [ ".&nbsp;&nbsp;","..&nbsp;","..." ].reverse();
that.span.innerHTML = conf.message + conf.messageAnimate[0];
} else {
conf.messageAnimate = false;
that.span.innerHTML = conf.message;
}
if (callback) {
setTimeout(callback, 50);
}
};
//
if (conf.display === false) return this;
//
this.css();
this.start();
//
return this;
};
})(widgets);

View file

@ -1,80 +0,0 @@
/*
Copyright (c) 2011, Daniel Guerrero
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the Daniel Guerrero nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL DANIEL GUERRERO BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
var Base64Binary = {
_keyStr : "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",
/* will return a Uint8Array type */
decodeArrayBuffer: function(input) {
var bytes = Math.ceil( (3*input.length) / 4.0);
var ab = new ArrayBuffer(bytes);
this.decode(input, ab);
return ab;
},
decode: function(input, arrayBuffer) {
//get last chars to see if are valid
var lkey1 = this._keyStr.indexOf(input.charAt(input.length-1));
var lkey2 = this._keyStr.indexOf(input.charAt(input.length-1));
var bytes = Math.ceil( (3*input.length) / 4.0);
if (lkey1 == 64) bytes--; //padding chars, so skip
if (lkey2 == 64) bytes--; //padding chars, so skip
var uarray;
var chr1, chr2, chr3;
var enc1, enc2, enc3, enc4;
var i = 0;
var j = 0;
if (arrayBuffer)
uarray = new Uint8Array(arrayBuffer);
else
uarray = new Uint8Array(bytes);
input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
for (i=0; i<bytes; i+=3) {
//get the 3 octects in 4 ascii chars
enc1 = this._keyStr.indexOf(input.charAt(j++));
enc2 = this._keyStr.indexOf(input.charAt(j++));
enc3 = this._keyStr.indexOf(input.charAt(j++));
enc4 = this._keyStr.indexOf(input.charAt(j++));
chr1 = (enc1 << 2) | (enc2 >> 4);
chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
chr3 = ((enc3 & 3) << 6) | enc4;
uarray[i] = chr1;
if (enc3 != 64) uarray[i+1] = chr2;
if (enc4 != 64) uarray[i+2] = chr3;
}
return uarray;
}
};

View file

@ -1,24 +0,0 @@
Copyright (c) 2010, Matt Westcott & Ben Firshman
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* The names of its contributors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View file

@ -1,24 +0,0 @@
Copyright (c) 2010, Matt Westcott & Ben Firshman
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* The names of its contributors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View file

@ -1,238 +0,0 @@
/*
class to parse the .mid file format
(depends on stream.js)
*/
function MidiFile(data) {
function readChunk(stream) {
var id = stream.read(4);
var length = stream.readInt32();
return {
'id': id,
'length': length,
'data': stream.read(length)
};
}
var lastEventTypeByte;
function readEvent(stream) {
var event = {};
event.deltaTime = stream.readVarInt();
var eventTypeByte = stream.readInt8();
if ((eventTypeByte & 0xf0) == 0xf0) {
/* system / meta event */
if (eventTypeByte == 0xff) {
/* meta event */
event.type = 'meta';
var subtypeByte = stream.readInt8();
var length = stream.readVarInt();
switch(subtypeByte) {
case 0x00:
event.subtype = 'sequenceNumber';
if (length != 2) throw "Expected length for sequenceNumber event is 2, got " + length;
event.number = stream.readInt16();
return event;
case 0x01:
event.subtype = 'text';
event.text = stream.read(length);
return event;
case 0x02:
event.subtype = 'copyrightNotice';
event.text = stream.read(length);
return event;
case 0x03:
event.subtype = 'trackName';
event.text = stream.read(length);
return event;
case 0x04:
event.subtype = 'instrumentName';
event.text = stream.read(length);
return event;
case 0x05:
event.subtype = 'lyrics';
event.text = stream.read(length);
return event;
case 0x06:
event.subtype = 'marker';
event.text = stream.read(length);
return event;
case 0x07:
event.subtype = 'cuePoint';
event.text = stream.read(length);
return event;
case 0x20:
event.subtype = 'midiChannelPrefix';
if (length != 1) throw "Expected length for midiChannelPrefix event is 1, got " + length;
event.channel = stream.readInt8();
return event;
case 0x2f:
event.subtype = 'endOfTrack';
if (length != 0) throw "Expected length for endOfTrack event is 0, got " + length;
return event;
case 0x51:
event.subtype = 'setTempo';
if (length != 3) throw "Expected length for setTempo event is 3, got " + length;
event.microsecondsPerBeat = (
(stream.readInt8() << 16)
+ (stream.readInt8() << 8)
+ stream.readInt8()
)
return event;
case 0x54:
event.subtype = 'smpteOffset';
if (length != 5) throw "Expected length for smpteOffset event is 5, got " + length;
var hourByte = stream.readInt8();
event.frameRate = {
0x00: 24, 0x20: 25, 0x40: 29, 0x60: 30
}[hourByte & 0x60];
event.hour = hourByte & 0x1f;
event.min = stream.readInt8();
event.sec = stream.readInt8();
event.frame = stream.readInt8();
event.subframe = stream.readInt8();
return event;
case 0x58:
event.subtype = 'timeSignature';
if (length != 4) throw "Expected length for timeSignature event is 4, got " + length;
event.numerator = stream.readInt8();
event.denominator = Math.pow(2, stream.readInt8());
event.metronome = stream.readInt8();
event.thirtyseconds = stream.readInt8();
return event;
case 0x59:
event.subtype = 'keySignature';
if (length != 2) throw "Expected length for keySignature event is 2, got " + length;
event.key = stream.readInt8();
event.scale = stream.readInt8();
return event;
case 0x7f:
event.subtype = 'sequencerSpecific';
event.data = stream.read(length);
return event;
default:
// console.log("Unrecognised meta event subtype: " + subtypeByte);
event.subtype = 'unknown'
event.data = stream.read(length);
return event;
}
event.data = stream.read(length);
return event;
} else if (eventTypeByte == 0xf0) {
event.type = 'sysEx';
var length = stream.readVarInt();
event.data = stream.read(length);
return event;
} else if (eventTypeByte == 0xf7) {
event.type = 'dividedSysEx';
var length = stream.readVarInt();
event.data = stream.read(length);
return event;
} else {
throw "Unrecognised MIDI event type byte: " + eventTypeByte;
}
} else {
/* channel event */
var param1;
if ((eventTypeByte & 0x80) == 0) {
/* running status - reuse lastEventTypeByte as the event type.
eventTypeByte is actually the first parameter
*/
param1 = eventTypeByte;
eventTypeByte = lastEventTypeByte;
} else {
param1 = stream.readInt8();
lastEventTypeByte = eventTypeByte;
}
var eventType = eventTypeByte >> 4;
event.channel = eventTypeByte & 0x0f;
event.type = 'channel';
switch (eventType) {
case 0x08:
event.subtype = 'noteOff';
event.noteNumber = param1;
event.velocity = stream.readInt8();
return event;
case 0x09:
event.noteNumber = param1;
event.velocity = stream.readInt8();
if (event.velocity == 0) {
event.subtype = 'noteOff';
} else {
event.subtype = 'noteOn';
}
return event;
case 0x0a:
event.subtype = 'noteAftertouch';
event.noteNumber = param1;
event.amount = stream.readInt8();
return event;
case 0x0b:
event.subtype = 'controller';
event.controllerType = param1;
event.value = stream.readInt8();
return event;
case 0x0c:
event.subtype = 'programChange';
event.programNumber = param1;
return event;
case 0x0d:
event.subtype = 'channelAftertouch';
event.amount = param1;
return event;
case 0x0e:
event.subtype = 'pitchBend';
event.value = param1 + (stream.readInt8() << 7);
return event;
default:
throw "Unrecognised MIDI event type: " + eventType
/*
console.log("Unrecognised MIDI event type: " + eventType);
stream.readInt8();
event.subtype = 'unknown';
return event;
*/
}
}
}
stream = Stream(data);
var headerChunk = readChunk(stream);
if (headerChunk.id != 'MThd' || headerChunk.length != 6) {
throw "Bad .mid file - header not found";
}
var headerStream = Stream(headerChunk.data);
var formatType = headerStream.readInt16();
var trackCount = headerStream.readInt16();
var timeDivision = headerStream.readInt16();
if (timeDivision & 0x8000) {
throw "Expressing time division in SMTPE frames is not supported yet"
} else {
ticksPerBeat = timeDivision;
}
var header = {
'formatType': formatType,
'trackCount': trackCount,
'ticksPerBeat': ticksPerBeat
}
var tracks = [];
for (var i = 0; i < header.trackCount; i++) {
tracks[i] = [];
var trackChunk = readChunk(stream);
if (trackChunk.id != 'MTrk') {
throw "Unexpected chunk - expected MTrk, got "+ trackChunk.id;
}
var trackStream = Stream(trackChunk.data);
while (!trackStream.eof()) {
var event = readEvent(trackStream);
tracks[i].push(event);
//console.log(event);
}
}
return {
'header': header,
'tracks': tracks
}
}

View file

@ -1,81 +0,0 @@
var clone = function (o) {
if (typeof o != 'object') return (o);
if (o == null) return (o);
var ret = (typeof o.length == 'number') ? [] : {};
for (var key in o) ret[key] = clone(o[key]);
return ret;
};
function Replayer(midiFile, timeWarp, eventProcessor) {
var trackStates = [];
var beatsPerMinute = 120;
var ticksPerBeat = midiFile.header.ticksPerBeat;
for (var i = 0; i < midiFile.tracks.length; i++) {
trackStates[i] = {
"nextEventIndex": 0,
"ticksToNextEvent": (
midiFile.tracks[i].length ? midiFile.tracks[i][0].deltaTime : null
)
};
}
function getNextEvent() {
var ticksToNextEvent = null;
var nextEventTrack = null;
var nextEventIndex = null;
for (var i = 0; i < trackStates.length; i++) {
if (trackStates[i].ticksToNextEvent != null && (ticksToNextEvent == null || trackStates[i].ticksToNextEvent < ticksToNextEvent)) {
ticksToNextEvent = trackStates[i].ticksToNextEvent;
nextEventTrack = i;
nextEventIndex = trackStates[i].nextEventIndex;
}
}
if (nextEventTrack != null) {
/// consume event from that track
var nextEvent = midiFile.tracks[nextEventTrack][nextEventIndex];
if (midiFile.tracks[nextEventTrack][nextEventIndex + 1]) {
trackStates[nextEventTrack].ticksToNextEvent += midiFile.tracks[nextEventTrack][nextEventIndex + 1].deltaTime;
} else {
trackStates[nextEventTrack].ticksToNextEvent = null;
}
trackStates[nextEventTrack].nextEventIndex += 1;
/// advance timings on all tracks by ticksToNextEvent
for (var i = 0; i < trackStates.length; i++) {
if (trackStates[i].ticksToNextEvent != null) {
trackStates[i].ticksToNextEvent -= ticksToNextEvent
}
}
return {
"ticksToEvent": ticksToNextEvent,
"event": nextEvent,
"track": nextEventTrack
}
} else {
return null;
}
};
//
var midiEvent;
var temporal = [];
//
function processEvents() {
function processNext() {
if (midiEvent.ticksToEvent > 0) {
var beatsToGenerate = midiEvent.ticksToEvent / ticksPerBeat;
var secondsToGenerate = beatsToGenerate / (beatsPerMinute / 60);
}
var time = (secondsToGenerate * 1000 * timeWarp) || 0;
temporal.push([ midiEvent, time]);
midiEvent = getNextEvent();
};
//
if (midiEvent = getNextEvent()) {
while(midiEvent) processNext(true);
}
};
processEvents();
return {
"getData": function() {
return clone(temporal);
}
};
};

View file

@ -1,68 +0,0 @@
/* Wrapper for accessing strings through sequential reads */
function Stream(str) {
var position = 0;
function read(length) {
var result = str.substr(position, length);
position += length;
return result;
}
/* read a big-endian 32-bit integer */
function readInt32() {
var result = (
(str.charCodeAt(position) << 24)
+ (str.charCodeAt(position + 1) << 16)
+ (str.charCodeAt(position + 2) << 8)
+ str.charCodeAt(position + 3));
position += 4;
return result;
}
/* read a big-endian 16-bit integer */
function readInt16() {
var result = (
(str.charCodeAt(position) << 8)
+ str.charCodeAt(position + 1));
position += 2;
return result;
}
/* read an 8-bit integer */
function readInt8() {
var result = str.charCodeAt(position);
position += 1;
return result;
}
function eof() {
return position >= str.length;
}
/* read a MIDI-style variable-length integer
(big-endian value in groups of 7 bits,
with top bit set to signify that another byte follows)
*/
function readVarInt() {
var result = 0;
while (true) {
var b = readInt8();
if (b & 0x80) {
result += (b & 0x7f);
result <<= 7;
} else {
/* b is the last byte */
return result + b;
}
}
}
return {
'eof': eof,
'read': read,
'readInt32': readInt32,
'readInt16': readInt16,
'readInt8': readInt8,
'readVarInt': readVarInt
}
}

View file

@ -1,238 +0,0 @@
/*
class to parse the .mid file format
(depends on stream.js)
*/
function MidiFile(data) {
function readChunk(stream) {
var id = stream.read(4);
var length = stream.readInt32();
return {
'id': id,
'length': length,
'data': stream.read(length)
};
}
var lastEventTypeByte;
function readEvent(stream) {
var event = {};
event.deltaTime = stream.readVarInt();
var eventTypeByte = stream.readInt8();
if ((eventTypeByte & 0xf0) == 0xf0) {
/* system / meta event */
if (eventTypeByte == 0xff) {
/* meta event */
event.type = 'meta';
var subtypeByte = stream.readInt8();
var length = stream.readVarInt();
switch(subtypeByte) {
case 0x00:
event.subtype = 'sequenceNumber';
if (length != 2) throw "Expected length for sequenceNumber event is 2, got " + length;
event.number = stream.readInt16();
return event;
case 0x01:
event.subtype = 'text';
event.text = stream.read(length);
return event;
case 0x02:
event.subtype = 'copyrightNotice';
event.text = stream.read(length);
return event;
case 0x03:
event.subtype = 'trackName';
event.text = stream.read(length);
return event;
case 0x04:
event.subtype = 'instrumentName';
event.text = stream.read(length);
return event;
case 0x05:
event.subtype = 'lyrics';
event.text = stream.read(length);
return event;
case 0x06:
event.subtype = 'marker';
event.text = stream.read(length);
return event;
case 0x07:
event.subtype = 'cuePoint';
event.text = stream.read(length);
return event;
case 0x20:
event.subtype = 'midiChannelPrefix';
if (length != 1) throw "Expected length for midiChannelPrefix event is 1, got " + length;
event.channel = stream.readInt8();
return event;
case 0x2f:
event.subtype = 'endOfTrack';
if (length != 0) throw "Expected length for endOfTrack event is 0, got " + length;
return event;
case 0x51:
event.subtype = 'setTempo';
if (length != 3) throw "Expected length for setTempo event is 3, got " + length;
event.microsecondsPerBeat = (
(stream.readInt8() << 16)
+ (stream.readInt8() << 8)
+ stream.readInt8()
)
return event;
case 0x54:
event.subtype = 'smpteOffset';
if (length != 5) throw "Expected length for smpteOffset event is 5, got " + length;
var hourByte = stream.readInt8();
event.frameRate = {
0x00: 24, 0x20: 25, 0x40: 29, 0x60: 30
}[hourByte & 0x60];
event.hour = hourByte & 0x1f;
event.min = stream.readInt8();
event.sec = stream.readInt8();
event.frame = stream.readInt8();
event.subframe = stream.readInt8();
return event;
case 0x58:
event.subtype = 'timeSignature';
if (length != 4) throw "Expected length for timeSignature event is 4, got " + length;
event.numerator = stream.readInt8();
event.denominator = Math.pow(2, stream.readInt8());
event.metronome = stream.readInt8();
event.thirtyseconds = stream.readInt8();
return event;
case 0x59:
event.subtype = 'keySignature';
if (length != 2) throw "Expected length for keySignature event is 2, got " + length;
event.key = stream.readInt8();
event.scale = stream.readInt8();
return event;
case 0x7f:
event.subtype = 'sequencerSpecific';
event.data = stream.read(length);
return event;
default:
// console.log("Unrecognised meta event subtype: " + subtypeByte);
event.subtype = 'unknown'
event.data = stream.read(length);
return event;
}
event.data = stream.read(length);
return event;
} else if (eventTypeByte == 0xf0) {
event.type = 'sysEx';
var length = stream.readVarInt();
event.data = stream.read(length);
return event;
} else if (eventTypeByte == 0xf7) {
event.type = 'dividedSysEx';
var length = stream.readVarInt();
event.data = stream.read(length);
return event;
} else {
throw "Unrecognised MIDI event type byte: " + eventTypeByte;
}
} else {
/* channel event */
var param1;
if ((eventTypeByte & 0x80) == 0) {
/* running status - reuse lastEventTypeByte as the event type.
eventTypeByte is actually the first parameter
*/
param1 = eventTypeByte;
eventTypeByte = lastEventTypeByte;
} else {
param1 = stream.readInt8();
lastEventTypeByte = eventTypeByte;
}
var eventType = eventTypeByte >> 4;
event.channel = eventTypeByte & 0x0f;
event.type = 'channel';
switch (eventType) {
case 0x08:
event.subtype = 'noteOff';
event.noteNumber = param1;
event.velocity = stream.readInt8();
return event;
case 0x09:
event.noteNumber = param1;
event.velocity = stream.readInt8();
if (event.velocity == 0) {
event.subtype = 'noteOff';
} else {
event.subtype = 'noteOn';
}
return event;
case 0x0a:
event.subtype = 'noteAftertouch';
event.noteNumber = param1;
event.amount = stream.readInt8();
return event;
case 0x0b:
event.subtype = 'controller';
event.controllerType = param1;
event.value = stream.readInt8();
return event;
case 0x0c:
event.subtype = 'programChange';
event.programNumber = param1;
return event;
case 0x0d:
event.subtype = 'channelAftertouch';
event.amount = param1;
return event;
case 0x0e:
event.subtype = 'pitchBend';
event.value = param1 + (stream.readInt8() << 7);
return event;
default:
throw "Unrecognised MIDI event type: " + eventType
/*
console.log("Unrecognised MIDI event type: " + eventType);
stream.readInt8();
event.subtype = 'unknown';
return event;
*/
}
}
}
stream = Stream(data);
var headerChunk = readChunk(stream);
if (headerChunk.id != 'MThd' || headerChunk.length != 6) {
throw "Bad .mid file - header not found";
}
var headerStream = Stream(headerChunk.data);
var formatType = headerStream.readInt16();
var trackCount = headerStream.readInt16();
var timeDivision = headerStream.readInt16();
if (timeDivision & 0x8000) {
throw "Expressing time division in SMTPE frames is not supported yet"
} else {
ticksPerBeat = timeDivision;
}
var header = {
'formatType': formatType,
'trackCount': trackCount,
'ticksPerBeat': ticksPerBeat
}
var tracks = [];
for (var i = 0; i < header.trackCount; i++) {
tracks[i] = [];
var trackChunk = readChunk(stream);
if (trackChunk.id != 'MTrk') {
throw "Unexpected chunk - expected MTrk, got "+ trackChunk.id;
}
var trackStream = Stream(trackChunk.data);
while (!trackStream.eof()) {
var event = readEvent(trackStream);
tracks[i].push(event);
//console.log(event);
}
}
return {
'header': header,
'tracks': tracks
}
}

View file

@ -1,81 +0,0 @@
var clone = function (o) {
if (typeof o != 'object') return (o);
if (o == null) return (o);
var ret = (typeof o.length == 'number') ? [] : {};
for (var key in o) ret[key] = clone(o[key]);
return ret;
};
function Replayer(midiFile, timeWarp, eventProcessor) {
var trackStates = [];
var beatsPerMinute = 120;
var ticksPerBeat = midiFile.header.ticksPerBeat;
for (var i = 0; i < midiFile.tracks.length; i++) {
trackStates[i] = {
"nextEventIndex": 0,
"ticksToNextEvent": (
midiFile.tracks[i].length ? midiFile.tracks[i][0].deltaTime : null
)
};
}
function getNextEvent() {
var ticksToNextEvent = null;
var nextEventTrack = null;
var nextEventIndex = null;
for (var i = 0; i < trackStates.length; i++) {
if (trackStates[i].ticksToNextEvent != null && (ticksToNextEvent == null || trackStates[i].ticksToNextEvent < ticksToNextEvent)) {
ticksToNextEvent = trackStates[i].ticksToNextEvent;
nextEventTrack = i;
nextEventIndex = trackStates[i].nextEventIndex;
}
}
if (nextEventTrack != null) {
/// consume event from that track
var nextEvent = midiFile.tracks[nextEventTrack][nextEventIndex];
if (midiFile.tracks[nextEventTrack][nextEventIndex + 1]) {
trackStates[nextEventTrack].ticksToNextEvent += midiFile.tracks[nextEventTrack][nextEventIndex + 1].deltaTime;
} else {
trackStates[nextEventTrack].ticksToNextEvent = null;
}
trackStates[nextEventTrack].nextEventIndex += 1;
/// advance timings on all tracks by ticksToNextEvent
for (var i = 0; i < trackStates.length; i++) {
if (trackStates[i].ticksToNextEvent != null) {
trackStates[i].ticksToNextEvent -= ticksToNextEvent
}
}
return {
"ticksToEvent": ticksToNextEvent,
"event": nextEvent,
"track": nextEventTrack
}
} else {
return null;
}
};
//
var midiEvent;
var temporal = [];
//
function processEvents() {
function processNext() {
if (midiEvent.ticksToEvent > 0) {
var beatsToGenerate = midiEvent.ticksToEvent / ticksPerBeat;
var secondsToGenerate = beatsToGenerate / (beatsPerMinute / 60);
}
var time = (secondsToGenerate * 1000 * timeWarp) || 0;
temporal.push([ midiEvent, time]);
midiEvent = getNextEvent();
};
//
if (midiEvent = getNextEvent()) {
while(midiEvent) processNext(true);
}
};
processEvents();
return {
"getData": function() {
return clone(temporal);
}
};
};

View file

@ -1,68 +0,0 @@
/* Wrapper for accessing strings through sequential reads */
function Stream(str) {
var position = 0;
function read(length) {
var result = str.substr(position, length);
position += length;
return result;
}
/* read a big-endian 32-bit integer */
function readInt32() {
var result = (
(str.charCodeAt(position) << 24)
+ (str.charCodeAt(position + 1) << 16)
+ (str.charCodeAt(position + 2) << 8)
+ str.charCodeAt(position + 3));
position += 4;
return result;
}
/* read a big-endian 16-bit integer */
function readInt16() {
var result = (
(str.charCodeAt(position) << 8)
+ str.charCodeAt(position + 1));
position += 2;
return result;
}
/* read an 8-bit integer */
function readInt8() {
var result = str.charCodeAt(position);
position += 1;
return result;
}
function eof() {
return position >= str.length;
}
/* read a MIDI-style variable-length integer
(big-endian value in groups of 7 bits,
with top bit set to signify that another byte follows)
*/
function readVarInt() {
var result = 0;
while (true) {
var b = readInt8();
if (b & 0x80) {
result += (b & 0x7f);
result <<= 7;
} else {
/* b is the last byte */
return result + b;
}
}
}
return {
'eof': eof,
'read': read,
'readInt32': readInt32,
'readInt16': readInt16,
'readInt8': readInt8,
'readVarInt': readVarInt
}
}