MIDI.js/demo-MIDIPlayer.html

378 lines
121 KiB
HTML
Raw Normal View History

2012-02-16 05:46:03 +01:00
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns = "http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>MIDI.js - Sequencing in Javascript.</title>
<!-- soundfont.js css -->
2012-10-10 07:59:04 +02:00
<link href="./css/MIDIPlayer.css" rel="stylesheet" type="text/css" />
2012-02-16 05:46:03 +01:00
<!-- soundfont.js package -->
2012-11-06 22:06:08 +01:00
<script src="./js/Color/SpaceW3.js" type="text/javascript"></script>
2012-10-10 07:59:04 +02:00
<script src="./js/MIDI/audioDetect.js" type="text/javascript"></script>
<script src="./js/MIDI/loadPlugin.js" type="text/javascript"></script>
<script src="./js/MIDI/Plugin.js" type="text/javascript"></script>
<script src="./js/MIDI/Player.js" type="text/javascript"></script>
<script src="./js/MusicTheory/Synesthesia.js" type="text/javascript"></script>
<script src="./js/Widgets/Loader.js" type="text/javascript"></script>
2012-11-06 22:06:08 +01:00
<script src="./js/Window/Event.js" type="text/javascript"></script>
<script src="./js/Window/DOMLoader.XMLHttp.js" type="text/javascript"></script>
<script src="./js/Window/DOMLoader.script.js" type="text/javascript"></script>
2012-02-16 05:46:03 +01:00
<!-- jasmid package -->
2012-10-10 07:59:04 +02:00
<script src="./inc/jasmid/stream.js"></script>
<script src="./inc/jasmid/midifile.js"></script>
<script src="./inc/jasmid/replayer.js"></script>
2012-02-16 05:46:03 +01:00
<!-- base64 packages -->
2013-01-14 02:03:02 +01:00
<script src="./inc/Polyfill/Base64.js" type="text/javascript"></script>
2012-10-10 07:59:04 +02:00
<script src="./inc/base64binary.js" type="text/javascript"></script>
2012-02-16 05:46:03 +01:00
</head>
<body>
<img src="./images/shiverMeTimbers.gif" style="position: fixed; top: 30px; left: 1300px; z-index: 4">
<img src="./images/tuna.png" onmousedown="event.preventDefault()" width="625" style="opacity: 0.95; position: fixed; top: 0; left: 765px; z-index: 2; padding: 10px; float: left; margin-right: 20px; ">
<h1>MIDI.js - Sequencing in Javascript.</h1>
<div style="position: fixed; top: 0; left: 0; z-index: 4; border-radius: 5px; overflow: hidden;" id="colors"></div><div style="text-align: center; border-radius: 5px; position: absolute; top: -70px; left: -40px; opacity: 0.9" id="colors"></div>
<div style="margin-bottom: 50px; border: 1px solid #000; background: rgba(255,255,255,0.5); border-radius: 10px; float: left; width: 800px; padding-bottom: 100px; position: relative; z-index: 2;">
<div class="player" style="height: 42px; box-shadow: 0 -1px #000; margin-bottom: 0; border-bottom-right-radius: 0; border-bottom-left-radius: 0;">
<div style="margin: 0 auto; width: 160px; float: right;">
<input type="image" src="./images/pause.png" align="absmiddle" value="pause" onclick="pausePlayStop()" id="pausePlayStop">
<input type="image" src="./images/stop.png" align="absmiddle" value="stop" onclick="pausePlayStop(true)">
2012-10-10 07:59:04 +02:00
<input type="image" src="./images/backward.png" align="absmiddle" value="stop" onclick="player.getNextSong(-1);">
<input type="image" src="./images/forward.png" align="absmiddle" value="stop" onclick="player.getNextSong(+1);">
2012-02-16 05:46:03 +01:00
</div>
<div class="time-controls" style="float: left; margin: 0; position: relative; top: 5px;">
<span id="time1" class="time">0:00</span>
<span id="capsule">
<span id="cursor"></span>
</span>
<span id="time2" class="time" style="text-align: left;">-0:00</span>
</div>
</div>
<div id="title" style="background: rgba(255,255,0,0.5); position: relative;color: #000; z-index: -1;padding: 5px 11px 5px;">Loading API...</div>
<h3 style="margin: 0">What&rsquo;s all this hubub?</h3>
2012-06-04 01:00:45 +02:00
<p><b><a href="https://github.com/mudcube/MIDI.js">MIDI.js</a></b> (on github) ties together, and builds upon frameworks that bring MIDI generation to the browser.
2012-02-16 05:46:03 +01:00
Combine it with <a href="https://github.com/gasman/jasmid">jasmid</a> to create a web-radio MIDI stream similar to this demo...
or with <a href="https://github.com/mrdoob/three.js/">Three.js</a>, <a href="https://github.com/zz85/sparks.js/">Sparks.js</a>, or <a href="http://glsl.heroku.com/">GLSL</a> to create Audio/visual experiments.
Piano/guitar simulations, Drum machines, MIDI recording, and all kinds of certified funkitude is within your grasps!
<p><a href="https://www.google.com/chrome">Google Chrome</a> is recommended for best listening experience, it&rsquo;s timing perfection! Firefox and Safari can both perform a bit more like the piano has been drinking, arrr.</p>
2012-06-04 01:00:45 +02:00
<p>Carpe beerum, and <a href="https://github.com/mudcube/MIDI.js">commandeer</a> yer own copy!</p>
2012-02-16 05:46:03 +01:00
<h3>Description of package;</h3>
<li><a href="./js/MIDI.loadPlugin.js">MIDI.loadPlugin.js</a>: &nbsp;Decides which framework is best to use, and sends request.</li>
<li class="indent">
<pre>
// interface to download soundfont, then execute callback;
2012-11-21 10:29:05 +01:00
MIDI.loadPlugin(callback);
2012-02-16 05:46:03 +01:00
// simple example to get started;
2012-11-21 10:29:05 +01:00
MIDI.loadPlugin({
instrument: 1, // or "Acoustic Grand Piano"
callback: function() {
MIDI.noteOn(0, 100, 127, 0); // plays note once loaded
}
});
2012-02-16 05:46:03 +01:00
</pre>
</li>
<li><a href="./soundfont/soundfont-ogg.js">MIDI.Soundfont.js</a>: &nbsp;Customizable base64 Soundfont.</li>
<li class="indent square"><a href="http://mudcu.be/journal/2011/11/base64-soundfonts/">Encode your own soundfonts</a>, Drums, Guitars, and so on.</li>
<li class="indent square">You are listening to <a href="http://packages.debian.org/search?keywords=fluid-soundfont-gm">Fluid (R3) General MIDI SoundFont (GM)</a>.</li>
<li><a href="./js/MIDI.Plugin.js">MIDI.Plugin.js</a>: &nbsp;Ties together the following frameworks;</li>
<li class="indent"><pre>
MIDI.noteOn(channel, note, velocity, delay);
MIDI.noteOff(channel, note, delay);
MIDI.chordOn(channel, chord, velocity, delay);
MIDI.chordOff(channel, chord, delay);
MIDI.keyToNote = object; // A0 => 21
MIDI.noteToKey = object; // 21 => A0
</pre></li>
<li><a href="./js/MIDI.Player.js">MIDI.Player.js</a>: &nbsp;Streams the MIDI to the browser.
<li class="indent">
<pre>
MIDI.Player.currentTime = integer; // time we are at now within the song.
MIDI.Player.endTime = integer; // time when song ends.
MIDI.Player.playing = boolean; // are we playing? yes or no.
MIDI.Player.loadFile(file, callback); // load .MIDI from base64 or binary XML request.
MIDI.Player.start(); // start the MIDI track (you can put this in the loadFile callback)
MIDI.Player.resume(); // resume the MIDI track from pause.
MIDI.Player.pause(); // pause the MIDI track.
MIDI.Player.stop(); // stops all audio being played, and resets currentTime to 0.
<b>Callback whenever a note is played;</b>
MIDI.Player.removeListener(); // removes current listener.
MIDI.Player.addListener(function(data) { // set it to your own function!
var now = data.now; // where we are now
var end = data.end; // time when song ends
var channel = data.channel; // channel note is playing on
var message = data.message; // 128 is noteOff, 144 is noteOn
var note = data.note; // the note
var velocity = data.velocity; // the velocity of the note
// then do whatever you want with the information!
});
<b>Smooth animation, interpolates between onMidiEvent calls;</b>
MIDI.Player.clearAnimation(); // clears current animation.
MIDI.Player.setAnimation(function(data) {
var now = data.now; // where we are now
var end = data.end; // time when song ends
var events = data.events; // all the notes currently being processed
// then do what you want with the information!
});</pre></li>
</li>
<li><a href="./js/Color.js">Color.js</a>: &nbsp;Color conversions, music isn&rsquo;t complete without!</li>
<li class="indent"><pre>Color.Space(0xff0000, "HEX>RGB>HSL");</pre></li>
<li><a href="./js/DOMLoader.script.js">DOMLoader.script.js</a>: &nbsp;Loads scripts in synchronously, or asynchronously.</li>
<li class="indent"><pre>DOMLoader.script.add(src, callback);</pre></li>
<li><a href="./js/DOMLoader.XMLHttp.js">DOMLoader.XMLHttp.js</a>: &nbsp;Cross-browser XMLHttpd request.</li>
<li class="indent"><pre>DOMLoader.sendRequest(src, callback);</pre></li>
<li><a href="./js/MusicTheory.Synesthesia.js">MusicTheory.Synesthesia.js</a>: &nbsp;Note-to-color mappings (from Isaac Newton onwards).</li>
<h3>Many thanks to the authors of these libraries;</h3>
<li><a href="http://dev.w3.org/html5/spec/Overview.html">&lt;audio&gt;</a>: &nbsp;HTML5 specs</li>
<li><a href="https://dvcs.w3.org/hg/audio/raw-file/tip/webaudio/specification.html">WebAudioAPI</a>: &nbsp;W3C proposal by Google</li>
<li>Java package: &nbsp;<a href="https://github.com/abudaan/midibridge-js">MIDIBridge</a> by <a href="http://abumarkub.net">Daniel van der Meer</a></li>
<li class="indent square">Use this to hook up a MIDI keyboard to your browser!</li>
<li class="indent square">Access to 128 General MIDI instruments.</li>
<li>Flash package: &nbsp;<a href="http://www.schillmania.com/projects/soundmanager2/">SoundManager2</a> by <a href="http://schillmania.com">Scott Schiller</a></li>
<li><a href="https://github.com/gasman/jasmid">jasmid</a>: &nbsp;Reads MIDI file byte-code, and translats into a Javascript array.</li>
<li><a href="http://blog.danguer.com/2011/10/24/base64-binary-decoding-in-javascript/">base642binary.js</a>: &nbsp;Cleans up XML base64-requests for Web Audio API.</li>
<h3>Example(s): &nbsp;<a href="http://twitter.com/mudcube">Tweet</a> me your app to be included!</h3>
2012-06-04 01:00:45 +02:00
2012-02-16 05:46:03 +01:00
<li class="indent square">
<a href="http://mudcu.be/piano/">Color Piano</a><br>Learn piano songs without reading sheet music.
<br>Coded by <a href="http://mudcu.be/">mud</a>.</li>
<hr size=1 style="opacity: 0.25;">
2012-06-04 01:00:45 +02:00
<li class="indent square">
<a href="http://labs.uxmonk.com/simon-says/">Simon Says</a><br>This app will play a simple melody, and you try to play it back.
<br>Coded by <a href="http://uxmonk.com/">uxmonk</a>.</li>
<hr size=1 style="opacity: 0.25;">
2012-02-16 05:46:03 +01:00
<li class="indent square">
2012-06-04 01:00:45 +02:00
<a href="http://labs.uxmonk.com/brite-lite/">Brite Lite</a><br>Digital Lite-Brite with sound!
<br>Coded by <a href="http://uxmonk.com/">uxmonk</a>.</li>
2012-02-16 05:46:03 +01:00
<hr size=1 style="opacity: 0.25;">
2012-06-04 01:00:45 +02:00
2012-02-16 05:46:03 +01:00
<li class="indent square">
<a href="http://mudcu.be/midi-js/WhitneyMusicBox.html">Whitney Music Box</a><br>Beautiful HTML5 simulation of a Whitney Music Box.
2012-02-16 05:46:03 +01:00
<br>Coded by <a href="http://www.krazydad.com/">KrazyDad</a>.</li>
</div>
<script type="text/javascript">
if (typeof(console) === "undefined") var console = { log: function() { } };
// Begin loading indication.
2012-10-10 07:59:04 +02:00
var player;
2012-02-16 05:46:03 +01:00
// Tchaikovsky via Disklavier World.
var songid = 0;
var song = [
'data:audio/midi;base64,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
'data:audio/midi;base64,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
'data:audio/midi;base64,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
'data:audio/midi;base64,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
'data:audio/midi;base64,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
];
// Toggle between Pause and Play modes.
var pausePlayStop = function(stop) {
var d = document.getElementById("pausePlayStop");
if (stop) {
MIDI.Player.stop();
d.src = "./images/play.png";
} else if (MIDI.Player.playing) {
d.src = "./images/play.png";
MIDI.Player.pause(true);
} else {
d.src = "./images/pause.png";
MIDI.Player.resume();
}
};
Event.add(window, "load", function(event) {
var link = document.createElement('link');
link.href = 'http://fonts.googleapis.com/css?family=Oswald';
link.ref = "stylesheet";
link.type = "text/css";
document.body.appendChild(link);
var link = document.createElement('link');
link.href = 'http://fonts.googleapis.com/css?family=Andada';
link.ref = "stylesheet";
link.type = "text/css";
document.body.appendChild(link);
// load up the piano keys
var colors = document.getElementById("colors");
var colorElements = [];
for (var n = 0; n < 88; n ++) {
var d = document.createElement("div");
d.innerHTML = MIDI.noteToKey[n+21];
colorElements.push(d);
colors.appendChild(d);
}
//
MIDI.loader = new widgets.Loader;
2012-11-21 10:29:46 +01:00
MIDI.loadPlugin(function () {
// this is the language we are running in
var title = document.getElementById("title");
title.innerHTML = "Sound being generated with " + MIDI.lang + ".";
// this sets up the MIDI.Player and gets things going...
player = MIDI.Player;
player.timeWarp = 1; // speed the song is played back
player.loadFile(song[songid++%3], player.start);
// control the piano keys colors
var colorMap = MusicTheory.Synesthesia.map();
player.addListener(function(data) {
var pianoKey = data.note - MIDI.pianoKeyOffset;
var d = colorElements[pianoKey];
if (data.message === 144) {
d.style.background = colorMap[data.note-27].hex;
d.style.color = "#fff";
} else {
d.style.background = "";
d.style.color = "";
}
});
//
ColorSphereBackground();
MIDIPlayerPercentage(player);
//
MIDI.loader.stop();
2012-02-16 05:46:03 +01:00
});
});
/////// ///////
var MIDIPlayerPercentage = function(player) {
// update the timestamp
var time1 = document.getElementById("time1");
var time2 = document.getElementById("time2");
var capsule = document.getElementById("capsule");
var timeCursor = document.getElementById("cursor");
//
2012-10-10 07:59:04 +02:00
Event.add(capsule, "drag", function (event, self) {
Event.cancel(event);
player.currentTime = (self.x) / 420 * player.endTime;
if (player.currentTime < 0) player.currentTime = 0;
if (player.currentTime > player.endTime) player.currentTime = player.endTime;
if (self.state === "down") {
player.pause(true);
} else if (self.state === "up") {
player.resume();
2012-02-16 05:46:03 +01:00
}
});
//
function timeFormatting(n) {
var minutes = n / 60 >> 0;
var seconds = String(n - (minutes * 60) >> 0);
if (seconds.length == 1) seconds = "0" + seconds;
return minutes + ":" + seconds;
};
2012-10-10 07:59:04 +02:00
player.getNextSong = function(n) {
2012-02-16 05:46:03 +01:00
var id = Math.abs((songid += n) % song.length);
player.loadFile(song[id], player.start); // load MIDI
};
player.setAnimation(function(data, element) {
var percent = data.now / data.end;
var now = data.now >> 0; // where we are now
var end = data.end >> 0; // end of song
if (now === end) { // go to next song
var id = ++ songid % song.length;
player.loadFile(song[id], player.start); // load MIDI
}
// display the information to the user
timeCursor.style.width = (percent * 100) + "%";
time1.innerHTML = timeFormatting(now);
time2.innerHTML = "-" + timeFormatting(end - now);
});
};
/////// SPHERE ///////
var ColorSphereBackground = function() {
var d = document;
var canvas = document.createElement("canvas");
var ctx = canvas.getContext("2d");
canvas.style.cssText = "position: fixed; left: 0; top: 0; opacity: 1";
canvas.style.width = window.innerWidth + "px";
canvas.style.height = window.innerHeight + "px";
document.body.appendChild(canvas);
//
Event.add(window, "resize", function() {
canvas.style.width = window.innerWidth + "px";
canvas.style.height = window.innerHeight + "px";
ctx.drawImage(theSphere = sphere(percent), 0, 0)
});
Event.add(d, "scroll", function(e) {
var percent = 1 - document.body.scrollTop / document.body.scrollHeight;
ctx.drawImage(theSphere = sphere(percent), 0, 0);
onMouseMove();
});
var theSphere;
var px = window.innerWidth / 2;
var py = window.innerHeight / 2;
var onMouseMove = function(event) {
ctx.drawImage(theSphere, 0, 0);
if (event) {
2012-10-10 07:59:04 +02:00
var coords = Event.proxy.getCoord(event);
2012-02-16 05:46:03 +01:00
coords.x -= document.body.scrollLeft;
coords.y -= document.body.scrollTop;
px = coords.x;
py = coords.y;
} else { //
var coords = { x: px, y: py };
}
//
var x = (coords.x / window.innerWidth) * 255 - 127; // grab mouse pixel coords, center at midpoint
var y = (coords.y / window.innerHeight) * 255 - 127;
var imageData = ctx.getImageData(0, 0, canvas.width, canvas.height); // get image data
var data = imageData.data;
for(var n = 0, length = data.length; n < length; n += 4) {
data[n] = data[n] + x - y; // red (control left)
data[n + 1] = data[n + 1] - x - y; // green (control right)
data[n + 2] = data[n + 2] + y + y; // blue (control down)
}
ctx.putImageData(imageData, 0, 0);
};
Event.add(d, "mousemove", onMouseMove);
//
function sphere(top) { // create Sphere image, and apply to <canvas>
var canvas1 = document.createElement("canvas");
var ctx = canvas1.getContext("2d");
var w = 75;
var left = -20;
var top = top * -50;
canvas.width = canvas1.width = w * window.innerWidth / window.innerHeight;
canvas.height = canvas1.height = w;
ctx.fillRect(0, 0, window.innerWidth, window.innerHeight);
n = 360; while(n--) { // go through hues
var x = left + w;
var y = top + w;
var g = ctx.createLinearGradient(x, top, x, y);
g.addColorStop(0, "#000");
g.addColorStop(.5, "hsl("+((n + 60) % 360)+",100%,50%)");
g.addColorStop(1, "#FFF");
ctx.beginPath(); // draw triangle
ctx.moveTo(x, top);
ctx.lineTo(x, y);
ctx.lineTo(x + 2, y);
ctx.lineTo(x + 5, top);
ctx.fillStyle = g; // apply gradient
ctx.fill();
ctx.translate(x, y); // rotate + translate into position
ctx.rotate((1 / 360) * Math.PI * 2);
ctx.translate(-x, -y);
}
return canvas1;
};
//
var percent = 1 - document.body.scrollTop / document.body.scrollHeight;
ctx.drawImage(theSphere = sphere(percent), 0, 0)
};
</script>
<script type="text/javascript">
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-420768-7']);
_gaq.push(['_trackPageview']);
(function() {
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
})();
2012-02-16 05:46:03 +01:00
</script>
</body>
</html>