2016-09-29 14:34:00 +00:00
<!DOCTYPE html>
< html >
< head >
< meta charset = "utf-8" >
< title > Transport Sync< / title >
< meta name = "viewport" content = "width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" >
< link rel = "icon" type = "image/png" sizes = "174x174" href = "./style/favicon.png" >
2017-03-18 16:35:37 +00:00
< script src = "../build/Tone.js" > < / script >
< script src = "./scripts/jquery.min.js" > < / script >
< script src = "./scripts/draggabilly.js" > < / script >
< script src = "https://tonejs.github.io/Logo/build/Logo.js" > < / script >
< script src = "./scripts/StartAudioContext.js" > < / script >
< script src = "./scripts/Interface.js" > < / script >
2016-09-29 14:34:00 +00:00
< link rel = "stylesheet" type = "text/css" href = "./style/examples.css" >
2017-03-18 16:35:37 +00:00
< script >
2016-09-29 14:34:00 +00:00
// jshint ignore: start
< / script >
< / head >
< body >
< style type = "text/css" >
#Left, #Right {
height: 200px;
width: 50%;
position: relative;
float: left;
margin-top: 5px;
margin-bottom: 5px;
}
.Button {
display: inline-block;
}
#TransportContainer{
2016-10-01 22:28:32 +00:00
margin-top: 5px;
margin-bottom: 5px;
2016-09-29 14:34:00 +00:00
width: 100%;
height: 100px;
position: relative;
}
2016-10-01 22:28:32 +00:00
#DawCanvas {
2016-09-29 14:34:00 +00:00
width: 100%;
height: 100%;
position: absolute;
top: 0px;
left: 0px;
}
#Bar {
width: 2px;
height: 94%;
position: absolute;
top: 3%;
left: 0%;
background-color: black;
}
2016-10-01 22:28:32 +00:00
#Images {
overflow: hidden;
height: 0px;
width: 100%;
}
2016-09-29 14:34:00 +00:00
< / style >
< div id = "Content" >
< div id = "Title" > Transport Sync< / div >
< div id = "Explanation" >
2016-10-01 22:30:53 +00:00
This beat is composed of 3 independent Players each with a different loop length, synced to the Transport to start at different times and different offsets. The players stay synchronized to the position and offset of the Transport.
2016-09-29 14:34:00 +00:00
< / div >
< div id = "TransportContainer" >
2016-10-01 22:28:32 +00:00
< canvas id = "DawCanvas" > < / canvas >
2016-09-29 14:34:00 +00:00
< div id = "Bar" > < / div >
< / div >
2016-10-01 22:28:32 +00:00
< div id = "Images" >
< img src = "./audio/loop/snare.png" id = "Snare" >
< img src = "./audio/loop/kick.png" id = "Kick" >
< img src = "./audio/loop/hh.png" id = "HH" >
< / div >
2016-09-29 14:34:00 +00:00
< / div >
2017-03-18 16:35:37 +00:00
< script >
2016-09-29 14:34:00 +00:00
2016-10-01 22:28:32 +00:00
Tone.Transport.bpm.value = 108;
2016-09-29 14:34:00 +00:00
var kick = new Tone.Player({
2016-09-29 14:42:35 +00:00
url : "./audio/loop/kick.mp3",
2016-09-29 14:34:00 +00:00
loop : true
}).toMaster().sync().start(0);
var snare = new Tone.Player({
2016-09-29 14:42:35 +00:00
url : "./audio/loop/snare.mp3",
2016-09-29 14:34:00 +00:00
loop : true
}).toMaster().sync().start("2n");
var hh = new Tone.Player({
2016-09-29 14:42:35 +00:00
url : "./audio/loop/hh.mp3",
2016-09-29 14:34:00 +00:00
loop : true
2016-10-01 22:28:32 +00:00
}).toMaster().sync().start("3:3", "4n"); //start with an offset
2016-09-29 14:34:00 +00:00
Tone.Transport.loop = true;
Tone.Transport.loopStart = "4m";
2016-10-01 22:28:32 +00:00
Tone.Transport.loopEnd = "8m";
2016-09-29 14:34:00 +00:00
< / script >
2017-03-18 16:35:37 +00:00
< script id = "GUI" >
2016-10-01 22:28:32 +00:00
2016-09-29 14:34:00 +00:00
$(function(){
2016-12-21 04:03:36 +00:00
Interface.Loader();
2016-09-29 14:34:00 +00:00
var dragging = false;
window.slider = new Interface.Slider({
max : Tone.Transport.loopEnd,
start : function(){
dragging = true;
if (started){
Tone.Transport.pause();
}
},
end : function(){
dragging = false;
if (started){
Tone.Transport.start("+0.1");
}
},
drag : function(val){
Tone.Transport.seconds = val;
}
})
var started = false;
2016-12-21 04:03:36 +00:00
Interface.Button({
2016-09-29 14:34:00 +00:00
key : 32,
type : "toggle",
text : "Start",
activeText : "Pause",
start : function(){
started = true;
Tone.Transport.start("+0.1");
},
end : function(){
started = false;
Tone.Transport.pause();
}
});
function loop(){
requestAnimationFrame(loop);
if (!dragging){
slider.value(Tone.Transport.seconds);
}
var progress = Tone.Transport.seconds / Tone.Transport.loopEnd;
$("#Bar").css("left", (progress * 100).toFixed(2) + "%");
}
loop();
});
2016-10-01 22:28:32 +00:00
var loadedPromise = new Promise(function(done){
Tone.Buffer.on("load", done);
});
//when the images have loaded
$(window).load(function(){
// draw the canvas to represent the 3 tracks
window.context = $("#DawCanvas").get(0).getContext("2d");
// size the canvas
function draw(){
context.canvas.width = $(window).width() * 2;
context.canvas.height = $(window).height() * 2;
var barHeight = context.canvas.height / 3;
var barMargin = 40;
var width = context.canvas.width;
var totalSeconds = Tone.Transport.loopEnd;
//seconds to width pixel conversion
function s2w(seconds){
return (seconds / totalSeconds) * width;
}
function drawBuffer(img, duration, yOffset, startTime, imgOffset){
imgOffset = imgOffset || 0;
imgLeft = img.width * imgOffset;
imgWidth = img.width * (1 - imgOffset);
yOffset *= barHeight;
imgPixels = s2w(duration);
for (var i = startTime; i < totalSeconds ; i + = duration ) {
context.drawImage(img,
imgLeft, 0, imgWidth, img.height,
s2w(i), yOffset + barMargin, imgPixels * (1 - imgOffset),
barHeight - barMargin * 2)
context.strokeRect(s2w(i), yOffset + barMargin, imgPixels,
barHeight - barMargin * 2)
}
}
2016-10-01 22:33:02 +00:00
context.strokeStyle = "white";
context.lineWidth = 3;
2016-10-01 22:28:32 +00:00
// draw the kick
drawBuffer($("#Kick").get(0), kick.buffer.duration, 0, 0);
drawBuffer($("#Snare").get(0), snare.buffer.duration, 1, Tone.Transport.toSeconds("2n"));
drawBuffer($("#HH").get(0), hh.buffer.duration, 2, Tone.Transport.toSeconds("3:3"), 0.5);
drawBuffer($("#HH").get(0), hh.buffer.duration, 2, Tone.Transport.toSeconds("4m"));
}
$(window).resize(draw);
//draw it for the first time when it's loaded
loadedPromise.then(draw);
});
2016-09-29 14:34:00 +00:00
< / script >
< / style >
< / body >
2017-03-18 16:35:37 +00:00
< / html >