-
Notifications
You must be signed in to change notification settings - Fork 3.4k
Fix Closure breaking AUDIO_WORKLET #22472
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix Closure breaking AUDIO_WORKLET #22472
Conversation
Looks great. Something that seems odd is that the browser test suite does have several AudioWorklet tests that do enable Closure, e.g. emscripten/test/test_browser.py Lines 5313 to 5350 in a19f7df
Any chance you'd be able to double check why those tests didn't catch this issue? And/or add/modify the tests there so that they would start failing before this fix? The fix itself looks solid. |
I'll take a look tomorrow (at a guess it silently fails, which is what the basic tests do). |
@juj I took a look at the tests you linked to and some of the individual parameterised tests fail to initialise the audio without this fix, e.g.:
And other tests fail for other reasons, e.g., missing
But running the original code with the test runner, none seems to flag as a failure. Though if I look at a complete run output I see that the worklet doesn't appear to be loaded for any of the tests:
In the end I ran each test individually, passed |
FYI, when you run just a single test, the output is always saved in |
This seems bad, I guess we need to improve the robustness of these test. Its hard I suppose because I'm not sure that we can actually run any actual, audio tests in CI (we run the browser tests with |
Yikes, something has definitely gone wrong then. I'll try to look at this tomorrow on how to make this more robust. Was this Closure change enough to get those tests to pass for you? |
The minimal runtime ones also fail, I’ll try to look at that tomorrow and roll it into this PR. |
I see there are multiple regressions to Audio Worklet usage from different PRs in the past months. I've got them fixed now in local tree, with interactive tests passing... I'll see what a good way to land these fixes will be. |
d3833d1
to
7fb6ddf
Compare
'ap': audioParams, | ||
'ch': contextHandle, | ||
'cb': callback, | ||
'ud': userData |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Makes me a bit sad that we have to do this in the source code rather than have the minifier tool do it... but I guess we don't have a better way.
Do we have any codesize test for audioworklets that can means that code size improvement here? If not maybe we should add one.
I wonder if we should do this in the pthreads code too? @juj what do you think of this technique?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks fine to me.
In general end users should never interact/snoop these postMessage()s, so their format should be strictly internal to the implementation. The only thing here is to make sure we generate messages that are not easy to confuse with user-sent messages - which I think manually mangled names make pretty clear it won't be anything that a user might have written.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So, IIUC, there is no difference between these mangled names and the existing _wsc
and _wpn
mangled names. Can we be consistent and use underscores either for all of them, or none?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One difference was that the _wsc
and _wpn
fields were the "keys" of the data object, used to identify what the postMessaged struct was. These other fields are the satellite data, that are assumed to be present when that one key field matches. That is why I initially only mangled and underscored that one field to make it clear that "that's the key, others are satellite" disposition.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fair enough, lgtm
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually I'm still a little confused. It looks like _wsc
and _wpn
are both fields the same object that ap
and ch
are part of.
For example I see registerProcessor(d['_wpn'], createWasmAudioWorkletProcessor(d['ap']));
where they are both fields of d
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the importance of _wpn
is that no other message is going to have such a property. There's a test, equivalent to
if (msg.data['_wpn']) {
I can imagine minified properties being called ap
, which might trigger a false positive, but it's unlikely there'd be a _wpn
.
So my take, I can see reasoning for the underscore here, but for anything else it's just extra characters.
src/audio_worklet.js
Outdated
// 'cb' is the callback function | ||
// 'ch' the context handle | ||
// 'ud' the passed user data | ||
p.postMessage({'_wsc': d['cb'], 'x': [d['ch'], 1/*EM_TRUE*/, d['ud']] }); // "WaSm Call" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Move the trailing comment here up above too?
Also, should we use a leading underscore for all of these or none of them? @juj do you remember why you add the underscore?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn't _wpn
part of the message name so could clash? Same as _wpn
, the worklet processor name.
There was already an existing x
in there so I didn't add underscores.
I did tidy the comments though because they repeat the same thing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@juj do you remember why you add the underscore?
Commented in #22472 (comment)
11af402
to
4136966
Compare
@juj Fixes also added for Tested manually but this works with combinations of Closure and minimal runtime. |
A better solution all round, sure. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd love to see a test for this in browser_tests.py
. Can we wait on this change until @juj has updated the audio_worklet tests to be more robust/accurate. IIUC they are currently passing erroneously despite some recent breakages.
lgtm though, @juj if you want to land this first thats fine with me to.
beea3b9
to
f76433b
Compare
This GitHub/CircleCI keeps on giving.. there was a test failure on build-test and test-browser-chrome due to the single offset converter test failure, which we know to be flaky. So I opened the test page, and clicked on "Re-run failed tests" to rerun the test-browser-chrome suite again. However that caused the test runner to re-run tons of other (already passing) suites, except that failing test-browser-chrome-suite that I wanted to rerun. And now other suites are failing with HTTP 500 No Fun for You. To me it seems that all relevant tests are passing, I'd be happy to land this PR. |
37a2737
to
f78e26e
Compare
f78e26e
to
a5eb47f
Compare
Run it enough times and it finally all passed! |
If building with
-sAUDIO_WORKLET
and--closure=1
the generated glue JS will minimise the property names passed to the worklet's message handler:emscripten/src/audio_worklet.js
Line 179 in 9445d6a
E.g. these are received as:
No sound will be generated as a result, since calls to
emscripten_create_wasm_audio_worklet_processor_async()
will never call the passed function.The quick fix being to add the names to the literal notation for the message (as per the commit). It might be worthwhile renaming the property names to something shorter though whilst making the changes.
Compiling any of the webaudio tests with
--closure
will reproduce the error:Links here for precompiled before and after. On the before test the 'Toggle playback' button doesn't get added because AudioWorkletProcessorCreated never gets called.