mirror of
https://github.com/Tonejs/Tone.js
synced 2024-12-28 12:33:12 +00:00
111 lines
3 KiB
TypeScript
111 lines
3 KiB
TypeScript
import { ToneAudioNode, ToneAudioNodeOptions } from "../../core/context/ToneAudioNode";
|
|
import { Decibels, Time } from "../../core/type/Units";
|
|
import { GreaterThan } from "../../signal/GreaterThan";
|
|
import { Gain } from "../../core/context/Gain";
|
|
import { Follower } from "../analysis/Follower";
|
|
import { optionsFromArguments } from "../../core/util/Defaults";
|
|
import { dbToGain, gainToDb } from "../../core/type/Conversions";
|
|
|
|
export interface GateOptions extends ToneAudioNodeOptions {
|
|
threshold: Decibels;
|
|
smoothing: Time;
|
|
}
|
|
|
|
/**
|
|
* Gate only passes a signal through when the incoming
|
|
* signal exceeds a specified threshold. It uses {@link Follower} to follow the ampltiude
|
|
* of the incoming signal and compares it to the {@link threshold} value using {@link GreaterThan}.
|
|
*
|
|
* @example
|
|
* const gate = new Tone.Gate(-30, 0.2).toDestination();
|
|
* const mic = new Tone.UserMedia().connect(gate);
|
|
* // the gate will only pass through the incoming
|
|
* // signal when it's louder than -30db
|
|
* @category Component
|
|
*/
|
|
export class Gate extends ToneAudioNode<GateOptions> {
|
|
|
|
readonly name: string = "Gate";
|
|
|
|
readonly input: ToneAudioNode;
|
|
readonly output: ToneAudioNode;
|
|
|
|
/**
|
|
* Follow the incoming signal
|
|
*/
|
|
private _follower: Follower;
|
|
|
|
/**
|
|
* Test if it's greater than the threshold
|
|
*/
|
|
private _gt: GreaterThan;
|
|
|
|
/**
|
|
* Gate the incoming signal when it does not exceed the threshold
|
|
*/
|
|
private _gate: Gain;
|
|
|
|
/**
|
|
* @param threshold The threshold above which the gate will open.
|
|
* @param smoothing The follower's smoothing time
|
|
*/
|
|
constructor(threshold?: Decibels, smoothing?: Time);
|
|
constructor(options?: Partial<GateOptions>);
|
|
constructor() {
|
|
super(Object.assign(optionsFromArguments(Gate.getDefaults(), arguments, ["threshold", "smoothing"])));
|
|
const options = optionsFromArguments(Gate.getDefaults(), arguments, ["threshold", "smoothing"]);
|
|
|
|
this._follower = new Follower({
|
|
context: this.context,
|
|
smoothing: options.smoothing,
|
|
});
|
|
this._gt = new GreaterThan({
|
|
context: this.context,
|
|
value: dbToGain(options.threshold),
|
|
});
|
|
this.input = new Gain({ context: this.context });
|
|
this._gate = this.output = new Gain({ context: this.context });
|
|
|
|
// connections
|
|
this.input.connect(this._gate);
|
|
// the control signal
|
|
this.input.chain(this._follower, this._gt, this._gate.gain);
|
|
}
|
|
|
|
static getDefaults(): GateOptions {
|
|
return Object.assign(ToneAudioNode.getDefaults(), {
|
|
smoothing: 0.1,
|
|
threshold: -40
|
|
});
|
|
}
|
|
|
|
/**
|
|
* The threshold of the gate in decibels
|
|
*/
|
|
get threshold(): Decibels {
|
|
return gainToDb(this._gt.value);
|
|
}
|
|
set threshold(thresh) {
|
|
this._gt.value = dbToGain(thresh);
|
|
}
|
|
|
|
/**
|
|
* The attack/decay speed of the gate.
|
|
* @see {@link Follower.smoothing}
|
|
*/
|
|
get smoothing(): Time {
|
|
return this._follower.smoothing;
|
|
}
|
|
set smoothing(smoothingTime) {
|
|
this._follower.smoothing = smoothingTime;
|
|
}
|
|
|
|
dispose(): this {
|
|
super.dispose();
|
|
this.input.dispose();
|
|
this._follower.dispose();
|
|
this._gt.dispose();
|
|
this._gate.dispose();
|
|
return this;
|
|
}
|
|
}
|