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/Events.js
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
const { kEnumerableProperty } = require('./lib/utils.js');
|
|
2
|
+
|
|
3
|
+
class OfflineAudioCompletionEvent extends Event {
|
|
4
|
+
#renderedBuffer = null;
|
|
5
|
+
|
|
6
|
+
constructor(type, eventInitDict) {
|
|
7
|
+
super(type);
|
|
8
|
+
|
|
9
|
+
if (typeof eventInitDict !== 'object' || eventInitDict === null || !('renderedBuffer' in eventInitDict)) {
|
|
10
|
+
throw TypeError(`Failed to construct 'OfflineAudioCompletionEvent': Failed to read the 'renderedBuffer' property from 'OfflineAudioCompletionEvent': Required member is undefined.`);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
this.#renderedBuffer = eventInitDict.renderedBuffer;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
get renderedBuffer() {
|
|
17
|
+
return this.#renderedBuffer;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
Object.defineProperties(OfflineAudioCompletionEvent.prototype, {
|
|
22
|
+
[Symbol.toStringTag]: {
|
|
23
|
+
__proto__: null,
|
|
24
|
+
writable: false,
|
|
25
|
+
enumerable: false,
|
|
26
|
+
configurable: true,
|
|
27
|
+
value: 'OfflineAudioCompletionEvent',
|
|
28
|
+
},
|
|
29
|
+
|
|
30
|
+
renderedBuffer: kEnumerableProperty,
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
class AudioProcessingEvent extends Event {
|
|
34
|
+
#playbackTime = null;
|
|
35
|
+
#inputBuffer = null;
|
|
36
|
+
#outputBuffer = null;
|
|
37
|
+
|
|
38
|
+
constructor(type, eventInitDict) {
|
|
39
|
+
if (
|
|
40
|
+
typeof eventInitDict !== 'object'
|
|
41
|
+
|| eventInitDict === null
|
|
42
|
+
|| !('playbackTime' in eventInitDict)
|
|
43
|
+
|| !('inputBuffer' in eventInitDict)
|
|
44
|
+
|| !('outputBuffer' in eventInitDict)
|
|
45
|
+
) {
|
|
46
|
+
throw TypeError(`Failed to construct 'AudioProcessingEvent': Invalid 'AudioProcessingEventInit' given`);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
super(type);
|
|
50
|
+
|
|
51
|
+
this.#playbackTime = eventInitDict.playbackTime;
|
|
52
|
+
this.#inputBuffer = eventInitDict.inputBuffer;
|
|
53
|
+
this.#outputBuffer = eventInitDict.outputBuffer;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
get playbackTime() {
|
|
57
|
+
return this.#playbackTime;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
get inputBuffer() {
|
|
61
|
+
return this.#inputBuffer;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
get outputBuffer() {
|
|
65
|
+
return this.#outputBuffer;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
Object.defineProperties(AudioProcessingEvent.prototype, {
|
|
70
|
+
[Symbol.toStringTag]: {
|
|
71
|
+
__proto__: null,
|
|
72
|
+
writable: false,
|
|
73
|
+
enumerable: false,
|
|
74
|
+
configurable: true,
|
|
75
|
+
value: 'AudioProcessingEvent',
|
|
76
|
+
},
|
|
77
|
+
|
|
78
|
+
playbackTime: kEnumerableProperty,
|
|
79
|
+
inputBuffer: kEnumerableProperty,
|
|
80
|
+
outputBuffer: kEnumerableProperty,
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
module.exports.OfflineAudioCompletionEvent = OfflineAudioCompletionEvent;
|
|
84
|
+
module.exports.AudioProcessingEvent = AudioProcessingEvent;
|
package/js/GainNode.js
CHANGED
|
@@ -17,40 +17,123 @@
|
|
|
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 GainNode extends AudioNode {
|
|
29
42
|
|
|
30
|
-
|
|
31
|
-
const AudioNode = AudioNodeMixin(EventTarget);
|
|
43
|
+
#gain = null;
|
|
32
44
|
|
|
33
|
-
class GainNode extends AudioNode {
|
|
34
45
|
constructor(context, options) {
|
|
35
|
-
|
|
36
|
-
|
|
46
|
+
|
|
47
|
+
if (arguments.length < 1) {
|
|
48
|
+
throw new TypeError(`Failed to construct 'GainNode': 1 argument required, but only ${arguments.length} present`);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
if (!(context instanceof jsExport.BaseAudioContext)) {
|
|
52
|
+
throw new TypeError(`Failed to construct 'GainNode': 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 \'GainNode\': argument 2 is not of type \'GainOptions\'');
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
if (options && options.gain !== undefined) {
|
|
63
|
+
parsedOptions.gain = conversions['float'](options.gain, {
|
|
64
|
+
context: `Failed to construct 'GainNode': Failed to read the 'gain' property from GainOptions: The provided value (${options.gain}})`,
|
|
65
|
+
});
|
|
66
|
+
} else {
|
|
67
|
+
parsedOptions.gain = 1.0;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
if (options && options.channelCount !== undefined) {
|
|
71
|
+
parsedOptions.channelCount = conversions['unsigned long'](options.channelCount, {
|
|
72
|
+
enforceRange: true,
|
|
73
|
+
context: `Failed to construct 'GainNode': Failed to read the 'channelCount' property from GainOptions: The provided value '${options.channelCount}'`,
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
if (options && options.channelCountMode !== undefined) {
|
|
78
|
+
parsedOptions.channelCountMode = conversions['DOMString'](options.channelCountMode, {
|
|
79
|
+
context: `Failed to construct 'GainNode': Failed to read the 'channelCount' property from GainOptions: The provided value '${options.channelCountMode}'`,
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
if (options && options.channelInterpretation !== undefined) {
|
|
84
|
+
parsedOptions.channelInterpretation = conversions['DOMString'](options.channelInterpretation, {
|
|
85
|
+
context: `Failed to construct 'GainNode': Failed to read the 'channelInterpretation' property from GainOptions: The provided value '${options.channelInterpretation}'`,
|
|
86
|
+
});
|
|
37
87
|
}
|
|
38
88
|
|
|
39
|
-
|
|
89
|
+
let napiObj;
|
|
40
90
|
|
|
41
|
-
|
|
91
|
+
try {
|
|
92
|
+
napiObj = new nativeBinding.GainNode(context[kNapiObj], parsedOptions);
|
|
93
|
+
} catch (err) {
|
|
94
|
+
throwSanitizedError(err);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
super(context, {
|
|
98
|
+
[kNapiObj]: napiObj,
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
this.#gain = new jsExport.AudioParam({
|
|
102
|
+
[kNapiObj]: this[kNapiObj].gain,
|
|
103
|
+
});
|
|
42
104
|
}
|
|
43
105
|
|
|
44
|
-
|
|
106
|
+
get gain() {
|
|
107
|
+
if (!(this instanceof GainNode)) {
|
|
108
|
+
throw new TypeError('Invalid Invocation: Value of \'this\' must be of type \'GainNode\'');
|
|
109
|
+
}
|
|
45
110
|
|
|
46
|
-
|
|
111
|
+
return this.#gain;
|
|
112
|
+
}
|
|
47
113
|
|
|
48
|
-
// methods
|
|
49
|
-
|
|
50
114
|
}
|
|
51
115
|
|
|
52
|
-
|
|
53
|
-
|
|
116
|
+
Object.defineProperties(GainNode, {
|
|
117
|
+
length: {
|
|
118
|
+
__proto__: null,
|
|
119
|
+
writable: false,
|
|
120
|
+
enumerable: false,
|
|
121
|
+
configurable: true,
|
|
122
|
+
value: 1,
|
|
123
|
+
},
|
|
124
|
+
});
|
|
54
125
|
|
|
126
|
+
Object.defineProperties(GainNode.prototype, {
|
|
127
|
+
[Symbol.toStringTag]: {
|
|
128
|
+
__proto__: null,
|
|
129
|
+
writable: false,
|
|
130
|
+
enumerable: false,
|
|
131
|
+
configurable: true,
|
|
132
|
+
value: 'GainNode',
|
|
133
|
+
},
|
|
134
|
+
gain: kEnumerableProperty,
|
|
55
135
|
|
|
56
|
-
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
return GainNode;
|
|
139
|
+
};
|
package/js/IIRFilterNode.js
CHANGED
|
@@ -17,38 +17,132 @@
|
|
|
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(NativeIIRFilterNode);
|
|
31
|
-
const AudioNode = AudioNodeMixin(EventTarget);
|
|
32
|
-
|
|
40
|
+
module.exports = (jsExport, nativeBinding) => {
|
|
33
41
|
class IIRFilterNode extends AudioNode {
|
|
42
|
+
|
|
34
43
|
constructor(context, options) {
|
|
35
|
-
|
|
36
|
-
|
|
44
|
+
|
|
45
|
+
if (arguments.length < 2) {
|
|
46
|
+
throw new TypeError(`Failed to construct 'IIRFilterNode': 2 argument required, but only ${arguments.length} present`);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
if (!(context instanceof jsExport.BaseAudioContext)) {
|
|
50
|
+
throw new TypeError(`Failed to construct 'IIRFilterNode': argument 1 is not of type BaseAudioContext`);
|
|
51
|
+
}
|
|
52
|
+
|
|
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 \'IIRFilterNode\': argument 2 is not of type \'IIRFilterOptions\'');
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// required options
|
|
61
|
+
if (typeof options !== 'object' || (options && options.feedforward === undefined)) {
|
|
62
|
+
throw new TypeError('Failed to construct \'IIRFilterNode\': Failed to read the \'feedforward\' property from IIRFilterOptions: Required member is undefined');
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
if (options && options.feedforward !== undefined) {
|
|
66
|
+
try {
|
|
67
|
+
parsedOptions.feedforward = toSanitizedSequence(options.feedforward, Float64Array);
|
|
68
|
+
} catch (err) {
|
|
69
|
+
throw new TypeError(`Failed to construct 'IIRFilterNode': Failed to read the 'feedforward' property from IIRFilterOptions: The provided value ${err.message}`);
|
|
70
|
+
}
|
|
71
|
+
} else {
|
|
72
|
+
parsedOptions.feedforward = null;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// required options
|
|
76
|
+
if (typeof options !== 'object' || (options && options.feedback === undefined)) {
|
|
77
|
+
throw new TypeError('Failed to construct \'IIRFilterNode\': Failed to read the \'feedback\' property from IIRFilterOptions: Required member is undefined');
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
if (options && options.feedback !== undefined) {
|
|
81
|
+
try {
|
|
82
|
+
parsedOptions.feedback = toSanitizedSequence(options.feedback, Float64Array);
|
|
83
|
+
} catch (err) {
|
|
84
|
+
throw new TypeError(`Failed to construct 'IIRFilterNode': Failed to read the 'feedback' property from IIRFilterOptions: The provided value ${err.message}`);
|
|
85
|
+
}
|
|
86
|
+
} else {
|
|
87
|
+
parsedOptions.feedback = null;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
if (options && options.channelCount !== undefined) {
|
|
91
|
+
parsedOptions.channelCount = conversions['unsigned long'](options.channelCount, {
|
|
92
|
+
enforceRange: true,
|
|
93
|
+
context: `Failed to construct 'IIRFilterNode': Failed to read the 'channelCount' property from IIRFilterOptions: The provided value '${options.channelCount}'`,
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
if (options && options.channelCountMode !== undefined) {
|
|
98
|
+
parsedOptions.channelCountMode = conversions['DOMString'](options.channelCountMode, {
|
|
99
|
+
context: `Failed to construct 'IIRFilterNode': Failed to read the 'channelCount' property from IIRFilterOptions: The provided value '${options.channelCountMode}'`,
|
|
100
|
+
});
|
|
37
101
|
}
|
|
38
102
|
|
|
39
|
-
|
|
103
|
+
if (options && options.channelInterpretation !== undefined) {
|
|
104
|
+
parsedOptions.channelInterpretation = conversions['DOMString'](options.channelInterpretation, {
|
|
105
|
+
context: `Failed to construct 'IIRFilterNode': Failed to read the 'channelInterpretation' property from IIRFilterOptions: The provided value '${options.channelInterpretation}'`,
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
let napiObj;
|
|
110
|
+
|
|
111
|
+
try {
|
|
112
|
+
napiObj = new nativeBinding.IIRFilterNode(context[kNapiObj], parsedOptions);
|
|
113
|
+
} catch (err) {
|
|
114
|
+
throwSanitizedError(err);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
super(context, {
|
|
118
|
+
[kNapiObj]: napiObj,
|
|
119
|
+
});
|
|
40
120
|
|
|
41
121
|
}
|
|
42
122
|
|
|
43
|
-
|
|
123
|
+
getFrequencyResponse(frequencyHz, magResponse, phaseResponse) {
|
|
124
|
+
if (!(this instanceof IIRFilterNode)) {
|
|
125
|
+
throw new TypeError('Invalid Invocation: Value of \'this\' must be of type \'IIRFilterNode\'');
|
|
126
|
+
}
|
|
44
127
|
|
|
45
|
-
|
|
128
|
+
if (arguments.length < 3) {
|
|
129
|
+
throw new TypeError(`Failed to execute 'getFrequencyResponse' on 'IIRFilterNode': 3 argument required, but only ${arguments.length} present`);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
if (!(frequencyHz instanceof Float32Array)) {
|
|
133
|
+
throw new TypeError(`Failed to execute 'getFrequencyResponse' on 'IIRFilterNode': Parameter 1 is not of type 'Float32Array'`);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
if (!(magResponse instanceof Float32Array)) {
|
|
137
|
+
throw new TypeError(`Failed to execute 'getFrequencyResponse' on 'IIRFilterNode': Parameter 2 is not of type 'Float32Array'`);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
if (!(phaseResponse instanceof Float32Array)) {
|
|
141
|
+
throw new TypeError(`Failed to execute 'getFrequencyResponse' on 'IIRFilterNode': Parameter 3 is not of type 'Float32Array'`);
|
|
142
|
+
}
|
|
46
143
|
|
|
47
|
-
// methods
|
|
48
|
-
|
|
49
|
-
getFrequencyResponse(...args) {
|
|
50
144
|
try {
|
|
51
|
-
return
|
|
145
|
+
return this[kNapiObj].getFrequencyResponse(frequencyHz, magResponse, phaseResponse);
|
|
52
146
|
} catch (err) {
|
|
53
147
|
throwSanitizedError(err);
|
|
54
148
|
}
|
|
@@ -56,8 +150,27 @@ module.exports = (NativeIIRFilterNode) => {
|
|
|
56
150
|
|
|
57
151
|
}
|
|
58
152
|
|
|
59
|
-
|
|
60
|
-
|
|
153
|
+
Object.defineProperties(IIRFilterNode, {
|
|
154
|
+
length: {
|
|
155
|
+
__proto__: null,
|
|
156
|
+
writable: false,
|
|
157
|
+
enumerable: false,
|
|
158
|
+
configurable: true,
|
|
159
|
+
value: 2,
|
|
160
|
+
},
|
|
161
|
+
});
|
|
162
|
+
|
|
163
|
+
Object.defineProperties(IIRFilterNode.prototype, {
|
|
164
|
+
[Symbol.toStringTag]: {
|
|
165
|
+
__proto__: null,
|
|
166
|
+
writable: false,
|
|
167
|
+
enumerable: false,
|
|
168
|
+
configurable: true,
|
|
169
|
+
value: 'IIRFilterNode',
|
|
170
|
+
},
|
|
61
171
|
|
|
172
|
+
getFrequencyResponse: kEnumerableProperty,
|
|
173
|
+
});
|
|
62
174
|
|
|
63
|
-
|
|
175
|
+
return IIRFilterNode;
|
|
176
|
+
};
|
|
@@ -17,43 +17,99 @@
|
|
|
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(NativeMediaStreamAudioSourceNode);
|
|
31
|
-
const AudioNode = AudioNodeMixin(EventTarget);
|
|
32
|
-
|
|
40
|
+
module.exports = (jsExport, nativeBinding) => {
|
|
33
41
|
class MediaStreamAudioSourceNode extends AudioNode {
|
|
42
|
+
|
|
34
43
|
constructor(context, options) {
|
|
35
|
-
|
|
36
|
-
|
|
44
|
+
|
|
45
|
+
if (arguments.length < 2) {
|
|
46
|
+
throw new TypeError(`Failed to construct 'MediaStreamAudioSourceNode': 2 argument required, but only ${arguments.length} present`);
|
|
37
47
|
}
|
|
38
48
|
|
|
39
|
-
|
|
49
|
+
if (!(context instanceof jsExport.AudioContext)) {
|
|
50
|
+
throw new TypeError(`Failed to construct 'MediaStreamAudioSourceNode': argument 1 is not of type AudioContext`);
|
|
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 \'MediaStreamAudioSourceNode\': argument 2 is not of type \'MediaStreamAudioSourceOptions\'');
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// required options
|
|
61
|
+
if (typeof options !== 'object' || (options && options.mediaStream === undefined)) {
|
|
62
|
+
throw new TypeError('Failed to construct \'MediaStreamAudioSourceNode\': Failed to read the \'mediaStream\' property from MediaStreamAudioSourceOptions: Required member is undefined');
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
parsedOptions.mediaStream = options.mediaStream;
|
|
66
|
+
|
|
67
|
+
let napiObj;
|
|
68
|
+
|
|
69
|
+
try {
|
|
70
|
+
napiObj = new nativeBinding.MediaStreamAudioSourceNode(context[kNapiObj], parsedOptions);
|
|
71
|
+
} catch (err) {
|
|
72
|
+
throwSanitizedError(err);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
super(context, {
|
|
76
|
+
[kNapiObj]: napiObj,
|
|
77
|
+
});
|
|
44
78
|
|
|
45
|
-
get mediaStream() {
|
|
46
|
-
return super.mediaStream;
|
|
47
79
|
}
|
|
48
80
|
|
|
49
|
-
|
|
81
|
+
get mediaStream() {
|
|
82
|
+
if (!(this instanceof MediaStreamAudioSourceNode)) {
|
|
83
|
+
throw new TypeError('Invalid Invocation: Value of \'this\' must be of type \'MediaStreamAudioSourceNode\'');
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
return this[kNapiObj].mediaStream;
|
|
87
|
+
}
|
|
50
88
|
|
|
51
|
-
// methods
|
|
52
|
-
|
|
53
89
|
}
|
|
54
90
|
|
|
55
|
-
|
|
56
|
-
|
|
91
|
+
Object.defineProperties(MediaStreamAudioSourceNode, {
|
|
92
|
+
length: {
|
|
93
|
+
__proto__: null,
|
|
94
|
+
writable: false,
|
|
95
|
+
enumerable: false,
|
|
96
|
+
configurable: true,
|
|
97
|
+
value: 2,
|
|
98
|
+
},
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
Object.defineProperties(MediaStreamAudioSourceNode.prototype, {
|
|
102
|
+
[Symbol.toStringTag]: {
|
|
103
|
+
__proto__: null,
|
|
104
|
+
writable: false,
|
|
105
|
+
enumerable: false,
|
|
106
|
+
configurable: true,
|
|
107
|
+
value: 'MediaStreamAudioSourceNode',
|
|
108
|
+
},
|
|
57
109
|
|
|
110
|
+
mediaStream: kEnumerableProperty,
|
|
58
111
|
|
|
59
|
-
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
return MediaStreamAudioSourceNode;
|
|
115
|
+
};
|