UNPKG

2.52 kBPlain TextView Raw
1import { StereoEffect, StereoEffectOptions } from "./StereoEffect.js";
2import { NormalRange } from "../core/type/Units.js";
3import { Signal } from "../signal/Signal.js";
4import { Gain } from "../core/context/Gain.js";
5import { readOnly } from "../core/util/Interface.js";
6import { Split } from "../component/channel/Split.js";
7import { Merge } from "../component/channel/Merge.js";
8
9export interface StereoFeedbackEffectOptions extends StereoEffectOptions {
10 feedback: NormalRange;
11}
12
13/**
14 * Base class for stereo feedback effects where the effectReturn is fed back into the same channel.
15 */
16export class StereoFeedbackEffect<
17 Options extends StereoFeedbackEffectOptions,
18> extends StereoEffect<Options> {
19 /**
20 * The amount of feedback from the output
21 * back into the input of the effect (routed
22 * across left and right channels).
23 */
24 readonly feedback: Signal<"normalRange">;
25
26 /**
27 * the left side feedback
28 */
29 protected _feedbackL: Gain;
30
31 /**
32 * the right side feedback
33 */
34 protected _feedbackR: Gain;
35
36 /**
37 * Split the channels for feedback
38 */
39 protected _feedbackSplit: Split;
40
41 /**
42 * Merge the channels for feedback
43 */
44 protected _feedbackMerge: Merge;
45
46 constructor(options: StereoFeedbackEffectOptions) {
47 super(options);
48
49 this.feedback = new Signal({
50 context: this.context,
51 value: options.feedback,
52 units: "normalRange",
53 });
54 this._feedbackL = new Gain({ context: this.context });
55 this._feedbackR = new Gain({ context: this.context });
56
57 this._feedbackSplit = new Split({ context: this.context, channels: 2 });
58 this._feedbackMerge = new Merge({ context: this.context, channels: 2 });
59
60 this._merge.connect(this._feedbackSplit);
61 this._feedbackMerge.connect(this._split);
62
63 // the left output connected to the left input
64 this._feedbackSplit.connect(this._feedbackL, 0, 0);
65 this._feedbackL.connect(this._feedbackMerge, 0, 0);
66
67 // the right output connected to the right input
68 this._feedbackSplit.connect(this._feedbackR, 1, 0);
69 this._feedbackR.connect(this._feedbackMerge, 0, 1);
70
71 // the feedback control
72 this.feedback.fan(this._feedbackL.gain, this._feedbackR.gain);
73 readOnly(this, ["feedback"]);
74 }
75
76 static getDefaults(): StereoFeedbackEffectOptions {
77 return Object.assign(StereoEffect.getDefaults(), {
78 feedback: 0.5,
79 });
80 }
81
82 dispose(): this {
83 super.dispose();
84 this.feedback.dispose();
85 this._feedbackL.dispose();
86 this._feedbackR.dispose();
87 this._feedbackSplit.dispose();
88 this._feedbackMerge.dispose();
89 return this;
90 }
91}