@@ -6035,6 +6035,19 @@ <h2 id="AudioWorklet-concepts">
6035
6035
"#widl-AudioWorkletGlobalScope-registerProcessor-void-DOMString-name-VoidFunction-processorCtor">
6036
6036
registerProcessor</a> method is called.
6037
6037
</dd>
6038
+ <dt>
6039
+ <dfn>node name to parameter descriptor map</dfn>
6040
+ </dt>
6041
+ <dd>
6042
+ Belongs to <a>BaseAudioContext</a>. This map contains an
6043
+ identical set of string keys from <a>node name to processor
6044
+ definition map</a> that are associated with the matching
6045
+ <a>parameterDescriptors</a> values. This internal storage is
6046
+ populated when a promise from <a href=
6047
+ "https://drafts.css-houdini.org/worklets/#dom-worklet-addmodule">addModule()</a>
6048
+ on <a href="#widl-Window-audioWorklet">audioWorklet</a> gets
6049
+ resolved.
6050
+ </dd>
6038
6051
</dl>
6039
6052
<pre class="example" title=
6040
6053
"Registering an AudioWorkletProcessor class definition">
@@ -6453,8 +6466,8 @@ <h2 id="defining-a-valid-audioworkletprocessor">
6453
6466
<a>AudioWorkletProcessor</a>. The subclass MUST define a method
6454
6467
named <code>process()</code> that implements the audio processing
6455
6468
algorithm and have a valid static property named
6456
- <code>parameterDescriptors</code> which is an iterable of
6457
- <a>AudioParamDescriptor</a> that is looked up by the
6469
+ <dfn>< code>parameterDescriptors</code></dfn> which is an iterable
6470
+ of <a>AudioParamDescriptor</a> that is looked up by the
6458
6471
<a>AudioWorkletProcessor</a> constructor to create instances of
6459
6472
<a>AudioParam</a> in the <code>parameters</code> maplike storage
6460
6473
in the node. The step 5 and 6 of <a href=
@@ -6693,92 +6706,147 @@ <h2 id="instantiation-of-AudioWorkletNode-and-AudioWorkletProcessor">
6693
6706
<a>AudioWorkletNode</a> instance is destroyed.
6694
6707
</p>
6695
6708
<p>
6696
- When <a>AudioWorkletNode</a>(<var>context</var>, <var>name</var>,
6697
- <var>options</var>) constructor is called, the user agent MUST run
6698
- the following steps <a data-lt="atomic">atomically</a>.
6709
+ Note that the instantiation of these two objects spans the control
6710
+ thread and the rendering thread.
6711
+ </p>
6712
+ <p>
6713
+ When <a>AudioWorkletNode</a>(<var>context</var>,
6714
+ <var>nodeName</var>, <var>options</var>) constructor is invoked,
6715
+ the user agent MUST perform the following steps on the control
6716
+ thread, where the constructor was called.
6699
6717
</p>
6700
6718
<ol>
6701
6719
<li>Let <var>this</var> be the instance being created by
6702
6720
constructor of <a>AudioWorkletNode</a> or its subclass.
6703
6721
</li>
6704
- <li>If <var>name </var> does not exists as a key in the
6705
- <a>AudioWorkletGlobalScope </a>’s <a>node name to processor
6706
- definition map</a>, throw a <code>NotSupportedError</code>
6707
- exception and abort these steps.
6722
+ <li>If <var>nodeName </var> does not exists as a key in the
6723
+ <a>BaseAudioContext </a>’s <a>node name to parameter descriptor
6724
+ map</a>, throw a <code>NotSupportedError</code> exception and abort
6725
+ these steps.
6708
6726
</li>
6709
- <li>Let <var>processorConstructor</var> be the result of looking up
6710
- <var>name</var> on the <a>AudioWorkletGlobalScope</a>’s <a>node
6711
- name to processor definition map</a>.
6727
+ <li>Let <var>node</var> be a new <a>AudioWorkletNode</a> object.
6728
+ </li>
6729
+ <li>Let <var>messageChannel</var> be a new <a href=
6730
+ "https://html.spec.whatwg.org/multipage/#message-channels">MessageChannel</a>.
6731
+ </li>
6732
+ <li>Let <var>nodePort</var> be the value of
6733
+ <var>messageChannel</var>'s <code>port1</code> attribute.
6712
6734
</li>
6713
- <li>Let <var>processorInstance</var> be the result of <a href=
6714
- "http://www.ecma-international.org/ecma-262/6.0/#sec-construct">Construct</a>(<var>processorConstructor</var>,
6715
- <var>« options »</var>). The argument list <var>options</var> is
6716
- serialized using the <a href=
6717
- "http://w3c.github.io/html/infrastructure.html#safe-passing-of-structured-data">
6718
- structured clone</a> algorithm.
6735
+ <li>Let <var>processorPortOnThisSide</var> be the value of
6736
+ <var>messageChannel</var>'s <code>port2</code> attribute.
6719
6737
</li>
6720
- <li>Let <var>parameterDescriptors </var> be the result of <a href=
6721
- "https://tc39.github.io/ecma262/#sec-get-o-p">Get</a>(O=<var>processorConstructor</var>,
6722
- P="parameterDescriptors"). If < var>parameterDescriptors </var> is
6723
- <code>undefined</code>, skip to the step 8 .
6738
+ <li>Let <var>processorPortSerialization </var> be <a href=
6739
+ "https://html.spec.whatwg.org/multipage/infrastructure.html#structuredserializewithtransfer">
6740
+ StructuredSerializeWithTransfer</a>(< var>processorPortOnThisSide </var>,
6741
+ « <var>processorPortOnThisSide</var> ») .
6724
6742
</li>
6725
- <li>Let <var>parameterMap </var> be the result of <a href=
6726
- "https://tc39.github.io/ecma262/#sec-map-iterable">Map </a>() .
6743
+ <li>Set <var>node </var>'s <a href=
6744
+ "#widl-AudioWorkletNode-port">port </a> to <var>nodePort</var> .
6727
6745
</li>
6728
- <li>For each <var>descriptor</var> in
6729
- <var>parameterDescriptors</var> perform the following substeps:
6746
+ <li>Let <var>parameterDescriptors</var> be the result of retrieval
6747
+ of <var>nodeName</var> from <a>node name to parameter descriptor
6748
+ map</a>:
6730
6749
<ol>
6731
- <li>Let <var>audioParam</var> be a new <a>AudioParam</a>
6732
- instance with:
6733
- <ul>
6734
- <li>
6735
- <var>paramName</var> being the result <a href=
6736
- "https://tc39.github.io/ecma262/#sec-get-o-p">Get</a>(O=<var>descriptor</var>,
6737
- P="name").
6750
+ <li>Let <var>audioParamMap</var> be a new <a>AudioParamMap</a>
6751
+ object.
6752
+ </li>
6753
+ <li>For each <var>descriptor</var> of
6754
+ <var>parameterDescriptors</var>:
6755
+ <ol>
6756
+ <li>Let <var>paramName</var> be the value of
6757
+ <var>descriptor</var>'s <a href=
6758
+ "#widl-AudioParamDescriptor-name">name</a>.
6738
6759
</li>
6739
- <li>
6740
- <var>defaultValue</var> being the result <a href=
6741
- "https://tc39.github.io/ecma262/#sec-get-o-p">Get</a>(O=<var>descriptor</var>,
6742
- P="defaultValue").
6760
+ <li>Let <var>audioParam</var> be a new <a>AudioParam</a>
6761
+ instance.
6743
6762
</li>
6744
- <li>
6745
- <var>minValue</var> being the result <a href=
6746
- "https://tc39.github.io/ecma262/#sec-get-o-p">Get</a>(O=<var>descriptor</var>,
6747
- P="minValue").
6763
+ <li>Append (<var>paramName</var>, <var>audioParam</var>) to
6764
+ <var>audioParamMap</var>'s entries.
6765
+ </li>
6766
+ </ol>
6767
+ </li>
6768
+ <li>For each <var>paramNameInOption</var> → <var>value</var> of
6769
+ <var>options</var>:
6770
+ <ol>
6771
+ <li>If there exists an entry with name member equal to
6772
+ <var>paramNameInOption</var> inside
6773
+ <var>audioParamMap</var>, set that <a>AudioParam</a>'s
6774
+ value to <var>value</var>.
6748
6775
</li>
6749
6776
<li>
6750
- <var>maxValue</var> being the result <a href=
6751
- "https://tc39.github.io/ecma262/#sec-get-o-p">Get</a>(O=<var>descriptor</var>,
6752
- P="maxValue").
6777
+ <var>paramNameInOption</var> will be ignored when:
6778
+ <ul>
6779
+ <li>
6780
+ <var>audioParamMap</var> does not have any entry with
6781
+ the same name member.
6782
+ </li>
6783
+ <li>
6784
+ <var>value</var> is not a type of <code>Number</code>
6785
+ or out of the range specified in
6786
+ <a>AudioParamDescriptor</a>.
6787
+ </li>
6788
+ </ul>
6753
6789
</li>
6754
- </ul>
6755
- </li>
6756
- <li>If <var>options</var> contains a dictionary member with
6757
- name <var>paramName</var> whose value is of type
6758
- <code>Number</code>, perform <a href=
6759
- "https://tc39.github.io/ecma262/#sec-set-o-p-v-throw">Set</a>(<var>audioParam</var>,
6760
- "value", <a href="https://tc39.github.io/ecma262/#sec-get-o-p">
6761
- Get</a>(O=<var>options</var>, P=<var>paramName</var>),
6762
- false).
6790
+ </ol>
6763
6791
</li>
6764
- <li>Perform <a href=
6765
- "https://tc39.github.io/ecma262/#https://tc39.github.io/ecma262/#sec-set-o-p-v-throw">
6766
- Set</a>(O=<var>parameterMap</var>, P=<var>paramName</var>,
6767
- V=<var>audioParam</var>).
6792
+ <li>Set <var>node</var>'s <a href=
6793
+ "#widl-AudioWorkletNode-parameters">parameters</a> to
6794
+ <var>audioParamMap</var>.
6768
6795
</li>
6769
6796
</ol>
6770
6797
</li>
6771
- <li>Perform <a href=
6772
- "https://tc39.github.io/ecma262/#sec-createmethodproperty">CreateDataProperty</a>(O=<var>this</var>,
6773
- P="parameters", V=<var>parameterMap</var>).
6798
+ <li>
6799
+ <a href="#queuing">Queue a control message</a> to create an
6800
+ <a>AudioWorkletProcessor</a>, given <var>nodeName</var>,
6801
+ <var>processorPortSerialization</var>, and <var>node</var>.
6802
+ </li>
6803
+ <li>Return <var>node</var>.
6804
+ </li>
6805
+ </ol>
6806
+ <p>
6807
+ In order to process a control message for the construction of an
6808
+ <a>AudioWorkletProcessor</a>, given a string <var>nodeName</var>, a
6809
+ serialization record <var>processorPortSerialization</var>, and an
6810
+ <a>AudioWorkletNode</a> <var>node</var>, perform the following
6811
+ steps on the <a>rendering thread</a>. If any of these steps throws
6812
+ an exception (either explicitly or implicitly), abort the rest of
6813
+ steps and queue a task on the <a>control thread</a> to fire
6814
+ <a href="#widl-AudioWorkletNode-onprocessorstatechange"><code>processorstatechange</code></a>
6815
+ event to <var>node</var> with <code>error</code> state.
6816
+ </p>
6817
+ <ol>
6818
+ <li>Let <var>processorPort</var> be <a href=
6819
+ "https://html.spec.whatwg.org/multipage/infrastructure.html#structureddeserializewithtransfer">
6820
+ StructuredDeserializeWithTransfer</a>(<var>processorPortSerialization</var>,
6821
+ the current Realm).
6822
+ </li>
6823
+ <li>Let <var>processorConstructor</var> be the result of looking up
6824
+ <var>nodeName</var> on the <a>AudioWorkletGlobalScope</a>'s <a>node
6825
+ name to processor definition map</a>.
6826
+ </li>
6827
+ <li>If <var>processorConstructor</var> is <code>undefined</code>,
6828
+ throw a <code>NotSupportedError</code> DOMException.
6829
+ </li>
6830
+ <li>Let <var>processor</var> be the result of
6831
+ Construct(<var>processorConstructor</var>).
6832
+ </li>
6833
+ <li>If <var>processor</var> does not implement the
6834
+ <a>AudioWorkletProcessor</a> interface, throw an
6835
+ <code>"InvalidStateError"</code> DOMException.
6836
+ </li>
6837
+ <li>Set <var>processor</var>'s <a href=
6838
+ "#widl-AudioWorkletProcessor-port">port</a> to
6839
+ <var>processorPort</var>.
6774
6840
</li>
6775
- <li>Set <a>node reference</a> in <var>processorInstance</var > to
6776
- <var>this </var>.
6841
+ <li>Set <var>processor</var>'s <a>node reference</a > to
6842
+ <var>node </var>.
6777
6843
</li>
6778
- <li>Set <a>processor reference</a> in <var>this</var > to
6779
- <var>processorInstance </var>.
6844
+ <li>Set <var>node</var>'s <a>processor reference</a > to
6845
+ <var>processor </var>.
6780
6846
</li>
6781
- <li>Return <var>this</var> as a result of the construction.
6847
+ <li>Queue a task the <a>control thread</a> to set the associated
6848
+ <a>AudioWorkletNode</a>'s state to <code>running</code>, then fire
6849
+ a <code>statechange</code> event.
6782
6850
</li>
6783
6851
</ol>
6784
6852
</section>
@@ -6927,6 +6995,14 @@ <h3>
6927
6995
6928
6996
});
6929
6997
</pre>
6998
+ <div class="note">
6999
+ <p>
7000
+ In the definition of <a>AudioWorkletProcessor</a> class, an
7001
+ <code>InvalidStateError</code> will be thrown if the
7002
+ author-supplied constructor uses JavaScript's return-override
7003
+ feature, or does not properly call <code>super()</code>.
7004
+ </p>
7005
+ </div>
6930
7006
</section>
6931
7007
<section>
6932
7008
<h3>
0 commit comments