1 | import { StereoEffect } from "./StereoEffect.js";
|
2 | import { optionsFromArguments } from "../core/util/Defaults.js";
|
3 | import { LFO } from "../source/oscillator/LFO.js";
|
4 | import { Signal } from "../signal/Signal.js";
|
5 | import { readOnly } from "../core/util/Interface.js";
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 |
|
14 |
|
15 |
|
16 |
|
17 |
|
18 |
|
19 |
|
20 |
|
21 | export class Phaser extends StereoEffect {
|
22 | constructor() {
|
23 | const options = optionsFromArguments(Phaser.getDefaults(), arguments, [
|
24 | "frequency",
|
25 | "octaves",
|
26 | "baseFrequency",
|
27 | ]);
|
28 | super(options);
|
29 | this.name = "Phaser";
|
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._baseFrequency = this.toFrequency(options.baseFrequency);
|
44 | this._octaves = options.octaves;
|
45 | this.Q = new Signal({
|
46 | context: this.context,
|
47 | value: options.Q,
|
48 | units: "positive",
|
49 | });
|
50 | this._filtersL = this._makeFilters(options.stages, this._lfoL);
|
51 | this._filtersR = this._makeFilters(options.stages, this._lfoR);
|
52 | this.frequency = this._lfoL.frequency;
|
53 | this.frequency.value = options.frequency;
|
54 |
|
55 | this.connectEffectLeft(...this._filtersL);
|
56 | this.connectEffectRight(...this._filtersR);
|
57 |
|
58 | this._lfoL.frequency.connect(this._lfoR.frequency);
|
59 |
|
60 | this.baseFrequency = options.baseFrequency;
|
61 | this.octaves = options.octaves;
|
62 |
|
63 | this._lfoL.start();
|
64 | this._lfoR.start();
|
65 | readOnly(this, ["frequency", "Q"]);
|
66 | }
|
67 | static getDefaults() {
|
68 | return Object.assign(StereoEffect.getDefaults(), {
|
69 | frequency: 0.5,
|
70 | octaves: 3,
|
71 | stages: 10,
|
72 | Q: 10,
|
73 | baseFrequency: 350,
|
74 | });
|
75 | }
|
76 | _makeFilters(stages, connectToFreq) {
|
77 | const filters = [];
|
78 |
|
79 | for (let i = 0; i < stages; i++) {
|
80 | const filter = this.context.createBiquadFilter();
|
81 | filter.type = "allpass";
|
82 | this.Q.connect(filter.Q);
|
83 | connectToFreq.connect(filter.frequency);
|
84 | filters.push(filter);
|
85 | }
|
86 | return filters;
|
87 | }
|
88 | |
89 |
|
90 |
|
91 | get octaves() {
|
92 | return this._octaves;
|
93 | }
|
94 | set octaves(octaves) {
|
95 | this._octaves = octaves;
|
96 | const max = this._baseFrequency * Math.pow(2, octaves);
|
97 | this._lfoL.max = max;
|
98 | this._lfoR.max = max;
|
99 | }
|
100 | |
101 |
|
102 |
|
103 | get baseFrequency() {
|
104 | return this._baseFrequency;
|
105 | }
|
106 | set baseFrequency(freq) {
|
107 | this._baseFrequency = this.toFrequency(freq);
|
108 | this._lfoL.min = this._baseFrequency;
|
109 | this._lfoR.min = this._baseFrequency;
|
110 | this.octaves = this._octaves;
|
111 | }
|
112 | dispose() {
|
113 | super.dispose();
|
114 | this.Q.dispose();
|
115 | this._lfoL.dispose();
|
116 | this._lfoR.dispose();
|
117 | this._filtersL.forEach((f) => f.disconnect());
|
118 | this._filtersR.forEach((f) => f.disconnect());
|
119 | this.frequency.dispose();
|
120 | return this;
|
121 | }
|
122 | }
|
123 |
|
\ | No newline at end of file |