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">
<title>Analyser</title>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
<link rel="icon" type="image/png" sizes="174x174" href="./style/favicon.png">
<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="./scripts/jquery.min.js"></script>
<script src="./scripts/draggabilly.js"></script>
<script src="https://tonejs.github.io/Logo/build/Logo.js"></script>
<script src="./scripts/StartAudioContext.js"></script>
<script src="./scripts/Interface.js"></script>
<script src="./js/tonejs-ui.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>
<body>
<div id="Content" class="FullScreen">
<div id="Title">Analyser</div>
<div id="Explanation">
<a href="https://tonejs.github.io/docs/#Analyser" target="_blank">Tone.Analyser</a>
analyses the incoming audio to produce a TypedArray of either the
<a href="https://en.wikipedia.org/wiki/Fast_Fourier_transform" target="_blank">FFT data</a>
or the waveform. The default <code>returnType</code> is "byte" which returns values
in the range 0-255.
</div>
<style>
tone-oscilloscope, tone-fft {
width: 100%;
height: 44px;
border-radius: 22px;
background-color: black;
}
</style>
<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>
//analyse the frequency/amplitude of the incoming signal
var fft = new Tone.FFT(32);
<tone-content>
<tone-oscilloscope></tone-oscilloscope>
<tone-fft></tone-fft>
<tone-play-toggle></tone-play-toggle>
</tone-content>
//get the waveform data for the audio
var waveform = new Tone.Waveform(1024);
<tone-drawer label="Components">
<tone-player collapsed></tone-player>
</tone-drawer>
</tone-example>
<script type="text/javascript">
var player = new Tone.Player({
"url" : "./audio/FWDL.[mp3|ogg]",
"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>
</body>
</html>

View file

@ -2,29 +2,23 @@
<html>
<head>
<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">
<link rel="icon" type="image/png" sizes="174x174" href="./style/favicon.png">
<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="./scripts/jquery.min.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="./js/tonejs-ui.js"></script>
<link rel="stylesheet" type="text/css" href="./style/examples.css">
<script>
// jshint ignore: start
</script>
</head>
<body>
<style type="text/css">
#Notes{
width: 100%;
height: 20px;
margin-top: 3px;
position: relative;
margin-bottom: 10px;
}
.Note {
width: 20%;
@ -33,17 +27,20 @@
float: left;
background-color: black;
opacity: 0;
transition: opacity 0.5s;
}
.Note.active {
opacity: 1;
transition-duration: 0.1s;
}
</style>
</head>
<body>
<div id="Content">
<div id="Title">Synchronizing Visuals</div>
<div id="Explanation">
<tone-example>
<tone-explanation label="Synchronizing Visuals">
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>
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="C4" class="Note"></div>
<div id="E4" class="Note"></div>
@ -51,10 +48,15 @@
<div id="B4" class="Note"></div>
<div id="D5" class="Note"></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({
"oscillator" : {
"type" : "fmsine4",
@ -68,29 +70,22 @@
// Draw.schedule takes a callback and a time to invoke the callback
Tone.Draw.schedule(function(){
//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);
}, ["C4", "E4", "G4", "B4", "D5"]).start(0);
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>
</body>
</html>

Binary file not shown.

After

Width:  |  Height:  |  Size: 227 KiB

View file

@ -2,40 +2,38 @@
<html>
<head>
<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">
<link rel="icon" type="image/png" sizes="174x174" href="./style/favicon.png">
<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="./scripts/jquery.min.js"></script>
<script src="./scripts/draggabilly.js"></script>
<script src="https://tonejs.github.io/Logo/build/Logo.js"></script>
<script src="./scripts/StartAudioContext.js"></script>
<script src="./scripts/Interface.js"></script>
<link rel="stylesheet" type="text/css" href="./style/examples.css">
<script>
// jshint ignore: start
</script>
<script src="./js/tonejs-ui.js"></script>
</head>
<body>
<div id="Content">
<div id="Title">Bembe</div>
<div id="Explanation">
<a href="https://tonejs.github.io/docs/#MetalSynth">Tone.MetalSynth</a>
<tone-example>
<tone-explanation label="Bembe">
<a href="https://tonejs.github.io/docs/MetalSynth">Tone.MetalSynth</a>
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.
<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.
</div>
</div>
</tone-explanation>
<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({
"harmonicity" : 12,
"resonance" : 800,
@ -49,7 +47,11 @@
var bellPart = new Tone.Sequence(function(time, freq){
bell.frequency.setValueAtTime(freq, time, Math.random()*0.5 + 0.5);
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.loopEnd = "1m";
@ -73,20 +75,10 @@
Tone.Transport.bpm.value = 115;
// GUI //
Interface.Button({
key : 32,
type : "toggle",
text : "Start",
activeText : "Stop",
start : function(){
Tone.Transport.start("+0.1");
},
end : function(){
Tone.Transport.stop();
}
});
//bind the interface
document.querySelector("tone-play-toggle").bind(Tone.Transport);
document.querySelector("tone-metal-synth").bind(bell);
document.querySelector("tone-membrane-synth").bind(conga);
</script>
</body>

View file

@ -4,48 +4,51 @@
<meta charset="utf-8">
<title>Buses</title>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
<link rel="icon" type="image/png" sizes="174x174" href="./style/favicon.png">
<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="./scripts/jquery.min.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>
<script src="./js/tonejs-ui.js"></script>
<style>
tone-content tone-slider {
display: block;
margin-top: 10px;
}
</style>
</head>
<body>
<div id="Content">
<div id="Title">Buses</div>
<div id="Explanation">
<tone-example>
<tone-explanation label="Buses">
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
channel on your effect. The gain values are all in decibels.
<br><br>
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>.
</div>
<div id="Sliders"></div>
<div id="Keyboard"></div>
</div>
<script>
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>.
</tone-explanation>
<tone-content>
<tone-piano></tone-piano>
<tone-slider label="Chorus Send" min="-100" max="0" value="-100" units="db"></tone-slider>
<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
var synth = new Tone.Synth().toMaster()
.set("envelope.attack", 0.04);
var synth = new Tone.Synth().toMaster().set("envelope.attack", 0.04);
//send audio to each of the effect channels
var chorusSend = synth.send("chorus", -Infinity);
var chebySend = synth.send("cheby", -Infinity);
var autowahSend = synth.send("autowah", -Infinity);
var reverbSend = synth.send("reverb", -Infinity);
//make some effects
@ -61,51 +64,21 @@
.receive("reverb")
.toMaster();
// GUI //
Interface.Slider({
name : "Chebyshev",
parent : $("#Sliders"),
min : -100,
max : 0,
drag : function(val){
chebySend.gain.value = val;
}
//bind the interface
document.querySelector("tone-chorus").bind(chorus);
document.querySelector("tone-chebyshev").bind(cheby);
document.querySelector("tone-freeverb").bind(reverb);
document.querySelector("tone-synth").bind(synth);
document.querySelector("tone-piano").bind(synth);
document.querySelector("[label=\"Chorus Send\"]").addEventListener("change", e => {
chorusSend.gain.value = e.detail;
});
Interface.Slider({
name : "Chorus",
parent : $("#Sliders"),
min : -100,
max : 0,
drag : function(val){
chorusSend.gain.value = val;
}
document.querySelector("[label=\"Chebyshev Send\"]").addEventListener("change", e => {
chebySend.gain.value = e.detail;
});
Interface.Slider({
name : "Freeverb",
parent : $("#Sliders"),
min : -100,
max : 0,
drag : function(val){
reverbSend.gain.value = val;
}
document.querySelector("[label=\"Freeverb Send\"]").addEventListener("change", e => {
reverbSend.gain.value = e.detail;
});
/**
* the keyboard
*/
var keyboard = Interface.Keyboard();
keyboard.keyDown = function (note) {
synth.triggerAttack(note);
};
keyboard.keyUp = function () {
synth.triggerRelease();
};
</script>
</body>
</html>

View file

@ -2,91 +2,61 @@
<html>
<head>
<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">
<link rel="icon" type="image/png" sizes="174x174" href="./style/favicon.png">
<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="./scripts/jquery.min.js"></script>
<script src="./scripts/draggabilly.js"></script>
<script src="https://tonejs.github.io/Logo/build/Logo.js"></script>
<script src="./scripts/StartAudioContext.js"></script>
<script src="./scripts/Interface.js"></script>
<link rel="stylesheet" type="text/css" href="./style/examples.css">
<script>
// jshint ignore: start
</script>
</head>
<body>
<script src="./js/tonejs-ui.js"></script>
<style type="text/css">
#Left, #Right {
height: 200px;
width: 50%;
tone-play-toggle {
margin-bottom: 10px;
}
#tracks {
position: relative;
float: left;
margin-top: 5px;
margin-bottom: 5px;
width: calc(100% - 10px);
margin-left: 10px;
}
.Button {
display: inline-block;
}
#TransportContainer{
margin-top: 5px;
margin-bottom: 5px;
width: 100%;
height: 100px;
position: relative;
}
#DawCanvas {
width: 100%;
#progress {
width: 1px;
height: 100%;
position: absolute;
top: 0px;
left: 0px;
}
#Bar {
width: 2px;
height: 94%;
position: absolute;
top: 3%;
left: 0%;
position: absolute;
background-color: black;
}
#Images {
overflow: hidden;
height: 0px;
img {
width: 100%;
height: 200px;
}
</style>
<div id="Content">
<div id="Title">Transport Sync</div>
<div id="Explanation">
</head>
<body>
<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.
</div>
<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>
</tone-explanation>
<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.loop = true;
Tone.Transport.loopStart = "4m";
Tone.Transport.loopEnd = "8m";
var kick = new Tone.Player({
url : "./audio/loop/kick.[mp3|ogg]",
@ -103,117 +73,11 @@
loop : true
}).toMaster().sync().start("3:3", "4n"); //start with an offset
Tone.Transport.loop = true;
Tone.Transport.loopStart = "4m";
Tone.Transport.loopEnd = "8m";
// GUI //
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);
//bind the transport
document.querySelector("tone-play-toggle").bind(Tone.Transport);
document.querySelector("tone-position").bind(Tone.Transport);
document.querySelector("tone-position").addEventListener("position", e => {
document.querySelector("#progress").style = `left: ${e.detail*100}%`;
});
</script>
</body>

View file

@ -4,61 +4,49 @@
<meta charset="utf-8">
<title>Envelope</title>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
<link rel="icon" type="image/png" sizes="174x174" href="./style/favicon.png">
<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="./scripts/jquery.min.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>
<script src="./js/tonejs-ui.js"></script>
</head>
<body>
<style type="text/css">
img {
display: block;
margin: 5px auto;
width: 300px!important;
}
.y {
float: left;
height: 290px!important;
}
#Sliders {
float: left;
position: relative;
width: calc(100% - 100px);
}
.Button {
clear: both;
tone-trigger {
margin-bottom: 10px;
}
</style>
<div id="Content">
<div id="Title">Envelope</div>
<div id="Explanation">
<tone-example>
<tone-explanation label="Envelope">
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
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">
</div>
<div id="Sliders"></div>
</div>
</tone-explanation>
<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({
"attack" : 0.11,
"decay" : 0.21,
"sustain" : 0.09,
"sustain" : 0.5,
"release" : 1.2
}).toMaster();
@ -70,58 +58,16 @@
"volume" : -8,
}).connect(env).start();
// GUI //
//bind the interface
document.querySelector("tone-envelope").bind(env);
document.querySelector("tone-oscillator").bind(osc);
Interface.Slider({
param : "attack",
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(){
document.querySelector("tone-trigger").addEventListener("change", e => {
if (e.detail){
env.triggerAttack();
},
end : function(){
} else {
env.triggerRelease();
},
}
});
</script>
</body>

View file

@ -2,42 +2,41 @@
<html>
<head>
<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">
<link rel="icon" type="image/png" sizes="174x174" href="./style/favicon.png">
<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="./scripts/jquery.min.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>
<script src="./js/tonejs-ui.js"></script>
</head>
<body>
<div id="Content">
<div id="Title">Events</div>
<div id="Explanation">
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/#Part">Tone.Part</a> and
<a href="https://tonejs.github.io/docs/#Sequence">Tone.Sequence</a>)
<tone-example>
<tone-explanation label="Events">
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/Part">Tone.Part</a> and
<a href="https://tonejs.github.io/docs/Sequence">Tone.Sequence</a>)
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.scheduleRepeat">scheduleRepeat</a>
<a href="https://tonejs.github.io/docs/Transport.schedule">Transport.schedule</a> or
<a href="https://tonejs.github.io/docs/Transport.scheduleRepeat">scheduleRepeat</a>
and lets you create precise, rhythmic events which are startable, stoppable and loopable.
</tone-explanation>
</div>
</div>
<tone-content>
<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
*/
@ -54,7 +53,6 @@
kick.triggerAttackRelease("C2", "8n", time);
}, "2n").start(0);
/*
SNARE
*/
@ -76,7 +74,6 @@
snare.triggerAttack(time);
}, "2n").start("4n");
/**
* PIANO
*/
@ -86,7 +83,7 @@
"partials" : [1, 2, 1],
},
"portamento" : 0.05
}).toMaster()
}).toMaster();
var cChord = ["C4", "E4", "G4", "B4"];
var dChord = ["D4", "F4", "A4", "C5"];
@ -100,7 +97,6 @@
pianoPart.loopEnd = "1m";
pianoPart.humanize = true;
/*
BASS
*/
@ -129,20 +125,12 @@
//set the transport
Tone.Transport.bpm.value = 90;
// GUI //
Interface.Button({
key : 32,
type : "toggle",
text : "Start",
activeText : "Stop",
start : function(){
Tone.Transport.start("+0.1");
},
end : function(){
Tone.Transport.stop();
}
});
//bind the interface
document.querySelector("tone-play-toggle").bind(Tone.Transport);
document.querySelector("tone-membrane-synth").bind(kick);
document.querySelector("tone-mono-synth").bind(bass);
document.querySelector("tone-synth").bind(piano);
document.querySelector("tone-noise-synth").bind(snare);
</script>
</body>
</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">
<title>FMSynth</title>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
<link rel="icon" type="image/png" sizes="174x174" href="./style/favicon.png">
<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="./scripts/jquery.min.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>
<script src="./js/tonejs-ui.js"></script>
</head>
<body>
<div id="Content">
<div id="Title">FMSynth</div>
<div id="Explanation">
<a href="https://tonejs.github.io/docs/#FMSynth">Tone.FMSynth</a>
<style>
tone-piano {
margin-bottom: 10px;
}
</style>
<tone-example>
<tone-explanation label="FMSynth">
<a href="https://tonejs.github.io/docs/FMSynth">Tone.FMSynth</a>
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.
</div>
</div>
</tone-explanation>
<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({
"modulationIndex" : 12.22,
"envelope" : {
@ -50,25 +47,9 @@
}
}).toMaster();
// GUI //
Interface.Slider({
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();
};
//bind the interface
document.querySelector("tone-piano").bind(synth);
document.querySelector("tone-fm-synth").bind(synth);
</script>
</body>
</html>

View file

@ -3,30 +3,14 @@
<head>
<meta charset="utf-8">
<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="./scripts/p5.Tone.js"></script>
<script src="./scripts/jquery.min.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>
<script src="./js/tonejs-ui.js"></script>
<script src="./js/p5.js"></script>
</head>
<body>
<style type="text/css">
@ -34,19 +18,36 @@
position: absolute;
top: 0px;
z-index: -1;
left: 0px;
}
</style>
<div id="Content" class="FullScreen">
<div id="Title">Using p5</div>
<div id="Explanation">
By accessing the envelope's current value, we can create responsive visuals that are directly tied to what is heard.
<tone-example>
<tone-explanation label="Tone with p5.js">
Access the envelopes current value to synchronize visuals. This sketch uses <a href="https://p5js.org" target="_blank">p5.js</a> for canvas rendering.
<br><br>
This sketch uses <a href="https://p5js.org" target="_blank">p5.js</a> for visual components.
</div>
</div>
<script id="p5">
Example by <a href="https://github.com/polyrhythmatic">polyrhythmatic</a>
</tone-explanation>
//creating our class name
<tone-content>
<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(){}
/*
@ -63,7 +64,7 @@
this.radius = radius;
this.xPos = 0;
this.yPos = 0;
}
};
//updates the x, y, and radius values of the shape
FunkyShape.prototype.update = function(envelope){
@ -77,7 +78,7 @@
"yPos" : this.yPos,
"radius" : this.sRadius
};
}
};
//using our FunkyShape class
//to create a funkyCircle class
@ -133,17 +134,12 @@
var circlePos = funkyCircle.update(bassEnvelope.value);
//circlePos returns x and y positions as an object
ellipse(circlePos.xPos, circlePos.yPos, circlePos.radius, circlePos.radius);
stroke('red');
stroke("red");
for (var i = 0; i < 3; i++){
var squarePos = funkySquare[i].update(bleepEnvelope.value);
rect(squarePos.xPos, squarePos.yPos, squarePos.radius, squarePos.radius);
}
}
</script>
<script id="Song">
//HATS
//filtering the hi-hats a bit
//to make them sound nicer
@ -173,7 +169,7 @@
var openHiHatPart = new Tone.Part(function(time){
openHiHat.triggerAttack(time);
}, ["2*8n", "6*8n"]).start(0);
}, [{ "8n" : 2 }, { "8n" : 6 }]).start(0);
var closedHiHat = new Tone.NoiseSynth({
"volume" : -10,
@ -196,14 +192,13 @@
var closedHatPart = new Tone.Part(function(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
var bassEnvelope = new Tone.AmplitudeEnvelope({
"attack" : 0.01,
"decay" : 0.2,
"sustain" : 0,
"release": 0,
}).toMaster();
var bassFilter = new Tone.Filter({
@ -227,10 +222,8 @@
"attack" : 0.01,
"decay" : 0.4,
"sustain" : 0,
"release": 0,
}).toMaster();
var bleep = new Tone.Oscillator("A4").connect(bleepEnvelope);
bleep.start();
@ -243,16 +236,14 @@
"attack" : 0.01,
"decay" : 0.2,
"sustain" : 0,
"release": 0
}).toMaster();
var kick = new Tone.Oscillator("A2").connect(kickEnvelope).start();
kickSnapEnv = new Tone.FrequencyEnvelope({
var kickSnapEnv = new Tone.FrequencyEnvelope({
"attack" : 0.005,
"decay" : 0.01,
"sustain" : 0,
"release": 0,
"baseFrequency" : "A2",
"octaves" : 2.7
}).connect(kick.frequency);
@ -267,20 +258,19 @@
Tone.Transport.loopEnd = "1:0";
Tone.Transport.loop = true;
// GUI //
Interface.Button({
type : "toggle",
text : "Start",
activeText : "Stop",
start : function(){
Tone.Transport.start("+0.1");
},
end : function(){
Tone.Transport.stop();
}
});
//bind the interface
document.querySelector("tone-play-toggle").bind(Tone.Transport);
document.querySelector("#hihatFilter").bind(lowPass);
document.querySelector("#openHiHat").bind(openHiHat);
document.querySelector("#closedHiHat").bind(closedHiHat);
document.querySelector("#bassOsc").bind(bass);
document.querySelector("#bassFilter").bind(bassFilter);
document.querySelector("#bassEnvelope").bind(bassEnvelope);
document.querySelector("#bleep").bind(bleep);
document.querySelector("#bleepEnvelope").bind(bleepEnvelope);
document.querySelector("#kickOsc").bind(kick);
document.querySelector("#kickEnvelope").bind(kickEnvelope);
document.querySelector("#kickFreqEnvelope").bind(kickSnapEnv);
</script>
</body>

View file

@ -2,39 +2,47 @@
<html>
<head>
<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">
<link rel="icon" type="image/png" sizes="174x174" href="./style/favicon.png">
<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="./scripts/jquery.min.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>
<script src="./js/tonejs-ui.js"></script>
</head>
<body>
<div id="Content">
<div id="Title">Granular Synthesis</div>
<div id="Explanation">
<a href="https://tonejs.github.io/docs/#GrainPlayer">Tone.GrainPlayer</a> uses
<style type="text/css">
tone-play-toggle, tone-fft {
margin-bottom: 10px;
}
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>
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 crossfading transition time between successive grains.
</div>
<div id="Sliders"></div>
</div>
<script>
</tone-explanation>
<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
var player = new Tone.GrainPlayer({
"url" : "./audio/FWDL.[mp3|ogg]",
@ -43,58 +51,10 @@
"overlap" : 0.05,
}).toMaster();
// GUI //
Interface.Loader();
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,
});
//bind the interface
document.querySelector("tone-fft").bind(player);
document.querySelector("tone-play-toggle").bind(player);
document.querySelector("tone-grain-player").bind(player);
</script>
</body>
</html>

View file

@ -2,93 +2,29 @@
<html>
<head>
<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">
<link rel="icon" type="image/png" sizes="174x174" href="./style/favicon.png">
<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="./scripts/jquery.min.js"></script>
<script src="https://tonejs.github.io/Logo/build/Logo.js"></script>
<script src="./scripts/ExampleList.js"></script>
<link rel="stylesheet" type="text/css" href="./style/examples.css">
<link href="https://fonts.googleapis.com/css?family=Inconsolata" rel="stylesheet">
<script type="text/javascript">
//forward links with hashes
if (window.location.hash !== ""){
var hash = window.location.hash.substring(1);
window.location.href = window.location.pathname+hash;
}
</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>
<body>
<div id="Content" class="Example">
<iframe></iframe>
<div id="Sidebar"></div>
</div>
<tone-example open>
<tone-explanation label="Examples">
Choose an example from the side panel.
</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>
</html>

View file

@ -1,4 +1,4 @@
var ExampleList = {
{
"Basic" : {
"Oscillators" : "oscillator",
"Envelope" : "envelope",
@ -34,7 +34,7 @@ var ExampleList = {
},
"Signals" : {
"Control Voltage" : "signal",
"Ramping Values" : "rampTo",
"Ramping Values" : "rampTo"
},
"Visualization" : {
"Animation Sync" : "animationSync",
@ -43,7 +43,6 @@ var ExampleList = {
"Meter" : "meter"
},
"Misc" : {
"Module Loaders" : "require",
"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,40 +4,41 @@
<meta charset="utf-8">
<title>FatOscillator</title>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
<link rel="icon" type="image/png" sizes="174x174" href="./style/favicon.png">
<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="./scripts/jquery.min.js"></script>
<script src="./scripts/draggabilly.js"></script>
<script src="https://tonejs.github.io/Logo/build/Logo.js"></script>
<script src="./scripts/StartAudioContext.js"></script>
<script src="./scripts/Interface.js"></script>
<link rel="stylesheet" type="text/css" href="./style/examples.css">
<script type="text/javascript">
// jshint ignore: start
</script>
<script src="./js/tonejs-ui.js"></script>
</head>
<body>
<div id="Content">
<div id="Title">Supersaw</div>
<div id="Explanation">
<a href="https://tonejs.github.io/docs/#FatOscillator">Tone.FatOscillator</a> creates multiple oscillators
<style type="text/css">
tone-play-toggle {
margin-bottom: 10px;
}
</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
the number of oscillators and <code>spread</code> sets the total spread (in cents) between the oscillators.
<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>.
<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>
</div>
</div>
</tone-explanation>
<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, {
"oscillator" : {
"type" : "fatsawtooth",
@ -57,8 +58,7 @@
// converted using
var part = new Tone.Part(function(time, note){
synth.triggerAttackRelease(note.noteName, note.duration, time, note.velocity);
}, [
{
}, [{
"time" : "192i",
"noteName" : "G4",
"velocity" : 0.8110236220472441,
@ -257,20 +257,9 @@
Tone.Transport.bpm.value = 132;
// GUI //
Interface.Button({
key : 32,
type : "toggle",
text : "Start",
activeText : "Stop",
start : function(){
Tone.Transport.start("+0.1");
},
end : function(){
Tone.Transport.stop();
}
});
//bind the interface
document.querySelector("tone-play-toggle").bind(Tone.Transport);
document.querySelector("tone-synth").bind(synth);
</script>
</body>

View file

@ -4,38 +4,43 @@
<meta charset="utf-8">
<title>LFO Effects</title>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
<link rel="icon" type="image/png" sizes="174x174" href="./style/favicon.png">
<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="./scripts/jquery.min.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>
<script src="./js/tonejs-ui.js"></script>
</head>
<body>
<div id="Content">
<div id="Title">LFO Effects</div>
<div id="Explanation">
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.
<style type="text/css">
tone-content * {
margin-bottom: 50px;
}
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>
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/#Tremolo">Tone.Tremolo</a>
</div>
<div id="DragContainer">
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/Tremolo">Tone.Tremolo</a>
</tone-explanation>
</div>
</div>
<script id="JSCode">
//AutoPanner - a penning modulation effect
<tone-content>
<tone-play-toggle id="osc0"></tone-play-toggle>
<tone-auto-panner collapsed></tone-auto-panner>
<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({
"frequency" : 4,
"depth" : 1
@ -72,7 +77,21 @@
"frequency" : "A4"
}).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({
tone : panner,
@ -132,7 +151,7 @@
end : function(){
osc2.volume.rampTo(-Infinity, 0.1);
}
});
});*/
</script>
</body>

View file

@ -4,106 +4,49 @@
<meta charset="utf-8">
<title>Meter</title>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
<link rel="icon" type="image/png" sizes="174x174" href="./style/favicon.png">
<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="./scripts/jquery.min.js"></script>
<script src="./scripts/draggabilly.js"></script>
<script src="https://tonejs.github.io/Logo/build/Logo.js"></script>
<script src="./scripts/StartAudioContext.js"></script>
<script src="./scripts/Interface.js"></script>
<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>
<script src="./js/tonejs-ui.js"></script>
</head>
<body>
<div id="Content" class="FullScreen">
<div id="Title">Meter</div>
<div id="Explanation">
<a href="https://tonejs.github.io/docs/#Meter" target="_blank">Tone.Meter</a>
<style type="text/css">
tone-meter {
width: 100%;
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.
</div>
</tone-explanation>
</div>
<tone-content>
<tone-meter level color="#eee"></tone-meter>
<tone-play-toggle></tone-play-toggle>
</tone-content>
<script>
//create a level meter
var meter = new Tone.Meter();
<tone-drawer>
<tone-player collapsed></tone-player>
</tone-drawer>
</tone-example>
<script type="text/javascript">
var player = new Tone.Player({
"url" : "./audio/FWDL.[mp3|ogg]",
"loop" : true
}).connect(meter).toMaster();
}).toMaster();
// GUI //
//start button
Interface.Button({
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();
//bind the interface
document.querySelector("tone-play-toggle").bind(player);
document.querySelector("tone-meter").bind(player);
document.querySelector("tone-player").bind(player);
</script>
</body>
</html>

View file

@ -2,104 +2,44 @@
<html>
<head>
<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">
<link rel="icon" type="image/png" sizes="174x174" href="./style/favicon.png">
<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="./scripts/jquery.min.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>
<script src="./js/tonejs-ui.js"></script>
</head>
<body>
<style type="text/css">
canvas {
tone-oscilloscope {
width: 100%;
height: 200px;
background-color: black;
border-bottom-left-radius: 5px;
border-bottom-right-radius: 5px;
height: 40px;
border-radius: 20px;
margin-bottom: 10px;
}
</style>
<div id="Content" class="FullScreen">
<div id="Title">Microphone</div>
<div id="Explanation">
<tone-example>
<tone-explanation label="Microphone">
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>
</div>
<script>
</tone-explanation>
<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
//directly to the master output because of feedback.
var mic = new Tone.UserMedia();
var analyser = new Tone.Waveform(256);
mic.connect(analyser);
// 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();
}
});
}
//bind the interface
document.querySelector("tone-microphone").bind(mic);
document.querySelector("tone-oscilloscope").bind(mic);
</script>

View file

@ -4,149 +4,58 @@
<meta charset="utf-8">
<title>Mixer</title>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
<link rel="icon" type="image/png" sizes="174x174" href="./style/favicon.png">
<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="./scripts/jquery.min.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>
<script src="./js/tonejs-ui.js"></script>
<style type="text/css">
img {
width: 300px!important;
#tracks {
display: flex;
}
.y {
height: 200px!important;
margin-left: auto;
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;
#tracks tone-channel {
flex-grow: 1;
margin: 5px;
width: 20%;
}
</style>
<div id="Content">
<div id="Title">PanVol / Solo</div>
<div id="Explanation">
<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.
</div>
<div id="Sliders"></div>
</head>
<body>
<tone-example>
<tone-loader></tone-loader>
<tone-explanation label="Channel">
<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>
</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);
function makeFader(track, name){
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;
},
});
//bind the UI
document.querySelector(`#${name}`).bind(channel);
}
makeFader("bass");
makeFader("chords");
makeFader("drone");
Interface.Button({
type : "toggle",
text : "Start",
activeText : "Stop",
start : function(){
Tone.Transport.start()
},
end : function(){
Tone.Transport.stop()
},
});
makeChannel("bass");
makeChannel("chords");
makeChannel("drone");
document.querySelector("tone-play-toggle").bind(Tone.Transport);
</script>
</body>
</html>

View file

@ -4,38 +4,34 @@
<meta charset="utf-8">
<title>MonoSynth</title>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
<link rel="icon" type="image/png" sizes="174x174" href="./style/favicon.png">
<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="./scripts/jquery.min.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>
<script src="./js/tonejs-ui.js"></script>
</head>
<body>
<div id="Content">
<div id="Title">MonoSynth</div>
<div id="Explanation">
<a href="https://tonejs.github.io/docs/#MonoSynth">Tone.MonoSynth</a>
<style>
tone-piano {
margin-bottom: 10px;
}
</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.
Both envelopes are triggered simultaneously when a note is triggered.
</div>
<div id="Keyboard"></div>
</div>
</tone-explanation>
<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" : {
"type" : "square8"
},
@ -55,18 +51,9 @@
}
}).toMaster();
// GUI //
var keyboard = Interface.Keyboard();
keyboard.keyDown = function (note) {
synth.triggerAttack(note);
};
keyboard.keyUp = function () {
synth.triggerRelease();
};
//bind the interface
document.querySelector("tone-piano").bind(synth);
document.querySelector("tone-mono-synth").bind(synth);
</script>
</body>

View file

@ -2,68 +2,50 @@
<html>
<head>
<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">
<link rel="icon" type="image/png" sizes="174x174" href="./style/favicon.png">
<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="./scripts/jquery.min.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>
<script src="./js/tonejs-ui.js"></script>
</head>
<body>
<style type="text/css">
.Dragger#Noise {
left: 50%;
<style>
tone-trigger, tone-oscilloscope {
margin-bottom: 10px;
}
tone-oscilloscope {
background-color: black;
height: 60px;
width: 100%;
}
</style>
<div id="Content">
<div id="Title">Noise</div>
<div id="Explanation">
<a href="https://tonejs.github.io/docs/#Noise">Tone.Noise</a>
<tone-example>
<tone-explanation label="Noise">
<a href="https://tonejs.github.io/docs/Noise">Tone.Noise</a>
has 3 different types of noise. Careful, it's loud!
</div>
<div id="DragContainer"></div>
</div>
<script id="ToneCode">
</tone-explanation>
<tone-content>
<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
var noise = new Tone.Noise({
"volume" : -20,
"volume" : -10,
"type" : "brown"
}).toMaster();
// GUI //
Interface.Dragger({
tone : 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);
}
});
//bind the inteface
document.querySelector("tone-oscilloscope").bind(noise);
document.querySelector("tone-trigger").bind(noise);
document.querySelector("tone-noise").bind(noise);
</script>
</body>
</html>

View file

@ -4,44 +4,38 @@
<meta charset="utf-8">
<title>Offline</title>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
<link rel="icon" type="image/png" sizes="174x174" href="./style/favicon.png">
<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="./scripts/jquery.min.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>
<script src="./js/tonejs-ui.js"></script>
<style type="text/css">
.Button:not(.Visible) {
display: none;
tone-button {
margin-bottom: 10px;
}
</style>
</head>
<body>
<div id="Content">
<div id="Title">Offline</div>
<div id="Explanation">
<tone-example>
<tone-loader></tone-loader>
<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.
<br><br>
<a href="https://tonejs.github.io/docs/#Tone.Offline">Tone.Offline</a> docs.
</div>
</div>
<script>
<a href="https://tonejs.github.io/docs/Tone#offline">Tone.Offline</a> docs.
</tone-explanation>
<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
var buffer = new Tone.Buffer("./audio/IRs/chorus-feedback.wav");
Interface.Loader();
function generateAudioOffline(){
return Tone.Offline(function(Transport){
@ -60,7 +54,7 @@
}
}).connect(pannerA);
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);
seqA.loop = false;
@ -76,7 +70,7 @@
}
}).connect(pannerB);
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");
seqB.loop = false;
@ -86,48 +80,31 @@
"decay" : 3,
"sustain" : 0.1
},
}).toMaster()
}).toMaster();
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);
bassSeq.loop = false;
Transport.bpm.value = 150;
Transport.start();
}, 7).then(function(buffer){
//set the buffer once it's rendered
player.buffer = buffer;
});
}, 7);
}
//play the buffer with a Tone.Player when it's been generated
var player = new Tone.Player().toMaster();
// GUI //
var playButton = Interface.Button({
text : "Play",
activeText : "Stop",
type : "toggle",
start : function(){
player.start();
},
end : function(){
player.stop();
}
//bind the interface
document.querySelector("tone-button").addEventListener("click", e => {
e.target.setAttribute("label", "Rendering...");
e.target.setAttribute("disabled", "");
var buffer = generateAudioOffline().then(buffer => {
document.querySelector("tone-button").setAttribute("label", "Rendered");
player.buffer = buffer;
document.querySelector("tone-play-toggle").removeAttribute("disabled");
});
//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");
});
}
});
renderButton.element.addClass("Visible");
document.querySelector("tone-play-toggle").bind(player);
</script>
</body>

View file

@ -4,63 +4,44 @@
<meta charset="utf-8">
<title>Oscillator</title>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
<link rel="icon" type="image/png" sizes="174x174" href="./style/favicon.png">
<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="./scripts/jquery.min.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>
<script src="./js/tonejs-ui.js"></script>
<style type="text/css">
tone-play-toggle {
margin-bottom: 10px;
}
</style>
</head>
<body>
<div id="Content">
<div id="Title">Oscillator</div>
<div id="Explanation">
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.
<tone-example>
<tone-explanation label="Oscillator">
The oscillator has 4 basic types which can be altered by setting the number
of partials and partials array.
<br><br>
<a href="https://tonejs.github.io/docs/#Oscillator">Tone.Oscillator</a> docs.
</div>
<div id="DragContainer"></div>
</div>
<script id="ToneCode">
<a href="https://tonejs.github.io/docs/Oscillator">Tone.Oscillator</a> docs.
</tone-explanation>
<tone-content>
<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({
"type" : "square",
"frequency" : 440,
"volume" : -10
"volume" : -16
}).toMaster();
// GUI //
Interface.Dragger({
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);
}
});
//bind the interface
document.querySelector("tone-oscillator").bind(osc);
document.querySelector("tone-play-toggle").bind(osc);
</script>
</body>
</html>

View file

@ -4,51 +4,46 @@
<meta charset="utf-8">
<title>Phasing</title>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
<link rel="icon" type="image/png" sizes="174x174" href="./style/favicon.png">
<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="./scripts/jquery.min.js"></script>
<script src="./scripts/draggabilly.js"></script>
<script src="https://tonejs.github.io/Logo/build/Logo.js"></script>
<script src="./scripts/StartAudioContext.js"></script>
<script src="./scripts/Interface.js"></script>
<link rel="stylesheet" type="text/css" href="./style/examples.css">
<script>
// jshint ignore: start
</script>
<script src="./js/tonejs-ui.js"></script>
</head>
<body>
<style type="text/css">
#Left, #Right {
height: 200px;
width: 50%;
position: relative;
float: left;
margin-top: 5px;
margin-bottom: 5px;
#loop {
margin-bottom: 10px;
display: flex;
background-color: #777;
border-radius: 20px;
padding: 10px;
}
.Button {
display: inline-block;
tone-loop {
flex-grow: 1;
width: 40%;
height: 150px;
}
</style>
<div id="Content">
<div id="Title">Piano Phase</div>
<div id="Explanation">
<tone-example>
<tone-explanation label="Piano Phase">
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.
<br><br>
Composition by Steve Reich. Inspiration from Alexander Chen.
</div>
<canvas id="Left"></canvas>
<canvas id="Right"></canvas>
</div>
</tone-explanation>
<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
Tone.Transport.timeSignature = [6, 4];
Tone.Transport.bpm.value = 180;
@ -99,7 +94,10 @@
//set the playback rate of the right part to be slightly slower
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({
key : 32,
@ -167,7 +165,7 @@
rightContext.stroke();
rightContext.restore();
}
loop();
loop();*/
</script>
</body>

View file

@ -2,34 +2,43 @@
<html>
<head>
<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">
<link rel="icon" type="image/png" sizes="174x174" href="./style/favicon.png">
<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="./scripts/jquery.min.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>
<script src="./js/tonejs-ui.js"></script>
<style type="text/css">
tone-trigger, tone-meter {
margin-bottom: 10px;
}
tone-meter {
background-color: black;
height: 100px;
width: 100%;
}
</style>
</head>
<body>
<div id="Content">
<div id="Title">Ping Pong Delay</div>
<div id="Explanation">
<tone-example>
<tone-loader></tone-loader>
<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.
<br><br>
<a href="https://tonejs.github.io/docs/#PingPongDelay">Tone.PingPongDelay</a> docs.
</div>
</div>
<script>
<a href="https://tonejs.github.io/docs/PingPongDelay">Tone.PingPongDelay</a> docs.
</tone-explanation>
<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
var feedbackDelay = new Tone.PingPongDelay({
"delayTime" : "8n",
@ -40,14 +49,10 @@
//play a snare sound through it
var player = new Tone.Player("./audio/505/snare.[mp3|ogg]").connect(feedbackDelay);
Interface.Loader();
Interface.Button({
text : "trigger",
start : function(){
player.start();
},
});
//bind the interface
document.querySelector("tone-trigger").bind(player);
document.querySelector("tone-ping-pong-delay").bind(feedbackDelay);
document.querySelector("tone-meter").bind(feedbackDelay);
</script>
</body>
</html>

View file

@ -2,55 +2,47 @@
<html>
<head>
<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">
<link rel="icon" type="image/png" sizes="174x174" href="./style/favicon.png">
<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="./scripts/jquery.min.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>
<script src="./js/tonejs-ui.js"></script>
<style type="text/css">
tone-play-toggle {
margin-bottom: 10px;
}
</style>
</head>
<body>
<div id="Content">
<div id="Title">Grains</div>
<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-example>
<tone-loader></tone-loader>
<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
var player = new Tone.Player({
"url" : "./audio/FWDL.[mp3|ogg]",
"loop" : true
"loop" : true,
"loopStart" : 0.5,
"loopEnd" : 0.7,
}).toMaster();
// GUI //
Interface.Loader();
Interface.Button({
text : "Start",
activeText : "Stop",
start : function(){
player.start();
},
end : function(){
player.stop();
}
});
//bind the interface
document.querySelector("tone-player").bind(player);
document.querySelector("tone-play-toggle").bind(player);
</script>
</body>

View file

@ -4,59 +4,45 @@
<meta charset="utf-8">
<title>PolySynth</title>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
<link rel="icon" type="image/png" sizes="174x174" href="./style/favicon.png">
<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="./scripts/jquery.min.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>
<script src="./js/tonejs-ui.js"></script>
</head>
<body>
<div id="Content" class="FullScreen">
<div id="Title">PolySynth</div>
<div id="Explanation">
<a href="https://tonejs.github.io/docs/#PolySynth">Tone.PolySynth</a>
handles voice creation and allocation for any
<style>
tone-piano {
margin-bottom: 10px;
}
</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
not a synthesizer by itself, it merely manages voices of
one of the other types of synths, allowing any of the
monophonic synthesizers to be polyphonic.
</div>
<div id="Keyboard"></div>
</div>
</tone-explanation>
<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" : {
"partials" : [0, 2, 3, 4],
}
}).toMaster();
// GUI //
var keyboard = Interface.Keyboard();
keyboard.keyDown = function (note) {
synth.triggerAttack(note);
};
keyboard.keyUp = function (note) {
synth.triggerRelease(note);
};
//bind the interface
document.querySelector("tone-piano").bind(synth);
document.querySelector("tone-synth").bind(synth);
</script>
</body>
</html>

View file

@ -2,79 +2,76 @@
<html>
<head>
<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">
<link rel="icon" type="image/png" sizes="174x174" href="./style/favicon.png">
<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="./scripts/jquery.min.js"></script>
<script src="./scripts/draggabilly.js"></script>
<script src="https://tonejs.github.io/Logo/build/Logo.js"></script>
<script src="./scripts/StartAudioContext.js"></script>
<script src="./scripts/Interface.js"></script>
<link rel="stylesheet" type="text/css" href="./style/examples.css">
<script>
// jshint ignore: start
</script>
<script src="./js/tonejs-ui.js"></script>
</head>
<body>
<style type="text/css">
.Button {
width: calc(50% - 4px)!important;
float: left;
margin: 2px;
<style>
#buttons {
display: flex;
margin: 10px 0;
}
#buttons tone-button {
flex-grow: 1;
margin: 5px;
}
</style>
<div id="Content" class="FullScreen">
<div id="Title">Quantization</div>
<div id="Explanation">
<tone-example>
<tone-explanation label="Quantization">
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>
(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>
<script id="JSCode">
</tone-content>
<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();
Tone.Transport.start();
// GUI //
Interface.Transport();
Interface.Button({
type : "moment",
text : "@1m",
start : function(){
polySynth.triggerAttackRelease("C2", "8n", "@1m", 2);
},
//bind the interface
document.querySelector("tone-transport").bind(Tone.Transport);
document.querySelector("tone-transport").addEventListener("play", e => {
//enable all of the buttons if it's playing
Array.from(document.querySelectorAll("tone-button")).forEach(el => {
if (e.detail){
el.removeAttribute("disabled");
} else {
el.setAttribute("disabled", "");
}
});
Interface.Button({
type : "moment",
text : "@2n",
start : function(){
polySynth.triggerAttackRelease("G3", "8n", "@2n");
},
});
Interface.Button({
type : "moment",
text : "@4n",
start : function(){
polySynth.triggerAttackRelease("E4", "8n", "@4n");
},
});
Interface.Button({
type : "moment",
text : "@8n",
start : function(){
document.querySelector("#at8n").addEventListener("click", e => {
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>
</body>

View file

@ -2,46 +2,38 @@
<html>
<head>
<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">
<link rel="icon" type="image/png" sizes="174x174" href="./style/favicon.png">
<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="./scripts/jquery.min.js"></script>
<script src="./scripts/draggabilly.js"></script>
<script src="https://tonejs.github.io/Logo/build/Logo.js"></script>
<script src="./scripts/StartAudioContext.js"></script>
<script src="./scripts/Interface.js"></script>
<link rel="stylesheet" type="text/css" href="./style/examples.css">
<script>
// jshint ignore: start
</script>
<script src="./js/tonejs-ui.js"></script>
</head>
<body>
<style type="text/css">
canvas {
margin-top: 3px;
<style>
tone-slider {
width: 100%;
margin-top: 10px;
}
</style>
<div id="Content" class="FullScreen">
<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>.
<tone-example>
<tone-explanation label="rampTo">
Working with signals is different than working with numbers or strings:
Signals are values which are updated at audio rate,
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.
This example uses <code>.rampTo</code> in to smooth out changes in volume and frequency.
</div>
</div>
</tone-explanation>
<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 bassFreq = 32;
@ -52,37 +44,26 @@
"type" : "sawtooth10",
"volume" : -Infinity,
"detune" : Math.random() * 30 - 15,
}).start().toMaster());
}).toMaster());
}
Interface.Slider({
name : "harmony",
min : 0.5,
max : 2,
value : 1,
drag : function(value){
oscillators.forEach(function(osc, i){
osc.frequency.rampTo(bassFreq * i * value, 0.4);
//bind the interface
document.querySelector("tone-play-toggle").addEventListener("play", e => {
oscillators.forEach(o => {
if (e.detail){
o.start();
o.volume.rampTo(0, 1);
} else {
o.stop("+1.2");
o.volume.rampTo(-Infinity, 1);
}
});
},
});
Interface.Button({
text : "Unmute",
activeText : "Mute",
type : "toggle",
key : 32, //spacebar
start : function(){
oscillators.forEach(function(osc){
osc.volume.rampTo(-20, 1);
document.querySelector("tone-slider").addEventListener("change", e => {
oscillators.forEach((osc, i) => {
osc.frequency.rampTo(bassFreq * i * e.detail, 0.4);
});
},
end : function(){
oscillators.forEach(function(osc){
osc.volume.rampTo(-Infinity, 1);
});
},
});
</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">
<title>Reverb</title>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
<link rel="icon" type="image/png" sizes="174x174" href="./style/favicon.png">
<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="./scripts/jquery.min.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>
<script src="./js/tonejs-ui.js"></script>
</head>
<body>
<div id="Content">
<div id="Title">Reverb</div>
<div id="Explanation">
<a href="https://tonejs.github.io/docs/#Reverb">Tone.Reverb</a>
<style>
tone-play-toggle {
margin-bottom: 10px;
}
</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
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
will need to be generated.
<br><br>
Note: because of restrictions on iOS, 'generate' must be called from an explicit user action like a tap or click.
</div>
</div>
</tone-explanation>
<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();
reverb.generate().then(() => {
document.querySelector("tone-play-toggle").removeAttribute("disabled");
});
var player = new Tone.Player({
"url" : "./audio/FWDL.[mp3|ogg]",
"loop" : true
}).connect(reverb);
// GUI //
Interface.Loader();
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();
}
});
//bind the interface
document.querySelector("tone-play-toggle").bind(player);
document.querySelector("tone-reverb").bind(reverb);
</script>
</body>

View file

@ -4,98 +4,72 @@
<meta charset="utf-8">
<title>Sampler</title>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
<link rel="icon" type="image/png" sizes="174x174" href="./style/favicon.png">
<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="./scripts/jquery.min.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>
<script src="./js/tonejs-ui.js"></script>
</head>
<body>
<style type="text/css">
img {
width: 80%;
max-width: 700px;
margin-left: auto;
margin-right: auto;
display: block;
}
#Keyboard {
margin: 3px!important;
<style>
tone-piano {
margin-bottom: 10px;
}
</style>
<div id="Content">
<div id="Title">Sampler</div>
<div id="Explanation">
<tone-example>
<tone-loader></tone-loader>
<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.
</div>
<div id="Keyboard"></div>
</div>
</tone-explanation>
<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({
'A0' : 'A0.[mp3|ogg]',
'C1' : 'C1.[mp3|ogg]',
'D#1' : 'Ds1.[mp3|ogg]',
'F#1' : 'Fs1.[mp3|ogg]',
'A1' : 'A1.[mp3|ogg]',
'C2' : 'C2.[mp3|ogg]',
'D#2' : 'Ds2.[mp3|ogg]',
'F#2' : 'Fs2.[mp3|ogg]',
'A2' : 'A2.[mp3|ogg]',
'C3' : 'C3.[mp3|ogg]',
'D#3' : 'Ds3.[mp3|ogg]',
'F#3' : 'Fs3.[mp3|ogg]',
'A3' : 'A3.[mp3|ogg]',
'C4' : 'C4.[mp3|ogg]',
'D#4' : 'Ds4.[mp3|ogg]',
'F#4' : 'Fs4.[mp3|ogg]',
'A4' : 'A4.[mp3|ogg]',
'C5' : 'C5.[mp3|ogg]',
'D#5' : 'Ds5.[mp3|ogg]',
'F#5' : 'Fs5.[mp3|ogg]',
'A5' : 'A5.[mp3|ogg]',
'C6' : 'C6.[mp3|ogg]',
'D#6' : 'Ds6.[mp3|ogg]',
'F#6' : 'Fs6.[mp3|ogg]',
'A6' : 'A6.[mp3|ogg]',
'C7' : 'C7.[mp3|ogg]',
'D#7' : 'Ds7.[mp3|ogg]',
'F#7' : 'Fs7.[mp3|ogg]',
'A7' : 'A7.[mp3|ogg]',
'C8' : 'C8.[mp3|ogg]'
"A0" : "A0.[mp3|ogg]",
"C1" : "C1.[mp3|ogg]",
"D#1" : "Ds1.[mp3|ogg]",
"F#1" : "Fs1.[mp3|ogg]",
"A1" : "A1.[mp3|ogg]",
"C2" : "C2.[mp3|ogg]",
"D#2" : "Ds2.[mp3|ogg]",
"F#2" : "Fs2.[mp3|ogg]",
"A2" : "A2.[mp3|ogg]",
"C3" : "C3.[mp3|ogg]",
"D#3" : "Ds3.[mp3|ogg]",
"F#3" : "Fs3.[mp3|ogg]",
"A3" : "A3.[mp3|ogg]",
"C4" : "C4.[mp3|ogg]",
"D#4" : "Ds4.[mp3|ogg]",
"F#4" : "Fs4.[mp3|ogg]",
"A4" : "A4.[mp3|ogg]",
"C5" : "C5.[mp3|ogg]",
"D#5" : "Ds5.[mp3|ogg]",
"F#5" : "Fs5.[mp3|ogg]",
"A5" : "A5.[mp3|ogg]",
"C6" : "C6.[mp3|ogg]",
"D#6" : "Ds6.[mp3|ogg]",
"F#6" : "Fs6.[mp3|ogg]",
"A6" : "A6.[mp3|ogg]",
"C7" : "C7.[mp3|ogg]",
"D#7" : "Ds7.[mp3|ogg]",
"F#7" : "Fs7.[mp3|ogg]",
"A7" : "A7.[mp3|ogg]",
"C8" : "C8.[mp3|ogg]"
}, {
'release' : 1,
'baseUrl' : './audio/salamander/'
"release" : 1,
"baseUrl" : "./audio/salamander/"
}).toMaster();
// GUI //
var keyboard = Interface.Keyboard();
keyboard.keyDown = function (note) {
piano.triggerAttack(note);
};
keyboard.keyUp = function (note) {
piano.triggerRelease(note);
};
Interface.Loader();
//bind the interface
document.querySelector("tone-piano").bind(piano);
document.querySelector("tone-sampler").bind(piano);
</script>
</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>
<head>
<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">
<link rel="icon" type="image/png" sizes="174x174" href="./style/favicon.png">
<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="./scripts/jquery.min.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/nexusUI.js"></script>
<link rel="stylesheet" type="text/css" href="./style/examples.css">
<script>
// jshint ignore: start
</script>
<script src="./js/tonejs-ui.js"></script>
<style type="text/css">
tone-play-toggle {
margin-bottom: 10px;
}
tone-slider {
display: block;
width: 100%;
}
</style>
</head>
<body>
<div id="Content">
<div id="Title">Play Along</div>
<div id="Explanation">
<tone-example>
<tone-loader></tone-loader>
<tone-explanation label="Play Along">
Touch/Mouse and drag to play along with the probabilistic backtrack. X = pitch, Y = modulation.
</div>
</div>
</tone-explanation>
<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({
"threshold" : -30,
"ratio" : 6,
@ -51,7 +62,6 @@
var hats = new Tone.Player({
"url" : "./audio/505/hh.[mp3|ogg]",
"volume" : -10,
"retrigger" : true,
"fadeOut" : 0.05
}).chain(distortion, drumCompress);
@ -66,7 +76,6 @@
//SNARE PART
var snare = new Tone.Player({
"url" : "./audio/505/snare.[mp3|ogg]",
"retrigger" : true,
"fadeOut" : 0.1
}).chain(distortion, drumCompress);
@ -122,7 +131,6 @@
}
}).toMaster();
var bassPart = new Tone.Part(function(time, event){
if (Math.random() < event.prob){
bass.triggerAttackRelease(event.note, event.dur, time);
@ -204,49 +212,30 @@
Tone.Transport.bpm.value = 125;
// GUI //
Interface.Button({
key : 32,
type : "toggle",
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){
//bind the interface
document.querySelector("tone-play-toggle").bind(Tone.Transport);
document.querySelector("tone-slider-2d").addEventListener("change", e => {
//use the x and y values to set the note and vibrato
const note = synthNotes[Math.round(e.detail.x * (synthNotes.length-1))];
synth.setNote(note);
lastSynthNote = note;
}
},
y : {
min : 0,
max : 2,
drag : function(val){
synth.vibratoAmount.value = val;
}
},
start : function(){
synth.triggerAttack(lastSynthNote);
},
end : function(){
synth.triggerRelease();
},
name : "Synth"
synth.vibratoAmount.value = e.detail.y * 3;
});
Interface.Loader();
document.querySelector("tone-slider-2d").addEventListener("mousedown", e => {
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>
</body>
</html>

View file

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

View file

@ -4,52 +4,34 @@
<meta charset="utf-8">
<title>Synth</title>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
<link rel="icon" type="image/png" sizes="174x174" href="./style/favicon.png">
<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="./scripts/jquery.min.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>
<script src="./js/tonejs-ui.js"></script>
</head>
<body>
<style type="text/css">
img {
width: 80%;
max-width: 700px;
margin-left: auto;
margin-right: auto;
display: block;
}
#Keyboard {
margin: 3px!important;
<style>
tone-piano {
margin-bottom: 10px;
}
</style>
<div id="Content">
<div id="Title">Synth</div>
<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/#OmniOscillator" target="_blank">Tone.OmniOscillator</a>
<tone-example>
<tone-explanation label="Synth">
<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>
routed through a
<a href="https://tonejs.github.io/docs/#AmplitudeEnvelope" target="_blank">Tone.AmplitudeEnvelope</a>.
</div>
<div id="Keyboard"></div>
</div>
<a href="https://tonejs.github.io/docs/AmplitudeEnvelope" target="_blank">Tone.AmplitudeEnvelope</a>.
</tone-explanation>
<script>
<tone-content>
<tone-piano></tone-piano>
<tone-synth></tone-synth>
</tone-content>
</tone-example>
<script type="text/javascript">
var synth = new Tone.Synth({
"oscillator" : {
"type" : "amtriangle",
@ -57,7 +39,7 @@
"modulationType" : "sine"
},
"envelope" : {
"attackCurve" : 'exponential',
"attackCurve" : "exponential",
"attack" : 0.05,
"decay" : 0.2,
"sustain" : 0.2,
@ -66,18 +48,10 @@
"portamento" : 0.05
}).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>
</body>
</html>

View file

@ -2,47 +2,46 @@
<html>
<head>
<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">
<link rel="icon" type="image/png" sizes="174x174" href="./style/favicon.png">
<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="./scripts/three.min.js"></script>
<script src="./scripts/OrbitControls.js"></script>
<script src="./scripts/WebGLDetector.js"></script>
<script src="./scripts/THREE.Tone.js"></script>
<script src="./scripts/jquery.min.js"></script>
<script src="./scripts/draggabilly.js"></script>
<script src="https://tonejs.github.io/Logo/build/Logo.js"></script>
<script src="./scripts/StartAudioContext.js"></script>
<script src="./scripts/Interface.js"></script>
<script src="./js/tonejs-ui.js"></script>
<script src="./js/three.min.js"></script>
<script src="./js/OrbitControls.js"></script>
<script src="./js/WebGLDetector.js"></script>
<script src="./js/THREE.Tone.js"></script>
<link rel="stylesheet" type="text/css" href="./style/examples.css">
<script>
// jshint ignore: start
</script>
</head>
<body>
<style type="text/css">
tone-play-toggle {
margin-bottom: 10px;
}
#three {
width: 100%;
height: 400px;
}
</style>
<div id="Content">
<div id="Title">Panner3D</div>
<div id="Explanation">
</head>
<body>
<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.
</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>
<script>
</tone-content>
</tone-example>
<script type="text/javascript">
var greenSphere = new Tone.Panner3D().toMaster();
var drone = new Tone.Player({
url : "./audio/loop/drone.[mp3|ogg]",
@ -61,23 +60,8 @@
loop : true,
}).connect(whiteSphere).sync().start(0);
</script>
<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();
}
});
//bind the interface
document.querySelector("tone-play-toggle").bind(Tone.Transport);
// THREE.JS //
@ -87,17 +71,19 @@
var SCREEN_HEIGHT = document.querySelector("#three").clientHeight;
var aspect = SCREEN_WIDTH / SCREEN_HEIGHT;
var scene = new THREE.Scene()
console.log(SCREEN_WIDTH, SCREEN_HEIGHT, aspect);
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(50, aspect, 1, 10000);
camera.position.z = 1;
camera.updateMatrixWorld()
camera.updateMatrixWorld();
var bassMesh = new THREE.Mesh(
new THREE.SphereBufferGeometry(2, 16, 8),
new THREE.MeshBasicMaterial({ color : 0xffffff, wireframe : true })
);
scene.add(bassMesh);
bassMesh.position.z = -10
bassMesh.position.z = -10;
var dronMesh = new THREE.Mesh(
new THREE.SphereBufferGeometry(1, 16, 8),
@ -120,7 +106,7 @@
controls = new THREE.OrbitControls(camera, renderer.domElement);
controls.addEventListener("change", function(){
Tone.Listener.updatePosition(camera);
})
});
//set the camer initially
Tone.Listener.updatePosition(camera);
@ -151,7 +137,7 @@
whiteSphere.updatePosition(chordMesh);
}
animate()
animate();
}
</script>

View file

@ -2,41 +2,37 @@
<html>
<head>
<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">
<link rel="icon" type="image/png" sizes="174x174" href="./style/favicon.png">
<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="./scripts/jquery.min.js"></script>
<script src="./scripts/draggabilly.js"></script>
<script src="https://tonejs.github.io/Logo/build/Logo.js"></script>
<script src="./scripts/StartAudioContext.js"></script>
<script src="./scripts/Interface.js"></script>
<script src="./scripts/nexusUI.js"></script>
<link rel="stylesheet" type="text/css" href="./style/examples.css">
<script>
// jshint ignore: start
</script>
</head>
<body>
<script src="./js/tonejs-ui.js"></script>
<script src="./js/tonejs-ui.js"></script>
<style type="text/css">
canvas {
margin-top: 3px;
tone-transport {
margin-bottom: 10px;
}
</style>
<div id="Content">
<div id="Title">Tone.Transport</div>
<div id="Explanation">
<a href="https://tonejs.github.io/docs/#Transport">Tone.Transport</a>
</head>
<body>
<tone-example>
<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.
</div>
<canvas nx="matrix"></canvas>
</div>
<script>
</tone-explanation>
<tone-content>
<tone-transport></tone-transport>
<tone-step-sequencer></tone-step-sequencer>
</tone-content>
</tone-example>
<script type="text/javascript">
//setup a polyphonic sampler
var keys = new Tone.Players({
"A" : "./audio/casio/A1.[mp3|ogg]",
@ -52,57 +48,27 @@
var noteNames = ["F#", "E", "C#", "A"];
var loop = new Tone.Sequence(function(time, col){
var column = matrix1.matrix[col];
for (var i = 0; i < 4; i++){
if (column[i] === 1){
var column = document.querySelector("tone-step-sequencer").currentColumn;
column.forEach(function(val, i){
if (val){
//slightly randomized velocities
var vel = Math.random() * 0.5 + 0.5;
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({
text : "Start",
activeText : "Stop",
type : "toggle",
key : 32, //spacebar
start : function(){
loop.start();
},
end : function(){
loop.stop();
},
});
//bind the interface
document.querySelector("tone-transport").bind(Tone.Transport);
Interface.Loader();
$(window).on("resize", function(){
matrix1.resize($("#Content").width(), 250);
matrix1.draw();
Tone.Transport.on("stop", () => {
setTimeout(() => {
document.querySelector("tone-step-sequencer").setAttribute("highlight", "-1");
}, 100);
});
</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;
}