UNPKG

5.1 kBJavaScriptView Raw
1import { StereoFeedbackEffect, } from "../effect/StereoFeedbackEffect.js";
2import { optionsFromArguments } from "../core/util/Defaults.js";
3import { LFO } from "../source/oscillator/LFO.js";
4import { Delay } from "../core/context/Delay.js";
5import { readOnly } from "../core/util/Interface.js";
6/**
7 * Chorus is a stereo chorus effect composed of a left and right delay with an {@link LFO} applied to the delayTime of each channel.
8 * When {@link feedback} is set to a value larger than 0, you also get Flanger-type effects.
9 * Inspiration from [Tuna.js](https://github.com/Dinahmoe/tuna/blob/master/tuna.js).
10 * Read more on the chorus effect on [Sound On Sound](http://www.soundonsound.com/sos/jun04/articles/synthsecrets.htm).
11 *
12 * @example
13 * const chorus = new Tone.Chorus(4, 2.5, 0.5).toDestination().start();
14 * const synth = new Tone.PolySynth().connect(chorus);
15 * synth.triggerAttackRelease(["C3", "E3", "G3"], "8n");
16 *
17 * @category Effect
18 */
19export class Chorus extends StereoFeedbackEffect {
20 constructor() {
21 const options = optionsFromArguments(Chorus.getDefaults(), arguments, [
22 "frequency",
23 "delayTime",
24 "depth",
25 ]);
26 super(options);
27 this.name = "Chorus";
28 this._depth = options.depth;
29 this._delayTime = options.delayTime / 1000;
30 this._lfoL = new LFO({
31 context: this.context,
32 frequency: options.frequency,
33 min: 0,
34 max: 1,
35 });
36 this._lfoR = new LFO({
37 context: this.context,
38 frequency: options.frequency,
39 min: 0,
40 max: 1,
41 phase: 180,
42 });
43 this._delayNodeL = new Delay({ context: this.context });
44 this._delayNodeR = new Delay({ context: this.context });
45 this.frequency = this._lfoL.frequency;
46 readOnly(this, ["frequency"]);
47 // have one LFO frequency control the other
48 this._lfoL.frequency.connect(this._lfoR.frequency);
49 // connections
50 this.connectEffectLeft(this._delayNodeL);
51 this.connectEffectRight(this._delayNodeR);
52 // lfo setup
53 this._lfoL.connect(this._delayNodeL.delayTime);
54 this._lfoR.connect(this._delayNodeR.delayTime);
55 // set the initial values
56 this.depth = this._depth;
57 this.type = options.type;
58 this.spread = options.spread;
59 }
60 static getDefaults() {
61 return Object.assign(StereoFeedbackEffect.getDefaults(), {
62 frequency: 1.5,
63 delayTime: 3.5,
64 depth: 0.7,
65 type: "sine",
66 spread: 180,
67 feedback: 0,
68 wet: 0.5,
69 });
70 }
71 /**
72 * The depth of the effect. A depth of 1 makes the delayTime
73 * modulate between 0 and 2*delayTime (centered around the delayTime).
74 */
75 get depth() {
76 return this._depth;
77 }
78 set depth(depth) {
79 this._depth = depth;
80 const deviation = this._delayTime * depth;
81 this._lfoL.min = Math.max(this._delayTime - deviation, 0);
82 this._lfoL.max = this._delayTime + deviation;
83 this._lfoR.min = Math.max(this._delayTime - deviation, 0);
84 this._lfoR.max = this._delayTime + deviation;
85 }
86 /**
87 * The delayTime in milliseconds of the chorus. A larger delayTime
88 * will give a more pronounced effect. Nominal range a delayTime
89 * is between 2 and 20ms.
90 */
91 get delayTime() {
92 return this._delayTime * 1000;
93 }
94 set delayTime(delayTime) {
95 this._delayTime = delayTime / 1000;
96 this.depth = this._depth;
97 }
98 /**
99 * The oscillator type of the LFO.
100 */
101 get type() {
102 return this._lfoL.type;
103 }
104 set type(type) {
105 this._lfoL.type = type;
106 this._lfoR.type = type;
107 }
108 /**
109 * Amount of stereo spread. When set to 0, both LFO's will be panned centrally.
110 * When set to 180, LFO's will be panned hard left and right respectively.
111 */
112 get spread() {
113 return this._lfoR.phase - this._lfoL.phase;
114 }
115 set spread(spread) {
116 this._lfoL.phase = 90 - spread / 2;
117 this._lfoR.phase = spread / 2 + 90;
118 }
119 /**
120 * Start the effect.
121 */
122 start(time) {
123 this._lfoL.start(time);
124 this._lfoR.start(time);
125 return this;
126 }
127 /**
128 * Stop the lfo
129 */
130 stop(time) {
131 this._lfoL.stop(time);
132 this._lfoR.stop(time);
133 return this;
134 }
135 /**
136 * Sync the filter to the transport.
137 * @see {@link LFO.sync}
138 */
139 sync() {
140 this._lfoL.sync();
141 this._lfoR.sync();
142 return this;
143 }
144 /**
145 * Unsync the filter from the transport.
146 */
147 unsync() {
148 this._lfoL.unsync();
149 this._lfoR.unsync();
150 return this;
151 }
152 dispose() {
153 super.dispose();
154 this._lfoL.dispose();
155 this._lfoR.dispose();
156 this._delayNodeL.dispose();
157 this._delayNodeR.dispose();
158 this.frequency.dispose();
159 return this;
160 }
161}
162//# sourceMappingURL=Chorus.js.map
\No newline at end of file