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.
- package/CHANGELOG.md +7 -0
- package/TODOS.md +140 -12
- package/index.mjs +10 -5
- package/js/AnalyserNode.js +262 -48
- package/js/AudioBuffer.js +244 -0
- package/js/AudioBufferSourceNode.js +265 -41
- package/js/AudioContext.js +271 -28
- package/js/AudioDestinationNode.js +42 -100
- package/js/AudioListener.js +219 -0
- package/js/AudioNode.js +323 -0
- package/js/AudioParam.js +252 -39
- package/js/AudioScheduledSourceNode.js +105 -0
- package/js/BaseAudioContext.js +419 -0
- package/js/BiquadFilterNode.js +221 -29
- package/js/ChannelMergerNode.js +96 -22
- package/js/ChannelSplitterNode.js +96 -22
- package/js/ConstantSourceNode.js +92 -26
- package/js/ConvolverNode.js +161 -29
- package/js/DelayNode.js +115 -21
- package/js/DynamicsCompressorNode.js +198 -27
- package/js/GainNode.js +107 -21
- package/js/IIRFilterNode.js +139 -23
- package/js/MediaStreamAudioSourceNode.js +83 -24
- package/js/OfflineAudioContext.js +182 -34
- package/js/OscillatorNode.js +195 -32
- package/js/PannerNode.js +461 -56
- package/js/PeriodicWave.js +67 -3
- package/js/StereoPannerNode.js +107 -21
- package/js/WaveShaperNode.js +147 -29
- package/js/lib/cast.js +19 -0
- package/js/lib/errors.js +10 -55
- package/js/lib/events.js +20 -0
- package/js/lib/symbols.js +5 -0
- package/js/lib/utils.js +12 -12
- package/js/monkey-patch.js +32 -30
- package/node-web-audio-api.darwin-arm64.node +0 -0
- package/node-web-audio-api.darwin-x64.node +0 -0
- package/node-web-audio-api.linux-arm-gnueabihf.node +0 -0
- package/node-web-audio-api.linux-arm64-gnu.node +0 -0
- package/node-web-audio-api.linux-x64-gnu.node +0 -0
- package/node-web-audio-api.win32-arm64-msvc.node +0 -0
- package/node-web-audio-api.win32-x64-msvc.node +0 -0
- package/package.json +7 -4
- package/run-wpt.md +27 -0
- package/run-wpt.sh +5 -0
- package/js/AudioNode.mixin.js +0 -132
- package/js/AudioScheduledSourceNode.mixin.js +0 -67
- package/js/BaseAudioContext.mixin.js +0 -154
- package/js/EventTarget.mixin.js +0 -60
package/js/DelayNode.js
CHANGED
|
@@ -17,40 +17,134 @@
|
|
|
17
17
|
// -------------------------------------------------------------------------- //
|
|
18
18
|
// -------------------------------------------------------------------------- //
|
|
19
19
|
|
|
20
|
-
|
|
21
|
-
const
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
const
|
|
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 = (
|
|
43
|
+
module.exports = (jsExport, nativeBinding) => {
|
|
44
|
+
class DelayNode extends AudioNode {
|
|
29
45
|
|
|
30
|
-
|
|
31
|
-
const AudioNode = AudioNodeMixin(EventTarget);
|
|
46
|
+
#delayTime = null;
|
|
32
47
|
|
|
33
|
-
class DelayNode extends AudioNode {
|
|
34
48
|
constructor(context, options) {
|
|
35
|
-
|
|
36
|
-
|
|
49
|
+
|
|
50
|
+
if (arguments.length < 1) {
|
|
51
|
+
throw new TypeError(`Failed to construct 'DelayNode': 1 argument required, but only ${arguments.length} present`);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
if (!(context instanceof jsExport.BaseAudioContext)) {
|
|
55
|
+
throw new TypeError(`Failed to construct 'DelayNode': 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 \'DelayNode\': argument 2 is not of type \'DelayOptions\'');
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
if (options && options.maxDelayTime !== undefined) {
|
|
66
|
+
parsedOptions.maxDelayTime = conversions['double'](options.maxDelayTime, {
|
|
67
|
+
context: `Failed to construct 'DelayNode': Failed to read the 'maxDelayTime' property from DelayOptions: The provided value (${options.maxDelayTime}})`,
|
|
68
|
+
});
|
|
69
|
+
} else {
|
|
70
|
+
parsedOptions.maxDelayTime = 1;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
if (options && options.delayTime !== undefined) {
|
|
74
|
+
parsedOptions.delayTime = conversions['double'](options.delayTime, {
|
|
75
|
+
context: `Failed to construct 'DelayNode': Failed to read the 'delayTime' property from DelayOptions: The provided value (${options.delayTime}})`,
|
|
76
|
+
});
|
|
77
|
+
} else {
|
|
78
|
+
parsedOptions.delayTime = 0;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
if (options && options.channelCount !== undefined) {
|
|
82
|
+
parsedOptions.channelCount = conversions['unsigned long'](options.channelCount, {
|
|
83
|
+
enforceRange: true,
|
|
84
|
+
context: `Failed to construct 'DelayNode': Failed to read the 'channelCount' property from DelayOptions: The provided value '${options.channelCount}'`,
|
|
85
|
+
});
|
|
37
86
|
}
|
|
38
87
|
|
|
39
|
-
|
|
88
|
+
if (options && options.channelCountMode !== undefined) {
|
|
89
|
+
parsedOptions.channelCountMode = conversions['DOMString'](options.channelCountMode, {
|
|
90
|
+
context: `Failed to construct 'DelayNode': Failed to read the 'channelCount' property from DelayOptions: The provided value '${options.channelCountMode}'`,
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
if (options && options.channelInterpretation !== undefined) {
|
|
95
|
+
parsedOptions.channelInterpretation = conversions['DOMString'](options.channelInterpretation, {
|
|
96
|
+
context: `Failed to construct 'DelayNode': Failed to read the 'channelInterpretation' property from DelayOptions: The provided value '${options.channelInterpretation}'`,
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
let napiObj;
|
|
101
|
+
|
|
102
|
+
try {
|
|
103
|
+
napiObj = new nativeBinding.DelayNode(context[kNapiObj], parsedOptions);
|
|
104
|
+
} catch (err) {
|
|
105
|
+
throwSanitizedError(err);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
super(context, {
|
|
109
|
+
[kNapiObj]: napiObj,
|
|
110
|
+
});
|
|
40
111
|
|
|
41
|
-
this
|
|
112
|
+
this.#delayTime = new jsExport.AudioParam({
|
|
113
|
+
[kNapiObj]: this[kNapiObj].delayTime,
|
|
114
|
+
});
|
|
42
115
|
}
|
|
43
116
|
|
|
44
|
-
|
|
117
|
+
get delayTime() {
|
|
118
|
+
if (!(this instanceof DelayNode)) {
|
|
119
|
+
throw new TypeError('Invalid Invocation: Value of \'this\' must be of type \'DelayNode\'');
|
|
120
|
+
}
|
|
45
121
|
|
|
46
|
-
|
|
122
|
+
return this.#delayTime;
|
|
123
|
+
}
|
|
47
124
|
|
|
48
|
-
// methods
|
|
49
|
-
|
|
50
125
|
}
|
|
51
126
|
|
|
52
|
-
|
|
53
|
-
|
|
127
|
+
Object.defineProperties(DelayNode, {
|
|
128
|
+
length: {
|
|
129
|
+
__proto__: null,
|
|
130
|
+
writable: false,
|
|
131
|
+
enumerable: false,
|
|
132
|
+
configurable: true,
|
|
133
|
+
value: 1,
|
|
134
|
+
},
|
|
135
|
+
});
|
|
54
136
|
|
|
137
|
+
Object.defineProperties(DelayNode.prototype, {
|
|
138
|
+
[Symbol.toStringTag]: {
|
|
139
|
+
__proto__: null,
|
|
140
|
+
writable: false,
|
|
141
|
+
enumerable: false,
|
|
142
|
+
configurable: true,
|
|
143
|
+
value: 'DelayNode',
|
|
144
|
+
},
|
|
145
|
+
delayTime: kEnumerableProperty,
|
|
55
146
|
|
|
56
|
-
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
return DelayNode;
|
|
150
|
+
};
|
|
@@ -17,48 +17,219 @@
|
|
|
17
17
|
// -------------------------------------------------------------------------- //
|
|
18
18
|
// -------------------------------------------------------------------------- //
|
|
19
19
|
|
|
20
|
-
|
|
21
|
-
const
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
const
|
|
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 = (
|
|
43
|
+
module.exports = (jsExport, nativeBinding) => {
|
|
44
|
+
class DynamicsCompressorNode extends AudioNode {
|
|
29
45
|
|
|
30
|
-
|
|
31
|
-
|
|
46
|
+
#threshold = null;
|
|
47
|
+
#knee = null;
|
|
48
|
+
#ratio = null;
|
|
49
|
+
#attack = null;
|
|
50
|
+
#release = null;
|
|
32
51
|
|
|
33
|
-
class DynamicsCompressorNode extends AudioNode {
|
|
34
52
|
constructor(context, options) {
|
|
35
|
-
|
|
36
|
-
|
|
53
|
+
|
|
54
|
+
if (arguments.length < 1) {
|
|
55
|
+
throw new TypeError(`Failed to construct 'DynamicsCompressorNode': 1 argument required, but only ${arguments.length} present`);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
if (!(context instanceof jsExport.BaseAudioContext)) {
|
|
59
|
+
throw new TypeError(`Failed to construct 'DynamicsCompressorNode': argument 1 is not of type BaseAudioContext`);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// parsed version of the option to be passed to NAPI
|
|
63
|
+
const parsedOptions = {};
|
|
64
|
+
|
|
65
|
+
if (options && typeof options !== 'object') {
|
|
66
|
+
throw new TypeError('Failed to construct \'DynamicsCompressorNode\': argument 2 is not of type \'DynamicsCompressorOptions\'');
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
if (options && options.attack !== undefined) {
|
|
70
|
+
parsedOptions.attack = conversions['float'](options.attack, {
|
|
71
|
+
context: `Failed to construct 'DynamicsCompressorNode': Failed to read the 'attack' property from DynamicsCompressorOptions: The provided value (${options.attack}})`,
|
|
72
|
+
});
|
|
73
|
+
} else {
|
|
74
|
+
parsedOptions.attack = 0.003;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
if (options && options.knee !== undefined) {
|
|
78
|
+
parsedOptions.knee = conversions['float'](options.knee, {
|
|
79
|
+
context: `Failed to construct 'DynamicsCompressorNode': Failed to read the 'knee' property from DynamicsCompressorOptions: The provided value (${options.knee}})`,
|
|
80
|
+
});
|
|
81
|
+
} else {
|
|
82
|
+
parsedOptions.knee = 30;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
if (options && options.ratio !== undefined) {
|
|
86
|
+
parsedOptions.ratio = conversions['float'](options.ratio, {
|
|
87
|
+
context: `Failed to construct 'DynamicsCompressorNode': Failed to read the 'ratio' property from DynamicsCompressorOptions: The provided value (${options.ratio}})`,
|
|
88
|
+
});
|
|
89
|
+
} else {
|
|
90
|
+
parsedOptions.ratio = 12;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
if (options && options.release !== undefined) {
|
|
94
|
+
parsedOptions.release = conversions['float'](options.release, {
|
|
95
|
+
context: `Failed to construct 'DynamicsCompressorNode': Failed to read the 'release' property from DynamicsCompressorOptions: The provided value (${options.release}})`,
|
|
96
|
+
});
|
|
97
|
+
} else {
|
|
98
|
+
parsedOptions.release = 0.25;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
if (options && options.threshold !== undefined) {
|
|
102
|
+
parsedOptions.threshold = conversions['float'](options.threshold, {
|
|
103
|
+
context: `Failed to construct 'DynamicsCompressorNode': Failed to read the 'threshold' property from DynamicsCompressorOptions: The provided value (${options.threshold}})`,
|
|
104
|
+
});
|
|
105
|
+
} else {
|
|
106
|
+
parsedOptions.threshold = -24;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
if (options && options.channelCount !== undefined) {
|
|
110
|
+
parsedOptions.channelCount = conversions['unsigned long'](options.channelCount, {
|
|
111
|
+
enforceRange: true,
|
|
112
|
+
context: `Failed to construct 'DynamicsCompressorNode': Failed to read the 'channelCount' property from DynamicsCompressorOptions: The provided value '${options.channelCount}'`,
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
if (options && options.channelCountMode !== undefined) {
|
|
117
|
+
parsedOptions.channelCountMode = conversions['DOMString'](options.channelCountMode, {
|
|
118
|
+
context: `Failed to construct 'DynamicsCompressorNode': Failed to read the 'channelCount' property from DynamicsCompressorOptions: The provided value '${options.channelCountMode}'`,
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
if (options && options.channelInterpretation !== undefined) {
|
|
123
|
+
parsedOptions.channelInterpretation = conversions['DOMString'](options.channelInterpretation, {
|
|
124
|
+
context: `Failed to construct 'DynamicsCompressorNode': Failed to read the 'channelInterpretation' property from DynamicsCompressorOptions: The provided value '${options.channelInterpretation}'`,
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
let napiObj;
|
|
129
|
+
|
|
130
|
+
try {
|
|
131
|
+
napiObj = new nativeBinding.DynamicsCompressorNode(context[kNapiObj], parsedOptions);
|
|
132
|
+
} catch (err) {
|
|
133
|
+
throwSanitizedError(err);
|
|
37
134
|
}
|
|
38
135
|
|
|
39
|
-
super(context,
|
|
136
|
+
super(context, {
|
|
137
|
+
[kNapiObj]: napiObj,
|
|
138
|
+
});
|
|
40
139
|
|
|
41
|
-
this
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
this
|
|
45
|
-
|
|
140
|
+
this.#threshold = new jsExport.AudioParam({
|
|
141
|
+
[kNapiObj]: this[kNapiObj].threshold,
|
|
142
|
+
});
|
|
143
|
+
this.#knee = new jsExport.AudioParam({
|
|
144
|
+
[kNapiObj]: this[kNapiObj].knee,
|
|
145
|
+
});
|
|
146
|
+
this.#ratio = new jsExport.AudioParam({
|
|
147
|
+
[kNapiObj]: this[kNapiObj].ratio,
|
|
148
|
+
});
|
|
149
|
+
this.#attack = new jsExport.AudioParam({
|
|
150
|
+
[kNapiObj]: this[kNapiObj].attack,
|
|
151
|
+
});
|
|
152
|
+
this.#release = new jsExport.AudioParam({
|
|
153
|
+
[kNapiObj]: this[kNapiObj].release,
|
|
154
|
+
});
|
|
46
155
|
}
|
|
47
156
|
|
|
48
|
-
|
|
157
|
+
get threshold() {
|
|
158
|
+
if (!(this instanceof DynamicsCompressorNode)) {
|
|
159
|
+
throw new TypeError('Invalid Invocation: Value of \'this\' must be of type \'DynamicsCompressorNode\'');
|
|
160
|
+
}
|
|
49
161
|
|
|
50
|
-
|
|
51
|
-
|
|
162
|
+
return this.#threshold;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
get knee() {
|
|
166
|
+
if (!(this instanceof DynamicsCompressorNode)) {
|
|
167
|
+
throw new TypeError('Invalid Invocation: Value of \'this\' must be of type \'DynamicsCompressorNode\'');
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
return this.#knee;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
get ratio() {
|
|
174
|
+
if (!(this instanceof DynamicsCompressorNode)) {
|
|
175
|
+
throw new TypeError('Invalid Invocation: Value of \'this\' must be of type \'DynamicsCompressorNode\'');
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
return this.#ratio;
|
|
52
179
|
}
|
|
53
180
|
|
|
54
|
-
|
|
181
|
+
get attack() {
|
|
182
|
+
if (!(this instanceof DynamicsCompressorNode)) {
|
|
183
|
+
throw new TypeError('Invalid Invocation: Value of \'this\' must be of type \'DynamicsCompressorNode\'');
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
return this.#attack;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
get release() {
|
|
190
|
+
if (!(this instanceof DynamicsCompressorNode)) {
|
|
191
|
+
throw new TypeError('Invalid Invocation: Value of \'this\' must be of type \'DynamicsCompressorNode\'');
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
return this.#release;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
get reduction() {
|
|
198
|
+
if (!(this instanceof DynamicsCompressorNode)) {
|
|
199
|
+
throw new TypeError('Invalid Invocation: Value of \'this\' must be of type \'DynamicsCompressorNode\'');
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
return this[kNapiObj].reduction;
|
|
203
|
+
}
|
|
55
204
|
|
|
56
|
-
// methods
|
|
57
|
-
|
|
58
205
|
}
|
|
59
206
|
|
|
60
|
-
|
|
61
|
-
|
|
207
|
+
Object.defineProperties(DynamicsCompressorNode, {
|
|
208
|
+
length: {
|
|
209
|
+
__proto__: null,
|
|
210
|
+
writable: false,
|
|
211
|
+
enumerable: false,
|
|
212
|
+
configurable: true,
|
|
213
|
+
value: 1,
|
|
214
|
+
},
|
|
215
|
+
});
|
|
62
216
|
|
|
217
|
+
Object.defineProperties(DynamicsCompressorNode.prototype, {
|
|
218
|
+
[Symbol.toStringTag]: {
|
|
219
|
+
__proto__: null,
|
|
220
|
+
writable: false,
|
|
221
|
+
enumerable: false,
|
|
222
|
+
configurable: true,
|
|
223
|
+
value: 'DynamicsCompressorNode',
|
|
224
|
+
},
|
|
225
|
+
threshold: kEnumerableProperty,
|
|
226
|
+
knee: kEnumerableProperty,
|
|
227
|
+
ratio: kEnumerableProperty,
|
|
228
|
+
attack: kEnumerableProperty,
|
|
229
|
+
release: kEnumerableProperty,
|
|
230
|
+
reduction: kEnumerableProperty,
|
|
63
231
|
|
|
64
|
-
|
|
232
|
+
});
|
|
233
|
+
|
|
234
|
+
return DynamicsCompressorNode;
|
|
235
|
+
};
|
package/js/GainNode.js
CHANGED
|
@@ -17,40 +17,126 @@
|
|
|
17
17
|
// -------------------------------------------------------------------------- //
|
|
18
18
|
// -------------------------------------------------------------------------- //
|
|
19
19
|
|
|
20
|
-
|
|
21
|
-
const
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
const
|
|
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 = (
|
|
43
|
+
module.exports = (jsExport, nativeBinding) => {
|
|
44
|
+
class GainNode extends AudioNode {
|
|
29
45
|
|
|
30
|
-
|
|
31
|
-
const AudioNode = AudioNodeMixin(EventTarget);
|
|
46
|
+
#gain = null;
|
|
32
47
|
|
|
33
|
-
class GainNode extends AudioNode {
|
|
34
48
|
constructor(context, options) {
|
|
35
|
-
|
|
36
|
-
|
|
49
|
+
|
|
50
|
+
if (arguments.length < 1) {
|
|
51
|
+
throw new TypeError(`Failed to construct 'GainNode': 1 argument required, but only ${arguments.length} present`);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
if (!(context instanceof jsExport.BaseAudioContext)) {
|
|
55
|
+
throw new TypeError(`Failed to construct 'GainNode': 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 \'GainNode\': argument 2 is not of type \'GainOptions\'');
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
if (options && options.gain !== undefined) {
|
|
66
|
+
parsedOptions.gain = conversions['float'](options.gain, {
|
|
67
|
+
context: `Failed to construct 'GainNode': Failed to read the 'gain' property from GainOptions: The provided value (${options.gain}})`,
|
|
68
|
+
});
|
|
69
|
+
} else {
|
|
70
|
+
parsedOptions.gain = 1.0;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
if (options && options.channelCount !== undefined) {
|
|
74
|
+
parsedOptions.channelCount = conversions['unsigned long'](options.channelCount, {
|
|
75
|
+
enforceRange: true,
|
|
76
|
+
context: `Failed to construct 'GainNode': Failed to read the 'channelCount' property from GainOptions: The provided value '${options.channelCount}'`,
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
if (options && options.channelCountMode !== undefined) {
|
|
81
|
+
parsedOptions.channelCountMode = conversions['DOMString'](options.channelCountMode, {
|
|
82
|
+
context: `Failed to construct 'GainNode': Failed to read the 'channelCount' property from GainOptions: The provided value '${options.channelCountMode}'`,
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
if (options && options.channelInterpretation !== undefined) {
|
|
87
|
+
parsedOptions.channelInterpretation = conversions['DOMString'](options.channelInterpretation, {
|
|
88
|
+
context: `Failed to construct 'GainNode': Failed to read the 'channelInterpretation' property from GainOptions: The provided value '${options.channelInterpretation}'`,
|
|
89
|
+
});
|
|
37
90
|
}
|
|
38
91
|
|
|
39
|
-
|
|
92
|
+
let napiObj;
|
|
40
93
|
|
|
41
|
-
|
|
94
|
+
try {
|
|
95
|
+
napiObj = new nativeBinding.GainNode(context[kNapiObj], parsedOptions);
|
|
96
|
+
} catch (err) {
|
|
97
|
+
throwSanitizedError(err);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
super(context, {
|
|
101
|
+
[kNapiObj]: napiObj,
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
this.#gain = new jsExport.AudioParam({
|
|
105
|
+
[kNapiObj]: this[kNapiObj].gain,
|
|
106
|
+
});
|
|
42
107
|
}
|
|
43
108
|
|
|
44
|
-
|
|
109
|
+
get gain() {
|
|
110
|
+
if (!(this instanceof GainNode)) {
|
|
111
|
+
throw new TypeError('Invalid Invocation: Value of \'this\' must be of type \'GainNode\'');
|
|
112
|
+
}
|
|
45
113
|
|
|
46
|
-
|
|
114
|
+
return this.#gain;
|
|
115
|
+
}
|
|
47
116
|
|
|
48
|
-
// methods
|
|
49
|
-
|
|
50
117
|
}
|
|
51
118
|
|
|
52
|
-
|
|
53
|
-
|
|
119
|
+
Object.defineProperties(GainNode, {
|
|
120
|
+
length: {
|
|
121
|
+
__proto__: null,
|
|
122
|
+
writable: false,
|
|
123
|
+
enumerable: false,
|
|
124
|
+
configurable: true,
|
|
125
|
+
value: 1,
|
|
126
|
+
},
|
|
127
|
+
});
|
|
54
128
|
|
|
129
|
+
Object.defineProperties(GainNode.prototype, {
|
|
130
|
+
[Symbol.toStringTag]: {
|
|
131
|
+
__proto__: null,
|
|
132
|
+
writable: false,
|
|
133
|
+
enumerable: false,
|
|
134
|
+
configurable: true,
|
|
135
|
+
value: 'GainNode',
|
|
136
|
+
},
|
|
137
|
+
gain: kEnumerableProperty,
|
|
55
138
|
|
|
56
|
-
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
return GainNode;
|
|
142
|
+
};
|