mirror of
https://github.com/Tonejs/Tone.js
synced 2024-11-15 16:17:58 +00:00
106 lines
3.2 KiB
TypeScript
106 lines
3.2 KiB
TypeScript
import { StereoXFeedbackEffect, StereoXFeedbackEffectOptions } from "./StereoXFeedbackEffect";
|
|
import { NormalRange, Seconds, Time } from "../core/type/Units";
|
|
import { optionsFromArguments } from "../core/util/Defaults";
|
|
import { Delay } from "../core/context/Delay";
|
|
import { Signal } from "../signal/Signal";
|
|
import { readOnly } from "../core/util/Interface";
|
|
|
|
export interface PingPongDelayOptions extends StereoXFeedbackEffectOptions {
|
|
delayTime: Time;
|
|
maxDelay: Seconds;
|
|
}
|
|
|
|
/**
|
|
* PingPongDelay is a feedback delay effect where the echo is heard
|
|
* first in one channel and next in the opposite channel. In a stereo
|
|
* system these are the right and left channels.
|
|
* PingPongDelay in more simplified terms is two Tone.FeedbackDelays
|
|
* with independent delay values. Each delay is routed to one channel
|
|
* (left or right), and the channel triggered second will always
|
|
* trigger at the same interval after the first.
|
|
* @example
|
|
* import { MembraneSynth, PingPongDelay } from "tone";
|
|
* const pingPong = new PingPongDelay("4n", 0.2).toDestination();
|
|
* const drum = new MembraneSynth().connect(pingPong);
|
|
* drum.triggerAttackRelease("C4", "32n");
|
|
* @category Effect
|
|
*/
|
|
export class PingPongDelay extends StereoXFeedbackEffect<PingPongDelayOptions> {
|
|
|
|
readonly name: string = "PingPongDelay";
|
|
|
|
/**
|
|
* the delay node on the left side
|
|
*/
|
|
private _leftDelay: Delay;
|
|
|
|
/**
|
|
* the delay node on the right side
|
|
*/
|
|
private _rightDelay: Delay;
|
|
|
|
/**
|
|
* the predelay on the right side
|
|
*/
|
|
private _rightPreDelay: Delay;
|
|
|
|
/**
|
|
* the delay time signal
|
|
*/
|
|
readonly delayTime: Signal<"time">;
|
|
|
|
/**
|
|
* @param delayTime The delayTime between consecutive echos.
|
|
* @param feedback The amount of the effected signal which is fed back through the delay.
|
|
*/
|
|
constructor(delayTime?: Time, feedback?: NormalRange);
|
|
constructor(options?: Partial<PingPongDelayOptions>);
|
|
constructor() {
|
|
|
|
super(optionsFromArguments(PingPongDelay.getDefaults(), arguments, ["delayTime", "feedback"]));
|
|
const options = optionsFromArguments(PingPongDelay.getDefaults(), arguments, ["delayTime", "feedback"]);
|
|
|
|
this._leftDelay = new Delay({
|
|
context: this.context,
|
|
maxDelay: options.maxDelay,
|
|
});
|
|
this._rightDelay = new Delay({
|
|
context: this.context,
|
|
maxDelay: options.maxDelay
|
|
});
|
|
this._rightPreDelay = new Delay({
|
|
context: this.context,
|
|
maxDelay: options.maxDelay
|
|
});
|
|
this.delayTime = new Signal({
|
|
context: this.context,
|
|
units: "time",
|
|
value: options.delayTime,
|
|
});
|
|
|
|
// connect it up
|
|
this.connectEffectLeft(this._leftDelay);
|
|
this.connectEffectRight(this._rightPreDelay, this._rightDelay);
|
|
this.delayTime.fan(this._leftDelay.delayTime, this._rightDelay.delayTime, this._rightPreDelay.delayTime);
|
|
// rearranged the feedback to be after the rightPreDelay
|
|
this._feedbackL.disconnect();
|
|
this._feedbackL.connect(this._rightDelay);
|
|
readOnly(this, ["delayTime"]);
|
|
}
|
|
|
|
static getDefaults(): PingPongDelayOptions {
|
|
return Object.assign(StereoXFeedbackEffect.getDefaults(), {
|
|
delayTime: 0.25,
|
|
maxDelay: 1
|
|
});
|
|
}
|
|
|
|
dispose(): this {
|
|
super.dispose();
|
|
this._leftDelay.dispose();
|
|
this._rightDelay.dispose();
|
|
this._rightPreDelay.dispose();
|
|
this.delayTime.dispose();
|
|
return this;
|
|
}
|
|
}
|