2016-05-14 23:13:50 +00:00
|
|
|
define(["Tone/core/Tone", "Tone/component/Analyser"], function(Tone){
|
2014-03-11 23:27:46 +00:00
|
|
|
|
2014-09-04 04:41:40 +00:00
|
|
|
"use strict";
|
|
|
|
|
2014-06-16 01:18:29 +00:00
|
|
|
/**
|
2015-07-04 19:25:37 +00:00
|
|
|
* @class Tone.Meter gets the [RMS](https://en.wikipedia.org/wiki/Root_mean_square)
|
2016-05-18 01:26:57 +00:00
|
|
|
* of an input signal with some averaging applied. It can also get the raw
|
|
|
|
* value of the input signal.
|
2014-06-16 01:18:29 +00:00
|
|
|
*
|
|
|
|
* @constructor
|
|
|
|
* @extends {Tone}
|
2016-05-18 01:26:57 +00:00
|
|
|
* @param {String} type Either "level" or "signal".
|
|
|
|
* @param {Number} smoothing The amount of smoothing applied between frames.
|
2015-07-02 00:19:58 +00:00
|
|
|
* @example
|
|
|
|
* var meter = new Tone.Meter();
|
2017-01-08 20:58:58 +00:00
|
|
|
* var mic = new Tone.UserMedia().start();
|
2015-07-02 00:19:58 +00:00
|
|
|
* //connect mic to the meter
|
|
|
|
* mic.connect(meter);
|
2016-05-18 01:26:57 +00:00
|
|
|
* //the current level of the mic input
|
|
|
|
* var level = meter.value;
|
2014-06-16 01:18:29 +00:00
|
|
|
*/
|
2015-08-28 22:32:20 +00:00
|
|
|
Tone.Meter = function(){
|
|
|
|
|
2016-05-14 23:13:50 +00:00
|
|
|
var options = this.optionsObject(arguments, ["type", "smoothing"], Tone.Meter.defaults);
|
|
|
|
|
2015-08-28 22:32:20 +00:00
|
|
|
/**
|
2016-05-18 01:26:57 +00:00
|
|
|
* The type of the meter, either "level" or "signal".
|
|
|
|
* A "level" meter will return the volume level (rms) of the
|
|
|
|
* input signal and a "signal" meter will return
|
|
|
|
* the signal value of the input.
|
2016-05-14 23:13:50 +00:00
|
|
|
* @type {String}
|
2014-06-16 01:18:29 +00:00
|
|
|
*/
|
2016-05-18 01:26:57 +00:00
|
|
|
this.type = options.type;
|
2014-06-16 01:18:29 +00:00
|
|
|
|
2016-05-14 23:13:50 +00:00
|
|
|
/**
|
|
|
|
* The analyser node which computes the levels.
|
2014-06-16 01:18:29 +00:00
|
|
|
* @private
|
2016-05-14 23:13:50 +00:00
|
|
|
* @type {Tone.Analyser}
|
2014-06-16 01:18:29 +00:00
|
|
|
*/
|
2016-05-18 01:26:57 +00:00
|
|
|
this.input = this.output = this._analyser = new Tone.Analyser("waveform", 512);
|
2016-05-14 23:13:50 +00:00
|
|
|
this._analyser.returnType = "float";
|
2014-03-11 23:27:46 +00:00
|
|
|
|
2016-05-18 01:26:57 +00:00
|
|
|
/**
|
|
|
|
* The amount of carryover between the current and last frame.
|
|
|
|
* Only applied meter for "level" type.
|
|
|
|
* @type {Number}
|
|
|
|
*/
|
2016-05-14 23:13:50 +00:00
|
|
|
this.smoothing = options.smoothing;
|
2016-05-18 01:26:57 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* The last computed value
|
|
|
|
* @type {Number}
|
|
|
|
* @private
|
|
|
|
*/
|
|
|
|
this._lastValue = 0;
|
2014-06-15 22:19:05 +00:00
|
|
|
};
|
2014-03-11 23:27:46 +00:00
|
|
|
|
2014-06-16 01:18:29 +00:00
|
|
|
Tone.extend(Tone.Meter);
|
2014-03-11 23:27:46 +00:00
|
|
|
|
2016-05-14 23:13:50 +00:00
|
|
|
/**
|
|
|
|
* @private
|
|
|
|
* @enum {String}
|
|
|
|
*/
|
|
|
|
Tone.Meter.Type = {
|
|
|
|
Level : "level",
|
|
|
|
Signal : "signal"
|
|
|
|
};
|
|
|
|
|
2015-08-28 22:32:20 +00:00
|
|
|
/**
|
|
|
|
* The defaults
|
|
|
|
* @type {Object}
|
|
|
|
* @static
|
|
|
|
* @const
|
|
|
|
*/
|
|
|
|
Tone.Meter.defaults = {
|
|
|
|
"smoothing" : 0.8,
|
2016-05-14 23:13:50 +00:00
|
|
|
"type" : Tone.Meter.Type.Level
|
2015-08-28 22:32:20 +00:00
|
|
|
};
|
|
|
|
|
2014-06-16 01:18:29 +00:00
|
|
|
/**
|
2016-05-18 01:26:57 +00:00
|
|
|
* The current value of the meter. A value of 1 is
|
|
|
|
* "unity".
|
2016-05-14 23:13:50 +00:00
|
|
|
* @memberOf Tone.Meter#
|
|
|
|
* @type {Number}
|
|
|
|
* @name value
|
|
|
|
* @readOnly
|
2015-02-02 17:49:13 +00:00
|
|
|
*/
|
2016-05-14 23:13:50 +00:00
|
|
|
Object.defineProperty(Tone.Meter.prototype, "value", {
|
|
|
|
get : function(){
|
2016-05-18 01:26:57 +00:00
|
|
|
var signal = this._analyser.analyse();
|
|
|
|
if (this.type === Tone.Meter.Type.Level){
|
|
|
|
//rms
|
|
|
|
var sum = 0;
|
|
|
|
for (var i = 0; i < signal.length; i++){
|
|
|
|
sum += Math.pow(signal[i], 2);
|
2016-05-14 23:13:50 +00:00
|
|
|
}
|
2016-05-18 01:26:57 +00:00
|
|
|
var rms = Math.sqrt(sum / signal.length);
|
|
|
|
//smooth it
|
|
|
|
rms = Math.max(rms, this._lastValue * this.smoothing);
|
|
|
|
this._lastValue = rms;
|
|
|
|
//scale it
|
|
|
|
var unity = 0.35;
|
|
|
|
var val = rms / unity;
|
|
|
|
//scale the output curve
|
|
|
|
return Math.sqrt(val);
|
2016-05-14 23:13:50 +00:00
|
|
|
} else {
|
2016-05-18 01:26:57 +00:00
|
|
|
return signal[0];
|
2016-05-14 23:13:50 +00:00
|
|
|
}
|
|
|
|
},
|
|
|
|
});
|
2014-04-05 22:05:42 +00:00
|
|
|
|
2014-06-19 02:35:31 +00:00
|
|
|
/**
|
2015-06-20 23:25:49 +00:00
|
|
|
* Clean up.
|
2015-06-14 00:54:29 +00:00
|
|
|
* @returns {Tone.Meter} this
|
2014-06-19 02:35:31 +00:00
|
|
|
*/
|
|
|
|
Tone.Meter.prototype.dispose = function(){
|
2014-08-24 20:24:16 +00:00
|
|
|
Tone.prototype.dispose.call(this);
|
2016-05-14 23:13:50 +00:00
|
|
|
this._analyser.dispose();
|
|
|
|
this._analyser = null;
|
2015-02-02 17:49:13 +00:00
|
|
|
return this;
|
2014-06-19 02:35:31 +00:00
|
|
|
};
|
|
|
|
|
2014-04-05 22:05:42 +00:00
|
|
|
return Tone.Meter;
|
|
|
|
});
|