WebAudio / web-audio-api

The Web Audio API v1.0, developed by the W3C Audio WG
https://webaudio.github.io/web-audio-api/
Other
1.04k stars 165 forks source link

Can ASSN.start() start an AudioContext that would otherwise not be allowed to start? #2588

Open majaha opened 1 month ago

majaha commented 1 month ago

In the specification for the AudioScheduledSourceNode start() method, step 5 says this:

  1. Send a control message to the associated AudioContext to start running its rendering thread only when all the following conditions are met:

    1. The context’s [[control thread state]] is "suspended".

    2. The context is allowed to start.

    3. [[suspended by user]] flag is false.

    NOTE: This allows start() to start an AudioContext that would otherwise not be allowed to start.

But 5.2 seems to directly contradict the NOTE underneath. Maybe I'm missing something, but I don't see how both can be true at once. At the very least, it's confusing.

A similar note appears in the AudioBufferSourceNode start() method steps.

In my testing in Firefox and Chrome, the start() method does not allow you to start an AudioContext without a user interaction, so it's the NOTE that disagrees with implementations. And that's what makes sense for preventing Autoplay, too.

The NOTE seems to have been added in https://github.com/WebAudio/web-audio-api/commit/d3607084e71ea54c2d2735f7c540b7c54990015f, but I can't work out what the intention was.

padenot commented 3 weeks ago

Teleconf 2024-06-11: let's rephrase the note. The intent here is that start(...) can be used to start an AudioContext that was otherwise prevented to start.

majaha commented 3 weeks ago

Thanks for looking into it.

I'm still having trouble understanding though. Could you give an example of how an AudioContext can be prevented from starting, but could still be started by AudioScheduledSourceNode.start()?

padenot commented 3 weeks ago

If the implementation decides that (e.g.) a click, touch or key press flips the allowed to start check, then it checks out. From within the handler, you can call .start(...), and the AudioContext resumes. Otherwise, the only way to resume an AudioContext that did not start automatically is to explicitly call resume() from a touch/click/key handler.

This is what is implemented in at least two implementations, here's Firefox's:

https://searchfox.org/mozilla-central/source/dom/media/webaudio/AudioBufferSourceNode.cpp#714 https://searchfox.org/mozilla-central/source/dom/media/webaudio/AudioContext.cpp#212

majaha commented 3 weeks ago

Ah, I think I get what you mean now. Would the note be more correct if it said:

NOTE: This can allow start() to start an AudioContext that is currently allowed to start, but has previously been prevented from starting.

majaha commented 3 weeks ago

I amended my PR to say that, if that seems good to you: https://github.com/WebAudio/web-audio-api/pull/2589