mirror of
https://github.com/Tonejs/Tone.js
synced 2024-12-29 04:53:10 +00:00
115 lines
2.9 KiB
TypeScript
115 lines
2.9 KiB
TypeScript
import { ToneAudioNode, ToneAudioNodeOptions } from "../../core/context/ToneAudioNode";
|
|
import { optionsFromArguments } from "../../core/util/Defaults";
|
|
|
|
type AnalyserType = "fft" | "waveform";
|
|
|
|
interface AnalyserOptions extends ToneAudioNodeOptions {
|
|
size: PowerOfTwo;
|
|
type: AnalyserType;
|
|
smoothing: NormalRange;
|
|
}
|
|
|
|
/**
|
|
* 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.
|
|
* @param type The return type of the analysis, either "fft", or "waveform".
|
|
* @param size The size of the FFT. This must be a power of two in the range 16 to 16384.
|
|
*/
|
|
export class Analyser extends ToneAudioNode<AnalyserOptions> {
|
|
|
|
name = "Analyser";
|
|
|
|
input: AnalyserNode;
|
|
output: AnalyserNode;
|
|
|
|
/**
|
|
* The analyser node.
|
|
*/
|
|
private _analyser = this.context.createAnalyser();
|
|
protected _internalChannels = [this._analyser];
|
|
|
|
/**
|
|
* The analysis type
|
|
*/
|
|
private _type!: AnalyserType;
|
|
|
|
/**
|
|
* The buffer that the FFT data is written to
|
|
*/
|
|
private _buffer!: Float32Array;
|
|
|
|
constructor(type?: AnalyserType, size?: number);
|
|
constructor(options?: Partial<AnalyserOptions>);
|
|
constructor() {
|
|
super(optionsFromArguments(Analyser.getDefaults(), arguments, ["type", "size"]));
|
|
const options = optionsFromArguments(Analyser.getDefaults(), arguments, ["type", "size"]);
|
|
// set the values initially
|
|
this.size = options.size;
|
|
this.type = options.type;
|
|
this.input = this.output = this._analyser;
|
|
}
|
|
|
|
static getDefaults(): AnalyserOptions {
|
|
return Object.assign(ToneAudioNode.getDefaults(), {
|
|
numberOfInputs: 1,
|
|
numberOfOutputs: 1,
|
|
size: 1024,
|
|
smoothing: 0.8,
|
|
type: "fft" as AnalyserType,
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Run the analysis given the current settings and return the
|
|
*/
|
|
getValue(): Float32Array {
|
|
if (this._type === "fft") {
|
|
this._analyser.getFloatFrequencyData(this._buffer);
|
|
} else if (this._type === "waveform") {
|
|
this._analyser.getFloatTimeDomainData(this._buffer);
|
|
}
|
|
return this._buffer;
|
|
}
|
|
|
|
/**
|
|
* The size of analysis. This must be a power of two in the range 16 to 16384.
|
|
*/
|
|
get size(): PowerOfTwo {
|
|
return this._analyser.frequencyBinCount;
|
|
}
|
|
set size(size: PowerOfTwo) {
|
|
this._analyser.fftSize = size * 2;
|
|
this._buffer = new Float32Array(size);
|
|
}
|
|
|
|
/**
|
|
* The analysis function returned by analyser.getValue(), either "fft" or "waveform".
|
|
*/
|
|
get type(): AnalyserType {
|
|
return this._type;
|
|
}
|
|
set type(type: AnalyserType) {
|
|
this.assert(type === "waveform" || type === "fft", `Analyser: invalid type: ${type}`);
|
|
this._type = type;
|
|
}
|
|
|
|
/**
|
|
* 0 represents no time averaging with the last analysis frame.
|
|
*/
|
|
get smoothing(): NormalRange {
|
|
return this._analyser.smoothingTimeConstant;
|
|
}
|
|
|
|
set smoothing(val: NormalRange) {
|
|
this._analyser.smoothingTimeConstant = val;
|
|
}
|
|
|
|
/**
|
|
* Clean up.
|
|
*/
|
|
dispose(): this {
|
|
super.dispose();
|
|
this._analyser.disconnect();
|
|
return this;
|
|
}
|
|
}
|