From 6b8befec2347d9b686d7933b7852df96d95b4e48 Mon Sep 17 00:00:00 2001 From: Hongchan Choi Date: Thu, 18 Jul 2019 14:29:15 -0700 Subject: [PATCH 01/14] Initial commit --- index.bs | 320 +++++++++++++++++++++++++++---------------------------- 1 file changed, 155 insertions(+), 165 deletions(-) diff --git a/index.bs b/index.bs index bc96e19cf..ceb9c9772 100644 --- a/index.bs +++ b/index.bs @@ -9844,19 +9844,104 @@ Constructors
: AudioWorkletNode(context, name, options) :: - Let node be a new {{AudioWorkletNode}} object. - Initialize - node. Perform the - construction procedure of an - {{AudioWorkletNode}} and the corresponding - {{AudioWorkletProcessor}} object. Return - node. + When the constructor of {{AudioWorkletNode}} ot its subclass is + invoked in the main global scope, the following construction + algorithm MUST be performed. + + During the construction of an AudioWorkletNode, a + corresponding {{AudioWorkletProcessor}} instance is also + automatically created in the {{AudioWorkletGlobalScope}}. + Note that the instantiation of these object pairs spans the + control thread and the rendering thread.
 			context: The {{BaseAudioContext}} this new {{AudioWorkletNode}} will be associated with.
 			name: A string that is a key for the {{BaseAudioContext}}’s node name to parameter descriptor map.
 			options: Optional initial parameters value for this {{AudioWorkletNode}}.
 		
+ +
+ When {{AudioWorkletNode()|AudioWorkletNode}}( + {{AudioWorkletNode/AudioWorkletNode(context, name, options)/context}}, + {{AudioWorkletNode/AudioWorkletNode(context, name, options)/name|nodeName}}, + {{AudioWorkletNode/AudioWorkletNode(context, name, options)/options}}) + constructor is invoked, the user agent MUST perform the + following steps on the control thread, where the constructor was + called. + + 1. Perform the validity check on options. If the + check throws any exception, propagate the exception + and abort these steps. + + 1. If nodeName does not exists as a key in the + {{BaseAudioContext}}’s node name to parameter + descriptor map, throw a {{InvalidStateError}} + exception and abort these steps. + + 1. Let node be the instance being created by the + constructor of the {{AudioWorkletNode}} or its subclass. + + 1. Let messageChannel be a new {{MessageChannel}}. + + 1. Let nodePort be the value of + messageChannel's {{MessageChannel/port1}} attribute. + + 1. Let processorPortOnThisSide be the value of + messageChannel's {{MessageChannel/port2}} attribute. + + 1. Let serializedProcessorPort be the result of + [$StructuredSerializeWithTransfer$](processorPortOnThisSide, + « processorPortOnThisSide »). + + 1. Convert + options dictionary to optionsObject. + + 1. Let serializedOptions be the result of + [$StructuredSerialize$](optionsObject). + + 1. Set node's {{AudioWorkletNode/port}} to nodePort. + + 1. Let parameterDescriptors be the result of retrieval + of nodeName from node name to parameter descriptor map: + + 1. Let audioParamMap be a new {{AudioParamMap}} object. + + 1. For each descriptor of parameterDescriptors: + 1. Let paramName be the value of + descriptor's {{AudioParamDescriptor/name}}. + + 1. Let audioParam be a new {{AudioParam}} + instance. + + 1. Append (paramName, audioParam) to + audioParamMap's entries. + + 1. For each key-value pair (paramNameInOption to + value) of options: + 1. If there exists an entry with name member equal to + paramNameInOption inside + audioParamMap, set that {{AudioParam}}'s + value to value. + + 1. paramNameInOption will be ignored when: + * audioParamMap does not have any entry with + the same name member. + + * value is out of the range specified in + {{AudioParamDescriptor}}. + + 1. Set node's {{AudioWorkletNode/parameters}} to audioParamMap. + + 1. Queue a control message to invoke the + {{AudioWorkletProcessor()|constructor}} of + the corresponding {{AudioWorkletProcessor}} with + nodeName, + serializedProcessorPort, + serializedOptions, + and node. + + 1. Return node. +
@@ -9896,9 +9981,13 @@ Attributes
{{AudioWorkletNodeOptions}} The {{AudioWorkletNodeOptions}} dictionary can be used -for the custom initialization of {{AudioNode}} -attributes in the {{AudioWorkletNode}} -constructor. +to initialize attibutes in the instance of an {{AudioWorkletNode}} and +an {{AudioWorkletProcessor}}. + +The base implementation of {{AudioWorkletProcessor}} does not examine the values +in this dictionary. However, an user-defined subclass of the +{{AudioWorkletProcessor}} can use this dictionary to initialize custom +properties in its instance. dictionary AudioWorkletNodeOptions : AudioNodeOptions { @@ -9944,9 +10033,12 @@ Dictionary {{AudioWorkletNodeOptions}} Members</h6> {{AudioWorkletNode}}. If the string key of an entry in the list does not match the name of any {{AudioParam}} objects in the node, it is ignored. + : <dfn>processorOptions</dfn> :: - This holds any additional user-defined data that may be used to initialize the corresponding {{AudioWorkletProcessor}} for this {{AudioWorkletNode}}. + This holds any additional user-defined data that may be used to + initialize the corresponding {{AudioWorkletProcessor}} for this + {{AudioWorkletNode}}. </dl> <h6 id="configuring-channels-with-audioworkletnodeoptions"> @@ -9978,12 +10070,10 @@ various channel configurations can be achieved. The {{AudioWorkletProcessor}} Interface</h4> This interface represents an audio processing code that runs on the -audio <a>rendering thread</a>. It lives in the -{{AudioWorkletGlobalScope}}, and the definition of -the class manifests the actual audio processing mechanism of a -custom audio node. {{AudioWorkletProcessor}} can -only be instantiated by the construction of an -{{AudioWorkletNode}} instance. +audio <a>rendering thread</a>. It lives in the {{AudioWorkletGlobalScope}}, +and the definition of the class manifests the actual audio processing. +Note that {{AudioWorkletProcessor}} can only be followed by the construction +of an {{AudioWorkletNode}} instance. <pre class="idl"> [Exposed=AudioWorklet, @@ -10008,35 +10098,58 @@ interface AudioWorkletProcessor { <h5 id="AudioWorketProcessor-constructors"> Constructors</h5> + <dl dfn-type="constructor" dfn-for="AudioWorkletProcessor"> : <dfn>AudioWorkletProcessor(options)</dfn> :: - When the constructor for {{AudioWorkletProcessor}} is invoked, the following steps are performed: + When the constructor for {{AudioWorkletProcessor}} is invoked, + the following steps are performed steps on the + <a>rendering thread</a>. + + If any of these steps throws an exception, abort the rest of + steps and <a>queue a task</a> to inform the associated + {{AudioWorkletNode}} on the <a>control thread</a> with the + relevant information about the error. In turn, the + {{AudioWorkletNode}} will fire an <a>ErrorEvent</a> via + the {{AudioWorkletNode/onprocessorerror}} event handler. + <div algorithm="AudioWorkletProcessor()"> - 1. Compare the value of <a href="https://www.ecma-international.org/ecma-262/6.0/#sec-built-in-function-objects">NewTarget</a> - with the <a href="https://www.ecma-international.org/ecma-262/6.0/#sec-execution-contexts">active function object</a>; - if the two are equal, throw a {{TypeError}}. - - Note: This check prevents the invocation of the constructor - directly from JavaScript. The interface object may only - be called internally by the UA. - - 1. Initialize the {{AudioWorkletProcessor}} using the - contents of the {{AudioWorkletNode/AudioWorkletNode()/options!!argument}} dictionary that was - passed to the constructor for {{AudioWorkletNode}}. The - contents of this dictionary will have been serialized and - deserialized according to the algorithm for <a href= - "#instantiation-of-AudioWorkletNode-and-AudioWorkletProcessor"> instantiating an AudioWorkletProcessor</a>. - - Note: The base implementation of {{AudioWorkletProcessor}} - does not examine the values in the {{AudioWorkletProcessor/AudioWorkletProcessor()/options!!argument}} - dictionary. However, processor classes that extend - {{AudioWorkletProcessor}} will use this dictionary to - initialize themselves based on the options relevant to - their specific node type. - - 1. Set {{[[node reference]]}} to `null` and {{[[callable process]]}} to - `false`. + This constructor is invoked by processing a control + message queued by the + {{AudioWorkletNode()|constructor}} of the associated + {{AudioWokrketNode}}. This control message carries + <dfn>processor construction data</dfn> consists of: + <var>nodeName</var>, + <var>serializedProcessorPort</var>, + <var>serializedOptions</var>, + and <var>node</var>. + + 1. If there is no <a>processor construction data</a> + available, throw a {{TypeError}}. + + 1. Let <var>processorPort</var> be + [$StructuredDeserializeWithTransfer$](<var>serializedProcessorPort</var>, + the current Realm). + + 1. Let <var>options</var> be + [$StructuredDeserialize$](<code>serializedOptions</code>, + the current Realm). + + 1. Let <var>processorCtor</var> be the result of looking + up <var>nodeName</var> on the + {{AudioWorkletGlobalScope}}'s + <a>node name to processor constructor map</a>. + + 1. Let <var>processor</var> be the result of + Construct(<var>processorCtor</var>, « <var>options</var> »). + + 1. Set <var>processor</var>'s {{[[node reference]]}} to + <var>node</var>. + + 1. Set {{[[callable process]]}} to `true`. + + 1. Set <var>node</var>'s <a>processor reference</a> to + <var>processor</var>. </div> <pre class="argumentdef" for="AudioWorkletProcessor/AudioWorkletProcessor()"> @@ -10232,129 +10345,6 @@ Dictionary {{AudioParamDescriptor}} Members</h6> definition.</span> </dl> -<h4 id="instantiation-of-AudioWorkletNode-and-AudioWorkletProcessor"> -The instantiation of {{AudioWorkletNode}} and {{AudioWorkletProcessor}}</h4> - -When the constructor of {{AudioWorkletNode}} is invoked in the -main global scope, the corresponding {{AudioWorkletProcessor}} -instance is automatically created in the -{{AudioWorkletGlobalScope}}. After the construction, they -maintain an internal reference to each other until the -{{AudioWorkletNode}} instance is destroyed. - -Note that the instantiation of these two objects spans the control -thread and the rendering thread. - -<div algorithm="audioworklet construction"> - When {{AudioWorkletNode()|AudioWorkletNode}}({{AudioWorkletNode/AudioWorkletNode(context, name, options)/context}}, - {{AudioWorkletNode/AudioWorkletNode(context, name, options)/name|nodeName}}, {{AudioWorkletNode/AudioWorkletNode(context, name, options)/options}}) constructor is invoked, - the user agent MUST perform the following steps on the control - thread, where the constructor was called. - - 1. Let <var>node</var> be the instance being created by the - constructor of the {{AudioWorkletNode}} or its subclass. - - 1. If <var>nodeName</var> does not exists as a key in the - {{BaseAudioContext}}’s <a>node name to parameter descriptor - map</a>, throw a {{NotSupportedError}} exception and abort - these steps. - - 1. Let <var>messageChannel</var> be a new {{MessageChannel}}. - - 1. Let <var>nodePort</var> be the value of - <var>messageChannel</var>'s {{MessageChannel/port1}} attribute. - - 1. Let <var>processorPortOnThisSide</var> be the value of - <var>messageChannel</var>'s {{MessageChannel/port2}} attribute. - - 1. Let <var>processorPortSerialization</var> be the result of - [$StructuredSerializeWithTransfer$](<var>processorPortOnThisSide</var>, - « <var>processorPortOnThisSide</var> »). - - 1. <a href="https://heycam.github.io/webidl/#dictionary-to-es">Convert</a> - <var>options</var> dictionary to <var>optionsObject</var>. - - 1. Let <var>optionsSerialization</var> be the result of - [$StructuredSerialize$](<var>optionsObject</var>). - - 1. Set <var>node</var>'s {{AudioWorkletNode/port}} to <var>nodePort</var>. - - 1. Let <var>parameterDescriptors</var> be the result of retrieval - of <var>nodeName</var> from <a>node name to parameter descriptor map</a>: - - 1. Let <var>audioParamMap</var> be a new {{AudioParamMap}} object. - - 1. For each <var>descriptor</var> of <var>parameterDescriptors</var>: - 1. Let <var>paramName</var> be the value of - <var>descriptor</var>'s {{AudioParamDescriptor/name}}. - - 1. Let <var>audioParam</var> be a new {{AudioParam}} - instance. - - 1. Append (<var>paramName</var>, <var>audioParam</var>) to - <var>audioParamMap</var>'s entries. - - 1. For each key-value pair (<var>paramNameInOption</var> to - <var>value</var>) of <var>options</var>: - 1. If there exists an entry with name member equal to - <var>paramNameInOption</var> inside - <var>audioParamMap</var>, set that {{AudioParam}}'s - value to <var>value</var>. - - 1. <var>paramNameInOption</var> will be ignored when: - * <var>audioParamMap</var> does not have any entry with - the same name member. - - * <var>value</var> is out of the range specified in - {{AudioParamDescriptor}}. - - 1. Set <var>node</var>'s {{AudioWorkletNode/parameters}} to <var>audioParamMap</var>. - - 1. <a>Queue a control message</a> to create an - {{AudioWorkletProcessor}}, given the <var>nodeName</var>, - <var>processorPortSerialization</var>, <var>optionsSerialization</var>, and <var>node</var>. - - 1. Return <var>node</var>. -</div> - -<div algorithm="process control message"> - In order to process a control message for the construction of an - {{AudioWorkletProcessor}}, given a string <var>nodeName</var>, a - serialization record <var>processorPortSerialization</var>, and an - {{AudioWorkletNode}} <var>node</var>, perform the following - steps on the <a>rendering thread</a>. If any of these steps throws - an exception (either explicitly or implicitly), abort the rest of - steps and <a>queue a task</a> on the <a>control thread</a> to fire - {{AudioWorkletNode/onprocessorerror}} event to - <var>node</var>. - - 1. Let <var>processorPort</var> be - [$StructuredDeserializeWithTransfer$](<var>processorPortSerialization</var>, - the current Realm). - - 1. Let <var>options</var> be - [$StructuredDeserialize$](<code>optionsSerialization</code>, the - current Realm). - - 1. Let <var>processorCtor</var> be the result of looking up - <var>nodeName</var> on the {{AudioWorkletGlobalScope}}'s <a>node - name to processor constructor map</a>. - - 1. Let <var>processor</var> be the result of - Construct(<var>processorCtor</var>, « <var>options</var> »). - - 1. Set <var>processor</var>'s {{AudioWorkletProcessor/port}} to - <var>processorPort</var>. - - 1. Set <var>processor</var>'s {{[[node reference]]}}to - <var>node</var>. - - 1. Set {{[[callable process]]}} to `true`. - - 1. Set <var>node</var>'s <a>processor reference</a> to - <var>processor</var>. -</div> - <h4 id="AudioWorklet-Sequence"> AudioWorklet Sequence of Events</h4> From 49a1860b159cfc075dcc14e02841ae2f1d4e93ff Mon Sep 17 00:00:00 2001 From: Hongchan Choi <hongchan.choi@gmail.com> Date: Thu, 18 Jul 2019 15:40:42 -0700 Subject: [PATCH 02/14] fixing bikeshed errors --- index.bs | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/index.bs b/index.bs index ceb9c9772..d265ddc92 100644 --- a/index.bs +++ b/index.bs @@ -10110,14 +10110,15 @@ Constructors</h5> steps and <a>queue a task</a> to inform the associated {{AudioWorkletNode}} on the <a>control thread</a> with the relevant information about the error. In turn, the - {{AudioWorkletNode}} will fire an <a>ErrorEvent</a> via - the {{AudioWorkletNode/onprocessorerror}} event handler. + {{AudioWorkletNode}} will fire an + <a href="https://www.w3.org/TR/html50/webappapis.html#the-errorevent-interface">ErrorEvent</a> + via the {{AudioWorkletNode/onprocessorerror}} event handler. <div algorithm="AudioWorkletProcessor()"> This constructor is invoked by processing a control message queued by the {{AudioWorkletNode()|constructor}} of the associated - {{AudioWokrketNode}}. This control message carries + {{AudioWorkletNode}}. This control message carries <dfn>processor construction data</dfn> consists of: <var>nodeName</var>, <var>serializedProcessorPort</var>, @@ -10125,14 +10126,15 @@ Constructors</h5> and <var>node</var>. 1. If there is no <a>processor construction data</a> - available, throw a {{TypeError}}. + passed from the associated {{AudioWorkletNode}}, + throw a {{TypeError}}. 1. Let <var>processorPort</var> be [$StructuredDeserializeWithTransfer$](<var>serializedProcessorPort</var>, the current Realm). 1. Let <var>options</var> be - [$StructuredDeserialize$](<code>serializedOptions</code>, + [$StructuredDeserialize$](<var>serializedOptions</var>, the current Realm). 1. Let <var>processorCtor</var> be the result of looking @@ -10143,6 +10145,8 @@ Constructors</h5> 1. Let <var>processor</var> be the result of Construct(<var>processorCtor</var>, « <var>options</var> »). + 1. Set <var>processor</var>’s port to <var>processorPort</var>. + 1. Set <var>processor</var>'s {{[[node reference]]}} to <var>node</var>. From a6b1de7895457c17a553e143ed9a4b5bb1f7a903 Mon Sep 17 00:00:00 2001 From: Hongchan Choi <hongchan.choi@gmail.com> Date: Thu, 18 Jul 2019 15:48:47 -0700 Subject: [PATCH 03/14] fixing bikeshed errors --- index.bs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/index.bs b/index.bs index d265ddc92..48fa78ad2 100644 --- a/index.bs +++ b/index.bs @@ -9935,6 +9935,8 @@ Constructors</h5> 1. <a>Queue a control message</a> to invoke the {{AudioWorkletProcessor()|constructor}} of the corresponding {{AudioWorkletProcessor}} with + <dfn>processor construction data</dfn>, + that consists of: <var>nodeName</var>, <var>serializedProcessorPort</var>, <var>serializedOptions</var>, @@ -10119,7 +10121,7 @@ Constructors</h5> message queued by the {{AudioWorkletNode()|constructor}} of the associated {{AudioWorkletNode}}. This control message carries - <dfn>processor construction data</dfn> consists of: + <a>processor construction data</a>: <var>nodeName</var>, <var>serializedProcessorPort</var>, <var>serializedOptions</var>, From 12cd8690c16f51803ae77e4e6d98cfba968bd265 Mon Sep 17 00:00:00 2001 From: Hongchan Choi <hongchan.choi@gmail.com> Date: Thu, 18 Jul 2019 15:59:14 -0700 Subject: [PATCH 04/14] fixing bikeshed errors --- index.bs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/index.bs b/index.bs index 48fa78ad2..2441772c5 100644 --- a/index.bs +++ b/index.bs @@ -9935,8 +9935,7 @@ Constructors</h5> 1. <a>Queue a control message</a> to invoke the {{AudioWorkletProcessor()|constructor}} of the corresponding {{AudioWorkletProcessor}} with - <dfn>processor construction data</dfn>, - that consists of: + the processor construction data that consists of: <var>nodeName</var>, <var>serializedProcessorPort</var>, <var>serializedOptions</var>, @@ -10121,13 +10120,13 @@ Constructors</h5> message queued by the {{AudioWorkletNode()|constructor}} of the associated {{AudioWorkletNode}}. This control message carries - <a>processor construction data</a>: + the processor construction data: <var>nodeName</var>, <var>serializedProcessorPort</var>, <var>serializedOptions</var>, and <var>node</var>. - 1. If there is no <a>processor construction data</a> + 1. If there is no processor construction data passed from the associated {{AudioWorkletNode}}, throw a {{TypeError}}. From e3f142051326bb8f0f8e1a897fde28cb16683105 Mon Sep 17 00:00:00 2001 From: Hongchan Choi <hongchan.choi@gmail.com> Date: Wed, 24 Jul 2019 10:06:06 -0700 Subject: [PATCH 05/14] address comments from padenot --- index.bs | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/index.bs b/index.bs index 98b3179e1..eb6e6d93e 100644 --- a/index.bs +++ b/index.bs @@ -9844,9 +9844,9 @@ Constructors</h5> <dl dfn-type=constructor dfn-for="AudioWorkletNode"> : <dfn>AudioWorkletNode(context, name, options)</dfn> :: - When the constructor of {{AudioWorkletNode}} ot its subclass is - invoked in the main global scope, the following construction - algorithm MUST be performed. + When the constructor of {{AudioWorkletNode}} is invoked in the + main global scope, the following construction algorithm MUST be + performed. During the construction of an AudioWorkletNode, a corresponding {{AudioWorkletProcessor}} instance is also @@ -10080,8 +10080,8 @@ The {{AudioWorkletProcessor}} Interface</h4> This interface represents an audio processing code that runs on the audio <a>rendering thread</a>. It lives in the {{AudioWorkletGlobalScope}}, and the definition of the class manifests the actual audio processing. -Note that {{AudioWorkletProcessor}} can only be followed by the construction -of an {{AudioWorkletNode}} instance. +Note that the an {{AudioWorkletProcessor}} construction can only happen as a +result of an {{AudioWorkletNode}} contruction. <pre class="idl"> [Exposed=AudioWorklet, @@ -10111,16 +10111,14 @@ Constructors</h5> : <dfn>AudioWorkletProcessor(options)</dfn> :: When the constructor for {{AudioWorkletProcessor}} is invoked, - the following steps are performed steps on the - <a>rendering thread</a>. + the following steps are performed on the <a>rendering thread</a>. If any of these steps throws an exception, abort the rest of - steps and <a>queue a task</a> to inform the associated - {{AudioWorkletNode}} on the <a>control thread</a> with the - relevant information about the error. In turn, the - {{AudioWorkletNode}} will fire an + steps and <a>queue a task</a> to fire an <a href="https://www.w3.org/TR/html50/webappapis.html#the-errorevent-interface">ErrorEvent</a> - via the {{AudioWorkletNode/onprocessorerror}} event handler. + named "processorerror" at the AudioWorkletNode on the + <a>control thread</a> with the relevant information about the + error. <div algorithm="AudioWorkletProcessor()"> This constructor is invoked by processing a control From 480705877b8d0fa960239e9e2a8a813b6098ca4c Mon Sep 17 00:00:00 2001 From: Hongchan Choi <hongchan.choi@gmail.com> Date: Thu, 25 Jul 2019 10:45:23 -0700 Subject: [PATCH 06/14] Fixes #1972 --- index.bs | 50 ++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 42 insertions(+), 8 deletions(-) diff --git a/index.bs b/index.bs index eb6e6d93e..b0e45e84f 100644 --- a/index.bs +++ b/index.bs @@ -9906,15 +9906,49 @@ Constructors</h5> 1. Let <var>audioParamMap</var> be a new {{AudioParamMap}} object. - 1. For each <var>descriptor</var> of <var>parameterDescriptors</var>: - 1. Let <var>paramName</var> be the value of - <var>descriptor</var>'s {{AudioParamDescriptor/name}}. - - 1. Let <var>audioParam</var> be a new {{AudioParam}} - instance. + 1. For each <var>descriptor</var> of + <var>parameterDescriptors</var>: - 1. Append (<var>paramName</var>, <var>audioParam</var>) to - <var>audioParamMap</var>'s entries. + 1. Let <var>paramName</var> be the value of + <var>name</var> member in + <var>descriptor</var>. + + 1. Let <var>audioParam</var> be a new + {{AudioParam}} instance with + {{AudioParamDescriptor/automationRate}}, + {{AudioParamDescriptor/defaultValue}}, + {{AudioParamDescriptor/minValue}}, and + {{AudioParamDescriptor/maxValue}} + having values equal to the values of + corresponding members on + <var>descriptor</var>. + + 1. Append a key-value pair + <var>paramName</var> → + <var>audioParam</var> to + <var>audioParamMap</var>'s + entries. + + 1. If {{AudioWorkletNodeOptions/parameterData}} is + present on <var>options</var>, perform the + following steps: + + 1. Let <var>parameterData</var> be the value of + {{AudioWorkletNodeOptions/parameterData}}. + + 1. For each <var>paramName</var> → + <var>paramValue</var> of + <var>parameterData</var>: + + 1. If there exists a map entry on + <var>audioParamMap</var> with + key <var>paramName</var>, let + <var>audioParamInMap</var> be + such entry. + + 1. Set {{AudioParam/value}} property + of <var>audioParamInMap</var> + to <var>paramValue</var>. 1. For each key-value pair (<var>paramNameInOption</var> to <var>value</var>) of <var>options</var>: From 7df14779b0d3dc54648aefd9eae94b9b2294fae6 Mon Sep 17 00:00:00 2001 From: Hongchan Choi <hongchan.choi@gmail.com> Date: Thu, 25 Jul 2019 10:50:37 -0700 Subject: [PATCH 07/14] fix build error --- index.bs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.bs b/index.bs index b0e45e84f..187caeba7 100644 --- a/index.bs +++ b/index.bs @@ -9910,7 +9910,7 @@ Constructors</h5> <var>parameterDescriptors</var>: 1. Let <var>paramName</var> be the value of - <var>name</var> member in + {{AudioParamDescriptor/name}} member in <var>descriptor</var>. 1. Let <var>audioParam</var> be a new From db79983b1fbf43534d0aa32fd40e052ee5b7cc71 Mon Sep 17 00:00:00 2001 From: Hongchan Choi <hongchan.choi@gmail.com> Date: Fri, 26 Jul 2019 08:54:40 -0700 Subject: [PATCH 08/14] Fix discussed in #1972 --- index.bs | 21 ++++++++------------- 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/index.bs b/index.bs index 187caeba7..000d7b737 100644 --- a/index.bs +++ b/index.bs @@ -9950,19 +9950,14 @@ Constructors</h5> of <var>audioParamInMap</var> to <var>paramValue</var>. - 1. For each key-value pair (<var>paramNameInOption</var> to - <var>value</var>) of <var>options</var>: - 1. If there exists an entry with name member equal to - <var>paramNameInOption</var> inside - <var>audioParamMap</var>, set that {{AudioParam}}'s - value to <var>value</var>. - - 1. <var>paramNameInOption</var> will be ignored when: - * <var>audioParamMap</var> does not have any entry with - the same name member. - - * <var>value</var> is out of the range specified in - {{AudioParamDescriptor}}. + 1. For each key-value pair <var>paramNameInOption</var> + → <var>paramValue</var> of <var>options</var>: + + 1. If there exists an entry with name member + equal to <var>paramNameInOption</var> + inside <var>audioParamMap</var>, + set that {{AudioParam}}'s value to + <var>paramValue</var>. 1. Set <var>node</var>'s {{AudioWorkletNode/parameters}} to <var>audioParamMap</var>. From 654f99f63f8419bffffd94151c641e0995ffe87b Mon Sep 17 00:00:00 2001 From: Hongchan Choi <hongchan.choi@gmail.com> Date: Fri, 2 Aug 2019 09:31:05 -0700 Subject: [PATCH 09/14] fixing auto linking --- index.bs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/index.bs b/index.bs index 373d8245b..c086d14cc 100644 --- a/index.bs +++ b/index.bs @@ -9969,7 +9969,7 @@ Constructors</h5> 1. <a>Queue a control message</a> to invoke the {{AudioWorkletProcessor()|constructor}} of the corresponding {{AudioWorkletProcessor}} with - the {{processor construction data}} that consists of: + the [=processor construction data=] that consists of: <var>nodeName</var>, <var>serializedProcessorPort</var>, <var>serializedOptions</var>, @@ -10158,14 +10158,14 @@ Constructors</h5> This constructor is invoked by processing a control message queued by the {{AudioWorkletNode()|constructor}} of the associated {{AudioWorkletNode}}. This control - message carries the {{processor construction data}} that + message carries the [=processor construction data=] that consists of: <var>nodeName</var>, <var>serializedProcessorPort</var>, <var>serializedOptions</var>, and <var>node</var>. - 1. If there is no processor construction data + 1. If there is no [=processor construction data=] passed from the associated {{AudioWorkletNode}}, throw a {{TypeError}}. From 95fc0bc5cbe47e3e186916537194a643d8c665a7 Mon Sep 17 00:00:00 2001 From: Hongchan Choi <hongchan.choi@gmail.com> Date: Fri, 2 Aug 2019 10:08:29 -0700 Subject: [PATCH 10/14] move dfn to fix build error --- index.bs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/index.bs b/index.bs index c086d14cc..fd1cbb482 100644 --- a/index.bs +++ b/index.bs @@ -9815,6 +9815,11 @@ Every {{AudioWorkletProcessor}} has an associated <dfn>active source</dfn> flag, the node to be retained in memory and perform audio processing in the absence of any connected inputs. +Once the construction of the node is completed, +<dfn>processor construction data</dfn> will be created and +trasnferred to the matching {{AudioWorkletProcessor}}'s +{{AudioWorkletProcessor()|constructor}}. + <xmp class="idl"> [Exposed=Window] interface AudioParamMap { @@ -9854,11 +9859,6 @@ Constructors</h5> Note that the instantiation of these object pairs spans the control thread and the rendering thread. - Once the construction of the node is completed, - <dfn>processor construction data</dfn> will be created and - trasnferred to the matching {{AudioWorkletProcessor}}'s - {{AudioWorkletProcessor()|constructor}}. - <pre class=argumentdef for="AudioWorkletNode/AudioWorkletNode()"> context: The {{BaseAudioContext}} this new {{AudioWorkletNode}} will be <a href="#associated">associated</a> with. name: A string that is a key for the {{BaseAudioContext}}’s <a>node name to parameter descriptor map</a>. From 9e2c02dc47566da3fae6e965a7dff6aed7062399 Mon Sep 17 00:00:00 2001 From: Hongchan Choi <hongchan.choi@gmail.com> Date: Wed, 7 Aug 2019 10:17:09 -0700 Subject: [PATCH 11/14] address comments from @rtoy --- index.bs | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/index.bs b/index.bs index b0b617cb8..8c8bd079f 100644 --- a/index.bs +++ b/index.bs @@ -9856,7 +9856,9 @@ the absence of any connected inputs. Once the construction of the node is completed, <dfn>processor construction data</dfn> will be created and trasnferred to the matching {{AudioWorkletProcessor}}'s -{{AudioWorkletProcessor()|constructor}}. +{{AudioWorkletProcessor()|constructor}}. This data contains +a set of objects and references that is required for +{{AudioWorkletProcessor}}'s construction. <xmp class="idl"> [Exposed=Window] @@ -9887,22 +9889,22 @@ Constructors</h5> <dl dfn-type=constructor dfn-for="AudioWorkletNode"> : <dfn>AudioWorkletNode(context, name, options)</dfn> :: + <pre class=argumentdef for="AudioWorkletNode/AudioWorkletNode()"> + context: The {{BaseAudioContext}} this new {{AudioWorkletNode}} will be <a href="#associated">associated</a> with. + name: A string that is a key for the {{BaseAudioContext}}’s <a>node name to parameter descriptor map</a>. + options: Optional initial parameters value for this {{AudioWorkletNode}}. + </pre> + When the constructor of {{AudioWorkletNode}} is invoked in the main global scope, the following construction algorithm MUST be performed. - During the construction of an AudioWorkletNode, a + During the construction of an {{AudioWorkletNode}}, a corresponding {{AudioWorkletProcessor}} instance is also automatically created in the {{AudioWorkletGlobalScope}}. Note that the instantiation of these object pairs spans the control thread and the rendering thread. - <pre class=argumentdef for="AudioWorkletNode/AudioWorkletNode()"> - context: The {{BaseAudioContext}} this new {{AudioWorkletNode}} will be <a href="#associated">associated</a> with. - name: A string that is a key for the {{BaseAudioContext}}’s <a>node name to parameter descriptor map</a>. - options: Optional initial parameters value for this {{AudioWorkletNode}}. - </pre> - <div algorithm="AudioWorkletNode()"> When {{AudioWorkletNode()|AudioWorkletNode}}( {{AudioWorkletNode/AudioWorkletNode(context, name, options)/context}}, @@ -9916,7 +9918,7 @@ Constructors</h5> check throws any exception, propagate the exception and abort these steps. - 1. If <var>nodeName</var> does not exists as a key in the + 1. If <var>nodeName</var> does not exist as a key in the {{BaseAudioContext}}’s <a>node name to parameter descriptor map</a>, throw a {{InvalidStateError}} exception and abort these steps. From c5c60339f1e2d0d4e162f38ec2ccf0d169cd5fc0 Mon Sep 17 00:00:00 2001 From: Hongchan Choi <hongchan.choi@gmail.com> Date: Wed, 7 Aug 2019 14:33:32 -0700 Subject: [PATCH 12/14] fixed indentation, and rearrange text for clarification --- index.bs | 204 +++++++++++++++++++++++++++---------------------------- 1 file changed, 99 insertions(+), 105 deletions(-) diff --git a/index.bs b/index.bs index 8c8bd079f..e5370a2d2 100644 --- a/index.bs +++ b/index.bs @@ -9895,128 +9895,122 @@ Constructors</h5> options: Optional initial parameters value for this {{AudioWorkletNode}}. </pre> - When the constructor of {{AudioWorkletNode}} is invoked in the - main global scope, the following construction algorithm MUST be - performed. + When the constructor was called, the user agent MUST perform the + following steps on the control thread: - During the construction of an {{AudioWorkletNode}}, a - corresponding {{AudioWorkletProcessor}} instance is also - automatically created in the {{AudioWorkletGlobalScope}}. - Note that the instantiation of these object pairs spans the - control thread and the rendering thread. + <div algorithm="AudioWorkletNode()"> + When the {{AudioWorkletNode()|AudioWorkletNode}} constructor + is invoked with <var ignore>context</var>, <var>nodeName</var>, <var>options</var>: - <div algorithm="AudioWorkletNode()"> - When {{AudioWorkletNode()|AudioWorkletNode}}( - {{AudioWorkletNode/AudioWorkletNode(context, name, options)/context}}, - {{AudioWorkletNode/AudioWorkletNode(context, name, options)/name|nodeName}}, - {{AudioWorkletNode/AudioWorkletNode(context, name, options)/options}}) - constructor is invoked, the user agent MUST perform the - following steps on the control thread, where the constructor was - called. + 1. Perform the validity check on <var>options</var>. If the + check throws any exception, propagate the exception + and abort these steps. - 1. Perform the validity check on <var>options</var>. If the - check throws any exception, propagate the exception - and abort these steps. + 1. If <var>nodeName</var> does not exist as a key in the + {{BaseAudioContext}}’s <a>node name to parameter + descriptor map</a>, throw a {{InvalidStateError}} + exception and abort these steps. - 1. If <var>nodeName</var> does not exist as a key in the - {{BaseAudioContext}}’s <a>node name to parameter - descriptor map</a>, throw a {{InvalidStateError}} - exception and abort these steps. + 1. Let <var>node</var> be the instance being created by the + constructor of the {{AudioWorkletNode}} or its subclass. - 1. Let <var>node</var> be the instance being created by the - constructor of the {{AudioWorkletNode}} or its subclass. + 1. Let <var>messageChannel</var> be a new {{MessageChannel}}. - 1. Let <var>messageChannel</var> be a new {{MessageChannel}}. + 1. Let <var>nodePort</var> be the value of + <var>messageChannel</var>'s {{MessageChannel/port1}} attribute. - 1. Let <var>nodePort</var> be the value of - <var>messageChannel</var>'s {{MessageChannel/port1}} attribute. + 1. Let <var>processorPortOnThisSide</var> be the value of + <var>messageChannel</var>'s {{MessageChannel/port2}} attribute. - 1. Let <var>processorPortOnThisSide</var> be the value of - <var>messageChannel</var>'s {{MessageChannel/port2}} attribute. + 1. Let <var>serializedProcessorPort</var> be the result of + [$StructuredSerializeWithTransfer$](<var>processorPortOnThisSide</var>, + « <var>processorPortOnThisSide</var> »). - 1. Let <var>serializedProcessorPort</var> be the result of - [$StructuredSerializeWithTransfer$](<var>processorPortOnThisSide</var>, - « <var>processorPortOnThisSide</var> »). + 1. <a href="https://heycam.github.io/webidl/#dictionary-to-es">Convert</a> + <var>options</var> dictionary to <var>optionsObject</var>. - 1. <a href="https://heycam.github.io/webidl/#dictionary-to-es">Convert</a> - <var>options</var> dictionary to <var>optionsObject</var>. + 1. Let <var>serializedOptions</var> be the result of + [$StructuredSerialize$](<var>optionsObject</var>). - 1. Let <var>serializedOptions</var> be the result of - [$StructuredSerialize$](<var>optionsObject</var>). + 1. Set <var>node</var>'s {{AudioWorkletNode/port}} to <var>nodePort</var>. - 1. Set <var>node</var>'s {{AudioWorkletNode/port}} to <var>nodePort</var>. + 1. Let <var>parameterDescriptors</var> be the result of retrieval + of <var>nodeName</var> from <a>node name to parameter descriptor map</a>: - 1. Let <var>parameterDescriptors</var> be the result of retrieval - of <var>nodeName</var> from <a>node name to parameter descriptor map</a>: + 1. Let <var>audioParamMap</var> be a new {{AudioParamMap}} object. - 1. Let <var>audioParamMap</var> be a new {{AudioParamMap}} object. + 1. For each <var>descriptor</var> of + <var>parameterDescriptors</var>: - 1. For each <var>descriptor</var> of - <var>parameterDescriptors</var>: + 1. Let <var>paramName</var> be the value of + {{AudioParamDescriptor/name}} member in + <var>descriptor</var>. - 1. Let <var>paramName</var> be the value of - {{AudioParamDescriptor/name}} member in - <var>descriptor</var>. - - 1. Let <var>audioParam</var> be a new - {{AudioParam}} instance with - {{AudioParamDescriptor/automationRate}}, - {{AudioParamDescriptor/defaultValue}}, - {{AudioParamDescriptor/minValue}}, and - {{AudioParamDescriptor/maxValue}} - having values equal to the values of - corresponding members on - <var>descriptor</var>. - - 1. Append a key-value pair - <var>paramName</var> → - <var>audioParam</var> to - <var>audioParamMap</var>'s - entries. - - 1. If {{AudioWorkletNodeOptions/parameterData}} is - present on <var>options</var>, perform the - following steps: - - 1. Let <var>parameterData</var> be the value of - {{AudioWorkletNodeOptions/parameterData}}. - - 1. For each <var>paramName</var> → - <var>paramValue</var> of - <var>parameterData</var>: - - 1. If there exists a map entry on - <var>audioParamMap</var> with - key <var>paramName</var>, let - <var>audioParamInMap</var> be - such entry. - - 1. Set {{AudioParam/value}} property - of <var>audioParamInMap</var> - to <var>paramValue</var>. - - 1. For each key-value pair <var>paramNameInOption</var> - → <var>paramValue</var> of <var>options</var>: - - 1. If there exists an entry with name member - equal to <var>paramNameInOption</var> - inside <var>audioParamMap</var>, - set that {{AudioParam}}'s value to - <var>paramValue</var>. - - 1. Set <var>node</var>'s {{AudioWorkletNode/parameters}} to <var>audioParamMap</var>. - - 1. <a>Queue a control message</a> to invoke the - {{AudioWorkletProcessor()|constructor}} of - the corresponding {{AudioWorkletProcessor}} with - the [=processor construction data=] that consists of: - <var>nodeName</var>, - <var>serializedProcessorPort</var>, - <var>serializedOptions</var>, - and <var>node</var>. + 1. Let <var>audioParam</var> be a new + {{AudioParam}} instance with + {{AudioParamDescriptor/automationRate}}, + {{AudioParamDescriptor/defaultValue}}, + {{AudioParamDescriptor/minValue}}, and + {{AudioParamDescriptor/maxValue}} + having values equal to the values of + corresponding members on + <var>descriptor</var>. + + 1. Append a key-value pair + <var>paramName</var> → + <var>audioParam</var> to + <var>audioParamMap</var>'s + entries. + + 1. If {{AudioWorkletNodeOptions/parameterData}} is + present on <var>options</var>, perform the + following steps: + + 1. Let <var>parameterData</var> be the value of + {{AudioWorkletNodeOptions/parameterData}}. - 1. Return <var>node</var>. - </div> + 1. For each <var>paramName</var> → + <var>paramValue</var> of + <var>parameterData</var>: + + 1. If there exists a map entry on + <var>audioParamMap</var> with + key <var>paramName</var>, let + <var>audioParamInMap</var> be + such entry. + + 1. Set {{AudioParam/value}} property + of <var>audioParamInMap</var> + to <var>paramValue</var>. + + 1. For each key-value pair <var>paramNameInOption</var> + → <var>paramValue</var> of <var>options</var>: + + 1. If there exists an entry with name member + equal to <var>paramNameInOption</var> + inside <var>audioParamMap</var>, + set that {{AudioParam}}'s value to + <var>paramValue</var>. + + 1. Set <var>node</var>'s {{AudioWorkletNode/parameters}} to <var>audioParamMap</var>. + + 1. <a>Queue a control message</a> to invoke the + {{AudioWorkletProcessor()|constructor}} of + the corresponding {{AudioWorkletProcessor}} with + the [=processor construction data=] that consists of: + <var>nodeName</var>, + <var>serializedProcessorPort</var>, + <var>serializedOptions</var>, + and <var>node</var>. + + 1. Return <var>node</var>. + </div> + + During the construction of an {{AudioWorkletNode}}, a + corresponding {{AudioWorkletProcessor}} instance is also + automatically created in the {{AudioWorkletGlobalScope}}. + Note that the instantiation of these object pairs spans the + control thread and the rendering thread. </dl> <h5 id="AudioWorkletNode-attributes"> From a308aae6395946659d1a07e53cd1b28159170f02 Mon Sep 17 00:00:00 2001 From: Hongchan Choi <hongchan.choi@gmail.com> Date: Thu, 8 Aug 2019 10:42:29 -0700 Subject: [PATCH 13/14] address comments from @rtoy --- index.bs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/index.bs b/index.bs index e5370a2d2..60b4afc8d 100644 --- a/index.bs +++ b/index.bs @@ -9855,7 +9855,7 @@ the absence of any connected inputs. Once the construction of the node is completed, <dfn>processor construction data</dfn> will be created and -trasnferred to the matching {{AudioWorkletProcessor}}'s +transferred to the matching {{AudioWorkletProcessor}}'s {{AudioWorkletProcessor()|constructor}}. This data contains a set of objects and references that is required for {{AudioWorkletProcessor}}'s construction. @@ -10181,13 +10181,6 @@ Constructors</h5> When the constructor for {{AudioWorkletProcessor}} is invoked, the following steps are performed on the <a>rendering thread</a>. - If any of these steps throws an exception, abort the rest of - steps and <a>queue a task</a> to fire an - <a href="https://www.w3.org/TR/html50/webappapis.html#the-errorevent-interface">ErrorEvent</a> - named <code>processorerror</code> at the {{AudioWorkletNode}} - on the <a>control thread</a> with the relevant information about - the error. - <div algorithm="AudioWorkletProcessor()"> This constructor is invoked by processing a control message queued by the {{AudioWorkletNode()|constructor}} @@ -10199,6 +10192,13 @@ Constructors</h5> <var>serializedOptions</var>, and <var>node</var>. + If any of these steps throws an exception, abort the rest of + steps and <a>queue a task</a> to fire an + <a href="https://www.w3.org/TR/html50/webappapis.html#the-errorevent-interface">ErrorEvent</a> + named <code>processorerror</code> at the {{AudioWorkletNode}} + on the <a>control thread</a> with the relevant information about + the error. + 1. If there is no [=processor construction data=] passed from the associated {{AudioWorkletNode}}, throw a {{TypeError}}. From f5cf604e9ebd0059fa79e2f78c453647c190891c Mon Sep 17 00:00:00 2001 From: Hongchan Choi <hongchan.choi@gmail.com> Date: Thu, 8 Aug 2019 11:21:59 -0700 Subject: [PATCH 14/14] move the paragraph to clarify the definition of processor construction data --- index.bs | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/index.bs b/index.bs index 60b4afc8d..84cb31984 100644 --- a/index.bs +++ b/index.bs @@ -9853,13 +9853,6 @@ Every {{AudioWorkletProcessor}} has an associated <dfn>active source</dfn> flag, the node to be retained in memory and perform audio processing in the absence of any connected inputs. -Once the construction of the node is completed, -<dfn>processor construction data</dfn> will be created and -transferred to the matching {{AudioWorkletProcessor}}'s -{{AudioWorkletProcessor()|constructor}}. This data contains -a set of objects and references that is required for -{{AudioWorkletProcessor}}'s construction. - <xmp class="idl"> [Exposed=Window] interface AudioParamMap { @@ -9895,6 +9888,14 @@ Constructors</h5> options: Optional initial parameters value for this {{AudioWorkletNode}}. </pre> + Once the construction of the node is completed, + <dfn dfn>processor construction data</dfn> will be created and + transferred to the matching {{AudioWorkletProcessor}}'s + {{AudioWorkletProcessor()|constructor}}. This data contains + a set of objects and references that is required for + {{AudioWorkletProcessor}}'s construction. See the step 12 in + the algorithm below. + When the constructor was called, the user agent MUST perform the following steps on the control thread: