@logue/reverb 1.3.4 → 1.3.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/Reverb.es.js +206 -424
- package/dist/Reverb.iife.js +2 -632
- package/dist/Reverb.umd.js +2 -635
- package/package.json +22 -24
package/dist/Reverb.es.js
CHANGED
|
@@ -5,84 +5,69 @@
|
|
|
5
5
|
* @author Logue <logue@hotmail.co.jp>
|
|
6
6
|
* @copyright 2019-2023 By Masashi Yoshikawa All rights reserved.
|
|
7
7
|
* @license MIT
|
|
8
|
-
* @version 1.3.
|
|
8
|
+
* @version 1.3.7
|
|
9
9
|
* @see {@link https://github.com/logue/Reverb.js}
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
|
-
const
|
|
13
|
-
class
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
12
|
+
const g = 23283064365386963e-26;
|
|
13
|
+
class F {
|
|
14
|
+
float(e = 1) {
|
|
15
|
+
return this.int() * g * e;
|
|
16
|
+
}
|
|
17
|
+
probability(e) {
|
|
18
|
+
return this.float() < e;
|
|
19
|
+
}
|
|
20
|
+
norm(e = 1) {
|
|
21
|
+
return (this.int() * g - 0.5) * 2 * e;
|
|
22
|
+
}
|
|
23
|
+
normMinMax(e, s) {
|
|
24
|
+
const i = this.minmax(e, s);
|
|
25
|
+
return this.float() < 0.5 ? i : -i;
|
|
26
|
+
}
|
|
27
|
+
minmax(e, s) {
|
|
28
|
+
return this.float() * (s - e) + e;
|
|
29
|
+
}
|
|
30
|
+
minmaxInt(e, s) {
|
|
31
|
+
e |= 0;
|
|
32
|
+
const i = (s | 0) - e;
|
|
33
|
+
return i ? e + this.int() % i : e;
|
|
34
|
+
}
|
|
35
|
+
minmaxUint(e, s) {
|
|
36
|
+
e >>>= 0;
|
|
37
|
+
const i = (s >>> 0) - e;
|
|
38
|
+
return i ? e + this.int() % i : e;
|
|
39
|
+
}
|
|
40
40
|
}
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
return random() * norm;
|
|
53
|
-
}
|
|
54
|
-
norm(norm = 1) {
|
|
55
|
-
return (random() - 0.5) * 2 * norm;
|
|
56
|
-
}
|
|
41
|
+
const m = Math.random;
|
|
42
|
+
class T extends F {
|
|
43
|
+
int() {
|
|
44
|
+
return m() * 4294967296 >>> 0;
|
|
45
|
+
}
|
|
46
|
+
float(e = 1) {
|
|
47
|
+
return m() * e;
|
|
48
|
+
}
|
|
49
|
+
norm(e = 1) {
|
|
50
|
+
return (m() - 0.5) * 2 * e;
|
|
51
|
+
}
|
|
57
52
|
}
|
|
58
|
-
|
|
59
|
-
* Used as default PRNG throughout most other thi.ng projects, though usually is
|
|
60
|
-
* configurable.
|
|
61
|
-
*/
|
|
62
|
-
const SYSTEM = new SystemRandom();
|
|
63
|
-
|
|
64
|
-
const defaults = {
|
|
53
|
+
const k = new T(), x = {
|
|
65
54
|
noise: "white",
|
|
66
55
|
scale: 1,
|
|
67
56
|
peaks: 2,
|
|
68
|
-
randomAlgorithm:
|
|
57
|
+
randomAlgorithm: k,
|
|
69
58
|
decay: 2,
|
|
70
59
|
delay: 0,
|
|
71
|
-
reverse:
|
|
60
|
+
reverse: !1,
|
|
72
61
|
time: 2,
|
|
73
62
|
filterType: "allpass",
|
|
74
63
|
filterFreq: 2200,
|
|
75
64
|
filterQ: 1,
|
|
76
65
|
mix: 0.5,
|
|
77
|
-
once:
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
date: "2023-11-06T00:21:39.551Z"
|
|
83
|
-
};
|
|
84
|
-
|
|
85
|
-
const Noise = {
|
|
66
|
+
once: !1
|
|
67
|
+
}, w = {
|
|
68
|
+
version: "1.3.7",
|
|
69
|
+
date: "2024-01-29T10:30:54.595Z"
|
|
70
|
+
}, d = {
|
|
86
71
|
/** Blue noise */
|
|
87
72
|
blue: "blue",
|
|
88
73
|
/** Brown noise (same as red noise) */
|
|
@@ -97,254 +82,112 @@ const Noise = {
|
|
|
97
82
|
violet: "violet",
|
|
98
83
|
/** White noise */
|
|
99
84
|
white: "white"
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
for (let i = 0; true; i ^= 1) {
|
|
119
|
-
const next = src[i].next();
|
|
120
|
-
if (next.done)
|
|
121
|
-
return;
|
|
122
|
-
yield next.value;
|
|
123
|
-
}
|
|
85
|
+
}, p = {
|
|
86
|
+
bins: 2,
|
|
87
|
+
scale: 1,
|
|
88
|
+
rnd: k
|
|
89
|
+
}, N = (t, e, s) => {
|
|
90
|
+
const i = new Array(t);
|
|
91
|
+
for (let n = 0; n < t; n++)
|
|
92
|
+
i[n] = s.norm(e);
|
|
93
|
+
return i;
|
|
94
|
+
}, v = (t) => t.reduce((e, s) => e + s, 0);
|
|
95
|
+
function* G(t, e) {
|
|
96
|
+
const s = [t[Symbol.iterator](), e[Symbol.iterator]()];
|
|
97
|
+
for (let i = 0; ; i ^= 1) {
|
|
98
|
+
const n = s[i].next();
|
|
99
|
+
if (n.done)
|
|
100
|
+
return;
|
|
101
|
+
yield n.value;
|
|
102
|
+
}
|
|
124
103
|
}
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
};
|
|
136
|
-
const state = preseed(bins, scale, rnd);
|
|
137
|
-
state.forEach((x, i) => (state[i] = i & 1 ? x : -x));
|
|
138
|
-
const invN = 1 / bins;
|
|
139
|
-
let acc = sum(state);
|
|
140
|
-
for (let i = 0, sign = -1; true; ++i >= bins && (i = 0)) {
|
|
141
|
-
acc -= state[i];
|
|
142
|
-
acc += state[i] = sign * rnd.norm(scale);
|
|
143
|
-
sign ^= 0xfffffffe;
|
|
144
|
-
yield sign * acc * invN;
|
|
145
|
-
}
|
|
104
|
+
function* b(t) {
|
|
105
|
+
const { bins: e, scale: s, rnd: i } = {
|
|
106
|
+
...p,
|
|
107
|
+
...t
|
|
108
|
+
}, n = N(e, s, i);
|
|
109
|
+
n.forEach((r, l) => n[l] = l & 1 ? r : -r);
|
|
110
|
+
const a = 1 / e;
|
|
111
|
+
let o = v(n);
|
|
112
|
+
for (let r = 0, l = -1; ; ++r >= e && (r = 0))
|
|
113
|
+
o -= n[r], o += n[r] = l * i.norm(s), l ^= 4294967294, yield l * o * a;
|
|
146
114
|
}
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
* {@link violet}.
|
|
151
|
-
*
|
|
152
|
-
* @param opts -
|
|
153
|
-
*/
|
|
154
|
-
const green = (opts) => interleave(blue(opts), blue(opts));
|
|
155
|
-
|
|
156
|
-
/**
|
|
157
|
-
* Returns number of 1 bits in `x`.
|
|
158
|
-
*
|
|
159
|
-
* @param x -
|
|
160
|
-
*/
|
|
161
|
-
const ctz32 = (x) => {
|
|
162
|
-
let c = 32;
|
|
163
|
-
x &= -x;
|
|
164
|
-
x && c--;
|
|
165
|
-
x & 0x0000ffff && (c -= 16);
|
|
166
|
-
x & 0x00ff00ff && (c -= 8);
|
|
167
|
-
x & 0x0f0f0f0f && (c -= 4);
|
|
168
|
-
x & 0x33333333 && (c -= 2);
|
|
169
|
-
x & 0x55555555 && (c -= 1);
|
|
170
|
-
return c;
|
|
115
|
+
const C = (t) => G(b(t), b(t)), E = (t) => {
|
|
116
|
+
let e = 32;
|
|
117
|
+
return t &= -t, t && e--, t & 65535 && (e -= 16), t & 16711935 && (e -= 8), t & 252645135 && (e -= 4), t & 858993459 && (e -= 2), t & 1431655765 && (e -= 1), e;
|
|
171
118
|
};
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
*
|
|
182
|
-
|
|
183
|
-
* - https://www.firstpr.com.au/dsp/pink-noise/#Voss-McCartney
|
|
184
|
-
*
|
|
185
|
-
* @param opts -
|
|
186
|
-
*/
|
|
187
|
-
function* pink(opts) {
|
|
188
|
-
const { bins, scale, rnd } = {
|
|
189
|
-
...DEFAULT_OPTS,
|
|
190
|
-
bins: 8,
|
|
191
|
-
...opts,
|
|
192
|
-
};
|
|
193
|
-
const state = preseed(bins, scale, rnd);
|
|
194
|
-
const invN = 1 / bins;
|
|
195
|
-
let acc = sum(state);
|
|
196
|
-
for (let i = 0; true; i = (i + 1) >>> 0) {
|
|
197
|
-
const id = ctz32(i) % bins;
|
|
198
|
-
acc -= state[id];
|
|
199
|
-
acc += state[id] = rnd.norm(scale);
|
|
200
|
-
yield acc * invN;
|
|
201
|
-
}
|
|
119
|
+
function* j(t) {
|
|
120
|
+
const { bins: e, scale: s, rnd: i } = {
|
|
121
|
+
...p,
|
|
122
|
+
bins: 8,
|
|
123
|
+
...t
|
|
124
|
+
}, n = N(e, s, i), a = 1 / e;
|
|
125
|
+
let o = v(n);
|
|
126
|
+
for (let r = 0; ; r = r + 1 >>> 0) {
|
|
127
|
+
const l = E(r) % e;
|
|
128
|
+
o -= n[l], o += n[l] = i.norm(s), yield o * a;
|
|
129
|
+
}
|
|
202
130
|
}
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
...DEFAULT_OPTS,
|
|
212
|
-
...opts,
|
|
213
|
-
};
|
|
214
|
-
const state = preseed(bins, scale, rnd);
|
|
215
|
-
const invN = 1 / bins;
|
|
216
|
-
let acc = sum(state);
|
|
217
|
-
for (let i = 0; true; ++i >= bins && (i = 0)) {
|
|
218
|
-
acc -= state[i];
|
|
219
|
-
acc += state[i] = rnd.norm(scale);
|
|
220
|
-
yield acc * invN;
|
|
221
|
-
}
|
|
131
|
+
function* y(t) {
|
|
132
|
+
const { bins: e, scale: s, rnd: i } = {
|
|
133
|
+
...p,
|
|
134
|
+
...t
|
|
135
|
+
}, n = N(e, s, i), a = 1 / e;
|
|
136
|
+
let o = v(n);
|
|
137
|
+
for (let r = 0; ; ++r >= e && (r = 0))
|
|
138
|
+
o -= n[r], o += n[r] = i.norm(s), yield o * a;
|
|
222
139
|
}
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
*/
|
|
229
|
-
const violet = (opts) => interleave(red(opts), red(opts));
|
|
230
|
-
|
|
231
|
-
/**
|
|
232
|
-
* Unfiltered noise w/ uniform distribution. Merely yields samples from
|
|
233
|
-
* given PRNG.
|
|
234
|
-
*
|
|
235
|
-
* @param opts -
|
|
236
|
-
*/
|
|
237
|
-
function* white(opts) {
|
|
238
|
-
const { scale, rnd } = { ...DEFAULT_OPTS, ...opts };
|
|
239
|
-
while (true) {
|
|
240
|
-
yield rnd.norm(scale);
|
|
241
|
-
}
|
|
140
|
+
const M = (t) => G(y(t), y(t));
|
|
141
|
+
function* R(t) {
|
|
142
|
+
const { scale: e, rnd: s } = { ...p, ...t };
|
|
143
|
+
for (; ; )
|
|
144
|
+
yield s.norm(e);
|
|
242
145
|
}
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
this.value = val;
|
|
253
|
-
}
|
|
254
|
-
deref() {
|
|
255
|
-
return this.value;
|
|
256
|
-
}
|
|
146
|
+
const S = (t, e) => t != null && typeof t[e] == "function", Q = (t) => S(t, "xform") ? t.xform() : t, q = (t) => t != null && typeof t[Symbol.iterator] == "function";
|
|
147
|
+
class u {
|
|
148
|
+
value;
|
|
149
|
+
constructor(e) {
|
|
150
|
+
this.value = e;
|
|
151
|
+
}
|
|
152
|
+
deref() {
|
|
153
|
+
return this.value;
|
|
154
|
+
}
|
|
257
155
|
}
|
|
258
|
-
const
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
* Convenience helper for building a full {@link Reducer} using the identity
|
|
265
|
-
* function (i.e. `(x) => x`) as completion step (true for 90% of all
|
|
266
|
-
* bundled transducers).
|
|
267
|
-
*
|
|
268
|
-
* @param init - init step of reducer
|
|
269
|
-
* @param rfn - reduction step of reducer
|
|
270
|
-
*/
|
|
271
|
-
const reducer = (init, rfn) => [init, (acc) => acc, rfn];
|
|
272
|
-
|
|
273
|
-
function push(xs) {
|
|
274
|
-
return xs
|
|
275
|
-
? [...xs]
|
|
276
|
-
: reducer(() => [], (acc, x) => (acc.push(x), acc));
|
|
156
|
+
const D = (t) => new u(t), L = (t) => t instanceof u, B = (t) => t instanceof u ? t : new u(t), I = (t) => t instanceof u ? t.deref() : t, O = (t, e) => [t, (s) => s, e];
|
|
157
|
+
function U(t) {
|
|
158
|
+
return t ? [...t] : O(
|
|
159
|
+
() => [],
|
|
160
|
+
(e, s) => (e.push(s), e)
|
|
161
|
+
);
|
|
277
162
|
}
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
*/
|
|
286
|
-
function* iterator(xform, xs) {
|
|
287
|
-
const rfn = ensureTransducer(xform)(push());
|
|
288
|
-
const complete = rfn[1];
|
|
289
|
-
const reduce = rfn[2];
|
|
290
|
-
for (let x of xs) {
|
|
291
|
-
const y = reduce([], x);
|
|
292
|
-
if (isReduced(y)) {
|
|
293
|
-
yield* unreduced(complete(y.deref()));
|
|
294
|
-
return;
|
|
295
|
-
}
|
|
296
|
-
if (y.length) {
|
|
297
|
-
yield* y;
|
|
298
|
-
}
|
|
163
|
+
function* z(t, e) {
|
|
164
|
+
const s = Q(t)(U()), i = s[1], n = s[2];
|
|
165
|
+
for (let a of e) {
|
|
166
|
+
const o = n([], a);
|
|
167
|
+
if (L(o)) {
|
|
168
|
+
yield* I(i(o.deref()));
|
|
169
|
+
return;
|
|
299
170
|
}
|
|
300
|
-
yield*
|
|
171
|
+
o.length && (yield* o);
|
|
172
|
+
}
|
|
173
|
+
yield* I(i([]));
|
|
301
174
|
}
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
* function. Therefore the resulting reducer takes inputs of `C` and an
|
|
313
|
-
* accumulator of type `A`.
|
|
314
|
-
*
|
|
315
|
-
* It is assumed that `fn` internally calls `rfn[2]` to pass its own
|
|
316
|
-
* results for further processing by the nested reducer `rfn`.
|
|
317
|
-
*
|
|
318
|
-
* @example
|
|
319
|
-
* ```ts
|
|
320
|
-
* compR(rfn, fn)
|
|
321
|
-
* // [rfn[0], rfn[1], fn]
|
|
322
|
-
* ```
|
|
323
|
-
*
|
|
324
|
-
* @param rfn -
|
|
325
|
-
* @param fn -
|
|
326
|
-
*/
|
|
327
|
-
const compR = (rfn, fn) => [rfn[0], rfn[1], fn];
|
|
328
|
-
|
|
329
|
-
function take(n, src) {
|
|
330
|
-
return isIterable(src)
|
|
331
|
-
? iterator(take(n), src)
|
|
332
|
-
: (rfn) => {
|
|
333
|
-
const r = rfn[2];
|
|
334
|
-
let m = n;
|
|
335
|
-
return compR(rfn, (acc, x) => --m > 0
|
|
336
|
-
? r(acc, x)
|
|
337
|
-
: m === 0
|
|
338
|
-
? ensureReduced(r(acc, x))
|
|
339
|
-
: reduced(acc));
|
|
340
|
-
};
|
|
175
|
+
const P = (t, e) => [t[0], t[1], e];
|
|
176
|
+
function A(t, e) {
|
|
177
|
+
return q(e) ? z(A(t), e) : (s) => {
|
|
178
|
+
const i = s[2];
|
|
179
|
+
let n = t;
|
|
180
|
+
return P(
|
|
181
|
+
s,
|
|
182
|
+
(a, o) => --n > 0 ? i(a, o) : n === 0 ? B(i(a, o)) : D(a)
|
|
183
|
+
);
|
|
184
|
+
};
|
|
341
185
|
}
|
|
342
|
-
|
|
343
|
-
class Reverb {
|
|
186
|
+
class h {
|
|
344
187
|
/** Version strings */
|
|
345
|
-
static version =
|
|
188
|
+
static version = w.version;
|
|
346
189
|
/** Build date */
|
|
347
|
-
static build =
|
|
190
|
+
static build = w.date;
|
|
348
191
|
/** AudioContext */
|
|
349
192
|
ctx;
|
|
350
193
|
/** Wet Level (Reverberated node) */
|
|
@@ -362,211 +205,167 @@ class Reverb {
|
|
|
362
205
|
/** Connected flag */
|
|
363
206
|
isConnected;
|
|
364
207
|
/** Noise Generator */
|
|
365
|
-
noise =
|
|
208
|
+
noise = R;
|
|
366
209
|
/**
|
|
367
210
|
* Constructor
|
|
368
211
|
*
|
|
369
212
|
* @param ctx - Root AudioContext
|
|
370
213
|
* @param options - Configure
|
|
371
214
|
*/
|
|
372
|
-
constructor(
|
|
373
|
-
this.ctx = ctx;
|
|
374
|
-
this.options = Object.assign(defaults, options);
|
|
375
|
-
this.wetGainNode = this.ctx.createGain();
|
|
376
|
-
this.dryGainNode = this.ctx.createGain();
|
|
377
|
-
this.filterNode = this.ctx.createBiquadFilter();
|
|
378
|
-
this.convolverNode = this.ctx.createConvolver();
|
|
379
|
-
this.outputNode = this.ctx.createGain();
|
|
380
|
-
this.isConnected = false;
|
|
381
|
-
this.filterType(this.options.filterType);
|
|
382
|
-
this.setNoise(this.options.noise);
|
|
383
|
-
this.buildImpulse();
|
|
384
|
-
this.mix(this.options.mix);
|
|
215
|
+
constructor(e, s) {
|
|
216
|
+
this.ctx = e, this.options = Object.assign(x, s), this.wetGainNode = this.ctx.createGain(), this.dryGainNode = this.ctx.createGain(), this.filterNode = this.ctx.createBiquadFilter(), this.convolverNode = this.ctx.createConvolver(), this.outputNode = this.ctx.createGain(), this.isConnected = !1, this.filterType(this.options.filterType), this.setNoise(this.options.noise), this.buildImpulse(), this.mix(this.options.mix);
|
|
385
217
|
}
|
|
386
218
|
/**
|
|
387
219
|
* Connect the node for the reverb effect to the original sound node.
|
|
388
220
|
*
|
|
389
221
|
* @param sourceNode - Input source node
|
|
390
222
|
*/
|
|
391
|
-
connect(
|
|
392
|
-
|
|
393
|
-
this.isConnected = false;
|
|
394
|
-
return this.outputNode;
|
|
395
|
-
}
|
|
396
|
-
this.convolverNode.connect(this.filterNode);
|
|
397
|
-
this.filterNode.connect(this.wetGainNode);
|
|
398
|
-
sourceNode.connect(this.convolverNode);
|
|
399
|
-
sourceNode.connect(this.dryGainNode).connect(this.outputNode);
|
|
400
|
-
sourceNode.connect(this.wetGainNode).connect(this.outputNode);
|
|
401
|
-
this.isConnected = true;
|
|
402
|
-
return this.outputNode;
|
|
223
|
+
connect(e) {
|
|
224
|
+
return this.isConnected && this.options.once ? (this.isConnected = !1, this.outputNode) : (this.convolverNode.connect(this.filterNode), this.filterNode.connect(this.wetGainNode), e.connect(this.convolverNode), e.connect(this.dryGainNode).connect(this.outputNode), e.connect(this.wetGainNode).connect(this.outputNode), this.isConnected = !0, this.outputNode);
|
|
403
225
|
}
|
|
404
226
|
/**
|
|
405
227
|
* Disconnect the reverb node
|
|
406
228
|
*
|
|
407
229
|
* @param sourceNode - Input source node
|
|
408
230
|
*/
|
|
409
|
-
disconnect(
|
|
410
|
-
|
|
411
|
-
this.convolverNode.disconnect(this.filterNode);
|
|
412
|
-
this.filterNode.disconnect(this.wetGainNode);
|
|
413
|
-
}
|
|
414
|
-
this.isConnected = false;
|
|
415
|
-
return sourceNode;
|
|
231
|
+
disconnect(e) {
|
|
232
|
+
return this.isConnected && (this.convolverNode.disconnect(this.filterNode), this.filterNode.disconnect(this.wetGainNode)), this.isConnected = !1, e;
|
|
416
233
|
}
|
|
417
234
|
/**
|
|
418
235
|
* Dry/Wet ratio
|
|
419
236
|
*
|
|
420
237
|
* @param mix - Ratio (0~1)
|
|
421
238
|
*/
|
|
422
|
-
mix(
|
|
423
|
-
if (!
|
|
239
|
+
mix(e) {
|
|
240
|
+
if (!h.inRange(e, 0, 1))
|
|
424
241
|
throw new RangeError("[Reverb.js] Dry/Wet ratio must be between 0 to 1.");
|
|
425
|
-
|
|
426
|
-
this.options.mix = mix;
|
|
427
|
-
this.dryGainNode.gain.value = 1 - this.options.mix;
|
|
428
|
-
this.wetGainNode.gain.value = this.options.mix;
|
|
242
|
+
this.options.mix = e, this.dryGainNode.gain.value = 1 - this.options.mix, this.wetGainNode.gain.value = this.options.mix;
|
|
429
243
|
}
|
|
430
244
|
/**
|
|
431
245
|
* Set Impulse Response time length (second)
|
|
432
246
|
*
|
|
433
247
|
* @param value - IR length
|
|
434
248
|
*/
|
|
435
|
-
time(
|
|
436
|
-
if (!
|
|
249
|
+
time(e) {
|
|
250
|
+
if (!h.inRange(e, 1, 50))
|
|
437
251
|
throw new RangeError(
|
|
438
252
|
"[Reverb.js] Time length of inpulse response must be less than 50sec."
|
|
439
253
|
);
|
|
440
|
-
|
|
441
|
-
this.options.time = value;
|
|
442
|
-
this.buildImpulse();
|
|
254
|
+
this.options.time = e, this.buildImpulse();
|
|
443
255
|
}
|
|
444
256
|
/**
|
|
445
257
|
* Impulse response decay rate.
|
|
446
258
|
*
|
|
447
259
|
* @param value - Decay value
|
|
448
260
|
*/
|
|
449
|
-
decay(
|
|
450
|
-
if (!
|
|
261
|
+
decay(e) {
|
|
262
|
+
if (!h.inRange(e, 0, 100))
|
|
451
263
|
throw new RangeError(
|
|
452
264
|
"[Reverb.js] Inpulse Response decay level must be less than 100."
|
|
453
265
|
);
|
|
454
|
-
|
|
455
|
-
this.options.decay = value;
|
|
456
|
-
this.buildImpulse();
|
|
266
|
+
this.options.decay = e, this.buildImpulse();
|
|
457
267
|
}
|
|
458
268
|
/**
|
|
459
269
|
* Delay before reverberation starts
|
|
460
270
|
*
|
|
461
271
|
* @param value - Time[ms]
|
|
462
272
|
*/
|
|
463
|
-
delay(
|
|
464
|
-
if (!
|
|
273
|
+
delay(e) {
|
|
274
|
+
if (!h.inRange(e, 0, 100))
|
|
465
275
|
throw new RangeError(
|
|
466
276
|
"[Reverb.js] Inpulse Response delay time must be less than 100."
|
|
467
277
|
);
|
|
468
|
-
|
|
469
|
-
this.options.delay = value;
|
|
470
|
-
this.buildImpulse();
|
|
278
|
+
this.options.delay = e, this.buildImpulse();
|
|
471
279
|
}
|
|
472
280
|
/**
|
|
473
281
|
* Reverse the impulse response.
|
|
474
282
|
*
|
|
475
283
|
* @param reverse - Reverse IR
|
|
476
284
|
*/
|
|
477
|
-
reverse(
|
|
478
|
-
this.options.reverse =
|
|
479
|
-
this.buildImpulse();
|
|
285
|
+
reverse(e) {
|
|
286
|
+
this.options.reverse = e, this.buildImpulse();
|
|
480
287
|
}
|
|
481
288
|
/**
|
|
482
289
|
* Filter for impulse response
|
|
483
290
|
*
|
|
484
291
|
* @param type - Filiter Type
|
|
485
292
|
*/
|
|
486
|
-
filterType(
|
|
487
|
-
this.filterNode.type = this.options.filterType =
|
|
293
|
+
filterType(e = "allpass") {
|
|
294
|
+
this.filterNode.type = this.options.filterType = e;
|
|
488
295
|
}
|
|
489
296
|
/**
|
|
490
297
|
* Filter frequency applied to impulse response
|
|
491
298
|
*
|
|
492
299
|
* @param freq - Frequency
|
|
493
300
|
*/
|
|
494
|
-
filterFreq(
|
|
495
|
-
if (!
|
|
301
|
+
filterFreq(e) {
|
|
302
|
+
if (!h.inRange(e, 20, 2e4))
|
|
496
303
|
throw new RangeError(
|
|
497
304
|
"[Reverb.js] Filter frequrncy must be between 20 and 20000."
|
|
498
305
|
);
|
|
499
|
-
|
|
500
|
-
this.options.filterFreq = freq;
|
|
501
|
-
this.filterNode.frequency.value = this.options.filterFreq;
|
|
306
|
+
this.options.filterFreq = e, this.filterNode.frequency.value = this.options.filterFreq;
|
|
502
307
|
}
|
|
503
308
|
/**
|
|
504
309
|
* Filter quality.
|
|
505
310
|
*
|
|
506
311
|
* @param q - Quality
|
|
507
312
|
*/
|
|
508
|
-
filterQ(
|
|
509
|
-
if (!
|
|
313
|
+
filterQ(e) {
|
|
314
|
+
if (!h.inRange(e, 0, 10))
|
|
510
315
|
throw new RangeError(
|
|
511
|
-
"[Reverb.js] Filter
|
|
316
|
+
"[Reverb.js] Filter Q value must be between 0 and 10."
|
|
512
317
|
);
|
|
513
|
-
|
|
514
|
-
this.options.filterQ = q;
|
|
515
|
-
this.filterNode.Q.value = this.options.filterQ;
|
|
318
|
+
this.options.filterQ = e, this.filterNode.Q.value = this.options.filterQ;
|
|
516
319
|
}
|
|
517
320
|
/**
|
|
518
321
|
* set IR source noise peaks
|
|
519
322
|
*
|
|
520
323
|
* @param p - Peaks
|
|
521
324
|
*/
|
|
522
|
-
peaks(
|
|
523
|
-
this.options.peaks =
|
|
524
|
-
this.buildImpulse();
|
|
325
|
+
peaks(e) {
|
|
326
|
+
this.options.peaks = e, this.buildImpulse();
|
|
525
327
|
}
|
|
526
328
|
/**
|
|
527
329
|
* set IR source noise scale.
|
|
528
330
|
*
|
|
529
331
|
* @param s - Scale
|
|
530
332
|
*/
|
|
531
|
-
scale(
|
|
532
|
-
this.options.scale =
|
|
533
|
-
this.buildImpulse();
|
|
333
|
+
scale(e) {
|
|
334
|
+
this.options.scale = e, this.buildImpulse();
|
|
534
335
|
}
|
|
535
336
|
/**
|
|
536
337
|
* set IR source noise generator.
|
|
537
338
|
*
|
|
538
339
|
* @param a - Algorithm
|
|
539
340
|
*/
|
|
540
|
-
randomAlgorithm(
|
|
541
|
-
this.options.randomAlgorithm =
|
|
542
|
-
this.buildImpulse();
|
|
341
|
+
randomAlgorithm(e) {
|
|
342
|
+
this.options.randomAlgorithm = e, this.buildImpulse();
|
|
543
343
|
}
|
|
544
344
|
/**
|
|
545
345
|
* Inpulse Response Noise algorithm.
|
|
546
346
|
*
|
|
547
347
|
* @param type - IR noise algorithm type.
|
|
548
348
|
*/
|
|
549
|
-
setNoise(
|
|
550
|
-
this.options.noise =
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
this.noise = blue;
|
|
349
|
+
setNoise(e) {
|
|
350
|
+
switch (this.options.noise = e, e) {
|
|
351
|
+
case d.blue:
|
|
352
|
+
this.noise = b;
|
|
554
353
|
break;
|
|
555
|
-
case
|
|
556
|
-
this.noise =
|
|
354
|
+
case d.green:
|
|
355
|
+
this.noise = C;
|
|
557
356
|
break;
|
|
558
|
-
case
|
|
559
|
-
this.noise =
|
|
357
|
+
case d.pink:
|
|
358
|
+
this.noise = j;
|
|
560
359
|
break;
|
|
561
|
-
case
|
|
562
|
-
case
|
|
563
|
-
this.noise =
|
|
360
|
+
case d.red:
|
|
361
|
+
case d.brown:
|
|
362
|
+
this.noise = y;
|
|
564
363
|
break;
|
|
565
|
-
case
|
|
566
|
-
this.noise =
|
|
364
|
+
case d.violet:
|
|
365
|
+
this.noise = M;
|
|
567
366
|
break;
|
|
568
367
|
default:
|
|
569
|
-
this.noise =
|
|
368
|
+
this.noise = R;
|
|
570
369
|
}
|
|
571
370
|
this.buildImpulse();
|
|
572
371
|
}
|
|
@@ -575,9 +374,8 @@ class Reverb {
|
|
|
575
374
|
*
|
|
576
375
|
* @param algorithm - Algorythm
|
|
577
376
|
*/
|
|
578
|
-
setRandomAlgorythm(
|
|
579
|
-
this.options.randomAlgorithm =
|
|
580
|
-
this.buildImpulse();
|
|
377
|
+
setRandomAlgorythm(e) {
|
|
378
|
+
this.options.randomAlgorithm = e, this.buildImpulse();
|
|
581
379
|
}
|
|
582
380
|
/**
|
|
583
381
|
* Return true if in range, otherwise false
|
|
@@ -586,44 +384,27 @@ class Reverb {
|
|
|
586
384
|
* @param min - Minimum value
|
|
587
385
|
* @param max - Maximum value
|
|
588
386
|
*/
|
|
589
|
-
static inRange(
|
|
590
|
-
return (
|
|
387
|
+
static inRange(e, s, i) {
|
|
388
|
+
return (e - s) * (e - i) <= 0;
|
|
591
389
|
}
|
|
592
390
|
/** Utility function for building an impulse response from the module parameters. */
|
|
593
391
|
buildImpulse() {
|
|
594
|
-
const
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
const impulseL = new Float32Array(duration);
|
|
599
|
-
const impulseR = new Float32Array(duration);
|
|
600
|
-
const noiseL = this.getNoise(duration);
|
|
601
|
-
const noiseR = this.getNoise(duration);
|
|
602
|
-
for (let i = 0; i < duration; i++) {
|
|
603
|
-
let n = 0;
|
|
604
|
-
if (i < delayDuration) {
|
|
605
|
-
impulseL[i] = 0;
|
|
606
|
-
impulseR[i] = 0;
|
|
607
|
-
n = this.options.reverse ?? false ? duration - (i - delayDuration) : i - delayDuration;
|
|
608
|
-
} else {
|
|
609
|
-
n = this.options.reverse ?? false ? duration - i : i;
|
|
610
|
-
}
|
|
611
|
-
impulseL[i] = (noiseL[i] ?? 0) * (1 - n / duration) ** this.options.decay;
|
|
612
|
-
impulseR[i] = (noiseR[i] ?? 0) * (1 - n / duration) ** this.options.decay;
|
|
392
|
+
const e = this.ctx.sampleRate, s = Math.max(e * this.options.time, 1), i = e * this.options.delay, n = this.ctx.createBuffer(2, s, e), a = new Float32Array(s), o = new Float32Array(s), r = this.getNoise(s), l = this.getNoise(s);
|
|
393
|
+
for (let c = 0; c < s; c++) {
|
|
394
|
+
let f = 0;
|
|
395
|
+
c < i ? (a[c] = 0, o[c] = 0, f = this.options.reverse ?? !1 ? s - (c - i) : c - i) : f = this.options.reverse ?? !1 ? s - c : c, a[c] = (r[c] ?? 0) * (1 - f / s) ** this.options.decay, o[c] = (l[c] ?? 0) * (1 - f / s) ** this.options.decay;
|
|
613
396
|
}
|
|
614
|
-
|
|
615
|
-
impulse.getChannelData(1).set(impulseR);
|
|
616
|
-
this.convolverNode.buffer = impulse;
|
|
397
|
+
n.getChannelData(0).set(a), n.getChannelData(1).set(o), this.convolverNode.buffer = n;
|
|
617
398
|
}
|
|
618
399
|
/**
|
|
619
400
|
* Noise source
|
|
620
401
|
*
|
|
621
402
|
* @param duration - length of IR.
|
|
622
403
|
*/
|
|
623
|
-
getNoise(
|
|
404
|
+
getNoise(e) {
|
|
624
405
|
return [
|
|
625
|
-
...
|
|
626
|
-
|
|
406
|
+
...A(
|
|
407
|
+
e,
|
|
627
408
|
this.noise({
|
|
628
409
|
bins: this.options.peaks,
|
|
629
410
|
scale: this.options.scale,
|
|
@@ -633,5 +414,6 @@ class Reverb {
|
|
|
633
414
|
];
|
|
634
415
|
}
|
|
635
416
|
}
|
|
636
|
-
|
|
637
|
-
|
|
417
|
+
export {
|
|
418
|
+
h as default
|
|
419
|
+
};
|