Tone.js/Tone/component/Analyser.js

158 lines
3.8 KiB
JavaScript
Raw Normal View History

2015-08-10 18:40:20 +00:00
define(["Tone/core/Tone"], function (Tone) {
2015-10-21 16:11:19 +00:00
"use strict";
2017-03-13 04:56:04 +00:00
/**
* AnalyserNode.getFloatTimeDomainData polyfill
* @private
*/
if (window.AnalyserNode && !AnalyserNode.prototype.getFloatTimeDomainData){
//referenced https://github.com/mohayonao/get-float-time-domain-data
AnalyserNode.prototype.getFloatTimeDomainData = function(array){
var uint8 = new Uint8Array(array.length);
this.getByteTimeDomainData(uint8);
for (var i = 0; i < uint8.length; i++){
array[i] = (uint8[i] - 128) / 128;
}
};
}
2015-08-10 18:40:20 +00:00
/**
* @class Wrapper around the native Web Audio's
* [AnalyserNode](http://webaudio.github.io/web-audio-api/#idl-def-AnalyserNode).
* Extracts FFT or Waveform data from the incoming signal.
* @extends {Tone}
* @param {String=} type The return type of the analysis, either "fft", or "waveform".
2015-08-10 18:40:20 +00:00
* @param {Number=} size The size of the FFT. Value must be a power of
* two in the range 32 to 32768.
*/
Tone.Analyser = function(){
var options = Tone.defaults(arguments, ["type", "size"], Tone.Analyser);
Tone.call(this);
2015-08-10 18:40:20 +00:00
/**
* The analyser node.
* @private
* @type {AnalyserNode}
*/
this._analyser = this.input = this.output = this.context.createAnalyser();
2015-08-10 18:40:20 +00:00
/**
* The analysis type
* @type {String}
* @private
*/
this._type = options.type;
/**
* The buffer that the FFT data is written to
* @type {TypedArray}
* @private
*/
this._buffer = null;
//set the values initially
this.size = options.size;
this.type = options.type;
};
Tone.extend(Tone.Analyser);
/**
* The default values.
* @type {Object}
* @const
*/
Tone.Analyser.defaults = {
"size" : 1024,
2015-08-10 18:40:20 +00:00
"type" : "fft",
"smoothing" : 0.8
2015-08-10 18:40:20 +00:00
};
/**
2016-04-17 17:41:54 +00:00
* Possible return types of Tone.Analyser.analyse()
2015-08-10 18:40:20 +00:00
* @enum {String}
*/
Tone.Analyser.Type = {
Waveform : "waveform",
FFT : "fft"
};
/**
* Run the analysis given the current settings and return the
* result as a TypedArray.
* @returns {TypedArray}
*/
Tone.Analyser.prototype.analyse = function(){
if (this._type === Tone.Analyser.Type.FFT){
this._analyser.getFloatFrequencyData(this._buffer);
2015-08-10 18:40:20 +00:00
} else if (this._type === Tone.Analyser.Type.Waveform){
this._analyser.getFloatTimeDomainData(this._buffer);
2015-08-10 18:40:20 +00:00
}
return this._buffer;
};
/**
* The size of analysis. This must be a power of two in the range 32 to 32768.
* @memberOf Tone.Analyser#
* @type {Number}
* @name size
*/
Object.defineProperty(Tone.Analyser.prototype, "size", {
get : function(){
return this._analyser.frequencyBinCount;
},
set : function(size){
this._analyser.fftSize = size * 2;
this._buffer = new Float32Array(size);
2015-08-10 18:40:20 +00:00
}
});
/**
2016-04-17 17:41:54 +00:00
* The analysis function returned by Tone.Analyser.analyse(), either "fft" or "waveform".
2015-08-10 18:40:20 +00:00
* @memberOf Tone.Analyser#
* @type {String}
* @name type
*/
Object.defineProperty(Tone.Analyser.prototype, "type", {
get : function(){
return this._type;
},
set : function(type){
if (type !== Tone.Analyser.Type.Waveform && type !== Tone.Analyser.Type.FFT){
2016-05-26 00:50:46 +00:00
throw new TypeError("Tone.Analyser: invalid type: "+type);
2015-08-10 18:40:20 +00:00
}
this._type = type;
}
});
/**
* 0 represents no time averaging with the last analysis frame.
* @memberOf Tone.Analyser#
* @type {NormalRange}
* @name smoothing
*/
Object.defineProperty(Tone.Analyser.prototype, "smoothing", {
get : function(){
return this._analyser.smoothingTimeConstant;
},
set : function(val){
this._analyser.smoothingTimeConstant = val;
}
});
/**
* Clean up.
* @return {Tone.Analyser} this
*/
Tone.Analyser.prototype.dispose = function(){
Tone.prototype.dispose.call(this);
this._analyser.disconnect();
this._analyser = null;
this._buffer = null;
};
return Tone.Analyser;
});