mirror of
https://github.com/Tonejs/Tone.js
synced 2024-11-16 16:48:00 +00:00
58a1223a9a
no more ScriptProcessorNodes
155 lines
No EOL
3.8 KiB
JavaScript
155 lines
No EOL
3.8 KiB
JavaScript
define(["Tone/core/Tone", "Tone/component/Analyser"], function(Tone){
|
|
|
|
"use strict";
|
|
|
|
/**
|
|
* @class Tone.Meter gets the [RMS](https://en.wikipedia.org/wiki/Root_mean_square)
|
|
* of an input signal with some averaging applied.
|
|
* It can also get the raw value of the signal or the value in dB. For signal
|
|
* processing, it's better to use Tone.Follower which will produce an audio-rate
|
|
* envelope follower instead of needing to poll the Meter to get the output.
|
|
* <br><br>
|
|
* Meter was inspired by [Chris Wilsons Volume Meter](https://github.com/cwilso/volume-meter/blob/master/volume-meter.js).
|
|
*
|
|
* @constructor
|
|
* @extends {Tone}
|
|
* @param {number} [channels=1] number of channels being metered
|
|
* @param {number} [smoothing=0.8] amount of smoothing applied to the volume
|
|
* @param {number} [clipMemory=0.5] number in seconds that a "clip" should be remembered
|
|
* @example
|
|
* var meter = new Tone.Meter();
|
|
* var mic = new Tone.Microphone().start();
|
|
* //connect mic to the meter
|
|
* mic.connect(meter);
|
|
* //use getLevel or getDb
|
|
* //to access meter level
|
|
* meter.getLevel();
|
|
*/
|
|
Tone.Meter = function(){
|
|
|
|
var options = this.optionsObject(arguments, ["type", "smoothing"], Tone.Meter.defaults);
|
|
|
|
/**
|
|
* @private
|
|
* Hold the type of the Meter
|
|
* @type {String}
|
|
*/
|
|
this._type = options.type;
|
|
|
|
/**
|
|
* The analyser node which computes the levels.
|
|
* @private
|
|
* @type {Tone.Analyser}
|
|
*/
|
|
this.input = this.output = this._analyser = new Tone.Analyser("fft", 32);
|
|
|
|
// set some ranges
|
|
this._analyser.minDecibels = -120;
|
|
this._analyser.maxDecibels = 10;
|
|
this._analyser.returnType = "float";
|
|
|
|
this.type = options.type;
|
|
this.smoothing = options.smoothing;
|
|
};
|
|
|
|
Tone.extend(Tone.Meter);
|
|
|
|
/**
|
|
* @private
|
|
* @enum {String}
|
|
*/
|
|
Tone.Meter.Type = {
|
|
Level : "level",
|
|
Signal : "signal"
|
|
};
|
|
|
|
/**
|
|
* The defaults
|
|
* @type {Object}
|
|
* @static
|
|
* @const
|
|
*/
|
|
Tone.Meter.defaults = {
|
|
"smoothing" : 0.8,
|
|
"type" : Tone.Meter.Type.Level
|
|
};
|
|
|
|
/**
|
|
* The smoothing which is applied meter (only for "level" type)
|
|
* @memberOf Tone.Meter#
|
|
* @type {NormalRange}
|
|
* @name smoothing
|
|
*/
|
|
Object.defineProperty(Tone.Meter.prototype, "smoothing", {
|
|
get : function(){
|
|
return this._analyser.smoothingTimeConstant;
|
|
},
|
|
set : function(smoothing){
|
|
this._analyser.smoothingTimeConstant = smoothing;
|
|
},
|
|
});
|
|
|
|
/**
|
|
* The type of the meter, either "level" or "signal".
|
|
* A level meter will return the volume level of the
|
|
* inpute signal and a value meter will return
|
|
* the signal value of the input.
|
|
* @memberOf Tone.Meter#
|
|
* @type {String}
|
|
* @name type
|
|
*/
|
|
Object.defineProperty(Tone.Meter.prototype, "type", {
|
|
get : function(){
|
|
return this._type;
|
|
},
|
|
set : function(type){
|
|
this._type = type;
|
|
if (type === Tone.Meter.Type.Level){
|
|
this._analyser.type = "fft";
|
|
} else if (type === Tone.Meter.Type.Signal){
|
|
this._analyser.type = "waveform";
|
|
}
|
|
},
|
|
});
|
|
|
|
/**
|
|
* The current value of the meter.
|
|
* @memberOf Tone.Meter#
|
|
* @type {Number}
|
|
* @name value
|
|
* @readOnly
|
|
*/
|
|
Object.defineProperty(Tone.Meter.prototype, "value", {
|
|
get : function(){
|
|
var analysis = this._analyser.analyse();
|
|
if (this._type === Tone.Meter.Type.Level){
|
|
var max = -Infinity;
|
|
for (var i = 0; i < analysis.length; i++){
|
|
max = Math.max(analysis[i], max);
|
|
}
|
|
//scale [-100,0] to [0, 1]
|
|
var min = this._analyser.minDecibels;
|
|
if (max < min){
|
|
return 0;
|
|
} else {
|
|
return (max - min) / -min;
|
|
}
|
|
} else {
|
|
return analysis[0];
|
|
}
|
|
},
|
|
});
|
|
|
|
/**
|
|
* Clean up.
|
|
* @returns {Tone.Meter} this
|
|
*/
|
|
Tone.Meter.prototype.dispose = function(){
|
|
Tone.prototype.dispose.call(this);
|
|
this._analyser.dispose();
|
|
this._analyser = null;
|
|
return this;
|
|
};
|
|
|
|
return Tone.Meter;
|
|
}); |