UNPKG

2.4 kBPlain TextView Raw
1import { CrossFade } from "../component/channel/CrossFade.js";
2import { Gain } from "../core/context/Gain.js";
3import {
4 ToneAudioNode,
5 ToneAudioNodeOptions,
6} from "../core/context/ToneAudioNode.js";
7import { NormalRange } from "../core/type/Units.js";
8import { readOnly } from "../core/util/Interface.js";
9import { Signal } from "../signal/Signal.js";
10
11export interface EffectOptions extends ToneAudioNodeOptions {
12 wet: NormalRange;
13}
14/**
15 * Effect is the base class for effects. Connect the effect between
16 * the effectSend and effectReturn GainNodes, then control the amount of
17 * effect which goes to the output using the wet control.
18 */
19export abstract class Effect<
20 Options extends EffectOptions,
21> extends ToneAudioNode<Options> {
22 readonly name: string = "Effect";
23
24 /**
25 * the drywet knob to control the amount of effect
26 */
27 private _dryWet: CrossFade = new CrossFade({ context: this.context });
28
29 /**
30 * The wet control is how much of the effected
31 * will pass through to the output. 1 = 100% effected
32 * signal, 0 = 100% dry signal.
33 */
34 wet: Signal<"normalRange"> = this._dryWet.fade;
35
36 /**
37 * connect the effectSend to the input of hte effect
38 */
39 protected effectSend: Gain = new Gain({ context: this.context });
40
41 /**
42 * connect the output of the effect to the effectReturn
43 */
44 protected effectReturn: Gain = new Gain({ context: this.context });
45
46 /**
47 * The effect input node
48 */
49 input: Gain = new Gain({ context: this.context });
50
51 /**
52 * The effect output
53 */
54 output = this._dryWet;
55
56 constructor(options: EffectOptions) {
57 super(options);
58
59 // connections
60 this.input.fan(this._dryWet.a, this.effectSend);
61 this.effectReturn.connect(this._dryWet.b);
62 this.wet.setValueAtTime(options.wet, 0);
63 this._internalChannels = [this.effectReturn, this.effectSend];
64 readOnly(this, "wet");
65 }
66
67 static getDefaults(): EffectOptions {
68 return Object.assign(ToneAudioNode.getDefaults(), {
69 wet: 1,
70 });
71 }
72
73 /**
74 * chains the effect in between the effectSend and effectReturn
75 */
76 protected connectEffect(effect: ToneAudioNode | AudioNode): this {
77 // add it to the internal channels
78 this._internalChannels.push(effect);
79 this.effectSend.chain(effect, this.effectReturn);
80 return this;
81 }
82
83 dispose(): this {
84 super.dispose();
85 this._dryWet.dispose();
86 this.effectSend.dispose();
87 this.effectReturn.dispose();
88 this.wet.dispose();
89 return this;
90 }
91}