updated examples with new interfaces

This commit is contained in:
tambien 2019-01-08 20:21:29 -05:00
parent b4b56f213e
commit c21e5758d8
53 changed files with 4672 additions and 13882 deletions

View file

@ -4,139 +4,56 @@
<meta charset="utf-8"> <meta charset="utf-8">
<title>Analyser</title> <title>Analyser</title>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"> <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<link rel="icon" type="image/png" sizes="174x174" href="./style/favicon.png"> <link rel="icon" type="image/png" sizes="174x174" href="./favicon.png">
<script src="https://unpkg.com/@webcomponents/webcomponentsjs@^2/webcomponents-bundle.js"></script>
<script src="../build/Tone.js"></script> <script src="../build/Tone.js"></script>
<script src="./scripts/jquery.min.js"></script> <script src="./js/tonejs-ui.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>
<link rel="stylesheet" type="text/css" href="./style/examples.css">
<script>
// jshint ignore: start
</script>
<style type="text/css">
canvas {
margin-top: 2px;
width: 100%;
height: 255px;
}
</style>
</head> </head>
<body> <body>
<div id="Content" class="FullScreen"> <style>
<div id="Title">Analyser</div> tone-oscilloscope, tone-fft {
<div id="Explanation"> width: 100%;
<a href="https://tonejs.github.io/docs/#Analyser" target="_blank">Tone.Analyser</a> height: 44px;
analyses the incoming audio to produce a TypedArray of either the border-radius: 22px;
<a href="https://en.wikipedia.org/wiki/Fast_Fourier_transform" target="_blank">FFT data</a> background-color: black;
or the waveform. The default <code>returnType</code> is "byte" which returns values }
in the range 0-255. </style>
</div> <tone-example>
<tone-loader></tone-loader>
</div> <tone-explanation label="Analyser">
<a href="https://tonejs.github.io/docs/FFT" target="_blank">Tone.FFT</a>
returns the amplitude of the incoming signal at different frequencies.
<a href="https://tonejs.github.io/docs/FFT" target="_blank">Tone.Waveform</a>
returns the signal value between 0-1.
</tone-explanation>
<script> <tone-content>
//analyse the frequency/amplitude of the incoming signal <tone-oscilloscope></tone-oscilloscope>
var fft = new Tone.FFT(32); <tone-fft></tone-fft>
<tone-play-toggle></tone-play-toggle>
</tone-content>
//get the waveform data for the audio <tone-drawer label="Components">
var waveform = new Tone.Waveform(1024); <tone-player collapsed></tone-player>
</tone-drawer>
</tone-example>
<script type="text/javascript">
var player = new Tone.Player({ var player = new Tone.Player({
"url" : "./audio/FWDL.[mp3|ogg]", "url" : "./audio/FWDL.[mp3|ogg]",
"loop" : true "loop" : true
}).fan(fft, waveform).toMaster(); }).toMaster();
//connect the UI with the components
document.querySelector("tone-player").bind(player);
document.querySelector("tone-play-toggle").bind(player);
document.querySelector("tone-oscilloscope").bind(player);
document.querySelector("tone-fft").bind(player);
// GUI //
Interface.Button({
key : 32,
type : "toggle",
text : "Start",
activeText : "Stop",
start : function(){
player.start();
},
end : function(){
player.stop();
}
});
//drawing the FFT
var fftContext = $("<canvas>",{
"id" : "fft"
}).appendTo("#Content").get(0).getContext("2d");
function drawFFT(values){
fftContext.clearRect(0, 0, canvasWidth, canvasHeight);
var barWidth = canvasWidth / fft.size;
for (var i = 0, len = values.length; i < len; i++){
var x = canvasWidth * (i / len);
var y = (values[i] + 140) * 2;
fftContext.fillStyle = "rgba(0, 0, 0, " + i/len + ")";
fftContext.fillRect(x, canvasHeight - y, barWidth, canvasHeight);
}
}
//the waveform data
var waveContext = $("<canvas>", {
"id" : "waveform"
}).appendTo("#Content").get(0).getContext("2d");
var waveformGradient;
function drawWaveform(values){
//draw the waveform
waveContext.clearRect(0, 0, canvasWidth, canvasHeight);
waveContext.beginPath();
waveContext.lineJoin = "round";
waveContext.lineWidth = 6;
waveContext.strokeStyle = waveformGradient;
waveContext.moveTo(0, (values[0] + 1) / 2 * canvasHeight);
for (var i = 1, len = values.length; i < len; i++){
var val = (values[i] + 1) / 2;
var x = canvasWidth * (i / len);
var y = val * canvasHeight;
waveContext.lineTo(x, y);
}
waveContext.stroke();
}
//size the canvases
var canvasWidth, canvasHeight;
function sizeCanvases(){
canvasWidth = $("#fft").width();
canvasHeight = $("#fft").height();
waveContext.canvas.width = canvasWidth;
fftContext.canvas.width = canvasWidth;
waveContext.canvas.height = canvasHeight;
fftContext.canvas.height = canvasHeight;
//make the gradient
waveformGradient = waveContext.createLinearGradient(0, 0, canvasWidth, canvasHeight);
waveformGradient.addColorStop(0, "#ddd");
waveformGradient.addColorStop(1, "#000");
}
sizeCanvases();
$(window).resize(sizeCanvases);
function loop(){
requestAnimationFrame(loop);
//get the fft data and draw it
var fftValues = fft.getValue();
drawFFT(fftValues);
//get the waveform valeus and draw it
var waveformValues = waveform.getValue();
drawWaveform(waveformValues);
}
loop();
</script> </script>
</body> </body>
</html> </html>

View file

@ -2,29 +2,23 @@
<html> <html>
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<title>ANIMATION SYNC</title> <title>Analyser</title>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"> <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<link rel="icon" type="image/png" sizes="174x174" href="./style/favicon.png"> <link rel="icon" type="image/png" sizes="174x174" href="./favicon.png">
<script src="https://unpkg.com/@webcomponents/webcomponentsjs@^2/webcomponents-bundle.js"></script>
<script src="../build/Tone.js"></script> <script src="../build/Tone.js"></script>
<script src="./scripts/jquery.min.js"></script> <script src="./js/tonejs-ui.js"></script>
<script src="./scripts/draggabilly.js"></script>
<script src="./scripts/StartAudioContext.js"></script>
<script src="./scripts/Interface.js"></script>
<script src="https://tonejs.github.io/Logo/build/Logo.js"></script>
<link rel="stylesheet" type="text/css" href="./style/examples.css"> </head>
<body>
<script>
// jshint ignore: start
</script>
<style type="text/css"> <style type="text/css">
#Notes{ #Notes{
width: 100%; width: 100%;
height: 20px; height: 20px;
margin-top: 3px;
position: relative; position: relative;
margin-bottom: 10px;
} }
.Note { .Note {
width: 20%; width: 20%;
@ -33,17 +27,20 @@
float: left; float: left;
background-color: black; background-color: black;
opacity: 0; opacity: 0;
transition: opacity 0.5s;
}
.Note.active {
opacity: 1;
transition-duration: 0.1s;
} }
</style> </style>
</head> <tone-example>
<body> <tone-explanation label="Synchronizing Visuals">
<div id="Content">
<div id="Title">Synchronizing Visuals</div>
<div id="Explanation">
Audio scheduling and rendering visuals should always be kept separate. Instead of triggering visuals from within a scheduled event callback, schedule a 'deferred' callback using Tone.Draw which will be invoked on an animation frame at the exact moment of the scheduled event. Audio scheduling and rendering visuals should always be kept separate. Instead of triggering visuals from within a scheduled event callback, schedule a 'deferred' callback using Tone.Draw which will be invoked on an animation frame at the exact moment of the scheduled event.
<br><br> <br><br>
For more information see <a href="https://github.com/Tonejs/Tone.js/wiki/Performance">this wiki article</a>. For more information see <a href="https://github.com/Tonejs/Tone.js/wiki/Performance">this wiki article</a>.
</div> </tone-explanation>
<tone-content>
<div id="Notes"> <div id="Notes">
<div id="C4" class="Note"></div> <div id="C4" class="Note"></div>
<div id="E4" class="Note"></div> <div id="E4" class="Note"></div>
@ -51,10 +48,15 @@
<div id="B4" class="Note"></div> <div id="B4" class="Note"></div>
<div id="D5" class="Note"></div> <div id="D5" class="Note"></div>
</div> </div>
</div> <tone-play-toggle></tone-play-toggle>
</tone-content>
<script id="ToneCode"> <tone-drawer>
<tone-synth collapsed></tone-synth>
</tone-drawer>
</tone-example>
<script type="text/javascript">
var piano = new Tone.Synth({ var piano = new Tone.Synth({
"oscillator" : { "oscillator" : {
"type" : "fmsine4", "type" : "fmsine4",
@ -68,29 +70,22 @@
// Draw.schedule takes a callback and a time to invoke the callback // Draw.schedule takes a callback and a time to invoke the callback
Tone.Draw.schedule(function(){ Tone.Draw.schedule(function(){
//the callback synced to the animation frame at the given time //the callback synced to the animation frame at the given time
$("#"+note).css("opacity", 1).animate({"opacity" : 0}, 300) const noteElement = document.querySelector("#"+note);
noteElement.classList.add("active");
setTimeout(() => {
noteElement.classList.remove("active");
}, 100);
}, time); }, time);
}, ["C4", "E4", "G4", "B4", "D5"]).start(0); }, ["C4", "E4", "G4", "B4", "D5"]).start(0);
loop.interval = "16n"; loop.interval = "16n";
Tone.Transport.lookAhead = 0.5;
// GUI // //connect the UI with the components
document.querySelector("tone-play-toggle").bind(Tone.Transport);
document.querySelector("tone-synth").bind(piano);
Tone.Transport.lookAhead = 0.5
Interface.Button({
key : 32,
type : "toggle",
text : "Start",
activeText : "Stop",
start : function(){
Tone.Transport.start("+0.1");
},
end : function(){
Tone.Transport.stop();
}
});
</script> </script>
</body> </body>
</html> </html>

Binary file not shown.

After

Width:  |  Height:  |  Size: 227 KiB

View file

@ -2,40 +2,38 @@
<html> <html>
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<title>CymbalSynth</title> <title>MetalSynth</title>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"> <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<link rel="icon" type="image/png" sizes="174x174" href="./style/favicon.png"> <link rel="icon" type="image/png" sizes="174x174" href="./favicon.png">
<script src="https://unpkg.com/@webcomponents/webcomponentsjs@^2/webcomponents-bundle.js"></script>
<script src="../build/Tone.js"></script> <script src="../build/Tone.js"></script>
<script src="./scripts/jquery.min.js"></script> <script src="./js/tonejs-ui.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>
<link rel="stylesheet" type="text/css" href="./style/examples.css">
<script>
// jshint ignore: start
</script>
</head> </head>
<body> <body>
<div id="Content"> <tone-example>
<div id="Title">Bembe</div> <tone-explanation label="Bembe">
<div id="Explanation"> <a href="https://tonejs.github.io/docs/MetalSynth">Tone.MetalSynth</a>
<a href="https://tonejs.github.io/docs/#MetalSynth">Tone.MetalSynth</a>
creates metallic, inharmonic sounds using 6 creates metallic, inharmonic sounds using 6
<a href="https://tonejs.github.io/docs/#FMOscillator">Tone.FMOscillators</a> <a href="https://tonejs.github.io/docs/FMOscillator">Tone.FMOscillators</a>
with a tuning based on the TR-808 Cymbal. with a tuning based on the TR-808 Cymbal.
<a href="https://tonejs.github.io/docs/#MembraneSynth">Tone.MembraneSynth</a> <a href="https://tonejs.github.io/docs/MembraneSynth">Tone.MembraneSynth</a>
makes kick and tom-like sounds using a frequency envelope which is triggered on notes attack. makes kick and tom-like sounds using a frequency envelope which is triggered on notes attack.
</div> </tone-explanation>
</div>
<script> <tone-content>
<tone-play-toggle></tone-play-toggle>
</tone-content>
<tone-drawer>
<tone-metal-synth collapsed></tone-metal-synth>
<tone-membrane-synth collapsed></tone-membrane-synth>
</tone-drawer>
</tone-example>
<script type="text/javascript">
var bell = new Tone.MetalSynth({ var bell = new Tone.MetalSynth({
"harmonicity" : 12, "harmonicity" : 12,
"resonance" : 800, "resonance" : 800,
@ -49,7 +47,11 @@
var bellPart = new Tone.Sequence(function(time, freq){ var bellPart = new Tone.Sequence(function(time, freq){
bell.frequency.setValueAtTime(freq, time, Math.random()*0.5 + 0.5); bell.frequency.setValueAtTime(freq, time, Math.random()*0.5 + 0.5);
bell.triggerAttack(time); bell.triggerAttack(time);
}, [300, null, 200, null, 200, 200, null, 200, null, 200, null, 200], "8t").start(0); }, [[300, null, 200],
[null, 200, 200],
[null, 200, null],
[200, null, 200]
], "4n").start(0);
// bellPart.loop = true; // bellPart.loop = true;
// bellPart.loopEnd = "1m"; // bellPart.loopEnd = "1m";
@ -73,20 +75,10 @@
Tone.Transport.bpm.value = 115; Tone.Transport.bpm.value = 115;
// GUI // //bind the interface
document.querySelector("tone-play-toggle").bind(Tone.Transport);
Interface.Button({ document.querySelector("tone-metal-synth").bind(bell);
key : 32, document.querySelector("tone-membrane-synth").bind(conga);
type : "toggle",
text : "Start",
activeText : "Stop",
start : function(){
Tone.Transport.start("+0.1");
},
end : function(){
Tone.Transport.stop();
}
});
</script> </script>
</body> </body>

View file

@ -4,48 +4,51 @@
<meta charset="utf-8"> <meta charset="utf-8">
<title>Buses</title> <title>Buses</title>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"> <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<link rel="icon" type="image/png" sizes="174x174" href="./style/favicon.png"> <link rel="icon" type="image/png" sizes="174x174" href="./favicon.png">
<script src="https://unpkg.com/@webcomponents/webcomponentsjs@^2/webcomponents-bundle.js"></script>
<script src="../build/Tone.js"></script> <script src="../build/Tone.js"></script>
<script src="./scripts/jquery.min.js"></script> <script src="./js/tonejs-ui.js"></script>
<script src="./scripts/draggabilly.js"></script> <style>
<script src="./scripts/StartAudioContext.js"></script> tone-content tone-slider {
<script src="./scripts/Interface.js"></script> display: block;
<script src="https://tonejs.github.io/Logo/build/Logo.js"></script> margin-top: 10px;
<script src="./scripts/Keyboard.js"></script> }
</style>
<link rel="stylesheet" type="text/css" href="./style/examples.css">
<script>
// jshint ignore: start
</script>
</head> </head>
<body> <body>
<div id="Content"> <tone-example>
<div id="Title">Buses</div> <tone-explanation label="Buses">
<div id="Explanation">
Buses make it easy to share effects across many instruments. <code>send</code> Buses make it easy to share effects across many instruments. <code>send</code>
audio to a named bus from an instrument and then <code>receive</code> that audio to a named bus from an instrument and then <code>receive</code> that
channel on your effect. The gain values are all in decibels. channel on your effect. The gain values are all in decibels.
<br><br> <br><br>
Docs on <a href="https://tonejs.github.io/docs/#Tone.send">send</a> and Docs on <a href="https://tonejs.github.io/docs/Tone.send">send</a> and
<a href="https://tonejs.github.io/docs/#Tone.receive">receive</a>. <a href="https://tonejs.github.io/docs/Tone.receive">receive</a>.
</div> </tone-explanation>
<div id="Sliders"></div> <tone-content>
<div id="Keyboard"></div> <tone-piano></tone-piano>
</div> <tone-slider label="Chorus Send" min="-100" max="0" value="-100" units="db"></tone-slider>
<script> <tone-slider label="Chebyshev Send" min="-100" max="0" value="-100" units="db"></tone-slider>
<tone-slider label="Freeverb Send" min="-100" max="0" value="-100" units="db"></tone-slider>
</tone-content>
<tone-drawer collapsed>
<tone-chorus collapsed></tone-chorus>
<tone-chebyshev collapsed></tone-chebyshev>
<tone-freeverb collapsed></tone-freeverb>
<tone-synth collapsed></tone-synth>
</tone-drawer>
</tone-example>
<script type="text/javascript">
//the synth //the synth
var synth = new Tone.Synth().toMaster() var synth = new Tone.Synth().toMaster().set("envelope.attack", 0.04);
.set("envelope.attack", 0.04);
//send audio to each of the effect channels //send audio to each of the effect channels
var chorusSend = synth.send("chorus", -Infinity); var chorusSend = synth.send("chorus", -Infinity);
var chebySend = synth.send("cheby", -Infinity); var chebySend = synth.send("cheby", -Infinity);
var autowahSend = synth.send("autowah", -Infinity);
var reverbSend = synth.send("reverb", -Infinity); var reverbSend = synth.send("reverb", -Infinity);
//make some effects //make some effects
@ -61,51 +64,21 @@
.receive("reverb") .receive("reverb")
.toMaster(); .toMaster();
//bind the interface
// GUI // document.querySelector("tone-chorus").bind(chorus);
document.querySelector("tone-chebyshev").bind(cheby);
Interface.Slider({ document.querySelector("tone-freeverb").bind(reverb);
name : "Chebyshev", document.querySelector("tone-synth").bind(synth);
parent : $("#Sliders"), document.querySelector("tone-piano").bind(synth);
min : -100, document.querySelector("[label=\"Chorus Send\"]").addEventListener("change", e => {
max : 0, chorusSend.gain.value = e.detail;
drag : function(val){
chebySend.gain.value = val;
}
}); });
document.querySelector("[label=\"Chebyshev Send\"]").addEventListener("change", e => {
Interface.Slider({ chebySend.gain.value = e.detail;
name : "Chorus",
parent : $("#Sliders"),
min : -100,
max : 0,
drag : function(val){
chorusSend.gain.value = val;
}
}); });
document.querySelector("[label=\"Freeverb Send\"]").addEventListener("change", e => {
Interface.Slider({ reverbSend.gain.value = e.detail;
name : "Freeverb",
parent : $("#Sliders"),
min : -100,
max : 0,
drag : function(val){
reverbSend.gain.value = val;
}
}); });
/**
* the keyboard
*/
var keyboard = Interface.Keyboard();
keyboard.keyDown = function (note) {
synth.triggerAttack(note);
};
keyboard.keyUp = function () {
synth.triggerRelease();
};
</script> </script>
</body> </body>
</html> </html>

View file

@ -2,91 +2,61 @@
<html> <html>
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<title>Transport Sync</title> <title>DAW</title>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"> <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<link rel="icon" type="image/png" sizes="174x174" href="./style/favicon.png"> <link rel="icon" type="image/png" sizes="174x174" href="./favicon.png">
<script src="https://unpkg.com/@webcomponents/webcomponentsjs@^2/webcomponents-bundle.js"></script>
<script src="../build/Tone.js"></script> <script src="../build/Tone.js"></script>
<script src="./scripts/jquery.min.js"></script> <script src="./js/tonejs-ui.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>
<link rel="stylesheet" type="text/css" href="./style/examples.css">
<script>
// jshint ignore: start
</script>
</head>
<body>
<style type="text/css"> <style type="text/css">
tone-play-toggle {
#Left, #Right { margin-bottom: 10px;
height: 200px; }
width: 50%; #tracks {
position: relative; position: relative;
float: left; width: calc(100% - 10px);
margin-top: 5px; margin-left: 10px;
margin-bottom: 5px;
} }
.Button { #progress {
display: inline-block; width: 1px;
}
#TransportContainer{
margin-top: 5px;
margin-bottom: 5px;
width: 100%;
height: 100px;
position: relative;
}
#DawCanvas {
width: 100%;
height: 100%; height: 100%;
position: absolute;
top: 0px;
left: 0px;
}
#Bar {
width: 2px;
height: 94%;
position: absolute;
top: 3%;
left: 0%; left: 0%;
position: absolute;
background-color: black; background-color: black;
} }
img {
#Images {
overflow: hidden;
height: 0px;
width: 100%; width: 100%;
height: 200px;
} }
</style> </style>
<div id="Content"> </head>
<div id="Title">Transport Sync</div> <body>
<div id="Explanation"> <tone-example>
<tone-loader></tone-loader>
<tone-explanation label="DAW">
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. 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.
</div> </tone-explanation>
<div id="TransportContainer">
<canvas id="DawCanvas"></canvas>
<div id="Bar"></div>
</div>
<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>
</div>
<script> <tone-content>
<tone-play-toggle></tone-play-toggle>
<div id="tracks">
<div id="progress"></div>
<img src="./audio/loop/drum_loop.png">
</div>
<tone-position min="-1"></tone-position>
</tone-content>
</tone-example>
<script type="text/javascript">
//set the transport
Tone.Transport.bpm.value = 108; Tone.Transport.bpm.value = 108;
Tone.Transport.loop = true;
Tone.Transport.loopStart = "4m";
Tone.Transport.loopEnd = "8m";
var kick = new Tone.Player({ var kick = new Tone.Player({
url : "./audio/loop/kick.[mp3|ogg]", url : "./audio/loop/kick.[mp3|ogg]",
@ -103,117 +73,11 @@
loop : true loop : true
}).toMaster().sync().start("3:3", "4n"); //start with an offset }).toMaster().sync().start("3:3", "4n"); //start with an offset
Tone.Transport.loop = true; //bind the transport
Tone.Transport.loopStart = "4m"; document.querySelector("tone-play-toggle").bind(Tone.Transport);
Tone.Transport.loopEnd = "8m"; document.querySelector("tone-position").bind(Tone.Transport);
document.querySelector("tone-position").addEventListener("position", e => {
// GUI // document.querySelector("#progress").style = `left: ${e.detail*100}%`;
Interface.Loader();
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;
Interface.Button({
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();
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)
}
}
context.strokeStyle = "white";
context.lineWidth = 3;
// 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);
}); });
</script> </script>
</body> </body>

View file

@ -4,61 +4,49 @@
<meta charset="utf-8"> <meta charset="utf-8">
<title>Envelope</title> <title>Envelope</title>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"> <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<link rel="icon" type="image/png" sizes="174x174" href="./style/favicon.png"> <link rel="icon" type="image/png" sizes="174x174" href="./favicon.png">
<script src="https://unpkg.com/@webcomponents/webcomponentsjs@^2/webcomponents-bundle.js"></script>
<script src="../build/Tone.js"></script> <script src="../build/Tone.js"></script>
<script src="./scripts/jquery.min.js"></script> <script src="./js/tonejs-ui.js"></script>
<script src="./scripts/draggabilly.js"></script>
<script src="./scripts/StartAudioContext.js"></script>
<script src="./scripts/Interface.js"></script>
<script src="https://tonejs.github.io/Logo/build/Logo.js"></script>
<link rel="stylesheet" type="text/css" href="./style/examples.css">
<script>
// jshint ignore: start
</script>
</head> </head>
<body> <body>
<style type="text/css"> <style type="text/css">
img { img {
display: block;
margin: 5px auto;
width: 300px!important; width: 300px!important;
} }
.y { tone-trigger {
float: left; margin-bottom: 10px;
height: 290px!important;
}
#Sliders {
float: left;
position: relative;
width: calc(100% - 100px);
}
.Button {
clear: both;
} }
</style> </style>
<div id="Content"> <tone-example>
<div id="Title">Envelope</div> <tone-explanation label="Envelope">
<div id="Explanation">
Envelopes ramp amplitude, frequency or any other parameter over time. Envelopes ramp amplitude, frequency or any other parameter over time.
<a href="https://tonejs.github.io/docs/#Envelope">Tone.Envelope</a> and the classes that extend it <a href="https://tonejs.github.io/docs/Envelope">Tone.Envelope</a> and the classes that extend it
implement an <a href="https://en.wikipedia.org/wiki/Synthesizer#ADSR_envelope" target="_blank">ADSR</a> envelope type implement an <a href="https://en.wikipedia.org/wiki/Synthesizer#ADSR_envelope" target="_blank">ADSR</a> envelope type
which splits its ramp into four distinct phases: Attack, Decay, Sustain, Release. which splits its ramp into four distinct phases: Attack, Decay, Sustain, Release.
<img src="https://upload.wikimedia.org/wikipedia/commons/e/ea/ADSR_parameter.svg"> <img src="https://upload.wikimedia.org/wikipedia/commons/e/ea/ADSR_parameter.svg">
</div> </tone-explanation>
<div id="Sliders"></div>
</div>
<script> <tone-content>
<tone-trigger></tone-trigger>
<tone-envelope><tone-envelope>
</tone-content>
<tone-drawer collapsed>
<tone-oscillator collapsed frequency><tone-oscillator>
</tone-drawer>
</tone-example>
<script type="text/javascript">
var env = new Tone.AmplitudeEnvelope({ var env = new Tone.AmplitudeEnvelope({
"attack" : 0.11, "attack" : 0.11,
"decay" : 0.21, "decay" : 0.21,
"sustain" : 0.09, "sustain" : 0.5,
"release" : 1.2 "release" : 1.2
}).toMaster(); }).toMaster();
@ -70,58 +58,16 @@
"volume" : -8, "volume" : -8,
}).connect(env).start(); }).connect(env).start();
// GUI // //bind the interface
document.querySelector("tone-envelope").bind(env);
document.querySelector("tone-oscillator").bind(osc);
Interface.Slider({ document.querySelector("tone-trigger").addEventListener("change", e => {
param : "attack", if (e.detail){
name : "attack",
parent : $("#Sliders"),
tone : env,
min : 0.005,
max : 1,
exp : 2,
});
Interface.Slider({
param : "decay",
name : "decay",
parent : $("#Sliders"),
tone : env,
min : 0.005,
max : 1,
exp : 2,
});
Interface.Slider({
param : "release",
name : "release",
parent : $("#Sliders"),
tone : env,
min : 0.2,
max : 2,
exp : 2,
});
Interface.Slider({
param : "sustain",
name : "sustain",
tone : env,
axis : "y",
min : 0.0,
max : 1,
exp : 2,
});
Interface.Button({
text : "Trigger Attack",
activeText : "Trigger Release",
key : 32, //spacebar
start : function(){
env.triggerAttack(); env.triggerAttack();
}, } else {
end : function(){
env.triggerRelease(); env.triggerRelease();
}, }
}); });
</script> </script>
</body> </body>

View file

@ -2,42 +2,41 @@
<html> <html>
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<title>SCORE</title> <title>Events</title>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"> <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<link rel="icon" type="image/png" sizes="174x174" href="./style/favicon.png"> <link rel="icon" type="image/png" sizes="174x174" href="./favicon.png">
<script src="https://unpkg.com/@webcomponents/webcomponentsjs@^2/webcomponents-bundle.js"></script>
<script src="../build/Tone.js"></script> <script src="../build/Tone.js"></script>
<script src="./scripts/jquery.min.js"></script> <script src="./js/tonejs-ui.js"></script>
<script src="./scripts/draggabilly.js"></script>
<script src="./scripts/StartAudioContext.js"></script>
<script src="./scripts/Interface.js"></script>
<script src="https://tonejs.github.io/Logo/build/Logo.js"></script>
<link rel="stylesheet" type="text/css" href="./style/examples.css">
<script>
// jshint ignore: start
</script>
</head> </head>
<body> <body>
<div id="Content"> <tone-example>
<div id="Title">Events</div> <tone-explanation label="Events">
<div id="Explanation"> Tone's Event classes (<a href="https://tonejs.github.io/docs/Event">Tone.Event</a>,
Tone's Event classes (<a href="https://tonejs.github.io/docs/#Event">Tone.Event</a>, <a href="https://tonejs.github.io/docs/Loop">Tone.Loop</a>,
<a href="https://tonejs.github.io/docs/#Loop">Tone.Loop</a>, <a href="https://tonejs.github.io/docs/Part">Tone.Part</a> and
<a href="https://tonejs.github.io/docs/#Part">Tone.Part</a> and <a href="https://tonejs.github.io/docs/Sequence">Tone.Sequence</a>)
<a href="https://tonejs.github.io/docs/#Sequence">Tone.Sequence</a>)
simplify scheduling events along the Transport. Each class abstracts away calls to simplify scheduling events along the Transport. Each class abstracts away calls to
<a href="https://tonejs.github.io/docs/#Transport.schedule">Transport.schedule</a> or <a href="https://tonejs.github.io/docs/Transport.schedule">Transport.schedule</a> or
<a href="https://tonejs.github.io/docs/#Transport.scheduleRepeat">scheduleRepeat</a> <a href="https://tonejs.github.io/docs/Transport.scheduleRepeat">scheduleRepeat</a>
and lets you create precise, rhythmic events which are startable, stoppable and loopable. and lets you create precise, rhythmic events which are startable, stoppable and loopable.
</tone-explanation>
</div> <tone-content>
</div> <tone-play-toggle></tone-play-toggle>
</tone-content>
<script id="ToneCode"> <tone-drawer>
<tone-membrane-synth collapsed label="Kick"></tone-membrane-synth>
<tone-noise-synth collapsed label="Snare"></tone-noise-synth>
<tone-mono-synth collapsed label="Bass"></tone-mono-synth>
<tone-synth collapsed polyphonic label="Keys"></tone-synth>
</tone-drawer>
</tone-example>
<script type="text/javascript">
/* /*
KICK KICK
*/ */
@ -54,7 +53,6 @@
kick.triggerAttackRelease("C2", "8n", time); kick.triggerAttackRelease("C2", "8n", time);
}, "2n").start(0); }, "2n").start(0);
/* /*
SNARE SNARE
*/ */
@ -76,7 +74,6 @@
snare.triggerAttack(time); snare.triggerAttack(time);
}, "2n").start("4n"); }, "2n").start("4n");
/** /**
* PIANO * PIANO
*/ */
@ -86,7 +83,7 @@
"partials" : [1, 2, 1], "partials" : [1, 2, 1],
}, },
"portamento" : 0.05 "portamento" : 0.05
}).toMaster() }).toMaster();
var cChord = ["C4", "E4", "G4", "B4"]; var cChord = ["C4", "E4", "G4", "B4"];
var dChord = ["D4", "F4", "A4", "C5"]; var dChord = ["D4", "F4", "A4", "C5"];
@ -100,7 +97,6 @@
pianoPart.loopEnd = "1m"; pianoPart.loopEnd = "1m";
pianoPart.humanize = true; pianoPart.humanize = true;
/* /*
BASS BASS
*/ */
@ -129,20 +125,12 @@
//set the transport //set the transport
Tone.Transport.bpm.value = 90; Tone.Transport.bpm.value = 90;
// GUI // //bind the interface
document.querySelector("tone-play-toggle").bind(Tone.Transport);
Interface.Button({ document.querySelector("tone-membrane-synth").bind(kick);
key : 32, document.querySelector("tone-mono-synth").bind(bass);
type : "toggle", document.querySelector("tone-synth").bind(piano);
text : "Start", document.querySelector("tone-noise-synth").bind(snare);
activeText : "Stop",
start : function(){
Tone.Transport.start("+0.1");
},
end : function(){
Tone.Transport.stop();
}
});
</script> </script>
</body> </body>
</html> </html>

View file

Before

Width:  |  Height:  |  Size: 6.8 KiB

After

Width:  |  Height:  |  Size: 6.8 KiB

View file

@ -4,37 +4,34 @@
<meta charset="utf-8"> <meta charset="utf-8">
<title>FMSynth</title> <title>FMSynth</title>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"> <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<link rel="icon" type="image/png" sizes="174x174" href="./style/favicon.png"> <link rel="icon" type="image/png" sizes="174x174" href="./favicon.png">
<script src="https://unpkg.com/@webcomponents/webcomponentsjs@^2/webcomponents-bundle.js"></script>
<script src="../build/Tone.js"></script> <script src="../build/Tone.js"></script>
<script src="./scripts/jquery.min.js"></script> <script src="./js/tonejs-ui.js"></script>
<script src="./scripts/draggabilly.js"></script>
<script src="./scripts/StartAudioContext.js"></script>
<script src="./scripts/Interface.js"></script>
<script src="https://tonejs.github.io/Logo/build/Logo.js"></script>
<script src="./scripts/Keyboard.js"></script>
<link rel="stylesheet" type="text/css" href="./style/examples.css">
<script>
// jshint ignore: start
</script>
</head> </head>
<body> <body>
<div id="Content"> <style>
<div id="Title">FMSynth</div> tone-piano {
<div id="Explanation"> margin-bottom: 10px;
<a href="https://tonejs.github.io/docs/#FMSynth">Tone.FMSynth</a> }
</style>
<tone-example>
<tone-explanation label="FMSynth">
<a href="https://tonejs.github.io/docs/FMSynth">Tone.FMSynth</a>
is composed of two is composed of two
<a href="https://tonejs.github.io/docs/#Synth">Tone.Synths</a> <a href="https://tonejs.github.io/docs/Synth">Tone.Synths</a>
where one Tone.Synth modulates the frequency of a second Tone.Synth. where one Tone.Synth modulates the frequency of a second Tone.Synth.
</div> </tone-explanation>
</div>
<script> <tone-content>
<tone-piano></tone-piano>
<tone-fm-synth></tone-fm-synth>
</tone-content>
</tone-example>
<script type="text/javascript">
var synth = new Tone.FMSynth({ var synth = new Tone.FMSynth({
"modulationIndex" : 12.22, "modulationIndex" : 12.22,
"envelope" : { "envelope" : {
@ -50,25 +47,9 @@
} }
}).toMaster(); }).toMaster();
// GUI // //bind the interface
document.querySelector("tone-piano").bind(synth);
Interface.Slider({ document.querySelector("tone-fm-synth").bind(synth);
tone : synth,
param : "modulationIndex",
name : "mod index",
max : 100
});
var keyboard = Interface.Keyboard();
keyboard.keyDown = function (note) {
synth.triggerAttack(note);
};
keyboard.keyUp = function (note) {
synth.triggerRelease();
};
</script> </script>
</body> </body>
</html> </html>

View file

@ -3,30 +3,14 @@
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<title>VISUALIZING ENVELOPES</title> <title>VISUALIZING ENVELOPES</title>
<!--
Funky Shape
Using Tone.js and p5.js
example written by Seth Kranzler
https://github.com/polyrhythmatic
-->
<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">
<script src="./scripts/p5.js"></script> <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<link rel="icon" type="image/png" sizes="174x174" href="./favicon.png">
<script src="https://unpkg.com/@webcomponents/webcomponentsjs@^2/webcomponents-bundle.js"></script>
<script src="../build/Tone.js"></script> <script src="../build/Tone.js"></script>
<script src="./scripts/p5.Tone.js"></script> <script src="./js/tonejs-ui.js"></script>
<script src="./scripts/jquery.min.js"></script> <script src="./js/p5.js"></script>
<script src="./scripts/draggabilly.js"></script>
<script src="./scripts/StartAudioContext.js"></script>
<script src="./scripts/Interface.js"></script>
<script src="https://tonejs.github.io/Logo/build/Logo.js"></script>
<link rel="stylesheet" type="text/css" href="./style/examples.css">
<script>
// jshint ignore: start
</script>
</head> </head>
<body> <body>
<style type="text/css"> <style type="text/css">
@ -34,20 +18,37 @@
position: absolute; position: absolute;
top: 0px; top: 0px;
z-index: -1; z-index: -1;
left: 0px;
} }
</style> </style>
<div id="Content" class="FullScreen"> <tone-example>
<div id="Title">Using p5</div> <tone-explanation label="Tone with p5.js">
<div id="Explanation"> Access the envelopes current value to synchronize visuals. This sketch uses <a href="https://p5js.org" target="_blank">p5.js</a> for canvas rendering.
By accessing the envelope's current value, we can create responsive visuals that are directly tied to what is heard.
<br><br> <br><br>
This sketch uses <a href="https://p5js.org" target="_blank">p5.js</a> for visual components. Example by <a href="https://github.com/polyrhythmatic">polyrhythmatic</a>
</div> </tone-explanation>
</div>
<script id="p5">
//creating our class name <tone-content>
function FunkyShape() {} <tone-play-toggle></tone-play-toggle>
</tone-content>
<tone-drawer collapsed>
<tone-filter frequency id="hihatFilter" collapsed label="Hihat Filter"></tone-filter>
<tone-noise-synth id="openHiHat" collapsed label="Open Hihat"></tone-noise-synth>
<tone-noise-synth id="closedHiHat" collapsed label="Closed Hihat"></tone-noise-synth>
<tone-oscillator id="bassOsc" collapsed label="Bass Osc" sourcetype="pulse"></tone-oscillator>
<tone-filter frequency id="bassFilter" collapsed label="Bass Filter"></tone-filter>
<tone-envelope id="bassEnvelope" collapsed label="Bass Envelope"></tone-envelope>
<tone-oscillator frequency id="bleep" collapsed label="Bleep"></tone-oscillator>
<tone-envelope id="bleepEnvelope" collapsed label="Bleep Envelope"></tone-envelope>
<tone-oscillator frequency id="kickOsc" collapsed label="Kick Oscillator"></tone-oscillator>
<tone-envelope id="kickEnvelope" collapsed label="Kick Envelope"></tone-envelope>
<tone-frequency-envelope id="kickFreqEnvelope" collapsed label="Kick Frequency Envelope"></tone-frequency-envelope>
</tone-drawer>
</tone-example>
<script type="text/javascript">
function FunkyShape(){}
/* /*
FunkyShape init gives initial and offset values for FunkyShape init gives initial and offset values for
@ -55,7 +56,7 @@
Giving different initial values ensures that Giving different initial values ensures that
each funky shape follows its own funky path each funky shape follows its own funky path
*/ */
FunkyShape.prototype.init = function(xInc, yInc, xOff, yOff, radius) { FunkyShape.prototype.init = function(xInc, yInc, xOff, yOff, radius){
this.xInc = xInc; this.xInc = xInc;
this.yInc = yInc; this.yInc = yInc;
this.xOff = xOff; this.xOff = xOff;
@ -63,21 +64,21 @@
this.radius = radius; this.radius = radius;
this.xPos = 0; this.xPos = 0;
this.yPos = 0; this.yPos = 0;
} };
//updates the x, y, and radius values of the shape //updates the x, y, and radius values of the shape
FunkyShape.prototype.update = function(envelope) { FunkyShape.prototype.update = function(envelope){
this.xPos = noise(this.xOff) * width; this.xPos = noise(this.xOff) * width;
this.yPos = noise(this.yOff) * height; this.yPos = noise(this.yOff) * height;
this.xOff += this.xInc; this.xOff += this.xInc;
this.yOff += this.yInc; this.yOff += this.yInc;
this.sRadius = this.radius * envelope; this.sRadius = this.radius * envelope;
return { return {
"xPos": this.xPos, "xPos" : this.xPos,
"yPos": this.yPos, "yPos" : this.yPos,
"radius": this.sRadius "radius" : this.sRadius
};
}; };
}
//using our FunkyShape class //using our FunkyShape class
//to create a funkyCircle class //to create a funkyCircle class
@ -86,11 +87,11 @@
//creating an empty array //creating an empty array
var funkySquare = []; var funkySquare = [];
//and populating it with 3 FunkyShapes //and populating it with 3 FunkyShapes
for (var i = 0; i < 3; i++) { for (var i = 0; i < 3; i++){
funkySquare[i] = new FunkyShape(); funkySquare[i] = new FunkyShape();
} }
function setup() { function setup(){
//create a canvas width and height of the screen //create a canvas width and height of the screen
createCanvas(windowWidth, windowHeight); createCanvas(windowWidth, windowHeight);
//no fill //no fill
@ -101,7 +102,7 @@
funkyCircle.init(0.01, 0.02, 0.0, 0.0, 400); funkyCircle.init(0.01, 0.02, 0.0, 0.0, 400);
//initializing our squares with random values //initializing our squares with random values
//to ensure they don't follow the same path //to ensure they don't follow the same path
for (var i = 0; i < 3; i++) { for (var i = 0; i < 3; i++){
var xInc = Math.random() / 10; var xInc = Math.random() / 10;
var yInc = Math.random() / 10; var yInc = Math.random() / 10;
funkySquare[i].init(xInc, yInc, 0, 0, 800); funkySquare[i].init(xInc, yInc, 0, 0, 800);
@ -110,13 +111,13 @@
var phase = 0; var phase = 0;
function draw() { function draw(){
background(255); background(255);
stroke(0); stroke(0);
//drawing the kick wave at the bottom //drawing the kick wave at the bottom
//it is composed of a simple sine wave that //it is composed of a simple sine wave that
//changes in height with the kick envelope //changes in height with the kick envelope
for (var i = 0; i < width; i++) { for (var i = 0; i < width; i++){
//scaling kickEnvelope value by 200 //scaling kickEnvelope value by 200
//since default is 0-1 //since default is 0-1
var kickValue = kickEnvelope.value * 200; var kickValue = kickEnvelope.value * 200;
@ -133,82 +134,76 @@
var circlePos = funkyCircle.update(bassEnvelope.value); var circlePos = funkyCircle.update(bassEnvelope.value);
//circlePos returns x and y positions as an object //circlePos returns x and y positions as an object
ellipse(circlePos.xPos, circlePos.yPos, circlePos.radius, circlePos.radius); ellipse(circlePos.xPos, circlePos.yPos, circlePos.radius, circlePos.radius);
stroke('red'); stroke("red");
for (var i = 0; i < 3; i++) { for (var i = 0; i < 3; i++){
var squarePos = funkySquare[i].update(bleepEnvelope.value); var squarePos = funkySquare[i].update(bleepEnvelope.value);
rect(squarePos.xPos, squarePos.yPos, squarePos.radius, squarePos.radius); rect(squarePos.xPos, squarePos.yPos, squarePos.radius, squarePos.radius);
} }
} }
</script>
<script id="Song">
//HATS
//filtering the hi-hats a bit //filtering the hi-hats a bit
//to make them sound nicer //to make them sound nicer
var lowPass = new Tone.Filter({ var lowPass = new Tone.Filter({
"frequency": 14000, "frequency" : 14000,
}).toMaster(); }).toMaster();
//we can make our own hi hats with //we can make our own hi hats with
//the noise synth and a sharp filter envelope //the noise synth and a sharp filter envelope
var openHiHat = new Tone.NoiseSynth({ var openHiHat = new Tone.NoiseSynth({
"volume" : -10, "volume" : -10,
"filter": { "filter" : {
"Q": 1 "Q" : 1
}, },
"envelope": { "envelope" : {
"attack": 0.01, "attack" : 0.01,
"decay": 0.3 "decay" : 0.3
}, },
"filterEnvelope": { "filterEnvelope" : {
"attack": 0.01, "attack" : 0.01,
"decay": 0.03, "decay" : 0.03,
"baseFrequency": 4000, "baseFrequency" : 4000,
"octaves": -2.5, "octaves" : -2.5,
"exponent": 4, "exponent" : 4,
} }
}).connect(lowPass); }).connect(lowPass);
var openHiHatPart = new Tone.Part(function(time){ var openHiHatPart = new Tone.Part(function(time){
openHiHat.triggerAttack(time); openHiHat.triggerAttack(time);
}, ["2*8n", "6*8n"]).start(0); }, [{ "8n" : 2 }, { "8n" : 6 }]).start(0);
var closedHiHat = new Tone.NoiseSynth({ var closedHiHat = new Tone.NoiseSynth({
"volume" : -10, "volume" : -10,
"filter": { "filter" : {
"Q": 1 "Q" : 1
}, },
"envelope": { "envelope" : {
"attack": 0.01, "attack" : 0.01,
"decay": 0.15 "decay" : 0.15
}, },
"filterEnvelope": { "filterEnvelope" : {
"attack": 0.01, "attack" : 0.01,
"decay": 0.03, "decay" : 0.03,
"baseFrequency": 4000, "baseFrequency" : 4000,
"octaves": -2.5, "octaves" : -2.5,
"exponent": 4, "exponent" : 4,
} }
}).connect(lowPass); }).connect(lowPass);
var closedHatPart = new Tone.Part(function(time){ var closedHatPart = new Tone.Part(function(time){
closedHiHat.triggerAttack(time); closedHiHat.triggerAttack(time);
}, ["0*8n", "1*16n", "1*8n", "3*8n", "4*8n", "5*8n", "7*8n", "8*8n"]).start(0); }, [0, { "16n" : 1 }, { "8n" : 1 }, { "8n" : 3 }, { "8n" : 4 }, { "8n" : 5 }, { "8n" : 7 }, { "8n" : 8 }]).start(0);
//BASS //BASS
var bassEnvelope = new Tone.AmplitudeEnvelope({ var bassEnvelope = new Tone.AmplitudeEnvelope({
"attack": 0.01, "attack" : 0.01,
"decay": 0.2, "decay" : 0.2,
"sustain": 0, "sustain" : 0,
"release": 0,
}).toMaster(); }).toMaster();
var bassFilter = new Tone.Filter({ var bassFilter = new Tone.Filter({
"frequency": 600, "frequency" : 600,
"Q": 8 "Q" : 8
}); });
var bass = new Tone.PulseOscillator("A2", 0.4).chain(bassFilter, bassEnvelope); var bass = new Tone.PulseOscillator("A2", 0.4).chain(bassFilter, bassEnvelope);
@ -224,13 +219,11 @@
//BLEEP //BLEEP
var bleepEnvelope = new Tone.AmplitudeEnvelope({ var bleepEnvelope = new Tone.AmplitudeEnvelope({
"attack": 0.01, "attack" : 0.01,
"decay": 0.4, "decay" : 0.4,
"sustain": 0, "sustain" : 0,
"release": 0,
}).toMaster(); }).toMaster();
var bleep = new Tone.Oscillator("A4").connect(bleepEnvelope); var bleep = new Tone.Oscillator("A4").connect(bleepEnvelope);
bleep.start(); bleep.start();
@ -240,21 +233,19 @@
//KICK //KICK
var kickEnvelope = new Tone.AmplitudeEnvelope({ var kickEnvelope = new Tone.AmplitudeEnvelope({
"attack": 0.01, "attack" : 0.01,
"decay": 0.2, "decay" : 0.2,
"sustain": 0, "sustain" : 0,
"release": 0
}).toMaster(); }).toMaster();
var kick = new Tone.Oscillator("A2").connect(kickEnvelope).start(); var kick = new Tone.Oscillator("A2").connect(kickEnvelope).start();
kickSnapEnv = new Tone.FrequencyEnvelope({ var kickSnapEnv = new Tone.FrequencyEnvelope({
"attack": 0.005, "attack" : 0.005,
"decay": 0.01, "decay" : 0.01,
"sustain": 0, "sustain" : 0,
"release": 0, "baseFrequency" : "A2",
"baseFrequency": "A2", "octaves" : 2.7
"octaves": 2.7
}).connect(kick.frequency); }).connect(kick.frequency);
var kickPart = new Tone.Part(function(time){ var kickPart = new Tone.Part(function(time){
@ -267,20 +258,19 @@
Tone.Transport.loopEnd = "1:0"; Tone.Transport.loopEnd = "1:0";
Tone.Transport.loop = true; Tone.Transport.loop = true;
// GUI // //bind the interface
document.querySelector("tone-play-toggle").bind(Tone.Transport);
Interface.Button({ document.querySelector("#hihatFilter").bind(lowPass);
type : "toggle", document.querySelector("#openHiHat").bind(openHiHat);
text : "Start", document.querySelector("#closedHiHat").bind(closedHiHat);
activeText : "Stop", document.querySelector("#bassOsc").bind(bass);
start : function(){ document.querySelector("#bassFilter").bind(bassFilter);
Tone.Transport.start("+0.1"); document.querySelector("#bassEnvelope").bind(bassEnvelope);
}, document.querySelector("#bleep").bind(bleep);
end : function(){ document.querySelector("#bleepEnvelope").bind(bleepEnvelope);
Tone.Transport.stop(); document.querySelector("#kickOsc").bind(kick);
} document.querySelector("#kickEnvelope").bind(kickEnvelope);
}); document.querySelector("#kickFreqEnvelope").bind(kickSnapEnv);
</script> </script>
</body> </body>

View file

@ -2,39 +2,47 @@
<html> <html>
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<title>GRAINPLAYER</title> <title>Grain Player</title>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"> <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<link rel="icon" type="image/png" sizes="174x174" href="./style/favicon.png"> <link rel="icon" type="image/png" sizes="174x174" href="./favicon.png">
<script src="https://unpkg.com/@webcomponents/webcomponentsjs@^2/webcomponents-bundle.js"></script>
<script src="../build/Tone.js"></script> <script src="../build/Tone.js"></script>
<script src="./scripts/jquery.min.js"></script> <script src="./js/tonejs-ui.js"></script>
<script src="./scripts/draggabilly.js"></script>
<script src="./scripts/StartAudioContext.js"></script>
<script src="./scripts/Interface.js"></script>
<script src="https://tonejs.github.io/Logo/build/Logo.js"></script>
<link rel="stylesheet" type="text/css" href="./style/examples.css">
<script>
// jshint ignore: start
</script>
</head> </head>
<body> <body>
<div id="Content"> <style type="text/css">
<div id="Title">Granular Synthesis</div> tone-play-toggle, tone-fft {
<div id="Explanation"> margin-bottom: 10px;
<a href="https://tonejs.github.io/docs/#GrainPlayer">Tone.GrainPlayer</a> uses }
tone-fft {
background-color: black;
height: 40px;
width: 100%;
border-radius: 20px;
}
</style>
<tone-example>
<tone-explanation label="Granular Synthesis">
<a href="https://tonejs.github.io/docs/GrainPlayer">Tone.GrainPlayer</a> uses
<a href="https://en.wikipedia.org/wiki/Granular_synthesis">granular synthesis</a> <a href="https://en.wikipedia.org/wiki/Granular_synthesis">granular synthesis</a>
to enable you to adjust pitch and playback rate independently. The grainSize is the to enable you to adjust pitch and playback rate independently. The grainSize is the
amount of time each small chunk of audio is played for and the overlap is the amount of time each small chunk of audio is played for and the overlap is the
amount of crossfading transition time between successive grains. amount of crossfading transition time between successive grains.
</div> </tone-explanation>
<div id="Sliders"></div>
</div>
<script>
<tone-loader></tone-loader>
<tone-content>
<tone-fft></tone-fft>
<tone-play-toggle></tone-play-toggle>
<tone-grain-player></tone-grain-player>
</tone-content>
</tone-example>
<script type="text/javascript">
//the player //the player
var player = new Tone.GrainPlayer({ var player = new Tone.GrainPlayer({
"url" : "./audio/FWDL.[mp3|ogg]", "url" : "./audio/FWDL.[mp3|ogg]",
@ -43,58 +51,10 @@
"overlap" : 0.05, "overlap" : 0.05,
}).toMaster(); }).toMaster();
// GUI // //bind the interface
document.querySelector("tone-fft").bind(player);
Interface.Loader(); document.querySelector("tone-play-toggle").bind(player);
document.querySelector("tone-grain-player").bind(player);
Interface.Button({
text : "Start",
activeText : "Stop",
type : "toggle",
start : function(){
player.start();
},
end : function(){
player.stop();
}
});
Interface.Slider({
param : "playbackRate",
name : "playbackRate",
parent : $("#Sliders"),
tone : player,
min : 0.5,
max : 2,
});
Interface.Slider({
param : "detune",
name : "detune",
parent : $("#Sliders"),
tone : player,
min : -1200,
max : 1200,
});
Interface.Slider({
param : "grainSize",
name : "grainSize",
parent : $("#Sliders"),
tone : player,
min : 0.01,
max : 0.2,
});
Interface.Slider({
param : "overlap",
name : "overlap",
parent : $("#Sliders"),
tone : player,
min : 0,
max : 0.2,
});
</script> </script>
</body> </body>
</html> </html>

View file

@ -2,93 +2,29 @@
<html> <html>
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<title>EXAMPLES</title> <title>Tone.js Examples</title>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"> <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<link rel="icon" type="image/png" sizes="174x174" href="./style/favicon.png"> <link rel="icon" type="image/png" sizes="174x174" href="./favicon.png">
<script src="./scripts/jquery.min.js"></script> <script type="text/javascript">
<script src="https://tonejs.github.io/Logo/build/Logo.js"></script> //forward links with hashes
<script src="./scripts/ExampleList.js"></script> if (window.location.hash !== ""){
var hash = window.location.hash.substring(1);
<link rel="stylesheet" type="text/css" href="./style/examples.css"> window.location.href = window.location.pathname+hash;
<link href="https://fonts.googleapis.com/css?family=Inconsolata" rel="stylesheet"> }
</script>
<script src="https://unpkg.com/@webcomponents/webcomponentsjs@^2/webcomponents-bundle.js"></script>
<script src="../build/Tone.js"></script>
<script src="./js/tonejs-ui.js"></script>
</head> </head>
<body> <body>
<div id="Content" class="Example"> <tone-example open>
<iframe></iframe> <tone-explanation label="Examples">
<div id="Sidebar"></div> Choose an example from the side panel.
</div> </tone-explanation>
</tone-example>
<script>
var container = $("#Sidebar");
var topbar = $("<div>").attr("id", "TopBar");
$("body").prepend(topbar);
// make the hamburger menu
var hamburger = $("<div>").attr("id", "Hamburger")
.appendTo(topbar);
for (var i = 0; i < 3; i++){
$("<span>").appendTo(hamburger);
}
hamburger.on("click", function(){
$("#Sidebar").toggleClass("Open");
});
//add the Logo
Logo({
"container" : topbar.get(0),
"height" : topbar.height() - 6,
"width" : 140
});
for (var catName in ExampleList){
$("<div>").addClass("Category").text(catName).appendTo(container);
var category = ExampleList[catName];
for (var example in category){
$("<div>").addClass("Item")
.appendTo(container)
.html($("<a>").attr("href", "#" + category[example]).text(example));
}
}
$(window).on("hashchange", setHash);
function setHash(){
var hash = window.location.hash.substring(1);
if (hash === ""){
return;
}
var exampleName;
//split hash at the .
if (hash.split(".").length === 2){
var split = hash.split(".");
hash = split[0];
exampleName = split[1];
}
var url = location.protocol+'//'+location.host+location.pathname + hash + ".html";
$("iframe").attr("src", url);
// close the sidebar if it's open
if ($("#Sidebar").hasClass("Open")){
$("#Sidebar").removeClass("Open");
}
// add the source link
var srcUrl = "https://github.com/Tonejs/Tone.js/blob/master/examples/"+hash+".html"
if (!$("#Source").length){
$("<a id=\"Source\"></a>").appendTo("#Content");
}
$("#Source").attr("href", srcUrl);
}
//set it initially
setHash();
</script>
</body> </body>
</html> </html>

View file

@ -1,4 +1,4 @@
var ExampleList = { {
"Basic" : { "Basic" : {
"Oscillators" : "oscillator", "Oscillators" : "oscillator",
"Envelope" : "envelope", "Envelope" : "envelope",
@ -34,7 +34,7 @@ var ExampleList = {
}, },
"Signals" : { "Signals" : {
"Control Voltage" : "signal", "Control Voltage" : "signal",
"Ramping Values" : "rampTo", "Ramping Values" : "rampTo"
}, },
"Visualization" : { "Visualization" : {
"Animation Sync" : "animationSync", "Animation Sync" : "animationSync",
@ -43,7 +43,6 @@ var ExampleList = {
"Meter" : "meter" "Meter" : "meter"
}, },
"Misc" : { "Misc" : {
"Module Loaders" : "require",
"Offline Rendering" : "offline" "Offline Rendering" : "offline"
}, }
}; }

3120
examples/js/tonejs-ui.js Normal file

File diff suppressed because one or more lines are too long

View file

@ -4,51 +4,52 @@
<meta charset="utf-8"> <meta charset="utf-8">
<title>FatOscillator</title> <title>FatOscillator</title>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"> <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<link rel="icon" type="image/png" sizes="174x174" href="./style/favicon.png"> <link rel="icon" type="image/png" sizes="174x174" href="./favicon.png">
<script src="https://unpkg.com/@webcomponents/webcomponentsjs@^2/webcomponents-bundle.js"></script>
<script src="../build/Tone.js"></script> <script src="../build/Tone.js"></script>
<script src="./scripts/jquery.min.js"></script> <script src="./js/tonejs-ui.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>
<link rel="stylesheet" type="text/css" href="./style/examples.css">
<script type="text/javascript">
// jshint ignore: start
</script>
</head> </head>
<body> <body>
<div id="Content"> <style type="text/css">
<div id="Title">Supersaw</div> tone-play-toggle {
<div id="Explanation"> margin-bottom: 10px;
<a href="https://tonejs.github.io/docs/#FatOscillator">Tone.FatOscillator</a> creates multiple oscillators }
</style>
<tone-example>
<tone-explanation label="Supersaw">
<a href="https://tonejs.github.io/docs/FatOscillator">Tone.FatOscillator</a> creates multiple oscillators
and detunes them slightly from each other to thicken the sound. The <code>count</code> parameter sets and detunes them slightly from each other to thicken the sound. The <code>count</code> parameter sets
the number of oscillators and <code>spread</code> sets the total spread (in cents) between the oscillators. the number of oscillators and <code>spread</code> sets the total spread (in cents) between the oscillators.
<br><br> <br><br>
FatOscillator is also available in <a href="https://tonejs.github.io/docs/#OmniOscillator">Tone.OmniOscillator</a> FatOscillator is also available in <a href="https://tonejs.github.io/docs/OmniOscillator">Tone.OmniOscillator</a>
by prefixing another type with "fat", then use the count and spread to control the number and detune of the oscillators. To create a "supersaw": <code>omniOscillator.type = "fatsawtooth"</code>. by prefixing another type with "fat", then use the count and spread to control the number and detune of the oscillators. To create a "supersaw": <code>omniOscillator.type = "fatsawtooth"</code>.
<br><br> <br><br>
<a href="http://www.midiworld.com/files/1121/">Jump by Van Halen MIDI</a> converted using <a href="http://tonejs.github.io/MidiConvert/">MidiConvert</a> <a href="http://www.midiworld.com/files/1121/">Jump by Van Halen MIDI</a> converted using <a href="http://tonejs.github.io/MidiConvert/">MidiConvert</a>
</div> </tone-explanation>
</div>
<script> <tone-content>
<tone-play-toggle></tone-play-toggle>
</tone-content>
<tone-drawer collapsed>
<tone-synth polyphonic></tone-synth>
</tone-drawer>
</tone-example>
<script type="text/javascript">
var synth = new Tone.PolySynth(3, Tone.Synth, { var synth = new Tone.PolySynth(3, Tone.Synth, {
"oscillator" : { "oscillator" : {
"type" : "fatsawtooth", "type" : "fatsawtooth",
"count" : 3, "count" : 3,
"spread" : 30 "spread" : 30
}, },
"envelope": { "envelope" : {
"attack": 0.01, "attack" : 0.01,
"decay": 0.1, "decay" : 0.1,
"sustain": 0.5, "sustain" : 0.5,
"release": 0.4, "release" : 0.4,
"attackCurve" : "exponential" "attackCurve" : "exponential"
}, },
}).toMaster(); }).toMaster();
@ -57,198 +58,197 @@
// converted using // converted using
var part = new Tone.Part(function(time, note){ var part = new Tone.Part(function(time, note){
synth.triggerAttackRelease(note.noteName, note.duration, time, note.velocity); synth.triggerAttackRelease(note.noteName, note.duration, time, note.velocity);
}, [ }, [{
{ "time" : "192i",
"time": "192i", "noteName" : "G4",
"noteName": "G4", "velocity" : 0.8110236220472441,
"velocity": 0.8110236220472441, "duration" : "104i"
"duration": "104i"
}, },
{ {
"time": "192i", "time" : "192i",
"noteName": "B4", "noteName" : "B4",
"velocity": 0.7874015748031497, "velocity" : 0.7874015748031497,
"duration": "104i" "duration" : "104i"
}, },
{ {
"time": "192i", "time" : "192i",
"noteName": "D5", "noteName" : "D5",
"velocity": 0.8031496062992126, "velocity" : 0.8031496062992126,
"duration": "104i" "duration" : "104i"
}, },
{ {
"time": "480i", "time" : "480i",
"noteName": "G4", "noteName" : "G4",
"velocity": 0.7559055118110236, "velocity" : 0.7559055118110236,
"duration": "104i" "duration" : "104i"
}, },
{ {
"time": "480i", "time" : "480i",
"noteName": "C5", "noteName" : "C5",
"velocity": 0.6850393700787402, "velocity" : 0.6850393700787402,
"duration": "104i" "duration" : "104i"
}, },
{ {
"time": "480i", "time" : "480i",
"noteName": "E5", "noteName" : "E5",
"velocity": 0.6771653543307087, "velocity" : 0.6771653543307087,
"duration": "104i" "duration" : "104i"
}, },
{ {
"time": "768i", "time" : "768i",
"noteName": "F4", "noteName" : "F4",
"velocity": 0.8661417322834646, "velocity" : 0.8661417322834646,
"duration": "104i" "duration" : "104i"
}, },
{ {
"time": "768i", "time" : "768i",
"noteName": "A4", "noteName" : "A4",
"velocity": 0.8346456692913385, "velocity" : 0.8346456692913385,
"duration": "104i" "duration" : "104i"
}, },
{ {
"time": "768i", "time" : "768i",
"noteName": "C5", "noteName" : "C5",
"velocity": 0.8188976377952756, "velocity" : 0.8188976377952756,
"duration": "104i" "duration" : "104i"
}, },
{ {
"time": "1056i", "time" : "1056i",
"noteName": "F4", "noteName" : "F4",
"velocity": 0.7007874015748031, "velocity" : 0.7007874015748031,
"duration": "104i" "duration" : "104i"
}, },
{ {
"time": "1056i", "time" : "1056i",
"noteName": "A4", "noteName" : "A4",
"velocity": 0.6850393700787402, "velocity" : 0.6850393700787402,
"duration": "104i" "duration" : "104i"
}, },
{ {
"time": "1056i", "time" : "1056i",
"noteName": "C5", "noteName" : "C5",
"velocity": 0.6614173228346457, "velocity" : 0.6614173228346457,
"duration": "104i" "duration" : "104i"
}, },
{ {
"time": "1248i", "time" : "1248i",
"noteName": "G4", "noteName" : "G4",
"velocity": 0.6771653543307087, "velocity" : 0.6771653543307087,
"duration": "104i" "duration" : "104i"
}, },
{ {
"time": "1248i", "time" : "1248i",
"noteName": "B4", "noteName" : "B4",
"velocity": 0.6771653543307087, "velocity" : 0.6771653543307087,
"duration": "104i" "duration" : "104i"
}, },
{ {
"time": "1248i", "time" : "1248i",
"noteName": "D5", "noteName" : "D5",
"velocity": 0.7165354330708661, "velocity" : 0.7165354330708661,
"duration": "104i" "duration" : "104i"
}, },
{ {
"time": "1440i", "time" : "1440i",
"noteName": "G4", "noteName" : "G4",
"velocity": 0.8818897637795275, "velocity" : 0.8818897637795275,
"duration": "248i" "duration" : "248i"
}, },
{ {
"time": "1440i", "time" : "1440i",
"noteName": "B4", "noteName" : "B4",
"velocity": 0.84251968503937, "velocity" : 0.84251968503937,
"duration": "248i" "duration" : "248i"
}, },
{ {
"time": "1440i", "time" : "1440i",
"noteName": "D5", "noteName" : "D5",
"velocity": 0.8818897637795275, "velocity" : 0.8818897637795275,
"duration": "248i" "duration" : "248i"
}, },
{ {
"time": "1728i", "time" : "1728i",
"noteName": "G4", "noteName" : "G4",
"velocity": 0.8267716535433071, "velocity" : 0.8267716535433071,
"duration": "104i" "duration" : "104i"
}, },
{ {
"time": "1728i", "time" : "1728i",
"noteName": "C5", "noteName" : "C5",
"velocity": 0.8031496062992126, "velocity" : 0.8031496062992126,
"duration": "104i" "duration" : "104i"
}, },
{ {
"time": "1728i", "time" : "1728i",
"noteName": "E5", "noteName" : "E5",
"velocity": 0.8188976377952756, "velocity" : 0.8188976377952756,
"duration": "104i" "duration" : "104i"
}, },
{ {
"time": "2016i", "time" : "2016i",
"noteName": "F4", "noteName" : "F4",
"velocity": 0.7086614173228346, "velocity" : 0.7086614173228346,
"duration": "104i" "duration" : "104i"
}, },
{ {
"time": "2016i", "time" : "2016i",
"noteName": "A4", "noteName" : "A4",
"velocity": 0.7244094488188977, "velocity" : 0.7244094488188977,
"duration": "104i" "duration" : "104i"
}, },
{ {
"time": "2016i", "time" : "2016i",
"noteName": "C5", "noteName" : "C5",
"velocity": 0.7007874015748031, "velocity" : 0.7007874015748031,
"duration": "104i" "duration" : "104i"
}, },
{ {
"time": "2208i", "time" : "2208i",
"noteName": "C4", "noteName" : "C4",
"velocity": 0.9921259842519685, "velocity" : 0.9921259842519685,
"duration": "296i" "duration" : "296i"
}, },
{ {
"time": "2208i", "time" : "2208i",
"noteName": "F4", "noteName" : "F4",
"velocity": 0.968503937007874, "velocity" : 0.968503937007874,
"duration": "200i" "duration" : "200i"
}, },
{ {
"time": "2208i", "time" : "2208i",
"noteName": "A4", "noteName" : "A4",
"velocity": 0.9606299212598425, "velocity" : 0.9606299212598425,
"duration": "208i" "duration" : "208i"
}, },
{ {
"time": "2400i", "time" : "2400i",
"noteName": "E4", "noteName" : "E4",
"velocity": 0.7559055118110236, "velocity" : 0.7559055118110236,
"duration": "104i" "duration" : "104i"
}, },
{ {
"time": "2400i", "time" : "2400i",
"noteName": "G4", "noteName" : "G4",
"velocity": 0.7007874015748031, "velocity" : 0.7007874015748031,
"duration": "104i" "duration" : "104i"
}, },
{ {
"time": "2592i", "time" : "2592i",
"noteName": "C4", "noteName" : "C4",
"velocity": 0.968503937007874, "velocity" : 0.968503937007874,
"duration": "488i" "duration" : "488i"
}, },
{ {
"time": "2592i", "time" : "2592i",
"noteName": "D4", "noteName" : "D4",
"velocity": 0.9448818897637795, "velocity" : 0.9448818897637795,
"duration": "488i" "duration" : "488i"
}, },
{ {
"time": "2592i", "time" : "2592i",
"noteName": "G4", "noteName" : "G4",
"velocity": 0.937007874015748, "velocity" : 0.937007874015748,
"duration": "488i" "duration" : "488i"
} }
]).start(0); ]).start(0);
@ -257,20 +257,9 @@
Tone.Transport.bpm.value = 132; Tone.Transport.bpm.value = 132;
// GUI // //bind the interface
document.querySelector("tone-play-toggle").bind(Tone.Transport);
Interface.Button({ document.querySelector("tone-synth").bind(synth);
key : 32,
type : "toggle",
text : "Start",
activeText : "Stop",
start : function(){
Tone.Transport.start("+0.1");
},
end : function(){
Tone.Transport.stop();
}
});
</script> </script>
</body> </body>

View file

@ -4,38 +4,43 @@
<meta charset="utf-8"> <meta charset="utf-8">
<title>LFO Effects</title> <title>LFO Effects</title>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"> <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<link rel="icon" type="image/png" sizes="174x174" href="./style/favicon.png"> <link rel="icon" type="image/png" sizes="174x174" href="./favicon.png">
<script src="https://unpkg.com/@webcomponents/webcomponentsjs@^2/webcomponents-bundle.js"></script>
<script src="../build/Tone.js"></script> <script src="../build/Tone.js"></script>
<script src="./scripts/jquery.min.js"></script> <script src="./js/tonejs-ui.js"></script>
<script src="./scripts/draggabilly.js"></script>
<script src="./scripts/StartAudioContext.js"></script>
<script src="./scripts/Interface.js"></script>
<script src="https://tonejs.github.io/Logo/build/Logo.js"></script>
<link rel="stylesheet" type="text/css" href="./style/examples.css">
<script>
// jshint ignore: start
</script>
</head> </head>
<body> <body>
<div id="Content"> <style type="text/css">
<div id="Title">LFO Effects</div> tone-content * {
<div id="Explanation"> margin-bottom: 50px;
These effects use an <a href="https://tonejs.github.io/docs/#LFO">LFO</a> (Low Frequency Oscillator) to modulate the effect. Click and drag the dot to change the frequency and depth of the effect. }
tone-play-toggle {
margin-bottom: 10px;
}
</style>
<tone-example>
<tone-explanation label="LFO Effects">
These effects use an <a href="https://tonejs.github.io/docs/LFO">LFO</a> (Low Frequency Oscillator) to modulate the effect. Click and drag the dot to change the frequency and depth of the effect.
<br><br> <br><br>
Docs on <a href="https://tonejs.github.io/docs/#AutoPanner">Tone.AutoPanner</a>, Docs on <a href="https://tonejs.github.io/docs/AutoPanner">Tone.AutoPanner</a>,
<a href="https://tonejs.github.io/docs/#AutoFilter">Tone.AutoFilter</a>, and <a href="https://tonejs.github.io/docs/AutoFilter">Tone.AutoFilter</a>, and
<a href="https://tonejs.github.io/docs/#Tremolo">Tone.Tremolo</a> <a href="https://tonejs.github.io/docs/Tremolo">Tone.Tremolo</a>
</div> </tone-explanation>
<div id="DragContainer">
</div> <tone-content>
</div> <tone-play-toggle id="osc0"></tone-play-toggle>
<script id="JSCode"> <tone-auto-panner collapsed></tone-auto-panner>
//AutoPanner - a penning modulation effect <tone-play-toggle id="osc1"></tone-play-toggle>
<tone-auto-filter collapsed></tone-auto-filter>
<tone-play-toggle id="osc2"></tone-play-toggle>
<tone-tremolo collapsed></tone-tremolo>
</tone-content>
</tone-example>
<script type="text/javascript">
//AutoPanner - a panning modulation effect
var panner = new Tone.AutoPanner({ var panner = new Tone.AutoPanner({
"frequency" : 4, "frequency" : 4,
"depth" : 1 "depth" : 1
@ -72,7 +77,21 @@
"frequency" : "A4" "frequency" : "A4"
}).connect(tremolo).start(); }).connect(tremolo).start();
// GUI // //bind the interface
document.querySelector("#osc0").addEventListener("change", e => {
osc0.volume.rampTo(e.detail ? 0 : -Infinity, 0.1);
});
document.querySelector("#osc1").addEventListener("change", e => {
osc1.volume.rampTo(e.detail ? 0 : -Infinity, 0.1);
});
document.querySelector("#osc2").addEventListener("change", e => {
osc2.volume.rampTo(e.detail ? 0 : -Infinity, 0.1);
});
document.querySelector("tone-tremolo").bind(tremolo);
document.querySelector("tone-auto-filter").bind(filter);
document.querySelector("tone-auto-panner").bind(panner);
/*// GUI //
Interface.Dragger({ Interface.Dragger({
tone : panner, tone : panner,
@ -132,7 +151,7 @@
end : function(){ end : function(){
osc2.volume.rampTo(-Infinity, 0.1); osc2.volume.rampTo(-Infinity, 0.1);
} }
}); });*/
</script> </script>
</body> </body>

View file

@ -4,106 +4,49 @@
<meta charset="utf-8"> <meta charset="utf-8">
<title>Meter</title> <title>Meter</title>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"> <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<link rel="icon" type="image/png" sizes="174x174" href="./style/favicon.png"> <link rel="icon" type="image/png" sizes="174x174" href="./favicon.png">
<script src="https://unpkg.com/@webcomponents/webcomponentsjs@^2/webcomponents-bundle.js"></script>
<script src="../build/Tone.js"></script> <script src="../build/Tone.js"></script>
<script src="./scripts/jquery.min.js"></script> <script src="./js/tonejs-ui.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>
<link rel="stylesheet" type="text/css" href="./style/examples.css">
<script>
// jshint ignore: start
</script>
<style type="text/css">
canvas {
margin-top: 2px;
width: 100%;
height: 90px;
border-radius: 10px;
}
</style>
</head> </head>
<body> <body>
<div id="Content" class="FullScreen"> <style type="text/css">
<div id="Title">Meter</div> tone-meter {
<div id="Explanation"> width: 100%;
<a href="https://tonejs.github.io/docs/#Meter" target="_blank">Tone.Meter</a> background-color: black;
height: 100px;
margin-bottom: 10px;
}
</style>
<tone-example>
<tone-loader></tone-loader>
<tone-explanation label="Meter">
<a href="https://tonejs.github.io/docs/Meter" target="_blank">Tone.Meter</a>
gives you the level of the incoming signal in decibels. gives you the level of the incoming signal in decibels.
</div> </tone-explanation>
</div> <tone-content>
<tone-meter level color="#eee"></tone-meter>
<tone-play-toggle></tone-play-toggle>
</tone-content>
<script> <tone-drawer>
//create a level meter <tone-player collapsed></tone-player>
var meter = new Tone.Meter(); </tone-drawer>
</tone-example>
<script type="text/javascript">
var player = new Tone.Player({ var player = new Tone.Player({
"url" : "./audio/FWDL.[mp3|ogg]", "url" : "./audio/FWDL.[mp3|ogg]",
"loop" : true "loop" : true
}).connect(meter).toMaster(); }).toMaster();
// GUI // //bind the interface
document.querySelector("tone-play-toggle").bind(player);
//start button document.querySelector("tone-meter").bind(player);
Interface.Button({ document.querySelector("tone-player").bind(player);
key : 32,
type : "toggle",
text : "Start",
activeText : "Stop",
start : function(){
player.start();
},
end : function(){
player.stop();
}
});
//drawing the FFT
var meterContext = $("<canvas>",{
"id" : "fft"
}).appendTo("#Content").get(0).getContext("2d");
var meterGraident;
function drawMeter(){
var level = meter.getLevel();
level = Tone.dbToGain(level); //scale it between 0 - 1
meterContext.clearRect(0, 0, canvasWidth, canvasHeight);
meterContext.fillStyle = meterGraident;
meterContext.fillRect(0, 0, canvasWidth, canvasHeight);
meterContext.fillStyle = "white";
meterContext.fillRect(canvasWidth * level, 0, canvasWidth, canvasHeight);
}
//size the canvase
var canvasWidth, canvasHeight;
function sizeCanvases(){
canvasWidth = $("#fft").width();
canvasHeight = $("#fft").height();
meterContext.canvas.width = canvasWidth;
meterContext.canvas.height = canvasHeight;
//make the gradient
meterGraident = meterContext.createLinearGradient(0, 0, canvasWidth, canvasHeight);
meterGraident.addColorStop(0, "#BFFF02");
meterGraident.addColorStop(0.8, "#02FF24");
meterGraident.addColorStop(1, "#FF0202");
}
sizeCanvases();
$(window).resize(sizeCanvases);
function loop(){
requestAnimationFrame(loop);
//draw the meter level
drawMeter();
}
loop();
</script> </script>
</body> </body>
</html> </html>

View file

@ -2,104 +2,44 @@
<html> <html>
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<title>MICROPHONE</title> <title>Microphone</title>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"> <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<link rel="icon" type="image/png" sizes="174x174" href="./style/favicon.png"> <link rel="icon" type="image/png" sizes="174x174" href="./favicon.png">
<script src="https://unpkg.com/@webcomponents/webcomponentsjs@^2/webcomponents-bundle.js"></script>
<script src="../build/Tone.js"></script> <script src="../build/Tone.js"></script>
<script src="./scripts/jquery.min.js"></script> <script src="./js/tonejs-ui.js"></script>
<script src="./scripts/draggabilly.js"></script>
<script src="./scripts/StartAudioContext.js"></script>
<script src="./scripts/Interface.js"></script>
<script src="https://tonejs.github.io/Logo/build/Logo.js"></script>
<link rel="stylesheet" type="text/css" href="./style/examples.css">
<script>
// jshint ignore: start
</script>
</head> </head>
<body> <body>
<style type="text/css"> <style type="text/css">
canvas { tone-oscilloscope {
width: 100%; width: 100%;
height: 200px;
background-color: black; background-color: black;
border-bottom-left-radius: 5px; height: 40px;
border-bottom-right-radius: 5px; border-radius: 20px;
margin-bottom: 10px;
} }
</style> </style>
<div id="Content" class="FullScreen"> <tone-example>
<div id="Title">Microphone</div> <tone-explanation label="Microphone">
<div id="Explanation">
If supported, Tone.UserMedia uses <code>getUserMedia</code> to open the user's microphone where it can then be processed with Tone.js. Only works on https domains. If supported, Tone.UserMedia uses <code>getUserMedia</code> to open the user's microphone where it can then be processed with Tone.js. Only works on https domains.
</div> </tone-explanation>
</div>
<script>
<tone-content>
<tone-oscilloscope></tone-oscilloscope>
<tone-microphone></tone-microphone>
</tone-content>
</tone-example>
<script type="text/javascript">
//you probably DONT want to connect the microphone //you probably DONT want to connect the microphone
//directly to the master output because of feedback. //directly to the master output because of feedback.
var mic = new Tone.UserMedia(); var mic = new Tone.UserMedia();
var analyser = new Tone.Waveform(256); //bind the interface
document.querySelector("tone-microphone").bind(mic);
mic.connect(analyser); document.querySelector("tone-oscilloscope").bind(mic);
// GUI //
//indicate if the microphone is supported or not
if (!Tone.UserMedia.supported){
$("<div>", {
"id" : "NotSupported",
"text" : "getUserMedia is not supported by your browser."
}).appendTo("#Content");
} else {
var canvas = $("<canvas>").appendTo("#Content");
var context = canvas.get(0).getContext("2d");
context.canvas.width = canvas.width();
context.canvas.height = canvas.height();
function drawLoop(){
var canvasWidth = context.canvas.width;
var canvasHeight = context.canvas.height;
requestAnimationFrame(drawLoop);
//draw the waveform
context.clearRect(0, 0, canvasWidth, canvasHeight);
var values = analyser.getValue();
context.beginPath();
context.lineJoin = "round";
context.lineWidth = 6;
context.strokeStyle = "white";
context.moveTo(0, (values[0] + 1) / 2 * canvasHeight);
for (var i = 1, len = values.length; i < len; i++){
var val = (values[i] + 1) / 2;
var x = canvasWidth * (i / (len - 1));
var y = val * canvasHeight;
context.lineTo(x, y);
}
context.stroke();
}
drawLoop();
Interface.Button({
type : "toggle",
text : "Open Mic",
activeText : "Close Mic",
start : function(){
mic.open();
},
end : function(){
mic.close();
}
});
}
</script> </script>

View file

@ -4,149 +4,58 @@
<meta charset="utf-8"> <meta charset="utf-8">
<title>Mixer</title> <title>Mixer</title>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"> <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<link rel="icon" type="image/png" sizes="174x174" href="./style/favicon.png"> <link rel="icon" type="image/png" sizes="174x174" href="./favicon.png">
<script src="https://unpkg.com/@webcomponents/webcomponentsjs@^2/webcomponents-bundle.js"></script>
<script src="../build/Tone.js"></script> <script src="../build/Tone.js"></script>
<script src="./scripts/jquery.min.js"></script> <script src="./js/tonejs-ui.js"></script>
<script src="./scripts/draggabilly.js"></script>
<script src="./scripts/StartAudioContext.js"></script>
<script src="./scripts/Interface.js"></script>
<script src="https://tonejs.github.io/Logo/build/Logo.js"></script>
<link rel="stylesheet" type="text/css" href="./style/examples.css">
<script>
// jshint ignore: start
</script>
</head>
<body>
<style type="text/css"> <style type="text/css">
img { #tracks {
width: 300px!important; display: flex;
} }
#tracks tone-channel {
.y { flex-grow: 1;
height: 200px!important; margin: 5px;
margin-left: auto; width: 20%;
margin-right: auto;
}
#Sliders {
position: relative;
width: 100%;
display: inline-block;
}
.Group {
width: calc(100%/3 - 6px);
margin-left: 3px;
height: 100%;
float: left;
}
@media (max-width: 500px) {
.Group {
width: calc(50% - 3px);
}
}
.Title {
width: 100%;
text-align: center;
text-transform: uppercase;
font-size: 1.5em;
margin-bottom: 10px;
}
.Group .Button {
width: 100%;
}
.Button {
clear: both;
margin-top: 5px;
} }
</style> </style>
<div id="Content"> </head>
<div id="Title">PanVol / Solo</div> <body>
<div id="Explanation"> <tone-example>
<a href="https://tonejs.github.io/docs/PanVol">Tone.PanVol</a> combines panning and volume control into one component. <a href="https://tonejs.github.io/docs/Solo">Tone.Solo</a> allows you to selectively solo the connected audio. <tone-loader></tone-loader>
</div> <tone-explanation label="Channel">
<div id="Sliders"></div> <a href="https://tonejs.github.io/docs/PanVol">Tone.Channel</a> provides a simple channel interface. It allows for panning and volume changes as well as the ability to <a href="https://tonejs.github.io/docs/Solo">solo</a> (exclude audio in other Tone.Channels).
</tone-explanation>
<tone-content>
<tone-play-toggle></tone-play-toggle>
<div id="tracks">
<tone-channel label="Bass" id="bass"></tone-channel>
<tone-channel label="Chords" id="chords"></tone-channel>
<tone-channel label="Drone" id="drone"></tone-channel>
</div> </div>
</tone-content>
</tone-example>
<script> <script type="text/javascript">
function makeChannel(name){
var channel = new Tone.Channel().toMaster();
var player = new Tone.Player({
url : `./audio/loop/${name}.[mp3|ogg]`,
loop : true
}).sync().start(0);
player.chain(channel);
//bind the UI
function makeFader(track, name){ document.querySelector(`#${name}`).bind(channel);
var player = new Tone.Player("./audio/loop/"+track+".[mp3|ogg]").sync().start(0);
player.loop = true;
var soloCtrl = new Tone.Solo();
var panVol = new Tone.PanVol();
player.chain(panVol, soloCtrl, Tone.Master);
var container = $("<div>", {
"class" : "Group"
}).appendTo('#Sliders');
$("<div>", {
"class" : "Title",
"text" : track
}).appendTo(container);
Interface.Slider({
param : "volume",
name : "volume",
parent : container,
tone : panVol,
axis : "y",
exp : 0.5,
max : 6,
min : -60,
});
Interface.Slider({
param : "pan",
name : "pan",
parent : container,
tone : panVol,
min : -1,
max : 1,
});
Interface.Button({
parent: container,
type : "toggle",
text : "solo",
activeText : "solo",
start : function(){
soloCtrl.solo = true;
},
end : function(){
soloCtrl.solo = false;
},
});
} }
makeFader("bass"); makeChannel("bass");
makeFader("chords"); makeChannel("chords");
makeFader("drone"); makeChannel("drone");
Interface.Button({
type : "toggle",
text : "Start",
activeText : "Stop",
start : function(){
Tone.Transport.start()
},
end : function(){
Tone.Transport.stop()
},
});
document.querySelector("tone-play-toggle").bind(Tone.Transport);
</script> </script>
</body> </body>
</html> </html>

View file

@ -4,38 +4,34 @@
<meta charset="utf-8"> <meta charset="utf-8">
<title>MonoSynth</title> <title>MonoSynth</title>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"> <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<link rel="icon" type="image/png" sizes="174x174" href="./style/favicon.png"> <link rel="icon" type="image/png" sizes="174x174" href="./favicon.png">
<script src="https://unpkg.com/@webcomponents/webcomponentsjs@^2/webcomponents-bundle.js"></script>
<script src="../build/Tone.js"></script> <script src="../build/Tone.js"></script>
<script src="./scripts/jquery.min.js"></script> <script src="./js/tonejs-ui.js"></script>
<script src="./scripts/draggabilly.js"></script>
<script src="./scripts/StartAudioContext.js"></script>
<script src="./scripts/Interface.js"></script>
<script src="https://tonejs.github.io/Logo/build/Logo.js"></script>
<script src="./scripts/Keyboard.js"></script>
<link rel="stylesheet" type="text/css" href="./style/examples.css">
<script>
// jshint ignore: start
</script>
</head> </head>
<body> <body>
<div id="Content"> <style>
<div id="Title">MonoSynth</div> tone-piano {
<div id="Explanation"> margin-bottom: 10px;
<a href="https://tonejs.github.io/docs/#MonoSynth">Tone.MonoSynth</a> }
</style>
<tone-example>
<tone-explanation label="MonoSynth">
<a href="https://tonejs.github.io/docs/MonoSynth">Tone.MonoSynth</a>
is composed of one oscillator, one filter, and two envelopes. is composed of one oscillator, one filter, and two envelopes.
Both envelopes are triggered simultaneously when a note is triggered. Both envelopes are triggered simultaneously when a note is triggered.
</div> </tone-explanation>
<div id="Keyboard"></div>
</div>
<script> <tone-content>
<tone-piano polyphonic></tone-piano>
<tone-mono-synth polyphonic></tone-mono-synth>
</tone-content>
</tone-example>
var synth = new Tone.MonoSynth({ <script type="text/javascript">
var synth = new Tone.PolySynth(4, Tone.MonoSynth, {
"oscillator" : { "oscillator" : {
"type" : "square8" "type" : "square8"
}, },
@ -55,18 +51,9 @@
} }
}).toMaster(); }).toMaster();
// GUI // //bind the interface
document.querySelector("tone-piano").bind(synth);
var keyboard = Interface.Keyboard(); document.querySelector("tone-mono-synth").bind(synth);
keyboard.keyDown = function (note) {
synth.triggerAttack(note);
};
keyboard.keyUp = function () {
synth.triggerRelease();
};
</script> </script>
</body> </body>

View file

@ -2,68 +2,50 @@
<html> <html>
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<title>NOISES</title> <title>Noise</title>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"> <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<link rel="icon" type="image/png" sizes="174x174" href="./style/favicon.png"> <link rel="icon" type="image/png" sizes="174x174" href="./favicon.png">
<script src="https://unpkg.com/@webcomponents/webcomponentsjs@^2/webcomponents-bundle.js"></script>
<script src="../build/Tone.js"></script> <script src="../build/Tone.js"></script>
<script src="./scripts/jquery.min.js"></script> <script src="./js/tonejs-ui.js"></script>
<script src="./scripts/draggabilly.js"></script>
<script src="./scripts/StartAudioContext.js"></script>
<script src="./scripts/Interface.js"></script>
<script src="https://tonejs.github.io/Logo/build/Logo.js"></script>
<link rel="stylesheet" type="text/css" href="./style/examples.css">
<script>
// jshint ignore: start
</script>
</head> </head>
<body> <body>
<style type="text/css"> <style>
.Dragger#Noise { tone-trigger, tone-oscilloscope {
left: 50%; margin-bottom: 10px;
}
tone-oscilloscope {
background-color: black;
height: 60px;
width: 100%;
} }
</style> </style>
<div id="Content"> <tone-example>
<div id="Title">Noise</div> <tone-explanation label="Noise">
<div id="Explanation"> <a href="https://tonejs.github.io/docs/Noise">Tone.Noise</a>
<a href="https://tonejs.github.io/docs/#Noise">Tone.Noise</a>
has 3 different types of noise. Careful, it's loud! has 3 different types of noise. Careful, it's loud!
</div> </tone-explanation>
<div id="DragContainer"></div>
</div> <tone-content>
<script id="ToneCode"> <tone-oscilloscope></tone-oscilloscope>
<tone-trigger></tone-trigger>
<tone-noise></tone-noise>
</tone-content>
</tone-example>
<script type="text/javascript">
//make the noise and connect it to the output //make the noise and connect it to the output
var noise = new Tone.Noise({ var noise = new Tone.Noise({
"volume" : -20, "volume" : -10,
"type" : "brown" "type" : "brown"
}).toMaster(); }).toMaster();
// GUI // //bind the inteface
document.querySelector("tone-oscilloscope").bind(noise);
Interface.Dragger({ document.querySelector("tone-trigger").bind(noise);
tone : noise, document.querySelector("tone-noise").bind(noise);
y : {
param : "volume",
min : -40,
max : 0
},
x : {
param : "type",
options : ["white", "brown", "pink"]
},
start : function(){
noise.start();
Tone.Master.volume.rampTo(0, 0.05);
},
end : function(){
//so it doesn't click
Tone.Master.volume.rampTo(-Infinity, 0.05);
}
});
</script> </script>
</body> </body>
</html> </html>

View file

@ -4,44 +4,38 @@
<meta charset="utf-8"> <meta charset="utf-8">
<title>Offline</title> <title>Offline</title>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"> <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<link rel="icon" type="image/png" sizes="174x174" href="./style/favicon.png"> <link rel="icon" type="image/png" sizes="174x174" href="./favicon.png">
<script src="https://unpkg.com/@webcomponents/webcomponentsjs@^2/webcomponents-bundle.js"></script>
<script src="../build/Tone.js"></script> <script src="../build/Tone.js"></script>
<script src="./scripts/jquery.min.js"></script> <script src="./js/tonejs-ui.js"></script>
<script src="./scripts/draggabilly.js"></script>
<script src="./scripts/StartAudioContext.js"></script>
<script src="./scripts/Interface.js"></script>
<script src="https://tonejs.github.io/Logo/build/Logo.js"></script>
<link rel="stylesheet" type="text/css" href="./style/examples.css">
<script>
// jshint ignore: start
</script>
<style type="text/css"> <style type="text/css">
.Button:not(.Visible) { tone-button {
display: none; margin-bottom: 10px;
} }
</style> </style>
</head> </head>
<body> <body>
<div id="Content"> <tone-example>
<div id="Title">Offline</div> <tone-loader></tone-loader>
<div id="Explanation">
<tone-explanation label="Offline Rendering">
Tone.Offline renders a chunk of Tone.js code into an AudioBuffer. An offline instance of Tone.Transport is passed into the callback which can be used to schedule events. It may take a moment to render the sound. Tone.Offline renders a chunk of Tone.js code into an AudioBuffer. An offline instance of Tone.Transport is passed into the callback which can be used to schedule events. It may take a moment to render the sound.
<br><br> <br><br>
<a href="https://tonejs.github.io/docs/#Tone.Offline">Tone.Offline</a> docs. <a href="https://tonejs.github.io/docs/Tone#offline">Tone.Offline</a> docs.
</div> </tone-explanation>
</div>
<script>
<tone-content>
<tone-button label="Render"></tone-button>
<tone-play-toggle disabled></tone-play-toggle>
</tone-content>
</tone-example>
<script type="text/javascript">
//load the buffer for use in the convolver //load the buffer for use in the convolver
var buffer = new Tone.Buffer("./audio/IRs/chorus-feedback.wav"); var buffer = new Tone.Buffer("./audio/IRs/chorus-feedback.wav");
Interface.Loader();
function generateAudioOffline(){ function generateAudioOffline(){
return Tone.Offline(function(Transport){ return Tone.Offline(function(Transport){
@ -60,7 +54,7 @@
} }
}).connect(pannerA); }).connect(pannerA);
var seqA = new Tone.Sequence(function(time, note){ var seqA = new Tone.Sequence(function(time, note){
synthA.triggerAttack(note, time) synthA.triggerAttack(note, time);
}, ["A4", "G4", "G#4", "F#4", "E4"], "8n").start(0); }, ["A4", "G4", "G#4", "F#4", "E4"], "8n").start(0);
seqA.loop = false; seqA.loop = false;
@ -76,7 +70,7 @@
} }
}).connect(pannerB); }).connect(pannerB);
var seqB = new Tone.Sequence(function(time, note){ var seqB = new Tone.Sequence(function(time, note){
synthB.triggerAttack(note, time) synthB.triggerAttack(note, time);
}, ["G#4", "A4", "G4", "F4", "C4"], "8n").start("16n"); }, ["G#4", "A4", "G4", "F4", "C4"], "8n").start("16n");
seqB.loop = false; seqB.loop = false;
@ -86,48 +80,31 @@
"decay" : 3, "decay" : 3,
"sustain" : 0.1 "sustain" : 0.1
}, },
}).toMaster() }).toMaster();
var bassSeq = new Tone.Sequence(function(time, note){ var bassSeq = new Tone.Sequence(function(time, note){
bass.triggerAttackRelease(note, "1n", time) bass.triggerAttackRelease(note, "1n", time);
}, ["C2", "C2", "F1", "F1"], "4n").start(0); }, ["C2", "C2", "F1", "F1"], "4n").start(0);
bassSeq.loop = false; bassSeq.loop = false;
Transport.bpm.value = 150; Transport.bpm.value = 150;
Transport.start(); Transport.start();
}, 7).then(function(buffer){ }, 7);
//set the buffer once it's rendered
player.buffer = buffer;
});
} }
//play the buffer with a Tone.Player when it's been generated
var player = new Tone.Player().toMaster(); var player = new Tone.Player().toMaster();
// GUI // //bind the interface
document.querySelector("tone-button").addEventListener("click", e => {
var playButton = Interface.Button({ e.target.setAttribute("label", "Rendering...");
text : "Play", e.target.setAttribute("disabled", "");
activeText : "Stop", var buffer = generateAudioOffline().then(buffer => {
type : "toggle", document.querySelector("tone-button").setAttribute("label", "Rendered");
start : function(){ player.buffer = buffer;
player.start(); document.querySelector("tone-play-toggle").removeAttribute("disabled");
},
end : function(){
player.stop();
}
}); });
//the render button
var renderButton = Interface.Button({
text : "Render",
start : function(){
renderButton.element.text("Rendering...");
generateAudioOffline().then(function(){
renderButton.element.remove();
playButton.element.addClass("Visible");
}); });
} document.querySelector("tone-play-toggle").bind(player);
});
renderButton.element.addClass("Visible");
</script> </script>
</body> </body>

View file

@ -4,63 +4,44 @@
<meta charset="utf-8"> <meta charset="utf-8">
<title>Oscillator</title> <title>Oscillator</title>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"> <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<link rel="icon" type="image/png" sizes="174x174" href="./style/favicon.png"> <link rel="icon" type="image/png" sizes="174x174" href="./favicon.png">
<script src="https://unpkg.com/@webcomponents/webcomponentsjs@^2/webcomponents-bundle.js"></script>
<script src="../build/Tone.js"></script> <script src="../build/Tone.js"></script>
<script src="./scripts/jquery.min.js"></script> <script src="./js/tonejs-ui.js"></script>
<script src="./scripts/draggabilly.js"></script> <style type="text/css">
<script src="./scripts/StartAudioContext.js"></script> tone-play-toggle {
<script src="./scripts/Interface.js"></script> margin-bottom: 10px;
<script src="https://tonejs.github.io/Logo/build/Logo.js"></script> }
</style>
<link rel="stylesheet" type="text/css" href="./style/examples.css">
<script>
// jshint ignore: start
</script>
</head> </head>
<body> <body>
<div id="Content"> <tone-example>
<div id="Title">Oscillator</div> <tone-explanation label="Oscillator">
<div id="Explanation"> The oscillator has 4 basic types which can be altered by setting the number
Click and drag the dot to hear the oscillator. The x-axis controls the frequency of the oscillator and the y-axis controls the volume. of partials and partials array.
<br><br> <br><br>
<a href="https://tonejs.github.io/docs/#Oscillator">Tone.Oscillator</a> docs. <a href="https://tonejs.github.io/docs/Oscillator">Tone.Oscillator</a> docs.
</div> </tone-explanation>
<div id="DragContainer"></div>
</div> <tone-content>
<script id="ToneCode"> <tone-play-toggle></tone-play-toggle>
<tone-oscillator label="Oscillator" frequency></tone-oscillator>
</tone-content>
</tone-example>
<script type="text/javascript">
var osc = new Tone.Oscillator({ var osc = new Tone.Oscillator({
"type" : "square",
"frequency" : 440, "frequency" : 440,
"volume" : -10 "volume" : -16
}).toMaster(); }).toMaster();
// GUI // //bind the interface
document.querySelector("tone-oscillator").bind(osc);
Interface.Dragger({ document.querySelector("tone-play-toggle").bind(osc);
tone : osc,
x : {
param : "frequency",
min : 60,
max : 2000,
exp : 2
},
y : {
param : "volume",
min : -40,
max : 0
},
start : function(){
osc.start();
Tone.Master.volume.rampTo(0, 0.05);
},
end : function(){
//so it doesn't click
Tone.Master.volume.rampTo(-Infinity, 0.05);
}
});
</script> </script>
</body> </body>
</html> </html>

View file

@ -4,51 +4,46 @@
<meta charset="utf-8"> <meta charset="utf-8">
<title>Phasing</title> <title>Phasing</title>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"> <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<link rel="icon" type="image/png" sizes="174x174" href="./style/favicon.png"> <link rel="icon" type="image/png" sizes="174x174" href="./favicon.png">
<script src="https://unpkg.com/@webcomponents/webcomponentsjs@^2/webcomponents-bundle.js"></script>
<script src="../build/Tone.js"></script> <script src="../build/Tone.js"></script>
<script src="./scripts/jquery.min.js"></script> <script src="./js/tonejs-ui.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>
<link rel="stylesheet" type="text/css" href="./style/examples.css">
<script>
// jshint ignore: start
</script>
</head> </head>
<body> <body>
<style type="text/css"> <style type="text/css">
#loop {
#Left, #Right { margin-bottom: 10px;
height: 200px; display: flex;
width: 50%; background-color: #777;
position: relative; border-radius: 20px;
float: left; padding: 10px;
margin-top: 5px;
margin-bottom: 5px;
} }
tone-loop {
.Button { flex-grow: 1;
display: inline-block; width: 40%;
height: 150px;
} }
</style> </style>
<div id="Content"> <tone-example>
<div id="Title">Piano Phase</div> <tone-explanation label="Piano Phase">
<div id="Explanation">
By slightly slowing down the playbackRate of the Tone.Sequence in the right channel, 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. the two identical melodies phase against each other in interesting ways.
<br><br>
Composition by Steve Reich. Inspiration from Alexander Chen. Composition by Steve Reich. Inspiration from Alexander Chen.
</div> </tone-explanation>
<canvas id="Left"></canvas>
<canvas id="Right"></canvas>
</div>
<script> <tone-content>
<div id="loop">
<tone-loop id="left" color="#7F33ED"></tone-loop>
<tone-loop id="right" color="#1EDF3E"></tone-loop>
</div>
<tone-play-toggle></tone-play-toggle>
</tone-content>
</tone-example>
<script type="text/javascript">
//set the bpm and time signature first //set the bpm and time signature first
Tone.Transport.timeSignature = [6, 4]; Tone.Transport.timeSignature = [6, 4];
Tone.Transport.bpm.value = 180; Tone.Transport.bpm.value = 180;
@ -66,21 +61,21 @@
//the synth settings //the synth settings
var synthSettings = { var synthSettings = {
"oscillator": { "oscillator" : {
"detune": 0, "detune" : 0,
"type": "custom", "type" : "custom",
"partials" : [2, 1, 2, 2], "partials" : [2, 1, 2, 2],
"phase": 0, "phase" : 0,
"volume": 0 "volume" : 0
}, },
"envelope": { "envelope" : {
"attack": 0.005, "attack" : 0.005,
"decay": 0.3, "decay" : 0.3,
"sustain": 0.2, "sustain" : 0.2,
"release": 1, "release" : 1,
}, },
"portamento": 0.01, "portamento" : 0.01,
"volume": -20 "volume" : -20
}; };
//left and right synthesizers //left and right synthesizers
@ -99,7 +94,10 @@
//set the playback rate of the right part to be slightly slower //set the playback rate of the right part to be slightly slower
partR.playbackRate = 0.985; partR.playbackRate = 0.985;
// GUI // document.querySelector("tone-play-toggle").bind(Tone.Transport);
document.querySelector("#left").bind(partL);
document.querySelector("#right").bind(partR);
/*// GUI //
Interface.Button({ Interface.Button({
key : 32, key : 32,
@ -167,7 +165,7 @@
rightContext.stroke(); rightContext.stroke();
rightContext.restore(); rightContext.restore();
} }
loop(); loop();*/
</script> </script>
</body> </body>

View file

@ -2,34 +2,43 @@
<html> <html>
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<title>PINGPONG DELAY</title> <title>Ping Pong Delay</title>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"> <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<link rel="icon" type="image/png" sizes="174x174" href="./style/favicon.png"> <link rel="icon" type="image/png" sizes="174x174" href="./favicon.png">
<script src="https://unpkg.com/@webcomponents/webcomponentsjs@^2/webcomponents-bundle.js"></script>
<script src="../build/Tone.js"></script> <script src="../build/Tone.js"></script>
<script src="./scripts/jquery.min.js"></script> <script src="./js/tonejs-ui.js"></script>
<script src="./scripts/draggabilly.js"></script> <style type="text/css">
<script src="./scripts/StartAudioContext.js"></script> tone-trigger, tone-meter {
<script src="./scripts/Interface.js"></script> margin-bottom: 10px;
<script src="https://tonejs.github.io/Logo/build/Logo.js"></script> }
tone-meter {
<link rel="stylesheet" type="text/css" href="./style/examples.css"> background-color: black;
height: 100px;
<script> width: 100%;
// jshint ignore: start }
</script> </style>
</head> </head>
<body> <body>
<div id="Content"> <tone-example>
<div id="Title">Ping Pong Delay</div> <tone-loader></tone-loader>
<div id="Explanation">
<tone-explanation label="Ping Pong Delay">
A Ping Pong Delay is a stereo feedback delay where the delay bounces back and forth between the left and right channels. Hit the button to trigger a snare sample into the effect. A Ping Pong Delay is a stereo feedback delay where the delay bounces back and forth between the left and right channels. Hit the button to trigger a snare sample into the effect.
<br><br> <br><br>
<a href="https://tonejs.github.io/docs/#PingPongDelay">Tone.PingPongDelay</a> docs. <a href="https://tonejs.github.io/docs/PingPongDelay">Tone.PingPongDelay</a> docs.
</div> </tone-explanation>
</div>
<script> <tone-content>
<tone-meter stereo></tone-meter>
<tone-trigger></tone-trigger>
<tone-ping-pong-delay></tone-ping-pong-delay>
</tone-content>
</tone-example>
<script type="text/javascript">
//the feedback delay //the feedback delay
var feedbackDelay = new Tone.PingPongDelay({ var feedbackDelay = new Tone.PingPongDelay({
"delayTime" : "8n", "delayTime" : "8n",
@ -40,14 +49,10 @@
//play a snare sound through it //play a snare sound through it
var player = new Tone.Player("./audio/505/snare.[mp3|ogg]").connect(feedbackDelay); var player = new Tone.Player("./audio/505/snare.[mp3|ogg]").connect(feedbackDelay);
Interface.Loader(); //bind the interface
document.querySelector("tone-trigger").bind(player);
Interface.Button({ document.querySelector("tone-ping-pong-delay").bind(feedbackDelay);
text : "trigger", document.querySelector("tone-meter").bind(feedbackDelay);
start : function(){
player.start();
},
});
</script> </script>
</body> </body>
</html> </html>

View file

@ -2,55 +2,47 @@
<html> <html>
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<title>PLAYER</title> <title>Player</title>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"> <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<link rel="icon" type="image/png" sizes="174x174" href="./style/favicon.png"> <link rel="icon" type="image/png" sizes="174x174" href="./favicon.png">
<script src="https://unpkg.com/@webcomponents/webcomponentsjs@^2/webcomponents-bundle.js"></script>
<script src="../build/Tone.js"></script> <script src="../build/Tone.js"></script>
<script src="./scripts/jquery.min.js"></script> <script src="./js/tonejs-ui.js"></script>
<script src="./scripts/draggabilly.js"></script> <style type="text/css">
<script src="./scripts/StartAudioContext.js"></script> tone-play-toggle {
<script src="./scripts/Interface.js"></script> margin-bottom: 10px;
<script src="https://tonejs.github.io/Logo/build/Logo.js"></script> }
</style>
<link rel="stylesheet" type="text/css" href="./style/examples.css">
<script>
// jshint ignore: start
</script>
</head> </head>
<body> <body>
<div id="Content"> <tone-example>
<div id="Title">Grains</div> <tone-loader></tone-loader>
<div id="Explanation">
Click on the button to play the audio file on loop
using <a href="https://tonejs.github.io/docs/#Player">Tone.Player</a>.
</div>
</div>
<script>
<tone-explanation label="Player">
Click on the button to play the audio file on loop
using <a href="https://tonejs.github.io/docs/Player">Tone.Player</a>.
</tone-explanation>
<tone-content>
<tone-play-toggle></tone-play-toggle>
<tone-player></tone-player>
</tone-content>
</tone-example>
<script type="text/javascript">
//the player //the player
var player = new Tone.Player({ var player = new Tone.Player({
"url" : "./audio/FWDL.[mp3|ogg]", "url" : "./audio/FWDL.[mp3|ogg]",
"loop" : true "loop" : true,
"loopStart" : 0.5,
"loopEnd" : 0.7,
}).toMaster(); }).toMaster();
// GUI // //bind the interface
document.querySelector("tone-player").bind(player);
Interface.Loader(); document.querySelector("tone-play-toggle").bind(player);
Interface.Button({
text : "Start",
activeText : "Stop",
start : function(){
player.start();
},
end : function(){
player.stop();
}
});
</script> </script>
</body> </body>

View file

@ -4,59 +4,45 @@
<meta charset="utf-8"> <meta charset="utf-8">
<title>PolySynth</title> <title>PolySynth</title>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"> <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<link rel="icon" type="image/png" sizes="174x174" href="./style/favicon.png"> <link rel="icon" type="image/png" sizes="174x174" href="./favicon.png">
<script src="https://unpkg.com/@webcomponents/webcomponentsjs@^2/webcomponents-bundle.js"></script>
<script src="../build/Tone.js"></script> <script src="../build/Tone.js"></script>
<script src="./scripts/jquery.min.js"></script> <script src="./js/tonejs-ui.js"></script>
<script src="./scripts/draggabilly.js"></script>
<script src="./scripts/StartAudioContext.js"></script>
<script src="./scripts/Interface.js"></script>
<script src="https://tonejs.github.io/Logo/build/Logo.js"></script>
<script src="./scripts/Keyboard.js"></script>
<link rel="stylesheet" type="text/css" href="./style/examples.css">
<script>
// jshint ignore: start
</script>
</head> </head>
<body> <body>
<div id="Content" class="FullScreen"> <style>
<div id="Title">PolySynth</div> tone-piano {
<div id="Explanation"> margin-bottom: 10px;
<a href="https://tonejs.github.io/docs/#PolySynth">Tone.PolySynth</a> }
handles voice creation and allocation for any </style>
<tone-example>
<tone-explanation label="Polyphony">
<a href="https://tonejs.github.io/docs/PolySynth">Tone.PolySynth</a>
handles voice creation and allocation for any monophonic
instruments passed in as the second parameter. PolySynth is instruments passed in as the second parameter. PolySynth is
not a synthesizer by itself, it merely manages voices of not a synthesizer by itself, it merely manages voices of
one of the other types of synths, allowing any of the one of the other types of synths, allowing any of the
monophonic synthesizers to be polyphonic. monophonic synthesizers to be polyphonic.
</div> </tone-explanation>
<div id="Keyboard"></div>
</div>
<script> <tone-content>
<tone-piano polyphonic></tone-piano>
<tone-synth polyphonic></tone-synth>
</tone-content>
</tone-example>
var synth = new Tone.PolySynth(6, Tone.Synth, { <script type="text/javascript">
var synth = new Tone.PolySynth(8, Tone.Synth, {
"oscillator" : { "oscillator" : {
"partials" : [0, 2, 3, 4], "partials" : [0, 2, 3, 4],
} }
}).toMaster(); }).toMaster();
// GUI // //bind the interface
document.querySelector("tone-piano").bind(synth);
var keyboard = Interface.Keyboard(); document.querySelector("tone-synth").bind(synth);
keyboard.keyDown = function (note) {
synth.triggerAttack(note);
};
keyboard.keyUp = function (note) {
synth.triggerRelease(note);
};
</script> </script>
</body> </body>
</html> </html>

View file

@ -2,79 +2,76 @@
<html> <html>
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<title>Quantize</title> <title>Quantization</title>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"> <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<link rel="icon" type="image/png" sizes="174x174" href="./style/favicon.png"> <link rel="icon" type="image/png" sizes="174x174" href="./favicon.png">
<script src="https://unpkg.com/@webcomponents/webcomponentsjs@^2/webcomponents-bundle.js"></script>
<script src="../build/Tone.js"></script> <script src="../build/Tone.js"></script>
<script src="./scripts/jquery.min.js"></script> <script src="./js/tonejs-ui.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>
<link rel="stylesheet" type="text/css" href="./style/examples.css">
<script>
// jshint ignore: start
</script>
</head> </head>
<body> <body>
<style type="text/css"> <style>
.Button { #buttons {
width: calc(50% - 4px)!important; display: flex;
float: left; margin: 10px 0;
margin: 2px; }
#buttons tone-button {
flex-grow: 1;
margin: 5px;
} }
</style> </style>
<div id="Content" class="FullScreen"> <tone-example>
<div id="Title">Quantization</div> <tone-explanation label="Quantization">
<div id="Explanation">
Using the "@" symbol, <a href="https://github.com/Tonejs/Tone.js/wiki/Time" target="_blank">Time</a> Using the "@" symbol, <a href="https://github.com/Tonejs/Tone.js/wiki/Time" target="_blank">Time</a>
expressions can be <a href="https://en.wikipedia.org/wiki/Quantization_(music)" target="_blank">quantized</a> expressions can be <a href="https://en.wikipedia.org/wiki/Quantization_(music)" target="_blank">quantized</a>
(aligned to a subdivision). In this example, a note's start time is aligned to the given subdivision. (aligned to a subdivision). In this example, a note's start time is aligned to the given subdivision.
<br><br>
The Transport must be started
</tone-explanation>
<tone-content>
<tone-transport></tone-transport>
<div id="buttons">
<tone-button disabled id="at8n" label="@8n"></tone-button>
<tone-button disabled id="at4n" label="@4n"></tone-button>
<tone-button disabled id="at2n" label="@2n"></tone-button>
<tone-button disabled id="at1m" label="@1m"></tone-button>
</div> </div>
</div> </tone-content>
<script id="JSCode">
<tone-drawer collapsed>
<tone-synth polyphonic collapsed></tone-synth>
</tone-drawer>
</tone-example>
<script type="text/javascript">
var polySynth = new Tone.PolySynth(4, Tone.Synth).toMaster(); var polySynth = new Tone.PolySynth(4, Tone.Synth).toMaster();
Tone.Transport.start(); //bind the interface
document.querySelector("tone-transport").bind(Tone.Transport);
// GUI // document.querySelector("tone-transport").addEventListener("play", e => {
//enable all of the buttons if it's playing
Interface.Transport(); Array.from(document.querySelectorAll("tone-button")).forEach(el => {
if (e.detail){
Interface.Button({ el.removeAttribute("disabled");
type : "moment", } else {
text : "@1m", el.setAttribute("disabled", "");
start : function(){ }
polySynth.triggerAttackRelease("C2", "8n", "@1m", 2);
},
}); });
Interface.Button({
type : "moment",
text : "@2n",
start : function(){
polySynth.triggerAttackRelease("G3", "8n", "@2n");
},
}); });
document.querySelector("#at8n").addEventListener("click", e => {
Interface.Button({
type : "moment",
text : "@4n",
start : function(){
polySynth.triggerAttackRelease("E4", "8n", "@4n");
},
});
Interface.Button({
type : "moment",
text : "@8n",
start : function(){
polySynth.triggerAttackRelease("B4", "8n", "@8n"); polySynth.triggerAttackRelease("B4", "8n", "@8n");
}, });
document.querySelector("#at4n").addEventListener("click", e => {
polySynth.triggerAttackRelease("E4", "8n", "@4n");
});
document.querySelector("#at2n").addEventListener("click", e => {
polySynth.triggerAttackRelease("G3", "8n", "@2n");
});
document.querySelector("#at1m").addEventListener("click", e => {
polySynth.triggerAttackRelease("C2", "8n", "@1m");
}); });
</script> </script>
</body> </body>

View file

@ -2,46 +2,38 @@
<html> <html>
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<title>SIGNAL RAMP</title> <title>Signal Ramping</title>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"> <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<link rel="icon" type="image/png" sizes="174x174" href="./style/favicon.png"> <link rel="icon" type="image/png" sizes="174x174" href="./favicon.png">
<script src="https://unpkg.com/@webcomponents/webcomponentsjs@^2/webcomponents-bundle.js"></script>
<script src="../build/Tone.js"></script> <script src="../build/Tone.js"></script>
<script src="./scripts/jquery.min.js"></script> <script src="./js/tonejs-ui.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>
<link rel="stylesheet" type="text/css" href="./style/examples.css">
<script>
// jshint ignore: start
</script>
</head> </head>
<body> <body>
<style type="text/css"> <style>
canvas { tone-slider {
margin-top: 3px; width: 100%;
margin-top: 10px;
} }
</style> </style>
<tone-example>
<div id="Content" class="FullScreen"> <tone-explanation label="rampTo">
<div id="Title">rampTo</div>
<div id="Explanation">
In Tone.js, many of a class' members are <a href="https://tonejs.github.io/docs/#Signal">Tone.Signals</a>.
Working with signals is different than working with numbers or strings: Working with signals is different than working with numbers or strings:
Signals are values which are updated at audio rate, Signals are values which are updated at audio rate,
which allows for sample-accurate scheduling and ramping. <code>.rampTo(value, rampTime)</code> which allows for sample-accurate scheduling and ramping. <code>.rampTo(value, rampTime)</code>
smoothly changes the signal from the current value to the target value over the duration of the rampTime. smoothly changes the signal from the current value to the target value over the duration of the rampTime.
This example uses <code>.rampTo</code> in to smooth out changes in volume and frequency. This example uses <code>.rampTo</code> in to smooth out changes in volume and frequency.
</div> </tone-explanation>
</div>
<script> <tone-content>
<tone-play-toggle></tone-play-toggle>
<tone-slider bare min="0.5" max="2" value="1"></tone-slider>
</tone-content>
</tone-example>
<script type="text/javascript">
var oscillators = []; var oscillators = [];
var bassFreq = 32; var bassFreq = 32;
@ -52,37 +44,26 @@
"type" : "sawtooth10", "type" : "sawtooth10",
"volume" : -Infinity, "volume" : -Infinity,
"detune" : Math.random() * 30 - 15, "detune" : Math.random() * 30 - 15,
}).start().toMaster()); }).toMaster());
} }
Interface.Slider({ //bind the interface
name : "harmony", document.querySelector("tone-play-toggle").addEventListener("play", e => {
min : 0.5, oscillators.forEach(o => {
max : 2, if (e.detail){
value : 1, o.start();
drag : function(value){ o.volume.rampTo(0, 1);
oscillators.forEach(function(osc, i){ } else {
osc.frequency.rampTo(bassFreq * i * value, 0.4); o.stop("+1.2");
o.volume.rampTo(-Infinity, 1);
}
}); });
},
}); });
document.querySelector("tone-slider").addEventListener("change", e => {
Interface.Button({ oscillators.forEach((osc, i) => {
text : "Unmute", osc.frequency.rampTo(bassFreq * i * e.detail, 0.4);
activeText : "Mute",
type : "toggle",
key : 32, //spacebar
start : function(){
oscillators.forEach(function(osc){
osc.volume.rampTo(-20, 1);
}); });
},
end : function(){
oscillators.forEach(function(osc){
osc.volume.rampTo(-Infinity, 1);
});
},
}); });
</script> </script>

View file

@ -1,49 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>MODULE LOADERS</title>
<script src="./scripts/StartAudioContext.js"></script>
<script src="./scripts/require.js"></script>
<script src="./scripts/jquery.min.js"></script>
<script src="./scripts/Interface.js"></script>
<link rel="stylesheet" type="text/css" href="./style/examples.css">
</head>
<body>
<div id="Content" class="FullScreen">
<div id="Title">Module Loaders</div>
<div id="Explanation">
<a href="http://requirejs.org/" target="_blank">RequireJS</a>
is a powerful module and build system which Tone.js uses internally.
By only including the modules that your application needs, your build can be
much smaller and your code much more modular.
<br><br>
If you use RequireJS (or any other UMD module loader), but build-size is less of a concern,
you can simply include the entire Tone.js build.
<br><br>
Take a look at the source to see how.
</div>
</div>
<script>
require.config({
baseUrl : "./",
//make a path to the Tone.js/Tone directory
//then include the sources as they are below
paths : {
"Tone" : "../Tone",
}
});
require(["Tone/core/Master", "Tone/instrument/Synth"],
function(Master, Synth){
var synth = new Synth().toMaster();
synth.triggerAttackRelease("C4", "8n");
});
</script>
</body>
</html>

View file

@ -4,88 +4,50 @@
<meta charset="utf-8"> <meta charset="utf-8">
<title>Reverb</title> <title>Reverb</title>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"> <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<link rel="icon" type="image/png" sizes="174x174" href="./style/favicon.png"> <link rel="icon" type="image/png" sizes="174x174" href="./favicon.png">
<script src="https://unpkg.com/@webcomponents/webcomponentsjs@^2/webcomponents-bundle.js"></script>
<script src="../build/Tone.js"></script> <script src="../build/Tone.js"></script>
<script src="./scripts/jquery.min.js"></script> <script src="./js/tonejs-ui.js"></script>
<script src="./scripts/draggabilly.js"></script>
<script src="./scripts/StartAudioContext.js"></script>
<script src="./scripts/Interface.js"></script>
<script src="https://tonejs.github.io/Logo/build/Logo.js"></script>
<script src="./scripts/Keyboard.js"></script>
<link rel="stylesheet" type="text/css" href="./style/examples.css">
<style type="text/css">
.Button:not(.Visible) {
display: none;
}
</style>
</head> </head>
<body> <body>
<div id="Content"> <style>
<div id="Title">Reverb</div> tone-play-toggle {
<div id="Explanation"> margin-bottom: 10px;
<a href="https://tonejs.github.io/docs/#Reverb">Tone.Reverb</a> }
</style>
<tone-example>
<tone-explanation label="Reverb">
<a href="https://tonejs.github.io/docs/Reverb">Tone.Reverb</a>
is a convolution-based reverb. An impulse response is created with a is a convolution-based reverb. An impulse response is created with a
decaying noise burst when you click 'Generate Reverb'. The 'Decay Time' controls decaying noise burst when you click 'Generate Reverb'. The 'Decay Time' controls
how long the noise burst lasts. If the 'Decay Time' is changed, a new noise burst how long the noise burst lasts. If the 'Decay Time' is changed, a new noise burst
will need to be generated. will need to be generated.
<br><br> <br><br>
Note: because of restrictions on iOS, 'generate' must be called from an explicit user action like a tap or click. Note: because of restrictions on iOS, 'generate' must be called from an explicit user action like a tap or click.
</div> </tone-explanation>
</div>
<script> <tone-content>
<tone-play-toggle disabled></tone-play-toggle>
<tone-reverb></tone-reverb>
</tone-content>
</tone-example>
<script type="text/javascript">
var reverb = new Tone.Reverb().toMaster(); var reverb = new Tone.Reverb().toMaster();
reverb.generate().then(() => {
document.querySelector("tone-play-toggle").removeAttribute("disabled");
});
var player = new Tone.Player({ var player = new Tone.Player({
"url" : "./audio/FWDL.[mp3|ogg]", "url" : "./audio/FWDL.[mp3|ogg]",
"loop" : true "loop" : true
}).connect(reverb); }).connect(reverb);
// GUI // //bind the interface
document.querySelector("tone-play-toggle").bind(player);
Interface.Loader(); document.querySelector("tone-reverb").bind(reverb);
var slider = Interface.Slider({
name : "Decay Time",
value : 1.4,
min : 0.1,
max : 8,
drag : function(decay){
reverb.decay = decay;
generateButton.element.addClass("Visible");
}
});
var generateButton = Interface.Button({
text : "Generate Reverb",
end : function(){
generateButton.element.removeClass("Visible");
//'generate' returns a promise
reverb.generate().then(function(){
startButton.element.addClass("Visible");
});
}
});
generateButton.element.addClass("Visible");
var startButton = Interface.Button({
text : "Start",
activeText : "Stop",
type : "toggle",
start : function(){
player.start();
},
end : function(){
player.stop();
}
});
</script> </script>
</body> </body>

View file

@ -4,98 +4,72 @@
<meta charset="utf-8"> <meta charset="utf-8">
<title>Sampler</title> <title>Sampler</title>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"> <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<link rel="icon" type="image/png" sizes="174x174" href="./style/favicon.png"> <link rel="icon" type="image/png" sizes="174x174" href="./favicon.png">
<script src="https://unpkg.com/@webcomponents/webcomponentsjs@^2/webcomponents-bundle.js"></script>
<script src="../build/Tone.js"></script> <script src="../build/Tone.js"></script>
<script src="./scripts/jquery.min.js"></script> <script src="./js/tonejs-ui.js"></script>
<script src="./scripts/draggabilly.js"></script>
<script src="./scripts/StartAudioContext.js"></script>
<script src="./scripts/Interface.js"></script>
<script src="https://tonejs.github.io/Logo/build/Logo.js"></script>
<script src="./scripts/Keyboard.js"></script>
<link rel="stylesheet" type="text/css" href="./style/examples.css">
<script>
// jshint ignore: start
</script>
</head> </head>
<body> <body>
<style type="text/css"> <style>
tone-piano {
img { margin-bottom: 10px;
width: 80%;
max-width: 700px;
margin-left: auto;
margin-right: auto;
display: block;
}
#Keyboard {
margin: 3px!important;
} }
</style> </style>
<div id="Content"> <tone-example>
<div id="Title">Sampler</div> <tone-loader></tone-loader>
<div id="Explanation">
<tone-explanation label="Sampler">
<a href="https://tonejs.github.io/docs/Sampler" target="_blank">Tone.Sampler</a> makes it easy to create an instrument from audio samples. Pass in an object which maps the note's pitch or midi value to the url, then you can trigger the attack and release of that note like other instruments. By automatically repitching the samples, it is possible to play pitches which were not explicitly included which can save loading time. <a href="https://tonejs.github.io/docs/Sampler" target="_blank">Tone.Sampler</a> makes it easy to create an instrument from audio samples. Pass in an object which maps the note's pitch or midi value to the url, then you can trigger the attack and release of that note like other instruments. By automatically repitching the samples, it is possible to play pitches which were not explicitly included which can save loading time.
</div> </tone-explanation>
<div id="Keyboard"></div>
</div>
<script> <tone-content>
<tone-piano polyphonic></tone-piano>
<tone-sampler collapsed></tone-sampler>
</tone-content>
</tone-example>
<script type="text/javascript">
var piano = new Tone.Sampler({ var piano = new Tone.Sampler({
'A0' : 'A0.[mp3|ogg]', "A0" : "A0.[mp3|ogg]",
'C1' : 'C1.[mp3|ogg]', "C1" : "C1.[mp3|ogg]",
'D#1' : 'Ds1.[mp3|ogg]', "D#1" : "Ds1.[mp3|ogg]",
'F#1' : 'Fs1.[mp3|ogg]', "F#1" : "Fs1.[mp3|ogg]",
'A1' : 'A1.[mp3|ogg]', "A1" : "A1.[mp3|ogg]",
'C2' : 'C2.[mp3|ogg]', "C2" : "C2.[mp3|ogg]",
'D#2' : 'Ds2.[mp3|ogg]', "D#2" : "Ds2.[mp3|ogg]",
'F#2' : 'Fs2.[mp3|ogg]', "F#2" : "Fs2.[mp3|ogg]",
'A2' : 'A2.[mp3|ogg]', "A2" : "A2.[mp3|ogg]",
'C3' : 'C3.[mp3|ogg]', "C3" : "C3.[mp3|ogg]",
'D#3' : 'Ds3.[mp3|ogg]', "D#3" : "Ds3.[mp3|ogg]",
'F#3' : 'Fs3.[mp3|ogg]', "F#3" : "Fs3.[mp3|ogg]",
'A3' : 'A3.[mp3|ogg]', "A3" : "A3.[mp3|ogg]",
'C4' : 'C4.[mp3|ogg]', "C4" : "C4.[mp3|ogg]",
'D#4' : 'Ds4.[mp3|ogg]', "D#4" : "Ds4.[mp3|ogg]",
'F#4' : 'Fs4.[mp3|ogg]', "F#4" : "Fs4.[mp3|ogg]",
'A4' : 'A4.[mp3|ogg]', "A4" : "A4.[mp3|ogg]",
'C5' : 'C5.[mp3|ogg]', "C5" : "C5.[mp3|ogg]",
'D#5' : 'Ds5.[mp3|ogg]', "D#5" : "Ds5.[mp3|ogg]",
'F#5' : 'Fs5.[mp3|ogg]', "F#5" : "Fs5.[mp3|ogg]",
'A5' : 'A5.[mp3|ogg]', "A5" : "A5.[mp3|ogg]",
'C6' : 'C6.[mp3|ogg]', "C6" : "C6.[mp3|ogg]",
'D#6' : 'Ds6.[mp3|ogg]', "D#6" : "Ds6.[mp3|ogg]",
'F#6' : 'Fs6.[mp3|ogg]', "F#6" : "Fs6.[mp3|ogg]",
'A6' : 'A6.[mp3|ogg]', "A6" : "A6.[mp3|ogg]",
'C7' : 'C7.[mp3|ogg]', "C7" : "C7.[mp3|ogg]",
'D#7' : 'Ds7.[mp3|ogg]', "D#7" : "Ds7.[mp3|ogg]",
'F#7' : 'Fs7.[mp3|ogg]', "F#7" : "Fs7.[mp3|ogg]",
'A7' : 'A7.[mp3|ogg]', "A7" : "A7.[mp3|ogg]",
'C8' : 'C8.[mp3|ogg]' "C8" : "C8.[mp3|ogg]"
}, { }, {
'release' : 1, "release" : 1,
'baseUrl' : './audio/salamander/' "baseUrl" : "./audio/salamander/"
}).toMaster(); }).toMaster();
// GUI // //bind the interface
document.querySelector("tone-piano").bind(piano);
var keyboard = Interface.Keyboard(); document.querySelector("tone-sampler").bind(piano);
keyboard.keyDown = function (note) {
piano.triggerAttack(note);
};
keyboard.keyUp = function (note) {
piano.triggerRelease(note);
};
Interface.Loader();
</script> </script>
</body> </body>

View file

@ -1,535 +0,0 @@
/* globals Tone, StartAudioContext */
var Interface = {
isMobile : false
};
/**
*
*
* INIT
*
*/
$(function(){
// make all links open a new tab
$("a").attr("target", "_blank");
//mobile start
if( /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent) ) {
Interface.isMobile = true;
$("body").addClass("Mobile");
var element = $("<div>", {"id" : "MobileStart"}).appendTo("body");
var button = $("<div>").attr("id", "Button").text("Enter").appendTo(element);
StartAudioContext(Tone.context, button, function(){
element.remove();
});
}
});
/**
*
* LOADING INDICATOR
*
*/
Interface.Loader = function(){
if (this instanceof Interface.Loader){
this.element = $("<div>", {
"id" : "Loading",
}).appendTo("body");
this.text = $("<div>", {
"id" : "Text",
"text" : "Loading"
}).appendTo(this.element);
Tone.Buffer.on("load", function(){
this.element.addClass("Loaded");
}.bind(this));
} else {
return new Interface.Loader();
}
};
/**
*
*
* DRAGGER
*
*/
Interface.Dragger = function(params){
if (this instanceof Interface.Dragger){
if ($("#DragContainer").length === 0){
$("<div>", {
"id" : "DragContainer"
}).appendTo(params.parent || "#Content");
}
this.container = $("#DragContainer");
/**
* the tone object
*/
this.tone = params.tone;
/**
* callbacks
*/
this.start = params.start;
this.end = params.end;
this.drag = params.drag;
/**
* the name
*/
var name = params.name ? params.name : this.tone ? this.tone.toString() : "";
/**
* elements
*/
this.element = $("<div>", {
"class" : "Dragger",
"id" : name
}).appendTo(this.container)
.on("dragMove", this._ondrag.bind(this))
.on("touchstart mousedown", this._onstart.bind(this))
.on("dragEnd touchend mouseup", this._onend.bind(this));
this.name = $("<div>", {
"id" : "Name",
"text" : name
}).appendTo(this.element);
this.element.draggabilly({
"axis" : this.axis,
"containment": this.container
});
/**
* x slider
*/
var xParams = params.x;
xParams.axis = "x";
xParams.element = this.element;
xParams.tone = this.tone;
xParams.container = this.container;
this.xAxis = new Interface.Slider(xParams);
/**
* y slider
*/
var yParams = params.y;
yParams.axis = "y";
yParams.element = this.element;
yParams.tone = this.tone;
yParams.container = this.container;
this.yAxis = new Interface.Slider(yParams);
//set the axis indicator
var position = this.element.position();
this.halfSize = this.xAxis.halfSize;
this.xAxis.axisIndicator.css("top", position.top + this.halfSize);
this.yAxis.axisIndicator.css("left", position.left + this.halfSize);
} else {
return new Interface.Dragger(params);
}
};
Interface.Dragger.prototype._ondrag = function(e, pointer){
if (this.drag){
this.drag();
}
this.xAxis._ondrag(e, pointer);
this.yAxis._ondrag(e, pointer);
var position = this.element.position();
this.xAxis.axisIndicator.css("top", position.top + this.halfSize);
this.yAxis.axisIndicator.css("left", position.left + this.halfSize);
};
Interface.Dragger.prototype._onstart = function(e){
if (this.start){
this.start();
}
this.xAxis._onstart(e);
this.yAxis._onstart(e);
};
Interface.Dragger.prototype._onend = function(e){
if (this.end){
this.end();
}
this.xAxis._onend(e);
this.yAxis._onend(e);
var position = this.element.position();
this.xAxis.axisIndicator.css("top", position.top + this.halfSize);
this.yAxis.axisIndicator.css("left", position.left + this.halfSize);
};
/**
*
*
* SLIDER
*
*/
Interface.Slider = function(params){
if (this instanceof Interface.Slider){
this.tone = params.tone;
/**
* the name
*/
var name = params.name ? params.name : this.tone ? this.tone.toString() : "";
/**
* callback functions
*/
this.start = params.start;
this.end = params.end;
this.drag = params.drag;
/**
* the axis indicator
*/
this.axis = params.axis || "x";
if (!params.element){
this.container = $("<div>", {
"class" : "Slider "+this.axis,
}).appendTo(params.parent || "#Content");
this.element = $("<div>", {
"class" : "Dragger",
"id" : name
}).appendTo(this.container)
.on("dragMove", this._ondrag.bind(this))
.on("touchstart mousedown", this._onstart.bind(this))
.on("dragEnd touchend mouseup", this._onend.bind(this));
this.name = $("<div>", {
"id" : "Name",
"text" : name
}).appendTo(this.element);
this.element.draggabilly({
"axis" : this.axis,
"containment": this.container.get(0)
});
} else {
this.element = params.element;
this.container = params.container;
}
this.axisIndicator = $("<div>", {
"id" : this.axis + "Axis",
"class" : "Axis"
}).appendTo(this.container);
/**
* the initial value / position
*/
this.parameter = params.param || false;
//default values
this.min = typeof params.min === "undefined" ? 0 : params.min;
this.max = typeof params.max === "undefined" ? 1 : params.max;
this.exp = typeof params.exp === "undefined" ? 1 : params.exp;
if (params.options){
this.options = params.options;
this.min = 0;
this.max = this.options.length - 1;
this.exp = params.exp || 1;
}
/**
* cache some measurements for later
*/
this.halfSize = this.element.width() / 2;
this.maxAxis = this.axis === "x" ? "width" : "height";
this.posAxis = this.axis === "x" ? "left" : "top";
this.oppositeAxis = this.axis === "x" ? "top" : "left";
/**
* initial value
*/
if (this.parameter || typeof params.value !== "undefined"){
var paramValue = typeof params.value !== "undefined" ? params.value : this.tone.get(this.parameter);
this.value(paramValue);
}
} else {
return new Interface.Slider(params);
}
};
Interface.Slider.prototype.value = function(val){
var maxSize = this.container[this.maxAxis]() - this.element[this.maxAxis]();
//y gets inverted
if (this.axis === "y"){
maxSize = this.container[this.maxAxis]() - maxSize;
}
if (val.hasOwnProperty(this.parameter)){
val = val[this.parameter];
}
if (this.options){
val = this.options.indexOf(val);
}
var pos = (val - this.min) / (this.max - this.min);
if (this.axis === "y"){
pos = 1 - pos
}
pos = Math.pow(pos, 1 / this.exp) * (maxSize );
this.element.css(this.posAxis, pos);
if (this.options){
this._setParam(this.options[val]);
}
};
Interface.Slider.prototype._ondrag = function(e, pointer){
if (typeof this.top === "undefined"){
this.top = this.container.offset().top;
this.left = this.container.offset().left;
}
var normPos;
if (this.axis === "x"){
var xVal = Math.max((pointer.pageX - this.left), 0);
normPos = xVal / (this.container.width());
} else {
var yVal = Math.max((pointer.pageY - this.top ), 0);
normPos = yVal / (this.container.height());
normPos = Math.max(1 - normPos, 0);
}
normPos = Math.pow(normPos, this.exp);
var result = normPos * (this.max - this.min) + this.min;
result = Math.max(Math.min(this.max, result), this.min);
var value = result;
if (this.options){
value = this.options[Math.round(result)];
}
if (this.drag){
this.drag(value);
}
this._setParam(value);
};
Interface.Slider.prototype._onstart = function(e){
e.preventDefault();
if (this.start){
this.start();
}
};
Interface.Slider.prototype._onend = function(){
if (this.end){
this.end();
}
};
Interface.Slider.prototype._setParam = function(value){
if (this.parameter && this.tone){
this.tone.set(this.parameter, value);
}
};
/**
*
* BUTTON
*
*/
Interface.Button = function(params){
if (this instanceof Interface.Button){
this.activeText = params.activeText || false;
this.text = params.text || "Button";
this.type = params.type || "moment";
this.element = $("<div>", {
"class" : "Button",
"text" : this.text
}).appendTo(params.parent || "#Content")
.on("mousedown touchstart", this._start.bind(this));
if (this.type === "moment"){
this.element.on("mouseup touchend", this._end.bind(this));
} else {
this.element.addClass("Toggle");
}
/**
* the button state
*/
this.active = false;
/**
* callbacks
*/
this.start = params.start;
this.end = params.end;
/**
* key presses
*/
if (params.key){
this.key = params.key;
$(window).on("keydown", this._keydown.bind(this));
if (this.type === "moment"){
$(window).on("keyup", this._keyup.bind(this));
}
}
} else {
return new Interface.Button(params);
}
};
Interface.Button.prototype._start = function(e){
if (e){
e.preventDefault();
}
if (!this.active){
this.active = true;
this.element.addClass("Active");
if (this.activeText){
this.element.text(this.activeText);
}
if (this.start){
this.start();
}
} else if (this.type === "toggle" && this.active){
this._end();
}
};
Interface.Button.prototype._end = function(e){
if (e){
e.preventDefault();
}
if (this.active){
this.active = false;
this.element.removeClass("Active");
this.element.text(this.text);
if (this.end){
this.end();
}
}
};
Interface.Button.prototype._keydown = function(e){
if (e.which === this.key){
e.preventDefault();
this._start();
}
};
Interface.Button.prototype._keyup = function(e){
if (e.which === this.key){
e.preventDefault();
this._end();
}
};
/**
*
* TRANSPORT
*
*/
Interface.Transport = function(){
if (this instanceof Interface.Transport){
this.element = $("<div>", {
"class" : "Transport",
}).appendTo("#Content");
this.position = $("<div>", {
"id" : "Position"
}).appendTo(this.element);
this._boundLoop = this._loop.bind(this);
this._loop();
} else {
return new Interface.Transport();
}
};
Interface.Transport.prototype._loop = function(){
setTimeout(this._boundLoop, 50);
this.position.text(Tone.Transport.position);
};
/**
*
* KEYBOARD
*
*/
Interface.Keyboard = function(){
if (this instanceof Interface.Keyboard){
this.element = $("<div>", {
"class" : "Keyboard",
}).appendTo("#Content");
if (window.Keyboard){
this.keyboard = new Keyboard(this.element.get(0), 48, 4);
$(window).on("resize", this._resize.bind(this));
this._resize();
this.keyboard.on("keyDown", function(midi){
if (this.keyDown){
this.keyDown(Tone.Frequency(midi, "midi").toNote());
}
}.bind(this));
this.keyboard.on("keyUp", function(midi){
if (this.keyUp){
this.keyUp(Tone.Frequency(midi, "midi").toNote());
}
}.bind(this));
}
} else {
return new Interface.Keyboard();
}
};
Interface.Keyboard.prototype._resize = function(){
var width = $(window).width();
var octaves = Math.round(width / 220);
this.keyboard.octaves = Math.max(octaves, 2);
if (octaves > 4){
this.keyboard.rootNote = 36;
} else {
this.keyboard.rootNote = 48;
}
}

File diff suppressed because one or more lines are too long

View file

@ -1,185 +0,0 @@
/**
* StartAudioContext.js
* @author Yotam Mann
* @license http://opensource.org/licenses/MIT MIT License
* @copyright 2016 Yotam Mann
*/
(function (root, factory) {
if (typeof define === "function" && define.amd) {
define([], factory)
} else if (typeof module === "object" && module.exports) {
module.exports = factory()
} else {
root.StartAudioContext = factory()
}
}(this, function () {
//TAP LISTENER/////////////////////////////////////////////////////////////
/**
* @class Listens for non-dragging tap ends on the given element
* @param {Element} element
* @internal
*/
var TapListener = function(element, context){
this._dragged = false
this._element = element
this._bindedMove = this._moved.bind(this)
this._bindedEnd = this._ended.bind(this, context)
element.addEventListener("touchmove", this._bindedMove)
element.addEventListener("touchend", this._bindedEnd)
element.addEventListener("mouseup", this._bindedEnd)
}
/**
* drag move event
*/
TapListener.prototype._moved = function(e){
this._dragged = true
};
/**
* tap ended listener
*/
TapListener.prototype._ended = function(context){
if (!this._dragged){
startContext(context)
}
this._dragged = false
};
/**
* remove all the bound events
*/
TapListener.prototype.dispose = function(){
this._element.removeEventListener("touchmove", this._bindedMove)
this._element.removeEventListener("touchend", this._bindedEnd)
this._element.removeEventListener("mouseup", this._bindedEnd)
this._bindedMove = null
this._bindedEnd = null
this._element = null
};
//END TAP LISTENER/////////////////////////////////////////////////////////
/**
* Plays a silent sound and also invoke the "resume" method
* @param {AudioContext} context
* @private
*/
function startContext(context){
// this accomplishes the iOS specific requirement
var buffer = context.createBuffer(1, 1, context.sampleRate)
var source = context.createBufferSource()
source.buffer = buffer
source.connect(context.destination)
source.start(0)
// resume the audio context
if (context.resume){
context.resume()
}
}
/**
* Returns true if the audio context is started
* @param {AudioContext} context
* @return {Boolean}
* @private
*/
function isStarted(context){
return context.state === "running"
}
/**
* Invokes the callback as soon as the AudioContext
* is started
* @param {AudioContext} context
* @param {Function} callback
*/
function onStarted(context, callback){
function checkLoop(){
if (isStarted(context)){
callback()
} else {
requestAnimationFrame(checkLoop)
if (context.resume){
context.resume()
}
}
}
if (isStarted(context)){
callback()
} else {
checkLoop()
}
}
/**
* Add a tap listener to the audio context
* @param {Array|Element|String|jQuery} element
* @param {Array} tapListeners
*/
function bindTapListener(element, tapListeners, context){
if (Array.isArray(element) || (NodeList && element instanceof NodeList)){
for (var i = 0; i < element.length; i++){
bindTapListener(element[i], tapListeners, context)
}
} else if (typeof element === "string"){
bindTapListener(document.querySelectorAll(element), tapListeners, context)
} else if (element.jquery && typeof element.toArray === "function"){
bindTapListener(element.toArray(), tapListeners, context)
} else if (Element && element instanceof Element){
//if it's an element, create a TapListener
var tap = new TapListener(element, context)
tapListeners.push(tap)
}
}
/**
* @param {AudioContext} context The AudioContext to start.
* @param {Array|String|Element|jQuery} elements For iOS, the list of elements
* to bind tap event listeners
* which will start the AudioContext.
* @param {Function=} callback The callback to invoke when the AudioContext is started.
* @return {Promise} The promise is invoked when the AudioContext
* is started.
*/
function StartAudioContext(context, elements, callback){
//the promise is invoked when the AudioContext is started
var promise = new Promise(function(success) {
onStarted(context, success)
})
// The TapListeners bound to the elements
var tapListeners = []
// add all the tap listeners
if (elements){
bindTapListener(elements, tapListeners, context)
}
//dispose all these tap listeners when the context is started
promise.then(function(){
for (var i = 0; i < tapListeners.length; i++){
tapListeners[i].dispose()
}
tapListeners = null
if (callback){
callback()
}
})
return promise
}
return StartAudioContext
}))

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load diff

View file

@ -1,27 +0,0 @@
// Adds the register preload method to Tone.js
// simply include this after Tone.js and p5.js
if (!Tone && !p5){
throw new Error("p5.js and Tone.js need to be loaded first");
}
(function(){
Tone.registeredPreload = function(callback){
return function(){
callback();
};
};
var originalToneBufferLoad = Tone.Buffer.load;
//overwrite load function
Tone.Buffer.load = function (url, callback) {
var handle = Tone.registeredPreload();
return originalToneBufferLoad(url).then(function(buffer){
handle();
callback(buffer);
});
};
p5.prototype.registerPreloadMethod("registeredPreload", Tone.Buffer.load);
}());

View file

@ -1,36 +0,0 @@
/*
RequireJS 2.1.11 Copyright (c) 2010-2014, The Dojo Foundation All Rights Reserved.
Available via the MIT or new BSD license.
see: http://github.com/jrburke/requirejs for details
*/
var requirejs,require,define;
(function(ca){function G(b){return"[object Function]"===M.call(b)}function H(b){return"[object Array]"===M.call(b)}function v(b,c){if(b){var d;for(d=0;d<b.length&&(!b[d]||!c(b[d],d,b));d+=1);}}function U(b,c){if(b){var d;for(d=b.length-1;-1<d&&(!b[d]||!c(b[d],d,b));d-=1);}}function s(b,c){return ga.call(b,c)}function j(b,c){return s(b,c)&&b[c]}function B(b,c){for(var d in b)if(s(b,d)&&c(b[d],d))break}function V(b,c,d,g){c&&B(c,function(c,h){if(d||!s(b,h))g&&"object"===typeof c&&c&&!H(c)&&!G(c)&&!(c instanceof
RegExp)?(b[h]||(b[h]={}),V(b[h],c,d,g)):b[h]=c});return b}function t(b,c){return function(){return c.apply(b,arguments)}}function da(b){throw b;}function ea(b){if(!b)return b;var c=ca;v(b.split("."),function(b){c=c[b]});return c}function C(b,c,d,g){c=Error(c+"\nhttp://requirejs.org/docs/errors.html#"+b);c.requireType=b;c.requireModules=g;d&&(c.originalError=d);return c}function ha(b){function c(a,e,b){var f,n,c,d,g,h,i,I=e&&e.split("/");n=I;var m=l.map,k=m&&m["*"];if(a&&"."===a.charAt(0))if(e){n=
I.slice(0,I.length-1);a=a.split("/");e=a.length-1;l.nodeIdCompat&&R.test(a[e])&&(a[e]=a[e].replace(R,""));n=a=n.concat(a);d=n.length;for(e=0;e<d;e++)if(c=n[e],"."===c)n.splice(e,1),e-=1;else if(".."===c)if(1===e&&(".."===n[2]||".."===n[0]))break;else 0<e&&(n.splice(e-1,2),e-=2);a=a.join("/")}else 0===a.indexOf("./")&&(a=a.substring(2));if(b&&m&&(I||k)){n=a.split("/");e=n.length;a:for(;0<e;e-=1){d=n.slice(0,e).join("/");if(I)for(c=I.length;0<c;c-=1)if(b=j(m,I.slice(0,c).join("/")))if(b=j(b,d)){f=b;
g=e;break a}!h&&(k&&j(k,d))&&(h=j(k,d),i=e)}!f&&h&&(f=h,g=i);f&&(n.splice(0,g,f),a=n.join("/"))}return(f=j(l.pkgs,a))?f:a}function d(a){z&&v(document.getElementsByTagName("script"),function(e){if(e.getAttribute("data-requiremodule")===a&&e.getAttribute("data-requirecontext")===i.contextName)return e.parentNode.removeChild(e),!0})}function g(a){var e=j(l.paths,a);if(e&&H(e)&&1<e.length)return e.shift(),i.require.undef(a),i.require([a]),!0}function u(a){var e,b=a?a.indexOf("!"):-1;-1<b&&(e=a.substring(0,
b),a=a.substring(b+1,a.length));return[e,a]}function m(a,e,b,f){var n,d,g=null,h=e?e.name:null,l=a,m=!0,k="";a||(m=!1,a="_@r"+(M+=1));a=u(a);g=a[0];a=a[1];g&&(g=c(g,h,f),d=j(p,g));a&&(g?k=d&&d.normalize?d.normalize(a,function(a){return c(a,h,f)}):c(a,h,f):(k=c(a,h,f),a=u(k),g=a[0],k=a[1],b=!0,n=i.nameToUrl(k)));b=g&&!d&&!b?"_unnormalized"+(Q+=1):"";return{prefix:g,name:k,parentMap:e,unnormalized:!!b,url:n,originalName:l,isDefine:m,id:(g?g+"!"+k:k)+b}}function q(a){var e=a.id,b=j(k,e);b||(b=k[e]=new i.Module(a));
return b}function r(a,e,b){var f=a.id,n=j(k,f);if(s(p,f)&&(!n||n.defineEmitComplete))"defined"===e&&b(p[f]);else if(n=q(a),n.error&&"error"===e)b(n.error);else n.on(e,b)}function w(a,e){var b=a.requireModules,f=!1;if(e)e(a);else if(v(b,function(e){if(e=j(k,e))e.error=a,e.events.error&&(f=!0,e.emit("error",a))}),!f)h.onError(a)}function x(){S.length&&(ia.apply(A,[A.length,0].concat(S)),S=[])}function y(a){delete k[a];delete W[a]}function F(a,e,b){var f=a.map.id;a.error?a.emit("error",a.error):(e[f]=
!0,v(a.depMaps,function(f,c){var d=f.id,g=j(k,d);g&&(!a.depMatched[c]&&!b[d])&&(j(e,d)?(a.defineDep(c,p[d]),a.check()):F(g,e,b))}),b[f]=!0)}function D(){var a,e,b=(a=1E3*l.waitSeconds)&&i.startTime+a<(new Date).getTime(),f=[],c=[],h=!1,k=!0;if(!X){X=!0;B(W,function(a){var i=a.map,m=i.id;if(a.enabled&&(i.isDefine||c.push(a),!a.error))if(!a.inited&&b)g(m)?h=e=!0:(f.push(m),d(m));else if(!a.inited&&(a.fetched&&i.isDefine)&&(h=!0,!i.prefix))return k=!1});if(b&&f.length)return a=C("timeout","Load timeout for modules: "+
f,null,f),a.contextName=i.contextName,w(a);k&&v(c,function(a){F(a,{},{})});if((!b||e)&&h)if((z||fa)&&!Y)Y=setTimeout(function(){Y=0;D()},50);X=!1}}function E(a){s(p,a[0])||q(m(a[0],null,!0)).init(a[1],a[2])}function K(a){var a=a.currentTarget||a.srcElement,e=i.onScriptLoad;a.detachEvent&&!Z?a.detachEvent("onreadystatechange",e):a.removeEventListener("load",e,!1);e=i.onScriptError;(!a.detachEvent||Z)&&a.removeEventListener("error",e,!1);return{node:a,id:a&&a.getAttribute("data-requiremodule")}}function L(){var a;
for(x();A.length;){a=A.shift();if(null===a[0])return w(C("mismatch","Mismatched anonymous define() module: "+a[a.length-1]));E(a)}}var X,$,i,N,Y,l={waitSeconds:7,baseUrl:"./",paths:{},bundles:{},pkgs:{},shim:{},config:{}},k={},W={},aa={},A=[],p={},T={},ba={},M=1,Q=1;N={require:function(a){return a.require?a.require:a.require=i.makeRequire(a.map)},exports:function(a){a.usingExports=!0;if(a.map.isDefine)return a.exports?p[a.map.id]=a.exports:a.exports=p[a.map.id]={}},module:function(a){return a.module?
a.module:a.module={id:a.map.id,uri:a.map.url,config:function(){return j(l.config,a.map.id)||{}},exports:a.exports||(a.exports={})}}};$=function(a){this.events=j(aa,a.id)||{};this.map=a;this.shim=j(l.shim,a.id);this.depExports=[];this.depMaps=[];this.depMatched=[];this.pluginMaps={};this.depCount=0};$.prototype={init:function(a,e,b,f){f=f||{};if(!this.inited){this.factory=e;if(b)this.on("error",b);else this.events.error&&(b=t(this,function(a){this.emit("error",a)}));this.depMaps=a&&a.slice(0);this.errback=
b;this.inited=!0;this.ignore=f.ignore;f.enabled||this.enabled?this.enable():this.check()}},defineDep:function(a,e){this.depMatched[a]||(this.depMatched[a]=!0,this.depCount-=1,this.depExports[a]=e)},fetch:function(){if(!this.fetched){this.fetched=!0;i.startTime=(new Date).getTime();var a=this.map;if(this.shim)i.makeRequire(this.map,{enableBuildCallback:!0})(this.shim.deps||[],t(this,function(){return a.prefix?this.callPlugin():this.load()}));else return a.prefix?this.callPlugin():this.load()}},load:function(){var a=
this.map.url;T[a]||(T[a]=!0,i.load(this.map.id,a))},check:function(){if(this.enabled&&!this.enabling){var a,e,b=this.map.id;e=this.depExports;var f=this.exports,c=this.factory;if(this.inited)if(this.error)this.emit("error",this.error);else{if(!this.defining){this.defining=!0;if(1>this.depCount&&!this.defined){if(G(c)){if(this.events.error&&this.map.isDefine||h.onError!==da)try{f=i.execCb(b,c,e,f)}catch(d){a=d}else f=i.execCb(b,c,e,f);this.map.isDefine&&void 0===f&&((e=this.module)?f=e.exports:this.usingExports&&
(f=this.exports));if(a)return a.requireMap=this.map,a.requireModules=this.map.isDefine?[this.map.id]:null,a.requireType=this.map.isDefine?"define":"require",w(this.error=a)}else f=c;this.exports=f;if(this.map.isDefine&&!this.ignore&&(p[b]=f,h.onResourceLoad))h.onResourceLoad(i,this.map,this.depMaps);y(b);this.defined=!0}this.defining=!1;this.defined&&!this.defineEmitted&&(this.defineEmitted=!0,this.emit("defined",this.exports),this.defineEmitComplete=!0)}}else this.fetch()}},callPlugin:function(){var a=
this.map,b=a.id,d=m(a.prefix);this.depMaps.push(d);r(d,"defined",t(this,function(f){var d,g;g=j(ba,this.map.id);var J=this.map.name,u=this.map.parentMap?this.map.parentMap.name:null,p=i.makeRequire(a.parentMap,{enableBuildCallback:!0});if(this.map.unnormalized){if(f.normalize&&(J=f.normalize(J,function(a){return c(a,u,!0)})||""),f=m(a.prefix+"!"+J,this.map.parentMap),r(f,"defined",t(this,function(a){this.init([],function(){return a},null,{enabled:!0,ignore:!0})})),g=j(k,f.id)){this.depMaps.push(f);
if(this.events.error)g.on("error",t(this,function(a){this.emit("error",a)}));g.enable()}}else g?(this.map.url=i.nameToUrl(g),this.load()):(d=t(this,function(a){this.init([],function(){return a},null,{enabled:!0})}),d.error=t(this,function(a){this.inited=!0;this.error=a;a.requireModules=[b];B(k,function(a){0===a.map.id.indexOf(b+"_unnormalized")&&y(a.map.id)});w(a)}),d.fromText=t(this,function(f,c){var g=a.name,J=m(g),k=O;c&&(f=c);k&&(O=!1);q(J);s(l.config,b)&&(l.config[g]=l.config[b]);try{h.exec(f)}catch(j){return w(C("fromtexteval",
"fromText eval for "+b+" failed: "+j,j,[b]))}k&&(O=!0);this.depMaps.push(J);i.completeLoad(g);p([g],d)}),f.load(a.name,p,d,l))}));i.enable(d,this);this.pluginMaps[d.id]=d},enable:function(){W[this.map.id]=this;this.enabling=this.enabled=!0;v(this.depMaps,t(this,function(a,b){var c,f;if("string"===typeof a){a=m(a,this.map.isDefine?this.map:this.map.parentMap,!1,!this.skipMap);this.depMaps[b]=a;if(c=j(N,a.id)){this.depExports[b]=c(this);return}this.depCount+=1;r(a,"defined",t(this,function(a){this.defineDep(b,
a);this.check()}));this.errback&&r(a,"error",t(this,this.errback))}c=a.id;f=k[c];!s(N,c)&&(f&&!f.enabled)&&i.enable(a,this)}));B(this.pluginMaps,t(this,function(a){var b=j(k,a.id);b&&!b.enabled&&i.enable(a,this)}));this.enabling=!1;this.check()},on:function(a,b){var c=this.events[a];c||(c=this.events[a]=[]);c.push(b)},emit:function(a,b){v(this.events[a],function(a){a(b)});"error"===a&&delete this.events[a]}};i={config:l,contextName:b,registry:k,defined:p,urlFetched:T,defQueue:A,Module:$,makeModuleMap:m,
nextTick:h.nextTick,onError:w,configure:function(a){a.baseUrl&&"/"!==a.baseUrl.charAt(a.baseUrl.length-1)&&(a.baseUrl+="/");var b=l.shim,c={paths:!0,bundles:!0,config:!0,map:!0};B(a,function(a,b){c[b]?(l[b]||(l[b]={}),V(l[b],a,!0,!0)):l[b]=a});a.bundles&&B(a.bundles,function(a,b){v(a,function(a){a!==b&&(ba[a]=b)})});a.shim&&(B(a.shim,function(a,c){H(a)&&(a={deps:a});if((a.exports||a.init)&&!a.exportsFn)a.exportsFn=i.makeShimExports(a);b[c]=a}),l.shim=b);a.packages&&v(a.packages,function(a){var b,
a="string"===typeof a?{name:a}:a;b=a.name;a.location&&(l.paths[b]=a.location);l.pkgs[b]=a.name+"/"+(a.main||"main").replace(ja,"").replace(R,"")});B(k,function(a,b){!a.inited&&!a.map.unnormalized&&(a.map=m(b))});if(a.deps||a.callback)i.require(a.deps||[],a.callback)},makeShimExports:function(a){return function(){var b;a.init&&(b=a.init.apply(ca,arguments));return b||a.exports&&ea(a.exports)}},makeRequire:function(a,e){function g(f,c,d){var j,l;e.enableBuildCallback&&(c&&G(c))&&(c.__requireJsBuild=
!0);if("string"===typeof f){if(G(c))return w(C("requireargs","Invalid require call"),d);if(a&&s(N,f))return N[f](k[a.id]);if(h.get)return h.get(i,f,a,g);j=m(f,a,!1,!0);j=j.id;return!s(p,j)?w(C("notloaded",'Module name "'+j+'" has not been loaded yet for context: '+b+(a?"":". Use require([])"))):p[j]}L();i.nextTick(function(){L();l=q(m(null,a));l.skipMap=e.skipMap;l.init(f,c,d,{enabled:!0});D()});return g}e=e||{};V(g,{isBrowser:z,toUrl:function(b){var e,d=b.lastIndexOf("."),g=b.split("/")[0];if(-1!==
d&&(!("."===g||".."===g)||1<d))e=b.substring(d,b.length),b=b.substring(0,d);return i.nameToUrl(c(b,a&&a.id,!0),e,!0)},defined:function(b){return s(p,m(b,a,!1,!0).id)},specified:function(b){b=m(b,a,!1,!0).id;return s(p,b)||s(k,b)}});a||(g.undef=function(b){x();var c=m(b,a,!0),e=j(k,b);d(b);delete p[b];delete T[c.url];delete aa[b];U(A,function(a,c){a[0]===b&&A.splice(c,1)});e&&(e.events.defined&&(aa[b]=e.events),y(b))});return g},enable:function(a){j(k,a.id)&&q(a).enable()},completeLoad:function(a){var b,
c,f=j(l.shim,a)||{},d=f.exports;for(x();A.length;){c=A.shift();if(null===c[0]){c[0]=a;if(b)break;b=!0}else c[0]===a&&(b=!0);E(c)}c=j(k,a);if(!b&&!s(p,a)&&c&&!c.inited){if(l.enforceDefine&&(!d||!ea(d)))return g(a)?void 0:w(C("nodefine","No define call for "+a,null,[a]));E([a,f.deps||[],f.exportsFn])}D()},nameToUrl:function(a,b,c){var f,d,g;(f=j(l.pkgs,a))&&(a=f);if(f=j(ba,a))return i.nameToUrl(f,b,c);if(h.jsExtRegExp.test(a))f=a+(b||"");else{f=l.paths;a=a.split("/");for(d=a.length;0<d;d-=1)if(g=a.slice(0,
d).join("/"),g=j(f,g)){H(g)&&(g=g[0]);a.splice(0,d,g);break}f=a.join("/");f+=b||(/^data\:|\?/.test(f)||c?"":".js");f=("/"===f.charAt(0)||f.match(/^[\w\+\.\-]+:/)?"":l.baseUrl)+f}return l.urlArgs?f+((-1===f.indexOf("?")?"?":"&")+l.urlArgs):f},load:function(a,b){h.load(i,a,b)},execCb:function(a,b,c,d){return b.apply(d,c)},onScriptLoad:function(a){if("load"===a.type||ka.test((a.currentTarget||a.srcElement).readyState))P=null,a=K(a),i.completeLoad(a.id)},onScriptError:function(a){var b=K(a);if(!g(b.id))return w(C("scripterror",
"Script error for: "+b.id,a,[b.id]))}};i.require=i.makeRequire();return i}var h,x,y,D,K,E,P,L,q,Q,la=/(\/\*([\s\S]*?)\*\/|([^:]|^)\/\/(.*)$)/mg,ma=/[^.]\s*require\s*\(\s*["']([^'"\s]+)["']\s*\)/g,R=/\.js$/,ja=/^\.\//;x=Object.prototype;var M=x.toString,ga=x.hasOwnProperty,ia=Array.prototype.splice,z=!!("undefined"!==typeof window&&"undefined"!==typeof navigator&&window.document),fa=!z&&"undefined"!==typeof importScripts,ka=z&&"PLAYSTATION 3"===navigator.platform?/^complete$/:/^(complete|loaded)$/,
Z="undefined"!==typeof opera&&"[object Opera]"===opera.toString(),F={},r={},S=[],O=!1;if("undefined"===typeof define){if("undefined"!==typeof requirejs){if(G(requirejs))return;r=requirejs;requirejs=void 0}"undefined"!==typeof require&&!G(require)&&(r=require,require=void 0);h=requirejs=function(b,c,d,g){var u,m="_";!H(b)&&"string"!==typeof b&&(u=b,H(c)?(b=c,c=d,d=g):b=[]);u&&u.context&&(m=u.context);(g=j(F,m))||(g=F[m]=h.s.newContext(m));u&&g.configure(u);return g.require(b,c,d)};h.config=function(b){return h(b)};
h.nextTick="undefined"!==typeof setTimeout?function(b){setTimeout(b,4)}:function(b){b()};require||(require=h);h.version="2.1.11";h.jsExtRegExp=/^\/|:|\?|\.js$/;h.isBrowser=z;x=h.s={contexts:F,newContext:ha};h({});v(["toUrl","undef","defined","specified"],function(b){h[b]=function(){var c=F._;return c.require[b].apply(c,arguments)}});if(z&&(y=x.head=document.getElementsByTagName("head")[0],D=document.getElementsByTagName("base")[0]))y=x.head=D.parentNode;h.onError=da;h.createNode=function(b){var c=
b.xhtml?document.createElementNS("http://www.w3.org/1999/xhtml","html:script"):document.createElement("script");c.type=b.scriptType||"text/javascript";c.charset="utf-8";c.async=!0;return c};h.load=function(b,c,d){var g=b&&b.config||{};if(z)return g=h.createNode(g,c,d),g.setAttribute("data-requirecontext",b.contextName),g.setAttribute("data-requiremodule",c),g.attachEvent&&!(g.attachEvent.toString&&0>g.attachEvent.toString().indexOf("[native code"))&&!Z?(O=!0,g.attachEvent("onreadystatechange",b.onScriptLoad)):
(g.addEventListener("load",b.onScriptLoad,!1),g.addEventListener("error",b.onScriptError,!1)),g.src=d,L=g,D?y.insertBefore(g,D):y.appendChild(g),L=null,g;if(fa)try{importScripts(d),b.completeLoad(c)}catch(j){b.onError(C("importscripts","importScripts failed for "+c+" at "+d,j,[c]))}};z&&!r.skipDataMain&&U(document.getElementsByTagName("script"),function(b){y||(y=b.parentNode);if(K=b.getAttribute("data-main"))return q=K,r.baseUrl||(E=q.split("/"),q=E.pop(),Q=E.length?E.join("/")+"/":"./",r.baseUrl=
Q),q=q.replace(R,""),h.jsExtRegExp.test(q)&&(q=K),r.deps=r.deps?r.deps.concat(q):[q],!0});define=function(b,c,d){var g,h;"string"!==typeof b&&(d=c,c=b,b=null);H(c)||(d=c,c=null);!c&&G(d)&&(c=[],d.length&&(d.toString().replace(la,"").replace(ma,function(b,d){c.push(d)}),c=(1===d.length?["require"]:["require","exports","module"]).concat(c)));if(O){if(!(g=L))P&&"interactive"===P.readyState||U(document.getElementsByTagName("script"),function(b){if("interactive"===b.readyState)return P=b}),g=P;g&&(b||
(b=g.getAttribute("data-requiremodule")),h=F[g.getAttribute("data-requirecontext")])}(h?h.defQueue:S).push([b,c,d])};define.amd={jQuery:!0};h.exec=function(b){return eval(b)};h(r)}})(this);

View file

@ -2,39 +2,50 @@
<html> <html>
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<title>SHINY</title> <title>Play Along</title>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"> <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<link rel="icon" type="image/png" sizes="174x174" href="./style/favicon.png"> <link rel="icon" type="image/png" sizes="174x174" href="./favicon.png">
<script src="https://unpkg.com/@webcomponents/webcomponentsjs@^2/webcomponents-bundle.js"></script>
<script src="../build/Tone.js"></script> <script src="../build/Tone.js"></script>
<script src="./scripts/jquery.min.js"></script> <script src="./js/tonejs-ui.js"></script>
<script src="./scripts/draggabilly.js"></script> <style type="text/css">
<script src="./scripts/StartAudioContext.js"></script> tone-play-toggle {
<script src="./scripts/Interface.js"></script> margin-bottom: 10px;
<script src="https://tonejs.github.io/Logo/build/Logo.js"></script> }
<script src="./scripts/nexusUI.js"></script> tone-slider {
display: block;
<link rel="stylesheet" type="text/css" href="./style/examples.css"> width: 100%;
}
<script> </style>
// jshint ignore: start
</script>
</head> </head>
<body> <body>
<div id="Content"> <tone-example>
<div id="Title">Play Along</div> <tone-loader></tone-loader>
<div id="Explanation"> <tone-explanation label="Play Along">
Touch/Mouse and drag to play along with the probabilistic backtrack. X = pitch, Y = modulation. Touch/Mouse and drag to play along with the probabilistic backtrack. X = pitch, Y = modulation.
</div> </tone-explanation>
</div>
<script> <tone-content>
<tone-play-toggle></tone-play-toggle>
<tone-slider-2d></tone-slider-2d>
</tone-content>
//DRUMS// <tone-drawer collapsed>
<tone-compressor collapsed id="compressor" label="Drum Compressor"></tone-compressor>
<tone-distortion collapsed id="distortion" label="HH/Snare Distortion"></tone-distortion>
<tone-player collapsed id="hats" label="Hats"></tone-player>
<tone-player collapsed id="snare" label="Snare"></tone-player>
<tone-membrane-synth collapsed id="kick" label="Kick"></tone-membrane-synth>
<tone-fm-synth collapsed id="bass" label="Bass"></tone-fm-synth>
<tone-duo-synth collapsed id="lead" label="Lead"></tone-duo-synth>
</tone-drawer>
//and a compressor </tone-example>
<script type="text/javascript">
//a compressor
var drumCompress = new Tone.Compressor({ var drumCompress = new Tone.Compressor({
"threshold" : -30, "threshold" : -30,
"ratio" : 6, "ratio" : 6,
@ -51,7 +62,6 @@
var hats = new Tone.Player({ var hats = new Tone.Player({
"url" : "./audio/505/hh.[mp3|ogg]", "url" : "./audio/505/hh.[mp3|ogg]",
"volume" : -10, "volume" : -10,
"retrigger" : true,
"fadeOut" : 0.05 "fadeOut" : 0.05
}).chain(distortion, drumCompress); }).chain(distortion, drumCompress);
@ -66,7 +76,6 @@
//SNARE PART //SNARE PART
var snare = new Tone.Player({ var snare = new Tone.Player({
"url" : "./audio/505/snare.[mp3|ogg]", "url" : "./audio/505/snare.[mp3|ogg]",
"retrigger" : true,
"fadeOut" : 0.1 "fadeOut" : 0.1
}).chain(distortion, drumCompress); }).chain(distortion, drumCompress);
@ -122,19 +131,18 @@
} }
}).toMaster(); }).toMaster();
var bassPart = new Tone.Part(function(time, event){ var bassPart = new Tone.Part(function(time, event){
if (Math.random() < event.prob){ if (Math.random() < event.prob){
bass.triggerAttackRelease(event.note, event.dur, time); bass.triggerAttackRelease(event.note, event.dur, time);
} }
}, [{time : "0:0", note : "C2", dur : "4n.", prob: 1}, {time : "0:2", note : "C2", dur : "8n", prob : 0.6}, }, [{ time : "0:0", note : "C2", dur : "4n.", prob : 1 }, { time : "0:2", note : "C2", dur : "8n", prob : 0.6 },
{time : "0:2.6666", note : "C2", dur : "8n", prob : 0.4}, {time : "0:3.33333", note : "C2", dur : "8n", prob : 0.9}, { time : "0:2.6666", note : "C2", dur : "8n", prob : 0.4 }, { time : "0:3.33333", note : "C2", dur : "8n", prob : 0.9 },
{time : "1:0", note : "C2", dur : "4n.", prob : 1}, {time : "1:2", note : "C2", dur : "8n", prob : 0.6}, { time : "1:0", note : "C2", dur : "4n.", prob : 1 }, { time : "1:2", note : "C2", dur : "8n", prob : 0.6 },
{time : "1:2.6666", note : "C2", dur : "8n", prob : 0.4}, {time : "1:3.33333", note : "E2", dur : "8n", prob : 0.9}, { time : "1:2.6666", note : "C2", dur : "8n", prob : 0.4 }, { time : "1:3.33333", note : "E2", dur : "8n", prob : 0.9 },
{time : "2:0", note : "F2", dur : "4n.", prob : 1}, {time : "2:2", note : "F2", dur : "8n", prob : 0.6}, { time : "2:0", note : "F2", dur : "4n.", prob : 1 }, { time : "2:2", note : "F2", dur : "8n", prob : 0.6 },
{time : "2:2.6666", note : "F2", dur : "8n", prob : 0.4}, {time : "2:3.33333", note : "F2", dur : "8n", prob : 0.9}, { time : "2:2.6666", note : "F2", dur : "8n", prob : 0.4 }, { time : "2:3.33333", note : "F2", dur : "8n", prob : 0.9 },
{time : "3:0", note : "F2", dur : "4n.", prob : 1}, {time : "3:2", note : "F2", dur : "8n", prob : 0.6}, { time : "3:0", note : "F2", dur : "4n.", prob : 1 }, { time : "3:2", note : "F2", dur : "8n", prob : 0.6 },
{time : "3:2.6666", note : "F2", dur : "8n", prob : 0.4}, {time : "3:3.33333", note : "B1", dur : "8n", prob : 0.9}]).start(0); { time : "3:2.6666", note : "F2", dur : "8n", prob : 0.4 }, { time : "3:3.33333", note : "B1", dur : "8n", prob : 0.9 }]).start(0);
bassPart.loop = true; bassPart.loop = true;
bassPart.loopEnd = "4m"; bassPart.loopEnd = "4m";
@ -204,49 +212,30 @@
Tone.Transport.bpm.value = 125; Tone.Transport.bpm.value = 125;
// GUI // //bind the interface
document.querySelector("tone-play-toggle").bind(Tone.Transport);
Interface.Button({ document.querySelector("tone-slider-2d").addEventListener("change", e => {
key : 32, //use the x and y values to set the note and vibrato
type : "toggle", const note = synthNotes[Math.round(e.detail.x * (synthNotes.length-1))];
text : "Start",
activeText : "Stop",
start : function(){
Tone.Transport.start("+0.1");
},
end : function(){
Tone.Transport.stop();
}
});
var lastSynthNote = synthNotes[0];
Interface.Dragger({
// container : "#Content",
x : {
options : synthNotes,
drag : function(note){
synth.setNote(note); synth.setNote(note);
lastSynthNote = note; synth.vibratoAmount.value = e.detail.y * 3;
}
},
y : {
min : 0,
max : 2,
drag : function(val){
synth.vibratoAmount.value = val;
}
},
start : function(){
synth.triggerAttack(lastSynthNote);
},
end : function(){
synth.triggerRelease();
},
name : "Synth"
}); });
document.querySelector("tone-slider-2d").addEventListener("mousedown", e => {
Interface.Loader(); const note = synthNotes[Math.round(e.detail.x * (synthNotes.length-1))];
synth.vibratoAmount.value = e.detail.y * 3;
synth.triggerAttack(note);
});
document.querySelector("tone-slider-2d").addEventListener("mouseup", e => {
synth.triggerRelease();
});
//bind the drawer interfaces
document.querySelector("#hats").bind(hats);
document.querySelector("#snare").bind(snare);
document.querySelector("#kick").bind(kick);
document.querySelector("#bass").bind(bass);
document.querySelector("#distortion").bind(distortion);
document.querySelector("#compressor").bind(drumCompress);
document.querySelector("#lead").bind(synth);
</script> </script>
</body> </body>
</html> </html>

View file

@ -2,30 +2,28 @@
<html> <html>
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<title>Signals</title> <title>Signal</title>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"> <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<link rel="icon" type="image/png" sizes="174x174" href="./style/favicon.png"> <link rel="icon" type="image/png" sizes="174x174" href="./favicon.png">
<script src="https://unpkg.com/@webcomponents/webcomponentsjs@^2/webcomponents-bundle.js"></script>
<script src="../build/Tone.js"></script> <script src="../build/Tone.js"></script>
<script src="./scripts/jquery.min.js"></script> <script src="./js/tonejs-ui.js"></script>
<script src="./scripts/draggabilly.js"></script> <style type="text/css">
<script src="https://tonejs.github.io/Logo/build/Logo.js"></script> tone-play-toggle {
<script src="./scripts/StartAudioContext.js"></script> margin-bottom: 10px;
<script src="./scripts/Interface.js"></script> }
tone-slider {
<link rel="stylesheet" type="text/css" href="./style/examples.css"> display: block;
width: 100%;
<script> }
// jshint ignore: start </style>
</script>
</head> </head>
<body> <body>
<div id="Content"> <tone-example>
<div id="Title">Control Voltage</div> <tone-explanation label="Control Voltage">
<div id="Explanation"> One of the most powerful features of Tone.js and the Web Audio API is the ability to
One of the most powerful features of Tone.js is the ability to
perform math and logic on audio-rate signal. Signals perform math and logic on audio-rate signal. Signals
can be ramped and scheduled to control Audio Parameters and can be ramped and scheduled to control Audio Parameters and
other Signals making it simple to create elaborate, other Signals making it simple to create elaborate,
@ -34,27 +32,29 @@
This example applies a series of mappings to a This example applies a series of mappings to a
signal value and applies the results of those mappings signal value and applies the results of those mappings
to the frequency attribute of 2 to the frequency attribute of 2
<a href="https://tonejs.github.io/docs/#Oscillator">Tone.Oscillators</a> <a href="https://tonejs.github.io/docs/Oscillator">Tone.Oscillators</a>
and a <a href="https://tonejs.github.io/docs/#LFO">Tone.LFO</a>. and a <a href="https://tonejs.github.io/docs/LFO">Tone.LFO</a>.
</div> </tone-explanation>
</div>
<script>
//initially muted
Tone.Master.mute = true;
//use this to pan the two oscillators hard left/right <tone-content>
<tone-play-toggle></tone-play-toggle>
<tone-slider label="Modulation Rate" min="0.1" max="1" exp="2" value="0.5"></tone-slider>
</tone-content>
</tone-example>
<script type="text/javascript">//use this to pan the two oscillators hard left/right
var merge = new Tone.Merge().toMaster(); var merge = new Tone.Merge().toMaster();
//two oscillators panned hard left / hard right //two oscillators panned hard left / hard right
var rightOsc = new Tone.Oscillator({ var rightOsc = new Tone.Oscillator({
"type" : "sawtooth", "type" : "sawtooth",
"volume" : -20 "volume" : -20
}).connect(merge.right).start(); }).connect(merge.right);
var leftOsc = new Tone.Oscillator({ var leftOsc = new Tone.Oscillator({
"type" : "square", "type" : "square",
"volume" : -20 "volume" : -20
}).connect(merge.left).start(); }).connect(merge.left);
//create an oscillation that goes from 0 to 1200 //create an oscillation that goes from 0 to 1200
//connection it to the detune of the two oscillators //connection it to the detune of the two oscillators
@ -82,25 +82,22 @@
var detuneScale = new Tone.Scale(14, 4); var detuneScale = new Tone.Scale(14, 4);
frequency.chain(detuneScale, detuneLFO.frequency); frequency.chain(detuneScale, detuneLFO.frequency);
// GUI // //start the oscillators with the play button
document.querySelector("tone-play-toggle").addEventListener("change", e => {
Interface.Slider({ if (e.detail){
drag : function(value){ rightOsc.start();
frequency.rampTo(value, 0.1); leftOsc.start();
}, } else {
start : function(){ rightOsc.stop();
Tone.Master.mute = false; leftOsc.stop();
}, }
end: function(){
Tone.Master.mute = true;
},
name : "frequency",
min : 0,
max : 1,
exp : 0.5,
value : 0.5,
position: 5
}); });
//ramp the frequency with the slider
document.querySelector("tone-slider").addEventListener("change", e => {
frequency.rampTo(e.detail, 0.1);
});
</script> </script>
</body> </body>

View file

@ -4,52 +4,34 @@
<meta charset="utf-8"> <meta charset="utf-8">
<title>Synth</title> <title>Synth</title>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"> <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<link rel="icon" type="image/png" sizes="174x174" href="./style/favicon.png"> <link rel="icon" type="image/png" sizes="174x174" href="./favicon.png">
<script src="https://unpkg.com/@webcomponents/webcomponentsjs@^2/webcomponents-bundle.js"></script>
<script src="../build/Tone.js"></script> <script src="../build/Tone.js"></script>
<script src="./scripts/jquery.min.js"></script> <script src="./js/tonejs-ui.js"></script>
<script src="./scripts/draggabilly.js"></script>
<script src="./scripts/StartAudioContext.js"></script>
<script src="./scripts/Interface.js"></script>
<script src="https://tonejs.github.io/Logo/build/Logo.js"></script>
<script src="./scripts/Keyboard.js"></script>
<link rel="stylesheet" type="text/css" href="./style/examples.css">
<script>
// jshint ignore: start
</script>
</head> </head>
<body> <body>
<style type="text/css"> <style>
tone-piano {
img { margin-bottom: 10px;
width: 80%;
max-width: 700px;
margin-left: auto;
margin-right: auto;
display: block;
}
#Keyboard {
margin: 3px!important;
} }
</style> </style>
<div id="Content"> <tone-example>
<div id="Title">Synth</div> <tone-explanation label="Synth">
<div id="Explanation"> <a href="https://tonejs.github.io/docs/Synth" target="_blank">Tone.Synth</a> is composed simply of a
<a href="https://tonejs.github.io/docs/#Synth" target="_blank">Tone.Synth</a> is composed simply of a <a href="https://tonejs.github.io/docs/OmniOscillator" target="_blank">Tone.OmniOscillator</a>
<a href="https://tonejs.github.io/docs/#OmniOscillator" target="_blank">Tone.OmniOscillator</a>
routed through a routed through a
<a href="https://tonejs.github.io/docs/#AmplitudeEnvelope" target="_blank">Tone.AmplitudeEnvelope</a>. <a href="https://tonejs.github.io/docs/AmplitudeEnvelope" target="_blank">Tone.AmplitudeEnvelope</a>.
</div> </tone-explanation>
<div id="Keyboard"></div>
</div>
<script> <tone-content>
<tone-piano></tone-piano>
<tone-synth></tone-synth>
</tone-content>
</tone-example>
<script type="text/javascript">
var synth = new Tone.Synth({ var synth = new Tone.Synth({
"oscillator" : { "oscillator" : {
"type" : "amtriangle", "type" : "amtriangle",
@ -57,7 +39,7 @@
"modulationType" : "sine" "modulationType" : "sine"
}, },
"envelope" : { "envelope" : {
"attackCurve" : 'exponential', "attackCurve" : "exponential",
"attack" : 0.05, "attack" : 0.05,
"decay" : 0.2, "decay" : 0.2,
"sustain" : 0.2, "sustain" : 0.2,
@ -66,18 +48,10 @@
"portamento" : 0.05 "portamento" : 0.05
}).toMaster(); }).toMaster();
// GUI // //bind the interface
document.querySelector("tone-piano").bind(synth);
document.querySelector("tone-synth").bind(synth);
var keyboard = Interface.Keyboard();
keyboard.keyDown = function (note) {
synth.triggerAttack(note);
};
keyboard.keyUp = function () {
synth.triggerRelease();
};
</script> </script>
</body> </body>
</html> </html>

View file

@ -2,82 +2,66 @@
<html> <html>
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<title>Panner3D</title> <title>Panner3d</title>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"> <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<link rel="icon" type="image/png" sizes="174x174" href="./style/favicon.png"> <link rel="icon" type="image/png" sizes="174x174" href="./favicon.png">
<script src="https://unpkg.com/@webcomponents/webcomponentsjs@^2/webcomponents-bundle.js"></script>
<script src="../build/Tone.js"></script> <script src="../build/Tone.js"></script>
<script src="./scripts/three.min.js"></script> <script src="./js/tonejs-ui.js"></script>
<script src="./scripts/OrbitControls.js"></script> <script src="./js/three.min.js"></script>
<script src="./scripts/WebGLDetector.js"></script> <script src="./js/OrbitControls.js"></script>
<script src="./scripts/THREE.Tone.js"></script> <script src="./js/WebGLDetector.js"></script>
<script src="./scripts/jquery.min.js"></script> <script src="./js/THREE.Tone.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>
<link rel="stylesheet" type="text/css" href="./style/examples.css">
<script>
// jshint ignore: start
</script>
</head>
<body>
<style type="text/css"> <style type="text/css">
tone-play-toggle {
margin-bottom: 10px;
}
#three { #three {
width: 100%; width: 100%;
height: 400px; height: 400px;
} }
</style> </style>
<div id="Content"> </head>
<div id="Title">Panner3D</div> <body>
<div id="Explanation"> <tone-example>
<tone-loader></tone-loader>
<tone-explanation label="3D Panning">
Tone.Panner3D and Tone.Listener work together to create 3D audio. Connect your synths and sources to Panner3D and then to the master output, anything you connect to the panner will be spatialized according the position of the panner relative to the position of the listener. This example synchronizes the position of the camera with Tone.Listener and the position of each of the spheres with a track. Tone.Panner3D and Tone.Listener work together to create 3D audio. Connect your synths and sources to Panner3D and then to the master output, anything you connect to the panner will be spatialized according the position of the panner relative to the position of the listener. This example synchronizes the position of the camera with Tone.Listener and the position of each of the spheres with a track.
</div> <br><br>
Note: the 3D panning effect is more effective with headphones.
</tone-explanation>
<tone-content>
<tone-play-toggle></tone-play-toggle>
<div id="three"></div> <div id="three"></div>
</div> </tone-content>
</tone-example>
<script>
<script type="text/javascript">
var greenSphere = new Tone.Panner3D().toMaster(); var greenSphere = new Tone.Panner3D().toMaster();
var drone = new Tone.Player({ var drone = new Tone.Player({
url : "./audio/loop/drone.[mp3|ogg]", url : "./audio/loop/drone.[mp3|ogg]",
loop: true, loop : true,
}).connect(greenSphere).sync().start(0); }).connect(greenSphere).sync().start(0);
var blueSphere = new Tone.Panner3D().toMaster(); var blueSphere = new Tone.Panner3D().toMaster();
var repeat = new Tone.Player({ var repeat = new Tone.Player({
url : "./audio/loop/bass.[mp3|ogg]", url : "./audio/loop/bass.[mp3|ogg]",
loop: true, loop : true,
}).connect(blueSphere).sync().start(0); }).connect(blueSphere).sync().start(0);
var whiteSphere = new Tone.Panner3D().toMaster(); var whiteSphere = new Tone.Panner3D().toMaster();
var chords = new Tone.Player({ var chords = new Tone.Player({
url : "./audio/loop/chords.[mp3|ogg]", url : "./audio/loop/chords.[mp3|ogg]",
loop: true, loop : true,
}).connect(whiteSphere).sync().start(0); }).connect(whiteSphere).sync().start(0);
</script> //bind the interface
document.querySelector("tone-play-toggle").bind(Tone.Transport);
<script id="GUI">
Interface.Loader()
Interface.Button({
key : 32,
type : "toggle",
text : "Start Sound",
activeText : "Stop",
start : function(){
Tone.Transport.start("+0.1");
},
end : function(){
Tone.Transport.stop();
}
});
// THREE.JS // // THREE.JS //
@ -87,63 +71,65 @@
var SCREEN_HEIGHT = document.querySelector("#three").clientHeight; var SCREEN_HEIGHT = document.querySelector("#three").clientHeight;
var aspect = SCREEN_WIDTH / SCREEN_HEIGHT; var aspect = SCREEN_WIDTH / SCREEN_HEIGHT;
var scene = new THREE.Scene() console.log(SCREEN_WIDTH, SCREEN_HEIGHT, aspect);
var camera = new THREE.PerspectiveCamera( 50, aspect, 1, 10000 );
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(50, aspect, 1, 10000);
camera.position.z = 1; camera.position.z = 1;
camera.updateMatrixWorld() camera.updateMatrixWorld();
var bassMesh = new THREE.Mesh( var bassMesh = new THREE.Mesh(
new THREE.SphereBufferGeometry( 2, 16, 8 ), new THREE.SphereBufferGeometry(2, 16, 8),
new THREE.MeshBasicMaterial( { color: 0xffffff, wireframe: true } ) new THREE.MeshBasicMaterial({ color : 0xffffff, wireframe : true })
); );
scene.add(bassMesh); scene.add(bassMesh);
bassMesh.position.z = -10 bassMesh.position.z = -10;
var dronMesh = new THREE.Mesh( var dronMesh = new THREE.Mesh(
new THREE.SphereBufferGeometry( 1, 16, 8 ), new THREE.SphereBufferGeometry(1, 16, 8),
new THREE.MeshBasicMaterial( { color: 0xff0000, wireframe: true } ) new THREE.MeshBasicMaterial({ color : 0xff0000, wireframe : true })
); );
scene.add(dronMesh); scene.add(dronMesh);
var chordMesh = new THREE.Mesh( var chordMesh = new THREE.Mesh(
new THREE.SphereBufferGeometry( 1, 16, 8 ), new THREE.SphereBufferGeometry(1, 16, 8),
new THREE.MeshBasicMaterial( { color: 0xff00ff, wireframe: true } ) new THREE.MeshBasicMaterial({ color : 0xff00ff, wireframe : true })
); );
scene.add(chordMesh); scene.add(chordMesh);
var renderer = new THREE.WebGLRenderer( { antialias: true } ); var renderer = new THREE.WebGLRenderer({ antialias : true });
renderer.setPixelRatio( window.devicePixelRatio ); renderer.setPixelRatio(window.devicePixelRatio);
onWindowResize(); onWindowResize();
renderer.domElement.style.position = "relative"; renderer.domElement.style.position = "relative";
document.querySelector("#three").appendChild( renderer.domElement ); document.querySelector("#three").appendChild(renderer.domElement);
controls = new THREE.OrbitControls( camera, renderer.domElement ); controls = new THREE.OrbitControls(camera, renderer.domElement);
controls.addEventListener("change", function(){ controls.addEventListener("change", function(){
Tone.Listener.updatePosition(camera); Tone.Listener.updatePosition(camera);
}) });
//set the camer initially //set the camer initially
Tone.Listener.updatePosition(camera); Tone.Listener.updatePosition(camera);
function onWindowResize( event ) { function onWindowResize(event){
SCREEN_WIDTH = document.querySelector("#three").clientWidth; SCREEN_WIDTH = document.querySelector("#three").clientWidth;
SCREEN_HEIGHT = document.querySelector("#three").clientHeight; SCREEN_HEIGHT = document.querySelector("#three").clientHeight;
aspect = SCREEN_WIDTH / SCREEN_HEIGHT; aspect = SCREEN_WIDTH / SCREEN_HEIGHT;
camera.aspect = aspect; camera.aspect = aspect;
renderer.setSize( SCREEN_WIDTH, SCREEN_HEIGHT ); renderer.setSize(SCREEN_WIDTH, SCREEN_HEIGHT);
camera.updateProjectionMatrix(); camera.updateProjectionMatrix();
} }
window.addEventListener("resize", onWindowResize); window.addEventListener("resize", onWindowResize);
function animate() { function animate(){
requestAnimationFrame( animate ); requestAnimationFrame(animate);
var r = Date.now() * 0.0005; var r = Date.now() * 0.0005;
chordMesh.position.x = 3 * Math.cos( r ); chordMesh.position.x = 3 * Math.cos(r);
chordMesh.position.z = 3 * Math.cos( r ); chordMesh.position.z = 3 * Math.cos(r);
chordMesh.position.y = 3 * Math.sin( r ); chordMesh.position.y = 3 * Math.sin(r);
dronMesh.position.x = 4 * Math.cos( 2 * r ); dronMesh.position.x = 4 * Math.cos(2 * r);
dronMesh.position.z = 4 * Math.sin( 2 * r ); dronMesh.position.z = 4 * Math.sin(2 * r);
renderer.render( scene, camera ); renderer.render(scene, camera);
controls.update(); controls.update();
greenSphere.updatePosition(dronMesh); greenSphere.updatePosition(dronMesh);
@ -151,7 +137,7 @@
whiteSphere.updatePosition(chordMesh); whiteSphere.updatePosition(chordMesh);
} }
animate() animate();
} }
</script> </script>

View file

@ -2,41 +2,37 @@
<html> <html>
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<title>SCORE</title> <title>Step Sequencer</title>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"> <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<link rel="icon" type="image/png" sizes="174x174" href="./style/favicon.png"> <link rel="icon" type="image/png" sizes="174x174" href="./favicon.png">
<script src="https://unpkg.com/@webcomponents/webcomponentsjs@^2/webcomponents-bundle.js"></script>
<script src="../build/Tone.js"></script> <script src="../build/Tone.js"></script>
<script src="./scripts/jquery.min.js"></script> <script src="./js/tonejs-ui.js"></script>
<script src="./scripts/draggabilly.js"></script> <script src="./js/tonejs-ui.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>
<script src="./scripts/nexusUI.js"></script>
<link rel="stylesheet" type="text/css" href="./style/examples.css">
<script>
// jshint ignore: start
</script>
</head>
<body>
<style type="text/css"> <style type="text/css">
canvas { tone-transport {
margin-top: 3px; margin-bottom: 10px;
} }
</style> </style>
<div id="Content"> </head>
<div id="Title">Tone.Transport</div> <body>
<div id="Explanation"> <tone-example>
<a href="https://tonejs.github.io/docs/#Transport">Tone.Transport</a> <tone-loader></tone-loader>
<tone-explanation label="Step Sequencer">
<a href="https://tonejs.github.io/docs/Transport">Tone.Transport</a>
is the application-wide timekeeper. It's clock source enables sample-accurate scheduling as well as tempo-curves and automation. This example uses Tone.Sequence to invoke a callback every 16th note. is the application-wide timekeeper. It's clock source enables sample-accurate scheduling as well as tempo-curves and automation. This example uses Tone.Sequence to invoke a callback every 16th note.
</div> </tone-explanation>
<canvas nx="matrix"></canvas>
</div> <tone-content>
<script> <tone-transport></tone-transport>
<tone-step-sequencer></tone-step-sequencer>
</tone-content>
</tone-example>
<script type="text/javascript">
//setup a polyphonic sampler //setup a polyphonic sampler
var keys = new Tone.Players({ var keys = new Tone.Players({
"A" : "./audio/casio/A1.[mp3|ogg]", "A" : "./audio/casio/A1.[mp3|ogg]",
@ -52,57 +48,27 @@
var noteNames = ["F#", "E", "C#", "A"]; var noteNames = ["F#", "E", "C#", "A"];
var loop = new Tone.Sequence(function(time, col){ var loop = new Tone.Sequence(function(time, col){
var column = matrix1.matrix[col]; var column = document.querySelector("tone-step-sequencer").currentColumn;
for (var i = 0; i < 4; i++){ column.forEach(function(val, i){
if (column[i] === 1){ if (val){
//slightly randomized velocities //slightly randomized velocities
var vel = Math.random() * 0.5 + 0.5; var vel = Math.random() * 0.5 + 0.5;
keys.get(noteNames[i]).start(time, 0, "32n", 0, vel); keys.get(noteNames[i]).start(time, 0, "32n", 0, vel);
} }
}
}, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15], "16n");
Tone.Transport.start();
// GUI //
nx.onload = function(){
nx.colorize("#f5871f");
matrix1.col = 16;
matrix1.init();
matrix1.resize($("#Content").width(), 250);
matrix1.draw();
}
Interface.Slider({
name : "BPM",
min : 80,
max : 200,
value : Tone.Transport.bpm.value,
drag : function(val){
Tone.Transport.bpm.value = val;
}
}); });
//set the columne on the correct draw frame
Tone.Draw.schedule(function(){
document.querySelector("tone-step-sequencer").setAttribute("highlight", col);
}, time);
}, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15], "16n").start(0);
Interface.Button({ //bind the interface
text : "Start", document.querySelector("tone-transport").bind(Tone.Transport);
activeText : "Stop",
type : "toggle",
key : 32, //spacebar
start : function(){
loop.start();
},
end : function(){
loop.stop();
},
});
Interface.Loader(); Tone.Transport.on("stop", () => {
setTimeout(() => {
$(window).on("resize", function(){ document.querySelector("tone-step-sequencer").setAttribute("highlight", "-1");
matrix1.resize($("#Content").width(), 250); }, 100);
matrix1.draw();
}); });
</script> </script>

View file

@ -1,346 +0,0 @@
/* FOR MOBILES */
@media (max-width: 750px) {
#TopBar #Homepage a {
font-size: 16px !important; }
#TopBar #Hamburger {
display: initial !important; }
#Sidebar {
display: none;
width: 100% !important; }
iframe {
width: 100% !important; } }
html, body {
padding: 0px;
margin: 0px;
height: calc(100% - 4px);
font-family: "Inconsolata", monospace; }
/**
*
* Example Home
*
*/
#Content.Example {
height: calc(100% - 44px);
width: calc(100% - 6px);
margin-bottom: 0px;
overflow: hidden;
left: 3px; }
#Content.Example #Sidebar {
background-color: white;
width: 280px;
position: absolute;
left: 0px;
top: 0px;
height: calc(100% - 3px);
border-right: 3px solid black;
overflow-y: scroll;
overflow-x: hidden;
z-index: 1; }
#Content.Example #Sidebar .Category {
background-color: black;
color: white;
width: calc(100% - 6px);
height: 25px;
line-height: 25px;
padding-left: 5px;
font-weight: 900; }
#Content.Example #Sidebar .Item {
line-height: 22px;
padding-left: 15px;
height: 22px;
width: 100%; }
#Content.Example #Sidebar .Item:last-child {
margin-bottom: 10px; }
#Content.Example #Sidebar.Open {
display: initial !important; }
#Content.Example iframe {
width: calc(100% - 286px);
border: 0px;
position: absolute;
top: 0px;
right: 0px;
height: 100%;
z-index: 0; }
#Content.Example #Source {
position: absolute;
bottom: 0px;
right: 0px;
width: 80px;
height: 40px;
background-color: black;
color: white;
opacity: 0.5;
cursor: pointer;
z-index: 0; }
#Content.Example #Source:before {
position: absolute;
width: 100%;
height: 100%;
content: "source";
text-align: center;
line-height: 40px; }
#Content.Example #Source:hover {
opacity: 1; }
#Content.Example #Source:hover:active {
background-color: white;
color: black; }
/**
*
* TOP BAR
*
*/
#TopBar {
background-color: black;
height: 35px;
margin: 3px;
position: relative;
width: calc(100% - 6px); }
#TopBar #TonejsLogo {
position: absolute;
top: 3px; }
#TopBar #Examples {
right: 10px;
top: 0px;
height: 35px;
line-height: 35px;
position: absolute;
width: 100px;
text-align: left; }
#TopBar #Examples a {
position: absolute;
font-size: 14px;
color: white;
text-transform: none;
text-decoration: none; }
#TopBar #Hamburger {
display: none;
width: 28px;
height: 28px;
position: absolute;
right: 10px;
top: 3.5px;
cursor: pointer; }
#TopBar #Hamburger span {
margin-top: 6px;
position: absolute;
width: 80%;
height: 3px;
left: 10%;
background-color: white; }
#TopBar #Hamburger span:nth-child(0) {
top: 0%; }
#TopBar #Hamburger span:nth-child(1) {
top: 25%; }
#TopBar #Hamburger span:nth-child(2) {
top: 50%; }
#TopBar #Hamburger:hover:active span {
background-color: #22DBC0; }
#MobileStart {
position: absolute;
width: 100%;
height: 100%;
z-index: 10000;
top: 0px;
left: 0px;
background-color: rgba(0, 0, 0, 0.8); }
#MobileStart #Button {
position: absolute;
left: 50%;
top: 50%;
background-color: #7F33ED;
color: white;
border-radius: 3px;
margin-top: -40px;
margin-left: -40px;
width: 80px;
height: 80px;
text-align: center;
line-height: 80px; }
#MobileStart #Button:hover {
background-color: #7F33ED;
color: white; }
#MobileStart #Button:hover:active {
background-color: #ED33CF;
color: #22DBC0; }
#Content {
position: absolute;
left: 0px;
width: 100%;
margin-bottom: 15px; }
#Content #Title {
height: 23px;
line-height: 23px;
font-size: 1.2em;
color: white;
width: calc(100% - 15px);
padding-left: 15px;
background-color: black; }
#Content #Explanation {
position: relative;
padding: 15px;
color: black;
font-size: 14px;
box-sizing: border-box;
border: 3px solid black;
border-top-width: 0px;
width: 100%; }
#Content #Explanation img {
width: 80%;
max-width: 700px;
margin-left: auto;
margin-right: auto;
display: block; }
#Content a {
color: black;
font-size: 14px;
font-weight: bold;
text-decoration: none; }
#Content a:hover {
color: #1EDF3E; }
#Content a:hover:active {
color: #ED33CF; }
#Content #DragContainer {
margin-left: 3px;
margin-top: 3px;
margin-bottom: 15px;
width: calc(100% - 3px);
height: 400px;
position: relative;
color: white; }
#Content .Slider.x {
position: relative;
height: 94px;
width: 100%;
margin-top: 3px; }
#Content .Slider.x .Axis {
top: 50%;
margin-top: -1.5px; }
#Content .Slider.y {
position: relative;
width: 94px;
height: 400px; }
#Content .Slider.y .Axis {
left: 50%;
margin-left: -1.5px; }
#Content .Dragger {
width: 90px;
height: 90px;
position: absolute;
background-color: black;
border-radius: 50%;
z-index: 1;
margin-top: -2px;
border: 2px solid white;
cursor: -webkit-grab; }
#Content .Dragger #Name {
width: 100%;
height: 100%;
position: relative;
text-align: center;
font-size: 12px;
line-height: 90px;
color: white; }
#Content .Dragger:hover {
background-color: #3833ED;
color: white; }
#Content .Dragger.is-pointer-down {
cursor: -webkit-grabbing;
background-color: #ED33CF; }
#Content .Dragger.is-pointer-down #Name {
color: #1EDF3E; }
#Content .Axis {
position: absolute;
background-color: black;
width: 3px;
height: 3px;
top: 3px;
left: 3px;
border-radius: 1.5px;
z-index: 0; }
#Content #xAxis {
width: calc(100% - 6px); }
#Content #yAxis {
height: calc(100% - 6px); }
#Content .Button {
width: 100%;
margin-top: 3px;
height: 90px;
background-color: black;
line-height: 90px;
color: white;
border-radius: 10px;
text-align: center;
cursor: pointer; }
#Content .Button:hover {
color: white;
background-color: #3833ED; }
#Content .Button:hover:active, #Content #Content .Button:hover:active.Active {
color: #22DBC0;
background-color: #ED33CF; }
#Content .Button.Toggle.Active {
box-sizing: border-box;
border: 3px solid black;
line-height: 84px;
color: black;
background-color: white; }
#Content .Transport {
width: 100%;
height: 30px;
background-color: black;
line-height: 30px;
color: white;
border-radius: 10px;
margin-top: 3px;
position: relative; }
#Content .Transport #Position {
width: 70px;
left: 50%;
margin-left: -35px;
text-align: left;
height: 100%;
position: absolute;
color: white; }
.Keyboard {
height: 100px;
width: 100%;
position: relative; }
code {
background-color: #ECECEC;
color: #333;
padding: 1px; }
#Loading {
z-index: 100000;
position: absolute;
background-color: rgba(140, 140, 140, 0.5);
width: 100%;
height: calc(100% - 37.5px);
top: 37.5px;
left: 0px;
opacity: 1;
transition: opacity 0.4s; }
#Loading #Text {
color: white;
position: absolute;
text-align: center;
top: 50%;
left: 50%;
width: 300px;
margin-left: -150px;
height: 60px;
margin-top: -30px;
line-height: 60px;
font-size: 42px; }
#Loading.Loaded {
pointer-events: none;
opacity: 0; }

View file

@ -1,508 +0,0 @@
//COLORS
$blue: #3833ED;
$green: #1EDF3E;
$red: #ED3333;
$purple: #7F33ED;
$teal : #22DBC0;
$pink : #ED33CF;
$yellow : #FFFC0C;
$orange : #f5871f;
//SIZES
$margin : 3px;
$sidebarWidth : 280px;
$topbarHeight : 35px;
$padding: 15px;
$fontSize : 14px;
/* FOR MOBILES */
@media (max-width: 750px) {
#TopBar #Homepage a {
font-size: 16px !important;
}
#TopBar #Hamburger {
display: initial!important;
}
#Sidebar {
display: none;
width: 100%!important;
}
iframe {
width: 100%!important;
}
}
html, body {
padding: 0px;
margin: 0px;
height: calc(100% - 4px);
font-family: "Inconsolata", monospace;
}
/**
*
* Example Home
*
*/
#Content.Example {
height: calc(100% - #{$topbarHeight + $margin * 3});
width: calc(100% - #{$margin * 2});
margin-bottom: 0px;
overflow: hidden;
left: $margin;
#Sidebar {
background-color: white;
width: $sidebarWidth;
position: absolute;
left: 0px;
top: 0px;
height: calc(100% - #{$margin});
border-right: $margin solid black;
overflow-y: scroll;
overflow-x: hidden;
$catHeight : 25px;
$itemHeight : 22px;
.Category {
background-color: black;
color: white;
width: calc(100% - #{$margin * 2});
height: $catHeight;
line-height: $catHeight;
padding-left: 5px;
font-weight: 900;
}
.Item {
line-height: $itemHeight;
padding-left: 15px;
height: $itemHeight;
width: 100%;
&:last-child{
margin-bottom: 10px;
}
}
&.Open {
display: initial!important;
}
z-index: 1;
}
iframe {
width: calc(100% - #{$sidebarWidth + $margin * 2});
border: 0px;
position: absolute;
top: 0px;
right: 0px;
height: 100%;
z-index: 0;
}
$sourceHeight: 40px;
#Source {
position: absolute;
bottom: 0px;
right: 0px;
width: 80px;
height: $sourceHeight;
background-color: black;
color: white;
opacity: 0.5;
cursor: pointer;
z-index: 0;
&:before {
position: absolute;
width: 100%;
height: 100%;
content : "source";
text-align: center;
line-height: $sourceHeight;
}
&:hover {
opacity: 1;
&:active {
background-color: white;
color: black;
}
}
}
}
/**
*
* TOP BAR
*
*/
#TopBar {
background-color: black;
height: $topbarHeight;
margin: $margin;
position: relative;
width: calc(100% - #{$margin * 2});
#TonejsLogo {
position: absolute;
top: $margin;
}
#Examples {
right: 10px;
top: 0px;
height: $topbarHeight;
line-height: $topbarHeight;
position: absolute;
width: 100px;
text-align: left;
a {
position: absolute;
font-size: $fontSize;
color: white;
text-transform: none;
text-decoration: none;
}
}
#Hamburger {
$shrink : 0.8;
display: none;
width: $topbarHeight * $shrink;
height: $topbarHeight * $shrink;
position: absolute;
right: 10px;
top: ($topbarHeight * (1 - $shrink)) / 2;
cursor: pointer;
span {
margin-top: 6px;
position: absolute;
width: 80%;
height: $margin;
left: 10%;
background-color: white;
}
span:nth-child(0) {
top: 25% * 0;
}
span:nth-child(1) {
top: 25% * 1;
}
span:nth-child(2) {
top: 25% * 2;
}
&:hover:active {
span {
background-color: $teal;
}
}
}
}
#MobileStart {
position: absolute;
width: 100%;
height: 100%;
z-index: 10000;
top: 0px;
left: 0px;
background-color: rgba(0, 0, 0, 0.8);
$ButtonSize : 80px;
#Button {
position: absolute;
left: 50%;
top: 50%;
background-color: $purple;
color: white;
border-radius: $margin;
margin-top: -$ButtonSize/2;
margin-left: -$ButtonSize/2;
width: $ButtonSize;
height: $ButtonSize;
text-align: center;
line-height: $ButtonSize;
}
#Button:hover {
background-color: $purple;
color: white;
}
#Button:hover:active {
background-color: $pink;
color: $teal;
}
}
.Mobile #Content {
// width: calc(100% - 28px);
}
#Content {
position: absolute;
left: 0px;
width: 100%;
margin-bottom: $padding;
#Title {
height: 23px;
line-height: 23px;
font-size: 1.2em;
color: white;
width: calc(100% - #{$padding});
padding-left: $padding;
background-color: black;
}
#Explanation {
position: relative;
padding: $padding;
color: black;
font-size: $fontSize;
box-sizing: border-box;
border: $margin solid black;
border-top-width: 0px;
width: 100%;
img {
width: 80%;
max-width: 700px;
margin-left: auto;
margin-right: auto;
display: block;
}
}
a {
color: black;
font-size: $fontSize;
font-weight: bold;
text-decoration: none;
}
a:hover {
color: $green;
}
a:hover:active {
color: $pink;
}
$DraggerHeight : 400px;
// DRAGER
#DragContainer {
margin-left: $margin;
margin-top: $margin;
margin-bottom: $padding;
width: calc(100% - #{$margin});
height: $DraggerHeight;
position: relative;
color: white;
}
//SLIDERS
.Slider.x {
position: relative;
height: 94px;
width: 100%;
margin-top: 3px;
.Axis {
top: 50%;
margin-top: -1.5px;
}
}
.Slider.y {
position: relative;
width: 94px;
height: $DraggerHeight;
.Axis {
left: 50%;
margin-left: -1.5px;
}
}
$DragHandleSize : 90px;
//DRAGGER
.Dragger {
width: $DragHandleSize;
height: $DragHandleSize;
position: absolute;
background-color: black;
border-radius: 50%;
z-index: 1;
margin-top: -2px;
border: 2px solid white;
cursor: -webkit-grab;
#Name {
width: 100%;
height: 100%;
position: relative;
text-align: center;
font-size: 12px;
line-height: $DragHandleSize;
color: white;
}
}
.Dragger:hover {
background-color: $blue;
color: white;
}
.Dragger.is-pointer-down {
cursor: -webkit-grabbing;
background-color: $pink;
#Name {
color: $green;
}
}
$AxisWidth : 3px;
//AXIS LINES
.Axis {
position: absolute;
background-color: black;
width: $AxisWidth;
height: $AxisWidth;
top: $AxisWidth;
left: $AxisWidth;
border-radius: $AxisWidth/2;
z-index: 0;
}
#xAxis {
width: calc(100% - #{$margin * 2});
}
#yAxis {
height: calc(100% - #{$margin * 2});
}
$ButtonHeight : 90px;
//BUTTONS
.Button {
width: 100%;
margin-top: $margin;
height: $ButtonHeight;
background-color: black;
line-height: $ButtonHeight;
color: white;
border-radius: 10px;
text-align: center;
cursor: pointer;
}
.Button:hover {
color: white;
background-color: $blue;
}
.Button:hover:active, #Content .Button:hover:active.Active {
color: $teal;
background-color: $pink;
}
.Button.Toggle.Active {
$ToggleBorder : 3px;
box-sizing: border-box;
border: $ToggleBorder solid black;
line-height: $ButtonHeight - $ToggleBorder*2;
color: black;
background-color: white;
}
//TRANSPORT
$TransportHeight : $ButtonHeight / 3;
.Transport {
width: 100%;
height: $TransportHeight;
background-color: black;
line-height: $TransportHeight;
color: white;
border-radius: 10px;
margin-top: $margin;
position: relative;
$PositionWidth: 70px;
#Position {
width: $PositionWidth;
left: 50%;
margin-left: -$PositionWidth/2;
text-align: left;
height: 100%;
position: absolute;
color: white;
}
}
}
.Keyboard {
height: 100px;
width: 100%;
position: relative;
}
code {
background-color: #ECECEC;
color: #333;
padding: 1px;
}
//LOADING
#Loading {
z-index: 100000;
position: absolute;
background-color: rgba(140, 140, 140, 0.5);
width: 100%;
height: calc(100% - 37.5px);
top: 37.5px;
left: 0px;
opacity: 1;
transition: opacity 0.4s;
#Text {
color: white;
position: absolute;
text-align: center;
top: 50%;
left: 50%;
width: 300px;
margin-left: -150px;
height: 60px;
margin-top: -30px;
line-height: 60px;
font-size: 42px;
}
}
#Loading.Loaded {
pointer-events: none;
opacity: 0;
}