From 982fd3b4076e9555c38214de857303fcc021f5b7 Mon Sep 17 00:00:00 2001 From: Yotam Mann Date: Sun, 15 Jun 2014 21:18:29 -0400 Subject: [PATCH] jsdoc + jshint. some name changes --- Tone/component/Meter.js | 168 +++++++++++++++++++++++++--------------- 1 file changed, 107 insertions(+), 61 deletions(-) diff --git a/Tone/component/Meter.js b/Tone/component/Meter.js index dc517225..c4c4284d 100644 --- a/Tone/component/Meter.js +++ b/Tone/component/Meter.js @@ -1,77 +1,83 @@ -/////////////////////////////////////////////////////////////////////////////// -// -// METER -// -// get the rms of the input signal with some averaging -// -// inspired by https://github.com/cwilso/volume-meter/blob/master/volume-meter.js -// The MIT License (MIT) Copyright (c) 2014 Chris Wilson -/////////////////////////////////////////////////////////////////////////////// - define(["Tone/core/Tone", "Tone/core/Master"], function(Tone){ - //@param {number=} channels - Tone.Meter = function(channels){ + /** + * get the rms of the input signal with some averaging + * can also just get the value of the signal + * or the value in dB + * + * inspired by https://github.com/cwilso/volume-meter/blob/master/volume-meter.js + * The MIT License (MIT) Copyright (c) 2014 Chris Wilson + * + * @constructor + * @extends {Tone} + * @param {number=} channels (optional) number of channels being metered + * @param {number=} smoothing (optional) amount of smoothing applied to the volume + * @param {number=} clipMemory (optional) number in ms that a "clip" should be remembered + */ + Tone.Meter = function(channels, smoothing, clipMemory){ //extends Unit Tone.call(this); + /** @type {number} */ this.channels = this.defaultArg(channels, 1); - this.volume = new Array(this.channels); - this.values = new Array(this.channels); + + /** @type {number} */ + this.smoothing = this.defaultArg(smoothing, 0.8); + + /** @type {number} */ + this.clipMemory = this.defaultArg(clipMemory, 500); + + /** + * @private + * @type {Array} + * the rms for each of the channels + */ + this._volume = new Array(this.channels); + + /** + * @private + * @type {Array} + * the raw values for each of the 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._volume[i] = 0; + this._values[i] = 0; } - this.clipTime = 0; + + /** + * @private + * @type {number} + * last time the values clipped + */ + this._lastClip = 0; - //components - this.jsNode = this.context.createScriptProcessor(this.bufferSize, this.channels, this.channels); - this.jsNode.onaudioprocess = this.onprocess.bind(this); + /** + * @private + * @type {ScriptProcessorNode} + */ + this._jsNode = this.context.createScriptProcessor(this.bufferSize, this.channels, 0); + this._jsNode.onaudioprocess = this._onprocess.bind(this); + //so it doesn't get garbage collected + this._jsNode.toMaster(); //signal just passes this.input.connect(this.output); - this.input.connect(this.jsNode); - //so it doesn't get garbage collected - this.jsNode.toMaster(); + this.input.connect(this._jsNode); }; - Tone.extend(Tone.Meter, Tone); + Tone.extend(Tone.Meter); - - //@param {number=} channel - //@returns {number} - Tone.Meter.prototype.getLevel = function(channel){ - channel = this.defaultArg(channel, 0); - var vol = this.volume[channel]; - if (vol < 0.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; + /** + * called on each processing frame + * @private + * @param {AudioProcessingEvent} event + */ + Tone.Meter.prototype._onprocess = function(event){ + var bufferSize = this._jsNode.bufferSize; + var smoothing = this.smoothing; for (var channel = 0; channel < this.channels; channel++){ var input = event.inputBuffer.getChannelData(channel); var sum = 0; @@ -82,17 +88,57 @@ define(["Tone/core/Tone", "Tone/core/Master"], function(Tone){ x = input[i]; if (!clipped && x > 0.95){ clipped = true; - this.clipTime = Date.now(); + this._lastClip = 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] * 0.8); - this.values[channel] = average; + this._volume[channel] = Math.max(rms, this._volume[channel] * smoothing); + this._values[channel] = average; } }; + /** + * get the rms of the signal + * + * @param {number=} channel which channel + * @return {number} the value + */ + Tone.Meter.prototype.getLevel = function(channel){ + channel = this.defaultArg(channel, 0); + var vol = this._volume[channel]; + if (vol < 0.00001){ + return 0; + } else { + return vol; + } + }; + + /** + * get the value of the signal + * @param {number=} channel + * @return {number} + */ + Tone.Meter.prototype.getValue = function(channel){ + channel = this.defaultArg(channel, 0); + return this._values[channel]; + }; + + /** + * get the volume of the signal in dB + * @param {number=} channel + * @return {number} + */ + 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._lastClip < this.clipMemory; + }; + return Tone.Meter; }); \ No newline at end of file