Skip to content

Commit 35faeb0

Browse files
committed
bug 1558123 call AudioWorkletProcessor.process() r=padenot,bzbarsky
https://heycam.github.io/webidl/#call-a-user-objects-operation may be a simpler option here, but there are some small optimizations possible with using JS::Call() directly: JS::ExposeObjectToActiveJS() is not necessary because parameters are PersistentRooted and so won't be gray. MaybeWrapObjectValue() is not necessary because parameters are already in the appropriate compartment. See also WebAudio/web-audio-api#1967 and WebAudio/web-audio-api#1933 Microtask support is tracked in https://bugzilla.mozilla.org/show_bug.cgi?id=1566312 Differential Revision: https://phabricator.services.mozilla.com/D34838 --HG-- extra : moz-landing-system : lando
1 parent 87d828f commit 35faeb0

File tree

2 files changed

+45
-7
lines changed

2 files changed

+45
-7
lines changed

dom/media/webaudio/AudioWorkletNode.cpp

Lines changed: 44 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,13 +63,16 @@ class WorkletNodeEngine final : public AudioNodeEngine {
6363

6464
private:
6565
void SendProcessorError();
66+
bool CallProcess(JSContext* aCx, JS::Handle<JS::Value> aCallable,
67+
bool* aActiveRet);
6668

6769
void ReleaseJSResources() {
6870
mInputs.mPorts.clearAndFree();
6971
mOutputs.mPorts.clearAndFree();
7072
mInputs.mJSArray.reset();
7173
mOutputs.mJSArray.reset();
7274
mGlobal = nullptr;
75+
// This is equivalent to setting [[callable process]] to false.
7376
mProcessor.reset();
7477
}
7578

@@ -231,6 +234,29 @@ static bool PrepareBufferArrays(JSContext* aCx, Span<const AudioBlock> aBlocks,
231234
return !(NS_WARN_IF(!PrepareArray(aCx, aPorts->mPorts, &aPorts->mJSArray)));
232235
}
233236

237+
// This runs JS script. MediaStreamGraph control messages, which would
238+
// potentially destroy the WorkletNodeEngine and its AudioNodeStream, cannot
239+
// be triggered by script. They are not run from an nsIThread event loop and
240+
// do not run until after ProcessBlocksOnPorts() has returned.
241+
bool WorkletNodeEngine::CallProcess(JSContext* aCx,
242+
JS::Handle<JS::Value> aCallable,
243+
bool* aActiveRet) {
244+
JS::RootedVector<JS::Value> argv(aCx);
245+
if (NS_WARN_IF(!argv.resize(3))) {
246+
return false;
247+
}
248+
argv[0].setObject(*mInputs.mJSArray);
249+
argv[1].setObject(*mOutputs.mJSArray);
250+
// TODO: argv[2].setObject() for parameters.
251+
JS::Rooted<JS::Value> rval(aCx);
252+
if (!JS::Call(aCx, mProcessor, aCallable, argv, &rval)) {
253+
return false;
254+
}
255+
256+
*aActiveRet = JS::ToBoolean(rval);
257+
return true;
258+
}
259+
234260
static void ProduceSilence(Span<AudioBlock> aOutput) {
235261
for (AudioBlock& output : aOutput) {
236262
output.SetNull(WEBAUDIO_BLOCK_SIZE);
@@ -262,9 +288,12 @@ void WorkletNodeEngine::ProcessBlocksOnPorts(AudioNodeStream* aStream,
262288
AutoEntryScript aes(mGlobal, "Worklet Process");
263289
JSContext* cx = aes.cx();
264290

265-
if (!PrepareBufferArrays(cx, aInput, &mInputs, ArrayElementInit::None) ||
291+
JS::Rooted<JS::Value> process(cx);
292+
if (!JS_GetProperty(cx, mProcessor, "process", &process) ||
293+
!process.isObject() || !JS::IsCallable(&process.toObject()) ||
294+
!PrepareBufferArrays(cx, aInput, &mInputs, ArrayElementInit::None) ||
266295
!PrepareBufferArrays(cx, aOutput, &mOutputs, ArrayElementInit::Zero)) {
267-
// OOM. Give up.
296+
// process() not callable or OOM.
268297
SendProcessorError();
269298
ProduceSilence(aOutput);
270299
return;
@@ -291,7 +320,19 @@ void WorkletNodeEngine::ProcessBlocksOnPorts(AudioNodeStream* aStream,
291320
}
292321
}
293322

294-
// TODO call process() - bug 1558123
323+
bool active;
324+
if (!CallProcess(cx, process, &active)) {
325+
// An exception occurred.
326+
SendProcessorError();
327+
/**
328+
* https://webaudio.github.io/web-audio-api/#dom-audioworkletnode-onprocessorerror
329+
* Note that once an exception is thrown, the processor will output silence
330+
* throughout its lifetime.
331+
*/
332+
ProduceSilence(aOutput);
333+
return;
334+
}
335+
// TODO: Stay active even without inputs, if active is set.
295336

296337
// Copy output values from JS objects.
297338
for (size_t o = 0; o < aOutput.Length(); ++o) {

testing/web-platform/meta/webaudio/the-audio-api/the-audioworklet-interface/simple-input-output.https.html.ini

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,9 @@
44
[# AUDIT TASK RUNNER FINISHED: 1 out of 2 tasks were failed.]
55
expected: FAIL
66

7-
[< [test\] 2 out of 2 assertions were failed.]
7+
[< [test\] 1 out of 2 assertions were failed.]
88
expected: FAIL
99

1010
[X AudioWorklet output[128:\]: Expected 1 for all values but found 47872 unexpected values: \n\tIndex\tActual\n\t[0\]\t0\n\t[1\]\t0\n\t[2\]\t0\n\t[3\]\t0\n\t...and 47868 more errors.]
1111
expected: FAIL
1212

13-
[X AudioWorklet output[0:127\] does not equal [1,1.0575640201568604,1.11493718624115,1.171929121017456,1.2283508777618408,1.2840152978897095,1.3387378454208374,1.3923370838165283,1.4446351528167725,1.4954586029052734,1.5446388721466064,1.5920131206512451,1.6374238729476929,1.6807208061218262,1.7217600345611572,1.7604057788848877...\] with an element-wise tolerance of {"absoluteThreshold":0,"relativeThreshold":0}.\n\tIndex\tActual\t\t\tExpected\t\tAbsError\t\tRelError\t\tTest threshold\n\t[0\]\t0.0000000000000000e+0\t1.0000000000000000e+0\t1.0000000000000000e+0\t1.0000000000000000e+0\t0.0000000000000000e+0\n\t[1\]\t0.0000000000000000e+0\t1.0575640201568604e+0\t1.0575640201568604e+0\t1.0000000000000000e+0\t0.0000000000000000e+0\n\t[2\]\t0.0000000000000000e+0\t1.1149371862411499e+0\t1.1149371862411499e+0\t1.0000000000000000e+0\t0.0000000000000000e+0\n\t[3\]\t0.0000000000000000e+0\t1.1719291210174561e+0\t1.1719291210174561e+0\t1.0000000000000000e+0\t0.0000000000000000e+0\n\t[4\]\t0.0000000000000000e+0\t1.2283508777618408e+0\t1.2283508777618408e+0\t1.0000000000000000e+0\t0.0000000000000000e+0\n\t...and 123 more errors.\n\tMax AbsError of 1.9998766183853149e+0 at index of 27.\n\t[27\]\t0.0000000000000000e+0\t1.9998766183853149e+0\t1.9998766183853149e+0\t1.0000000000000000e+0\t0.0000000000000000e+0\n\tMax RelError of 1.0000000000000000e+0 at index of 0.\n]
14-
expected: FAIL
15-

0 commit comments

Comments
 (0)