Tone.js/examples/pianoPhase.html

179 lines
4.7 KiB
HTML
Raw Normal View History

2015-08-17 00:32:06 +00:00
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>SimpleSynth</title>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
2015-12-08 05:06:58 +00:00
<link rel="icon" type="image/png" sizes="174x174" href="./style/favicon.png">
2015-08-17 00:32:06 +00:00
<script type="text/javascript" src="../build/Tone.js"></script>
<script type="text/javascript" src="./scripts/jquery.min.js"></script>
2015-12-05 19:00:44 +00:00
<script type="text/javascript" src="./scripts/draggabilly.js"></script>
<script type="text/javascript" src="./scripts/Logo.js"></script>
2015-08-17 00:32:06 +00:00
<script type="text/javascript" src="./scripts/Interface.js"></script>
<link rel="stylesheet" type="text/css" href="./style/examples.css">
<script type="text/javascript">
// jshint ignore: start
</script>
</head>
<body>
<style type="text/css">
2015-12-05 19:00:44 +00:00
#Left, #Right {
height: 200px;
width: 50%;
position: relative;
float: left;
margin-top: 5px;
margin-bottom: 5px;
2015-08-17 00:32:06 +00:00
}
2015-12-05 19:00:44 +00:00
.Button {
display: inline-block;
2015-08-17 00:32:06 +00:00
}
</style>
<div id="Content">
<div id="Title">Piano Phase</div>
<div id="Explanation">
2015-12-05 19:00:44 +00:00
By slightly slowing down the playbackRate of the Tone.Sequence in the right channel,
the two identical melodies phase against each other in interesting ways.
Composition by Steve Reich. Inspiration from Alexander Chen.
2015-08-17 00:32:06 +00:00
</div>
2015-12-05 19:00:44 +00:00
<canvas id="Left"></canvas>
<canvas id="Right"></canvas>
2015-08-17 00:32:06 +00:00
</div>
<script type="text/javascript">
//set the bpm and time signature first
2015-12-05 19:00:44 +00:00
Tone.Transport.timeSignature = [6, 4];
Tone.Transport.bpm.value = 180;
2015-08-17 00:32:06 +00:00
//L/R channel merging
2015-12-05 19:00:44 +00:00
var merge = new Tone.Merge();
2015-08-17 00:32:06 +00:00
2015-12-05 19:00:44 +00:00
//a little reverb
var reverb = new Tone.Freeverb({
2015-08-17 00:32:06 +00:00
"roomSize" : 0.2,
"wet" : 0.3
});
2015-12-05 19:00:44 +00:00
merge.chain(reverb, Tone.Master);
2015-08-17 00:32:06 +00:00
//the synth settings
var synthSettings = {
"oscillator": {
"detune": 0,
2015-12-05 19:00:44 +00:00
"type": "custom",
"partials" : [2, 1, 2, 2],
2015-08-17 00:32:06 +00:00
"phase": 0,
"volume": 0
},
"envelope": {
"attack": 0.005,
"decay": 0.3,
"sustain": 0.2,
"release": 1,
},
"portamento": 0.01,
"volume": -20
};
//left and right synthesizers
2015-12-05 19:00:44 +00:00
var synthL = new Tone.SimpleSynth(synthSettings).connect(merge.left);
var synthR = new Tone.SimpleSynth(synthSettings).connect(merge.right);
2015-08-17 00:32:06 +00:00
//the two Tone.Sequences
2015-12-05 19:00:44 +00:00
var partL = new Tone.Sequence(function(time, note){
2015-08-17 00:32:06 +00:00
synthL.triggerAttackRelease(note, "8n", time);
2015-12-05 19:00:44 +00:00
}, ["E4", "F#4", "B4", "C#5", "D5", "F#4", "E4", "C#5", "B4", "F#4", "C#5", "B4"], "8n").start();
2015-08-17 00:32:06 +00:00
2015-12-05 19:00:44 +00:00
var partR = new Tone.Sequence(function(time, note){
2015-08-17 00:32:06 +00:00
synthR.triggerAttackRelease(note, "8n", time);
2015-12-05 19:00:44 +00:00
}, ["E4", "F#4", "B4", "C#5", "D5", "F#4", "E4", "C#5", "B4", "F#4", "C#5", "B4"], "8n").start("2m");
2015-08-17 00:32:06 +00:00
//set the playback rate of the right part to be slightly slower
2015-12-05 19:00:44 +00:00
partR.playbackRate = 0.985;
2015-08-17 00:32:06 +00:00
</script>
<script id="GUI" type="text/javascript">
$(function(){
2015-12-05 19:00:44 +00:00
new Interface.Button({
key : 32,
type : "toggle",
text : "Start",
activeText : "Stop",
start : function(){
Tone.Transport.start();
},
end : function(){
Tone.Transport.stop();
}
});
//draw two circles
var leftCanvas = $("#Left");
var rightCanvas = $("#Right");
var leftContext = leftCanvas.get(0).getContext("2d");
var rightContext = rightCanvas.get(0).getContext("2d");
var canvasWidth = leftCanvas.width() * 2;
var canvasHeight = leftCanvas.height() * 2;
var radius = Math.min(canvasWidth, canvasHeight);
function sizeCanvas(){
canvasWidth = leftCanvas.width() * 2;
canvasHeight = leftCanvas.height() * 2;
radius = Math.min(canvasWidth, canvasHeight);
leftContext.canvas.width = canvasWidth;
leftContext.canvas.height = canvasHeight;
rightContext.canvas.width = canvasWidth;
rightContext.canvas.height = canvasHeight;
}
$(window).on("resize", sizeCanvas);
sizeCanvas();
var twoPi = Math.PI * 2;
2015-08-17 00:32:06 +00:00
function loop(){
requestAnimationFrame(loop);
2015-12-05 19:00:44 +00:00
//draw the left progress
leftContext.clearRect(0, 0, canvasWidth, canvasHeight);
leftContext.fillStyle = "#3833ED";
leftContext.save();
leftContext.translate(canvasWidth / 2, canvasHeight / 2);
leftContext.rotate(-Math.PI / 2);
leftContext.beginPath();
leftContext.moveTo(0, 0);
leftContext.arc(0, 0, radius/2, 0, twoPi * partL.progress, false);
leftContext.fill();
leftContext.restore();
//draw the left progress
rightContext.clearRect(0, 0, canvasWidth, canvasHeight);
rightContext.fillStyle = "#ED3333";
rightContext.save();
rightContext.translate(canvasWidth / 2, canvasHeight / 2);
rightContext.rotate(-Math.PI / 2);
rightContext.beginPath();
rightContext.moveTo(0, 0);
rightContext.arc(0, 0, radius/2, 0, twoPi * partR.progress, false);
rightContext.fill();
rightContext.restore();
2015-08-17 00:32:06 +00:00
}
loop();
});
</script>
</style>
</body>
</html>