mirror of
https://github.com/Tonejs/Tone.js
synced 2024-11-16 08:38:00 +00:00
moved files. added requires support. added Panner
This commit is contained in:
parent
0055cc683f
commit
a9a84fc07c
30 changed files with 740 additions and 1020 deletions
|
@ -6,14 +6,20 @@
|
|||
|
||||
<script src="http://code.jquery.com/jquery-2.1.0.min.js"></script>
|
||||
<!--
|
||||
<script type="text/javascript" src="../deps/require.js"></script>
|
||||
-->
|
||||
<script type="text/javascript" src='../Tone.js'></script>
|
||||
-->
|
||||
<script type="text/javascript" src="../deps/require.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<script type="text/javascript">
|
||||
|
||||
require.config({
|
||||
baseUrl : "../src"
|
||||
});
|
||||
|
||||
require(["core/Tone"], function(Tone){
|
||||
console.log(Tone);
|
||||
});
|
||||
|
||||
</script>
|
||||
</body>
|
||||
|
|
60
examples/mergeSplit.html
Normal file
60
examples/mergeSplit.html
Normal file
|
@ -0,0 +1,60 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>MERGE/SPLIT</title>
|
||||
|
||||
<script src="http://code.jquery.com/jquery-2.1.0.min.js"></script>
|
||||
<script type="text/javascript" src="../deps/require.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<style type="text/css">
|
||||
|
||||
</style>
|
||||
<div id='mono'>0</div>
|
||||
<div id='left'>0</div>
|
||||
<div id='right'>0</div>
|
||||
<script type="text/javascript">
|
||||
require.config({
|
||||
baseUrl : "../src"
|
||||
});
|
||||
|
||||
|
||||
require(["core/Tone", "signal/Signal", 'signal/Merge', "signal/Split", "component/Meter"],
|
||||
|
||||
function(Tone){
|
||||
|
||||
//two signals into one (stereo) channel
|
||||
var left = new Tone.Signal(-100);
|
||||
var right = new Tone.Signal(75);
|
||||
var mergeMeter = new Tone.Meter();
|
||||
var merge = new Tone.Merge();
|
||||
|
||||
//connect it up
|
||||
left.connect(merge.left);
|
||||
right.connect(merge.right);
|
||||
merge.connect(mergeMeter);
|
||||
|
||||
//one (stereo) signal split into two channels
|
||||
var split = new Tone.Split();
|
||||
merge.connect(split);
|
||||
var rightMeter = new Tone.Meter();
|
||||
var leftmeter = new Tone.Meter();
|
||||
|
||||
split.right.connect(rightMeter);
|
||||
split.left.connect(leftmeter);
|
||||
|
||||
|
||||
var $mono = $("#mono");
|
||||
var $left = $("#left");
|
||||
var $right = $("#right");
|
||||
|
||||
setInterval(function(){
|
||||
$mono.html("merged: " + mergeMeter.getValue(0).toFixed(3));
|
||||
$left.html("left: " + rightMeter.getValue(0).toFixed(3));
|
||||
$right.html("right: " + leftmeter.getValue(0).toFixed(3));
|
||||
}, 100);
|
||||
});
|
||||
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -1,21 +1,9 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>SIGNAL PROCESSING</title>
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="../style/GUI.css">
|
||||
<title>PANNER</title>
|
||||
|
||||
<script src="http://code.jquery.com/jquery-2.1.0.min.js"></script>
|
||||
<script type="text/javascript" src="../src/core/Tone.js"></script>
|
||||
<script type="text/javascript" src="../src/signal/Signal.js"></script>
|
||||
<script type="text/javascript" src="../src/signal/Scale.js"></script>
|
||||
<script type="text/javascript" src="../src/signal/Invert.js"></script>
|
||||
<script type="text/javascript" src="../src/signal/Mono.js"></script>
|
||||
<script type="text/javascript" src="../src/signal/Stereo.js"></script>
|
||||
<script type="text/javascript" src="../src/component/DryWet.js"></script>
|
||||
<script type="text/javascript" src="../src/component/Panner.js"></script>
|
||||
|
||||
<script type="text/javascript" src="../src/component/Meter.js"></script>
|
||||
<script type="text/javascript" src="../src/component/LFO.js"></script>
|
||||
<script type="text/javascript" src="../deps/require.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<style type="text/css">
|
||||
|
@ -25,40 +13,47 @@
|
|||
<div id='left'>0</div>
|
||||
<div id='right'>0</div>
|
||||
<script type="text/javascript">
|
||||
require.config({
|
||||
baseUrl : "../src"
|
||||
});
|
||||
require(["core/Tone", "core/Master", "component/Panner", "component/Meter"],
|
||||
function(Tone){
|
||||
|
||||
//panner
|
||||
var pan = new Tone.Panner();
|
||||
//panner
|
||||
var pan = new Tone.Panner();
|
||||
|
||||
//input signals
|
||||
var sine = Tone.context.createOscillator();
|
||||
sine.start(0);
|
||||
//input signals
|
||||
var sine = Tone.context.createOscillator();
|
||||
sine.start(0);
|
||||
// var sine = new Tone.Signal(100);
|
||||
|
||||
//connect it up
|
||||
sine.connect(pan);
|
||||
//connect it up
|
||||
sine.connect(pan);
|
||||
|
||||
pan.toMaster();
|
||||
pan.toMaster();
|
||||
|
||||
//meters
|
||||
var output = new Tone.Meter(2);
|
||||
//meters
|
||||
var output = new Tone.Meter(2);
|
||||
|
||||
//meter the outputs
|
||||
pan.connect(output);
|
||||
//meter the outputs
|
||||
pan.connect(output);
|
||||
|
||||
|
||||
var $left = $("#left");
|
||||
var $right = $("#right");
|
||||
|
||||
setInterval(function(){
|
||||
$left.html("left: " + output.getDb(0).toFixed(2) + " db");
|
||||
$right.html("right: " + output.getDb(1).toFixed(2) + " db");
|
||||
}, 100);
|
||||
var $left = $("#left");
|
||||
var $right = $("#right");
|
||||
|
||||
setInterval(function(){
|
||||
$left.html("left: " + output.getDb(0).toFixed(2) + " db");
|
||||
$right.html("right: " + output.getDb(1).toFixed(2) + " db");
|
||||
}, 100);
|
||||
|
||||
var range = $("input")[0];
|
||||
range.onchange = function(){
|
||||
var val = range.value;
|
||||
var now = pan.now();
|
||||
pan.setPan(val/50 - 1);
|
||||
}
|
||||
var range = $("input")[0];
|
||||
range.onchange = function(){
|
||||
var val = range.value;
|
||||
var now = pan.now();
|
||||
pan.setPan(val/50 - 1, now+.1);
|
||||
}
|
||||
});
|
||||
|
||||
</script>
|
||||
</body>
|
||||
|
|
|
@ -2,17 +2,8 @@
|
|||
<head>
|
||||
<title>SIGNAL PROCESSING</title>
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="../style/GUI.css">
|
||||
|
||||
<script src="http://code.jquery.com/jquery-2.1.0.min.js"></script>
|
||||
<script type="text/javascript" src="../src/core/Tone.js"></script>
|
||||
<script type="text/javascript" src="../src/signal/Signal.js"></script>
|
||||
<script type="text/javascript" src="../src/signal/Add.js"></script>
|
||||
<script type="text/javascript" src="../src/signal/Invert.js"></script>
|
||||
<script type="text/javascript" src="../src/signal/Normalize.js"></script>
|
||||
<script type="text/javascript" src="../src/signal/Scale.js"></script>
|
||||
|
||||
<script type="text/javascript" src="../src/component/Meter.js"></script>
|
||||
<script type="text/javascript" src="../deps/require.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<style type="text/css">
|
||||
|
@ -20,66 +11,66 @@
|
|||
</style>
|
||||
<input type='range' value='50'>
|
||||
<div id='signal'>0</div>
|
||||
<div id='invert'>0</div>
|
||||
<div id='add'>0</div>
|
||||
<div id='normalize'>0</div>
|
||||
<div id='sub'>0</div>
|
||||
<div id='scale'>0</div>
|
||||
<script type="text/javascript">
|
||||
var signal = new Tone.Signal();
|
||||
var dryMeter = new Tone.Meter();
|
||||
signal.connect(dryMeter);
|
||||
|
||||
//the inverter
|
||||
var inverter = new Tone.Invert();
|
||||
var invertMeter = new Tone.Meter();
|
||||
inverter.connect(invertMeter);
|
||||
signal.connect(inverter);
|
||||
|
||||
//the adder
|
||||
var adder = new Tone.Add(100);
|
||||
var addMeter = new Tone.Meter();
|
||||
adder.connect(addMeter);
|
||||
inverter.connect(adder);
|
||||
|
||||
//normalize back to -1 to 1
|
||||
var norm = new Tone.Normalize(99, 101);
|
||||
var normMeter = new Tone.Meter();
|
||||
norm.connect(normMeter);
|
||||
adder.connect(norm);
|
||||
|
||||
//the scaler
|
||||
var scaler = new Tone.Scale(5, 10);
|
||||
var scaleMeter = new Tone.Meter();
|
||||
scaler.connect(scaleMeter);
|
||||
norm.connect(scaler);
|
||||
require.config({
|
||||
baseUrl : "../src"
|
||||
});
|
||||
|
||||
|
||||
var $signal = $("#signal");
|
||||
var $invert = $("#invert");
|
||||
var $add = $("#add");
|
||||
var $norm = $("#normalize");
|
||||
var $scale = $("#scale");
|
||||
require(["core/Tone", "core/Master", "signal/Signal", "signal/Add", "signal/Scale", "component/Meter",
|
||||
"signal/Subtract"],
|
||||
function(Tone){
|
||||
var signal = new Tone.Signal();
|
||||
var dryMeter = new Tone.Meter();
|
||||
signal.connect(dryMeter);
|
||||
|
||||
setInterval(function(){
|
||||
$signal.html("signal: " + dryMeter.getValue().toFixed(3));
|
||||
$invert.html("inverted: " + invertMeter.getValue().toFixed(3));
|
||||
$add.html("add 100: " + addMeter.getValue().toFixed(3));
|
||||
$norm.html("normalized : "+normMeter.getValue().toFixed(3));
|
||||
$scale.html("scaled 5 to 10: " + scaleMeter.getValue().toFixed(3));
|
||||
/*$signal.html("signal: " + dryMeter.getValue());
|
||||
$invert.html("incoming: " + );
|
||||
$add.html("add 10: " + addMeter.getValue());*/
|
||||
}, 100);
|
||||
|
||||
//the adder
|
||||
var adder = new Tone.Add(100);
|
||||
var addMeter = new Tone.Meter();
|
||||
adder.connect(addMeter);
|
||||
signal.connect(adder);
|
||||
|
||||
var range = $("input")[0];
|
||||
range.onchange = function(){
|
||||
var val = range.value;
|
||||
var now = signal.now();
|
||||
signal.linearRampToValueAtTime(val / 50 - 1, now + .1);
|
||||
}
|
||||
//the adder
|
||||
var subtract = new Tone.Subtract(100);
|
||||
var subMeter = new Tone.Meter();
|
||||
subtract.connect(subMeter);
|
||||
signal.connect(subtract);
|
||||
|
||||
|
||||
//the scaler
|
||||
var scaler = new Tone.Scale(5, 10);
|
||||
var scaleMeter = new Tone.Meter();
|
||||
scaler.connect(scaleMeter);
|
||||
signal.connect(scaler);
|
||||
|
||||
|
||||
// signal.toMaster();
|
||||
var $signal = $("#signal");
|
||||
var $add = $("#add");
|
||||
var $scale = $("#scale");
|
||||
var $sub = $("#sub");
|
||||
|
||||
setInterval(function(){
|
||||
$signal.html("signal: " + dryMeter.getValue().toFixed(3));
|
||||
$add.html("signal + 100: " + addMeter.getValue().toFixed(3));
|
||||
$scale.html("scaled 5 to 10: " + scaleMeter.getValue().toFixed(3));
|
||||
$sub.html("100 - signal: " + subMeter.getValue().toFixed(3));
|
||||
}, 100);
|
||||
|
||||
var range = $("input")[0];
|
||||
range.onchange = function(){
|
||||
var val = range.value;
|
||||
var now = signal.now();
|
||||
signal.linearRampToValueAtTime(val / 50 - 1, now + .1);
|
||||
}
|
||||
|
||||
window.Tone = Tone;
|
||||
|
||||
});
|
||||
|
||||
|
||||
</script>
|
||||
</body>
|
||||
|
|
|
@ -8,61 +8,64 @@
|
|||
// 1 = 100% wet
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Tone.DryWet = function(initialDry){
|
||||
Tone.call(this);
|
||||
define(["core/Tone", "signal/Signal", "signal/Invert", "signal/Scale"], function(Tone){
|
||||
|
||||
//components
|
||||
this.dry = this.context.createGain();
|
||||
this.wet = this.context.createGain();
|
||||
this.output = this.context.createGain();
|
||||
this.equalGain = this.context.createWaveShaper();
|
||||
//control signal
|
||||
this.control = new Tone.Signal();
|
||||
this.invert = new Tone.Invert();
|
||||
this.dryScale = new Tone.Scale(0, 1);
|
||||
this.wetScale = new Tone.Scale(0, 1);
|
||||
Tone.DryWet = function(initialDry){
|
||||
Tone.call(this);
|
||||
|
||||
//alias
|
||||
this.input = this.dry;
|
||||
//components
|
||||
this.dry = this.context.createGain();
|
||||
this.wet = this.context.createGain();
|
||||
this.output = this.context.createGain();
|
||||
this.equalGain = this.context.createWaveShaper();
|
||||
//control signal
|
||||
this.control = new Tone.Signal();
|
||||
this.invert = new Tone.Invert();
|
||||
this.dryScale = new Tone.Scale(0, 1);
|
||||
this.wetScale = new Tone.Scale(0, 1);
|
||||
|
||||
//connections
|
||||
this.dry.connect(this.output);
|
||||
this.wet.connect(this.output);
|
||||
//control signal connections
|
||||
this.control.connect(this.equalGain);
|
||||
//wet chain
|
||||
this.chain(this.equalGain, this.wetScale, this.wet.gain);
|
||||
//dry chain
|
||||
this.chain(this.equalGain, this.invert, this.dryScale, this.dry.gain);
|
||||
|
||||
//setup
|
||||
this._equalPowerGainCurve();
|
||||
this.dry.gain.value = 0;
|
||||
this.wet.gain.value = 0;
|
||||
this.setDry(0);
|
||||
}
|
||||
//connections
|
||||
this.dry.connect(this.output);
|
||||
this.wet.connect(this.output);
|
||||
//control signal connections
|
||||
this.control.connect(this.equalGain);
|
||||
//wet chain
|
||||
this.chain(this.equalGain, this.wetScale, this.wet.gain);
|
||||
//dry chain
|
||||
this.chain(this.equalGain, this.invert, this.dryScale, this.dry.gain);
|
||||
|
||||
Tone.extend(Tone.DryWet);
|
||||
|
||||
Tone.DryWet.prototype.setDry = function(val, rampTime){
|
||||
rampTime = this.defaultArg(rampTime, 0);
|
||||
this.control.linearRampToValueAtTime(val, rampTime);
|
||||
}
|
||||
|
||||
Tone.DryWet.prototype.setWet = function(val, rampTime){
|
||||
this.setDry(-val, rampTime);
|
||||
}
|
||||
|
||||
//generates the values for the waveshaper
|
||||
Tone.DryWet.prototype._equalPowerGainCurve = function(){
|
||||
var len = this.bufferSize;
|
||||
var curve = new Float32Array(len);
|
||||
for (var i = 0; i < len; i++){
|
||||
//values between -1 to 1
|
||||
var baseline = (i / (len - 1)) * 2 - 1;
|
||||
// scale it by amount
|
||||
curve[i] = this.equalPowerGain(baseline);
|
||||
// curve[i] = baseline;
|
||||
//setup
|
||||
this._equalPowerGainCurve();
|
||||
this.dry.gain.value = 0;
|
||||
this.wet.gain.value = 0;
|
||||
this.setDry(0);
|
||||
}
|
||||
this.equalGain.curve = curve;
|
||||
}
|
||||
|
||||
Tone.extend(Tone.DryWet);
|
||||
|
||||
Tone.DryWet.prototype.setDry = function(val, rampTime){
|
||||
rampTime = this.defaultArg(rampTime, 0);
|
||||
this.control.linearRampToValueAtTime(val, rampTime);
|
||||
}
|
||||
|
||||
Tone.DryWet.prototype.setWet = function(val, rampTime){
|
||||
this.setDry(-val, rampTime);
|
||||
}
|
||||
|
||||
//generates the values for the waveshaper
|
||||
Tone.DryWet.prototype._equalPowerGainCurve = function(){
|
||||
var len = this.bufferSize;
|
||||
var curve = new Float32Array(len);
|
||||
for (var i = 0; i < len; i++){
|
||||
//values between -1 to 1
|
||||
var baseline = (i / (len - 1)) * 2 - 1;
|
||||
// scale it by amount
|
||||
curve[i] = this.equalPowerGain(baseline);
|
||||
// curve[i] = baseline;
|
||||
}
|
||||
this.equalGain.curve = curve;
|
||||
}
|
||||
|
||||
return Tone.DryWet;
|
||||
});
|
||||
|
|
|
@ -8,85 +8,91 @@
|
|||
// The MIT License (MIT) Copyright (c) 2014 Chris Wilson
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//@param {number=} channels
|
||||
Tone.Meter = function(channels){
|
||||
//extends Unit
|
||||
Tone.call(this);
|
||||
define(["core/Tone", "core/Master"], function(Tone){
|
||||
|
||||
this.channels = this.defaultArg(channels, 1);
|
||||
this.volume = new Array(this.channels);
|
||||
this.values = new Array(this.channels);
|
||||
//zero out the volume array
|
||||
for (var i = 0; i < this.channels; i++){
|
||||
this.volume[i] = 0;
|
||||
this.values[i] = 0;
|
||||
}
|
||||
this.clipTime = 0;
|
||||
|
||||
//components
|
||||
this.jsNode = this.context.createScriptProcessor(this.bufferSize, this.channels, this.channels);
|
||||
this.jsNode.onaudioprocess = this.onprocess.bind(this);
|
||||
//@param {number=} channels
|
||||
Tone.Meter = function(channels){
|
||||
//extends Unit
|
||||
Tone.call(this);
|
||||
|
||||
//signal just passes
|
||||
this.input.connect(this.output);
|
||||
this.input.connect(this.jsNode);
|
||||
this.toMaster(this.jsNode);
|
||||
}
|
||||
|
||||
Tone.extend(Tone.Meter, Tone);
|
||||
|
||||
|
||||
//@param {number=} channel
|
||||
//@returns {number}
|
||||
Tone.Meter.prototype.getLevel = function(channel){
|
||||
channel = this.defaultArg(channel, 0);
|
||||
var vol = this.volume[channel];
|
||||
if (vol < .00001){
|
||||
return 0;
|
||||
} else {
|
||||
return vol;
|
||||
}
|
||||
}
|
||||
|
||||
//@param {number=} channel
|
||||
//@returns {number}
|
||||
Tone.Meter.prototype.getValue = function(channel){
|
||||
channel = this.defaultArg(channel, 0);
|
||||
return this.values[channel];
|
||||
}
|
||||
|
||||
//@param {number=} channel
|
||||
//@returns {number} the channel volume in decibels
|
||||
Tone.Meter.prototype.getDb = function(channel){
|
||||
return this.gainToDb(this.getLevel(channel));
|
||||
}
|
||||
|
||||
// @returns {boolean} if the audio has clipped in the last 500ms
|
||||
Tone.Meter.prototype.isClipped = function(){
|
||||
return Date.now() - this.clipTime < 500;
|
||||
}
|
||||
|
||||
//get the max value
|
||||
Tone.Meter.prototype.onprocess = function(event){
|
||||
var bufferSize = this.jsNode.bufferSize;
|
||||
for (var channel = 0; channel < this.channels; channel++){
|
||||
var input = event.inputBuffer.getChannelData(channel);
|
||||
var sum = 0;
|
||||
var total = 0;
|
||||
var x;
|
||||
var clipped = false;
|
||||
for (var i = 0; i < bufferSize; i++){
|
||||
x = input[i];
|
||||
if (!clipped && x > .95){
|
||||
clipped = true;
|
||||
this.clipTime = Date.now();
|
||||
}
|
||||
total += x;
|
||||
sum += x * x;
|
||||
this.channels = this.defaultArg(channels, 1);
|
||||
this.volume = new Array(this.channels);
|
||||
this.values = new Array(this.channels);
|
||||
//zero out the volume array
|
||||
for (var i = 0; i < this.channels; i++){
|
||||
this.volume[i] = 0;
|
||||
this.values[i] = 0;
|
||||
}
|
||||
var average = total / bufferSize;
|
||||
var rms = Math.sqrt(sum / bufferSize);
|
||||
this.volume[channel] = Math.max(rms, this.volume[channel] * .8);
|
||||
this.values[channel] = average;
|
||||
this.clipTime = 0;
|
||||
|
||||
//components
|
||||
this.jsNode = this.context.createScriptProcessor(this.bufferSize, this.channels, this.channels);
|
||||
this.jsNode.onaudioprocess = this.onprocess.bind(this);
|
||||
|
||||
//signal just passes
|
||||
this.input.connect(this.output);
|
||||
this.input.connect(this.jsNode);
|
||||
//so it doesn't get garbage collected
|
||||
this.jsNode.toMaster();
|
||||
}
|
||||
}
|
||||
|
||||
Tone.extend(Tone.Meter, Tone);
|
||||
|
||||
|
||||
//@param {number=} channel
|
||||
//@returns {number}
|
||||
Tone.Meter.prototype.getLevel = function(channel){
|
||||
channel = this.defaultArg(channel, 0);
|
||||
var vol = this.volume[channel];
|
||||
if (vol < .00001){
|
||||
return 0;
|
||||
} else {
|
||||
return vol;
|
||||
}
|
||||
}
|
||||
|
||||
//@param {number=} channel
|
||||
//@returns {number}
|
||||
Tone.Meter.prototype.getValue = function(channel){
|
||||
channel = this.defaultArg(channel, 0);
|
||||
return this.values[channel];
|
||||
}
|
||||
|
||||
//@param {number=} channel
|
||||
//@returns {number} the channel volume in decibels
|
||||
Tone.Meter.prototype.getDb = function(channel){
|
||||
return this.gainToDb(this.getLevel(channel));
|
||||
}
|
||||
|
||||
// @returns {boolean} if the audio has clipped in the last 500ms
|
||||
Tone.Meter.prototype.isClipped = function(){
|
||||
return Date.now() - this.clipTime < 500;
|
||||
}
|
||||
|
||||
//get the max value
|
||||
Tone.Meter.prototype.onprocess = function(event){
|
||||
var bufferSize = this.jsNode.bufferSize;
|
||||
for (var channel = 0; channel < this.channels; channel++){
|
||||
var input = event.inputBuffer.getChannelData(channel);
|
||||
var sum = 0;
|
||||
var total = 0;
|
||||
var x;
|
||||
var clipped = false;
|
||||
for (var i = 0; i < bufferSize; i++){
|
||||
x = input[i];
|
||||
if (!clipped && x > .95){
|
||||
clipped = true;
|
||||
this.clipTime = Date.now();
|
||||
}
|
||||
total += x;
|
||||
sum += x * x;
|
||||
}
|
||||
var average = total / bufferSize;
|
||||
var rms = Math.sqrt(sum / bufferSize);
|
||||
this.volume[channel] = Math.max(rms, this.volume[channel] * .8);
|
||||
this.values[channel] = average;
|
||||
}
|
||||
}
|
||||
|
||||
return Tone.Meter;
|
||||
});
|
|
@ -7,53 +7,44 @@
|
|||
// 1 = 100% Right
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Tone.Panner = function(){
|
||||
Tone.call(this);
|
||||
define(["core/Tone", "signal/Merge", "signal/Signal", "signal/Scale", "signal/Subtract"],
|
||||
function(Tone){
|
||||
|
||||
//components
|
||||
this.mono = new Tone.Mono();
|
||||
this.split = new Tone.Stereo();
|
||||
this.control = new Tone.Signal();
|
||||
this.invert = new Tone.Invert();
|
||||
this.leftScale = new Tone.Scale(0, 1);
|
||||
this.rightScale = new Tone.Scale(0, 1);
|
||||
this.equalGain = this.context.createWaveShaper();
|
||||
this.merger = this.context.createChannelMerger(2);
|
||||
Tone.Panner = function(){
|
||||
Tone.call(this);
|
||||
|
||||
//connections
|
||||
this.chain(this.input, this.mono, this.split);
|
||||
this.split.right.connect(this.merger, 0, 0);
|
||||
this.split.left.connect(this.merger, 0, 1);
|
||||
this.merger.connect(this.output);
|
||||
//control connections
|
||||
this.control.connect(this.equalGain);
|
||||
this.chain(this.equalGain, this.leftScale, this.split.left.gain);
|
||||
this.chain(this.equalGain, this.invert, this.rightScale, this.split.right.gain);
|
||||
//components
|
||||
//incoming signal is sent to left and right
|
||||
this.left = this.context.createGain();
|
||||
this.right = this.context.createGain();
|
||||
this.control = new Tone.Signal();
|
||||
this.merge = new Tone.Merge();
|
||||
this.invert = new Tone.Scale(1, -1);
|
||||
this.equalPowerL = new Tone.Scale(0, 1, "equalPower");
|
||||
this.equalPowerR = new Tone.Scale(0, 1, "equalPower");
|
||||
|
||||
//setup
|
||||
this.split.left.gain.value = 0;
|
||||
this.split.right.gain.value = 0;
|
||||
this.setPan(0);
|
||||
this._equalPowerGainCurve();
|
||||
}
|
||||
//connections
|
||||
this.chain(this.input, this.left, this.merge.left);
|
||||
this.chain(this.input, this.right, this.merge.right);
|
||||
this.merge.connect(this.output);
|
||||
//left channel control
|
||||
this.chain(this.control, this.invert, this.equalPowerL, this.left.gain);
|
||||
//right channel control
|
||||
this.chain(this.control, this.equalPowerR, this.right.gain);
|
||||
|
||||
Tone.extend(Tone.Panner);
|
||||
|
||||
Tone.Panner.prototype.setPan = function(val, rampTime){
|
||||
rampTime = this.defaultArg(rampTime, 0);
|
||||
this.control.linearRampToValueAtTime(val, rampTime);
|
||||
}
|
||||
|
||||
//generates the values for the waveshaper
|
||||
Tone.Panner.prototype._equalPowerGainCurve = function(){
|
||||
var len = this.bufferSize;
|
||||
var curve = new Float32Array(len);
|
||||
for (var i = 0; i < len; i++){
|
||||
//values between -1 to 1
|
||||
var baseline = (i / (len - 1)) * 2 - 1;
|
||||
// scale it by amount
|
||||
curve[i] = this.equalPowerGain(baseline);
|
||||
// curve[i] = baseline;
|
||||
//setup
|
||||
this.left.gain.value = 0;
|
||||
this.right.gain.value = 0;
|
||||
this.setPan(0);
|
||||
}
|
||||
this.equalGain.curve = curve;
|
||||
}
|
||||
|
||||
Tone.extend(Tone.Panner);
|
||||
|
||||
Tone.Panner.prototype.setPan = function(val, rampTime){
|
||||
rampTime = this.defaultArg(rampTime, 0);
|
||||
this.control.linearRampToValueAtTime(val, rampTime);
|
||||
}
|
||||
|
||||
return Tone.Panner;
|
||||
});;
|
|
@ -1,43 +0,0 @@
|
|||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// STEREO Split
|
||||
//
|
||||
// splits left/right, gives leftSend/Return and rightSend/Return
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
Tone.StereoSplit = function(){
|
||||
//extends Unit
|
||||
Tone.call(this);
|
||||
|
||||
//components
|
||||
this.splitter = Tone.context.createChannelSplitter();
|
||||
this.mono = this.context.createGain();
|
||||
this.merger = this.context.createChannelMerger(2);
|
||||
this.leftSend = this.context.createGain();
|
||||
this.leftReturn = this.context.createGain();
|
||||
this.rightSend = this.context.createGain();
|
||||
this.rightReturn = this.context.createGain();
|
||||
|
||||
//connections
|
||||
//mono input
|
||||
this.input.connect(this.splitter);
|
||||
this.splitter.connect(this.mono, 0, 0);
|
||||
this.splitter.connect(this.mono, 1, 0);
|
||||
|
||||
this.mono.connect(this.leftSend);
|
||||
this.mono.connect(this.rightSend);
|
||||
this.leftReturn.connect(this.merger, 0, 0);
|
||||
this.rightReturn.connect(this.merger, 0, 1);
|
||||
this.merger.connect(this.output);
|
||||
}
|
||||
|
||||
Tone.extend(Tone.StereoSplit, Tone);
|
||||
|
||||
Tone.StereoSplit.prototype.connectLeft = function(unit){
|
||||
this.chain(this.leftSend, unit, this.leftReturn);
|
||||
}
|
||||
|
||||
Tone.StereoSplit.prototype.connectRight = function(unit){
|
||||
this.chain(this.rightSend, unit, this.rightReturn);
|
||||
}
|
42
src/core/Master.js
Normal file
42
src/core/Master.js
Normal file
|
@ -0,0 +1,42 @@
|
|||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// MASTER OUTPUT
|
||||
//
|
||||
// a single master output
|
||||
// adds a toMaster method on AudioNodes and components
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
define(["core/Tone"], function(Tone){
|
||||
|
||||
var Master = function(){
|
||||
//extend audio unit
|
||||
Tone.call(this);
|
||||
|
||||
//put a hard limiter on the output so we don't blow any eardrums
|
||||
this.limiter = this.context.createDynamicsCompressor();
|
||||
this.limiter.threshold.value = 0;
|
||||
this.limiter.ratio.value = 20;
|
||||
this.chain(this.input, this.limiter, this.output, this.context.destination);
|
||||
}
|
||||
|
||||
Tone.extend(Master);
|
||||
|
||||
//a single master output
|
||||
Tone.Master = new Master();
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Add toMaster methods
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//@param {AudioNode|Tone=} unit
|
||||
Tone.prototype.toMaster = function(){
|
||||
this.connect(Tone.Master);
|
||||
}
|
||||
|
||||
AudioNode.prototype.toMaster = function(){
|
||||
this.connect(Tone.Master);
|
||||
}
|
||||
|
||||
return Tone.Master;
|
||||
})
|
|
@ -6,20 +6,28 @@
|
|||
// MIT License (MIT)
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
(function (global, undefined) {
|
||||
define(function () {
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// HELPERS
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function isUndef(val){
|
||||
return typeof val === "undefined";
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// WEB AUDIO CONTEXT
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//ALIAS
|
||||
if (!global.AudioContext){
|
||||
global.AudioContext = global.webkitAudioContext;
|
||||
if (!window.AudioContext){
|
||||
window.AudioContext = window.webkitAudioContext;
|
||||
}
|
||||
|
||||
var audioContext;
|
||||
if (global.AudioContext){
|
||||
audioContext = new global.AudioContext();
|
||||
if (window.AudioContext){
|
||||
audioContext = new window.AudioContext();
|
||||
}
|
||||
|
||||
//SHIMS////////////////////////////////////////////////////////////////////
|
||||
|
@ -69,6 +77,7 @@
|
|||
Tone.prototype.context = audioContext;
|
||||
Tone.prototype.fadeTime = .005; //5ms
|
||||
Tone.prototype.bufferSize = 2048; //default buffer size
|
||||
Tone.prototype.waveShaperResolution = 1024; //default buffer size
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// CLASS METHODS
|
||||
|
@ -149,16 +158,28 @@
|
|||
//@param {*} fallback
|
||||
//@returns {*}
|
||||
Tone.prototype.defaultArg = function(given, fallback){
|
||||
return typeof(given) !== 'undefined' ? given : fallback;
|
||||
return isUndef(given) ? fallback : given;
|
||||
}
|
||||
|
||||
//@param {number} percent (0-1)
|
||||
//@returns {number} the equal power gain
|
||||
//@returns {number} the equal power gain (0-1)
|
||||
//good for cross fades
|
||||
Tone.prototype.equalPowerGain = function(percent){
|
||||
Tone.prototype.equalPowerScale = function(percent){
|
||||
return Math.sin((percent) * 0.5*Math.PI);
|
||||
}
|
||||
|
||||
//@param {number} gain
|
||||
//@returns {number} gain (decibel scale but betwee 0-1)
|
||||
Tone.prototype.logScale = function(gain) {
|
||||
return Math.max(this.normalize(this.gainToDb(gain), -100, 0), 0);
|
||||
}
|
||||
|
||||
//@param {number} gain
|
||||
//@returns {number} gain (decibel scale but betwee 0-1)
|
||||
Tone.prototype.expScale = function(gain) {
|
||||
return this.dbToGain(this.interpolate(gain, -100, 0));
|
||||
}
|
||||
|
||||
//@param {number} db
|
||||
//@returns {number} gain
|
||||
Tone.prototype.dbToGain = function(db) {
|
||||
|
@ -171,18 +192,6 @@
|
|||
return 20 * (Math.log(gain) / Math.LN10);
|
||||
}
|
||||
|
||||
//@param {number} gain
|
||||
//@returns {number} gain (decibel scale but betwee 0-1)
|
||||
Tone.prototype.gainToLogScale = function(gain) {
|
||||
return Math.max(this.normalize(this.gainToDb(gain), -100, 0), 0);
|
||||
}
|
||||
|
||||
//@param {number} gain
|
||||
//@returns {number} gain (decibel scale but betwee 0-1)
|
||||
Tone.prototype.gainToPowScale = function(gain) {
|
||||
return this.dbToGain(this.interpolate(gain, -100, 0));
|
||||
}
|
||||
|
||||
//@param {number} input 0-1
|
||||
Tone.prototype.interpolate = function(input, outputMin, outputMax){
|
||||
return input*(outputMax - outputMin) + outputMin;
|
||||
|
@ -208,16 +217,6 @@
|
|||
return samples / audioContext.sampleRate;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// CHANNEL ROUTING
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//@param {AudioNode|Tone=} unit
|
||||
Tone.prototype.toMaster = function(node){
|
||||
node = this.defaultArg(node, this.output);
|
||||
node.connect(Tone.Master);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// MUSICAL TIMING
|
||||
//
|
||||
|
@ -294,7 +293,7 @@
|
|||
|
||||
//based on closure library 'inherit' function
|
||||
Tone.extend = function(child, parent){
|
||||
if (parent === undefined){
|
||||
if (isUndef(parent)){
|
||||
parent = Tone;
|
||||
}
|
||||
/** @constructor */
|
||||
|
@ -307,24 +306,5 @@
|
|||
|
||||
Tone.context = audioContext;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// MASTER OUTPUT
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
var Master = function(){
|
||||
//extend audio unit
|
||||
Tone.call(this);
|
||||
|
||||
//put a hard limiter on the output so we don't blow any eardrums
|
||||
this.limiter = this.context.createDynamicsCompressor();
|
||||
this.limiter.threshold.value = 0;
|
||||
this.limiter.ratio.value = 20;
|
||||
this.chain(this.input, this.limiter, this.output, this.context.destination);
|
||||
}
|
||||
Tone.extend(Master, Tone);
|
||||
Tone.Master = new Master();
|
||||
|
||||
//make it global
|
||||
global.Tone = Tone;
|
||||
|
||||
})(this);
|
||||
return Tone;
|
||||
});
|
||||
|
|
|
@ -22,7 +22,7 @@ Tone.AutoPanner = function(rate, amount){
|
|||
this.osc.connect(this.panner.control);
|
||||
}
|
||||
|
||||
//extend StereoSplit
|
||||
//extend Effect
|
||||
Tone.extend(Tone.AutoPanner, Tone.Effect);
|
||||
|
||||
Tone.AutoPanner.prototype.start = function(time){
|
||||
|
|
|
@ -5,33 +5,38 @@
|
|||
// adds a constant value to the incoming signal in normal range (-1 to 1)
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Tone.Add = function(constant){
|
||||
Tone.call(this);
|
||||
define(["core/Tone"], function(Tone){
|
||||
|
||||
this.constant = constant;
|
||||
Tone.Add = function(constant){
|
||||
Tone.call(this);
|
||||
|
||||
//component
|
||||
this.adder = this.context.createWaveShaper();
|
||||
this.constant = constant;
|
||||
|
||||
//connections
|
||||
this.chain(this.input, this.adder, this.output);
|
||||
//component
|
||||
this.adder = this.context.createWaveShaper();
|
||||
|
||||
//setup
|
||||
this._adderCurve();
|
||||
}
|
||||
//connections
|
||||
this.chain(this.input, this.adder, this.output);
|
||||
|
||||
Tone.extend(Tone.Add);
|
||||
|
||||
//adds a constant value to the incoming signal
|
||||
Tone.Add.prototype._adderCurve = function(){
|
||||
var len = this.bufferSize;
|
||||
var curve = new Float32Array(len);
|
||||
for (var i = 0; i < len; i++){
|
||||
///scale the values between -1 to 1
|
||||
var baseline = (i / (len - 1)) * 2 - 1;
|
||||
//all inputs produce the output value
|
||||
curve[i] = baseline + this.constant;
|
||||
//setup
|
||||
this._adderCurve();
|
||||
}
|
||||
//console.log(curve);
|
||||
this.adder.curve = curve;
|
||||
}
|
||||
|
||||
Tone.extend(Tone.Add);
|
||||
|
||||
//adds a constant value to the incoming signal
|
||||
Tone.Add.prototype._adderCurve = function(){
|
||||
var len = this.waveShaperResolution;
|
||||
var curve = new Float32Array(len);
|
||||
for (var i = 0; i < len; i++){
|
||||
///scale the values between -1 to 1
|
||||
var baseline = (i / (len - 1)) * 2 - 1;
|
||||
//all inputs produce the output value
|
||||
curve[i] = baseline + this.constant;
|
||||
}
|
||||
//console.log(curve);
|
||||
this.adder.curve = curve;
|
||||
}
|
||||
|
||||
return Tone.Add;
|
||||
});
|
|
@ -1,27 +0,0 @@
|
|||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// EQUAL POWER GAIN
|
||||
//
|
||||
// takes an input and between -1 and 1
|
||||
// outputs values between -1 and 1 equal power gain
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Tone.EqualPowerGain = function(){
|
||||
Tone.call(this);
|
||||
}
|
||||
|
||||
Tone.extend(Tone.EqualPowerGain);
|
||||
|
||||
//generates the values for the waveshaper
|
||||
Tone.EqualPowerGain.prototype._equalPowerGainCurve = function(){
|
||||
var len = this.bufferSize;
|
||||
var curve = new Float32Array(len);
|
||||
for (var i = 0; i < len; i++){
|
||||
//values between -1 to 1
|
||||
var baseline = (i / (len - 1)) * 2 - 1;
|
||||
// scale it by amount
|
||||
curve[i] = this.equalPowerGain(baseline);
|
||||
// curve[i] = baseline;
|
||||
}
|
||||
this.equalGain.curve = curve;
|
||||
}
|
|
@ -1,37 +0,0 @@
|
|||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// INVERT
|
||||
//
|
||||
// accepts normal range signal (-1 to 1) and inverts the output
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
Tone.Invert = function(){
|
||||
Tone.call(this);
|
||||
|
||||
//components
|
||||
this.inverter = Tone.context.createWaveShaper();
|
||||
|
||||
//connections
|
||||
this.chain(this.input, this.inverter, this.output);
|
||||
|
||||
//setup
|
||||
this._inverterCurve();
|
||||
}
|
||||
|
||||
//extend StereoSplit
|
||||
Tone.extend(Tone.Invert);
|
||||
|
||||
//generates the values for the waveshaper
|
||||
Tone.Invert.prototype._inverterCurve = function(){
|
||||
var len = this.bufferSize;
|
||||
var curve = new Float32Array(len);
|
||||
for (var i = 0; i < len; i++){
|
||||
//values between -1 to 1
|
||||
var baseline = (i / (len - 1)) * 2 - 1;
|
||||
//scale it by amount
|
||||
curve[i] = -baseline;
|
||||
}
|
||||
this.inverter.curve = curve;
|
||||
}
|
27
src/signal/Merge.js
Normal file
27
src/signal/Merge.js
Normal file
|
@ -0,0 +1,27 @@
|
|||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// MONO
|
||||
//
|
||||
// Merge a left and a right into a single left/right channel
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
define(["core/Tone"], function(Tone){
|
||||
|
||||
Tone.Merge = function(){
|
||||
Tone.call(this);
|
||||
|
||||
//components
|
||||
this.left = this.context.createGain();
|
||||
this.right = this.context.createGain();
|
||||
this.merger = this.context.createChannelMerger(2);
|
||||
|
||||
//connections
|
||||
this.left.connect(this.merger, 0, 0);
|
||||
this.right.connect(this.merger, 0, 1);
|
||||
this.merger.connect(this.output);
|
||||
}
|
||||
|
||||
Tone.extend(Tone.Merge);
|
||||
|
||||
return Tone.Merge;
|
||||
})
|
|
@ -1,20 +0,0 @@
|
|||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// MONO
|
||||
//
|
||||
// Sum a stereo channel into a mono channel
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Tone.Mono = function(){
|
||||
Tone.call(this);
|
||||
|
||||
//components
|
||||
this.merger = this.context.createChannelMerger(2);
|
||||
|
||||
//connections
|
||||
this.input.connect(this.merger, 0, 0);
|
||||
this.input.connect(this.merger, 0, 1);
|
||||
this.merger.connect(this.output);
|
||||
}
|
||||
|
||||
Tone.extend(Tone.Mono, Tone);
|
|
@ -4,35 +4,41 @@
|
|||
//
|
||||
// normalizes the incoming signal (between inputMin and inputMax)
|
||||
// to normal range (-1 to 1)
|
||||
// should deprecate!
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Tone.Normalize = function(inputMin, inputMax){
|
||||
Tone.call(this);
|
||||
define(["core/Tone"], function(Tone){
|
||||
|
||||
//vars
|
||||
this.inputMin = this.defaultArg(inputMin, -1);
|
||||
this.inputMax = this.defaultArg(inputMax, 1);
|
||||
Tone.Normalize = function(inputMin, inputMax){
|
||||
Tone.call(this);
|
||||
|
||||
//components
|
||||
this.normalize = this.context.createScriptProcessor(this.bufferSize, 1, 1);
|
||||
//vars
|
||||
this.inputMin = this.defaultArg(inputMin, -1);
|
||||
this.inputMax = this.defaultArg(inputMax, 1);
|
||||
|
||||
//connections
|
||||
this.chain(this.input, this.normalize, this.output);
|
||||
//components
|
||||
this.normalize = this.context.createScriptProcessor(this.bufferSize, 1, 1);
|
||||
|
||||
//setup
|
||||
this.normalize.onaudioprocess = this._process.bind(this);
|
||||
}
|
||||
//connections
|
||||
this.chain(this.input, this.normalize, this.output);
|
||||
|
||||
Tone.extend(Tone.Normalize);
|
||||
|
||||
Tone.Normalize.prototype._process = function(e) {
|
||||
var bufferSize = this.normalize.bufferSize;
|
||||
var input = e.inputBuffer.getChannelData(0);
|
||||
var output = e.outputBuffer.getChannelData(0);
|
||||
var min = this.inputMin;
|
||||
var max = this.inputMax;
|
||||
var divisor = (max - min) / 2;
|
||||
for (var i = 0; i < bufferSize; i++) {
|
||||
output[i] = (input[i] - min) / divisor - 1;
|
||||
//setup
|
||||
this.normalize.onaudioprocess = this._process.bind(this);
|
||||
}
|
||||
}
|
||||
|
||||
Tone.extend(Tone.Normalize);
|
||||
|
||||
Tone.Normalize.prototype._process = function(e) {
|
||||
var bufferSize = this.normalize.bufferSize;
|
||||
var input = e.inputBuffer.getChannelData(0);
|
||||
var output = e.outputBuffer.getChannelData(0);
|
||||
var min = this.inputMin;
|
||||
var max = this.inputMax;
|
||||
var divisor = (max - min) / 2;
|
||||
for (var i = 0; i < bufferSize; i++) {
|
||||
output[i] = (input[i] - min) / divisor - 1;
|
||||
}
|
||||
}
|
||||
|
||||
return Tone.Normalize;
|
||||
})
|
||||
|
|
|
@ -1,61 +0,0 @@
|
|||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OSCILLATOR
|
||||
//
|
||||
// just an oscillator,
|
||||
// but starting and stopping is easier than the native version
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Tone.Oscillator = function(freq, type){
|
||||
Tone.call(this);
|
||||
|
||||
this.playing = false;
|
||||
|
||||
//components
|
||||
this.oscillator = this.context.createOscillator();
|
||||
this.oscillator.frequency.value = this.defaultArg(freq, 440);
|
||||
this.oscillator.type = this.defaultArg(type, "sine");
|
||||
console.log(freq);
|
||||
//connections
|
||||
this.chain(this.oscillator, this.output);
|
||||
}
|
||||
|
||||
Tone.extend(Tone.Oscillator);
|
||||
|
||||
//@param {number=} time
|
||||
Tone.Oscillator.prototype.start = function(time){
|
||||
if (!this.playing){
|
||||
var freq = this.oscillator.frequency.value;
|
||||
var type = this.oscillator.type;
|
||||
var detune = this.oscillator.frequency.value;
|
||||
this.oscillator = this.context.createOscillator();
|
||||
this.oscillator.frequency.value = freq;
|
||||
this.oscillator.type = type;
|
||||
this.oscillator.detune.value = detune;
|
||||
this.oscillator.connect(this.output);
|
||||
this.playing = true;
|
||||
time = this.defaultArg(time, this.now());
|
||||
this.oscillator.start(time);
|
||||
}
|
||||
}
|
||||
|
||||
//@param {number=} time
|
||||
Tone.Oscillator.prototype.stop = function(time){
|
||||
if (this.playing){
|
||||
time = this.defaultArg(time, this.now());
|
||||
this.oscillator.stop(time);
|
||||
this.playing = false;
|
||||
}
|
||||
}
|
||||
|
||||
//@param {number} val
|
||||
//@param {number=} rampTime
|
||||
Tone.Oscillator.prototype.setFrequency = function(val, rampTime){
|
||||
rampTime = this.defaultArg(rampTime, 0);
|
||||
this.oscillator.linearRampToValueAtTime(val, rampTime);
|
||||
}
|
||||
|
||||
//@param {string} type
|
||||
Tone.Oscillator.prototype.setType = function(type){
|
||||
this.oscillator.type = type;
|
||||
}
|
|
@ -5,47 +5,66 @@
|
|||
// scales the input in normal range (-1 to 1) to the output between min and max
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Tone.Scale = function(min, max){
|
||||
Tone.call(this);
|
||||
define(["core/Tone"], function(Tone){
|
||||
|
||||
//vals
|
||||
this.min = min;
|
||||
this.max = max;
|
||||
//@param {number} min
|
||||
//@param {number} max
|
||||
//@param {string} scaling (lin|exp|log|equalPower)
|
||||
Tone.Scale = function(min, max, scaling){
|
||||
Tone.call(this);
|
||||
|
||||
//components
|
||||
this.scaler = Tone.context.createWaveShaper();
|
||||
//vals
|
||||
this.min = min;
|
||||
this.max = max;
|
||||
this.scaling = this.defaultArg(scaling, "lin");
|
||||
this.scalingFunction = this._selectScalingFunction(this.scaling);
|
||||
|
||||
//connections
|
||||
this.chain(this.input, this.scaler, this.output);
|
||||
//components
|
||||
this.scaler = this.context.createWaveShaper();
|
||||
|
||||
//setup
|
||||
this._scaleCurve();
|
||||
}
|
||||
//connections
|
||||
this.chain(this.input, this.scaler, this.output);
|
||||
|
||||
//extend StereoSplit
|
||||
Tone.extend(Tone.Scale);
|
||||
|
||||
//generates the values for the waveshaper
|
||||
Tone.Scale.prototype._scaleCurve = function(){
|
||||
var len = 512;
|
||||
var curve = new Float32Array(len);
|
||||
var min = this.min;
|
||||
var max = this.max;
|
||||
for (var i = 0; i < len; i++){
|
||||
//values between 0 and 1
|
||||
var terp = (i / (len - 1));
|
||||
curve[i] = terp * (max - min) + min;
|
||||
//setup
|
||||
this._scaleCurve();
|
||||
}
|
||||
//console.log(curve);
|
||||
this.scaler.curve = curve;
|
||||
}
|
||||
|
||||
Tone.Scale.prototype.setMax = function(max){
|
||||
this.max = max;
|
||||
this._scaleCurve();
|
||||
}
|
||||
//extend StereoSplit
|
||||
Tone.extend(Tone.Scale);
|
||||
|
||||
Tone.Scale.prototype.setMin = function(min){
|
||||
this.min = min;
|
||||
this._scaleCurve();
|
||||
}
|
||||
//generates the values for the waveshaper
|
||||
Tone.Scale.prototype._scaleCurve = function(){
|
||||
var len = this.waveShaperResolution;
|
||||
var curve = new Float32Array(len);
|
||||
var min = this.min;
|
||||
var max = this.max;
|
||||
for (var i = 0; i < len; i++){
|
||||
//values between 0 and 1
|
||||
var terp = this.scalingFunction(i / (len - 1));
|
||||
curve[i] = terp * (max - min) + min;
|
||||
}
|
||||
this.scaler.curve = curve;
|
||||
}
|
||||
|
||||
//
|
||||
Tone.Scale.prototype._selectScalingFunction = function(scaling){
|
||||
switch(scaling){
|
||||
case "lin" : return function(x) {return x};
|
||||
case "exp" : return this.expScale;
|
||||
case "log" : return this.logScale;
|
||||
case "equalPower" : return this.equalPowerScale;
|
||||
}
|
||||
}
|
||||
|
||||
Tone.Scale.prototype.setMax = function(max){
|
||||
this.max = max;
|
||||
this._scaleCurve();
|
||||
}
|
||||
|
||||
Tone.Scale.prototype.setMin = function(min){
|
||||
this.min = min;
|
||||
this._scaleCurve();
|
||||
}
|
||||
|
||||
return Tone.Scale;
|
||||
});
|
||||
|
|
|
@ -6,69 +6,73 @@
|
|||
// useful for controlling AudioParams
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Tone.Signal = function(){
|
||||
Tone.call(this);
|
||||
define(["core/Tone"], function(Tone){
|
||||
|
||||
//@param {number=} value
|
||||
Tone.Signal = function(value){
|
||||
Tone.call(this);
|
||||
|
||||
//components
|
||||
this.signal = this.context.createWaveShaper();
|
||||
this.scalar = this.context.createGain();
|
||||
//generator to drive values
|
||||
this.generator = this.context.createOscillator();
|
||||
//components
|
||||
this.signal = this.context.createWaveShaper();
|
||||
this.scalar = this.context.createGain();
|
||||
//generator to drive values
|
||||
this.generator = this.context.createOscillator();
|
||||
|
||||
//connections
|
||||
this.chain(this.generator, this.signal, this.scalar, this.output);
|
||||
//connect the input to the scalar's gain so that can be controlled with the incoming signal
|
||||
this.input.connect(this.scalar.gain);
|
||||
//connections
|
||||
this.chain(this.generator, this.signal, this.scalar, this.output);
|
||||
|
||||
//setup
|
||||
this.generator.start(0);
|
||||
this.scalar.gain.value = 0;
|
||||
this._signalCurve();
|
||||
}
|
||||
|
||||
Tone.extend(Tone.Signal);
|
||||
|
||||
//generates a constant output of 1
|
||||
Tone.Signal.prototype._signalCurve = function(){
|
||||
var len = 8;
|
||||
var curve = new Float32Array(len);
|
||||
for (var i = 0; i < len; i++){
|
||||
//all inputs produce the output value
|
||||
curve[i] = 1;
|
||||
//setup
|
||||
this.generator.start(0);
|
||||
this._signalCurve();
|
||||
this.setValue(this.defaultArg(value, 0));
|
||||
}
|
||||
//console.log(curve);
|
||||
this.signal.curve = curve;
|
||||
}
|
||||
|
||||
Tone.Signal.prototype.getValue = function(val){
|
||||
return this.scalar.gain.value;
|
||||
}
|
||||
Tone.extend(Tone.Signal);
|
||||
|
||||
Tone.Signal.prototype.setValue = function(val){
|
||||
this.scalar.gain.value = val;
|
||||
}
|
||||
//generates a constant output of 1
|
||||
Tone.Signal.prototype._signalCurve = function(){
|
||||
var len = 8;
|
||||
var curve = new Float32Array(len);
|
||||
for (var i = 0; i < len; i++){
|
||||
//all inputs produce the output value
|
||||
curve[i] = 1;
|
||||
}
|
||||
//console.log(curve);
|
||||
this.signal.curve = curve;
|
||||
}
|
||||
|
||||
//all of the automation curves are available
|
||||
Tone.Signal.prototype.setValueAtTime = function(value, time){
|
||||
this.scalar.gain.setValueAtTime(value, time);
|
||||
}
|
||||
Tone.Signal.prototype.getValue = function(val){
|
||||
return this.scalar.gain.value;
|
||||
}
|
||||
|
||||
Tone.Signal.prototype.linearRampToValueAtTime = function(value, endTime){
|
||||
this.scalar.gain.linearRampToValueAtTime(value, endTime);
|
||||
}
|
||||
Tone.Signal.prototype.setValue = function(val){
|
||||
this.scalar.gain.value = val;
|
||||
}
|
||||
|
||||
Tone.Signal.prototype.exponentialRampToValueAtTime = function(value, endTime){
|
||||
this.scalar.gain.exponentialRampToValueAtTime(value, endTime);
|
||||
}
|
||||
//all of the automation curves are available
|
||||
Tone.Signal.prototype.setValueAtTime = function(value, time){
|
||||
this.scalar.gain.setValueAtTime(value, time);
|
||||
}
|
||||
|
||||
Tone.Signal.prototype.setTargetAtTime = function(target, startTime, timeConstant){
|
||||
this.scalar.gain.setTargetAtTime(target, startTime, timeConstant);
|
||||
}
|
||||
Tone.Signal.prototype.linearRampToValueAtTime = function(value, endTime){
|
||||
this.scalar.gain.linearRampToValueAtTime(value, endTime);
|
||||
}
|
||||
|
||||
Tone.Signal.prototype.setValueCurveAtTime = function(values, startTime, duration){
|
||||
this.scalar.gain.setValueCurveAtTime(values, startTime, duration);
|
||||
}
|
||||
Tone.Signal.prototype.exponentialRampToValueAtTime = function(value, endTime){
|
||||
this.scalar.gain.exponentialRampToValueAtTime(value, endTime);
|
||||
}
|
||||
|
||||
Tone.Signal.prototype.cancelScheduledValues = function(startTime){
|
||||
this.scalar.gain.cancelScheduledValues(startTime);
|
||||
}
|
||||
Tone.Signal.prototype.setTargetAtTime = function(target, startTime, timeConstant){
|
||||
this.scalar.gain.setTargetAtTime(target, startTime, timeConstant);
|
||||
}
|
||||
|
||||
Tone.Signal.prototype.setValueCurveAtTime = function(values, startTime, duration){
|
||||
this.scalar.gain.setValueCurveAtTime(values, startTime, duration);
|
||||
}
|
||||
|
||||
Tone.Signal.prototype.cancelScheduledValues = function(startTime){
|
||||
this.scalar.gain.cancelScheduledValues(startTime);
|
||||
}
|
||||
|
||||
return Tone.Signal;
|
||||
})
|
28
src/signal/Split.js
Normal file
28
src/signal/Split.js
Normal file
|
@ -0,0 +1,28 @@
|
|||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// STEREO
|
||||
//
|
||||
// splits the incoming signal into left and right outputs
|
||||
// one input two outputs
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
define(["core/Tone"], function(Tone){
|
||||
|
||||
Tone.Split = function(){
|
||||
Tone.call(this);
|
||||
|
||||
//components
|
||||
this.splitter = this.context.createChannelSplitter(2);
|
||||
this.left = this.context.createGain();
|
||||
this.right = this.context.createGain();
|
||||
|
||||
//connections
|
||||
this.input.connect(this.splitter);
|
||||
this.splitter.connect(this.left, 1, 0);
|
||||
this.splitter.connect(this.right, 0, 0);
|
||||
}
|
||||
|
||||
Tone.extend(Tone.Split);
|
||||
|
||||
return Tone.Split;
|
||||
});
|
|
@ -1,22 +0,0 @@
|
|||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// STEREO
|
||||
//
|
||||
// splits the incoming signal into left and right outputs
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Tone.Stereo = function(){
|
||||
Tone.call(this);
|
||||
|
||||
//components
|
||||
this.splitter = this.context.createChannelSplitter();
|
||||
this.left = this.context.createGain();
|
||||
this.right = this.context.createGain();
|
||||
|
||||
//connections
|
||||
this.input.connect(this.splitter);
|
||||
this.splitter.connect(this.left, 0, 0);
|
||||
this.splitter.connect(this.right, 1, 0);
|
||||
}
|
||||
|
||||
Tone.extend(Tone.Stereo);
|
43
src/signal/Subtract.js
Normal file
43
src/signal/Subtract.js
Normal file
|
@ -0,0 +1,43 @@
|
|||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// SUBTRACT FROM
|
||||
//
|
||||
// subtract the signal from the constant
|
||||
// for subtracting from the signal, use Tone.Add with a negative number
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
define(["core/Tone"], function(Tone){
|
||||
|
||||
Tone.Subtract = function(constant){
|
||||
Tone.call(this);
|
||||
|
||||
this.constant = constant;
|
||||
|
||||
//component
|
||||
this.subber = this.context.createWaveShaper();
|
||||
|
||||
//connections
|
||||
this.chain(this.input, this.subber, this.output);
|
||||
|
||||
//setup
|
||||
this._subCurve();
|
||||
}
|
||||
|
||||
Tone.extend(Tone.Subtract);
|
||||
|
||||
//subtracts the signal from the value
|
||||
Tone.Subtract.prototype._subCurve = function(){
|
||||
var len = this.waveShaperResolution;
|
||||
var curve = new Float32Array(len);
|
||||
for (var i = 0; i < len; i++){
|
||||
///scale the values between -1 to 1
|
||||
var baseline = (i / (len - 1)) * 2 - 1;
|
||||
//all inputs produce the output value
|
||||
curve[i] = this.constant - baseline;
|
||||
}
|
||||
//console.log(curve);
|
||||
this.subber.curve = curve;
|
||||
}
|
||||
|
||||
return Tone.Subtract;
|
||||
});
|
66
src/source/Oscillator.js
Normal file
66
src/source/Oscillator.js
Normal file
|
@ -0,0 +1,66 @@
|
|||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OSCILLATOR
|
||||
//
|
||||
// just an oscillator,
|
||||
// but starting and stopping is easier than the native version
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
define(["core/Tone"], function(Tone){
|
||||
|
||||
Tone.Oscillator = function(freq, type){
|
||||
Tone.call(this);
|
||||
|
||||
this.playing = false;
|
||||
|
||||
//components
|
||||
this.oscillator = this.context.createOscillator();
|
||||
this.oscillator.frequency.value = this.defaultArg(freq, 440);
|
||||
this.oscillator.type = this.defaultArg(type, "sine");
|
||||
console.log(freq);
|
||||
//connections
|
||||
this.chain(this.oscillator, this.output);
|
||||
}
|
||||
|
||||
Tone.extend(Tone.Oscillator);
|
||||
|
||||
//@param {number=} time
|
||||
Tone.Oscillator.prototype.start = function(time){
|
||||
if (!this.playing){
|
||||
var freq = this.oscillator.frequency.value;
|
||||
var type = this.oscillator.type;
|
||||
var detune = this.oscillator.frequency.value;
|
||||
this.oscillator = this.context.createOscillator();
|
||||
this.oscillator.frequency.value = freq;
|
||||
this.oscillator.type = type;
|
||||
this.oscillator.detune.value = detune;
|
||||
this.oscillator.connect(this.output);
|
||||
this.playing = true;
|
||||
time = this.defaultArg(time, this.now());
|
||||
this.oscillator.start(time);
|
||||
}
|
||||
}
|
||||
|
||||
//@param {number=} time
|
||||
Tone.Oscillator.prototype.stop = function(time){
|
||||
if (this.playing){
|
||||
time = this.defaultArg(time, this.now());
|
||||
this.oscillator.stop(time);
|
||||
this.playing = false;
|
||||
}
|
||||
}
|
||||
|
||||
//@param {number} val
|
||||
//@param {number=} rampTime
|
||||
Tone.Oscillator.prototype.setFrequency = function(val, rampTime){
|
||||
rampTime = this.defaultArg(rampTime, 0);
|
||||
this.oscillator.linearRampToValueAtTime(val, rampTime);
|
||||
}
|
||||
|
||||
//@param {string} type
|
||||
Tone.Oscillator.prototype.setType = function(type){
|
||||
this.oscillator.type = type;
|
||||
}
|
||||
|
||||
return Tone.Oscillator;
|
||||
});
|
Binary file not shown.
146
style/GUI.css
146
style/GUI.css
|
@ -1,146 +0,0 @@
|
|||
.label {
|
||||
font-family: monospace;
|
||||
text-align: center;
|
||||
width: 100%; }
|
||||
|
||||
/*=============================================================================
|
||||
BAR
|
||||
=============================================================================*/
|
||||
.bar {
|
||||
padding: 0px 2px 0px 2px; }
|
||||
|
||||
.bar .segment {
|
||||
width: 30px;
|
||||
height: 6px;
|
||||
margin: 2px auto 2px auto;
|
||||
opacity: 1;
|
||||
/*@include transitionAndTime(opacity, .016s);*/ }
|
||||
|
||||
.bar .segment.peak {
|
||||
background-color: red; }
|
||||
|
||||
.bar .segment.high {
|
||||
background-color: orange; }
|
||||
|
||||
.bar .segment.normal {
|
||||
background-color: green; }
|
||||
|
||||
.meter .bar .label {
|
||||
font-size: 10px; }
|
||||
|
||||
/*=============================================================================
|
||||
METER
|
||||
=============================================================================*/
|
||||
.meter {
|
||||
position: relative;
|
||||
float: left;
|
||||
margin: 5px;
|
||||
display: table;
|
||||
border: 1px solid black;
|
||||
border-radius: 3px; }
|
||||
|
||||
.meter .label {
|
||||
clear: both;
|
||||
font-size: 15px; }
|
||||
|
||||
.meter .bar {
|
||||
position: relative;
|
||||
float: left; }
|
||||
|
||||
/*=============================================================================
|
||||
FADER
|
||||
=============================================================================*/
|
||||
.fader {
|
||||
width: 40px;
|
||||
display: table;
|
||||
border: 1px solid black;
|
||||
border-radius: 3px;
|
||||
position: relative;
|
||||
float: left;
|
||||
margin: 5px; }
|
||||
|
||||
.fader .track {
|
||||
position: relative;
|
||||
width: auto;
|
||||
height: auto;
|
||||
margin: 0px; }
|
||||
|
||||
.fader .slider {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
margin: 0px;
|
||||
top: 0px;
|
||||
left: 0px;
|
||||
-webkit-appearance: slider-vertical;
|
||||
-moz-appearance: slider-vertical;
|
||||
appearance: slider-vertical; }
|
||||
|
||||
.fader input.label {
|
||||
padding: 0px;
|
||||
border: 0px;
|
||||
font-size: 10px;
|
||||
height: 15px; }
|
||||
|
||||
.fader .bar .segment {
|
||||
width: 40px;
|
||||
background-color: black; }
|
||||
|
||||
/*=============================================================================
|
||||
BUTTONS
|
||||
=============================================================================*/
|
||||
.button {
|
||||
margin: 5px;
|
||||
width: 40px;
|
||||
height: 20px;
|
||||
position: relative;
|
||||
left: 0px;
|
||||
border: none;
|
||||
display: inline-block; }
|
||||
|
||||
.button input {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
left: 0px;
|
||||
top: 0px;
|
||||
border: none;
|
||||
cursor: pointer; }
|
||||
|
||||
.button .label {
|
||||
position: absolute;
|
||||
top: 0px;
|
||||
left: 0px;
|
||||
height: 100%;
|
||||
line-height: 20px;
|
||||
color: white;
|
||||
pointer-events: none; }
|
||||
|
||||
.button:active input {
|
||||
background-color: white; }
|
||||
|
||||
.button:active .label {
|
||||
color: black; }
|
||||
|
||||
/*=============================================================================
|
||||
TRANSPORT
|
||||
=============================================================================*/
|
||||
.transport {
|
||||
border: 1px solid black;
|
||||
border-radius: 3px;
|
||||
position: absolute;
|
||||
width: auto;
|
||||
height: auto; }
|
||||
|
||||
.transport .button {
|
||||
float: left; }
|
||||
|
||||
.transport .progress {
|
||||
margin: 5px;
|
||||
float: left;
|
||||
display: inline-block;
|
||||
width: 60px;
|
||||
text-align: center;
|
||||
border: none;
|
||||
font-size: 14px;
|
||||
font-family: monospace; }
|
196
style/GUI.scss
196
style/GUI.scss
|
@ -1,196 +0,0 @@
|
|||
$fastUpdateTime : .1s;
|
||||
|
||||
@mixin transitionAndTime($property, $time){
|
||||
-webkit-transition: $property $time linear;
|
||||
-moz-transition: $property $time linear;
|
||||
-o-transition: $property $time linear;
|
||||
transition: $property $time linear;
|
||||
}
|
||||
|
||||
$unitWidth : 30px;
|
||||
|
||||
@mixin borderStyle{
|
||||
border: 1px solid black;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.label {
|
||||
font-family: monospace;
|
||||
text-align: center;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
/*=============================================================================
|
||||
BAR
|
||||
=============================================================================*/
|
||||
|
||||
.bar {
|
||||
padding: 0px 2px 0px 2px;
|
||||
}
|
||||
|
||||
.bar .segment {
|
||||
width: $unitWidth;
|
||||
height: 6px;
|
||||
margin: 2px auto 2px auto;
|
||||
opacity: 1;
|
||||
/*@include transitionAndTime(opacity, .016s);*/
|
||||
}
|
||||
|
||||
.bar .segment.peak {
|
||||
background-color: red;
|
||||
}
|
||||
|
||||
.bar .segment.high {
|
||||
background-color: orange;
|
||||
}
|
||||
|
||||
.bar .segment.normal {
|
||||
background-color: green;
|
||||
}
|
||||
|
||||
.meter .bar .label {
|
||||
font-size: 10px;
|
||||
}
|
||||
|
||||
/*=============================================================================
|
||||
METER
|
||||
=============================================================================*/
|
||||
|
||||
.meter {
|
||||
position: relative;
|
||||
float: left;
|
||||
margin: 5px;
|
||||
display: table;
|
||||
@include borderStyle;
|
||||
}
|
||||
|
||||
.meter .label {
|
||||
clear: both;
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
.meter .bar {
|
||||
position: relative;
|
||||
float: left;
|
||||
}
|
||||
|
||||
/*=============================================================================
|
||||
FADER
|
||||
=============================================================================*/
|
||||
|
||||
$faderWidth: 40px;
|
||||
|
||||
.fader {
|
||||
width: $faderWidth;
|
||||
display: table;
|
||||
@include borderStyle;
|
||||
position: relative;
|
||||
float: left;
|
||||
margin: 5px;
|
||||
}
|
||||
|
||||
.fader .track {
|
||||
position: relative;
|
||||
width: auto;
|
||||
height: auto;
|
||||
margin: 0px;
|
||||
}
|
||||
|
||||
.fader .slider {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
margin: 0px;
|
||||
top: 0px;
|
||||
left: 0px;
|
||||
-webkit-appearance: slider-vertical;
|
||||
-moz-appearance: slider-vertical;
|
||||
appearance: slider-vertical;
|
||||
}
|
||||
|
||||
.fader input.label {
|
||||
padding: 0px;
|
||||
border: 0px;
|
||||
font-size: 10px;
|
||||
height: 15px;
|
||||
}
|
||||
|
||||
.fader .bar .segment {
|
||||
width: $faderWidth;
|
||||
background-color: black;
|
||||
}
|
||||
|
||||
|
||||
/*=============================================================================
|
||||
BUTTONS
|
||||
=============================================================================*/
|
||||
|
||||
$buttonWidth: 40px;
|
||||
$buttonHeight: 20px;
|
||||
|
||||
.button {
|
||||
margin: 5px;
|
||||
width: $buttonWidth;
|
||||
height: $buttonHeight;
|
||||
position: relative;
|
||||
left: 0px;
|
||||
border: none;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.button input{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
left: 0px;
|
||||
top:0px;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
|
||||
.button .label {
|
||||
position: absolute;
|
||||
top: 0px;
|
||||
left: 0px;
|
||||
height: 100%;
|
||||
line-height: $buttonHeight;
|
||||
color: white;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.button:active input{
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
.button:active .label{
|
||||
color: black;
|
||||
}
|
||||
|
||||
|
||||
/*=============================================================================
|
||||
TRANSPORT
|
||||
=============================================================================*/
|
||||
|
||||
.transport {
|
||||
@include borderStyle;
|
||||
position: absolute;
|
||||
width: auto;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.transport .button{
|
||||
float: left;
|
||||
}
|
||||
|
||||
.transport .progress{
|
||||
margin: 5px;
|
||||
float: left;
|
||||
display: inline-block;
|
||||
width: 60px;
|
||||
text-align: center;
|
||||
border: none;
|
||||
font-size: 14px;
|
||||
font-family: monospace;
|
||||
}
|
||||
|
Loading…
Reference in a new issue