1 | import { Effect } from "./Effect.js";
|
2 | import { Filter } from "../component/filter/Filter.js";
|
3 | import { Follower } from "../component/analysis/Follower.js";
|
4 | import { optionsFromArguments } from "../core/util/Defaults.js";
|
5 | import { Gain } from "../core/context/Gain.js";
|
6 | import { dbToGain, gainToDb } from "../core/type/Conversions.js";
|
7 | import { ScaleExp } from "../signal/ScaleExp.js";
|
8 | import { readOnly } from "../core/util/Interface.js";
|
9 |
|
10 |
|
11 |
|
12 |
|
13 |
|
14 |
|
15 |
|
16 |
|
17 |
|
18 |
|
19 |
|
20 |
|
21 |
|
22 |
|
23 |
|
24 | export class AutoWah extends Effect {
|
25 | constructor() {
|
26 | const options = optionsFromArguments(AutoWah.getDefaults(), arguments, [
|
27 | "baseFrequency",
|
28 | "octaves",
|
29 | "sensitivity",
|
30 | ]);
|
31 | super(options);
|
32 | this.name = "AutoWah";
|
33 | this._follower = new Follower({
|
34 | context: this.context,
|
35 | smoothing: options.follower,
|
36 | });
|
37 | this._sweepRange = new ScaleExp({
|
38 | context: this.context,
|
39 | min: 0,
|
40 | max: 1,
|
41 | exponent: 0.5,
|
42 | });
|
43 | this._baseFrequency = this.toFrequency(options.baseFrequency);
|
44 | this._octaves = options.octaves;
|
45 | this._inputBoost = new Gain({ context: this.context });
|
46 | this._bandpass = new Filter({
|
47 | context: this.context,
|
48 | rolloff: -48,
|
49 | frequency: 0,
|
50 | Q: options.Q,
|
51 | });
|
52 | this._peaking = new Filter({
|
53 | context: this.context,
|
54 | type: "peaking",
|
55 | });
|
56 | this._peaking.gain.value = options.gain;
|
57 | this.gain = this._peaking.gain;
|
58 | this.Q = this._bandpass.Q;
|
59 |
|
60 | this.effectSend.chain(this._inputBoost, this._follower, this._sweepRange);
|
61 | this._sweepRange.connect(this._bandpass.frequency);
|
62 | this._sweepRange.connect(this._peaking.frequency);
|
63 |
|
64 | this.effectSend.chain(this._bandpass, this._peaking, this.effectReturn);
|
65 |
|
66 | this._setSweepRange();
|
67 | this.sensitivity = options.sensitivity;
|
68 | readOnly(this, ["gain", "Q"]);
|
69 | }
|
70 | static getDefaults() {
|
71 | return Object.assign(Effect.getDefaults(), {
|
72 | baseFrequency: 100,
|
73 | octaves: 6,
|
74 | sensitivity: 0,
|
75 | Q: 2,
|
76 | gain: 2,
|
77 | follower: 0.2,
|
78 | });
|
79 | }
|
80 | |
81 |
|
82 |
|
83 | get octaves() {
|
84 | return this._octaves;
|
85 | }
|
86 | set octaves(octaves) {
|
87 | this._octaves = octaves;
|
88 | this._setSweepRange();
|
89 | }
|
90 | |
91 |
|
92 |
|
93 | get follower() {
|
94 | return this._follower.smoothing;
|
95 | }
|
96 | set follower(follower) {
|
97 | this._follower.smoothing = follower;
|
98 | }
|
99 | |
100 |
|
101 |
|
102 | get baseFrequency() {
|
103 | return this._baseFrequency;
|
104 | }
|
105 | set baseFrequency(baseFreq) {
|
106 | this._baseFrequency = this.toFrequency(baseFreq);
|
107 | this._setSweepRange();
|
108 | }
|
109 | |
110 |
|
111 |
|
112 | get sensitivity() {
|
113 | return gainToDb(1 / this._inputBoost.gain.value);
|
114 | }
|
115 | set sensitivity(sensitivity) {
|
116 | this._inputBoost.gain.value = 1 / dbToGain(sensitivity);
|
117 | }
|
118 | |
119 |
|
120 |
|
121 | _setSweepRange() {
|
122 | this._sweepRange.min = this._baseFrequency;
|
123 | this._sweepRange.max = Math.min(this._baseFrequency * Math.pow(2, this._octaves), this.context.sampleRate / 2);
|
124 | }
|
125 | dispose() {
|
126 | super.dispose();
|
127 | this._follower.dispose();
|
128 | this._sweepRange.dispose();
|
129 | this._bandpass.dispose();
|
130 | this._peaking.dispose();
|
131 | this._inputBoost.dispose();
|
132 | return this;
|
133 | }
|
134 | }
|
135 |
|
\ | No newline at end of file |