node-web-audio-api 0.15.0 → 0.17.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/CHANGELOG.md CHANGED
@@ -1,3 +1,14 @@
1
+ ## v0.17.0 (08/03/2024)
2
+
3
+ - Update upstream crate to [1.0.0-rc.2](https://github.com/orottier/web-audio-api-rs/blob/main/CHANGELOG.md#version-100-rc2-2024-03-07)
4
+ - Improve compliance and error handling
5
+
6
+ ## v0.16.0 (09/02/2024)
7
+
8
+ - Update upstream create to [v0.42.0](https://github.com/orottier/web-audio-api-rs/blob/main/CHANGELOG.md#version-0420-2024-02-05)
9
+ - Improve Error handling
10
+ - Add channelCounnt to media constraints
11
+
1
12
  ## v0.15.0 (16/01/2024)
2
13
 
3
14
  - Update upstream create to [v0.41.1](https://github.com/orottier/web-audio-api-rs/blob/main/CHANGELOG.md#version-0411-2024-01-11)
package/index.mjs CHANGED
@@ -27,6 +27,8 @@ const nativeModule = require('./index.cjs');
27
27
  export const {
28
28
  AudioContext,
29
29
  OfflineAudioContext,
30
+ AudioParam,
31
+ AudioDestinationNode,
30
32
  AudioBuffer,
31
33
  PeriodicWave,
32
34
  // manually written nodes
@@ -32,6 +32,10 @@ module.exports = (NativeAnalyserNode) => {
32
32
 
33
33
  class AnalyserNode extends AudioNode {
34
34
  constructor(context, options) {
35
+ if (options !== undefined && typeof options !== 'object') {
36
+ throw new TypeError("Failed to construct 'AnalyserNode': argument 2 is not of type 'AnalyserOptions'")
37
+ }
38
+
35
39
  super(context, options);
36
40
 
37
41
  }
@@ -33,6 +33,10 @@ module.exports = (NativeAudioBufferSourceNode) => {
33
33
 
34
34
  class AudioBufferSourceNode extends AudioScheduledSourceNode {
35
35
  constructor(context, options) {
36
+ if (options !== undefined && typeof options !== 'object') {
37
+ throw new TypeError("Failed to construct 'AudioBufferSourceNode': argument 2 is not of type 'AudioBufferSourceOptions'")
38
+ }
39
+
36
40
  super(context, options);
37
41
  // EventTargetMixin has been called so EventTargetMixin[kDispatchEvent] is
38
42
  // bound to this, then we can safely finalize event target initialization
@@ -0,0 +1,111 @@
1
+ // @note - This should be reviewed (but how...?)
2
+ //
3
+ // We can't really use the AudioNode mixin because we need to wrap
4
+ // the native destination instance.
5
+
6
+ const { throwSanitizedError } = require('./lib/errors.js');
7
+ const { AudioParam, kNativeAudioParam } = require('./AudioParam.js');
8
+ const kNativeAudioDestinationNode = Symbol('node-web-audio-api:audio-destination-node');
9
+
10
+ class AudioDestinationNode {
11
+ constructor(nativeAudioDestinationNode) {
12
+ this[kNativeAudioDestinationNode] = nativeAudioDestinationNode;
13
+ }
14
+
15
+ // AudioNode interface
16
+ get context() {
17
+ return this[kNativeAudioDestinationNode].context;
18
+ }
19
+
20
+ get numberOfInputs() {
21
+ return this[kNativeAudioDestinationNode].numberOfInputs;
22
+ }
23
+
24
+ get numberOfOutputs() {
25
+ return this[kNativeAudioDestinationNode].numberOfOutputs;
26
+ }
27
+
28
+ get channelCount() {
29
+ return this[kNativeAudioDestinationNode].channelCount;
30
+ }
31
+
32
+ get channelCountMode() {
33
+ return this[kNativeAudioDestinationNode].channelCountMode;
34
+ }
35
+
36
+ get channelInterpretation() {
37
+ return this[kNativeAudioDestinationNode].channelInterpretation;
38
+ }
39
+
40
+ // setters
41
+
42
+ set channelCount(value) {
43
+ try {
44
+ this[kNativeAudioDestinationNode].channelCount = value;
45
+ } catch (err) {
46
+ throwSanitizedError(err);
47
+ }
48
+ }
49
+
50
+ set channelCountMode(value) {
51
+ try {
52
+ this[kNativeAudioDestinationNode].channelCountMode = value;
53
+ } catch (err) {
54
+ throwSanitizedError(err);
55
+ }
56
+ }
57
+
58
+ set channelInterpretation(value) {
59
+ try {
60
+ this[kNativeAudioDestinationNode].channelInterpretation = value;
61
+ } catch (err) {
62
+ throwSanitizedError(err);
63
+ }
64
+ }
65
+
66
+ // methods - connect / disconnect
67
+
68
+ connect(...args) {
69
+ // unwrap raw audio params from facade
70
+ if (args[0] instanceof AudioParam) {
71
+ args[0] = args[0][kNativeAudioParam];
72
+ }
73
+
74
+ // unwrap raw audio destination from facade
75
+ if (args[0] instanceof AudioDestinationNode) {
76
+ args[0] = args[0][kNativeAudioDestinationNode];
77
+ }
78
+
79
+ try {
80
+ return this[kNativeAudioDestinationNode].connect(...args);
81
+ } catch (err) {
82
+ throwSanitizedError(err);
83
+ }
84
+ }
85
+
86
+ disconnect(...args) {
87
+ // unwrap raw audio params from facade
88
+ if (args[0] instanceof AudioParam) {
89
+ args[0] = args[0][kNativeAudioParam];
90
+ }
91
+
92
+ // unwrap raw audio destination from facade
93
+ if (args[0] instanceof AudioDestinationNode) {
94
+ args[0] = args[0][kNativeAudioDestinationNode];
95
+ }
96
+
97
+ try {
98
+ return this[kNativeAudioDestinationNode].disconnect(...args);
99
+ } catch (err) {
100
+ throwSanitizedError(err);
101
+ }
102
+ }
103
+
104
+ get maxChannelCount() {
105
+ return this[kNativeAudioDestinationNode].maxChannelCount;
106
+ }
107
+ }
108
+
109
+ module.exports.kNativeAudioDestinationNode = kNativeAudioDestinationNode;
110
+ module.exports.AudioDestinationNode = AudioDestinationNode;
111
+
@@ -20,6 +20,7 @@
20
20
  const { throwSanitizedError } = require('./lib/errors.js');
21
21
 
22
22
  const { AudioParam, kNativeAudioParam } = require('./AudioParam.js');
23
+ const { AudioDestinationNode, kNativeAudioDestinationNode } = require('./AudioDestinationNode.js');
23
24
 
24
25
  module.exports = (superclass) => {
25
26
  class AudioNode extends superclass {
@@ -93,6 +94,11 @@ module.exports = (superclass) => {
93
94
  args[0] = args[0][kNativeAudioParam];
94
95
  }
95
96
 
97
+ // unwrap raw audio destination from facade
98
+ if (args[0] instanceof AudioDestinationNode) {
99
+ args[0] = args[0][kNativeAudioDestinationNode];
100
+ }
101
+
96
102
  try {
97
103
  return super.connect(...args);
98
104
  } catch (err) {
@@ -106,6 +112,11 @@ module.exports = (superclass) => {
106
112
  args[0] = args[0][kNativeAudioParam];
107
113
  }
108
114
 
115
+ // unwrap raw audio destination from facade
116
+ if (args[0] instanceof AudioDestinationNode) {
117
+ args[0] = args[0][kNativeAudioDestinationNode];
118
+ }
119
+
109
120
  try {
110
121
  return super.disconnect(...args);
111
122
  } catch (err) {
@@ -17,6 +17,7 @@
17
17
  // -------------------------------------------------------------------------- //
18
18
  // -------------------------------------------------------------------------- //
19
19
 
20
+ const { AudioDestinationNode } = require('./AudioDestinationNode.js');
20
21
  const { isFunction } = require('./lib/utils.js');
21
22
 
22
23
  module.exports = (superclass, bindings) => {
@@ -36,9 +37,16 @@ module.exports = (superclass, bindings) => {
36
37
  PannerNode,
37
38
  StereoPannerNode,
38
39
  WaveShaperNode,
40
+ PeriodicWave,
39
41
  } = bindings;
40
42
 
41
43
  class BaseAudioContext extends superclass {
44
+ constructor(...args) {
45
+ super(...args);
46
+
47
+ this.destination = new AudioDestinationNode(this.destination);
48
+ }
49
+
42
50
  // This is not exactly what the spec says, but if we reject the promise
43
51
  // when decodeErrorCallback is present the program will crash in an
44
52
  // unexpected manner
@@ -65,6 +73,10 @@ module.exports = (superclass, bindings) => {
65
73
  }
66
74
  }
67
75
 
76
+ createPeriodicWave(real, imag) {
77
+ return new PeriodicWave(this, { real, imag });
78
+ }
79
+
68
80
  // --------------------------------------------------------------------
69
81
  // Factory Methods (use the patched AudioNodes)
70
82
  // --------------------------------------------------------------------
@@ -32,6 +32,10 @@ module.exports = (NativeBiquadFilterNode) => {
32
32
 
33
33
  class BiquadFilterNode extends AudioNode {
34
34
  constructor(context, options) {
35
+ if (options !== undefined && typeof options !== 'object') {
36
+ throw new TypeError("Failed to construct 'BiquadFilterNode': argument 2 is not of type 'BiquadFilterOptions'")
37
+ }
38
+
35
39
  super(context, options);
36
40
 
37
41
  this.frequency = new AudioParam(this.frequency);
@@ -32,6 +32,10 @@ module.exports = (NativeChannelMergerNode) => {
32
32
 
33
33
  class ChannelMergerNode extends AudioNode {
34
34
  constructor(context, options) {
35
+ if (options !== undefined && typeof options !== 'object') {
36
+ throw new TypeError("Failed to construct 'ChannelMergerNode': argument 2 is not of type 'ChannelMergerOptions'")
37
+ }
38
+
35
39
  super(context, options);
36
40
 
37
41
  }
@@ -32,6 +32,10 @@ module.exports = (NativeChannelSplitterNode) => {
32
32
 
33
33
  class ChannelSplitterNode extends AudioNode {
34
34
  constructor(context, options) {
35
+ if (options !== undefined && typeof options !== 'object') {
36
+ throw new TypeError("Failed to construct 'ChannelSplitterNode': argument 2 is not of type 'ChannelSplitterOptions'")
37
+ }
38
+
35
39
  super(context, options);
36
40
 
37
41
  }
@@ -33,6 +33,10 @@ module.exports = (NativeConstantSourceNode) => {
33
33
 
34
34
  class ConstantSourceNode extends AudioScheduledSourceNode {
35
35
  constructor(context, options) {
36
+ if (options !== undefined && typeof options !== 'object') {
37
+ throw new TypeError("Failed to construct 'ConstantSourceNode': argument 2 is not of type 'ConstantSourceOptions'")
38
+ }
39
+
36
40
  super(context, options);
37
41
  // EventTargetMixin has been called so EventTargetMixin[kDispatchEvent] is
38
42
  // bound to this, then we can safely finalize event target initialization
@@ -32,6 +32,10 @@ module.exports = (NativeConvolverNode) => {
32
32
 
33
33
  class ConvolverNode extends AudioNode {
34
34
  constructor(context, options) {
35
+ if (options !== undefined && typeof options !== 'object') {
36
+ throw new TypeError("Failed to construct 'ConvolverNode': argument 2 is not of type 'ConvolverOptions'")
37
+ }
38
+
35
39
  super(context, options);
36
40
 
37
41
  }
package/js/DelayNode.js CHANGED
@@ -32,6 +32,10 @@ module.exports = (NativeDelayNode) => {
32
32
 
33
33
  class DelayNode extends AudioNode {
34
34
  constructor(context, options) {
35
+ if (options !== undefined && typeof options !== 'object') {
36
+ throw new TypeError("Failed to construct 'DelayNode': argument 2 is not of type 'DelayOptions'")
37
+ }
38
+
35
39
  super(context, options);
36
40
 
37
41
  this.delayTime = new AudioParam(this.delayTime);
@@ -32,6 +32,10 @@ module.exports = (NativeDynamicsCompressorNode) => {
32
32
 
33
33
  class DynamicsCompressorNode extends AudioNode {
34
34
  constructor(context, options) {
35
+ if (options !== undefined && typeof options !== 'object') {
36
+ throw new TypeError("Failed to construct 'DynamicsCompressorNode': argument 2 is not of type 'DynamicsCompressorOptions'")
37
+ }
38
+
35
39
  super(context, options);
36
40
 
37
41
  this.threshold = new AudioParam(this.threshold);
@@ -54,6 +54,7 @@ module.exports = (superclass, eventTypes = []) => class EventTarget extends supe
54
54
  // event.target = this;
55
55
  // event.currentTarget = this;
56
56
  // event.srcElement = this;
57
+
57
58
  this.dispatchEvent(event);
58
59
  }
59
60
  };
package/js/GainNode.js CHANGED
@@ -32,6 +32,10 @@ module.exports = (NativeGainNode) => {
32
32
 
33
33
  class GainNode extends AudioNode {
34
34
  constructor(context, options) {
35
+ if (options !== undefined && typeof options !== 'object') {
36
+ throw new TypeError("Failed to construct 'GainNode': argument 2 is not of type 'GainOptions'")
37
+ }
38
+
35
39
  super(context, options);
36
40
 
37
41
  this.gain = new AudioParam(this.gain);
@@ -32,6 +32,10 @@ module.exports = (NativeIIRFilterNode) => {
32
32
 
33
33
  class IIRFilterNode extends AudioNode {
34
34
  constructor(context, options) {
35
+ if (options !== undefined && typeof options !== 'object') {
36
+ throw new TypeError("Failed to construct 'IIRFilterNode': argument 2 is not of type 'IIRFilterOptions'")
37
+ }
38
+
35
39
  super(context, options);
36
40
 
37
41
  }
@@ -1,4 +1,4 @@
1
- const { NotSupportedError } = require('./lib/errors.js');
1
+ const { nameCodeMap, DOMException } = require('./lib/errors.js');
2
2
  const { isPlainObject, isPositiveInt, isPositiveNumber } = require('./lib/utils.js');
3
3
 
4
4
  module.exports = function patchOfflineAudioContext(bindings) {
@@ -23,21 +23,31 @@ module.exports = function patchOfflineAudioContext(bindings) {
23
23
  const [numberOfChannels, length, sampleRate] = args;
24
24
 
25
25
  if (!isPositiveInt(numberOfChannels)) {
26
- throw new NotSupportedError(`Invalid value for numberOfChannels: ${numberOfChannels}`);
26
+ throw new TypeError(`Invalid value for numberOfChannels: ${numberOfChannels}`);
27
27
  } else if (!isPositiveInt(length)) {
28
- throw new NotSupportedError(`Invalid value for length: ${length}`);
28
+ throw new TypeError(`Invalid value for length: ${length}`);
29
29
  } else if (!isPositiveNumber(sampleRate)) {
30
- throw new NotSupportedError(`Invalid value for sampleRate: ${sampleRate}`);
30
+ throw new TypeError(`Invalid value for sampleRate: ${sampleRate}`);
31
31
  }
32
32
 
33
33
  super(numberOfChannels, length, sampleRate);
34
34
 
35
- // @todo - do not init the event target, no way to clean the thread safe
36
- // functions for now
37
-
38
35
  // EventTargetMixin has been called so EventTargetMixin[kDispatchEvent] is
39
36
  // bound to this, then we can safely finalize event target initialization
40
- // super.__initEventTarget__();
37
+ super.__initEventTarget__();
38
+ }
39
+
40
+ async startRendering() {
41
+ const renderedBuffer = await super.startRendering();
42
+
43
+ // We do this here, so that we can just share the same audioBuffer instance.
44
+ // This also simplifies code on the rust side as we don't need to deal
45
+ // with the OfflineAudioCompletionEvent.
46
+ const event = new Event('complete');
47
+ event.renderedBuffer = renderedBuffer;
48
+ this.dispatchEvent(event)
49
+
50
+ return renderedBuffer;
41
51
  }
42
52
  }
43
53
 
@@ -33,6 +33,10 @@ module.exports = (NativeOscillatorNode) => {
33
33
 
34
34
  class OscillatorNode extends AudioScheduledSourceNode {
35
35
  constructor(context, options) {
36
+ if (options !== undefined && typeof options !== 'object') {
37
+ throw new TypeError("Failed to construct 'OscillatorNode': argument 2 is not of type 'OscillatorOptions'")
38
+ }
39
+
36
40
  super(context, options);
37
41
  // EventTargetMixin has been called so EventTargetMixin[kDispatchEvent] is
38
42
  // bound to this, then we can safely finalize event target initialization
package/js/PannerNode.js CHANGED
@@ -32,6 +32,10 @@ module.exports = (NativePannerNode) => {
32
32
 
33
33
  class PannerNode extends AudioNode {
34
34
  constructor(context, options) {
35
+ if (options !== undefined && typeof options !== 'object') {
36
+ throw new TypeError("Failed to construct 'PannerNode': argument 2 is not of type 'PannerOptions'")
37
+ }
38
+
35
39
  super(context, options);
36
40
 
37
41
  this.positionX = new AudioParam(this.positionX);
@@ -0,0 +1,16 @@
1
+ const { throwSanitizedError } = require('./lib/errors.js');
2
+
3
+ module.exports = (NativePeriodicWave) => {
4
+ class PeriodicWave extends NativePeriodicWave {
5
+ constructor(context, options) {
6
+ try {
7
+ super(context, options);
8
+ } catch (err) {
9
+ throwSanitizedError(err);
10
+ }
11
+ }
12
+ }
13
+
14
+ return PeriodicWave;
15
+ };
16
+
@@ -32,6 +32,10 @@ module.exports = (NativeStereoPannerNode) => {
32
32
 
33
33
  class StereoPannerNode extends AudioNode {
34
34
  constructor(context, options) {
35
+ if (options !== undefined && typeof options !== 'object') {
36
+ throw new TypeError("Failed to construct 'StereoPannerNode': argument 2 is not of type 'StereoPannerOptions'")
37
+ }
38
+
35
39
  super(context, options);
36
40
 
37
41
  this.pan = new AudioParam(this.pan);
@@ -32,6 +32,10 @@ module.exports = (NativeWaveShaperNode) => {
32
32
 
33
33
  class WaveShaperNode extends AudioNode {
34
34
  constructor(context, options) {
35
+ if (options !== undefined && typeof options !== 'object') {
36
+ throw new TypeError("Failed to construct 'WaveShaperNode': argument 2 is not of type 'WaveShaperOptions'")
37
+ }
38
+
35
39
  super(context, options);
36
40
 
37
41
  }
package/js/lib/errors.js CHANGED
@@ -4,37 +4,57 @@ const path = require('path');
4
4
  const internalPath = path.join('node-web-audio-api', 'js');
5
5
  const internalRe = new RegExp(internalPath);
6
6
 
7
- class NotSupportedError extends Error {
8
- constructor(message) {
7
+ // from wpt/resources/tesharness.js (line 2226)
8
+ const nameCodeMap = {
9
+ IndexSizeError: 1,
10
+ HierarchyRequestError: 3,
11
+ WrongDocumentError: 4,
12
+ InvalidCharacterError: 5,
13
+ NoModificationAllowedError: 7,
14
+ NotFoundError: 8,
15
+ NotSupportedError: 9,
16
+ InUseAttributeError: 10,
17
+ InvalidStateError: 11,
18
+ SyntaxError: 12,
19
+ InvalidModificationError: 13,
20
+ NamespaceError: 14,
21
+ InvalidAccessError: 15,
22
+ TypeMismatchError: 17,
23
+ SecurityError: 18,
24
+ NetworkError: 19,
25
+ AbortError: 20,
26
+ URLMismatchError: 21,
27
+ QuotaExceededError: 22,
28
+ TimeoutError: 23,
29
+ InvalidNodeTypeError: 24,
30
+ DataCloneError: 25,
31
+
32
+ EncodingError: 0,
33
+ NotReadableError: 0,
34
+ UnknownError: 0,
35
+ ConstraintError: 0,
36
+ DataError: 0,
37
+ TransactionInactiveError: 0,
38
+ ReadOnlyError: 0,
39
+ VersionError: 0,
40
+ OperationError: 0,
41
+ NotAllowedError: 0,
42
+ OptOutError: 0
43
+ };
44
+
45
+ exports.nameCodeMap = nameCodeMap;
46
+
47
+
48
+ class DOMException extends Error {
49
+ constructor(message, name) {
9
50
  super(message);
10
- this.name = 'NotSupportedError';
11
- }
12
- }
13
-
14
- class InvalidStateError extends Error {
15
- constructor(message) {
16
- super(message);
17
- this.name = 'InvalidStateError';
18
- }
19
- }
20
51
 
21
- class IndexSizeError extends Error {
22
- constructor(message) {
23
- super(message);
24
- this.name = 'IndexSizeError';
25
- }
26
- }
27
-
28
- class InvalidAccessError extends Error {
29
- constructor(message) {
30
- super(message);
31
- this.name = 'InvalidAccessError';
52
+ this.name = name;
53
+ this.code = nameCodeMap[this.name];
32
54
  }
33
55
  }
34
56
 
35
- exports.NotSupportedError = NotSupportedError;
36
- exports.InvalidStateError = InvalidStateError;
37
- exports.IndexSizeError = IndexSizeError;
57
+ exports.DOMException = DOMException;
38
58
 
39
59
  function overrideStack(originalError, newError) {
40
60
  // override previous error message
@@ -60,6 +80,7 @@ exports.throwSanitizedError = function throwSanitizedError(err) {
60
80
  // right: Max
61
81
  let originalMessage = err.message;
62
82
  originalMessage = originalMessage.replace('assertion `left != right` failed: ', '');
83
+ originalMessage = originalMessage.replace('assertion `left == right` failed: ', '');
63
84
  originalMessage = originalMessage.split(EOL)[0]; // keep only first line
64
85
 
65
86
  // "Native Errors"
@@ -76,33 +97,33 @@ exports.throwSanitizedError = function throwSanitizedError(err) {
76
97
  throw error;
77
98
  }
78
99
 
79
- // "other errors"
100
+ // DOM Exceptions
80
101
  if (originalMessage.startsWith('NotSupportedError')) {
81
102
  const msg = originalMessage.replace(/^NotSupportedError - /, '');
82
- const error = new NotSupportedError(msg);
103
+ const error = new DOMException(msg, 'NotSupportedError');
83
104
  overrideStack(err, error);
84
105
 
85
106
  throw error;
86
107
  } else if (originalMessage.startsWith('InvalidStateError')) {
87
108
  const msg = originalMessage.replace(/^InvalidStateError - /, '');
88
- const error = new InvalidStateError(msg);
109
+ const error = new DOMException(msg, 'InvalidStateError');
89
110
  overrideStack(err, error);
90
111
 
91
112
  throw error;
92
113
  } if (originalMessage.startsWith('IndexSizeError')) {
93
114
  const msg = originalMessage.replace(/^IndexSizeError - /, '');
94
- const error = new IndexSizeError(msg);
115
+ const error = new DOMException(msg, 'IndexSizeError');
95
116
  overrideStack(err, error);
96
117
 
97
118
  throw error;
98
119
  } if (originalMessage.startsWith('InvalidAccessError')) {
99
120
  const msg = originalMessage.replace(/^InvalidAccessError - /, '');
100
- const error = new InvalidAccessError(msg);
121
+ const error = new DOMException(msg, 'InvalidAccessError');
101
122
  overrideStack(err, error);
102
123
 
103
124
  throw error;
104
125
  }
105
126
 
106
- console.warn('[lib/errors.js] Unhandled error type', err.name, err.message);
127
+ console.warn('[lib/errors.js] Possibly unhandled error type', err.message);
107
128
  throw err;
108
129
  }
@@ -38,9 +38,16 @@ module.exports = function monkeyPatch(nativeBinding) {
38
38
  nativeBinding.StereoPannerNode = require('./StereoPannerNode.js')(nativeBinding.StereoPannerNode);
39
39
  nativeBinding.WaveShaperNode = require('./WaveShaperNode.js')(nativeBinding.WaveShaperNode);
40
40
 
41
+ // @todo - wrap AudioBuffer interface as well
42
+ nativeBinding.PeriodicWave = require('./PeriodicWave.js')(nativeBinding.PeriodicWave);
43
+
41
44
  nativeBinding.AudioContext = require('./AudioContext.js')(nativeBinding);
42
45
  nativeBinding.OfflineAudioContext = require('./OfflineAudioContext.js')(nativeBinding);
43
46
 
47
+ // find a way to make the constructor private
48
+ nativeBinding.AudioParam = require('./AudioParam.js').AudioParam;
49
+ nativeBinding.AudioDestinationNode = require('./AudioDestinationNode.js').AudioDestinationNode;
50
+
44
51
  // --------------------------------------------------------------------------
45
52
  // Promisify MediaDevices API
46
53
  // --------------------------------------------------------------------------
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "node-web-audio-api",
3
- "version": "0.15.0",
3
+ "version": "0.17.0",
4
4
  "author": "Benjamin Matuszewski",
5
5
  "description": "Node.js bindings for web-audio-api-rs using napi-rs",
6
6
  "exports": {