tone
Version:
A Web Audio framework for making interactive music in the browser.
170 lines • 6.81 kB
JavaScript
import * as tslib_1 from "tslib";
import { Gain } from "../../core/context/Gain";
import { connectSeries, ToneAudioNode } from "../../core/context/ToneAudioNode";
import { optionsFromArguments } from "../../core/util/Defaults";
import { readOnly, writable } from "../../core/util/Interface";
import { isNumber } from "../../core/util/TypeCheck";
import { Signal } from "../../signal/Signal";
import { assert } from "../../core/util/Debug";
/**
* Tone.Filter is a filter which allows for all of the same native methods
* as the [BiquadFilterNode](http://webaudio.github.io/web-audio-api/#the-biquadfilternode-interface).
* Tone.Filter has the added ability to set the filter rolloff at -12
* (default), -24 and -48.
* @example
* import { Filter, Noise } from "tone";
*
* const filter = new Filter(1500, "highpass").toDestination();
* filter.frequency.rampTo(20000, 10);
* const noise = new Noise().connect(filter).start();
* @category Component
*/
var Filter = /** @class */ (function (_super) {
tslib_1.__extends(Filter, _super);
function Filter() {
var _this = _super.call(this, optionsFromArguments(Filter.getDefaults(), arguments, ["frequency", "type", "rolloff"])) || this;
_this.name = "Filter";
_this.input = new Gain({ context: _this.context });
_this.output = new Gain({ context: _this.context });
_this._filters = [];
var options = optionsFromArguments(Filter.getDefaults(), arguments, ["frequency", "type", "rolloff"]);
_this._filters = [];
_this.Q = new Signal({
context: _this.context,
units: "positive",
value: options.Q,
});
_this.frequency = new Signal({
context: _this.context,
units: "frequency",
value: options.frequency,
});
_this.detune = new Signal({
context: _this.context,
units: "cents",
value: options.detune,
});
_this.gain = new Signal({
context: _this.context,
units: "decibels",
value: options.gain,
});
_this._type = options.type;
_this.rolloff = options.rolloff;
readOnly(_this, ["detune", "frequency", "gain", "Q"]);
return _this;
}
Filter.getDefaults = function () {
return Object.assign(ToneAudioNode.getDefaults(), {
Q: 1,
detune: 0,
frequency: 350,
gain: 0,
rolloff: -12,
type: "lowpass",
});
};
Object.defineProperty(Filter.prototype, "type", {
/**
* The type of the filter. Types: "lowpass", "highpass",
* "bandpass", "lowshelf", "highshelf", "notch", "allpass", or "peaking".
*/
get: function () {
return this._type;
},
set: function (type) {
var types = ["lowpass", "highpass", "bandpass",
"lowshelf", "highshelf", "notch", "allpass", "peaking"];
assert(types.indexOf(type) !== -1, "Invalid filter type: " + type);
this._type = type;
this._filters.forEach(function (filter) { return filter.type = type; });
},
enumerable: true,
configurable: true
});
Object.defineProperty(Filter.prototype, "rolloff", {
/**
* The rolloff of the filter which is the drop in db
* per octave. Implemented internally by cascading filters.
* Only accepts the values -12, -24, -48 and -96.
*/
get: function () {
return this._rolloff;
},
set: function (rolloff) {
var rolloffNum = isNumber(rolloff) ? rolloff : parseInt(rolloff, 10);
var possibilities = [-12, -24, -48, -96];
var cascadingCount = possibilities.indexOf(rolloffNum);
// check the rolloff is valid
assert(cascadingCount !== -1, "rolloff can only be " + possibilities.join(", "));
cascadingCount += 1;
this._rolloff = rolloffNum;
this.input.disconnect();
this._filters.forEach(function (filter) { return filter.disconnect(); });
this._filters = new Array(cascadingCount);
for (var count = 0; count < cascadingCount; count++) {
var filter = this.context.createBiquadFilter();
filter.type = this._type;
this.frequency.connect(filter.frequency);
this.detune.connect(filter.detune);
this.Q.connect(filter.Q);
this.gain.connect(filter.gain);
this._filters[count] = filter;
}
this._internalChannels = this._filters;
connectSeries.apply(void 0, tslib_1.__spread([this.input], this._internalChannels, [this.output]));
},
enumerable: true,
configurable: true
});
/**
* Get the frequency response curve. This curve represents how the filter
* responses to frequencies between 20hz-20khz.
* @param len The number of values to return
* @return The frequency response curve between 20-20kHz
*/
Filter.prototype.getFrequencyResponse = function (len) {
var _this = this;
if (len === void 0) { len = 128; }
// start with all 1s
var totalResponse = new Float32Array(len).map(function () { return 1; });
var freqValues = new Float32Array(len);
for (var i = 0; i < len; i++) {
var norm = Math.pow(i / len, 2);
var freq = norm * (20000 - 20) + 20;
freqValues[i] = freq;
}
var magValues = new Float32Array(len);
var phaseValues = new Float32Array(len);
this._filters.forEach(function () {
var filterClone = _this.context.createBiquadFilter();
filterClone.type = _this._type;
filterClone.Q.value = _this.Q.value;
filterClone.frequency.value = _this.frequency.value;
filterClone.gain.value = _this.gain.value;
filterClone.getFrequencyResponse(freqValues, magValues, phaseValues);
magValues.forEach(function (val, i) {
totalResponse[i] *= val;
});
});
return totalResponse;
};
/**
* Clean up.
*/
Filter.prototype.dispose = function () {
_super.prototype.dispose.call(this);
this._filters.forEach(function (filter) {
filter.disconnect();
});
writable(this, ["detune", "frequency", "gain", "Q"]);
this.frequency.dispose();
this.Q.dispose();
this.detune.dispose();
this.gain.dispose();
return this;
};
return Filter;
}(ToneAudioNode));
export { Filter };
//# sourceMappingURL=Filter.js.map