node-web-audio-api 0.18.0 → 0.20.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.
Files changed (51) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/TODOS.md +134 -12
  3. package/index.mjs +17 -6
  4. package/js/AnalyserNode.js +259 -48
  5. package/js/AudioBuffer.js +243 -0
  6. package/js/AudioBufferSourceNode.js +259 -41
  7. package/js/AudioContext.js +294 -28
  8. package/js/AudioDestinationNode.js +42 -100
  9. package/js/AudioListener.js +219 -0
  10. package/js/AudioNode.js +323 -0
  11. package/js/AudioParam.js +252 -39
  12. package/js/AudioScheduledSourceNode.js +120 -0
  13. package/js/BaseAudioContext.js +434 -0
  14. package/js/BiquadFilterNode.js +218 -29
  15. package/js/ChannelMergerNode.js +93 -22
  16. package/js/ChannelSplitterNode.js +93 -22
  17. package/js/ConstantSourceNode.js +86 -26
  18. package/js/ConvolverNode.js +158 -29
  19. package/js/DelayNode.js +112 -21
  20. package/js/DynamicsCompressorNode.js +195 -27
  21. package/js/Events.js +84 -0
  22. package/js/GainNode.js +104 -21
  23. package/js/IIRFilterNode.js +136 -23
  24. package/js/MediaStreamAudioSourceNode.js +80 -24
  25. package/js/OfflineAudioContext.js +198 -35
  26. package/js/OscillatorNode.js +189 -32
  27. package/js/PannerNode.js +458 -56
  28. package/js/PeriodicWave.js +67 -3
  29. package/js/ScriptProcessorNode.js +179 -0
  30. package/js/StereoPannerNode.js +104 -21
  31. package/js/WaveShaperNode.js +144 -29
  32. package/js/lib/cast.js +19 -0
  33. package/js/lib/errors.js +10 -55
  34. package/js/lib/events.js +10 -0
  35. package/js/lib/symbols.js +20 -0
  36. package/js/lib/utils.js +12 -12
  37. package/js/monkey-patch.js +40 -31
  38. package/node-web-audio-api.darwin-arm64.node +0 -0
  39. package/node-web-audio-api.darwin-x64.node +0 -0
  40. package/node-web-audio-api.linux-arm-gnueabihf.node +0 -0
  41. package/node-web-audio-api.linux-arm64-gnu.node +0 -0
  42. package/node-web-audio-api.linux-x64-gnu.node +0 -0
  43. package/node-web-audio-api.win32-arm64-msvc.node +0 -0
  44. package/node-web-audio-api.win32-x64-msvc.node +0 -0
  45. package/package.json +7 -4
  46. package/run-wpt.md +27 -0
  47. package/run-wpt.sh +5 -0
  48. package/js/AudioNode.mixin.js +0 -132
  49. package/js/AudioScheduledSourceNode.mixin.js +0 -67
  50. package/js/BaseAudioContext.mixin.js +0 -154
  51. package/js/EventTarget.mixin.js +0 -60
@@ -0,0 +1,434 @@
1
+ // -------------------------------------------------------------------------- //
2
+ // -------------------------------------------------------------------------- //
3
+ // //
4
+ // //
5
+ // //
6
+ // ██╗ ██╗ █████╗ ██████╗ ███╗ ██╗██╗███╗ ██╗ ██████╗ //
7
+ // ██║ ██║██╔══██╗██╔══██╗████╗ ██║██║████╗ ██║██╔════╝ //
8
+ // ██║ █╗ ██║███████║██████╔╝██╔██╗ ██║██║██╔██╗ ██║██║ ███╗ //
9
+ // ██║███╗██║██╔══██║██╔══██╗██║╚██╗██║██║██║╚██╗██║██║ ██║ //
10
+ // ╚███╔███╔╝██║ ██║██║ ██║██║ ╚████║██║██║ ╚████║╚██████╔╝ //
11
+ // ╚══╝╚══╝ ╚═╝ ╚═╝╚═╝ ╚═╝╚═╝ ╚═══╝╚═╝╚═╝ ╚═══╝ ╚═════╝ //
12
+ // //
13
+ // //
14
+ // - This file has been generated --------------------------- //
15
+ // //
16
+ // //
17
+ // -------------------------------------------------------------------------- //
18
+ // -------------------------------------------------------------------------- //
19
+
20
+ const {
21
+ isFunction,
22
+ kEnumerableProperty,
23
+ kHiddenProperty,
24
+ } = require('./lib/utils.js');
25
+ const {
26
+ kNapiObj,
27
+ } = require('./lib/symbols.js');
28
+
29
+ module.exports = (jsExport, _nativeBinding) => {
30
+ class BaseAudioContext extends EventTarget {
31
+ #listener = null;
32
+ #destination = null;
33
+
34
+ constructor(options) {
35
+ // Make constructor "private"
36
+ if (
37
+ (typeof options !== 'object') ||
38
+ !(kNapiObj in options)
39
+ ) {
40
+ throw new TypeError('Illegal constructor');
41
+ }
42
+
43
+ super();
44
+
45
+ Object.defineProperty(this, kNapiObj, {
46
+ value: options[kNapiObj],
47
+ ...kHiddenProperty,
48
+ });
49
+
50
+ this.#listener = null; // lazily instanciated
51
+ this.#destination = new jsExport.AudioDestinationNode(this, {
52
+ [kNapiObj]: this[kNapiObj].destination,
53
+ });
54
+ }
55
+
56
+ get listener() {
57
+ if (!(this instanceof BaseAudioContext)) {
58
+ throw new TypeError('Invalid Invocation: Value of \'this\' must be of type \'BaseAudioContext\'');
59
+ }
60
+
61
+ if (this.#listener === null) {
62
+ this.#listener = new jsExport.AudioListener({
63
+ [kNapiObj]: this[kNapiObj].listener,
64
+ });
65
+ }
66
+
67
+ return this.#listener;
68
+ }
69
+
70
+ get destination() {
71
+ if (!(this instanceof BaseAudioContext)) {
72
+ throw new TypeError('Invalid Invocation: Value of \'this\' must be of type \'BaseAudioContext\'');
73
+ }
74
+
75
+ return this.#destination;
76
+ }
77
+
78
+ get sampleRate() {
79
+ if (!(this instanceof BaseAudioContext)) {
80
+ throw new TypeError('Invalid Invocation: Value of \'this\' must be of type \'BaseAudioContext\'');
81
+ }
82
+
83
+ return this[kNapiObj].sampleRate;
84
+ }
85
+
86
+ get currentTime() {
87
+ if (!(this instanceof BaseAudioContext)) {
88
+ throw new TypeError('Invalid Invocation: Value of \'this\' must be of type \'BaseAudioContext\'');
89
+ }
90
+
91
+ return this[kNapiObj].currentTime;
92
+ }
93
+
94
+ get state() {
95
+ if (!(this instanceof BaseAudioContext)) {
96
+ throw new TypeError('Invalid Invocation: Value of \'this\' must be of type \'BaseAudioContext\'');
97
+ }
98
+
99
+ return this[kNapiObj].state;
100
+ }
101
+
102
+ // renderQuantumSize
103
+ // audioWorklet
104
+
105
+ get onstatechange() {
106
+ if (!(this instanceof BaseAudioContext)) {
107
+ throw new TypeError('Invalid Invocation: Value of \'this\' must be of type \'BaseAudioContext\'');
108
+ }
109
+
110
+ return this._statechange || null;
111
+ }
112
+
113
+ set onstatechange(value) {
114
+ if (!(this instanceof BaseAudioContext)) {
115
+ throw new TypeError('Invalid Invocation: Value of \'this\' must be of type \'BaseAudioContext\'');
116
+ }
117
+
118
+ if (isFunction(value) || value === null) {
119
+ this._statechange = value;
120
+ }
121
+ }
122
+
123
+ // This is not exactly what the spec says, but if we reject the promise
124
+ // when decodeErrorCallback is present the program will crash in an
125
+ // unexpected manner
126
+ // cf. https://webaudio.github.io/web-audio-api/#dom-baseaudiocontext-decodeaudiodata
127
+ async decodeAudioData(arrayBuffer, decodeSuccessCallback = undefined, decodeErrorCallback = undefined) {
128
+ if (!(this instanceof BaseAudioContext)) {
129
+ throw new TypeError('Invalid Invocation: Value of \'this\' must be of type \'BaseAudioContext\'');
130
+ }
131
+
132
+ if (arguments.length < 1) {
133
+ throw new TypeError(`Failed to execute 'decodeAudioData' on 'BaseAudioContext': 1 argument required, but only ${arguments.length} present`);
134
+ }
135
+
136
+ if (!(arrayBuffer instanceof ArrayBuffer)) {
137
+ throw new TypeError('Failed to execute "decodeAudioData": parameter 1 is not of type "ArrayBuffer"');
138
+ }
139
+
140
+ try {
141
+ const nativeAudioBuffer = await this[kNapiObj].decodeAudioData(arrayBuffer);
142
+ const audioBuffer = new jsExport.AudioBuffer({
143
+ [kNapiObj]: nativeAudioBuffer,
144
+ });
145
+
146
+ if (isFunction(decodeSuccessCallback)) {
147
+ decodeSuccessCallback(audioBuffer);
148
+ } else {
149
+ return audioBuffer;
150
+ }
151
+ } catch (err) {
152
+ const error = new DOMException(`Failed to execute 'decodeAudioData': ${err.message}`, 'EncodingError');
153
+
154
+ if (isFunction(decodeErrorCallback)) {
155
+ decodeErrorCallback(error);
156
+ } else {
157
+ throw error;
158
+ }
159
+ }
160
+ }
161
+
162
+ createBuffer(numberOfChannels, length, sampleRate) {
163
+ if (!(this instanceof BaseAudioContext)) {
164
+ throw new TypeError('Invalid Invocation: Value of \'this\' must be of type \'BaseAudioContext\'');
165
+ }
166
+
167
+ if (arguments.length < 3) {
168
+ throw new TypeError(`Failed to execute 'createBuffer' on 'BaseAudioContext': 3 argument required, but only ${arguments.length} present`);
169
+ }
170
+
171
+ const options = {};
172
+
173
+ if (numberOfChannels !== undefined) {
174
+ options.numberOfChannels = numberOfChannels;
175
+ }
176
+
177
+ if (length !== undefined) {
178
+ options.length = length;
179
+ }
180
+
181
+ if (sampleRate !== undefined) {
182
+ options.sampleRate = sampleRate;
183
+ }
184
+
185
+ return new jsExport.AudioBuffer(options);
186
+ }
187
+
188
+ createPeriodicWave(real, imag) {
189
+ if (!(this instanceof BaseAudioContext)) {
190
+ throw new TypeError('Invalid Invocation: Value of \'this\' must be of type \'BaseAudioContext\'');
191
+ }
192
+
193
+ if (arguments.length < 2) {
194
+ throw new TypeError(`Failed to execute 'createPeriodicWave' on 'BaseAudioContext': 2 argument required, but only ${arguments.length} present`);
195
+ }
196
+
197
+ const options = {};
198
+
199
+ if (real !== undefined) {
200
+ options.real = real;
201
+ }
202
+
203
+ if (imag !== undefined) {
204
+ options.imag = imag;
205
+ }
206
+
207
+ return new jsExport.PeriodicWave(this, options);
208
+ }
209
+
210
+ // --------------------------------------------------------------------
211
+ // Factory Methods (use the patched AudioNodes)
212
+ // --------------------------------------------------------------------
213
+ createScriptProcessor(bufferSize = 0, numberOfInputChannels = 2, numberOfOutputChannels = 2) {
214
+ if (!(this instanceof BaseAudioContext)) {
215
+ throw new TypeError('Invalid Invocation: Value of \'this\' must be of type \'BaseAudioContext\'');
216
+ }
217
+
218
+ const options = {
219
+ bufferSize,
220
+ numberOfInputChannels,
221
+ numberOfOutputChannels,
222
+ };
223
+
224
+ return new jsExport.ScriptProcessorNode(this, options);
225
+ }
226
+
227
+ createAnalyser() {
228
+ if (!(this instanceof BaseAudioContext)) {
229
+ throw new TypeError('Invalid Invocation: Value of \'this\' must be of type \'BaseAudioContext\'');
230
+ }
231
+
232
+ const options = {};
233
+
234
+ return new jsExport.AnalyserNode(this, options);
235
+ }
236
+
237
+ createBufferSource() {
238
+ if (!(this instanceof BaseAudioContext)) {
239
+ throw new TypeError('Invalid Invocation: Value of \'this\' must be of type \'BaseAudioContext\'');
240
+ }
241
+
242
+ const options = {};
243
+
244
+ return new jsExport.AudioBufferSourceNode(this, options);
245
+ }
246
+
247
+ createBiquadFilter() {
248
+ if (!(this instanceof BaseAudioContext)) {
249
+ throw new TypeError('Invalid Invocation: Value of \'this\' must be of type \'BaseAudioContext\'');
250
+ }
251
+
252
+ const options = {};
253
+
254
+ return new jsExport.BiquadFilterNode(this, options);
255
+ }
256
+
257
+ createChannelMerger(numberOfInputs = 6) {
258
+ if (!(this instanceof BaseAudioContext)) {
259
+ throw new TypeError('Invalid Invocation: Value of \'this\' must be of type \'BaseAudioContext\'');
260
+ }
261
+
262
+ const options = {
263
+ numberOfInputs,
264
+ };
265
+
266
+ return new jsExport.ChannelMergerNode(this, options);
267
+ }
268
+
269
+ createChannelSplitter(numberOfOutputs = 6) {
270
+ if (!(this instanceof BaseAudioContext)) {
271
+ throw new TypeError('Invalid Invocation: Value of \'this\' must be of type \'BaseAudioContext\'');
272
+ }
273
+
274
+ const options = {
275
+ numberOfOutputs,
276
+ };
277
+
278
+ return new jsExport.ChannelSplitterNode(this, options);
279
+ }
280
+
281
+ createConstantSource() {
282
+ if (!(this instanceof BaseAudioContext)) {
283
+ throw new TypeError('Invalid Invocation: Value of \'this\' must be of type \'BaseAudioContext\'');
284
+ }
285
+
286
+ const options = {};
287
+
288
+ return new jsExport.ConstantSourceNode(this, options);
289
+ }
290
+
291
+ createConvolver() {
292
+ if (!(this instanceof BaseAudioContext)) {
293
+ throw new TypeError('Invalid Invocation: Value of \'this\' must be of type \'BaseAudioContext\'');
294
+ }
295
+
296
+ const options = {};
297
+
298
+ return new jsExport.ConvolverNode(this, options);
299
+ }
300
+
301
+ createDelay(maxDelayTime = 1.0) {
302
+ if (!(this instanceof BaseAudioContext)) {
303
+ throw new TypeError('Invalid Invocation: Value of \'this\' must be of type \'BaseAudioContext\'');
304
+ }
305
+
306
+ const options = {
307
+ maxDelayTime,
308
+ };
309
+
310
+ return new jsExport.DelayNode(this, options);
311
+ }
312
+
313
+ createDynamicsCompressor() {
314
+ if (!(this instanceof BaseAudioContext)) {
315
+ throw new TypeError('Invalid Invocation: Value of \'this\' must be of type \'BaseAudioContext\'');
316
+ }
317
+
318
+ const options = {};
319
+
320
+ return new jsExport.DynamicsCompressorNode(this, options);
321
+ }
322
+
323
+ createGain() {
324
+ if (!(this instanceof BaseAudioContext)) {
325
+ throw new TypeError('Invalid Invocation: Value of \'this\' must be of type \'BaseAudioContext\'');
326
+ }
327
+
328
+ const options = {};
329
+
330
+ return new jsExport.GainNode(this, options);
331
+ }
332
+
333
+ createIIRFilter(feedforward, feedback) {
334
+ if (!(this instanceof BaseAudioContext)) {
335
+ throw new TypeError('Invalid Invocation: Value of \'this\' must be of type \'BaseAudioContext\'');
336
+ }
337
+
338
+ const options = {
339
+ feedforward,
340
+ feedback,
341
+ };
342
+
343
+ return new jsExport.IIRFilterNode(this, options);
344
+ }
345
+
346
+ createOscillator() {
347
+ if (!(this instanceof BaseAudioContext)) {
348
+ throw new TypeError('Invalid Invocation: Value of \'this\' must be of type \'BaseAudioContext\'');
349
+ }
350
+
351
+ const options = {};
352
+
353
+ return new jsExport.OscillatorNode(this, options);
354
+ }
355
+
356
+ createPanner() {
357
+ if (!(this instanceof BaseAudioContext)) {
358
+ throw new TypeError('Invalid Invocation: Value of \'this\' must be of type \'BaseAudioContext\'');
359
+ }
360
+
361
+ const options = {};
362
+
363
+ return new jsExport.PannerNode(this, options);
364
+ }
365
+
366
+ createStereoPanner() {
367
+ if (!(this instanceof BaseAudioContext)) {
368
+ throw new TypeError('Invalid Invocation: Value of \'this\' must be of type \'BaseAudioContext\'');
369
+ }
370
+
371
+ const options = {};
372
+
373
+ return new jsExport.StereoPannerNode(this, options);
374
+ }
375
+
376
+ createWaveShaper() {
377
+ if (!(this instanceof BaseAudioContext)) {
378
+ throw new TypeError('Invalid Invocation: Value of \'this\' must be of type \'BaseAudioContext\'');
379
+ }
380
+
381
+ const options = {};
382
+
383
+ return new jsExport.WaveShaperNode(this, options);
384
+ }
385
+
386
+ }
387
+
388
+ Object.defineProperties(BaseAudioContext, {
389
+ length: {
390
+ __proto__: null,
391
+ writable: false,
392
+ enumerable: false,
393
+ configurable: true,
394
+ value: 0,
395
+ },
396
+ });
397
+
398
+ Object.defineProperties(BaseAudioContext.prototype, {
399
+ [Symbol.toStringTag]: {
400
+ __proto__: null,
401
+ writable: false,
402
+ enumerable: false,
403
+ configurable: true,
404
+ value: 'BaseAudioContext',
405
+ },
406
+ createScriptProcessor: kEnumerableProperty,
407
+ createAnalyser: kEnumerableProperty,
408
+ createBufferSource: kEnumerableProperty,
409
+ createBiquadFilter: kEnumerableProperty,
410
+ createChannelMerger: kEnumerableProperty,
411
+ createChannelSplitter: kEnumerableProperty,
412
+ createConstantSource: kEnumerableProperty,
413
+ createConvolver: kEnumerableProperty,
414
+ createDelay: kEnumerableProperty,
415
+ createDynamicsCompressor: kEnumerableProperty,
416
+ createGain: kEnumerableProperty,
417
+ createIIRFilter: kEnumerableProperty,
418
+ createOscillator: kEnumerableProperty,
419
+ createPanner: kEnumerableProperty,
420
+ createStereoPanner: kEnumerableProperty,
421
+ createWaveShaper: kEnumerableProperty,
422
+ listener: kEnumerableProperty,
423
+ destination: kEnumerableProperty,
424
+ sampleRate: kEnumerableProperty,
425
+ currentTime: kEnumerableProperty,
426
+ state: kEnumerableProperty,
427
+ onstatechange: kEnumerableProperty,
428
+ decodeAudioData: kEnumerableProperty,
429
+ createBuffer: kEnumerableProperty,
430
+ createPeriodicWave: kEnumerableProperty,
431
+ });
432
+
433
+ return BaseAudioContext;
434
+ };