mirror of
https://github.com/Tonejs/Tone.js
synced 2024-12-26 11:33:09 +00:00
updated examples with new interfaces
This commit is contained in:
parent
b4b56f213e
commit
c21e5758d8
53 changed files with 4672 additions and 13882 deletions
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
BIN
examples/audio/loop/drum_loop.png
Normal file
BIN
examples/audio/loop/drum_loop.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 227 KiB |
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
Before Width: | Height: | Size: 6.8 KiB After Width: | Height: | Size: 6.8 KiB |
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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
3120
examples/js/tonejs-ui.js
Normal file
File diff suppressed because one or more lines are too long
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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
|
@ -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
4
examples/scripts/jquery.min.js
vendored
4
examples/scripts/jquery.min.js
vendored
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load diff
|
@ -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);
|
||||
}());
|
|
@ -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);
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
|
@ -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>
|
||||
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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; }
|
|
@ -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;
|
||||
}
|
Loading…
Reference in a new issue