@logue/reverb 1.3.5 → 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 -425
- package/dist/Reverb.iife.js +2 -633
- package/dist/Reverb.umd.js +2 -636
- package/package.json +21 -23
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-20T03:01:00.334Z"
|
|
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,255 +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
|
-
constructor(val) {
|
|
253
|
-
this.value = val;
|
|
254
|
-
}
|
|
255
|
-
deref() {
|
|
256
|
-
return this.value;
|
|
257
|
-
}
|
|
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
|
+
}
|
|
258
155
|
}
|
|
259
|
-
const
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
* Convenience helper for building a full {@link Reducer} using the identity
|
|
266
|
-
* function (i.e. `(x) => x`) as completion step (true for 90% of all
|
|
267
|
-
* bundled transducers).
|
|
268
|
-
*
|
|
269
|
-
* @param init - init step of reducer
|
|
270
|
-
* @param rfn - reduction step of reducer
|
|
271
|
-
*/
|
|
272
|
-
const reducer = (init, rfn) => [init, (acc) => acc, rfn];
|
|
273
|
-
|
|
274
|
-
function push(xs) {
|
|
275
|
-
return xs
|
|
276
|
-
? [...xs]
|
|
277
|
-
: 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
|
+
);
|
|
278
162
|
}
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
*/
|
|
287
|
-
function* iterator(xform, xs) {
|
|
288
|
-
const rfn = ensureTransducer(xform)(push());
|
|
289
|
-
const complete = rfn[1];
|
|
290
|
-
const reduce = rfn[2];
|
|
291
|
-
for (let x of xs) {
|
|
292
|
-
const y = reduce([], x);
|
|
293
|
-
if (isReduced(y)) {
|
|
294
|
-
yield* unreduced(complete(y.deref()));
|
|
295
|
-
return;
|
|
296
|
-
}
|
|
297
|
-
if (y.length) {
|
|
298
|
-
yield* y;
|
|
299
|
-
}
|
|
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;
|
|
300
170
|
}
|
|
301
|
-
yield*
|
|
171
|
+
o.length && (yield* o);
|
|
172
|
+
}
|
|
173
|
+
yield* I(i([]));
|
|
302
174
|
}
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
* function. Therefore the resulting reducer takes inputs of `C` and an
|
|
314
|
-
* accumulator of type `A`.
|
|
315
|
-
*
|
|
316
|
-
* It is assumed that `fn` internally calls `rfn[2]` to pass its own
|
|
317
|
-
* results for further processing by the nested reducer `rfn`.
|
|
318
|
-
*
|
|
319
|
-
* @example
|
|
320
|
-
* ```ts
|
|
321
|
-
* compR(rfn, fn)
|
|
322
|
-
* // [rfn[0], rfn[1], fn]
|
|
323
|
-
* ```
|
|
324
|
-
*
|
|
325
|
-
* @param rfn -
|
|
326
|
-
* @param fn -
|
|
327
|
-
*/
|
|
328
|
-
const compR = (rfn, fn) => [rfn[0], rfn[1], fn];
|
|
329
|
-
|
|
330
|
-
function take(n, src) {
|
|
331
|
-
return isIterable(src)
|
|
332
|
-
? iterator(take(n), src)
|
|
333
|
-
: (rfn) => {
|
|
334
|
-
const r = rfn[2];
|
|
335
|
-
let m = n;
|
|
336
|
-
return compR(rfn, (acc, x) => --m > 0
|
|
337
|
-
? r(acc, x)
|
|
338
|
-
: m === 0
|
|
339
|
-
? ensureReduced(r(acc, x))
|
|
340
|
-
: reduced(acc));
|
|
341
|
-
};
|
|
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
|
+
};
|
|
342
185
|
}
|
|
343
|
-
|
|
344
|
-
class Reverb {
|
|
186
|
+
class h {
|
|
345
187
|
/** Version strings */
|
|
346
|
-
static version =
|
|
188
|
+
static version = w.version;
|
|
347
189
|
/** Build date */
|
|
348
|
-
static build =
|
|
190
|
+
static build = w.date;
|
|
349
191
|
/** AudioContext */
|
|
350
192
|
ctx;
|
|
351
193
|
/** Wet Level (Reverberated node) */
|
|
@@ -363,211 +205,167 @@ class Reverb {
|
|
|
363
205
|
/** Connected flag */
|
|
364
206
|
isConnected;
|
|
365
207
|
/** Noise Generator */
|
|
366
|
-
noise =
|
|
208
|
+
noise = R;
|
|
367
209
|
/**
|
|
368
210
|
* Constructor
|
|
369
211
|
*
|
|
370
212
|
* @param ctx - Root AudioContext
|
|
371
213
|
* @param options - Configure
|
|
372
214
|
*/
|
|
373
|
-
constructor(
|
|
374
|
-
this.ctx = ctx;
|
|
375
|
-
this.options = Object.assign(defaults, options);
|
|
376
|
-
this.wetGainNode = this.ctx.createGain();
|
|
377
|
-
this.dryGainNode = this.ctx.createGain();
|
|
378
|
-
this.filterNode = this.ctx.createBiquadFilter();
|
|
379
|
-
this.convolverNode = this.ctx.createConvolver();
|
|
380
|
-
this.outputNode = this.ctx.createGain();
|
|
381
|
-
this.isConnected = false;
|
|
382
|
-
this.filterType(this.options.filterType);
|
|
383
|
-
this.setNoise(this.options.noise);
|
|
384
|
-
this.buildImpulse();
|
|
385
|
-
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);
|
|
386
217
|
}
|
|
387
218
|
/**
|
|
388
219
|
* Connect the node for the reverb effect to the original sound node.
|
|
389
220
|
*
|
|
390
221
|
* @param sourceNode - Input source node
|
|
391
222
|
*/
|
|
392
|
-
connect(
|
|
393
|
-
|
|
394
|
-
this.isConnected = false;
|
|
395
|
-
return this.outputNode;
|
|
396
|
-
}
|
|
397
|
-
this.convolverNode.connect(this.filterNode);
|
|
398
|
-
this.filterNode.connect(this.wetGainNode);
|
|
399
|
-
sourceNode.connect(this.convolverNode);
|
|
400
|
-
sourceNode.connect(this.dryGainNode).connect(this.outputNode);
|
|
401
|
-
sourceNode.connect(this.wetGainNode).connect(this.outputNode);
|
|
402
|
-
this.isConnected = true;
|
|
403
|
-
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);
|
|
404
225
|
}
|
|
405
226
|
/**
|
|
406
227
|
* Disconnect the reverb node
|
|
407
228
|
*
|
|
408
229
|
* @param sourceNode - Input source node
|
|
409
230
|
*/
|
|
410
|
-
disconnect(
|
|
411
|
-
|
|
412
|
-
this.convolverNode.disconnect(this.filterNode);
|
|
413
|
-
this.filterNode.disconnect(this.wetGainNode);
|
|
414
|
-
}
|
|
415
|
-
this.isConnected = false;
|
|
416
|
-
return sourceNode;
|
|
231
|
+
disconnect(e) {
|
|
232
|
+
return this.isConnected && (this.convolverNode.disconnect(this.filterNode), this.filterNode.disconnect(this.wetGainNode)), this.isConnected = !1, e;
|
|
417
233
|
}
|
|
418
234
|
/**
|
|
419
235
|
* Dry/Wet ratio
|
|
420
236
|
*
|
|
421
237
|
* @param mix - Ratio (0~1)
|
|
422
238
|
*/
|
|
423
|
-
mix(
|
|
424
|
-
if (!
|
|
239
|
+
mix(e) {
|
|
240
|
+
if (!h.inRange(e, 0, 1))
|
|
425
241
|
throw new RangeError("[Reverb.js] Dry/Wet ratio must be between 0 to 1.");
|
|
426
|
-
|
|
427
|
-
this.options.mix = mix;
|
|
428
|
-
this.dryGainNode.gain.value = 1 - this.options.mix;
|
|
429
|
-
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;
|
|
430
243
|
}
|
|
431
244
|
/**
|
|
432
245
|
* Set Impulse Response time length (second)
|
|
433
246
|
*
|
|
434
247
|
* @param value - IR length
|
|
435
248
|
*/
|
|
436
|
-
time(
|
|
437
|
-
if (!
|
|
249
|
+
time(e) {
|
|
250
|
+
if (!h.inRange(e, 1, 50))
|
|
438
251
|
throw new RangeError(
|
|
439
252
|
"[Reverb.js] Time length of inpulse response must be less than 50sec."
|
|
440
253
|
);
|
|
441
|
-
|
|
442
|
-
this.options.time = value;
|
|
443
|
-
this.buildImpulse();
|
|
254
|
+
this.options.time = e, this.buildImpulse();
|
|
444
255
|
}
|
|
445
256
|
/**
|
|
446
257
|
* Impulse response decay rate.
|
|
447
258
|
*
|
|
448
259
|
* @param value - Decay value
|
|
449
260
|
*/
|
|
450
|
-
decay(
|
|
451
|
-
if (!
|
|
261
|
+
decay(e) {
|
|
262
|
+
if (!h.inRange(e, 0, 100))
|
|
452
263
|
throw new RangeError(
|
|
453
264
|
"[Reverb.js] Inpulse Response decay level must be less than 100."
|
|
454
265
|
);
|
|
455
|
-
|
|
456
|
-
this.options.decay = value;
|
|
457
|
-
this.buildImpulse();
|
|
266
|
+
this.options.decay = e, this.buildImpulse();
|
|
458
267
|
}
|
|
459
268
|
/**
|
|
460
269
|
* Delay before reverberation starts
|
|
461
270
|
*
|
|
462
271
|
* @param value - Time[ms]
|
|
463
272
|
*/
|
|
464
|
-
delay(
|
|
465
|
-
if (!
|
|
273
|
+
delay(e) {
|
|
274
|
+
if (!h.inRange(e, 0, 100))
|
|
466
275
|
throw new RangeError(
|
|
467
276
|
"[Reverb.js] Inpulse Response delay time must be less than 100."
|
|
468
277
|
);
|
|
469
|
-
|
|
470
|
-
this.options.delay = value;
|
|
471
|
-
this.buildImpulse();
|
|
278
|
+
this.options.delay = e, this.buildImpulse();
|
|
472
279
|
}
|
|
473
280
|
/**
|
|
474
281
|
* Reverse the impulse response.
|
|
475
282
|
*
|
|
476
283
|
* @param reverse - Reverse IR
|
|
477
284
|
*/
|
|
478
|
-
reverse(
|
|
479
|
-
this.options.reverse =
|
|
480
|
-
this.buildImpulse();
|
|
285
|
+
reverse(e) {
|
|
286
|
+
this.options.reverse = e, this.buildImpulse();
|
|
481
287
|
}
|
|
482
288
|
/**
|
|
483
289
|
* Filter for impulse response
|
|
484
290
|
*
|
|
485
291
|
* @param type - Filiter Type
|
|
486
292
|
*/
|
|
487
|
-
filterType(
|
|
488
|
-
this.filterNode.type = this.options.filterType =
|
|
293
|
+
filterType(e = "allpass") {
|
|
294
|
+
this.filterNode.type = this.options.filterType = e;
|
|
489
295
|
}
|
|
490
296
|
/**
|
|
491
297
|
* Filter frequency applied to impulse response
|
|
492
298
|
*
|
|
493
299
|
* @param freq - Frequency
|
|
494
300
|
*/
|
|
495
|
-
filterFreq(
|
|
496
|
-
if (!
|
|
301
|
+
filterFreq(e) {
|
|
302
|
+
if (!h.inRange(e, 20, 2e4))
|
|
497
303
|
throw new RangeError(
|
|
498
304
|
"[Reverb.js] Filter frequrncy must be between 20 and 20000."
|
|
499
305
|
);
|
|
500
|
-
|
|
501
|
-
this.options.filterFreq = freq;
|
|
502
|
-
this.filterNode.frequency.value = this.options.filterFreq;
|
|
306
|
+
this.options.filterFreq = e, this.filterNode.frequency.value = this.options.filterFreq;
|
|
503
307
|
}
|
|
504
308
|
/**
|
|
505
309
|
* Filter quality.
|
|
506
310
|
*
|
|
507
311
|
* @param q - Quality
|
|
508
312
|
*/
|
|
509
|
-
filterQ(
|
|
510
|
-
if (!
|
|
313
|
+
filterQ(e) {
|
|
314
|
+
if (!h.inRange(e, 0, 10))
|
|
511
315
|
throw new RangeError(
|
|
512
|
-
"[Reverb.js] Filter
|
|
316
|
+
"[Reverb.js] Filter Q value must be between 0 and 10."
|
|
513
317
|
);
|
|
514
|
-
|
|
515
|
-
this.options.filterQ = q;
|
|
516
|
-
this.filterNode.Q.value = this.options.filterQ;
|
|
318
|
+
this.options.filterQ = e, this.filterNode.Q.value = this.options.filterQ;
|
|
517
319
|
}
|
|
518
320
|
/**
|
|
519
321
|
* set IR source noise peaks
|
|
520
322
|
*
|
|
521
323
|
* @param p - Peaks
|
|
522
324
|
*/
|
|
523
|
-
peaks(
|
|
524
|
-
this.options.peaks =
|
|
525
|
-
this.buildImpulse();
|
|
325
|
+
peaks(e) {
|
|
326
|
+
this.options.peaks = e, this.buildImpulse();
|
|
526
327
|
}
|
|
527
328
|
/**
|
|
528
329
|
* set IR source noise scale.
|
|
529
330
|
*
|
|
530
331
|
* @param s - Scale
|
|
531
332
|
*/
|
|
532
|
-
scale(
|
|
533
|
-
this.options.scale =
|
|
534
|
-
this.buildImpulse();
|
|
333
|
+
scale(e) {
|
|
334
|
+
this.options.scale = e, this.buildImpulse();
|
|
535
335
|
}
|
|
536
336
|
/**
|
|
537
337
|
* set IR source noise generator.
|
|
538
338
|
*
|
|
539
339
|
* @param a - Algorithm
|
|
540
340
|
*/
|
|
541
|
-
randomAlgorithm(
|
|
542
|
-
this.options.randomAlgorithm =
|
|
543
|
-
this.buildImpulse();
|
|
341
|
+
randomAlgorithm(e) {
|
|
342
|
+
this.options.randomAlgorithm = e, this.buildImpulse();
|
|
544
343
|
}
|
|
545
344
|
/**
|
|
546
345
|
* Inpulse Response Noise algorithm.
|
|
547
346
|
*
|
|
548
347
|
* @param type - IR noise algorithm type.
|
|
549
348
|
*/
|
|
550
|
-
setNoise(
|
|
551
|
-
this.options.noise =
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
this.noise = blue;
|
|
349
|
+
setNoise(e) {
|
|
350
|
+
switch (this.options.noise = e, e) {
|
|
351
|
+
case d.blue:
|
|
352
|
+
this.noise = b;
|
|
555
353
|
break;
|
|
556
|
-
case
|
|
557
|
-
this.noise =
|
|
354
|
+
case d.green:
|
|
355
|
+
this.noise = C;
|
|
558
356
|
break;
|
|
559
|
-
case
|
|
560
|
-
this.noise =
|
|
357
|
+
case d.pink:
|
|
358
|
+
this.noise = j;
|
|
561
359
|
break;
|
|
562
|
-
case
|
|
563
|
-
case
|
|
564
|
-
this.noise =
|
|
360
|
+
case d.red:
|
|
361
|
+
case d.brown:
|
|
362
|
+
this.noise = y;
|
|
565
363
|
break;
|
|
566
|
-
case
|
|
567
|
-
this.noise =
|
|
364
|
+
case d.violet:
|
|
365
|
+
this.noise = M;
|
|
568
366
|
break;
|
|
569
367
|
default:
|
|
570
|
-
this.noise =
|
|
368
|
+
this.noise = R;
|
|
571
369
|
}
|
|
572
370
|
this.buildImpulse();
|
|
573
371
|
}
|
|
@@ -576,9 +374,8 @@ class Reverb {
|
|
|
576
374
|
*
|
|
577
375
|
* @param algorithm - Algorythm
|
|
578
376
|
*/
|
|
579
|
-
setRandomAlgorythm(
|
|
580
|
-
this.options.randomAlgorithm =
|
|
581
|
-
this.buildImpulse();
|
|
377
|
+
setRandomAlgorythm(e) {
|
|
378
|
+
this.options.randomAlgorithm = e, this.buildImpulse();
|
|
582
379
|
}
|
|
583
380
|
/**
|
|
584
381
|
* Return true if in range, otherwise false
|
|
@@ -587,44 +384,27 @@ class Reverb {
|
|
|
587
384
|
* @param min - Minimum value
|
|
588
385
|
* @param max - Maximum value
|
|
589
386
|
*/
|
|
590
|
-
static inRange(
|
|
591
|
-
return (
|
|
387
|
+
static inRange(e, s, i) {
|
|
388
|
+
return (e - s) * (e - i) <= 0;
|
|
592
389
|
}
|
|
593
390
|
/** Utility function for building an impulse response from the module parameters. */
|
|
594
391
|
buildImpulse() {
|
|
595
|
-
const
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
const impulseL = new Float32Array(duration);
|
|
600
|
-
const impulseR = new Float32Array(duration);
|
|
601
|
-
const noiseL = this.getNoise(duration);
|
|
602
|
-
const noiseR = this.getNoise(duration);
|
|
603
|
-
for (let i = 0; i < duration; i++) {
|
|
604
|
-
let n = 0;
|
|
605
|
-
if (i < delayDuration) {
|
|
606
|
-
impulseL[i] = 0;
|
|
607
|
-
impulseR[i] = 0;
|
|
608
|
-
n = this.options.reverse ?? false ? duration - (i - delayDuration) : i - delayDuration;
|
|
609
|
-
} else {
|
|
610
|
-
n = this.options.reverse ?? false ? duration - i : i;
|
|
611
|
-
}
|
|
612
|
-
impulseL[i] = (noiseL[i] ?? 0) * (1 - n / duration) ** this.options.decay;
|
|
613
|
-
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;
|
|
614
396
|
}
|
|
615
|
-
|
|
616
|
-
impulse.getChannelData(1).set(impulseR);
|
|
617
|
-
this.convolverNode.buffer = impulse;
|
|
397
|
+
n.getChannelData(0).set(a), n.getChannelData(1).set(o), this.convolverNode.buffer = n;
|
|
618
398
|
}
|
|
619
399
|
/**
|
|
620
400
|
* Noise source
|
|
621
401
|
*
|
|
622
402
|
* @param duration - length of IR.
|
|
623
403
|
*/
|
|
624
|
-
getNoise(
|
|
404
|
+
getNoise(e) {
|
|
625
405
|
return [
|
|
626
|
-
...
|
|
627
|
-
|
|
406
|
+
...A(
|
|
407
|
+
e,
|
|
628
408
|
this.noise({
|
|
629
409
|
bins: this.options.peaks,
|
|
630
410
|
scale: this.options.scale,
|
|
@@ -634,5 +414,6 @@ class Reverb {
|
|
|
634
414
|
];
|
|
635
415
|
}
|
|
636
416
|
}
|
|
637
|
-
|
|
638
|
-
|
|
417
|
+
export {
|
|
418
|
+
h as default
|
|
419
|
+
};
|