@mulsense/xnew 0.4.7 → 0.5.0

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
@@ -13,7 +13,7 @@ providing a flexible architecture well-suited for applications with dynamic scen
13
13
  ### Via CDN
14
14
  Include the following script in your HTML file:
15
15
  ```html
16
- <script src="https://unpkg.com/@mulsense/xnew@0.4.x/dist/xnew.js"></script>
16
+ <script src="https://unpkg.com/@mulsense/xnew@0.5.x/dist/xnew.js"></script>
17
17
  ```
18
18
 
19
19
  ### Via CDN (ESM)
@@ -22,7 +22,7 @@ Use the ES module version with an import map:
22
22
  <script type="importmap">
23
23
  {
24
24
  "imports": {
25
- "@mulsense/xnew": "https://unpkg.com/@mulsense/xnew@0.4.x/dist/xnew.mjs"
25
+ "@mulsense/xnew": "https://unpkg.com/@mulsense/xnew@0.5.x/dist/xnew.mjs"
26
26
  }
27
27
  }
28
28
  </script>
@@ -37,7 +37,7 @@ import xnew from '@mulsense/xnew';
37
37
  ### Via npm
38
38
  Install `xnew` using npm:
39
39
  ```bash
40
- npm install @mulsense/xnew@0.4.x
40
+ npm install @mulsense/xnew@0.5.x
41
41
  ```
42
42
 
43
43
  Then import it in your JavaScript file:
@@ -63,6 +63,9 @@
63
63
  unit.on('finalize', () => {
64
64
  parent.removeChild(object);
65
65
  });
66
+ return {
67
+ pixiObject: object,
68
+ };
66
69
  }
67
70
 
68
71
  return xpixi;
@@ -41,6 +41,9 @@ function Nest(unit, { object }) {
41
41
  unit.on('finalize', () => {
42
42
  parent.removeChild(object);
43
43
  });
44
+ return {
45
+ pixiObject: object,
46
+ };
44
47
  }
45
48
 
46
49
  export { xpixi as default };
@@ -65,6 +65,9 @@
65
65
  unit.on('finalize', () => {
66
66
  parent.remove(object);
67
67
  });
68
+ return {
69
+ threeObject: object,
70
+ };
68
71
  }
69
72
 
70
73
  return xthree;
@@ -43,6 +43,9 @@ function Nest(unit, { object }) {
43
43
  unit.on('finalize', () => {
44
44
  parent.remove(object);
45
45
  });
46
+ return {
47
+ threeObject: object,
48
+ };
46
49
  }
47
50
 
48
51
  export { xthree as default };
package/dist/xnew.js CHANGED
@@ -930,12 +930,6 @@
930
930
  else if (typeof args[0] === 'string' && args[0].match(/<((\w+)[^>]*?)\/?>/)) {
931
931
  target = args.shift();
932
932
  }
933
- else if (typeof args[0] === 'string') {
934
- const query = args.shift();
935
- target = document.querySelector(query);
936
- if (target === null)
937
- throw new Error(`'${query}' can not be found.`);
938
- }
939
933
  else {
940
934
  target = null;
941
935
  }
package/dist/xnew.mjs CHANGED
@@ -924,12 +924,6 @@ function parseArguments(...args) {
924
924
  else if (typeof args[0] === 'string' && args[0].match(/<((\w+)[^>]*?)\/?>/)) {
925
925
  target = args.shift();
926
926
  }
927
- else if (typeof args[0] === 'string') {
928
- const query = args.shift();
929
- target = document.querySelector(query);
930
- if (target === null)
931
- throw new Error(`'${query}' can not be found.`);
932
- }
933
927
  else {
934
928
  target = null;
935
929
  }
package/package.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "keywords": [
5
5
  "Component-Oriented Programming"
6
6
  ],
7
- "version": "0.4.7",
7
+ "version": "0.5.0",
8
8
  "main": "dist/xnew.js",
9
9
  "module": "dist/xnew.mjs",
10
10
  "types": "dist/xnew.d.ts",
@@ -1,53 +0,0 @@
1
- declare const _default: {
2
- load(path: string): {
3
- promise: Promise<any>;
4
- component: Function | null;
5
- then(callback: Function): /*elided*/ any;
6
- catch(callback: Function): /*elided*/ any;
7
- finally(callback: Function): /*elided*/ any;
8
- };
9
- synthesizer(props: SynthesizerOptions): Synthesizer;
10
- volume: number;
11
- };
12
-
13
- type SynthesizerOptions = {
14
- oscillator: OscillatorOptions;
15
- amp: AmpOptions;
16
- filter?: FilterOptions;
17
- reverb?: ReverbOptions;
18
- bpm?: number;
19
- };
20
- type OscillatorOptions = {
21
- type: OscillatorType;
22
- envelope?: Envelope;
23
- LFO?: LFO;
24
- };
25
- type FilterOptions = {
26
- type: BiquadFilterType;
27
- cutoff: number;
28
- };
29
- type AmpOptions = {
30
- envelope: Envelope;
31
- };
32
- type ReverbOptions = {
33
- time: number;
34
- mix: number;
35
- };
36
- type Envelope = {
37
- amount: number;
38
- ADSR: [number, number, number, number];
39
- };
40
- type LFO = {
41
- amount: number;
42
- type: OscillatorType;
43
- rate: number;
44
- };
45
- declare class Synthesizer {
46
- props: SynthesizerOptions;
47
- constructor(props: SynthesizerOptions);
48
- press(frequency: number | string, duration?: number | string, wait?: number): {
49
- release: () => void;
50
- } | undefined;
51
- }
52
-
53
- export { _default as default };
@@ -1,256 +0,0 @@
1
- (function (global, factory) {
2
- typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('@mulsense/xnew')) :
3
- typeof define === 'function' && define.amd ? define(['@mulsense/xnew'], factory) :
4
- (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.xaudio = factory(global.xnew));
5
- })(this, (function (xnew) { 'use strict';
6
-
7
- var xaudio = {
8
- load(path) {
9
- const music = new AudioFile(path);
10
- const object = {
11
- play(options) {
12
- const unit = xnew();
13
- if (music.played === null) {
14
- music.play(options);
15
- unit.on('finalize', () => music.pause({ fade: options.fade }));
16
- }
17
- },
18
- pause(options) {
19
- music.pause(options);
20
- }
21
- };
22
- return xnew.promise(music.promise).then(() => object);
23
- },
24
- synthesizer(props) {
25
- return new Synthesizer(props);
26
- },
27
- get volume() {
28
- return master.gain.value;
29
- },
30
- set volume(value) {
31
- master.gain.value = value;
32
- }
33
- };
34
- const context = window.AudioContext ? new window.AudioContext() : (null);
35
- const master = context ? context.createGain() : (null);
36
- if (context) {
37
- master.gain.value = 0.1;
38
- master.connect(context.destination);
39
- }
40
- class AudioFile {
41
- constructor(path) {
42
- this.promise = fetch(path)
43
- .then((response) => response.arrayBuffer())
44
- .then((response) => context.decodeAudioData(response))
45
- .then((response) => { this.buffer = response; })
46
- .catch(() => {
47
- console.warn(`"${path}" could not be loaded.`);
48
- });
49
- this.amp = context.createGain();
50
- this.amp.gain.value = 1.0;
51
- this.amp.connect(master);
52
- this.fade = context.createGain();
53
- this.fade.gain.value = 1.0;
54
- this.fade.connect(this.amp);
55
- this.source = null;
56
- this.played = null;
57
- }
58
- set volume(value) {
59
- this.amp.gain.value = value;
60
- }
61
- get volume() {
62
- return this.amp.gain.value;
63
- }
64
- play({ offset = 0, fade = 0, loop = false } = {}) {
65
- if (this.buffer !== undefined && this.played === null) {
66
- this.source = context.createBufferSource();
67
- this.source.buffer = this.buffer;
68
- this.source.loop = loop;
69
- this.source.connect(this.fade);
70
- this.played = context.currentTime;
71
- this.source.playbackRate.value = 1;
72
- this.source.start(context.currentTime, offset / 1000);
73
- // Apply fade-in effect if fade duration is specified
74
- if (fade > 0) {
75
- this.fade.gain.setValueAtTime(0, context.currentTime);
76
- this.fade.gain.linearRampToValueAtTime(1.0, context.currentTime + fade / 1000);
77
- }
78
- this.source.onended = () => {
79
- var _a;
80
- this.played = null;
81
- (_a = this.source) === null || _a === void 0 ? void 0 : _a.disconnect();
82
- this.source = null;
83
- };
84
- }
85
- }
86
- pause({ fade = 0 } = {}) {
87
- var _a, _b;
88
- if (this.buffer !== undefined && this.played !== null) {
89
- const elapsed = (context.currentTime - this.played) % this.buffer.duration * 1000;
90
- // Apply fade-out effect if fade duration is specified
91
- if (fade > 0) {
92
- this.fade.gain.setValueAtTime(1.0, context.currentTime);
93
- this.fade.gain.linearRampToValueAtTime(0, context.currentTime + fade / 1000);
94
- (_a = this.source) === null || _a === void 0 ? void 0 : _a.stop(context.currentTime + fade / 1000);
95
- }
96
- else {
97
- (_b = this.source) === null || _b === void 0 ? void 0 : _b.stop(context.currentTime);
98
- }
99
- this.played = null;
100
- return elapsed;
101
- }
102
- }
103
- clear() {
104
- var _a;
105
- this.amp.disconnect();
106
- this.fade.disconnect();
107
- (_a = this.source) === null || _a === void 0 ? void 0 : _a.disconnect();
108
- }
109
- }
110
- const keymap = {
111
- 'A0': 27.500, 'A#0': 29.135, 'B0': 30.868,
112
- 'C1': 32.703, 'C#1': 34.648, 'D1': 36.708, 'D#1': 38.891, 'E1': 41.203, 'F1': 43.654, 'F#1': 46.249, 'G1': 48.999, 'G#1': 51.913, 'A1': 55.000, 'A#1': 58.270, 'B1': 61.735,
113
- 'C2': 65.406, 'C#2': 69.296, 'D2': 73.416, 'D#2': 77.782, 'E2': 82.407, 'F2': 87.307, 'F#2': 92.499, 'G2': 97.999, 'G#2': 103.826, 'A2': 110.000, 'A#2': 116.541, 'B2': 123.471,
114
- 'C3': 130.813, 'C#3': 138.591, 'D3': 146.832, 'D#3': 155.563, 'E3': 164.814, 'F3': 174.614, 'F#3': 184.997, 'G3': 195.998, 'G#3': 207.652, 'A3': 220.000, 'A#3': 233.082, 'B3': 246.942,
115
- 'C4': 261.626, 'C#4': 277.183, 'D4': 293.665, 'D#4': 311.127, 'E4': 329.628, 'F4': 349.228, 'F#4': 369.994, 'G4': 391.995, 'G#4': 415.305, 'A4': 440.000, 'A#4': 466.164, 'B4': 493.883,
116
- 'C5': 523.251, 'C#5': 554.365, 'D5': 587.330, 'D#5': 622.254, 'E5': 659.255, 'F5': 698.456, 'F#5': 739.989, 'G5': 783.991, 'G#5': 830.609, 'A5': 880.000, 'A#5': 932.328, 'B5': 987.767,
117
- 'C6': 1046.502, 'C#6': 1108.731, 'D6': 1174.659, 'D#6': 1244.508, 'E6': 1318.510, 'F6': 1396.913, 'F#6': 1479.978, 'G6': 1567.982, 'G#6': 1661.219, 'A6': 1760.000, 'A#6': 1864.655, 'B6': 1975.533,
118
- 'C7': 2093.005, 'C#7': 2217.461, 'D7': 2349.318, 'D#7': 2489.016, 'E7': 2637.020, 'F7': 2793.826, 'F#7': 2959.955, 'G7': 3135.963, 'G#7': 3322.438, 'A7': 3520.000, 'A#7': 3729.310, 'B7': 3951.066,
119
- 'C8': 4186.009,
120
- };
121
- const notemap = {
122
- '1m': 4.000, '2n': 2.000, '4n': 1.000, '8n': 0.500, '16n': 0.250, '32n': 0.125,
123
- };
124
- class Synthesizer {
125
- constructor(props) { this.props = props; }
126
- press(frequency, duration, wait) {
127
- var _a;
128
- const props = this.props;
129
- const fv = typeof frequency === 'string' ? keymap[frequency] : frequency;
130
- const dv = typeof duration === 'string' ? (notemap[duration] * 60 / ((_a = props.bpm) !== null && _a !== void 0 ? _a : 120)) : (typeof duration === 'number' ? (duration / 1000) : 0);
131
- const start = context.currentTime + (wait !== null && wait !== void 0 ? wait : 0) / 1000;
132
- const nodes = {};
133
- nodes.oscillator = context.createOscillator();
134
- nodes.oscillator.type = props.oscillator.type;
135
- nodes.oscillator.frequency.value = fv;
136
- if (props.oscillator.LFO) {
137
- nodes.oscillatorLFO = context.createOscillator();
138
- nodes.oscillatorLFODepth = context.createGain();
139
- nodes.oscillatorLFODepth.gain.value = fv * (Math.pow(2.0, props.oscillator.LFO.amount / 12.0) - 1.0);
140
- nodes.oscillatorLFO.type = props.oscillator.LFO.type;
141
- nodes.oscillatorLFO.frequency.value = props.oscillator.LFO.rate;
142
- nodes.oscillatorLFO.start(start);
143
- nodes.oscillatorLFO.connect(nodes.oscillatorLFODepth);
144
- nodes.oscillatorLFODepth.connect(nodes.oscillator.frequency);
145
- }
146
- nodes.amp = context.createGain();
147
- nodes.amp.gain.value = 0.0;
148
- nodes.target = context.createGain();
149
- nodes.target.gain.value = 1.0;
150
- nodes.amp.connect(nodes.target);
151
- nodes.target.connect(master);
152
- if (props.filter) {
153
- nodes.filter = context.createBiquadFilter();
154
- nodes.filter.type = props.filter.type;
155
- nodes.filter.frequency.value = props.filter.cutoff;
156
- nodes.oscillator.connect(nodes.filter);
157
- nodes.filter.connect(nodes.amp);
158
- }
159
- else {
160
- nodes.oscillator.connect(nodes.amp);
161
- }
162
- if (props.reverb) {
163
- nodes.convolver = context.createConvolver();
164
- nodes.convolver.buffer = impulseResponse({ time: props.reverb.time });
165
- nodes.convolverDepth = context.createGain();
166
- nodes.convolverDepth.gain.value = 1.0;
167
- nodes.convolverDepth.gain.value *= props.reverb.mix;
168
- nodes.target.gain.value *= (1.0 - props.reverb.mix);
169
- nodes.amp.connect(nodes.convolver);
170
- nodes.convolver.connect(nodes.convolverDepth);
171
- nodes.convolverDepth.connect(master);
172
- }
173
- if (props.oscillator.envelope) {
174
- const amount = fv * (Math.pow(2.0, props.oscillator.envelope.amount / 12.0) - 1.0);
175
- startEnvelope(nodes.oscillator.frequency, fv, amount, props.oscillator.envelope.ADSR);
176
- }
177
- if (props.amp.envelope) {
178
- startEnvelope(nodes.amp.gain, 0.0, props.amp.envelope.amount, props.amp.envelope.ADSR);
179
- }
180
- nodes.oscillator.start(start);
181
- if (dv > 0) {
182
- release();
183
- }
184
- else {
185
- return { release };
186
- }
187
- function release() {
188
- let stop = null;
189
- const end = dv > 0 ? dv : (context.currentTime - start);
190
- if (props.amp.envelope) {
191
- const ADSR = props.amp.envelope.ADSR;
192
- const adsr = [ADSR[0] / 1000, ADSR[1] / 1000, ADSR[2], ADSR[3] / 1000];
193
- const rate = adsr[0] === 0.0 ? 1.0 : Math.min(end / (adsr[0] + 0.001), 1.0);
194
- stop = start + Math.max((adsr[0] + adsr[1]) * rate, end) + adsr[3];
195
- }
196
- else {
197
- stop = start + end;
198
- }
199
- if (nodes.oscillatorLFO) {
200
- nodes.oscillatorLFO.stop(stop);
201
- }
202
- if (props.oscillator.envelope) {
203
- const amount = fv * (Math.pow(2.0, props.oscillator.envelope.amount / 12.0) - 1.0);
204
- stopEnvelope(nodes.oscillator.frequency, fv, amount, props.oscillator.envelope.ADSR);
205
- }
206
- if (props.amp.envelope) {
207
- stopEnvelope(nodes.amp.gain, 0.0, props.amp.envelope.amount, props.amp.envelope.ADSR);
208
- }
209
- nodes.oscillator.stop(stop);
210
- setTimeout(() => {
211
- var _a, _b, _c, _d, _e;
212
- nodes.oscillator.disconnect();
213
- nodes.amp.disconnect();
214
- nodes.target.disconnect();
215
- (_a = nodes.oscillatorLFO) === null || _a === void 0 ? void 0 : _a.disconnect();
216
- (_b = nodes.oscillatorLFODepth) === null || _b === void 0 ? void 0 : _b.disconnect();
217
- (_c = nodes.filter) === null || _c === void 0 ? void 0 : _c.disconnect();
218
- (_d = nodes.convolver) === null || _d === void 0 ? void 0 : _d.disconnect();
219
- (_e = nodes.convolverDepth) === null || _e === void 0 ? void 0 : _e.disconnect();
220
- }, 2000);
221
- }
222
- function stopEnvelope(param, base, amount, ADSR) {
223
- const end = dv > 0 ? dv : (context.currentTime - start);
224
- const rate = ADSR[0] === 0.0 ? 1.0 : Math.min(end / (ADSR[0] / 1000), 1.0);
225
- if (rate < 1.0) {
226
- param.cancelScheduledValues(start);
227
- param.setValueAtTime(base, start);
228
- param.linearRampToValueAtTime(base + amount * rate, start + ADSR[0] / 1000 * rate);
229
- param.linearRampToValueAtTime(base + amount * rate * ADSR[2], start + (ADSR[0] + ADSR[1]) / 1000 * rate);
230
- }
231
- param.linearRampToValueAtTime(base + amount * rate * ADSR[2], start + Math.max((ADSR[0] + ADSR[1]) / 1000 * rate, dv));
232
- param.linearRampToValueAtTime(base, start + Math.max((ADSR[0] + ADSR[1]) / 1000 * rate, end) + ADSR[3] / 1000);
233
- }
234
- function startEnvelope(param, base, amount, ADSR) {
235
- param.value = base;
236
- param.setValueAtTime(base, start);
237
- param.linearRampToValueAtTime(base + amount, start + ADSR[0] / 1000);
238
- param.linearRampToValueAtTime(base + amount * ADSR[2], start + (ADSR[0] + ADSR[1]) / 1000);
239
- }
240
- function impulseResponse({ time, decay = 2.0 }) {
241
- const length = context.sampleRate * time / 1000;
242
- const impulse = context.createBuffer(2, length, context.sampleRate);
243
- const ch0 = impulse.getChannelData(0);
244
- const ch1 = impulse.getChannelData(1);
245
- for (let i = 0; i < length; i++) {
246
- ch0[i] = (2 * Math.random() - 1) * Math.pow(1 - i / length, decay);
247
- ch1[i] = (2 * Math.random() - 1) * Math.pow(1 - i / length, decay);
248
- }
249
- return impulse;
250
- }
251
- }
252
- }
253
-
254
- return xaudio;
255
-
256
- }));
@@ -1,250 +0,0 @@
1
- import xnew from '@mulsense/xnew';
2
-
3
- var xaudio = {
4
- load(path) {
5
- const music = new AudioFile(path);
6
- const object = {
7
- play(options) {
8
- const unit = xnew();
9
- if (music.played === null) {
10
- music.play(options);
11
- unit.on('finalize', () => music.pause({ fade: options.fade }));
12
- }
13
- },
14
- pause(options) {
15
- music.pause(options);
16
- }
17
- };
18
- return xnew.promise(music.promise).then(() => object);
19
- },
20
- synthesizer(props) {
21
- return new Synthesizer(props);
22
- },
23
- get volume() {
24
- return master.gain.value;
25
- },
26
- set volume(value) {
27
- master.gain.value = value;
28
- }
29
- };
30
- const context = window.AudioContext ? new window.AudioContext() : (null);
31
- const master = context ? context.createGain() : (null);
32
- if (context) {
33
- master.gain.value = 0.1;
34
- master.connect(context.destination);
35
- }
36
- class AudioFile {
37
- constructor(path) {
38
- this.promise = fetch(path)
39
- .then((response) => response.arrayBuffer())
40
- .then((response) => context.decodeAudioData(response))
41
- .then((response) => { this.buffer = response; })
42
- .catch(() => {
43
- console.warn(`"${path}" could not be loaded.`);
44
- });
45
- this.amp = context.createGain();
46
- this.amp.gain.value = 1.0;
47
- this.amp.connect(master);
48
- this.fade = context.createGain();
49
- this.fade.gain.value = 1.0;
50
- this.fade.connect(this.amp);
51
- this.source = null;
52
- this.played = null;
53
- }
54
- set volume(value) {
55
- this.amp.gain.value = value;
56
- }
57
- get volume() {
58
- return this.amp.gain.value;
59
- }
60
- play({ offset = 0, fade = 0, loop = false } = {}) {
61
- if (this.buffer !== undefined && this.played === null) {
62
- this.source = context.createBufferSource();
63
- this.source.buffer = this.buffer;
64
- this.source.loop = loop;
65
- this.source.connect(this.fade);
66
- this.played = context.currentTime;
67
- this.source.playbackRate.value = 1;
68
- this.source.start(context.currentTime, offset / 1000);
69
- // Apply fade-in effect if fade duration is specified
70
- if (fade > 0) {
71
- this.fade.gain.setValueAtTime(0, context.currentTime);
72
- this.fade.gain.linearRampToValueAtTime(1.0, context.currentTime + fade / 1000);
73
- }
74
- this.source.onended = () => {
75
- var _a;
76
- this.played = null;
77
- (_a = this.source) === null || _a === void 0 ? void 0 : _a.disconnect();
78
- this.source = null;
79
- };
80
- }
81
- }
82
- pause({ fade = 0 } = {}) {
83
- var _a, _b;
84
- if (this.buffer !== undefined && this.played !== null) {
85
- const elapsed = (context.currentTime - this.played) % this.buffer.duration * 1000;
86
- // Apply fade-out effect if fade duration is specified
87
- if (fade > 0) {
88
- this.fade.gain.setValueAtTime(1.0, context.currentTime);
89
- this.fade.gain.linearRampToValueAtTime(0, context.currentTime + fade / 1000);
90
- (_a = this.source) === null || _a === void 0 ? void 0 : _a.stop(context.currentTime + fade / 1000);
91
- }
92
- else {
93
- (_b = this.source) === null || _b === void 0 ? void 0 : _b.stop(context.currentTime);
94
- }
95
- this.played = null;
96
- return elapsed;
97
- }
98
- }
99
- clear() {
100
- var _a;
101
- this.amp.disconnect();
102
- this.fade.disconnect();
103
- (_a = this.source) === null || _a === void 0 ? void 0 : _a.disconnect();
104
- }
105
- }
106
- const keymap = {
107
- 'A0': 27.500, 'A#0': 29.135, 'B0': 30.868,
108
- 'C1': 32.703, 'C#1': 34.648, 'D1': 36.708, 'D#1': 38.891, 'E1': 41.203, 'F1': 43.654, 'F#1': 46.249, 'G1': 48.999, 'G#1': 51.913, 'A1': 55.000, 'A#1': 58.270, 'B1': 61.735,
109
- 'C2': 65.406, 'C#2': 69.296, 'D2': 73.416, 'D#2': 77.782, 'E2': 82.407, 'F2': 87.307, 'F#2': 92.499, 'G2': 97.999, 'G#2': 103.826, 'A2': 110.000, 'A#2': 116.541, 'B2': 123.471,
110
- 'C3': 130.813, 'C#3': 138.591, 'D3': 146.832, 'D#3': 155.563, 'E3': 164.814, 'F3': 174.614, 'F#3': 184.997, 'G3': 195.998, 'G#3': 207.652, 'A3': 220.000, 'A#3': 233.082, 'B3': 246.942,
111
- 'C4': 261.626, 'C#4': 277.183, 'D4': 293.665, 'D#4': 311.127, 'E4': 329.628, 'F4': 349.228, 'F#4': 369.994, 'G4': 391.995, 'G#4': 415.305, 'A4': 440.000, 'A#4': 466.164, 'B4': 493.883,
112
- 'C5': 523.251, 'C#5': 554.365, 'D5': 587.330, 'D#5': 622.254, 'E5': 659.255, 'F5': 698.456, 'F#5': 739.989, 'G5': 783.991, 'G#5': 830.609, 'A5': 880.000, 'A#5': 932.328, 'B5': 987.767,
113
- 'C6': 1046.502, 'C#6': 1108.731, 'D6': 1174.659, 'D#6': 1244.508, 'E6': 1318.510, 'F6': 1396.913, 'F#6': 1479.978, 'G6': 1567.982, 'G#6': 1661.219, 'A6': 1760.000, 'A#6': 1864.655, 'B6': 1975.533,
114
- 'C7': 2093.005, 'C#7': 2217.461, 'D7': 2349.318, 'D#7': 2489.016, 'E7': 2637.020, 'F7': 2793.826, 'F#7': 2959.955, 'G7': 3135.963, 'G#7': 3322.438, 'A7': 3520.000, 'A#7': 3729.310, 'B7': 3951.066,
115
- 'C8': 4186.009,
116
- };
117
- const notemap = {
118
- '1m': 4.000, '2n': 2.000, '4n': 1.000, '8n': 0.500, '16n': 0.250, '32n': 0.125,
119
- };
120
- class Synthesizer {
121
- constructor(props) { this.props = props; }
122
- press(frequency, duration, wait) {
123
- var _a;
124
- const props = this.props;
125
- const fv = typeof frequency === 'string' ? keymap[frequency] : frequency;
126
- const dv = typeof duration === 'string' ? (notemap[duration] * 60 / ((_a = props.bpm) !== null && _a !== void 0 ? _a : 120)) : (typeof duration === 'number' ? (duration / 1000) : 0);
127
- const start = context.currentTime + (wait !== null && wait !== void 0 ? wait : 0) / 1000;
128
- const nodes = {};
129
- nodes.oscillator = context.createOscillator();
130
- nodes.oscillator.type = props.oscillator.type;
131
- nodes.oscillator.frequency.value = fv;
132
- if (props.oscillator.LFO) {
133
- nodes.oscillatorLFO = context.createOscillator();
134
- nodes.oscillatorLFODepth = context.createGain();
135
- nodes.oscillatorLFODepth.gain.value = fv * (Math.pow(2.0, props.oscillator.LFO.amount / 12.0) - 1.0);
136
- nodes.oscillatorLFO.type = props.oscillator.LFO.type;
137
- nodes.oscillatorLFO.frequency.value = props.oscillator.LFO.rate;
138
- nodes.oscillatorLFO.start(start);
139
- nodes.oscillatorLFO.connect(nodes.oscillatorLFODepth);
140
- nodes.oscillatorLFODepth.connect(nodes.oscillator.frequency);
141
- }
142
- nodes.amp = context.createGain();
143
- nodes.amp.gain.value = 0.0;
144
- nodes.target = context.createGain();
145
- nodes.target.gain.value = 1.0;
146
- nodes.amp.connect(nodes.target);
147
- nodes.target.connect(master);
148
- if (props.filter) {
149
- nodes.filter = context.createBiquadFilter();
150
- nodes.filter.type = props.filter.type;
151
- nodes.filter.frequency.value = props.filter.cutoff;
152
- nodes.oscillator.connect(nodes.filter);
153
- nodes.filter.connect(nodes.amp);
154
- }
155
- else {
156
- nodes.oscillator.connect(nodes.amp);
157
- }
158
- if (props.reverb) {
159
- nodes.convolver = context.createConvolver();
160
- nodes.convolver.buffer = impulseResponse({ time: props.reverb.time });
161
- nodes.convolverDepth = context.createGain();
162
- nodes.convolverDepth.gain.value = 1.0;
163
- nodes.convolverDepth.gain.value *= props.reverb.mix;
164
- nodes.target.gain.value *= (1.0 - props.reverb.mix);
165
- nodes.amp.connect(nodes.convolver);
166
- nodes.convolver.connect(nodes.convolverDepth);
167
- nodes.convolverDepth.connect(master);
168
- }
169
- if (props.oscillator.envelope) {
170
- const amount = fv * (Math.pow(2.0, props.oscillator.envelope.amount / 12.0) - 1.0);
171
- startEnvelope(nodes.oscillator.frequency, fv, amount, props.oscillator.envelope.ADSR);
172
- }
173
- if (props.amp.envelope) {
174
- startEnvelope(nodes.amp.gain, 0.0, props.amp.envelope.amount, props.amp.envelope.ADSR);
175
- }
176
- nodes.oscillator.start(start);
177
- if (dv > 0) {
178
- release();
179
- }
180
- else {
181
- return { release };
182
- }
183
- function release() {
184
- let stop = null;
185
- const end = dv > 0 ? dv : (context.currentTime - start);
186
- if (props.amp.envelope) {
187
- const ADSR = props.amp.envelope.ADSR;
188
- const adsr = [ADSR[0] / 1000, ADSR[1] / 1000, ADSR[2], ADSR[3] / 1000];
189
- const rate = adsr[0] === 0.0 ? 1.0 : Math.min(end / (adsr[0] + 0.001), 1.0);
190
- stop = start + Math.max((adsr[0] + adsr[1]) * rate, end) + adsr[3];
191
- }
192
- else {
193
- stop = start + end;
194
- }
195
- if (nodes.oscillatorLFO) {
196
- nodes.oscillatorLFO.stop(stop);
197
- }
198
- if (props.oscillator.envelope) {
199
- const amount = fv * (Math.pow(2.0, props.oscillator.envelope.amount / 12.0) - 1.0);
200
- stopEnvelope(nodes.oscillator.frequency, fv, amount, props.oscillator.envelope.ADSR);
201
- }
202
- if (props.amp.envelope) {
203
- stopEnvelope(nodes.amp.gain, 0.0, props.amp.envelope.amount, props.amp.envelope.ADSR);
204
- }
205
- nodes.oscillator.stop(stop);
206
- setTimeout(() => {
207
- var _a, _b, _c, _d, _e;
208
- nodes.oscillator.disconnect();
209
- nodes.amp.disconnect();
210
- nodes.target.disconnect();
211
- (_a = nodes.oscillatorLFO) === null || _a === void 0 ? void 0 : _a.disconnect();
212
- (_b = nodes.oscillatorLFODepth) === null || _b === void 0 ? void 0 : _b.disconnect();
213
- (_c = nodes.filter) === null || _c === void 0 ? void 0 : _c.disconnect();
214
- (_d = nodes.convolver) === null || _d === void 0 ? void 0 : _d.disconnect();
215
- (_e = nodes.convolverDepth) === null || _e === void 0 ? void 0 : _e.disconnect();
216
- }, 2000);
217
- }
218
- function stopEnvelope(param, base, amount, ADSR) {
219
- const end = dv > 0 ? dv : (context.currentTime - start);
220
- const rate = ADSR[0] === 0.0 ? 1.0 : Math.min(end / (ADSR[0] / 1000), 1.0);
221
- if (rate < 1.0) {
222
- param.cancelScheduledValues(start);
223
- param.setValueAtTime(base, start);
224
- param.linearRampToValueAtTime(base + amount * rate, start + ADSR[0] / 1000 * rate);
225
- param.linearRampToValueAtTime(base + amount * rate * ADSR[2], start + (ADSR[0] + ADSR[1]) / 1000 * rate);
226
- }
227
- param.linearRampToValueAtTime(base + amount * rate * ADSR[2], start + Math.max((ADSR[0] + ADSR[1]) / 1000 * rate, dv));
228
- param.linearRampToValueAtTime(base, start + Math.max((ADSR[0] + ADSR[1]) / 1000 * rate, end) + ADSR[3] / 1000);
229
- }
230
- function startEnvelope(param, base, amount, ADSR) {
231
- param.value = base;
232
- param.setValueAtTime(base, start);
233
- param.linearRampToValueAtTime(base + amount, start + ADSR[0] / 1000);
234
- param.linearRampToValueAtTime(base + amount * ADSR[2], start + (ADSR[0] + ADSR[1]) / 1000);
235
- }
236
- function impulseResponse({ time, decay = 2.0 }) {
237
- const length = context.sampleRate * time / 1000;
238
- const impulse = context.createBuffer(2, length, context.sampleRate);
239
- const ch0 = impulse.getChannelData(0);
240
- const ch1 = impulse.getChannelData(1);
241
- for (let i = 0; i < length; i++) {
242
- ch0[i] = (2 * Math.random() - 1) * Math.pow(1 - i / length, decay);
243
- ch1[i] = (2 * Math.random() - 1) * Math.pow(1 - i / length, decay);
244
- }
245
- return impulse;
246
- }
247
- }
248
- }
249
-
250
- export { xaudio as default };