@@ -709,16 +709,19 @@ Each {{BaseAudioContext}} has a unique
709709media element event task source</a>.
710710Additionally, a {{BaseAudioContext}} has several private slots <dfn attribute
711711for="BaseAudioContext">[[rendering thread state]]</dfn> and <dfn attribute
712- for="BaseAudioContext">[[control thread state]]</dfn> that take values from
713- {{AudioContextState}}, and that are both initially set to <code>"suspended"
714- </code>, and a private slot <dfn attribute for="BaseAudioContext">
715- [[render quantum size]]</dfn> that is an unsigned integer.
712+ for="BaseAudioContext">[[control thread state]]</dfn> that take values
713+ from {{AudioContextState}}, and that are both initially set to <code>"suspended"
714+ </code>, <dfn attribute for="BaseAudioContext">[[state before interruption]]
715+ </dfn> that also take values from {{AudioContextState}} and is initially set to
716+ `null` and a private slot <dfn attribute for="BaseAudioContext">[[render quantum
717+ size]]</dfn> that is an unsigned integer.
716718
717719<pre class="idl">
718720enum AudioContextState {
719721 "suspended",
720722 "running",
721- "closed"
723+ "closed",
724+ "interrupted"
722725};
723726</pre>
724727
@@ -746,6 +749,12 @@ enum AudioContextState {
746749 <td>
747750 This context has been released, and can no longer be used to
748751 process audio. All system audio resources have been released.
752+ <tr>
753+ <td>
754+ "<dfn>interrupted</dfn>"
755+ <td>
756+ This context is currently interrupted and cannot process audio
757+ until the [=interruption=] ends.
749758</table>
750759</div>
751760
@@ -1542,6 +1551,8 @@ Constructors</h4>
15421551
15431552 1. Set a {{[[rendering thread state]]}} to <code>suspended</code> on
15441553 |context|.
1554+
1555+ 1. Set {{[[state before interruption]]}} to `null` on |context|.
15451556
15461557 1. Let |messageChannel| be a new {{MessageChannel}}.
15471558
@@ -1960,28 +1971,50 @@ Methods</h4>
19601971 <span class="synchronous">When resume is called,
19611972 execute these steps:</span>
19621973
1963- 1. If [=this=]'s [=relevant global object=]'s [=associated Document=] is not [=fully active=] then return [=a promise rejected with=] "{{InvalidStateError}}" {{DOMException}}.
1974+ 1. If [=this=]'s [=relevant global object=]'s
1975+ [=associated Document=] is not [=fully active=] then return
1976+ [=a promise rejected with=] "{{InvalidStateError}}"
1977+ {{DOMException}}.
19641978
19651979 1. Let <var>promise</var> be a new Promise.
19661980
1967- 2 . If the {{[[control thread state]]}} on the
1981+ 1 . If the {{[[control thread state]]}} on the
19681982 {{AudioContext}} is <code>closed</code> reject the
19691983 promise with {{InvalidStateError}}, abort these steps,
19701984 returning <var>promise</var>.
19711985
1972- 3. Set {{[[suspended by user]]}} to <code>false</code>.
1986+ 1. Set {{[[suspended by user]]}} to <code>false</code>.
1987+
1988+ 1. If the context's {{BaseAudioContext/state}} attribute is
1989+ "{{AudioContextState/suspended}}" and the context's
1990+ {{[[control thread state]]}} is
1991+ "{{AudioContextState/interrupted}}", then:
19731992
1974- 4. If the context is not <a>allowed to start</a>, append
1975- <var>promise</var> to {{BaseAudioContext/[[pending promises]]}} and
1976- {{AudioContext/[[pending resume promises]]}} and abort these steps, returning
1977- <var>promise</var>.
1993+ 1. <a>Queue a media element task</a> to execute the following steps:
19781994
1979- 5. Set the {{[[control thread state]]}} on the
1980- {{AudioContext}} to <code>running</code>.
1995+ 1. Set the {{BaseAudioContext/state}} attribute of the
1996+ {{AudioContext}} to "{{AudioContextState/interrupted}}".
1997+
1998+ 1. Set the {{[[state before interruption]]}} slot to
1999+ "{{AudioContextState/running}}".
19812000
1982- 6. <a>Queue a control message</a> to resume the {{AudioContext}} with <var>promise</var>.
2001+ 1. [=Queue a media element task=] to [=fire an event=] named
2002+ {{BaseAudioContext/statechange}} at the {{AudioContext}}.
2003+
2004+ 1. Reject the promise with {{InvalidStateError}}, abort these
2005+ steps, returning <var>promise</var>.
19832006
1984- 7. Return <var>promise</var>.
2007+ 1. If the context is not <a>allowed to start</a>, append
2008+ <var>promise</var> to {{BaseAudioContext/[[pending promises]]}}
2009+ and {{AudioContext/[[pending resume promises]]}} and abort
2010+ these steps, returning <var>promise</var>.
2011+
2012+ 1. Set the {{[[control thread state]]}} on the {{AudioContext}} to
2013+ <code>running</code>.
2014+
2015+ 1. <a>Queue a control message</a> to resume the {{AudioContext}} with <var>promise</var>.
2016+
2017+ 1. Return <var>promise</var>.
19852018 </div>
19862019
19872020 <div id="context-resume" algorithm="run a control message in AudioContext">
@@ -2080,14 +2113,19 @@ Methods</h4>
20802113
20812114 1. Attempt to <a>release system resources</a>.
20822115
2083- 2. Set the {{[[rendering thread state]]}} on the {{AudioContext}} to <code>suspended</code>.
2116+ 1. If the {{[[rendering thread state]]}} on the {{AudioContext}} is
2117+ "{{AudioContextState/interrupted}}", <a>queue a media element
2118+ task</a> to set the {{[[state before interruption]]}} slot to
2119+ "{{AudioContextState/suspended}}".
20842120
2085- 3. <a href="https://html.spec.whatwg.org/multipage/media.html#queue-a-media-element-task">
2086- queue a media element task</a> to execute the following steps:
2121+ 1. Set the {{[[rendering thread state]]}} on the {{AudioContext}} to
2122+ "{{AudioContextState/suspended}}".
2123+
2124+ 1. <a>Queue a media element task</a> to execute the following steps:
20872125
20882126 1. Resolve <var>promise</var>.
20892127
2090- 2 . If the {{BaseAudioContext/state}}
2128+ 1 . If the {{BaseAudioContext/state}}
20912129 attribute of the {{AudioContext}} is not already "{{AudioContextState/suspended}}":
20922130
20932131 1. Set the {{BaseAudioContext/state}} attribute of the {{AudioContext}} to "{{AudioContextState/suspended}}".
@@ -4071,7 +4109,7 @@ Methods</h4>
40714109 scheduled parameter changes with times greater than or equal to
40724110 {{AudioParam/cancelAndHoldAtTime()/cancelTime!!argument}}. However, in addition, the automation
40734111 value that would have happened at {{AudioParam/cancelAndHoldAtTime()/cancelTime!!argument}} is
4074- then proprogated for all future time until other automation
4112+ then propagated for all future time until other automation
40754113 events are introduced.
40764114
40774115 The behavior of the timeline in the face of
@@ -11534,7 +11572,7 @@ and a <a>rendering thread</a>.
1153411572
1153511573The <dfn>control thread</dfn> is the thread from which the
1153611574{{AudioContext}} is instantiated, and from which authors
11537- manipulate the audio graph, that is, from where the operation on a
11575+ manipulate the audio graph, that is, from where the operations on a
1153811576{{BaseAudioContext}} are invoked. The <dfn>rendering thread</dfn>
1153911577is the thread on which the actual audio output is computed, in
1154011578reaction to the calls from the <a>control thread</a>. It can be a
@@ -11641,7 +11679,7 @@ The algorithm for rendering a block of audio from a {{BaseAudioContext}}
1164111679in the algorithm of <a href="#rendering-a-graph">rendering a graph</a>.
1164211680
1164311681The {{AudioContext}} <a>rendering thread</a> is driven by a
11644- <dfn>system-level audio callback</dfn>, that is periodically
11682+ <dfn>system-level audio callback</dfn>, that is periodically called
1164511683at regular intevals. Each call has a <dfn>system-level audio callback buffer
1164611684size</dfn>, which is a varying number of sample-frames that needs to be
1164711685computed on time before the next <a>system-level audio callback</a> arrives.
@@ -11961,6 +11999,103 @@ running the algorithm for an {{AudioNode}}, using an <a>input
1196111999buffer</a> and the value(s) of the {{AudioParam}}(s) of this
1196212000{{AudioNode}} as the input for this algorithm.
1196312001
12002+ <h3 id="interruption-handling">Handling an interruption on the {{AudioContext}}</h3>
12003+
12004+ An <dfn>interruption</dfn> is an event generated by the user agent when it needs
12005+ to halt audio playback for an {{AudioContext}}. For example, The user agent may
12006+ create an interruption when another application requests exclusive access to the
12007+ audio output hardware.
12008+
12009+ When an [=interruption=] happens, the user agent MUST <a>queue a control message</a>
12010+ to interrupt the {{AudioContext}}.
12011+
12012+ Running a <a>control message</a> to <dfn attribute for="AudioContext"
12013+ lt="interruption-start">interrupt an {{AudioContext}}</dfn> |context|
12014+ means running these steps on the <a>rendering thread</a>:
12015+
12016+ 1. If the |context|'s {{[[rendering thread state]]}} is
12017+ {{AudioContextState/closed}} or {{AudioContextState/interrupted}}, abort
12018+ these steps.
12019+
12020+ 1. If the |context|'s {{[[rendering thread state]]}} is
12021+ {{AudioContextState/running}}:
12022+
12023+ 1. Attempt to <a>release system resources</a>.
12024+
12025+ 1. [=Queue a media element task=] to execute the following steps:
12026+
12027+ 1. Set the |context|'s {{[[control thread state]]}} to
12028+ {{AudioContextState/interrupted}}.
12029+
12030+ 1. Set the |context|'s {{[[state before interruption]]}} slot to
12031+ "{{AudioContextState/running}}".
12032+
12033+ 1. [=Fire an event=] named {{BaseAudioContext/statechange}} at the
12034+ |context|.
12035+
12036+ 1. If the |context|'s {{[[rendering thread state]]}} is
12037+ {{AudioContextState/suspended}}:
12038+
12039+ 1. [=Queue a media element task=] to execute the following steps:
12040+
12041+ 1. Set the |context|'s {{[[control thread state]]}} to
12042+ {{AudioContextState/interrupted}}.
12043+
12044+ 1. Set the |context|'s {{[[state before interruption]]}} slot to
12045+ "{{AudioContextState/suspended}}".
12046+
12047+ 1. Set the |context|'s {{[[rendering thread state]]}} to
12048+ {{AudioContextState/interrupted}}.
12049+
12050+ Note: If the {{AudioContext}} is {{AudioContextState/suspended}} a
12051+ {{BaseAudioContext/statechange}} event is not fired for privacy reasons to avoid
12052+ over-sharing user activity - e.g. when a phone call comes in or when the screen
12053+ gets locked.
12054+
12055+ When an [=interruption=] ends, the user agent MUST <a>queue a control message</a>
12056+ to <dfn attribute for="AudioContext" lt="interruption-end">end the
12057+ {{AudioContext}} interruption</dfn>.
12058+
12059+ Running a <a>control message</a> to end an {{AudioContext}} |context|
12060+ [=interruption=] means running these steps on the <a>rendering thread</a>:
12061+
12062+ 1. If the |context|'s {{[[rendering thread state]]}} is not
12063+ {{AudioContextState/interrupted}}, abort these steps.
12064+
12065+ 1. If the |context|'s {{[[state before interruption]]}} is
12066+ "{{AudioContextState/running}}":
12067+
12068+ 1. Attempt to <a href="#acquiring">acquire system resources</a>.
12069+
12070+ 1. Set the {{[[rendering thread state]]}} on the {{AudioContext}} to
12071+ "{{AudioContextState/running}}".
12072+
12073+ 1. Start <a href="#rendering-loop">rendering the audio graph</a>.
12074+
12075+ 1. [=Queue a media element task=] to execute the following steps:
12076+
12077+ 1. If the {{BaseAudioContext/state}} attribute of the {{AudioContext}}
12078+ is not already "{{AudioContextState/running}}":
12079+
12080+ 1. Set the |context|'s {{[[control thread state]]}} to
12081+ "{{AudioContextState/running}}".
12082+
12083+ 1. [=Fire an event=] named {{BaseAudioContext/statechange}} at the
12084+ |context|.
12085+
12086+ 1. If the |context|'s {{[[state before interruption]]}} is
12087+ "{{AudioContextState/suspended}}"
12088+
12089+ 1. Set the {{[[rendering thread state]]}} on the {{AudioContext}} to
12090+ <code>suspended</code>.
12091+
12092+ 1. [=Queue a media element task=] to execute the following steps:
12093+
12094+ 1. Set the |context|'s {{[[control thread state]]}} to
12095+ <code>suspended</code>.
12096+
12097+ 1. Set the |context|'s {{[[state before interruption]]}} to `null`.
12098+
1196412099<h3 id="error-handling-on-a-running-audio-context">
1196512100 Handling an error from System Audio Resources on the {{AudioContext}}</h3>
1196612101
0 commit comments