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/OscillatorNode.js
CHANGED
|
@@ -17,56 +17,198 @@
|
|
|
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
|
+
const {
|
|
37
|
+
bridgeEventTarget,
|
|
38
|
+
} = require('./lib/events.js');
|
|
39
|
+
/* eslint-enable no-unused-vars */
|
|
27
40
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
const EventTarget = EventTargetMixin(NativeOscillatorNode, ['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 OscillatorNode extends AudioScheduledSourceNode {
|
|
45
|
+
|
|
46
|
+
#frequency = null;
|
|
47
|
+
#detune = null;
|
|
48
|
+
|
|
35
49
|
constructor(context, options) {
|
|
36
|
-
|
|
37
|
-
|
|
50
|
+
|
|
51
|
+
if (arguments.length < 1) {
|
|
52
|
+
throw new TypeError(`Failed to construct 'OscillatorNode': 1 argument required, but only ${arguments.length} present`);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
if (!(context instanceof jsExport.BaseAudioContext)) {
|
|
56
|
+
throw new TypeError(`Failed to construct 'OscillatorNode': 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 \'OscillatorNode\': argument 2 is not of type \'OscillatorOptions\'');
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
if (options && options.type !== undefined) {
|
|
67
|
+
if (!['sine', 'square', 'sawtooth', 'triangle', 'custom'].includes(options.type)) {
|
|
68
|
+
throw new TypeError(`Failed to construct 'OscillatorNode': Failed to read the 'type' property from OscillatorOptions: The provided value '${options.type}' is not a valid enum value of type OscillatorType`);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
parsedOptions.type = conversions['DOMString'](options.type, {
|
|
72
|
+
context: `Failed to construct 'OscillatorNode': Failed to read the 'type' property from OscillatorOptions: The provided value '${options.type}'`,
|
|
73
|
+
});
|
|
74
|
+
} else {
|
|
75
|
+
parsedOptions.type = 'sine';
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
if (options && options.frequency !== undefined) {
|
|
79
|
+
parsedOptions.frequency = conversions['float'](options.frequency, {
|
|
80
|
+
context: `Failed to construct 'OscillatorNode': Failed to read the 'frequency' property from OscillatorOptions: The provided value (${options.frequency}})`,
|
|
81
|
+
});
|
|
82
|
+
} else {
|
|
83
|
+
parsedOptions.frequency = 440;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
if (options && options.detune !== undefined) {
|
|
87
|
+
parsedOptions.detune = conversions['float'](options.detune, {
|
|
88
|
+
context: `Failed to construct 'OscillatorNode': Failed to read the 'detune' property from OscillatorOptions: The provided value (${options.detune}})`,
|
|
89
|
+
});
|
|
90
|
+
} else {
|
|
91
|
+
parsedOptions.detune = 0;
|
|
38
92
|
}
|
|
39
93
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
94
|
+
if (options && options.periodicWave !== undefined) {
|
|
95
|
+
if (!(options.periodicWave instanceof jsExport.PeriodicWave)) {
|
|
96
|
+
throw new TypeError(`Failed to construct 'OscillatorNode': Failed to read the 'periodicWave' property from OscillatorOptions: The provided value '${options.periodicWave}' is not an instance of PeriodicWave`);
|
|
97
|
+
}
|
|
44
98
|
|
|
45
|
-
|
|
46
|
-
|
|
99
|
+
parsedOptions.periodicWave = options.periodicWave[kNapiObj];
|
|
100
|
+
} else {
|
|
101
|
+
parsedOptions.periodicWave = null;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
if (parsedOptions.type === 'custom' && parsedOptions.periodicWave === null) {
|
|
105
|
+
throw new DOMException('Failed to construct \'OscillatorNode\': A PeriodicWave must be specified if the type is set to \'custom\'', 'InvalidStateError');
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
if (parsedOptions.periodicWave !== null) {
|
|
109
|
+
parsedOptions.type = 'custom';
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
if (options && options.channelCount !== undefined) {
|
|
113
|
+
parsedOptions.channelCount = conversions['unsigned long'](options.channelCount, {
|
|
114
|
+
enforceRange: true,
|
|
115
|
+
context: `Failed to construct 'OscillatorNode': Failed to read the 'channelCount' property from OscillatorOptions: The provided value '${options.channelCount}'`,
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
if (options && options.channelCountMode !== undefined) {
|
|
120
|
+
parsedOptions.channelCountMode = conversions['DOMString'](options.channelCountMode, {
|
|
121
|
+
context: `Failed to construct 'OscillatorNode': Failed to read the 'channelCount' property from OscillatorOptions: The provided value '${options.channelCountMode}'`,
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
if (options && options.channelInterpretation !== undefined) {
|
|
126
|
+
parsedOptions.channelInterpretation = conversions['DOMString'](options.channelInterpretation, {
|
|
127
|
+
context: `Failed to construct 'OscillatorNode': Failed to read the 'channelInterpretation' property from OscillatorOptions: The provided value '${options.channelInterpretation}'`,
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
let napiObj;
|
|
132
|
+
|
|
133
|
+
try {
|
|
134
|
+
napiObj = new nativeBinding.OscillatorNode(context[kNapiObj], parsedOptions);
|
|
135
|
+
} catch (err) {
|
|
136
|
+
throwSanitizedError(err);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
super(context, {
|
|
140
|
+
[kNapiObj]: napiObj,
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
// Bridge Rust native event to Node EventTarget
|
|
144
|
+
bridgeEventTarget(this);
|
|
145
|
+
|
|
146
|
+
this.#frequency = new jsExport.AudioParam({
|
|
147
|
+
[kNapiObj]: this[kNapiObj].frequency,
|
|
148
|
+
});
|
|
149
|
+
this.#detune = new jsExport.AudioParam({
|
|
150
|
+
[kNapiObj]: this[kNapiObj].detune,
|
|
151
|
+
});
|
|
47
152
|
}
|
|
48
153
|
|
|
49
|
-
|
|
154
|
+
get frequency() {
|
|
155
|
+
if (!(this instanceof OscillatorNode)) {
|
|
156
|
+
throw new TypeError('Invalid Invocation: Value of \'this\' must be of type \'OscillatorNode\'');
|
|
157
|
+
}
|
|
50
158
|
|
|
51
|
-
|
|
52
|
-
return super.type;
|
|
159
|
+
return this.#frequency;
|
|
53
160
|
}
|
|
54
161
|
|
|
55
|
-
|
|
162
|
+
get detune() {
|
|
163
|
+
if (!(this instanceof OscillatorNode)) {
|
|
164
|
+
throw new TypeError('Invalid Invocation: Value of \'this\' must be of type \'OscillatorNode\'');
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
return this.#detune;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
get type() {
|
|
171
|
+
if (!(this instanceof OscillatorNode)) {
|
|
172
|
+
throw new TypeError('Invalid Invocation: Value of \'this\' must be of type \'OscillatorNode\'');
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
return this[kNapiObj].type;
|
|
176
|
+
}
|
|
56
177
|
|
|
57
178
|
set type(value) {
|
|
179
|
+
if (!(this instanceof OscillatorNode)) {
|
|
180
|
+
throw new TypeError('Invalid Invocation: Value of \'this\' must be of type \'OscillatorNode\'');
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
if (!['sine', 'square', 'sawtooth', 'triangle', 'custom'].includes(value)) {
|
|
184
|
+
console.warn(`Failed to set the 'type' property on 'OscillatorNode': Value '${value}' is not a valid 'OscillatorType' enum value`);
|
|
185
|
+
return;
|
|
186
|
+
}
|
|
187
|
+
|
|
58
188
|
try {
|
|
59
|
-
|
|
189
|
+
this[kNapiObj].type = value;
|
|
60
190
|
} catch (err) {
|
|
61
191
|
throwSanitizedError(err);
|
|
62
192
|
}
|
|
63
193
|
}
|
|
64
194
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
195
|
+
setPeriodicWave(periodicWave) {
|
|
196
|
+
if (!(this instanceof OscillatorNode)) {
|
|
197
|
+
throw new TypeError('Invalid Invocation: Value of \'this\' must be of type \'OscillatorNode\'');
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
if (arguments.length < 1) {
|
|
201
|
+
throw new TypeError(`Failed to execute 'setPeriodicWave' on 'OscillatorNode': 1 argument required, but only ${arguments.length} present`);
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
if (!(periodicWave instanceof jsExport.PeriodicWave)) {
|
|
205
|
+
throw new TypeError(`Failed to execute 'setPeriodicWave' on 'OscillatorNode': Parameter 1 is not of type 'PeriodicWave'`);
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
periodicWave = periodicWave[kNapiObj];
|
|
209
|
+
|
|
68
210
|
try {
|
|
69
|
-
return
|
|
211
|
+
return this[kNapiObj].setPeriodicWave(periodicWave);
|
|
70
212
|
} catch (err) {
|
|
71
213
|
throwSanitizedError(err);
|
|
72
214
|
}
|
|
@@ -74,8 +216,29 @@ module.exports = (NativeOscillatorNode) => {
|
|
|
74
216
|
|
|
75
217
|
}
|
|
76
218
|
|
|
77
|
-
|
|
78
|
-
|
|
219
|
+
Object.defineProperties(OscillatorNode, {
|
|
220
|
+
length: {
|
|
221
|
+
__proto__: null,
|
|
222
|
+
writable: false,
|
|
223
|
+
enumerable: false,
|
|
224
|
+
configurable: true,
|
|
225
|
+
value: 1,
|
|
226
|
+
},
|
|
227
|
+
});
|
|
79
228
|
|
|
229
|
+
Object.defineProperties(OscillatorNode.prototype, {
|
|
230
|
+
[Symbol.toStringTag]: {
|
|
231
|
+
__proto__: null,
|
|
232
|
+
writable: false,
|
|
233
|
+
enumerable: false,
|
|
234
|
+
configurable: true,
|
|
235
|
+
value: 'OscillatorNode',
|
|
236
|
+
},
|
|
237
|
+
frequency: kEnumerableProperty,
|
|
238
|
+
detune: kEnumerableProperty,
|
|
239
|
+
type: kEnumerableProperty,
|
|
240
|
+
setPeriodicWave: kEnumerableProperty,
|
|
241
|
+
});
|
|
80
242
|
|
|
81
|
-
|
|
243
|
+
return OscillatorNode;
|
|
244
|
+
};
|