mader the fader

This commit is contained in:
Yotam Mann 2014-03-13 20:03:14 -04:00
parent b5f81c1c8c
commit 1c013c7241
14 changed files with 652 additions and 94 deletions

View file

@ -6,8 +6,9 @@
<script src="http://code.jquery.com/jquery-2.1.0.min.js"></script>
<script type="text/javascript" src="../src/core/AudioUnit.js"></script>
<script type="text/javascript" src="../src/components/Player.js"></script>
<script type="text/javascript" src="../src/core/Master.js"></script>
<script type="text/javascript" src="../src/components/Meter.js"></script>
<script type="text/javascript" src="../src/components/Player.js"></script>
<script type="text/javascript" src="../src/components/Envelope.js"></script>
<script type="text/javascript" src="../src/components/LFO.js"></script>
<script type="text/javascript" src="../src/components/Noise.js"></script>
@ -17,19 +18,31 @@
<script type="text/javascript" src="../src/effects/PingPongDelay.js"></script>
<script type="text/javascript" src="../src/components/Microphone.js"></script>
<script type="text/javascript" src="../src/GUI/GUI.js"></script>
<script type="text/javascript" src="../src/GUI/GUI.Bars.js"></script>
<script type="text/javascript" src="../src/GUI/GUI.Bar.js"></script>
<script type="text/javascript" src="../src/GUI/GUI.Meter.js"></script>
<script type="text/javascript" src="../src/GUI/GUI.Fader.js"></script>
</head>
<body>
<style type="text/css">
#meter {
width: 100%;
width: auto;
text-align: center;
font-size: 10px;
float: right;
position: absolute;
bottom: 10px;
right: 10px;
}
#fader {
position: absolute;
bottom: 10px;
right: 100px;
width: auto;
}
</style>
<div id='Instructions'>Press 'e'</div>
<div id='meter'></div>
<div id='fader'></div>
<script type="text/javascript">
var player = new AudioUnit.Player("../audio/A3.mp3");
var meter = new AudioUnit.Meter(2);
@ -37,26 +50,21 @@
var lfo = new AudioUnit.LFO(undefined, 1, .5, 1);
var noise = new AudioUnit.Noise();
var feedbackDelay = new AudioUnit.PingPongDelay(.25);
var bars = new AudioUnit.GUI.Bars(document.body);
// var meterGui = new WebAudio.GUI.Meter($("#meter")[0], meter);
var meterGui = new AudioUnit.GUI.Meter($("#meter"), meter, "master", 20);
var fader = new AudioUnit.GUI.Fader($("#fader"), 0, 20, "master gain", 20);
noise.connect(env);
env.connect(feedbackDelay);
feedbackDelay.setFeedback(.5);
feedbackDelay.toSpeakers();
// feedbackDelay.connect(meter);
feedbackDelay.toMaster();
noise.setVolume(.4);
//the master output meter
AudioUnit.Master.connect(meter);
player.load(function(){
// player.loop(0, 0, 1);
player.loop();
});
setInterval(function(){
// var text = meter.getVolume(0).toFixed(3);
// text += " "+meter.getVolume(1).toFixed(3)
// $("#meter").html(text);
}, 100);
$(document).keydown(function(e){
if (e.which == 69){

55
src/GUI/GUI.Bar.js Normal file
View file

@ -0,0 +1,55 @@
///////////////////////////////////////////////////////////////////////////////
//
// BAR
//
// bars for meters and other UI elements
///////////////////////////////////////////////////////////////////////////////
//@param {Element} container
//@param {number=} segments
AudioUnit.GUI.Bar = function(container, segments){
//extend GUI
AudioUnit.GUI.call(this);
//vars
this.element = this.createElement();
this.segmentCount = this.defaultArg(segments, 10);
this.segments = new Array(this.segmentCount);
this.label = this.createElement();
//create the segments
for (var i = 0; i < this.segmentCount; i++){
var segment = this.createElement();
if (i === 0){
this.setClass(segment, "segment peak");
} else if (i < this.segmentCount * .3){
this.setClass(segment, "segment high");
} else {
this.setClass(segment, "segment normal");
}
this.appendChild(this.element, segment);
this.segments[this.segmentCount - i - 1] = segment;
}
this.setClass(this.element, "bar");
this.setClass(this.label, "label");
//add it to the container
this.appendChild(container, this.element);
this.appendChild(this.element, this.label);
}
AudioUnit.extend(AudioUnit.GUI.Bar, AudioUnit.GUI);
//@param {number} val (0-1)
AudioUnit.GUI.Bar.prototype.setLevel = function(val){
val *= this.segmentCount;
for (var i = 0; i < this.segmentCount; i++){
var seg = this.segments[i];
seg.style.opacity = Math.max(Math.min(val - i, 1), 0);
}
}
//@param {string} str
AudioUnit.GUI.Bar.prototype.setLabel = function(str){
this.label.textContent = str;
}

View file

@ -1,37 +0,0 @@
///////////////////////////////////////////////////////////////////////////////
//
// BARS
//
// bars for meters and other UI elements
///////////////////////////////////////////////////////////////////////////////
//@param {Element} container
//@param {number=} segments
AudioUnit.GUI.Bars = function(container, segments){
//extend GUI
AudioUnit.GUI.call(this);
//vars
this.element = document.createElement("div");
this.segmentCount = this.defaultArg(segments, 10);
this.segments = new Array(this.segmentCount);
//create the segments
for (var i = 0; i < this.segmentCount; i++){
var segment = document.createElement("div");
if (i === 0){
segment.className = "segment peak";
} else if (i < this.segmentCount * .3){
segment.className = "segment high";
} else {
segment.className = "segment normal";
}
this.element.appendChild(segment);
this.segments[i] = segment;
}
this.element.className = "bar";
//add it to the container
container.appendChild(this.element);
}
AudioUnit.extend(AudioUnit.GUI.Bars, AudioUnit.GUI);

134
src/GUI/GUI.Fader.js Normal file
View file

@ -0,0 +1,134 @@
///////////////////////////////////////////////////////////////////////////////
//
// FADER
//
///////////////////////////////////////////////////////////////////////////////
AudioUnit.GUI.Fader = function(container, minOutput, maxOutput, label, segments){
//extend GUI
AudioUnit.GUI.call(this);
//components
this.element = this.createElement();
this.track = this.createElement();
this.slider = this.createElement("input");
this.slider.type = "range";
this.textInput = this.createElement("input");
this.textInput.type = "text";
this.isDragging = false;
this.min = this.defaultArg(minOutput, 0);
this.max = this.defaultArg(maxOutput, 1);
this.scaling = "log";
this.bars = new AudioUnit.GUI.Bar(this.track, segments);
//set it
this.setClass(this.element, "fader");
this.setClass(this.track, "track");
this.setClass(this.slider, "slider");
this.setClass(this.textInput, "label");
this.appendChild(container, this.element);
this.appendChild(this.element, this.track);
this.appendChild(this.track, this.slider);
this.appendChild(this.element, this.textInput);
// this.onAnimationFrame(this.followValue, this);
this._setupEvents();
this.setLevel(this.min);
}
AudioUnit.extend(AudioUnit.GUI.Fader, AudioUnit.GUI);
//called when the value has changed
AudioUnit.GUI.Fader.prototype.onchange = function(){};
//set the level of the
AudioUnit.GUI.Fader.prototype.setLevel = function(level){
this._setText(level);
this._setSlider(level);
};
///////////////////////////////////////////////////////////////////////////////
// SCALING VALUES
///////////////////////////////////////////////////////////////////////////////
AudioUnit.GUI.Fader.prototype._onchangeText = function(e){
var val = parseFloat(this.textInput.value);
this.setLevel(val);
}
//called when the value has changed
AudioUnit.GUI.Fader.prototype._onchangeSlider = function(){
var scaledVal = this._scale(this.slider.value / 100)
var val = this.interpolate(scaledVal, this.min, this.max);
this.setLevel(val);
};
//@param {number} val
AudioUnit.GUI.Fader.prototype._setText = function(val){
if (val < 10){
this.textInput.value = val.toFixed(3);
} else if (val < 100){
this.textInput.value = val.toFixed(2);
} else {
this.textInput.value = parseInt(val, 10);
}
this.onchange(val);
}
AudioUnit.GUI.Fader.prototype._setSlider = function(val){
//scale it to the slider range
var normed = this.normalize(val, this.min, this.max);
var scaled = this._inverseScale(normed);
this.slider.value = scaled * 100;
this.bars.setLevel(scaled);
}
//input a value between 0-1
AudioUnit.GUI.Fader.prototype._inverseScale = function(x){
switch(this.scaling){
case "lin" :
return parseFloat(x);
case "log" :
return this.gainToLogScale(x);
case "exp" :
return this.gainToPowScale(x);
}
}
//input a value between 0-1
AudioUnit.GUI.Fader.prototype._scale = function(x){
switch(this.scaling){
case "lin" :
return parseFloat(x);
case "log" :
return this.gainToPowScale(x);
case "exp" :
return this.gainToLogScale(x);
}
}
///////////////////////////////////////////////////////////////////////////////
// INTERACTIONS
///////////////////////////////////////////////////////////////////////////////
//called when the value has changed
AudioUnit.GUI.Fader.prototype._setupEvents = function(){
this.textInput.onchange = this._onchangeText.bind(this);
this.slider.onchange = this._onchangeSlider.bind(this);
this.slider.onmousedown = this._mousedown.bind(this);
this.slider.onmouseup = this._mouseup.bind(this);
};
AudioUnit.GUI.Fader.prototype._mousedown = function(e){
this.isDragging = true;
}
AudioUnit.GUI.Fader.prototype._mouseup = function(e){
this.isDragging = false;
}

0
src/GUI/GUI.LinFader.js Normal file
View file

119
src/GUI/GUI.LogFader.js Normal file
View file

@ -0,0 +1,119 @@
AudioUnit.GUI.ParamFader = function(container, connectTo, minOutput, maxOutput, label, scaling, segments){
//extend GUI
AudioUnit.GUI.call(this);
//components
this.element = this.createElement();
this.track = this.createElement();
this.slider = this.createElement("input");
this.slider.type = "range";
this.textInput = this.createElement("input");
this.textInput.type = "text";
this.watch = connectTo;
if (connectTo.output && connectTo.output.gain instanceof AudioParam){
this.watch = connectTo.output.gain;
}
this.isDragging = false;
this.min = this.defaultArg(minOutput, 0);
this.max = this.defaultArg(maxOutput, 1);
this.scaling = this.defaultArg(scaling, "log");
this.bars = new AudioUnit.GUI.Bar(this.track, segments);
//set it
this.setClass(this.element, "fader");
this.setClass(this.track, "track");
this.setClass(this.slider, "slider");
this.setClass(this.textInput, "label");
this.appendChild(container, this.element);
this.appendChild(this.element, this.track);
this.appendChild(this.track, this.slider);
this.appendChild(this.element, this.textInput);
this.onAnimationFrame(this.followValue, this);
this._setupEvents();
this._setInitial();
}
AudioUnit.extend(AudioUnit.GUI.Fader, AudioUnit.GUI);
//called when the value has changed
AudioUnit.GUI.Fader.prototype.onchange = function(){};
//called when the value has changed
AudioUnit.GUI.Fader.prototype._onchange = function(){
var val = this.slider.value / 100;
this.bars.setLevel(val);
var scaled = this.interpolate(this._scale(val), this.min, this.max);
this.textInput.value = scaled.toFixed(3);
this.watch.value = scaled;
this.onchange(scaled);
};
AudioUnit.GUI.Fader.prototype._onchangeText = function(e){
var val = parseFloat(this.textInput.value);
this.slider.value = this._inverseScale(this.normalize(val, this.min, this.max)) * 100;
this._onchange();
}
//called 60fps
AudioUnit.GUI.Fader.prototype.followValue = function(){
if (!this.isDragging){
var normalized = this._inverseScale(this.normalize(this.watch.value, this.min, this.max)) * 100;
if (normalized !== this.slider.value){
this.slider.value = normalized;
}
}
}
//sets the initial values
AudioUnit.GUI.Fader.prototype._setInitial = function(){
var val = this.watch.value;
this.slider.value = this._inverseScale(this.normalize(val, this.min, this.max)) * 100;
this.textInput.value = val.toFixed(3);
this.bars.setLevel(this.slider.value / 100);
}
//input a value between 0-1
AudioUnit.GUI.Fader.prototype._inverseScale = function(x){
switch(this.scaling){
case "lin" :
return parseFloat(x);
case "log" :
return this.gainToLogScale(x);
case "exp" :
return this.gainToPowScale(x);
}
}
//input a value between 0-1
AudioUnit.GUI.Fader.prototype._scale = function(x){
switch(this.scaling){
case "lin" :
return parseFloat(x);
case "log" :
return this.gainToPowScale(x);
case "exp" :
return this.gainToLogScale(x);
}
}
//called when the value has changed
AudioUnit.GUI.Fader.prototype._setupEvents = function(){
this.textInput.onchange = this._onchangeText.bind(this);
this.slider.onchange = this._onchange.bind(this);
this.slider.onmousedown = this._mousedown.bind(this);
this.slider.onmouseup = this._mouseup.bind(this);
};
AudioUnit.GUI.Fader.prototype._mousedown = function(e){
this.isDragging = true;
}
AudioUnit.GUI.Fader.prototype._mouseup = function(e){
this.isDragging = false;
}

View file

@ -0,0 +1,55 @@
//@param {Element} container
//@param {AudioUnit.Meter} meter
//@param {string=} label
//@param {number=} segments
AudioUnit.GUI.Meter = function(container, meter, label, segments){
AudioUnit.GUI.call(this);
//components
this.meter = meter;
this.element = this.createElement();
this.bars = new Array(this.meter.channels);
this.label = this.createElement();
//add the bars
for (var i = 0; i < this.meter.channels; i++){
var bar = new AudioUnit.GUI.Bar(this.element, segments);
this.bars[i] = bar;
}
//set it up
this.setClass(this.element, "meter");
this.setClass(this.label, "label");
this.setLabel(this.defaultArg(label, ""));
this.onAnimationFrame(this.update, this);
this.onSlowUpdate(this.labelUpdate, this);
this.appendChild(container, this.element);
this.appendChild(this.element, this.label);
}
AudioUnit.extend(AudioUnit.GUI.Meter, AudioUnit.GUI);
AudioUnit.GUI.Meter.prototype.update = function(){
for (var channel = 0, channelCount = this.meter.channels; channel < channelCount; channel++){
var volume = this.meter.getLevel(channel);
this.bars[channel].setLevel(this.gainToLogScale(volume));
}
}
AudioUnit.GUI.Meter.prototype.labelUpdate = function(){
for (var channel = 0, channelCount = this.meter.channels; channel < channelCount; channel++){
var db = this.meter.getDb(channel);
if (db < -100){
db = "-inf"
} else {
db = db.toFixed(1);
}
this.bars[channel].setLabel(db);
}
}
//@param {string} str
AudioUnit.GUI.Meter.prototype.setLabel = function(str){
this.label.textContent = str;
}

View file

@ -47,12 +47,15 @@ window.requestAnimFrame = (function(){
function doSlowUpdate(){
setTimeout(doSlowUpdate, 250);
for (var i = 0; i < _onSlowUpdateCallbacks.length; i++){
var cback = _onSlowUpdateCallbacks[i];
cback.callback.call(cback.context);
}
}
doSlowUpdate();
function doFastUpdate(){
global.requestAnimFrame(doFastUpdate);
//remove from the updates
for (var i = 0; i < _onFastUpdateCallbacks.length; i++){
var cback = _onFastUpdateCallbacks[i];
cback.callback.call(cback.context);
@ -74,7 +77,7 @@ window.requestAnimFrame = (function(){
context : this.defaultArg(ctx, global),
id : id
}
_onFastUpdate.push(callback);
_onFastUpdateCallbacks.push(callbackObj);
}
//callback gets envoked at 60fps
@ -87,7 +90,7 @@ window.requestAnimFrame = (function(){
context : this.defaultArg(ctx, global),
id : id
}
_onSlowUpdateCallbacks.push(callback);
_onSlowUpdateCallbacks.push(callbackObj);
}
AudioUnit.GUI.prototype.remove = function(){
@ -122,6 +125,36 @@ window.requestAnimFrame = (function(){
}
}
//@param {Element} container
//@param {Element} element
AudioUnit.GUI.prototype.appendChild = function(container, element){
this._getElement(container).appendChild(this._getElement(element));
}
//@param {string=} type
AudioUnit.GUI.prototype.createElement = function(type){
type = this.defaultArg(type, "div");
return document.createElement(type);
}
//@param {Element} element
//@param {Element} unwraps jquery if necessary
AudioUnit.GUI.prototype._getElement = function(el){
if (typeof jQuery !== 'undefined' && el instanceof jQuery){
return el[0];
} else if (el.element && meterGui.element instanceof HTMLElement){
return el.element
} else {
return el;
}
}
//@param {Element} element
//@param {string} className
AudioUnit.GUI.prototype.setClass = function(element, className){
this._getElement(element).className = className;
}
///////////////////////////////////////////////////////////////////////////
// BORROW SOME METHODS
@ -131,6 +164,10 @@ window.requestAnimFrame = (function(){
AudioUnit.GUI.prototype.equalPowerGain = AudioUnit.prototype.equalPowerGain;
AudioUnit.GUI.prototype.dbToGain = AudioUnit.prototype.dbToGain;
AudioUnit.GUI.prototype.gainToDb = AudioUnit.prototype.gainToDb;
AudioUnit.GUI.prototype.gainToLogScale = AudioUnit.prototype.gainToLogScale;
AudioUnit.GUI.prototype.gainToPowScale = AudioUnit.prototype.gainToPowScale;
AudioUnit.GUI.prototype.interpolate = AudioUnit.prototype.interpolate;
AudioUnit.GUI.prototype.normalize = AudioUnit.prototype.normalize;
//give it to the window

View file

@ -28,7 +28,7 @@ AudioUnit.Meter = function(channels){
//signal just passes
this.input.connect(this.output);
this.input.connect(this.jsNode);
this.toSpeakers(this.jsNode);
this.toMaster(this.jsNode);
}
AudioUnit.extend(AudioUnit.Meter, AudioUnit);
@ -36,7 +36,7 @@ AudioUnit.extend(AudioUnit.Meter, AudioUnit);
//@param {number=} channel
//@returns {number}
AudioUnit.Meter.prototype.getVolume = function(channel){
AudioUnit.Meter.prototype.getLevel = function(channel){
channel = this.defaultArg(channel, 0);
var vol = this.volume[channel];
if (vol < .001){
@ -49,7 +49,7 @@ AudioUnit.Meter.prototype.getVolume = function(channel){
//@param {number=} channel
//@returns {number} the channel volume in decibels
AudioUnit.Meter.prototype.getDb = function(channel){
return this.gainToDb(this.getVolume(channel));
return this.gainToDb(this.getLevel(channel));
}
// @returns {boolean} if the audio has clipped in the last 500ms

View file

@ -71,11 +71,22 @@
//@param {AudioParam | AudioUnit} unit
AudioUnit.prototype.connect = function(unit){
if (unit.input && unit.input instanceof GainNode){
this.output.connect(unit.input);
} else {
this.output.connect(unit);
this._connect(this, unit);
}
//@private internal connect
//@param {AudioNode | AudioUnit} from
//@param {AudioNode | AudioUnit} to
AudioUnit.prototype._connect = function(A, B){
var compA = A;
if (A.output && A.output instanceof GainNode){
compA = A.output;
}
var compB = B;
if (B.input && B.input instanceof GainNode){
compB = B.input;
}
compA.connect(compB);
}
//connect together an array of units in series
@ -85,11 +96,7 @@
var currentUnit = arguments[0];
for (var i = 1; i < arguments.length; i++){
var toUnit = arguments[i];
if (toUnit.input && toUnit.input instanceof GainNode){
currentUnit.connect(toUnit.input);
} else {
currentUnit.connect(toUnit);
}
this._connect(currentUnit, toUnit);
currentUnit = toUnit;
}
}
@ -168,12 +175,43 @@
return 20 * (Math.log(gain) / Math.LN10);
}
//@param {AudioParam|AudioUnit=} unit
AudioUnit.prototype.toSpeakers = function(unit){
unit = this.defaultArg(unit, this.output);
unit.connect(audioContext.destination);
//@param {number} gain
//@returns {number} gain (decibel scale but betwee 0-1)
AudioUnit.prototype.gainToLogScale = function(gain) {
return Math.max(this.normalize(this.gainToDb(gain), -60, 0), 0);
}
//@param {number} gain
//@returns {number} gain (decibel scale but betwee 0-1)
AudioUnit.prototype.gainToPowScale = function(gain) {
return this.dbToGain(this.interpolate(gain, -60, 0));
}
//@param {number} input 0-1
AudioUnit.prototype.interpolate = function(input, outputMin, outputMax){
return input*(outputMax - outputMin) + outputMin;
}
//@returns {number} 0-1
AudioUnit.prototype.normalize = function(input, inputMin, inputMax){
//make sure that min < max
if (inputMin > inputMax){
var tmp = inputMax;
inputMax = inputMin;
inputMin = tmp;
} else if (inputMin == inputMax){
return 0;
}
return (input - inputMin) / (inputMax - inputMin);
}
//@param {AudioParam|AudioUnit=} unit
AudioUnit.prototype.toMaster = function(unit){
unit = this.defaultArg(unit, this.output);
this._connect(unit, AudioUnit.Master);
}
///////////////////////////////////////////////////////////////////////////
// STATIC METHODS
///////////////////////////////////////////////////////////////////////////
@ -184,19 +222,6 @@
A.prototype.constructor = A;
}
AudioUnit.muteAll = function(){
}
AudioUnit.unmuteAll = function(){
}
AudioUnit.setGlobalVolume = function(){
}
//make it global
global.AudioUnit = AudioUnit;

17
src/core/Master.js Normal file
View file

@ -0,0 +1,17 @@
(function(){
///////////////////////////////////////////////////////////////////////////
// MASTER OUTPUT
///////////////////////////////////////////////////////////////////////////
var Master = function(){
//extend audio unit
AudioUnit.call(this);
this.input.connect(this.output);
this.output.connect(this.context.destination);
}
AudioUnit.extend(Master, AudioUnit);
AudioUnit.Master = new Master();
})();

View file

@ -1,12 +1,20 @@
.label {
font-family: monospace;
text-align: center;
width: 100%; }
/*=============================================================================
BAR
=============================================================================*/
.bar {
pointer-events: none; }
.bar .segment {
width: 30px;
height: 6px;
margin-bottom: 2px;
opacity: 0;
-webkit-transition: opacity 0.016s linear;
-moz-transition: opacity 0.016s linear;
-o-transition: opacity 0.016s linear;
transition: opacity 0.016s linear; }
margin: 2px;
opacity: 1;
/*@include transitionAndTime(opacity, .016s);*/ }
.bar .segment.peak {
background-color: red; }
@ -16,3 +24,56 @@
.bar .segment.normal {
background-color: green; }
.meter .bar .label {
font-size: 10px; }
/*=============================================================================
METER
=============================================================================*/
.meter {
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; }
.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; }
.fader input.label {
padding: 0px;
border: 0px;
font-size: 10px;
height: 15px; }
.fader .bar .segment {
width: 40px;
background-color: black; }

View file

@ -1,3 +1,5 @@
$fastUpdateTime : .1s;
@mixin transitionAndTime($property, $time){
-webkit-transition: $property $time linear;
-moz-transition: $property $time linear;
@ -5,16 +7,33 @@
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 {
pointer-events: none;
}
.bar .segment {
width: 30px;
width: $unitWidth;
height: 6px;
margin-bottom: 2px;
opacity: 0;
@include transitionAndTime(opacity, .016s);
margin: 2px;
opacity: 1;
/*@include transitionAndTime(opacity, .016s);*/
}
.bar .segment.peak {
@ -28,3 +47,68 @@
.bar .segment.normal {
background-color: green;
}
.meter .bar .label {
font-size: 10px;
}
/*=============================================================================
METER
=============================================================================*/
.meter {
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;
}
.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;
}
.fader input.label {
padding: 0px;
border: 0px;
font-size: 10px;
height: 15px;
}
.fader .bar .segment {
width: $faderWidth;
background-color: black;
}