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.
- package/CHANGELOG.md +14 -0
- package/TODOS.md +134 -12
- package/index.mjs +17 -6
- package/js/AnalyserNode.js +259 -48
- package/js/AudioBuffer.js +243 -0
- package/js/AudioBufferSourceNode.js +259 -41
- package/js/AudioContext.js +294 -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 +120 -0
- package/js/BaseAudioContext.js +434 -0
- package/js/BiquadFilterNode.js +218 -29
- package/js/ChannelMergerNode.js +93 -22
- package/js/ChannelSplitterNode.js +93 -22
- package/js/ConstantSourceNode.js +86 -26
- package/js/ConvolverNode.js +158 -29
- package/js/DelayNode.js +112 -21
- package/js/DynamicsCompressorNode.js +195 -27
- package/js/Events.js +84 -0
- package/js/GainNode.js +104 -21
- package/js/IIRFilterNode.js +136 -23
- package/js/MediaStreamAudioSourceNode.js +80 -24
- package/js/OfflineAudioContext.js +198 -35
- package/js/OscillatorNode.js +189 -32
- package/js/PannerNode.js +458 -56
- package/js/PeriodicWave.js +67 -3
- package/js/ScriptProcessorNode.js +179 -0
- package/js/StereoPannerNode.js +104 -21
- package/js/WaveShaperNode.js +144 -29
- package/js/lib/cast.js +19 -0
- package/js/lib/errors.js +10 -55
- package/js/lib/events.js +10 -0
- package/js/lib/symbols.js +20 -0
- package/js/lib/utils.js +12 -12
- package/js/monkey-patch.js +40 -31
- 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/BiquadFilterNode.js
CHANGED
|
@@ -17,54 +17,220 @@
|
|
|
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
|
+
/* eslint-enable no-unused-vars */
|
|
26
37
|
|
|
38
|
+
const AudioNode = require('./AudioNode.js');
|
|
27
39
|
|
|
28
|
-
module.exports = (
|
|
40
|
+
module.exports = (jsExport, nativeBinding) => {
|
|
41
|
+
class BiquadFilterNode extends AudioNode {
|
|
29
42
|
|
|
30
|
-
|
|
31
|
-
|
|
43
|
+
#frequency = null;
|
|
44
|
+
#detune = null;
|
|
45
|
+
#Q = null;
|
|
46
|
+
#gain = null;
|
|
32
47
|
|
|
33
|
-
class BiquadFilterNode extends AudioNode {
|
|
34
48
|
constructor(context, options) {
|
|
35
|
-
|
|
36
|
-
|
|
49
|
+
|
|
50
|
+
if (arguments.length < 1) {
|
|
51
|
+
throw new TypeError(`Failed to construct 'BiquadFilterNode': 1 argument required, but only ${arguments.length} present`);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
if (!(context instanceof jsExport.BaseAudioContext)) {
|
|
55
|
+
throw new TypeError(`Failed to construct 'BiquadFilterNode': 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 \'BiquadFilterNode\': argument 2 is not of type \'BiquadFilterOptions\'');
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
if (options && options.type !== undefined) {
|
|
66
|
+
if (!['lowpass', 'highpass', 'bandpass', 'lowshelf', 'highshelf', 'peaking', 'notch', 'allpass'].includes(options.type)) {
|
|
67
|
+
throw new TypeError(`Failed to construct 'BiquadFilterNode': Failed to read the 'type' property from BiquadFilterOptions: The provided value '${options.type}' is not a valid enum value of type BiquadFilterType`);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
parsedOptions.type = conversions['DOMString'](options.type, {
|
|
71
|
+
context: `Failed to construct 'BiquadFilterNode': Failed to read the 'type' property from BiquadFilterOptions: The provided value '${options.type}'`,
|
|
72
|
+
});
|
|
73
|
+
} else {
|
|
74
|
+
parsedOptions.type = 'lowpass';
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
if (options && options.Q !== undefined) {
|
|
78
|
+
parsedOptions.Q = conversions['float'](options.Q, {
|
|
79
|
+
context: `Failed to construct 'BiquadFilterNode': Failed to read the 'Q' property from BiquadFilterOptions: The provided value (${options.Q}})`,
|
|
80
|
+
});
|
|
81
|
+
} else {
|
|
82
|
+
parsedOptions.Q = 1;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
if (options && options.detune !== undefined) {
|
|
86
|
+
parsedOptions.detune = conversions['float'](options.detune, {
|
|
87
|
+
context: `Failed to construct 'BiquadFilterNode': Failed to read the 'detune' property from BiquadFilterOptions: The provided value (${options.detune}})`,
|
|
88
|
+
});
|
|
89
|
+
} else {
|
|
90
|
+
parsedOptions.detune = 0;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
if (options && options.frequency !== undefined) {
|
|
94
|
+
parsedOptions.frequency = conversions['float'](options.frequency, {
|
|
95
|
+
context: `Failed to construct 'BiquadFilterNode': Failed to read the 'frequency' property from BiquadFilterOptions: The provided value (${options.frequency}})`,
|
|
96
|
+
});
|
|
97
|
+
} else {
|
|
98
|
+
parsedOptions.frequency = 350;
|
|
37
99
|
}
|
|
38
100
|
|
|
39
|
-
|
|
101
|
+
if (options && options.gain !== undefined) {
|
|
102
|
+
parsedOptions.gain = conversions['float'](options.gain, {
|
|
103
|
+
context: `Failed to construct 'BiquadFilterNode': Failed to read the 'gain' property from BiquadFilterOptions: The provided value (${options.gain}})`,
|
|
104
|
+
});
|
|
105
|
+
} else {
|
|
106
|
+
parsedOptions.gain = 0;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
if (options && options.channelCount !== undefined) {
|
|
110
|
+
parsedOptions.channelCount = conversions['unsigned long'](options.channelCount, {
|
|
111
|
+
enforceRange: true,
|
|
112
|
+
context: `Failed to construct 'BiquadFilterNode': Failed to read the 'channelCount' property from BiquadFilterOptions: 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 'BiquadFilterNode': Failed to read the 'channelCount' property from BiquadFilterOptions: The provided value '${options.channelCountMode}'`,
|
|
119
|
+
});
|
|
120
|
+
}
|
|
40
121
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
122
|
+
if (options && options.channelInterpretation !== undefined) {
|
|
123
|
+
parsedOptions.channelInterpretation = conversions['DOMString'](options.channelInterpretation, {
|
|
124
|
+
context: `Failed to construct 'BiquadFilterNode': Failed to read the 'channelInterpretation' property from BiquadFilterOptions: The provided value '${options.channelInterpretation}'`,
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
let napiObj;
|
|
129
|
+
|
|
130
|
+
try {
|
|
131
|
+
napiObj = new nativeBinding.BiquadFilterNode(context[kNapiObj], parsedOptions);
|
|
132
|
+
} catch (err) {
|
|
133
|
+
throwSanitizedError(err);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
super(context, {
|
|
137
|
+
[kNapiObj]: napiObj,
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
this.#frequency = new jsExport.AudioParam({
|
|
141
|
+
[kNapiObj]: this[kNapiObj].frequency,
|
|
142
|
+
});
|
|
143
|
+
this.#detune = new jsExport.AudioParam({
|
|
144
|
+
[kNapiObj]: this[kNapiObj].detune,
|
|
145
|
+
});
|
|
146
|
+
this.#Q = new jsExport.AudioParam({
|
|
147
|
+
[kNapiObj]: this[kNapiObj].Q,
|
|
148
|
+
});
|
|
149
|
+
this.#gain = new jsExport.AudioParam({
|
|
150
|
+
[kNapiObj]: this[kNapiObj].gain,
|
|
151
|
+
});
|
|
45
152
|
}
|
|
46
153
|
|
|
47
|
-
|
|
154
|
+
get frequency() {
|
|
155
|
+
if (!(this instanceof BiquadFilterNode)) {
|
|
156
|
+
throw new TypeError('Invalid Invocation: Value of \'this\' must be of type \'BiquadFilterNode\'');
|
|
157
|
+
}
|
|
48
158
|
|
|
49
|
-
|
|
50
|
-
return super.type;
|
|
159
|
+
return this.#frequency;
|
|
51
160
|
}
|
|
52
161
|
|
|
53
|
-
|
|
162
|
+
get detune() {
|
|
163
|
+
if (!(this instanceof BiquadFilterNode)) {
|
|
164
|
+
throw new TypeError('Invalid Invocation: Value of \'this\' must be of type \'BiquadFilterNode\'');
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
return this.#detune;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
get Q() {
|
|
171
|
+
if (!(this instanceof BiquadFilterNode)) {
|
|
172
|
+
throw new TypeError('Invalid Invocation: Value of \'this\' must be of type \'BiquadFilterNode\'');
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
return this.#Q;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
get gain() {
|
|
179
|
+
if (!(this instanceof BiquadFilterNode)) {
|
|
180
|
+
throw new TypeError('Invalid Invocation: Value of \'this\' must be of type \'BiquadFilterNode\'');
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
return this.#gain;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
get type() {
|
|
187
|
+
if (!(this instanceof BiquadFilterNode)) {
|
|
188
|
+
throw new TypeError('Invalid Invocation: Value of \'this\' must be of type \'BiquadFilterNode\'');
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
return this[kNapiObj].type;
|
|
192
|
+
}
|
|
54
193
|
|
|
55
194
|
set type(value) {
|
|
195
|
+
if (!(this instanceof BiquadFilterNode)) {
|
|
196
|
+
throw new TypeError('Invalid Invocation: Value of \'this\' must be of type \'BiquadFilterNode\'');
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
if (!['lowpass', 'highpass', 'bandpass', 'lowshelf', 'highshelf', 'peaking', 'notch', 'allpass'].includes(value)) {
|
|
200
|
+
console.warn(`Failed to set the 'type' property on 'BiquadFilterNode': Value '${value}' is not a valid 'BiquadFilterType' enum value`);
|
|
201
|
+
return;
|
|
202
|
+
}
|
|
203
|
+
|
|
56
204
|
try {
|
|
57
|
-
|
|
205
|
+
this[kNapiObj].type = value;
|
|
58
206
|
} catch (err) {
|
|
59
207
|
throwSanitizedError(err);
|
|
60
208
|
}
|
|
61
209
|
}
|
|
62
210
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
211
|
+
getFrequencyResponse(frequencyHz, magResponse, phaseResponse) {
|
|
212
|
+
if (!(this instanceof BiquadFilterNode)) {
|
|
213
|
+
throw new TypeError('Invalid Invocation: Value of \'this\' must be of type \'BiquadFilterNode\'');
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
if (arguments.length < 3) {
|
|
217
|
+
throw new TypeError(`Failed to execute 'getFrequencyResponse' on 'BiquadFilterNode': 3 argument required, but only ${arguments.length} present`);
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
if (!(frequencyHz instanceof Float32Array)) {
|
|
221
|
+
throw new TypeError(`Failed to execute 'getFrequencyResponse' on 'BiquadFilterNode': Parameter 1 is not of type 'Float32Array'`);
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
if (!(magResponse instanceof Float32Array)) {
|
|
225
|
+
throw new TypeError(`Failed to execute 'getFrequencyResponse' on 'BiquadFilterNode': Parameter 2 is not of type 'Float32Array'`);
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
if (!(phaseResponse instanceof Float32Array)) {
|
|
229
|
+
throw new TypeError(`Failed to execute 'getFrequencyResponse' on 'BiquadFilterNode': Parameter 3 is not of type 'Float32Array'`);
|
|
230
|
+
}
|
|
231
|
+
|
|
66
232
|
try {
|
|
67
|
-
return
|
|
233
|
+
return this[kNapiObj].getFrequencyResponse(frequencyHz, magResponse, phaseResponse);
|
|
68
234
|
} catch (err) {
|
|
69
235
|
throwSanitizedError(err);
|
|
70
236
|
}
|
|
@@ -72,8 +238,31 @@ module.exports = (NativeBiquadFilterNode) => {
|
|
|
72
238
|
|
|
73
239
|
}
|
|
74
240
|
|
|
75
|
-
|
|
76
|
-
|
|
241
|
+
Object.defineProperties(BiquadFilterNode, {
|
|
242
|
+
length: {
|
|
243
|
+
__proto__: null,
|
|
244
|
+
writable: false,
|
|
245
|
+
enumerable: false,
|
|
246
|
+
configurable: true,
|
|
247
|
+
value: 1,
|
|
248
|
+
},
|
|
249
|
+
});
|
|
77
250
|
|
|
251
|
+
Object.defineProperties(BiquadFilterNode.prototype, {
|
|
252
|
+
[Symbol.toStringTag]: {
|
|
253
|
+
__proto__: null,
|
|
254
|
+
writable: false,
|
|
255
|
+
enumerable: false,
|
|
256
|
+
configurable: true,
|
|
257
|
+
value: 'BiquadFilterNode',
|
|
258
|
+
},
|
|
259
|
+
frequency: kEnumerableProperty,
|
|
260
|
+
detune: kEnumerableProperty,
|
|
261
|
+
Q: kEnumerableProperty,
|
|
262
|
+
gain: kEnumerableProperty,
|
|
263
|
+
type: kEnumerableProperty,
|
|
264
|
+
getFrequencyResponse: kEnumerableProperty,
|
|
265
|
+
});
|
|
78
266
|
|
|
79
|
-
|
|
267
|
+
return BiquadFilterNode;
|
|
268
|
+
};
|
package/js/ChannelMergerNode.js
CHANGED
|
@@ -17,39 +17,110 @@
|
|
|
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
|
+
/* eslint-enable no-unused-vars */
|
|
26
37
|
|
|
38
|
+
const AudioNode = require('./AudioNode.js');
|
|
27
39
|
|
|
28
|
-
module.exports = (
|
|
29
|
-
|
|
30
|
-
const EventTarget = EventTargetMixin(NativeChannelMergerNode);
|
|
31
|
-
const AudioNode = AudioNodeMixin(EventTarget);
|
|
32
|
-
|
|
40
|
+
module.exports = (jsExport, nativeBinding) => {
|
|
33
41
|
class ChannelMergerNode extends AudioNode {
|
|
42
|
+
|
|
34
43
|
constructor(context, options) {
|
|
35
|
-
|
|
36
|
-
|
|
44
|
+
|
|
45
|
+
if (arguments.length < 1) {
|
|
46
|
+
throw new TypeError(`Failed to construct 'ChannelMergerNode': 1 argument required, but only ${arguments.length} present`);
|
|
37
47
|
}
|
|
38
48
|
|
|
39
|
-
|
|
49
|
+
if (!(context instanceof jsExport.BaseAudioContext)) {
|
|
50
|
+
throw new TypeError(`Failed to construct 'ChannelMergerNode': argument 1 is not of type BaseAudioContext`);
|
|
51
|
+
}
|
|
40
52
|
|
|
41
|
-
|
|
53
|
+
// parsed version of the option to be passed to NAPI
|
|
54
|
+
const parsedOptions = {};
|
|
42
55
|
|
|
43
|
-
|
|
56
|
+
if (options && typeof options !== 'object') {
|
|
57
|
+
throw new TypeError('Failed to construct \'ChannelMergerNode\': argument 2 is not of type \'ChannelMergerOptions\'');
|
|
58
|
+
}
|
|
44
59
|
|
|
45
|
-
|
|
60
|
+
if (options && options.numberOfInputs !== undefined) {
|
|
61
|
+
parsedOptions.numberOfInputs = conversions['unsigned long'](options.numberOfInputs, {
|
|
62
|
+
enforceRange: true,
|
|
63
|
+
context: `Failed to construct 'ChannelMergerNode': Failed to read the 'numberOfInputs' property from ChannelMergerOptions: The provided value (${options.numberOfInputs}})`,
|
|
64
|
+
});
|
|
65
|
+
} else {
|
|
66
|
+
parsedOptions.numberOfInputs = 6;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
if (options && options.channelCount !== undefined) {
|
|
70
|
+
parsedOptions.channelCount = conversions['unsigned long'](options.channelCount, {
|
|
71
|
+
enforceRange: true,
|
|
72
|
+
context: `Failed to construct 'ChannelMergerNode': Failed to read the 'channelCount' property from ChannelMergerOptions: The provided value '${options.channelCount}'`,
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
if (options && options.channelCountMode !== undefined) {
|
|
77
|
+
parsedOptions.channelCountMode = conversions['DOMString'](options.channelCountMode, {
|
|
78
|
+
context: `Failed to construct 'ChannelMergerNode': Failed to read the 'channelCount' property from ChannelMergerOptions: The provided value '${options.channelCountMode}'`,
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
if (options && options.channelInterpretation !== undefined) {
|
|
83
|
+
parsedOptions.channelInterpretation = conversions['DOMString'](options.channelInterpretation, {
|
|
84
|
+
context: `Failed to construct 'ChannelMergerNode': Failed to read the 'channelInterpretation' property from ChannelMergerOptions: The provided value '${options.channelInterpretation}'`,
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
let napiObj;
|
|
89
|
+
|
|
90
|
+
try {
|
|
91
|
+
napiObj = new nativeBinding.ChannelMergerNode(context[kNapiObj], parsedOptions);
|
|
92
|
+
} catch (err) {
|
|
93
|
+
throwSanitizedError(err);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
super(context, {
|
|
97
|
+
[kNapiObj]: napiObj,
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
}
|
|
46
101
|
|
|
47
|
-
// methods
|
|
48
|
-
|
|
49
102
|
}
|
|
50
103
|
|
|
51
|
-
|
|
52
|
-
|
|
104
|
+
Object.defineProperties(ChannelMergerNode, {
|
|
105
|
+
length: {
|
|
106
|
+
__proto__: null,
|
|
107
|
+
writable: false,
|
|
108
|
+
enumerable: false,
|
|
109
|
+
configurable: true,
|
|
110
|
+
value: 1,
|
|
111
|
+
},
|
|
112
|
+
});
|
|
53
113
|
|
|
114
|
+
Object.defineProperties(ChannelMergerNode.prototype, {
|
|
115
|
+
[Symbol.toStringTag]: {
|
|
116
|
+
__proto__: null,
|
|
117
|
+
writable: false,
|
|
118
|
+
enumerable: false,
|
|
119
|
+
configurable: true,
|
|
120
|
+
value: 'ChannelMergerNode',
|
|
121
|
+
},
|
|
54
122
|
|
|
55
|
-
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
return ChannelMergerNode;
|
|
126
|
+
};
|
|
@@ -17,39 +17,110 @@
|
|
|
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
|
+
/* eslint-enable no-unused-vars */
|
|
26
37
|
|
|
38
|
+
const AudioNode = require('./AudioNode.js');
|
|
27
39
|
|
|
28
|
-
module.exports = (
|
|
29
|
-
|
|
30
|
-
const EventTarget = EventTargetMixin(NativeChannelSplitterNode);
|
|
31
|
-
const AudioNode = AudioNodeMixin(EventTarget);
|
|
32
|
-
|
|
40
|
+
module.exports = (jsExport, nativeBinding) => {
|
|
33
41
|
class ChannelSplitterNode extends AudioNode {
|
|
42
|
+
|
|
34
43
|
constructor(context, options) {
|
|
35
|
-
|
|
36
|
-
|
|
44
|
+
|
|
45
|
+
if (arguments.length < 1) {
|
|
46
|
+
throw new TypeError(`Failed to construct 'ChannelSplitterNode': 1 argument required, but only ${arguments.length} present`);
|
|
37
47
|
}
|
|
38
48
|
|
|
39
|
-
|
|
49
|
+
if (!(context instanceof jsExport.BaseAudioContext)) {
|
|
50
|
+
throw new TypeError(`Failed to construct 'ChannelSplitterNode': argument 1 is not of type BaseAudioContext`);
|
|
51
|
+
}
|
|
40
52
|
|
|
41
|
-
|
|
53
|
+
// parsed version of the option to be passed to NAPI
|
|
54
|
+
const parsedOptions = {};
|
|
42
55
|
|
|
43
|
-
|
|
56
|
+
if (options && typeof options !== 'object') {
|
|
57
|
+
throw new TypeError('Failed to construct \'ChannelSplitterNode\': argument 2 is not of type \'ChannelSplitterOptions\'');
|
|
58
|
+
}
|
|
44
59
|
|
|
45
|
-
|
|
60
|
+
if (options && options.numberOfOutputs !== undefined) {
|
|
61
|
+
parsedOptions.numberOfOutputs = conversions['unsigned long'](options.numberOfOutputs, {
|
|
62
|
+
enforceRange: true,
|
|
63
|
+
context: `Failed to construct 'ChannelSplitterNode': Failed to read the 'numberOfOutputs' property from ChannelSplitterOptions: The provided value (${options.numberOfOutputs}})`,
|
|
64
|
+
});
|
|
65
|
+
} else {
|
|
66
|
+
parsedOptions.numberOfOutputs = 6;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
if (options && options.channelCount !== undefined) {
|
|
70
|
+
parsedOptions.channelCount = conversions['unsigned long'](options.channelCount, {
|
|
71
|
+
enforceRange: true,
|
|
72
|
+
context: `Failed to construct 'ChannelSplitterNode': Failed to read the 'channelCount' property from ChannelSplitterOptions: The provided value '${options.channelCount}'`,
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
if (options && options.channelCountMode !== undefined) {
|
|
77
|
+
parsedOptions.channelCountMode = conversions['DOMString'](options.channelCountMode, {
|
|
78
|
+
context: `Failed to construct 'ChannelSplitterNode': Failed to read the 'channelCount' property from ChannelSplitterOptions: The provided value '${options.channelCountMode}'`,
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
if (options && options.channelInterpretation !== undefined) {
|
|
83
|
+
parsedOptions.channelInterpretation = conversions['DOMString'](options.channelInterpretation, {
|
|
84
|
+
context: `Failed to construct 'ChannelSplitterNode': Failed to read the 'channelInterpretation' property from ChannelSplitterOptions: The provided value '${options.channelInterpretation}'`,
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
let napiObj;
|
|
89
|
+
|
|
90
|
+
try {
|
|
91
|
+
napiObj = new nativeBinding.ChannelSplitterNode(context[kNapiObj], parsedOptions);
|
|
92
|
+
} catch (err) {
|
|
93
|
+
throwSanitizedError(err);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
super(context, {
|
|
97
|
+
[kNapiObj]: napiObj,
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
}
|
|
46
101
|
|
|
47
|
-
// methods
|
|
48
|
-
|
|
49
102
|
}
|
|
50
103
|
|
|
51
|
-
|
|
52
|
-
|
|
104
|
+
Object.defineProperties(ChannelSplitterNode, {
|
|
105
|
+
length: {
|
|
106
|
+
__proto__: null,
|
|
107
|
+
writable: false,
|
|
108
|
+
enumerable: false,
|
|
109
|
+
configurable: true,
|
|
110
|
+
value: 1,
|
|
111
|
+
},
|
|
112
|
+
});
|
|
53
113
|
|
|
114
|
+
Object.defineProperties(ChannelSplitterNode.prototype, {
|
|
115
|
+
[Symbol.toStringTag]: {
|
|
116
|
+
__proto__: null,
|
|
117
|
+
writable: false,
|
|
118
|
+
enumerable: false,
|
|
119
|
+
configurable: true,
|
|
120
|
+
value: 'ChannelSplitterNode',
|
|
121
|
+
},
|
|
54
122
|
|
|
55
|
-
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
return ChannelSplitterNode;
|
|
126
|
+
};
|
package/js/ConstantSourceNode.js
CHANGED
|
@@ -17,44 +17,104 @@
|
|
|
17
17
|
// -------------------------------------------------------------------------- //
|
|
18
18
|
// -------------------------------------------------------------------------- //
|
|
19
19
|
|
|
20
|
-
|
|
21
|
-
const
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
const
|
|
26
|
-
|
|
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 */
|
|
27
37
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
const EventTarget = EventTargetMixin(NativeConstantSourceNode, ['ended']);
|
|
31
|
-
const AudioNode = AudioNodeMixin(EventTarget);
|
|
32
|
-
const AudioScheduledSourceNode = AudioScheduledSourceNodeMixin(AudioNode);
|
|
38
|
+
const AudioScheduledSourceNode = require('./AudioScheduledSourceNode.js');
|
|
33
39
|
|
|
40
|
+
module.exports = (jsExport, nativeBinding) => {
|
|
34
41
|
class ConstantSourceNode extends AudioScheduledSourceNode {
|
|
42
|
+
|
|
43
|
+
#offset = null;
|
|
44
|
+
|
|
35
45
|
constructor(context, options) {
|
|
36
|
-
|
|
37
|
-
|
|
46
|
+
|
|
47
|
+
if (arguments.length < 1) {
|
|
48
|
+
throw new TypeError(`Failed to construct 'ConstantSourceNode': 1 argument required, but only ${arguments.length} present`);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
if (!(context instanceof jsExport.BaseAudioContext)) {
|
|
52
|
+
throw new TypeError(`Failed to construct 'ConstantSourceNode': 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 \'ConstantSourceNode\': argument 2 is not of type \'ConstantSourceOptions\'');
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
if (options && options.offset !== undefined) {
|
|
63
|
+
parsedOptions.offset = conversions['float'](options.offset, {
|
|
64
|
+
context: `Failed to construct 'ConstantSourceNode': Failed to read the 'offset' property from ConstantSourceOptions: The provided value (${options.offset}})`,
|
|
65
|
+
});
|
|
66
|
+
} else {
|
|
67
|
+
parsedOptions.offset = 1;
|
|
38
68
|
}
|
|
39
69
|
|
|
40
|
-
|
|
41
|
-
// EventTargetMixin has been called so EventTargetMixin[kDispatchEvent] is
|
|
42
|
-
// bound to this, then we can safely finalize event target initialization
|
|
43
|
-
super.__initEventTarget__();
|
|
70
|
+
let napiObj;
|
|
44
71
|
|
|
45
|
-
|
|
72
|
+
try {
|
|
73
|
+
napiObj = new nativeBinding.ConstantSourceNode(context[kNapiObj], parsedOptions);
|
|
74
|
+
} catch (err) {
|
|
75
|
+
throwSanitizedError(err);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
super(context, {
|
|
79
|
+
[kNapiObj]: napiObj,
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
this.#offset = new jsExport.AudioParam({
|
|
83
|
+
[kNapiObj]: this[kNapiObj].offset,
|
|
84
|
+
});
|
|
46
85
|
}
|
|
47
86
|
|
|
48
|
-
|
|
87
|
+
get offset() {
|
|
88
|
+
if (!(this instanceof ConstantSourceNode)) {
|
|
89
|
+
throw new TypeError('Invalid Invocation: Value of \'this\' must be of type \'ConstantSourceNode\'');
|
|
90
|
+
}
|
|
49
91
|
|
|
50
|
-
|
|
92
|
+
return this.#offset;
|
|
93
|
+
}
|
|
51
94
|
|
|
52
|
-
// methods
|
|
53
|
-
|
|
54
95
|
}
|
|
55
96
|
|
|
56
|
-
|
|
57
|
-
|
|
97
|
+
Object.defineProperties(ConstantSourceNode, {
|
|
98
|
+
length: {
|
|
99
|
+
__proto__: null,
|
|
100
|
+
writable: false,
|
|
101
|
+
enumerable: false,
|
|
102
|
+
configurable: true,
|
|
103
|
+
value: 1,
|
|
104
|
+
},
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
Object.defineProperties(ConstantSourceNode.prototype, {
|
|
108
|
+
[Symbol.toStringTag]: {
|
|
109
|
+
__proto__: null,
|
|
110
|
+
writable: false,
|
|
111
|
+
enumerable: false,
|
|
112
|
+
configurable: true,
|
|
113
|
+
value: 'ConstantSourceNode',
|
|
114
|
+
},
|
|
115
|
+
offset: kEnumerableProperty,
|
|
58
116
|
|
|
117
|
+
});
|
|
59
118
|
|
|
60
|
-
|
|
119
|
+
return ConstantSourceNode;
|
|
120
|
+
};
|