@logue/reverb 1.1.0 → 1.2.1

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 CHANGED
@@ -5,7 +5,7 @@
5
5
  [![Open in unpkg](https://img.shields.io/badge/Open%20in-unpkg-blue)](https://uiwjs.github.io/npm-unpkg/#/pkg/@logue/reverb/file/README.md)
6
6
  [![npm version](https://img.shields.io/npm/v/@logue/reverb.svg)](https://www.npmjs.com/package/@logue/reverb)
7
7
  [![Open in Gitpod](https://shields.io/badge/Open%20in-Gitpod-green?logo=Gitpod)](https://gitpod.io/#https://github.com/logue/Reverb.js)
8
- [![Twitter Follow](https://img.shields.io/twitter/follow/logue256?style=plastic)](https://twitter.com/thing_umbrella)
8
+ [![Twitter Follow](https://img.shields.io/twitter/follow/logue256?style=plastic)](https://twitter.com/logue256)
9
9
 
10
10
  Append reverb effect to audio source.
11
11
 
@@ -1,7 +1,7 @@
1
1
  /** Impulse response noise generation algorithm */
2
2
  declare const Noise: Record<string, string>;
3
3
  /** Noise Type */
4
- export declare type NoiseType = typeof Noise[keyof typeof Noise];
4
+ export type NoiseType = typeof Noise[keyof typeof Noise];
5
5
  /** Noise */
6
6
  export default Noise;
7
7
  //# sourceMappingURL=NoiseType.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"NoiseType.d.ts","sourceRoot":"","sources":["../src/NoiseType.ts"],"names":[],"mappings":"AAAA,kDAAkD;AAClD,QAAA,MAAM,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAexB,CAAC;AAEX,iBAAiB;AACjB,oBAAY,SAAS,GAAG,OAAO,KAAK,CAAC,MAAM,OAAO,KAAK,CAAC,CAAC;AAEzD,YAAY;AACZ,eAAe,KAAK,CAAC"}
1
+ {"version":3,"file":"NoiseType.d.ts","sourceRoot":"","sources":["../src/NoiseType.ts"],"names":[],"mappings":"AAAA,kDAAkD;AAClD,QAAA,MAAM,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAexB,CAAC;AAEX,iBAAiB;AACjB,MAAM,MAAM,SAAS,GAAG,OAAO,KAAK,CAAC,MAAM,OAAO,KAAK,CAAC,CAAC;AAEzD,YAAY;AACZ,eAAe,KAAK,CAAC"}
package/dist/Reverb.d.ts CHANGED
@@ -45,7 +45,7 @@ export default class Reverb {
45
45
  *
46
46
  * @param sourceNode - Input source node
47
47
  */
48
- disconnect(sourceNode: AudioNode | undefined): AudioNode | undefined;
48
+ disconnect(sourceNode?: AudioNode): AudioNode | undefined;
49
49
  /**
50
50
  * Dry/Wet ratio
51
51
  *
@@ -81,7 +81,7 @@ export default class Reverb {
81
81
  *
82
82
  * @param type - Filiter Type
83
83
  */
84
- filterType(type: BiquadFilterType): void;
84
+ filterType(type?: BiquadFilterType): void;
85
85
  /**
86
86
  * Filter frequency applied to impulse response
87
87
  *
@@ -1 +1 @@
1
- {"version":3,"file":"Reverb.d.ts","sourceRoot":"","sources":["../src/Reverb.ts"],"names":[],"mappings":"AAEA,OAAc,EAAE,KAAK,SAAS,EAAE,MAAM,aAAa,CAAC;AACpD,OAAO,KAAK,eAAe,MAAM,8BAA8B,CAAC;AAIhE,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AAE5C;;GAEG;AACH,MAAM,CAAC,OAAO,OAAO,MAAM;IACzB,sBAAsB;IACtB,MAAM,CAAC,OAAO,EAAE,MAAM,CAAgB;IACtC,iBAAiB;IACjB,MAAM,CAAC,KAAK,EAAE,MAAM,CAAa;IACjC,mBAAmB;IACnB,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAe;IACnC,oCAAoC;IACpC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAW;IACvC,sCAAsC;IACtC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAW;IACvC,8BAA8B;IAC9B,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAmB;IAC9C,qDAAqD;IACrD,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAgB;IAC9C,uBAAuB;IACvB,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAW;IACtC,aAAa;IACb,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAkB;IAC1C,qBAAqB;IACrB,OAAO,CAAC,WAAW,CAAU;IAC7B,sBAAsB;IACtB,OAAO,CAAC,KAAK,CAAmB;IAEhC;;;;;OAKG;gBACS,GAAG,EAAE,YAAY,EAAE,OAAO,CAAC,EAAE,eAAe;IAoBxD;;;;OAIG;IACI,OAAO,CAAC,UAAU,EAAE,SAAS,GAAG,SAAS;IAsBhD;;;;OAIG;IACI,UAAU,CAAC,UAAU,EAAE,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG,SAAS;IAe3E;;;;OAIG;IACI,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAU7B;;;;OAIG;IACI,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAahC;;;;OAIG;IACI,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAWjC;;;;OAIG;IACI,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAajC;;;;OAIG;IACI,OAAO,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAQtC;;;;OAIG;IACI,UAAU,CAAC,IAAI,EAAE,gBAAgB,GAAG,IAAI;IAK/C;;;;OAIG;IACI,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAWrC;;;;OAIG;IACI,OAAO,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI;IAW/B;;;;OAIG;IACI,KAAK,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI;IAM7B;;;;OAIG;IACI,KAAK,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI;IAM7B;;;;OAIG;IACI,eAAe,CAAC,CAAC,EAAE,KAAK,GAAG,IAAI;IAMtC;;;;OAIG;IACI,QAAQ,CAAC,IAAI,EAAE,SAAS;IA2B/B;;;;OAIG;IACI,kBAAkB,CAAC,SAAS,EAAE,KAAK;IAK1C;;;;;;OAMG;IACH,OAAO,CAAC,OAAO;IAIf,oFAAoF;IACpF,OAAO,CAAC,YAAY;IA+CpB;;;;OAIG;IACH,OAAO,CAAC,QAAQ;CAcjB"}
1
+ {"version":3,"file":"Reverb.d.ts","sourceRoot":"","sources":["../src/Reverb.ts"],"names":[],"mappings":"AAEA,OAAc,EAAE,KAAK,SAAS,EAAE,MAAM,aAAa,CAAC;AACpD,OAAO,KAAK,eAAe,MAAM,8BAA8B,CAAC;AAIhE,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AAE5C;;GAEG;AACH,MAAM,CAAC,OAAO,OAAO,MAAM;IACzB,sBAAsB;IACtB,MAAM,CAAC,OAAO,EAAE,MAAM,CAAgB;IACtC,iBAAiB;IACjB,MAAM,CAAC,KAAK,EAAE,MAAM,CAAa;IACjC,mBAAmB;IACnB,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAe;IACnC,oCAAoC;IACpC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAW;IACvC,sCAAsC;IACtC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAW;IACvC,8BAA8B;IAC9B,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAmB;IAC9C,qDAAqD;IACrD,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAgB;IAC9C,uBAAuB;IACvB,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAW;IACtC,aAAa;IACb,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAkB;IAC1C,qBAAqB;IACrB,OAAO,CAAC,WAAW,CAAU;IAC7B,sBAAsB;IACtB,OAAO,CAAC,KAAK,CAAmB;IAEhC;;;;;OAKG;gBACS,GAAG,EAAE,YAAY,EAAE,OAAO,CAAC,EAAE,eAAe;IAqBxD;;;;OAIG;IACI,OAAO,CAAC,UAAU,EAAE,SAAS,GAAG,SAAS;IAsBhD;;;;OAIG;IACI,UAAU,CAAC,UAAU,CAAC,EAAE,SAAS,GAAG,SAAS,GAAG,SAAS;IAehE;;;;OAIG;IACI,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAU7B;;;;OAIG;IACI,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAahC;;;;OAIG;IACI,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAWjC;;;;OAIG;IACI,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAajC;;;;OAIG;IACI,OAAO,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAQtC;;;;OAIG;IACI,UAAU,CAAC,IAAI,GAAE,gBAA4B,GAAG,IAAI;IAK3D;;;;OAIG;IACI,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAWrC;;;;OAIG;IACI,OAAO,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI;IAW/B;;;;OAIG;IACI,KAAK,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI;IAM7B;;;;OAIG;IACI,KAAK,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI;IAM7B;;;;OAIG;IACI,eAAe,CAAC,CAAC,EAAE,KAAK,GAAG,IAAI;IAMtC;;;;OAIG;IACI,QAAQ,CAAC,IAAI,EAAE,SAAS;IA0B/B;;;;OAIG;IACI,kBAAkB,CAAC,SAAS,EAAE,KAAK;IAK1C;;;;;;OAMG;IACH,OAAO,CAAC,OAAO;IAIf,oFAAoF;IACpF,OAAO,CAAC,YAAY;IA+CpB;;;;OAIG;IACH,OAAO,CAAC,QAAQ;CAYjB"}
package/dist/Reverb.es.js CHANGED
@@ -5,11 +5,15 @@
5
5
  * @author Logue <logue@hotmail.co.jp>
6
6
  * @copyright 2019-2022 By Masashi Yoshikawa All rights reserved.
7
7
  * @license MIT
8
- * @version 1.1.0
8
+ * @version 1.2.1
9
9
  * @see {@link https://github.com/logue/Reverb.js}
10
10
  */
11
11
 
12
- const a = {
12
+ import { SYSTEM } from '@thi.ng/random';
13
+ import { white, violet, red, pink, green, blue } from '@thi.ng/colored-noise';
14
+ import { take } from '@thi.ng/transducers';
15
+
16
+ const Noise = {
13
17
  BLUE: "blue",
14
18
  GREEN: "green",
15
19
  PINK: "pink",
@@ -17,243 +21,209 @@ const a = {
17
21
  VIOLET: "violet",
18
22
  WHITE: "white",
19
23
  BROWN: "red"
20
- }, g = 1 / 2 ** 32;
21
- class S {
22
- float(e = 1) {
23
- return this.int() * g * e;
24
- }
25
- norm(e = 1) {
26
- return (this.int() * g - 0.5) * 2 * e;
27
- }
28
- minmax(e, s) {
29
- return this.float() * (s - e) + e;
30
- }
31
- minmaxInt(e, s) {
32
- return e |= 0, s |= 0, e + (this.float() * (s - e) | 0);
33
- }
34
- }
35
- const f = Math.random;
36
- class k extends S {
37
- int() {
38
- return f() * 4294967296 >>> 0;
39
- }
40
- float(e = 1) {
41
- return f() * e;
42
- }
43
- norm(e = 1) {
44
- return (f() - 0.5) * 2 * e;
45
- }
46
- }
47
- const h = new k(), G = {
48
- noise: a.WHITE,
49
- scale: 2,
24
+ };
25
+
26
+ const defaults = {
27
+ noise: Noise.WHITE,
28
+ scale: 1,
50
29
  peaks: 2,
51
- randomAlgorithm: h,
30
+ randomAlgorithm: SYSTEM,
52
31
  decay: 2,
53
32
  delay: 0,
54
- reverse: !1,
33
+ reverse: false,
55
34
  time: 2,
56
- filterType: "lowpass",
35
+ filterType: "allpass",
57
36
  filterFreq: 2200,
58
37
  filterQ: 1,
59
38
  mix: 0.5,
60
- once: !1
61
- }, w = {
62
- version: "1.1.0",
63
- date: "2022-10-04T02:13:31.946Z"
64
- }, b = (t, e, s) => {
65
- const o = new Array(t);
66
- for (let n = 0; n < t; n++)
67
- o[n] = s.norm(e);
68
- return o;
69
- }, R = (t) => t.reduce((e, s) => e + s, 0);
70
- function* I(t, e) {
71
- const s = [t[Symbol.iterator](), e[Symbol.iterator]()];
72
- for (let o = 0; ; o ^= 1) {
73
- const n = s[o].next();
74
- if (n.done)
75
- return;
76
- yield n.value;
77
- }
78
- }
79
- function* p(t = 2, e = 1, s = h) {
80
- const o = b(t, e, s);
81
- o.forEach((i, c) => o[c] = c & 1 ? i : -i);
82
- const n = 1 / t;
83
- let r = R(o);
84
- for (let i = 0, c = -1; ; ++i >= t && (i = 0))
85
- r -= o[i], r += o[i] = c * s.norm(e), c ^= 4294967294, yield c * r * n;
86
- }
87
- const A = (t = 2, e = 1, s = h) => I(p(t, e, s), p(t, e, s)), T = (t) => {
88
- let e = 32;
89
- 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;
39
+ once: false
90
40
  };
91
- function* $(t = 8, e = 1, s = h) {
92
- const o = b(t, e, s), n = 1 / t;
93
- let r = R(o);
94
- for (let i = 0; ; i = i + 1 >>> 0) {
95
- const c = T(i) % t;
96
- r -= o[c], r += o[c] = s.norm(e), yield r * n;
97
- }
98
- }
99
- function* m(t = 2, e = 1, s = h) {
100
- const o = b(t, e, s), n = 1 / t;
101
- let r = R(o);
102
- for (let i = 0; ; ++i >= t && (i = 0))
103
- r -= o[i], r += o[i] = s.norm(e), yield r * n;
104
- }
105
- const F = (t = 2, e = 1, s = h) => I(m(t, e, s), m(t, e, s));
106
- function* y(t = 1, e = h) {
107
- for (; ; )
108
- yield e.norm(t);
109
- }
110
- const x = (t, e) => t != null && typeof t[e] == "function", C = (t) => x(t, "xform") ? t.xform() : t, B = (t) => t != null && typeof t[Symbol.iterator] == "function";
111
- class u {
112
- constructor(e) {
113
- this.value = e;
114
- }
115
- deref() {
116
- return this.value;
117
- }
118
- }
119
- const D = (t) => new u(t), L = (t) => t instanceof u, Q = (t) => t instanceof u ? t : new u(t), N = (t) => t instanceof u ? t.deref() : t, W = (t, e) => [t, (s) => s, e];
120
- function q(t) {
121
- return t ? [...t] : W(() => [], (e, s) => (e.push(s), e));
122
- }
123
- function* H(t, e) {
124
- const s = C(t)(q()), o = s[1], n = s[2];
125
- for (let r of e) {
126
- const i = n([], r);
127
- if (L(i)) {
128
- yield* N(o(i.deref()));
129
- return;
41
+
42
+ const meta = {
43
+ version: "1.2.1",
44
+ date: "2022-11-24T14:46:07.438Z"
45
+ };
46
+
47
+ class Reverb {
48
+ static version = meta.version;
49
+ static build = meta.date;
50
+ ctx;
51
+ wetGainNode;
52
+ dryGainNode;
53
+ filterNode;
54
+ convolverNode;
55
+ outputNode;
56
+ options;
57
+ isConnected;
58
+ noise = white;
59
+ constructor(ctx, options) {
60
+ this.ctx = ctx;
61
+ this.options = { ...defaults, ...options };
62
+ this.wetGainNode = this.ctx.createGain();
63
+ this.dryGainNode = this.ctx.createGain();
64
+ this.filterNode = this.ctx.createBiquadFilter();
65
+ this.convolverNode = this.ctx.createConvolver();
66
+ this.outputNode = this.ctx.createGain();
67
+ this.isConnected = false;
68
+ this.filterType(this.options.filterType);
69
+ this.setNoise(this.options.noise);
70
+ this.buildImpulse();
71
+ this.mix(this.options.mix);
72
+ }
73
+ connect(sourceNode) {
74
+ if (this.isConnected && this.options.once) {
75
+ this.isConnected = false;
76
+ return this.outputNode;
130
77
  }
131
- i.length && (yield* i);
132
- }
133
- yield* N(o([]));
134
- }
135
- const M = (t, e) => [t[0], t[1], e];
136
- function E(t, e) {
137
- return B(e) ? H(E(t), e) : (s) => {
138
- const o = s[2];
139
- let n = t;
140
- return M(s, (r, i) => --n > 0 ? o(r, i) : n === 0 ? Q(o(r, i)) : D(r));
141
- };
142
- }
143
- class v {
144
- constructor(e, s) {
145
- this.noise = y, this.ctx = e, this.options = { ...G, ...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.setNoise(this.options.noise), this.buildImpulse(), this.mix(this.options.mix);
146
- }
147
- connect(e) {
148
- 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);
149
- }
150
- disconnect(e) {
151
- return this.isConnected && (this.convolverNode.disconnect(this.filterNode), this.filterNode.disconnect(this.wetGainNode)), this.isConnected = !1, e;
78
+ this.convolverNode.connect(this.filterNode);
79
+ this.filterNode.connect(this.wetGainNode);
80
+ sourceNode.connect(this.convolverNode);
81
+ sourceNode.connect(this.dryGainNode).connect(this.outputNode);
82
+ sourceNode.connect(this.wetGainNode).connect(this.outputNode);
83
+ this.isConnected = true;
84
+ return this.outputNode;
85
+ }
86
+ disconnect(sourceNode) {
87
+ if (this.isConnected) {
88
+ this.convolverNode.disconnect(this.filterNode);
89
+ this.filterNode.disconnect(this.wetGainNode);
90
+ }
91
+ this.isConnected = false;
92
+ return sourceNode;
152
93
  }
153
- mix(e) {
154
- if (!this.inRange(e, 0, 1))
94
+ mix(mix) {
95
+ if (!this.inRange(mix, 0, 1)) {
155
96
  throw new RangeError("[Reverb.js] Dry/Wet ratio must be between 0 to 1.");
156
- this.options.mix = e, this.dryGainNode.gain.value = 1 - this.options.mix, this.wetGainNode.gain.value = this.options.mix, console.debug(`[Reverb.js] Set dry/wet ratio to ${e * 100}%`);
97
+ }
98
+ this.options.mix = mix;
99
+ this.dryGainNode.gain.value = 1 - this.options.mix;
100
+ this.wetGainNode.gain.value = this.options.mix;
157
101
  }
158
- time(e) {
159
- if (!this.inRange(e, 1, 50))
102
+ time(value) {
103
+ if (!this.inRange(value, 1, 50)) {
160
104
  throw new RangeError(
161
105
  "[Reverb.js] Time length of inpulse response must be less than 50sec."
162
106
  );
163
- this.options.time = e, this.buildImpulse(), console.debug(
164
- `[Reverb.js] Set inpulse response time length to ${e}sec.`
165
- );
107
+ }
108
+ this.options.time = value;
109
+ this.buildImpulse();
166
110
  }
167
- decay(e) {
168
- if (!this.inRange(e, 0, 100))
111
+ decay(value) {
112
+ if (!this.inRange(value, 0, 100)) {
169
113
  throw new RangeError(
170
114
  "[Reverb.js] Inpulse Response decay level must be less than 100."
171
115
  );
172
- this.options.decay = e, this.buildImpulse(), console.debug(`[Reverb.js] Set inpulse response decay level to ${e}.`);
116
+ }
117
+ this.options.decay = value;
118
+ this.buildImpulse();
173
119
  }
174
- delay(e) {
175
- if (!this.inRange(e, 0, 100))
120
+ delay(value) {
121
+ if (!this.inRange(value, 0, 100)) {
176
122
  throw new RangeError(
177
123
  "[Reverb.js] Inpulse Response delay time must be less than 100."
178
124
  );
179
- this.options.delay = e, this.buildImpulse(), console.debug(
180
- `[Reverb.js] Set inpulse response delay time to ${e}sec.`
181
- );
125
+ }
126
+ this.options.delay = value;
127
+ this.buildImpulse();
182
128
  }
183
- reverse(e) {
184
- this.options.reverse = e, this.buildImpulse(), console.debug(
185
- `[Reverb.js] Inpulse response is ${e ? "" : "not "}reversed.`
186
- );
129
+ reverse(reverse) {
130
+ this.options.reverse = reverse;
131
+ this.buildImpulse();
187
132
  }
188
- filterType(e) {
189
- this.filterNode.type = this.options.filterType = e, console.debug(`[Reverb.js] Set filter type to ${e}`);
133
+ filterType(type = "allpass") {
134
+ this.filterNode.type = this.options.filterType = type;
190
135
  }
191
- filterFreq(e) {
192
- if (!this.inRange(e, 20, 2e4))
136
+ filterFreq(freq) {
137
+ if (!this.inRange(freq, 20, 2e4)) {
193
138
  throw new RangeError(
194
139
  "[Reverb.js] Filter frequrncy must be between 20 and 20000."
195
140
  );
196
- this.options.filterFreq = e, this.filterNode.frequency.value = this.options.filterFreq, console.debug(`[Reverb.js] Set filter frequency to ${e}Hz.`);
141
+ }
142
+ this.options.filterFreq = freq;
143
+ this.filterNode.frequency.value = this.options.filterFreq;
197
144
  }
198
- filterQ(e) {
199
- if (!this.inRange(e, 0, 10))
145
+ filterQ(q) {
146
+ if (!this.inRange(q, 0, 10)) {
200
147
  throw new RangeError(
201
148
  "[Reverb.js] Filter quality value must be between 0 and 10."
202
149
  );
203
- this.options.filterQ = e, this.filterNode.Q.value = this.options.filterQ, console.debug(`[Reverb.js] Set filter Q to ${e}.`);
204
- }
205
- peaks(e) {
206
- this.options.peaks = e, this.buildImpulse(), console.debug(`[Reverb.js] Set IR source noise peaks to ${e}.`);
207
- }
208
- scale(e) {
209
- this.options.scale = e, this.buildImpulse(), console.debug(`[Reverb.js] Set IR source noise scale to ${e}.`);
210
- }
211
- randomAlgorithm(e) {
212
- this.options.randomAlgorithm = e, this.buildImpulse(), console.debug(`[Reverb.js] Set IR source noise generator to ${e}.`);
213
- }
214
- setNoise(e) {
215
- switch (this.options.noise = e, e) {
216
- case a.BLUE:
217
- this.noise = p;
150
+ }
151
+ this.options.filterQ = q;
152
+ this.filterNode.Q.value = this.options.filterQ;
153
+ }
154
+ peaks(p) {
155
+ this.options.peaks = p;
156
+ this.buildImpulse();
157
+ }
158
+ scale(s) {
159
+ this.options.scale = s;
160
+ this.buildImpulse();
161
+ }
162
+ randomAlgorithm(a) {
163
+ this.options.randomAlgorithm = a;
164
+ this.buildImpulse();
165
+ }
166
+ setNoise(type) {
167
+ this.options.noise = type;
168
+ switch (type) {
169
+ case Noise.BLUE:
170
+ this.noise = blue;
218
171
  break;
219
- case a.GREEN:
220
- this.noise = A;
172
+ case Noise.GREEN:
173
+ this.noise = green;
221
174
  break;
222
- case a.PINK:
223
- this.noise = $;
175
+ case Noise.PINK:
176
+ this.noise = pink;
224
177
  break;
225
- case a.RED:
226
- case a.BROWN:
227
- this.noise = m;
178
+ case Noise.RED:
179
+ case Noise.BROWN:
180
+ this.noise = red;
228
181
  break;
229
- case a.VIOLET:
230
- this.noise = F;
182
+ case Noise.VIOLET:
183
+ this.noise = violet;
231
184
  break;
232
185
  default:
233
- this.noise = y;
234
- break;
186
+ this.noise = white;
235
187
  }
236
- this.buildImpulse(), console.debug(`[Reverb.js] Set IR generator source noise type to ${e}.`);
188
+ this.buildImpulse();
237
189
  }
238
- setRandomAlgorythm(e) {
239
- this.options.randomAlgorithm = e, this.buildImpulse();
190
+ setRandomAlgorythm(algorithm) {
191
+ this.options.randomAlgorithm = algorithm;
192
+ this.buildImpulse();
240
193
  }
241
- inRange(e, s, o) {
242
- return (e - s) * (e - o) <= 0;
194
+ inRange(x, min, max) {
195
+ return (x - min) * (x - max) <= 0;
243
196
  }
244
197
  buildImpulse() {
245
- const e = this.ctx.sampleRate, s = Math.max(e * this.options.time, 1), o = e * this.options.delay, n = this.ctx.createBuffer(2, s, e), r = new Float32Array(s), i = new Float32Array(s), c = this.getNoise(s), j = this.getNoise(s);
246
- for (let l = 0; l < s; l++) {
247
- let d = 0;
248
- l < o ? (r[l] = 0, i[l] = 0, d = this.options.reverse ? s - (l - o) : l - o) : d = this.options.reverse ? s - l : l, r[l] = c[l] * (1 - d / s) ** this.options.decay, i[l] = j[l] * (1 - d / s) ** this.options.decay;
198
+ const rate = this.ctx.sampleRate;
199
+ const duration = Math.max(rate * this.options.time, 1);
200
+ const delayDuration = rate * this.options.delay;
201
+ const impulse = this.ctx.createBuffer(2, duration, rate);
202
+ const impulseL = new Float32Array(duration);
203
+ const impulseR = new Float32Array(duration);
204
+ const noiseL = this.getNoise(duration);
205
+ const noiseR = this.getNoise(duration);
206
+ for (let i = 0; i < duration; i++) {
207
+ let n = 0;
208
+ if (i < delayDuration) {
209
+ impulseL[i] = 0;
210
+ impulseR[i] = 0;
211
+ n = this.options.reverse ? duration - (i - delayDuration) : i - delayDuration;
212
+ } else {
213
+ n = this.options.reverse ? duration - i : i;
214
+ }
215
+ impulseL[i] = noiseL[i] * (1 - n / duration) ** this.options.decay;
216
+ impulseR[i] = noiseR[i] * (1 - n / duration) ** this.options.decay;
249
217
  }
250
- n.getChannelData(0).set(r), n.getChannelData(1).set(i), this.convolverNode.buffer = n;
218
+ impulse.getChannelData(0).set(impulseL);
219
+ impulse.getChannelData(1).set(impulseR);
220
+ this.convolverNode.buffer = impulse;
251
221
  }
252
- getNoise(e) {
222
+ getNoise(duration) {
253
223
  return [
254
- ...E(
255
- e,
256
- this.options.noise === a.WHITE ? this.noise(this.options.peaks, this.options.randomAlgorithm) : this.noise(
224
+ ...take(
225
+ duration,
226
+ this.noise(
257
227
  this.options.peaks,
258
228
  this.options.scale,
259
229
  this.options.randomAlgorithm
@@ -262,9 +232,8 @@ class v {
262
232
  ];
263
233
  }
264
234
  }
265
- v.version = w.version;
266
- v.build = w.date;
267
- window.Reverb || (window.Reverb = v);
268
- export {
269
- v as default
270
- };
235
+ if (!window.Reverb) {
236
+ window.Reverb = Reverb;
237
+ }
238
+
239
+ export { Reverb as default };
@@ -5,8 +5,236 @@
5
5
  * @author Logue <logue@hotmail.co.jp>
6
6
  * @copyright 2019-2022 By Masashi Yoshikawa All rights reserved.
7
7
  * @license MIT
8
- * @version 1.1.0
8
+ * @version 1.2.1
9
9
  * @see {@link https://github.com/logue/Reverb.js}
10
10
  */
11
11
 
12
- var Reverb=function(){"use strict";const a={BLUE:"blue",GREEN:"green",PINK:"pink",RED:"red",VIOLET:"violet",WHITE:"white",BROWN:"red"},g=1/2**32;class j{float(e=1){return this.int()*g*e}norm(e=1){return(this.int()*g-.5)*2*e}minmax(e,s){return this.float()*(s-e)+e}minmaxInt(e,s){return e|=0,s|=0,e+(this.float()*(s-e)|0)}}const p=Math.random;class S extends j{int(){return p()*4294967296>>>0}float(e=1){return p()*e}norm(e=1){return(p()-.5)*2*e}}const h=new S,k={noise:a.WHITE,scale:2,peaks:2,randomAlgorithm:h,decay:2,delay:0,reverse:!1,time:2,filterType:"lowpass",filterFreq:2200,filterQ:1,mix:.5,once:!1},y={version:"1.1.0",date:"2022-10-04T02:13:31.946Z"},m=(t,e,s)=>{const o=new Array(t);for(let n=0;n<t;n++)o[n]=s.norm(e);return o},b=t=>t.reduce((e,s)=>e+s,0);function*N(t,e){const s=[t[Symbol.iterator](),e[Symbol.iterator]()];for(let o=0;;o^=1){const n=s[o].next();if(n.done)return;yield n.value}}function*R(t=2,e=1,s=h){const o=m(t,e,s);o.forEach((i,l)=>o[l]=l&1?i:-i);const n=1/t;let r=b(o);for(let i=0,l=-1;;++i>=t&&(i=0))r-=o[i],r+=o[i]=l*s.norm(e),l^=4294967294,yield l*r*n}const G=(t=2,e=1,s=h)=>N(R(t,e,s),R(t,e,s)),A=t=>{let e=32;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};function*T(t=8,e=1,s=h){const o=m(t,e,s),n=1/t;let r=b(o);for(let i=0;;i=i+1>>>0){const l=A(i)%t;r-=o[l],r+=o[l]=s.norm(e),yield r*n}}function*v(t=2,e=1,s=h){const o=m(t,e,s),n=1/t;let r=b(o);for(let i=0;;++i>=t&&(i=0))r-=o[i],r+=o[i]=s.norm(e),yield r*n}const $=(t=2,e=1,s=h)=>N(v(t,e,s),v(t,e,s));function*w(t=1,e=h){for(;;)yield e.norm(t)}const F=(t,e)=>t!=null&&typeof t[e]=="function",C=t=>F(t,"xform")?t.xform():t,x=t=>t!=null&&typeof t[Symbol.iterator]=="function";class u{constructor(e){this.value=e}deref(){return this.value}}const B=t=>new u(t),D=t=>t instanceof u,L=t=>t instanceof u?t:new u(t),I=t=>t instanceof u?t.deref():t,Q=(t,e)=>[t,s=>s,e];function W(t){return t?[...t]:Q(()=>[],(e,s)=>(e.push(s),e))}function*q(t,e){const s=C(t)(W()),o=s[1],n=s[2];for(let r of e){const i=n([],r);if(D(i)){yield*I(o(i.deref()));return}i.length&&(yield*i)}yield*I(o([]))}const H=(t,e)=>[t[0],t[1],e];function E(t,e){return x(e)?q(E(t),e):s=>{const o=s[2];let n=t;return H(s,(r,i)=>--n>0?o(r,i):n===0?L(o(r,i)):B(r))}}class d{constructor(e,s){this.noise=w,this.ctx=e,this.options={...k,...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.setNoise(this.options.noise),this.buildImpulse(),this.mix(this.options.mix)}connect(e){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)}disconnect(e){return this.isConnected&&(this.convolverNode.disconnect(this.filterNode),this.filterNode.disconnect(this.wetGainNode)),this.isConnected=!1,e}mix(e){if(!this.inRange(e,0,1))throw new RangeError("[Reverb.js] Dry/Wet ratio must be between 0 to 1.");this.options.mix=e,this.dryGainNode.gain.value=1-this.options.mix,this.wetGainNode.gain.value=this.options.mix,console.debug(`[Reverb.js] Set dry/wet ratio to ${e*100}%`)}time(e){if(!this.inRange(e,1,50))throw new RangeError("[Reverb.js] Time length of inpulse response must be less than 50sec.");this.options.time=e,this.buildImpulse(),console.debug(`[Reverb.js] Set inpulse response time length to ${e}sec.`)}decay(e){if(!this.inRange(e,0,100))throw new RangeError("[Reverb.js] Inpulse Response decay level must be less than 100.");this.options.decay=e,this.buildImpulse(),console.debug(`[Reverb.js] Set inpulse response decay level to ${e}.`)}delay(e){if(!this.inRange(e,0,100))throw new RangeError("[Reverb.js] Inpulse Response delay time must be less than 100.");this.options.delay=e,this.buildImpulse(),console.debug(`[Reverb.js] Set inpulse response delay time to ${e}sec.`)}reverse(e){this.options.reverse=e,this.buildImpulse(),console.debug(`[Reverb.js] Inpulse response is ${e?"":"not "}reversed.`)}filterType(e){this.filterNode.type=this.options.filterType=e,console.debug(`[Reverb.js] Set filter type to ${e}`)}filterFreq(e){if(!this.inRange(e,20,2e4))throw new RangeError("[Reverb.js] Filter frequrncy must be between 20 and 20000.");this.options.filterFreq=e,this.filterNode.frequency.value=this.options.filterFreq,console.debug(`[Reverb.js] Set filter frequency to ${e}Hz.`)}filterQ(e){if(!this.inRange(e,0,10))throw new RangeError("[Reverb.js] Filter quality value must be between 0 and 10.");this.options.filterQ=e,this.filterNode.Q.value=this.options.filterQ,console.debug(`[Reverb.js] Set filter Q to ${e}.`)}peaks(e){this.options.peaks=e,this.buildImpulse(),console.debug(`[Reverb.js] Set IR source noise peaks to ${e}.`)}scale(e){this.options.scale=e,this.buildImpulse(),console.debug(`[Reverb.js] Set IR source noise scale to ${e}.`)}randomAlgorithm(e){this.options.randomAlgorithm=e,this.buildImpulse(),console.debug(`[Reverb.js] Set IR source noise generator to ${e}.`)}setNoise(e){switch(this.options.noise=e,e){case a.BLUE:this.noise=R;break;case a.GREEN:this.noise=G;break;case a.PINK:this.noise=T;break;case a.RED:case a.BROWN:this.noise=v;break;case a.VIOLET:this.noise=$;break;default:this.noise=w;break}this.buildImpulse(),console.debug(`[Reverb.js] Set IR generator source noise type to ${e}.`)}setRandomAlgorythm(e){this.options.randomAlgorithm=e,this.buildImpulse()}inRange(e,s,o){return(e-s)*(e-o)<=0}buildImpulse(){const e=this.ctx.sampleRate,s=Math.max(e*this.options.time,1),o=e*this.options.delay,n=this.ctx.createBuffer(2,s,e),r=new Float32Array(s),i=new Float32Array(s),l=this.getNoise(s),M=this.getNoise(s);for(let c=0;c<s;c++){let f=0;c<o?(r[c]=0,i[c]=0,f=this.options.reverse?s-(c-o):c-o):f=this.options.reverse?s-c:c,r[c]=l[c]*(1-f/s)**this.options.decay,i[c]=M[c]*(1-f/s)**this.options.decay}n.getChannelData(0).set(r),n.getChannelData(1).set(i),this.convolverNode.buffer=n}getNoise(e){return[...E(e,this.options.noise===a.WHITE?this.noise(this.options.peaks,this.options.randomAlgorithm):this.noise(this.options.peaks,this.options.scale,this.options.randomAlgorithm))]}}return d.version=y.version,d.build=y.date,window.Reverb||(window.Reverb=d),d}();
12
+ var Reverb = (function (random, coloredNoise, transducers) {
13
+ 'use strict';
14
+
15
+ const Noise = {
16
+ BLUE: "blue",
17
+ GREEN: "green",
18
+ PINK: "pink",
19
+ RED: "red",
20
+ VIOLET: "violet",
21
+ WHITE: "white",
22
+ BROWN: "red"
23
+ };
24
+
25
+ const defaults = {
26
+ noise: Noise.WHITE,
27
+ scale: 1,
28
+ peaks: 2,
29
+ randomAlgorithm: random.SYSTEM,
30
+ decay: 2,
31
+ delay: 0,
32
+ reverse: false,
33
+ time: 2,
34
+ filterType: "allpass",
35
+ filterFreq: 2200,
36
+ filterQ: 1,
37
+ mix: 0.5,
38
+ once: false
39
+ };
40
+
41
+ const meta = {
42
+ version: "1.2.1",
43
+ date: "2022-11-24T14:46:07.438Z"
44
+ };
45
+
46
+ class Reverb {
47
+ static version = meta.version;
48
+ static build = meta.date;
49
+ ctx;
50
+ wetGainNode;
51
+ dryGainNode;
52
+ filterNode;
53
+ convolverNode;
54
+ outputNode;
55
+ options;
56
+ isConnected;
57
+ noise = coloredNoise.white;
58
+ constructor(ctx, options) {
59
+ this.ctx = ctx;
60
+ this.options = { ...defaults, ...options };
61
+ this.wetGainNode = this.ctx.createGain();
62
+ this.dryGainNode = this.ctx.createGain();
63
+ this.filterNode = this.ctx.createBiquadFilter();
64
+ this.convolverNode = this.ctx.createConvolver();
65
+ this.outputNode = this.ctx.createGain();
66
+ this.isConnected = false;
67
+ this.filterType(this.options.filterType);
68
+ this.setNoise(this.options.noise);
69
+ this.buildImpulse();
70
+ this.mix(this.options.mix);
71
+ }
72
+ connect(sourceNode) {
73
+ if (this.isConnected && this.options.once) {
74
+ this.isConnected = false;
75
+ return this.outputNode;
76
+ }
77
+ this.convolverNode.connect(this.filterNode);
78
+ this.filterNode.connect(this.wetGainNode);
79
+ sourceNode.connect(this.convolverNode);
80
+ sourceNode.connect(this.dryGainNode).connect(this.outputNode);
81
+ sourceNode.connect(this.wetGainNode).connect(this.outputNode);
82
+ this.isConnected = true;
83
+ return this.outputNode;
84
+ }
85
+ disconnect(sourceNode) {
86
+ if (this.isConnected) {
87
+ this.convolverNode.disconnect(this.filterNode);
88
+ this.filterNode.disconnect(this.wetGainNode);
89
+ }
90
+ this.isConnected = false;
91
+ return sourceNode;
92
+ }
93
+ mix(mix) {
94
+ if (!this.inRange(mix, 0, 1)) {
95
+ throw new RangeError("[Reverb.js] Dry/Wet ratio must be between 0 to 1.");
96
+ }
97
+ this.options.mix = mix;
98
+ this.dryGainNode.gain.value = 1 - this.options.mix;
99
+ this.wetGainNode.gain.value = this.options.mix;
100
+ }
101
+ time(value) {
102
+ if (!this.inRange(value, 1, 50)) {
103
+ throw new RangeError(
104
+ "[Reverb.js] Time length of inpulse response must be less than 50sec."
105
+ );
106
+ }
107
+ this.options.time = value;
108
+ this.buildImpulse();
109
+ }
110
+ decay(value) {
111
+ if (!this.inRange(value, 0, 100)) {
112
+ throw new RangeError(
113
+ "[Reverb.js] Inpulse Response decay level must be less than 100."
114
+ );
115
+ }
116
+ this.options.decay = value;
117
+ this.buildImpulse();
118
+ }
119
+ delay(value) {
120
+ if (!this.inRange(value, 0, 100)) {
121
+ throw new RangeError(
122
+ "[Reverb.js] Inpulse Response delay time must be less than 100."
123
+ );
124
+ }
125
+ this.options.delay = value;
126
+ this.buildImpulse();
127
+ }
128
+ reverse(reverse) {
129
+ this.options.reverse = reverse;
130
+ this.buildImpulse();
131
+ }
132
+ filterType(type = "allpass") {
133
+ this.filterNode.type = this.options.filterType = type;
134
+ }
135
+ filterFreq(freq) {
136
+ if (!this.inRange(freq, 20, 2e4)) {
137
+ throw new RangeError(
138
+ "[Reverb.js] Filter frequrncy must be between 20 and 20000."
139
+ );
140
+ }
141
+ this.options.filterFreq = freq;
142
+ this.filterNode.frequency.value = this.options.filterFreq;
143
+ }
144
+ filterQ(q) {
145
+ if (!this.inRange(q, 0, 10)) {
146
+ throw new RangeError(
147
+ "[Reverb.js] Filter quality value must be between 0 and 10."
148
+ );
149
+ }
150
+ this.options.filterQ = q;
151
+ this.filterNode.Q.value = this.options.filterQ;
152
+ }
153
+ peaks(p) {
154
+ this.options.peaks = p;
155
+ this.buildImpulse();
156
+ }
157
+ scale(s) {
158
+ this.options.scale = s;
159
+ this.buildImpulse();
160
+ }
161
+ randomAlgorithm(a) {
162
+ this.options.randomAlgorithm = a;
163
+ this.buildImpulse();
164
+ }
165
+ setNoise(type) {
166
+ this.options.noise = type;
167
+ switch (type) {
168
+ case Noise.BLUE:
169
+ this.noise = coloredNoise.blue;
170
+ break;
171
+ case Noise.GREEN:
172
+ this.noise = coloredNoise.green;
173
+ break;
174
+ case Noise.PINK:
175
+ this.noise = coloredNoise.pink;
176
+ break;
177
+ case Noise.RED:
178
+ case Noise.BROWN:
179
+ this.noise = coloredNoise.red;
180
+ break;
181
+ case Noise.VIOLET:
182
+ this.noise = coloredNoise.violet;
183
+ break;
184
+ default:
185
+ this.noise = coloredNoise.white;
186
+ }
187
+ this.buildImpulse();
188
+ }
189
+ setRandomAlgorythm(algorithm) {
190
+ this.options.randomAlgorithm = algorithm;
191
+ this.buildImpulse();
192
+ }
193
+ inRange(x, min, max) {
194
+ return (x - min) * (x - max) <= 0;
195
+ }
196
+ buildImpulse() {
197
+ const rate = this.ctx.sampleRate;
198
+ const duration = Math.max(rate * this.options.time, 1);
199
+ const delayDuration = rate * this.options.delay;
200
+ const impulse = this.ctx.createBuffer(2, duration, rate);
201
+ const impulseL = new Float32Array(duration);
202
+ const impulseR = new Float32Array(duration);
203
+ const noiseL = this.getNoise(duration);
204
+ const noiseR = this.getNoise(duration);
205
+ for (let i = 0; i < duration; i++) {
206
+ let n = 0;
207
+ if (i < delayDuration) {
208
+ impulseL[i] = 0;
209
+ impulseR[i] = 0;
210
+ n = this.options.reverse ? duration - (i - delayDuration) : i - delayDuration;
211
+ } else {
212
+ n = this.options.reverse ? duration - i : i;
213
+ }
214
+ impulseL[i] = noiseL[i] * (1 - n / duration) ** this.options.decay;
215
+ impulseR[i] = noiseR[i] * (1 - n / duration) ** this.options.decay;
216
+ }
217
+ impulse.getChannelData(0).set(impulseL);
218
+ impulse.getChannelData(1).set(impulseR);
219
+ this.convolverNode.buffer = impulse;
220
+ }
221
+ getNoise(duration) {
222
+ return [
223
+ ...transducers.take(
224
+ duration,
225
+ this.noise(
226
+ this.options.peaks,
227
+ this.options.scale,
228
+ this.options.randomAlgorithm
229
+ )
230
+ )
231
+ ];
232
+ }
233
+ }
234
+ if (!window.Reverb) {
235
+ window.Reverb = Reverb;
236
+ }
237
+
238
+ return Reverb;
239
+
240
+ })(random, colordNoise, transducers);
@@ -5,8 +5,239 @@
5
5
  * @author Logue <logue@hotmail.co.jp>
6
6
  * @copyright 2019-2022 By Masashi Yoshikawa All rights reserved.
7
7
  * @license MIT
8
- * @version 1.1.0
8
+ * @version 1.2.1
9
9
  * @see {@link https://github.com/logue/Reverb.js}
10
10
  */
11
11
 
12
- (function(l,h){typeof exports=="object"&&typeof module<"u"?module.exports=h():typeof define=="function"&&define.amd?define(h):(l=typeof globalThis<"u"?globalThis:l||self,l.Reverb=h())})(this,function(){"use strict";const l={BLUE:"blue",GREEN:"green",PINK:"pink",RED:"red",VIOLET:"violet",WHITE:"white",BROWN:"red"},h=1/2**32;class j{float(e=1){return this.int()*h*e}norm(e=1){return(this.int()*h-.5)*2*e}minmax(e,s){return this.float()*(s-e)+e}minmaxInt(e,s){return e|=0,s|=0,e+(this.float()*(s-e)|0)}}const m=Math.random;class S extends j{int(){return m()*4294967296>>>0}float(e=1){return m()*e}norm(e=1){return(m()-.5)*2*e}}const a=new S,k={noise:l.WHITE,scale:2,peaks:2,randomAlgorithm:a,decay:2,delay:0,reverse:!1,time:2,filterType:"lowpass",filterFreq:2200,filterQ:1,mix:.5,once:!1},y={version:"1.1.0",date:"2022-10-04T02:13:31.946Z"},b=(t,e,s)=>{const o=new Array(t);for(let n=0;n<t;n++)o[n]=s.norm(e);return o},R=t=>t.reduce((e,s)=>e+s,0);function*N(t,e){const s=[t[Symbol.iterator](),e[Symbol.iterator]()];for(let o=0;;o^=1){const n=s[o].next();if(n.done)return;yield n.value}}function*v(t=2,e=1,s=a){const o=b(t,e,s);o.forEach((i,u)=>o[u]=u&1?i:-i);const n=1/t;let r=R(o);for(let i=0,u=-1;;++i>=t&&(i=0))r-=o[i],r+=o[i]=u*s.norm(e),u^=4294967294,yield u*r*n}const T=(t=2,e=1,s=a)=>N(v(t,e,s),v(t,e,s)),G=t=>{let e=32;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};function*A(t=8,e=1,s=a){const o=b(t,e,s),n=1/t;let r=R(o);for(let i=0;;i=i+1>>>0){const u=G(i)%t;r-=o[u],r+=o[u]=s.norm(e),yield r*n}}function*g(t=2,e=1,s=a){const o=b(t,e,s),n=1/t;let r=R(o);for(let i=0;;++i>=t&&(i=0))r-=o[i],r+=o[i]=s.norm(e),yield r*n}const $=(t=2,e=1,s=a)=>N(g(t,e,s),g(t,e,s));function*w(t=1,e=a){for(;;)yield e.norm(t)}const x=(t,e)=>t!=null&&typeof t[e]=="function",F=t=>x(t,"xform")?t.xform():t,C=t=>t!=null&&typeof t[Symbol.iterator]=="function";class d{constructor(e){this.value=e}deref(){return this.value}}const B=t=>new d(t),D=t=>t instanceof d,L=t=>t instanceof d?t:new d(t),I=t=>t instanceof d?t.deref():t,Q=(t,e)=>[t,s=>s,e];function W(t){return t?[...t]:Q(()=>[],(e,s)=>(e.push(s),e))}function*q(t,e){const s=F(t)(W()),o=s[1],n=s[2];for(let r of e){const i=n([],r);if(D(i)){yield*I(o(i.deref()));return}i.length&&(yield*i)}yield*I(o([]))}const H=(t,e)=>[t[0],t[1],e];function E(t,e){return C(e)?q(E(t),e):s=>{const o=s[2];let n=t;return H(s,(r,i)=>--n>0?o(r,i):n===0?L(o(r,i)):B(r))}}class f{constructor(e,s){this.noise=w,this.ctx=e,this.options={...k,...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.setNoise(this.options.noise),this.buildImpulse(),this.mix(this.options.mix)}connect(e){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)}disconnect(e){return this.isConnected&&(this.convolverNode.disconnect(this.filterNode),this.filterNode.disconnect(this.wetGainNode)),this.isConnected=!1,e}mix(e){if(!this.inRange(e,0,1))throw new RangeError("[Reverb.js] Dry/Wet ratio must be between 0 to 1.");this.options.mix=e,this.dryGainNode.gain.value=1-this.options.mix,this.wetGainNode.gain.value=this.options.mix,console.debug(`[Reverb.js] Set dry/wet ratio to ${e*100}%`)}time(e){if(!this.inRange(e,1,50))throw new RangeError("[Reverb.js] Time length of inpulse response must be less than 50sec.");this.options.time=e,this.buildImpulse(),console.debug(`[Reverb.js] Set inpulse response time length to ${e}sec.`)}decay(e){if(!this.inRange(e,0,100))throw new RangeError("[Reverb.js] Inpulse Response decay level must be less than 100.");this.options.decay=e,this.buildImpulse(),console.debug(`[Reverb.js] Set inpulse response decay level to ${e}.`)}delay(e){if(!this.inRange(e,0,100))throw new RangeError("[Reverb.js] Inpulse Response delay time must be less than 100.");this.options.delay=e,this.buildImpulse(),console.debug(`[Reverb.js] Set inpulse response delay time to ${e}sec.`)}reverse(e){this.options.reverse=e,this.buildImpulse(),console.debug(`[Reverb.js] Inpulse response is ${e?"":"not "}reversed.`)}filterType(e){this.filterNode.type=this.options.filterType=e,console.debug(`[Reverb.js] Set filter type to ${e}`)}filterFreq(e){if(!this.inRange(e,20,2e4))throw new RangeError("[Reverb.js] Filter frequrncy must be between 20 and 20000.");this.options.filterFreq=e,this.filterNode.frequency.value=this.options.filterFreq,console.debug(`[Reverb.js] Set filter frequency to ${e}Hz.`)}filterQ(e){if(!this.inRange(e,0,10))throw new RangeError("[Reverb.js] Filter quality value must be between 0 and 10.");this.options.filterQ=e,this.filterNode.Q.value=this.options.filterQ,console.debug(`[Reverb.js] Set filter Q to ${e}.`)}peaks(e){this.options.peaks=e,this.buildImpulse(),console.debug(`[Reverb.js] Set IR source noise peaks to ${e}.`)}scale(e){this.options.scale=e,this.buildImpulse(),console.debug(`[Reverb.js] Set IR source noise scale to ${e}.`)}randomAlgorithm(e){this.options.randomAlgorithm=e,this.buildImpulse(),console.debug(`[Reverb.js] Set IR source noise generator to ${e}.`)}setNoise(e){switch(this.options.noise=e,e){case l.BLUE:this.noise=v;break;case l.GREEN:this.noise=T;break;case l.PINK:this.noise=A;break;case l.RED:case l.BROWN:this.noise=g;break;case l.VIOLET:this.noise=$;break;default:this.noise=w;break}this.buildImpulse(),console.debug(`[Reverb.js] Set IR generator source noise type to ${e}.`)}setRandomAlgorythm(e){this.options.randomAlgorithm=e,this.buildImpulse()}inRange(e,s,o){return(e-s)*(e-o)<=0}buildImpulse(){const e=this.ctx.sampleRate,s=Math.max(e*this.options.time,1),o=e*this.options.delay,n=this.ctx.createBuffer(2,s,e),r=new Float32Array(s),i=new Float32Array(s),u=this.getNoise(s),M=this.getNoise(s);for(let c=0;c<s;c++){let p=0;c<o?(r[c]=0,i[c]=0,p=this.options.reverse?s-(c-o):c-o):p=this.options.reverse?s-c:c,r[c]=u[c]*(1-p/s)**this.options.decay,i[c]=M[c]*(1-p/s)**this.options.decay}n.getChannelData(0).set(r),n.getChannelData(1).set(i),this.convolverNode.buffer=n}getNoise(e){return[...E(e,this.options.noise===l.WHITE?this.noise(this.options.peaks,this.options.randomAlgorithm):this.noise(this.options.peaks,this.options.scale,this.options.randomAlgorithm))]}}return f.version=y.version,f.build=y.date,window.Reverb||(window.Reverb=f),f});
12
+ (function (global, factory) {
13
+ typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('@thi.ng/random'), require('@thi.ng/colored-noise'), require('@thi.ng/transducers')) :
14
+ typeof define === 'function' && define.amd ? define(['@thi.ng/random', '@thi.ng/colored-noise', '@thi.ng/transducers'], factory) :
15
+ (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.Reverb = factory(global.random, global.colordNoise, global.transducers));
16
+ })(this, (function (random, coloredNoise, transducers) { 'use strict';
17
+
18
+ const Noise = {
19
+ BLUE: "blue",
20
+ GREEN: "green",
21
+ PINK: "pink",
22
+ RED: "red",
23
+ VIOLET: "violet",
24
+ WHITE: "white",
25
+ BROWN: "red"
26
+ };
27
+
28
+ const defaults = {
29
+ noise: Noise.WHITE,
30
+ scale: 1,
31
+ peaks: 2,
32
+ randomAlgorithm: random.SYSTEM,
33
+ decay: 2,
34
+ delay: 0,
35
+ reverse: false,
36
+ time: 2,
37
+ filterType: "allpass",
38
+ filterFreq: 2200,
39
+ filterQ: 1,
40
+ mix: 0.5,
41
+ once: false
42
+ };
43
+
44
+ const meta = {
45
+ version: "1.2.1",
46
+ date: "2022-11-24T14:46:07.438Z"
47
+ };
48
+
49
+ class Reverb {
50
+ static version = meta.version;
51
+ static build = meta.date;
52
+ ctx;
53
+ wetGainNode;
54
+ dryGainNode;
55
+ filterNode;
56
+ convolverNode;
57
+ outputNode;
58
+ options;
59
+ isConnected;
60
+ noise = coloredNoise.white;
61
+ constructor(ctx, options) {
62
+ this.ctx = ctx;
63
+ this.options = { ...defaults, ...options };
64
+ this.wetGainNode = this.ctx.createGain();
65
+ this.dryGainNode = this.ctx.createGain();
66
+ this.filterNode = this.ctx.createBiquadFilter();
67
+ this.convolverNode = this.ctx.createConvolver();
68
+ this.outputNode = this.ctx.createGain();
69
+ this.isConnected = false;
70
+ this.filterType(this.options.filterType);
71
+ this.setNoise(this.options.noise);
72
+ this.buildImpulse();
73
+ this.mix(this.options.mix);
74
+ }
75
+ connect(sourceNode) {
76
+ if (this.isConnected && this.options.once) {
77
+ this.isConnected = false;
78
+ return this.outputNode;
79
+ }
80
+ this.convolverNode.connect(this.filterNode);
81
+ this.filterNode.connect(this.wetGainNode);
82
+ sourceNode.connect(this.convolverNode);
83
+ sourceNode.connect(this.dryGainNode).connect(this.outputNode);
84
+ sourceNode.connect(this.wetGainNode).connect(this.outputNode);
85
+ this.isConnected = true;
86
+ return this.outputNode;
87
+ }
88
+ disconnect(sourceNode) {
89
+ if (this.isConnected) {
90
+ this.convolverNode.disconnect(this.filterNode);
91
+ this.filterNode.disconnect(this.wetGainNode);
92
+ }
93
+ this.isConnected = false;
94
+ return sourceNode;
95
+ }
96
+ mix(mix) {
97
+ if (!this.inRange(mix, 0, 1)) {
98
+ throw new RangeError("[Reverb.js] Dry/Wet ratio must be between 0 to 1.");
99
+ }
100
+ this.options.mix = mix;
101
+ this.dryGainNode.gain.value = 1 - this.options.mix;
102
+ this.wetGainNode.gain.value = this.options.mix;
103
+ }
104
+ time(value) {
105
+ if (!this.inRange(value, 1, 50)) {
106
+ throw new RangeError(
107
+ "[Reverb.js] Time length of inpulse response must be less than 50sec."
108
+ );
109
+ }
110
+ this.options.time = value;
111
+ this.buildImpulse();
112
+ }
113
+ decay(value) {
114
+ if (!this.inRange(value, 0, 100)) {
115
+ throw new RangeError(
116
+ "[Reverb.js] Inpulse Response decay level must be less than 100."
117
+ );
118
+ }
119
+ this.options.decay = value;
120
+ this.buildImpulse();
121
+ }
122
+ delay(value) {
123
+ if (!this.inRange(value, 0, 100)) {
124
+ throw new RangeError(
125
+ "[Reverb.js] Inpulse Response delay time must be less than 100."
126
+ );
127
+ }
128
+ this.options.delay = value;
129
+ this.buildImpulse();
130
+ }
131
+ reverse(reverse) {
132
+ this.options.reverse = reverse;
133
+ this.buildImpulse();
134
+ }
135
+ filterType(type = "allpass") {
136
+ this.filterNode.type = this.options.filterType = type;
137
+ }
138
+ filterFreq(freq) {
139
+ if (!this.inRange(freq, 20, 2e4)) {
140
+ throw new RangeError(
141
+ "[Reverb.js] Filter frequrncy must be between 20 and 20000."
142
+ );
143
+ }
144
+ this.options.filterFreq = freq;
145
+ this.filterNode.frequency.value = this.options.filterFreq;
146
+ }
147
+ filterQ(q) {
148
+ if (!this.inRange(q, 0, 10)) {
149
+ throw new RangeError(
150
+ "[Reverb.js] Filter quality value must be between 0 and 10."
151
+ );
152
+ }
153
+ this.options.filterQ = q;
154
+ this.filterNode.Q.value = this.options.filterQ;
155
+ }
156
+ peaks(p) {
157
+ this.options.peaks = p;
158
+ this.buildImpulse();
159
+ }
160
+ scale(s) {
161
+ this.options.scale = s;
162
+ this.buildImpulse();
163
+ }
164
+ randomAlgorithm(a) {
165
+ this.options.randomAlgorithm = a;
166
+ this.buildImpulse();
167
+ }
168
+ setNoise(type) {
169
+ this.options.noise = type;
170
+ switch (type) {
171
+ case Noise.BLUE:
172
+ this.noise = coloredNoise.blue;
173
+ break;
174
+ case Noise.GREEN:
175
+ this.noise = coloredNoise.green;
176
+ break;
177
+ case Noise.PINK:
178
+ this.noise = coloredNoise.pink;
179
+ break;
180
+ case Noise.RED:
181
+ case Noise.BROWN:
182
+ this.noise = coloredNoise.red;
183
+ break;
184
+ case Noise.VIOLET:
185
+ this.noise = coloredNoise.violet;
186
+ break;
187
+ default:
188
+ this.noise = coloredNoise.white;
189
+ }
190
+ this.buildImpulse();
191
+ }
192
+ setRandomAlgorythm(algorithm) {
193
+ this.options.randomAlgorithm = algorithm;
194
+ this.buildImpulse();
195
+ }
196
+ inRange(x, min, max) {
197
+ return (x - min) * (x - max) <= 0;
198
+ }
199
+ buildImpulse() {
200
+ const rate = this.ctx.sampleRate;
201
+ const duration = Math.max(rate * this.options.time, 1);
202
+ const delayDuration = rate * this.options.delay;
203
+ const impulse = this.ctx.createBuffer(2, duration, rate);
204
+ const impulseL = new Float32Array(duration);
205
+ const impulseR = new Float32Array(duration);
206
+ const noiseL = this.getNoise(duration);
207
+ const noiseR = this.getNoise(duration);
208
+ for (let i = 0; i < duration; i++) {
209
+ let n = 0;
210
+ if (i < delayDuration) {
211
+ impulseL[i] = 0;
212
+ impulseR[i] = 0;
213
+ n = this.options.reverse ? duration - (i - delayDuration) : i - delayDuration;
214
+ } else {
215
+ n = this.options.reverse ? duration - i : i;
216
+ }
217
+ impulseL[i] = noiseL[i] * (1 - n / duration) ** this.options.decay;
218
+ impulseR[i] = noiseR[i] * (1 - n / duration) ** this.options.decay;
219
+ }
220
+ impulse.getChannelData(0).set(impulseL);
221
+ impulse.getChannelData(1).set(impulseR);
222
+ this.convolverNode.buffer = impulse;
223
+ }
224
+ getNoise(duration) {
225
+ return [
226
+ ...transducers.take(
227
+ duration,
228
+ this.noise(
229
+ this.options.peaks,
230
+ this.options.scale,
231
+ this.options.randomAlgorithm
232
+ )
233
+ )
234
+ ];
235
+ }
236
+ }
237
+ if (!window.Reverb) {
238
+ window.Reverb = Reverb;
239
+ }
240
+
241
+ return Reverb;
242
+
243
+ }));
@@ -1 +1 @@
1
- {"version":3,"file":"OptionInterface.d.ts","sourceRoot":"","sources":["../../src/interfaces/OptionInterface.ts"],"names":[],"mappings":"AAAA,OAAc,EAAE,KAAK,SAAS,EAAE,MAAM,cAAc,CAAC;AAErD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AAG5C,oBAAoB;AACpB,MAAM,CAAC,OAAO,WAAW,eAAe;IACtC;;;OAGG;IACH,KAAK,EAAE,SAAS,CAAC;IACjB,4BAA4B;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,sCAAsC;IACtC,KAAK,EAAE,MAAM,CAAC;IACd;;;OAGG;IACH,eAAe,EAAE,KAAK,CAAC;IACvB,YAAY;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,gDAAgD;IAChD,KAAK,EAAE,MAAM,CAAC;IACd,uDAAuD;IACvD,UAAU,EAAE,MAAM,CAAC;IACnB,0CAA0C;IAC1C,OAAO,EAAE,MAAM,CAAC;IAChB,uCAAuC;IACvC,UAAU,EAAE,gBAAgB,CAAC;IAC7B,oBAAoB;IACpB,GAAG,EAAE,MAAM,CAAC;IACZ,kCAAkC;IAClC,OAAO,EAAE,OAAO,CAAC;IACjB,8BAA8B;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,wDAAwD;IACxD,IAAI,EAAE,OAAO,CAAC;CACf;AAED,aAAa;AACb,eAAO,MAAM,QAAQ,EAAE,eActB,CAAC"}
1
+ {"version":3,"file":"OptionInterface.d.ts","sourceRoot":"","sources":["../../src/interfaces/OptionInterface.ts"],"names":[],"mappings":"AAAA,OAAc,EAAE,KAAK,SAAS,EAAE,MAAM,cAAc,CAAC;AAGrD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AAE5C,oBAAoB;AACpB,MAAM,CAAC,OAAO,WAAW,eAAe;IACtC;;;OAGG;IACH,KAAK,EAAE,SAAS,CAAC;IACjB,4BAA4B;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,sCAAsC;IACtC,KAAK,EAAE,MAAM,CAAC;IACd;;;OAGG;IACH,eAAe,EAAE,KAAK,CAAC;IACvB,YAAY;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,gDAAgD;IAChD,KAAK,EAAE,MAAM,CAAC;IACd,uDAAuD;IACvD,UAAU,EAAE,MAAM,CAAC;IACnB,0CAA0C;IAC1C,OAAO,EAAE,MAAM,CAAC;IAChB,uCAAuC;IACvC,UAAU,EAAE,gBAAgB,CAAC;IAC7B,oBAAoB;IACpB,GAAG,EAAE,MAAM,CAAC;IACZ,kCAAkC;IAClC,OAAO,EAAE,OAAO,CAAC;IACjB,8BAA8B;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,wDAAwD;IACxD,IAAI,EAAE,OAAO,CAAC;CACf;AAED,aAAa;AACb,eAAO,MAAM,QAAQ,EAAE,eActB,CAAC"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://json.schemastore.org/package.json",
3
3
  "name": "@logue/reverb",
4
- "version": "1.1.0",
4
+ "version": "1.2.1",
5
5
  "description": "JavaScript Reverb effect class",
6
6
  "keywords": [
7
7
  "webaudio",
@@ -37,45 +37,48 @@
37
37
  }
38
38
  },
39
39
  "engines": {
40
- "node": ">=16.17.1",
41
- "yarn": ">=1.22.10"
40
+ "node": ">=18.12.1",
41
+ "yarn": ">=1.22.19"
42
42
  },
43
- "packageManager": "yarn@3.2.3",
43
+ "packageManager": "yarn@3.3.0",
44
44
  "sideEffects": false,
45
45
  "scripts": {
46
46
  "dev": "vite",
47
- "build": "vite build && tsc --declaration --emitDeclarationOnly",
48
- "build:analyze": "vite build --mode analyze && tsc --declaration --emitDeclarationOnly ",
47
+ "type-check": "tsc --composite false",
48
+ "build": "vite build && tsc --noEmit false --declaration --emitDeclarationOnly",
49
+ "build:analyze": "vite build --mode analyze",
49
50
  "build:clean": "rimraf dist",
50
51
  "lint": "eslint . --fix --cache --cache-location ./node_modules/.vite/vite-plugin-eslint && prettier . --write",
52
+ "preview": "vite serve docs",
51
53
  "prepare": "husky install"
52
54
  },
53
55
  "dependencies": {
54
- "@thi.ng/colored-noise": "^0.3.18",
55
- "@thi.ng/transducers": "^8.3.16"
56
+ "@thi.ng/colored-noise": "^1.0.0",
57
+ "@thi.ng/transducers": "^8.3.23"
56
58
  },
57
59
  "devDependencies": {
58
- "@types/node": "^18.8.1",
59
- "@typescript-eslint/eslint-plugin": "^5.39.0",
60
- "@typescript-eslint/parser": "^5.39.0",
61
- "eslint": "^8.24.0",
60
+ "@types/node": "^18.11.9",
61
+ "@typescript-eslint/eslint-plugin": "^5.44.0",
62
+ "@typescript-eslint/parser": "^5.44.0",
63
+ "eslint": "^8.28.0",
62
64
  "eslint-config-google": "^0.14.0",
63
65
  "eslint-config-prettier": "^8.5.0",
64
66
  "eslint-import-resolver-alias": "^1.1.2",
65
- "eslint-import-resolver-typescript": "^3.5.1",
67
+ "eslint-import-resolver-typescript": "^3.5.2",
66
68
  "eslint-plugin-import": "^2.26.0",
67
- "eslint-plugin-jsdoc": "^39.3.6",
69
+ "eslint-plugin-jsdoc": "^39.6.2",
68
70
  "eslint-plugin-prettier": "^4.2.1",
69
71
  "eslint-plugin-tsdoc": "^0.2.17",
70
- "husky": "^8.0.1",
72
+ "husky": "^8.0.2",
71
73
  "lint-staged": "^13.0.3",
72
- "prettier": "^2.7.1",
74
+ "prettier": "^2.8.0",
73
75
  "rimraf": "^3.0.2",
74
- "rollup-plugin-visualizer": "^5.8.2",
75
- "typescript": "^4.8.4",
76
- "vite": "^3.1.4",
77
- "vite-plugin-banner": "^0.5.0",
78
- "vite-plugin-checker": "^0.5.1"
76
+ "rollup-plugin-visualizer": "^5.8.3",
77
+ "typescript": "^4.9.3",
78
+ "vite": "^3.2.4",
79
+ "vite-plugin-banner": "^0.6.1",
80
+ "vite-plugin-checker": "^0.5.1",
81
+ "vite-plugin-dts": "^1.7.1"
79
82
  },
80
83
  "husky": {
81
84
  "hooks": {
@@ -87,6 +90,6 @@
87
90
  "*": "prettier -w -u"
88
91
  },
89
92
  "resolutions": {
90
- "prettier": "^2.7.1"
93
+ "prettier": "^2.8.0"
91
94
  }
92
95
  }