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
@@ -17,63 +17,192 @@
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
+ /* eslint-enable no-unused-vars */
37
+
38
+ const AudioNode = require('./AudioNode.js');
39
+
40
+ module.exports = (jsExport, nativeBinding) => {
41
+ class ConvolverNode extends AudioNode {
26
42
 
43
+ constructor(context, options) {
27
44
 
28
- module.exports = (NativeConvolverNode) => {
45
+ if (arguments.length < 1) {
46
+ throw new TypeError(`Failed to construct 'ConvolverNode': 1 argument required, but only ${arguments.length} present`);
47
+ }
29
48
 
30
- const EventTarget = EventTargetMixin(NativeConvolverNode);
31
- const AudioNode = AudioNodeMixin(EventTarget);
49
+ if (!(context instanceof jsExport.BaseAudioContext)) {
50
+ throw new TypeError(`Failed to construct 'ConvolverNode': argument 1 is not of type BaseAudioContext`);
51
+ }
32
52
 
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'")
53
+ // parsed version of the option to be passed to NAPI
54
+ const parsedOptions = {};
55
+
56
+ if (options && typeof options !== 'object') {
57
+ throw new TypeError('Failed to construct \'ConvolverNode\': argument 2 is not of type \'ConvolverOptions\'');
37
58
  }
38
59
 
39
- super(context, options);
60
+ if (options && options.buffer !== undefined) {
61
+ if (options.buffer !== null) {
62
+ if (!(options.buffer instanceof jsExport.AudioBuffer)) {
63
+ throw new TypeError('Failed to construct \'ConvolverNode\': Failed to read the \'buffer\' property from ConvolverOptions: The provided value cannot be converted to \'AudioBuffer\'');
64
+ }
65
+
66
+ // unwrap napi audio buffer
67
+ parsedOptions.buffer = options.buffer[kNapiObj];
68
+ } else {
69
+ parsedOptions.buffer = null;
70
+ }
71
+ } else {
72
+ parsedOptions.buffer = null;
73
+ }
40
74
 
41
- }
75
+ if (options && options.disableNormalization !== undefined) {
76
+ parsedOptions.disableNormalization = conversions['boolean'](options.disableNormalization, {
77
+ context: `Failed to construct 'ConvolverNode': Failed to read the 'disableNormalization' property from ConvolverOptions: The provided value (${options.disableNormalization}})`,
78
+ });
79
+ } else {
80
+ parsedOptions.disableNormalization = false;
81
+ }
42
82
 
43
- // getters
83
+ if (options && options.channelCount !== undefined) {
84
+ parsedOptions.channelCount = conversions['unsigned long'](options.channelCount, {
85
+ enforceRange: true,
86
+ context: `Failed to construct 'ConvolverNode': Failed to read the 'channelCount' property from ConvolverOptions: The provided value '${options.channelCount}'`,
87
+ });
88
+ }
44
89
 
45
- get buffer() {
46
- return super.buffer;
47
- }
90
+ if (options && options.channelCountMode !== undefined) {
91
+ parsedOptions.channelCountMode = conversions['DOMString'](options.channelCountMode, {
92
+ context: `Failed to construct 'ConvolverNode': Failed to read the 'channelCount' property from ConvolverOptions: The provided value '${options.channelCountMode}'`,
93
+ });
94
+ }
95
+
96
+ if (options && options.channelInterpretation !== undefined) {
97
+ parsedOptions.channelInterpretation = conversions['DOMString'](options.channelInterpretation, {
98
+ context: `Failed to construct 'ConvolverNode': Failed to read the 'channelInterpretation' property from ConvolverOptions: The provided value '${options.channelInterpretation}'`,
99
+ });
100
+ }
101
+
102
+ let napiObj;
103
+
104
+ try {
105
+ napiObj = new nativeBinding.ConvolverNode(context[kNapiObj], parsedOptions);
106
+ } catch (err) {
107
+ throwSanitizedError(err);
108
+ }
109
+
110
+ super(context, {
111
+ [kNapiObj]: napiObj,
112
+ });
113
+
114
+ // keep the wrapped AudioBuffer around
115
+ Object.defineProperty(this, kAudioBuffer, {
116
+ __proto__: null,
117
+ enumerable: false,
118
+ writable: true,
119
+ value: null,
120
+ });
121
+
122
+ if (options && options.buffer !== undefined) {
123
+ this[kAudioBuffer] = options.buffer;
124
+ }
48
125
 
49
- get normalize() {
50
- return super.normalize;
51
126
  }
52
127
 
53
- // setters
128
+ get buffer() {
129
+ if (!(this instanceof ConvolverNode)) {
130
+ throw new TypeError('Invalid Invocation: Value of \'this\' must be of type \'ConvolverNode\'');
131
+ }
132
+
133
+ return this[kAudioBuffer];
134
+ }
54
135
 
55
136
  set buffer(value) {
137
+ if (!(this instanceof ConvolverNode)) {
138
+ throw new TypeError('Invalid Invocation: Value of \'this\' must be of type \'ConvolverNode\'');
139
+ }
140
+
141
+ if (value === null) {
142
+ console.warn('Setting the \'buffer\' property on \'ConvolverNode\' to \'null\' is not supported yet');
143
+ return;
144
+ } else if (!(kNapiObj in value)) {
145
+ throw new TypeError('Failed to set the \'buffer\' property on \'ConvolverNode\': Failed to convert value to \'AudioBuffer\'');
146
+ }
147
+
56
148
  try {
57
- super.buffer = value;
149
+ this[kNapiObj].buffer = value[kNapiObj];
58
150
  } catch (err) {
59
151
  throwSanitizedError(err);
60
152
  }
153
+
154
+ this[kAudioBuffer] = value;
155
+ }
156
+
157
+ get normalize() {
158
+ if (!(this instanceof ConvolverNode)) {
159
+ throw new TypeError('Invalid Invocation: Value of \'this\' must be of type \'ConvolverNode\'');
160
+ }
161
+
162
+ return this[kNapiObj].normalize;
61
163
  }
62
164
 
63
165
  set normalize(value) {
166
+ if (!(this instanceof ConvolverNode)) {
167
+ throw new TypeError('Invalid Invocation: Value of \'this\' must be of type \'ConvolverNode\'');
168
+ }
169
+
170
+ value = conversions['boolean'](value, {
171
+ context: `Failed to set the 'normalize' property on 'ConvolverNode': Value`,
172
+ });
173
+
64
174
  try {
65
- super.normalize = value;
175
+ this[kNapiObj].normalize = value;
66
176
  } catch (err) {
67
177
  throwSanitizedError(err);
68
178
  }
69
179
  }
70
180
 
71
- // methods
72
-
73
181
  }
74
182
 
183
+ Object.defineProperties(ConvolverNode, {
184
+ length: {
185
+ __proto__: null,
186
+ writable: false,
187
+ enumerable: false,
188
+ configurable: true,
189
+ value: 1,
190
+ },
191
+ });
192
+
193
+ Object.defineProperties(ConvolverNode.prototype, {
194
+ [Symbol.toStringTag]: {
195
+ __proto__: null,
196
+ writable: false,
197
+ enumerable: false,
198
+ configurable: true,
199
+ value: 'ConvolverNode',
200
+ },
201
+
202
+ buffer: kEnumerableProperty,
203
+ normalize: kEnumerableProperty,
204
+
205
+ });
206
+
75
207
  return ConvolverNode;
76
208
  };
77
-
78
-
79
-
package/js/DelayNode.js CHANGED
@@ -17,40 +17,131 @@
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
+ /* eslint-enable no-unused-vars */
26
37
 
38
+ const AudioNode = require('./AudioNode.js');
27
39
 
28
- module.exports = (NativeDelayNode) => {
40
+ module.exports = (jsExport, nativeBinding) => {
41
+ class DelayNode extends AudioNode {
29
42
 
30
- const EventTarget = EventTargetMixin(NativeDelayNode);
31
- const AudioNode = AudioNodeMixin(EventTarget);
43
+ #delayTime = null;
32
44
 
33
- class DelayNode extends AudioNode {
34
45
  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'")
46
+
47
+ if (arguments.length < 1) {
48
+ throw new TypeError(`Failed to construct 'DelayNode': 1 argument required, but only ${arguments.length} present`);
49
+ }
50
+
51
+ if (!(context instanceof jsExport.BaseAudioContext)) {
52
+ throw new TypeError(`Failed to construct 'DelayNode': argument 1 is not of type BaseAudioContext`);
53
+ }
54
+
55
+ // parsed version of the option to be passed to NAPI
56
+ const parsedOptions = {};
57
+
58
+ if (options && typeof options !== 'object') {
59
+ throw new TypeError('Failed to construct \'DelayNode\': argument 2 is not of type \'DelayOptions\'');
60
+ }
61
+
62
+ if (options && options.maxDelayTime !== undefined) {
63
+ parsedOptions.maxDelayTime = conversions['double'](options.maxDelayTime, {
64
+ context: `Failed to construct 'DelayNode': Failed to read the 'maxDelayTime' property from DelayOptions: The provided value (${options.maxDelayTime}})`,
65
+ });
66
+ } else {
67
+ parsedOptions.maxDelayTime = 1;
68
+ }
69
+
70
+ if (options && options.delayTime !== undefined) {
71
+ parsedOptions.delayTime = conversions['double'](options.delayTime, {
72
+ context: `Failed to construct 'DelayNode': Failed to read the 'delayTime' property from DelayOptions: The provided value (${options.delayTime}})`,
73
+ });
74
+ } else {
75
+ parsedOptions.delayTime = 0;
76
+ }
77
+
78
+ if (options && options.channelCount !== undefined) {
79
+ parsedOptions.channelCount = conversions['unsigned long'](options.channelCount, {
80
+ enforceRange: true,
81
+ context: `Failed to construct 'DelayNode': Failed to read the 'channelCount' property from DelayOptions: The provided value '${options.channelCount}'`,
82
+ });
37
83
  }
38
84
 
39
- super(context, options);
85
+ if (options && options.channelCountMode !== undefined) {
86
+ parsedOptions.channelCountMode = conversions['DOMString'](options.channelCountMode, {
87
+ context: `Failed to construct 'DelayNode': Failed to read the 'channelCount' property from DelayOptions: The provided value '${options.channelCountMode}'`,
88
+ });
89
+ }
90
+
91
+ if (options && options.channelInterpretation !== undefined) {
92
+ parsedOptions.channelInterpretation = conversions['DOMString'](options.channelInterpretation, {
93
+ context: `Failed to construct 'DelayNode': Failed to read the 'channelInterpretation' property from DelayOptions: The provided value '${options.channelInterpretation}'`,
94
+ });
95
+ }
96
+
97
+ let napiObj;
98
+
99
+ try {
100
+ napiObj = new nativeBinding.DelayNode(context[kNapiObj], parsedOptions);
101
+ } catch (err) {
102
+ throwSanitizedError(err);
103
+ }
104
+
105
+ super(context, {
106
+ [kNapiObj]: napiObj,
107
+ });
40
108
 
41
- this.delayTime = new AudioParam(this.delayTime);
109
+ this.#delayTime = new jsExport.AudioParam({
110
+ [kNapiObj]: this[kNapiObj].delayTime,
111
+ });
42
112
  }
43
113
 
44
- // getters
114
+ get delayTime() {
115
+ if (!(this instanceof DelayNode)) {
116
+ throw new TypeError('Invalid Invocation: Value of \'this\' must be of type \'DelayNode\'');
117
+ }
45
118
 
46
- // setters
119
+ return this.#delayTime;
120
+ }
47
121
 
48
- // methods
49
-
50
122
  }
51
123
 
52
- return DelayNode;
53
- };
124
+ Object.defineProperties(DelayNode, {
125
+ length: {
126
+ __proto__: null,
127
+ writable: false,
128
+ enumerable: false,
129
+ configurable: true,
130
+ value: 1,
131
+ },
132
+ });
54
133
 
134
+ Object.defineProperties(DelayNode.prototype, {
135
+ [Symbol.toStringTag]: {
136
+ __proto__: null,
137
+ writable: false,
138
+ enumerable: false,
139
+ configurable: true,
140
+ value: 'DelayNode',
141
+ },
142
+ delayTime: kEnumerableProperty,
55
143
 
56
-
144
+ });
145
+
146
+ return DelayNode;
147
+ };
@@ -17,48 +17,216 @@
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
+ /* eslint-enable no-unused-vars */
26
37
 
38
+ const AudioNode = require('./AudioNode.js');
27
39
 
28
- module.exports = (NativeDynamicsCompressorNode) => {
40
+ module.exports = (jsExport, nativeBinding) => {
41
+ class DynamicsCompressorNode extends AudioNode {
29
42
 
30
- const EventTarget = EventTargetMixin(NativeDynamicsCompressorNode);
31
- const AudioNode = AudioNodeMixin(EventTarget);
43
+ #threshold = null;
44
+ #knee = null;
45
+ #ratio = null;
46
+ #attack = null;
47
+ #release = null;
32
48
 
33
- class DynamicsCompressorNode extends AudioNode {
34
49
  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'")
50
+
51
+ if (arguments.length < 1) {
52
+ throw new TypeError(`Failed to construct 'DynamicsCompressorNode': 1 argument required, but only ${arguments.length} present`);
53
+ }
54
+
55
+ if (!(context instanceof jsExport.BaseAudioContext)) {
56
+ throw new TypeError(`Failed to construct 'DynamicsCompressorNode': argument 1 is not of type BaseAudioContext`);
57
+ }
58
+
59
+ // parsed version of the option to be passed to NAPI
60
+ const parsedOptions = {};
61
+
62
+ if (options && typeof options !== 'object') {
63
+ throw new TypeError('Failed to construct \'DynamicsCompressorNode\': argument 2 is not of type \'DynamicsCompressorOptions\'');
64
+ }
65
+
66
+ if (options && options.attack !== undefined) {
67
+ parsedOptions.attack = conversions['float'](options.attack, {
68
+ context: `Failed to construct 'DynamicsCompressorNode': Failed to read the 'attack' property from DynamicsCompressorOptions: The provided value (${options.attack}})`,
69
+ });
70
+ } else {
71
+ parsedOptions.attack = 0.003;
72
+ }
73
+
74
+ if (options && options.knee !== undefined) {
75
+ parsedOptions.knee = conversions['float'](options.knee, {
76
+ context: `Failed to construct 'DynamicsCompressorNode': Failed to read the 'knee' property from DynamicsCompressorOptions: The provided value (${options.knee}})`,
77
+ });
78
+ } else {
79
+ parsedOptions.knee = 30;
80
+ }
81
+
82
+ if (options && options.ratio !== undefined) {
83
+ parsedOptions.ratio = conversions['float'](options.ratio, {
84
+ context: `Failed to construct 'DynamicsCompressorNode': Failed to read the 'ratio' property from DynamicsCompressorOptions: The provided value (${options.ratio}})`,
85
+ });
86
+ } else {
87
+ parsedOptions.ratio = 12;
88
+ }
89
+
90
+ if (options && options.release !== undefined) {
91
+ parsedOptions.release = conversions['float'](options.release, {
92
+ context: `Failed to construct 'DynamicsCompressorNode': Failed to read the 'release' property from DynamicsCompressorOptions: The provided value (${options.release}})`,
93
+ });
94
+ } else {
95
+ parsedOptions.release = 0.25;
96
+ }
97
+
98
+ if (options && options.threshold !== undefined) {
99
+ parsedOptions.threshold = conversions['float'](options.threshold, {
100
+ context: `Failed to construct 'DynamicsCompressorNode': Failed to read the 'threshold' property from DynamicsCompressorOptions: The provided value (${options.threshold}})`,
101
+ });
102
+ } else {
103
+ parsedOptions.threshold = -24;
104
+ }
105
+
106
+ if (options && options.channelCount !== undefined) {
107
+ parsedOptions.channelCount = conversions['unsigned long'](options.channelCount, {
108
+ enforceRange: true,
109
+ context: `Failed to construct 'DynamicsCompressorNode': Failed to read the 'channelCount' property from DynamicsCompressorOptions: The provided value '${options.channelCount}'`,
110
+ });
111
+ }
112
+
113
+ if (options && options.channelCountMode !== undefined) {
114
+ parsedOptions.channelCountMode = conversions['DOMString'](options.channelCountMode, {
115
+ context: `Failed to construct 'DynamicsCompressorNode': Failed to read the 'channelCount' property from DynamicsCompressorOptions: The provided value '${options.channelCountMode}'`,
116
+ });
117
+ }
118
+
119
+ if (options && options.channelInterpretation !== undefined) {
120
+ parsedOptions.channelInterpretation = conversions['DOMString'](options.channelInterpretation, {
121
+ context: `Failed to construct 'DynamicsCompressorNode': Failed to read the 'channelInterpretation' property from DynamicsCompressorOptions: The provided value '${options.channelInterpretation}'`,
122
+ });
123
+ }
124
+
125
+ let napiObj;
126
+
127
+ try {
128
+ napiObj = new nativeBinding.DynamicsCompressorNode(context[kNapiObj], parsedOptions);
129
+ } catch (err) {
130
+ throwSanitizedError(err);
37
131
  }
38
132
 
39
- super(context, options);
133
+ super(context, {
134
+ [kNapiObj]: napiObj,
135
+ });
40
136
 
41
- this.threshold = new AudioParam(this.threshold);
42
- this.knee = new AudioParam(this.knee);
43
- this.ratio = new AudioParam(this.ratio);
44
- this.attack = new AudioParam(this.attack);
45
- this.release = new AudioParam(this.release);
137
+ this.#threshold = new jsExport.AudioParam({
138
+ [kNapiObj]: this[kNapiObj].threshold,
139
+ });
140
+ this.#knee = new jsExport.AudioParam({
141
+ [kNapiObj]: this[kNapiObj].knee,
142
+ });
143
+ this.#ratio = new jsExport.AudioParam({
144
+ [kNapiObj]: this[kNapiObj].ratio,
145
+ });
146
+ this.#attack = new jsExport.AudioParam({
147
+ [kNapiObj]: this[kNapiObj].attack,
148
+ });
149
+ this.#release = new jsExport.AudioParam({
150
+ [kNapiObj]: this[kNapiObj].release,
151
+ });
46
152
  }
47
153
 
48
- // getters
154
+ get threshold() {
155
+ if (!(this instanceof DynamicsCompressorNode)) {
156
+ throw new TypeError('Invalid Invocation: Value of \'this\' must be of type \'DynamicsCompressorNode\'');
157
+ }
49
158
 
50
- get reduction() {
51
- return super.reduction;
159
+ return this.#threshold;
160
+ }
161
+
162
+ get knee() {
163
+ if (!(this instanceof DynamicsCompressorNode)) {
164
+ throw new TypeError('Invalid Invocation: Value of \'this\' must be of type \'DynamicsCompressorNode\'');
165
+ }
166
+
167
+ return this.#knee;
168
+ }
169
+
170
+ get ratio() {
171
+ if (!(this instanceof DynamicsCompressorNode)) {
172
+ throw new TypeError('Invalid Invocation: Value of \'this\' must be of type \'DynamicsCompressorNode\'');
173
+ }
174
+
175
+ return this.#ratio;
52
176
  }
53
177
 
54
- // setters
178
+ get attack() {
179
+ if (!(this instanceof DynamicsCompressorNode)) {
180
+ throw new TypeError('Invalid Invocation: Value of \'this\' must be of type \'DynamicsCompressorNode\'');
181
+ }
182
+
183
+ return this.#attack;
184
+ }
185
+
186
+ get release() {
187
+ if (!(this instanceof DynamicsCompressorNode)) {
188
+ throw new TypeError('Invalid Invocation: Value of \'this\' must be of type \'DynamicsCompressorNode\'');
189
+ }
190
+
191
+ return this.#release;
192
+ }
193
+
194
+ get reduction() {
195
+ if (!(this instanceof DynamicsCompressorNode)) {
196
+ throw new TypeError('Invalid Invocation: Value of \'this\' must be of type \'DynamicsCompressorNode\'');
197
+ }
198
+
199
+ return this[kNapiObj].reduction;
200
+ }
55
201
 
56
- // methods
57
-
58
202
  }
59
203
 
60
- return DynamicsCompressorNode;
61
- };
204
+ Object.defineProperties(DynamicsCompressorNode, {
205
+ length: {
206
+ __proto__: null,
207
+ writable: false,
208
+ enumerable: false,
209
+ configurable: true,
210
+ value: 1,
211
+ },
212
+ });
62
213
 
214
+ Object.defineProperties(DynamicsCompressorNode.prototype, {
215
+ [Symbol.toStringTag]: {
216
+ __proto__: null,
217
+ writable: false,
218
+ enumerable: false,
219
+ configurable: true,
220
+ value: 'DynamicsCompressorNode',
221
+ },
222
+ threshold: kEnumerableProperty,
223
+ knee: kEnumerableProperty,
224
+ ratio: kEnumerableProperty,
225
+ attack: kEnumerableProperty,
226
+ release: kEnumerableProperty,
227
+ reduction: kEnumerableProperty,
63
228
 
64
-
229
+ });
230
+
231
+ return DynamicsCompressorNode;
232
+ };