node-web-audio-api 0.18.0 → 0.19.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 (49) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/TODOS.md +140 -12
  3. package/index.mjs +10 -5
  4. package/js/AnalyserNode.js +262 -48
  5. package/js/AudioBuffer.js +244 -0
  6. package/js/AudioBufferSourceNode.js +265 -41
  7. package/js/AudioContext.js +271 -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 +105 -0
  13. package/js/BaseAudioContext.js +419 -0
  14. package/js/BiquadFilterNode.js +221 -29
  15. package/js/ChannelMergerNode.js +96 -22
  16. package/js/ChannelSplitterNode.js +96 -22
  17. package/js/ConstantSourceNode.js +92 -26
  18. package/js/ConvolverNode.js +161 -29
  19. package/js/DelayNode.js +115 -21
  20. package/js/DynamicsCompressorNode.js +198 -27
  21. package/js/GainNode.js +107 -21
  22. package/js/IIRFilterNode.js +139 -23
  23. package/js/MediaStreamAudioSourceNode.js +83 -24
  24. package/js/OfflineAudioContext.js +182 -34
  25. package/js/OscillatorNode.js +195 -32
  26. package/js/PannerNode.js +461 -56
  27. package/js/PeriodicWave.js +67 -3
  28. package/js/StereoPannerNode.js +107 -21
  29. package/js/WaveShaperNode.js +147 -29
  30. package/js/lib/cast.js +19 -0
  31. package/js/lib/errors.js +10 -55
  32. package/js/lib/events.js +20 -0
  33. package/js/lib/symbols.js +5 -0
  34. package/js/lib/utils.js +12 -12
  35. package/js/monkey-patch.js +32 -30
  36. package/node-web-audio-api.darwin-arm64.node +0 -0
  37. package/node-web-audio-api.darwin-x64.node +0 -0
  38. package/node-web-audio-api.linux-arm-gnueabihf.node +0 -0
  39. package/node-web-audio-api.linux-arm64-gnu.node +0 -0
  40. package/node-web-audio-api.linux-x64-gnu.node +0 -0
  41. package/node-web-audio-api.win32-arm64-msvc.node +0 -0
  42. package/node-web-audio-api.win32-x64-msvc.node +0 -0
  43. package/package.json +7 -4
  44. package/run-wpt.md +27 -0
  45. package/run-wpt.sh +5 -0
  46. package/js/AudioNode.mixin.js +0 -132
  47. package/js/AudioScheduledSourceNode.mixin.js +0 -67
  48. package/js/BaseAudioContext.mixin.js +0 -154
  49. package/js/EventTarget.mixin.js +0 -60
@@ -17,39 +17,113 @@
17
17
  // -------------------------------------------------------------------------- //
18
18
  // -------------------------------------------------------------------------- //
19
19
 
20
- // eslint-disable-next-line no-unused-vars
21
- const { throwSanitizedError } = require('./lib/errors.js');
22
- // eslint-disable-next-line no-unused-vars
23
- const { AudioParam } = require('./AudioParam.js');
24
- const EventTargetMixin = require('./EventTarget.mixin.js');
25
- const AudioNodeMixin = require('./AudioNode.mixin.js');
20
+ /* eslint-disable no-unused-vars */
21
+ const conversions = require('webidl-conversions');
22
+ const {
23
+ toSanitizedSequence,
24
+ } = require('./lib/cast.js');
25
+ const {
26
+ isFunction,
27
+ kEnumerableProperty,
28
+ } = require('./lib/utils.js');
29
+ const {
30
+ throwSanitizedError,
31
+ } = require('./lib/errors.js');
32
+ const {
33
+ kNapiObj,
34
+ kAudioBuffer,
35
+ } = require('./lib/symbols.js');
36
+ const {
37
+ bridgeEventTarget,
38
+ } = require('./lib/events.js');
39
+ /* eslint-enable no-unused-vars */
26
40
 
41
+ const AudioNode = require('./AudioNode.js');
27
42
 
28
- module.exports = (NativeChannelMergerNode) => {
29
-
30
- const EventTarget = EventTargetMixin(NativeChannelMergerNode);
31
- const AudioNode = AudioNodeMixin(EventTarget);
32
-
43
+ module.exports = (jsExport, nativeBinding) => {
33
44
  class ChannelMergerNode extends AudioNode {
45
+
34
46
  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'")
47
+
48
+ if (arguments.length < 1) {
49
+ throw new TypeError(`Failed to construct 'ChannelMergerNode': 1 argument required, but only ${arguments.length} present`);
37
50
  }
38
51
 
39
- super(context, options);
52
+ if (!(context instanceof jsExport.BaseAudioContext)) {
53
+ throw new TypeError(`Failed to construct 'ChannelMergerNode': argument 1 is not of type BaseAudioContext`);
54
+ }
40
55
 
41
- }
56
+ // parsed version of the option to be passed to NAPI
57
+ const parsedOptions = {};
42
58
 
43
- // getters
59
+ if (options && typeof options !== 'object') {
60
+ throw new TypeError('Failed to construct \'ChannelMergerNode\': argument 2 is not of type \'ChannelMergerOptions\'');
61
+ }
44
62
 
45
- // setters
63
+ if (options && options.numberOfInputs !== undefined) {
64
+ parsedOptions.numberOfInputs = conversions['unsigned long'](options.numberOfInputs, {
65
+ enforceRange: true,
66
+ context: `Failed to construct 'ChannelMergerNode': Failed to read the 'numberOfInputs' property from ChannelMergerOptions: The provided value (${options.numberOfInputs}})`,
67
+ });
68
+ } else {
69
+ parsedOptions.numberOfInputs = 6;
70
+ }
71
+
72
+ if (options && options.channelCount !== undefined) {
73
+ parsedOptions.channelCount = conversions['unsigned long'](options.channelCount, {
74
+ enforceRange: true,
75
+ context: `Failed to construct 'ChannelMergerNode': Failed to read the 'channelCount' property from ChannelMergerOptions: The provided value '${options.channelCount}'`,
76
+ });
77
+ }
78
+
79
+ if (options && options.channelCountMode !== undefined) {
80
+ parsedOptions.channelCountMode = conversions['DOMString'](options.channelCountMode, {
81
+ context: `Failed to construct 'ChannelMergerNode': Failed to read the 'channelCount' property from ChannelMergerOptions: The provided value '${options.channelCountMode}'`,
82
+ });
83
+ }
84
+
85
+ if (options && options.channelInterpretation !== undefined) {
86
+ parsedOptions.channelInterpretation = conversions['DOMString'](options.channelInterpretation, {
87
+ context: `Failed to construct 'ChannelMergerNode': Failed to read the 'channelInterpretation' property from ChannelMergerOptions: The provided value '${options.channelInterpretation}'`,
88
+ });
89
+ }
90
+
91
+ let napiObj;
92
+
93
+ try {
94
+ napiObj = new nativeBinding.ChannelMergerNode(context[kNapiObj], parsedOptions);
95
+ } catch (err) {
96
+ throwSanitizedError(err);
97
+ }
98
+
99
+ super(context, {
100
+ [kNapiObj]: napiObj,
101
+ });
102
+
103
+ }
46
104
 
47
- // methods
48
-
49
105
  }
50
106
 
51
- return ChannelMergerNode;
52
- };
107
+ Object.defineProperties(ChannelMergerNode, {
108
+ length: {
109
+ __proto__: null,
110
+ writable: false,
111
+ enumerable: false,
112
+ configurable: true,
113
+ value: 1,
114
+ },
115
+ });
53
116
 
117
+ Object.defineProperties(ChannelMergerNode.prototype, {
118
+ [Symbol.toStringTag]: {
119
+ __proto__: null,
120
+ writable: false,
121
+ enumerable: false,
122
+ configurable: true,
123
+ value: 'ChannelMergerNode',
124
+ },
54
125
 
55
-
126
+ });
127
+
128
+ return ChannelMergerNode;
129
+ };
@@ -17,39 +17,113 @@
17
17
  // -------------------------------------------------------------------------- //
18
18
  // -------------------------------------------------------------------------- //
19
19
 
20
- // eslint-disable-next-line no-unused-vars
21
- const { throwSanitizedError } = require('./lib/errors.js');
22
- // eslint-disable-next-line no-unused-vars
23
- const { AudioParam } = require('./AudioParam.js');
24
- const EventTargetMixin = require('./EventTarget.mixin.js');
25
- const AudioNodeMixin = require('./AudioNode.mixin.js');
20
+ /* eslint-disable no-unused-vars */
21
+ const conversions = require('webidl-conversions');
22
+ const {
23
+ toSanitizedSequence,
24
+ } = require('./lib/cast.js');
25
+ const {
26
+ isFunction,
27
+ kEnumerableProperty,
28
+ } = require('./lib/utils.js');
29
+ const {
30
+ throwSanitizedError,
31
+ } = require('./lib/errors.js');
32
+ const {
33
+ kNapiObj,
34
+ kAudioBuffer,
35
+ } = require('./lib/symbols.js');
36
+ const {
37
+ bridgeEventTarget,
38
+ } = require('./lib/events.js');
39
+ /* eslint-enable no-unused-vars */
26
40
 
41
+ const AudioNode = require('./AudioNode.js');
27
42
 
28
- module.exports = (NativeChannelSplitterNode) => {
29
-
30
- const EventTarget = EventTargetMixin(NativeChannelSplitterNode);
31
- const AudioNode = AudioNodeMixin(EventTarget);
32
-
43
+ module.exports = (jsExport, nativeBinding) => {
33
44
  class ChannelSplitterNode extends AudioNode {
45
+
34
46
  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'")
47
+
48
+ if (arguments.length < 1) {
49
+ throw new TypeError(`Failed to construct 'ChannelSplitterNode': 1 argument required, but only ${arguments.length} present`);
37
50
  }
38
51
 
39
- super(context, options);
52
+ if (!(context instanceof jsExport.BaseAudioContext)) {
53
+ throw new TypeError(`Failed to construct 'ChannelSplitterNode': argument 1 is not of type BaseAudioContext`);
54
+ }
40
55
 
41
- }
56
+ // parsed version of the option to be passed to NAPI
57
+ const parsedOptions = {};
42
58
 
43
- // getters
59
+ if (options && typeof options !== 'object') {
60
+ throw new TypeError('Failed to construct \'ChannelSplitterNode\': argument 2 is not of type \'ChannelSplitterOptions\'');
61
+ }
44
62
 
45
- // setters
63
+ if (options && options.numberOfOutputs !== undefined) {
64
+ parsedOptions.numberOfOutputs = conversions['unsigned long'](options.numberOfOutputs, {
65
+ enforceRange: true,
66
+ context: `Failed to construct 'ChannelSplitterNode': Failed to read the 'numberOfOutputs' property from ChannelSplitterOptions: The provided value (${options.numberOfOutputs}})`,
67
+ });
68
+ } else {
69
+ parsedOptions.numberOfOutputs = 6;
70
+ }
71
+
72
+ if (options && options.channelCount !== undefined) {
73
+ parsedOptions.channelCount = conversions['unsigned long'](options.channelCount, {
74
+ enforceRange: true,
75
+ context: `Failed to construct 'ChannelSplitterNode': Failed to read the 'channelCount' property from ChannelSplitterOptions: The provided value '${options.channelCount}'`,
76
+ });
77
+ }
78
+
79
+ if (options && options.channelCountMode !== undefined) {
80
+ parsedOptions.channelCountMode = conversions['DOMString'](options.channelCountMode, {
81
+ context: `Failed to construct 'ChannelSplitterNode': Failed to read the 'channelCount' property from ChannelSplitterOptions: The provided value '${options.channelCountMode}'`,
82
+ });
83
+ }
84
+
85
+ if (options && options.channelInterpretation !== undefined) {
86
+ parsedOptions.channelInterpretation = conversions['DOMString'](options.channelInterpretation, {
87
+ context: `Failed to construct 'ChannelSplitterNode': Failed to read the 'channelInterpretation' property from ChannelSplitterOptions: The provided value '${options.channelInterpretation}'`,
88
+ });
89
+ }
90
+
91
+ let napiObj;
92
+
93
+ try {
94
+ napiObj = new nativeBinding.ChannelSplitterNode(context[kNapiObj], parsedOptions);
95
+ } catch (err) {
96
+ throwSanitizedError(err);
97
+ }
98
+
99
+ super(context, {
100
+ [kNapiObj]: napiObj,
101
+ });
102
+
103
+ }
46
104
 
47
- // methods
48
-
49
105
  }
50
106
 
51
- return ChannelSplitterNode;
52
- };
107
+ Object.defineProperties(ChannelSplitterNode, {
108
+ length: {
109
+ __proto__: null,
110
+ writable: false,
111
+ enumerable: false,
112
+ configurable: true,
113
+ value: 1,
114
+ },
115
+ });
53
116
 
117
+ Object.defineProperties(ChannelSplitterNode.prototype, {
118
+ [Symbol.toStringTag]: {
119
+ __proto__: null,
120
+ writable: false,
121
+ enumerable: false,
122
+ configurable: true,
123
+ value: 'ChannelSplitterNode',
124
+ },
54
125
 
55
-
126
+ });
127
+
128
+ return ChannelSplitterNode;
129
+ };
@@ -17,44 +17,110 @@
17
17
  // -------------------------------------------------------------------------- //
18
18
  // -------------------------------------------------------------------------- //
19
19
 
20
- // eslint-disable-next-line no-unused-vars
21
- const { throwSanitizedError } = require('./lib/errors.js');
22
- // eslint-disable-next-line no-unused-vars
23
- const { AudioParam } = require('./AudioParam.js');
24
- const EventTargetMixin = require('./EventTarget.mixin.js');
25
- const AudioNodeMixin = require('./AudioNode.mixin.js');
26
- const AudioScheduledSourceNodeMixin = require('./AudioScheduledSourceNode.mixin.js');
20
+ /* eslint-disable no-unused-vars */
21
+ const conversions = require('webidl-conversions');
22
+ const {
23
+ toSanitizedSequence,
24
+ } = require('./lib/cast.js');
25
+ const {
26
+ isFunction,
27
+ kEnumerableProperty,
28
+ } = require('./lib/utils.js');
29
+ const {
30
+ throwSanitizedError,
31
+ } = require('./lib/errors.js');
32
+ const {
33
+ kNapiObj,
34
+ kAudioBuffer,
35
+ } = require('./lib/symbols.js');
36
+ const {
37
+ bridgeEventTarget,
38
+ } = require('./lib/events.js');
39
+ /* eslint-enable no-unused-vars */
27
40
 
28
- module.exports = (NativeConstantSourceNode) => {
29
-
30
- const EventTarget = EventTargetMixin(NativeConstantSourceNode, ['ended']);
31
- const AudioNode = AudioNodeMixin(EventTarget);
32
- const AudioScheduledSourceNode = AudioScheduledSourceNodeMixin(AudioNode);
41
+ const AudioScheduledSourceNode = require('./AudioScheduledSourceNode.js');
33
42
 
43
+ module.exports = (jsExport, nativeBinding) => {
34
44
  class ConstantSourceNode extends AudioScheduledSourceNode {
45
+
46
+ #offset = null;
47
+
35
48
  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'")
49
+
50
+ if (arguments.length < 1) {
51
+ throw new TypeError(`Failed to construct 'ConstantSourceNode': 1 argument required, but only ${arguments.length} present`);
52
+ }
53
+
54
+ if (!(context instanceof jsExport.BaseAudioContext)) {
55
+ throw new TypeError(`Failed to construct 'ConstantSourceNode': argument 1 is not of type BaseAudioContext`);
56
+ }
57
+
58
+ // parsed version of the option to be passed to NAPI
59
+ const parsedOptions = {};
60
+
61
+ if (options && typeof options !== 'object') {
62
+ throw new TypeError('Failed to construct \'ConstantSourceNode\': argument 2 is not of type \'ConstantSourceOptions\'');
63
+ }
64
+
65
+ if (options && options.offset !== undefined) {
66
+ parsedOptions.offset = conversions['float'](options.offset, {
67
+ context: `Failed to construct 'ConstantSourceNode': Failed to read the 'offset' property from ConstantSourceOptions: The provided value (${options.offset}})`,
68
+ });
69
+ } else {
70
+ parsedOptions.offset = 1;
38
71
  }
39
72
 
40
- super(context, options);
41
- // EventTargetMixin has been called so EventTargetMixin[kDispatchEvent] is
42
- // bound to this, then we can safely finalize event target initialization
43
- super.__initEventTarget__();
73
+ let napiObj;
44
74
 
45
- this.offset = new AudioParam(this.offset);
75
+ try {
76
+ napiObj = new nativeBinding.ConstantSourceNode(context[kNapiObj], parsedOptions);
77
+ } catch (err) {
78
+ throwSanitizedError(err);
79
+ }
80
+
81
+ super(context, {
82
+ [kNapiObj]: napiObj,
83
+ });
84
+
85
+ // Bridge Rust native event to Node EventTarget
86
+ bridgeEventTarget(this);
87
+
88
+ this.#offset = new jsExport.AudioParam({
89
+ [kNapiObj]: this[kNapiObj].offset,
90
+ });
46
91
  }
47
92
 
48
- // getters
93
+ get offset() {
94
+ if (!(this instanceof ConstantSourceNode)) {
95
+ throw new TypeError('Invalid Invocation: Value of \'this\' must be of type \'ConstantSourceNode\'');
96
+ }
49
97
 
50
- // setters
98
+ return this.#offset;
99
+ }
51
100
 
52
- // methods
53
-
54
101
  }
55
102
 
56
- return ConstantSourceNode;
57
- };
103
+ Object.defineProperties(ConstantSourceNode, {
104
+ length: {
105
+ __proto__: null,
106
+ writable: false,
107
+ enumerable: false,
108
+ configurable: true,
109
+ value: 1,
110
+ },
111
+ });
112
+
113
+ Object.defineProperties(ConstantSourceNode.prototype, {
114
+ [Symbol.toStringTag]: {
115
+ __proto__: null,
116
+ writable: false,
117
+ enumerable: false,
118
+ configurable: true,
119
+ value: 'ConstantSourceNode',
120
+ },
121
+ offset: kEnumerableProperty,
58
122
 
123
+ });
59
124
 
60
-
125
+ return ConstantSourceNode;
126
+ };
@@ -17,63 +17,195 @@
17
17
  // -------------------------------------------------------------------------- //
18
18
  // -------------------------------------------------------------------------- //
19
19
 
20
- // eslint-disable-next-line no-unused-vars
21
- const { throwSanitizedError } = require('./lib/errors.js');
22
- // eslint-disable-next-line no-unused-vars
23
- const { AudioParam } = require('./AudioParam.js');
24
- const EventTargetMixin = require('./EventTarget.mixin.js');
25
- const AudioNodeMixin = require('./AudioNode.mixin.js');
20
+ /* eslint-disable no-unused-vars */
21
+ const conversions = require('webidl-conversions');
22
+ const {
23
+ toSanitizedSequence,
24
+ } = require('./lib/cast.js');
25
+ const {
26
+ isFunction,
27
+ kEnumerableProperty,
28
+ } = require('./lib/utils.js');
29
+ const {
30
+ throwSanitizedError,
31
+ } = require('./lib/errors.js');
32
+ const {
33
+ kNapiObj,
34
+ kAudioBuffer,
35
+ } = require('./lib/symbols.js');
36
+ const {
37
+ bridgeEventTarget,
38
+ } = require('./lib/events.js');
39
+ /* eslint-enable no-unused-vars */
40
+
41
+ const AudioNode = require('./AudioNode.js');
42
+
43
+ module.exports = (jsExport, nativeBinding) => {
44
+ class ConvolverNode extends AudioNode {
26
45
 
46
+ constructor(context, options) {
27
47
 
28
- module.exports = (NativeConvolverNode) => {
48
+ if (arguments.length < 1) {
49
+ throw new TypeError(`Failed to construct 'ConvolverNode': 1 argument required, but only ${arguments.length} present`);
50
+ }
29
51
 
30
- const EventTarget = EventTargetMixin(NativeConvolverNode);
31
- const AudioNode = AudioNodeMixin(EventTarget);
52
+ if (!(context instanceof jsExport.BaseAudioContext)) {
53
+ throw new TypeError(`Failed to construct 'ConvolverNode': argument 1 is not of type BaseAudioContext`);
54
+ }
32
55
 
33
- class ConvolverNode extends AudioNode {
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'")
56
+ // parsed version of the option to be passed to NAPI
57
+ const parsedOptions = {};
58
+
59
+ if (options && typeof options !== 'object') {
60
+ throw new TypeError('Failed to construct \'ConvolverNode\': argument 2 is not of type \'ConvolverOptions\'');
37
61
  }
38
62
 
39
- super(context, options);
63
+ if (options && options.buffer !== undefined) {
64
+ if (options.buffer !== null) {
65
+ if (!(options.buffer instanceof jsExport.AudioBuffer)) {
66
+ throw new TypeError('Failed to construct \'ConvolverNode\': Failed to read the \'buffer\' property from ConvolverOptions: The provided value cannot be converted to \'AudioBuffer\'');
67
+ }
68
+
69
+ // unwrap napi audio buffer
70
+ parsedOptions.buffer = options.buffer[kNapiObj];
71
+ } else {
72
+ parsedOptions.buffer = null;
73
+ }
74
+ } else {
75
+ parsedOptions.buffer = null;
76
+ }
40
77
 
41
- }
78
+ if (options && options.disableNormalization !== undefined) {
79
+ parsedOptions.disableNormalization = conversions['boolean'](options.disableNormalization, {
80
+ context: `Failed to construct 'ConvolverNode': Failed to read the 'disableNormalization' property from ConvolverOptions: The provided value (${options.disableNormalization}})`,
81
+ });
82
+ } else {
83
+ parsedOptions.disableNormalization = false;
84
+ }
42
85
 
43
- // getters
86
+ if (options && options.channelCount !== undefined) {
87
+ parsedOptions.channelCount = conversions['unsigned long'](options.channelCount, {
88
+ enforceRange: true,
89
+ context: `Failed to construct 'ConvolverNode': Failed to read the 'channelCount' property from ConvolverOptions: The provided value '${options.channelCount}'`,
90
+ });
91
+ }
44
92
 
45
- get buffer() {
46
- return super.buffer;
47
- }
93
+ if (options && options.channelCountMode !== undefined) {
94
+ parsedOptions.channelCountMode = conversions['DOMString'](options.channelCountMode, {
95
+ context: `Failed to construct 'ConvolverNode': Failed to read the 'channelCount' property from ConvolverOptions: The provided value '${options.channelCountMode}'`,
96
+ });
97
+ }
98
+
99
+ if (options && options.channelInterpretation !== undefined) {
100
+ parsedOptions.channelInterpretation = conversions['DOMString'](options.channelInterpretation, {
101
+ context: `Failed to construct 'ConvolverNode': Failed to read the 'channelInterpretation' property from ConvolverOptions: The provided value '${options.channelInterpretation}'`,
102
+ });
103
+ }
104
+
105
+ let napiObj;
106
+
107
+ try {
108
+ napiObj = new nativeBinding.ConvolverNode(context[kNapiObj], parsedOptions);
109
+ } catch (err) {
110
+ throwSanitizedError(err);
111
+ }
112
+
113
+ super(context, {
114
+ [kNapiObj]: napiObj,
115
+ });
116
+
117
+ // keep the wrapped AudioBuffer around
118
+ Object.defineProperty(this, kAudioBuffer, {
119
+ __proto__: null,
120
+ enumerable: false,
121
+ writable: true,
122
+ value: null,
123
+ });
124
+
125
+ if (options && options.buffer !== undefined) {
126
+ this[kAudioBuffer] = options.buffer;
127
+ }
48
128
 
49
- get normalize() {
50
- return super.normalize;
51
129
  }
52
130
 
53
- // setters
131
+ get buffer() {
132
+ if (!(this instanceof ConvolverNode)) {
133
+ throw new TypeError('Invalid Invocation: Value of \'this\' must be of type \'ConvolverNode\'');
134
+ }
135
+
136
+ return this[kAudioBuffer];
137
+ }
54
138
 
55
139
  set buffer(value) {
140
+ if (!(this instanceof ConvolverNode)) {
141
+ throw new TypeError('Invalid Invocation: Value of \'this\' must be of type \'ConvolverNode\'');
142
+ }
143
+
144
+ if (value === null) {
145
+ console.warn('Setting the \'buffer\' property on \'ConvolverNode\' to \'null\' is not supported yet');
146
+ return;
147
+ } else if (!(kNapiObj in value)) {
148
+ throw new TypeError('Failed to set the \'buffer\' property on \'ConvolverNode\': Failed to convert value to \'AudioBuffer\'');
149
+ }
150
+
56
151
  try {
57
- super.buffer = value;
152
+ this[kNapiObj].buffer = value[kNapiObj];
58
153
  } catch (err) {
59
154
  throwSanitizedError(err);
60
155
  }
156
+
157
+ this[kAudioBuffer] = value;
158
+ }
159
+
160
+ get normalize() {
161
+ if (!(this instanceof ConvolverNode)) {
162
+ throw new TypeError('Invalid Invocation: Value of \'this\' must be of type \'ConvolverNode\'');
163
+ }
164
+
165
+ return this[kNapiObj].normalize;
61
166
  }
62
167
 
63
168
  set normalize(value) {
169
+ if (!(this instanceof ConvolverNode)) {
170
+ throw new TypeError('Invalid Invocation: Value of \'this\' must be of type \'ConvolverNode\'');
171
+ }
172
+
173
+ value = conversions['boolean'](value, {
174
+ context: `Failed to set the 'normalize' property on 'ConvolverNode': Value`,
175
+ });
176
+
64
177
  try {
65
- super.normalize = value;
178
+ this[kNapiObj].normalize = value;
66
179
  } catch (err) {
67
180
  throwSanitizedError(err);
68
181
  }
69
182
  }
70
183
 
71
- // methods
72
-
73
184
  }
74
185
 
186
+ Object.defineProperties(ConvolverNode, {
187
+ length: {
188
+ __proto__: null,
189
+ writable: false,
190
+ enumerable: false,
191
+ configurable: true,
192
+ value: 1,
193
+ },
194
+ });
195
+
196
+ Object.defineProperties(ConvolverNode.prototype, {
197
+ [Symbol.toStringTag]: {
198
+ __proto__: null,
199
+ writable: false,
200
+ enumerable: false,
201
+ configurable: true,
202
+ value: 'ConvolverNode',
203
+ },
204
+
205
+ buffer: kEnumerableProperty,
206
+ normalize: kEnumerableProperty,
207
+
208
+ });
209
+
75
210
  return ConvolverNode;
76
211
  };
77
-
78
-
79
-