Add AudioWorklet section #869

Merged
merged 14 commits into from Aug 19, 2016

Projects

None yet

8 participants

@hoch
Member
hoch commented Jun 29, 2016

PTAL.

Preview: http://hoch.github.io/web-audio-api/#AudioWorklet

I did not remove the AudioWorker section yet per @rtoy's suggestion. Once we settle on this change, I will submit another PR to remove the section.

@rtoy rtoy and 1 other commented on an outdated diff Jun 29, 2016
@@ -4975,6 +4975,621 @@ <h2 id="AudioWorkerParamDescriptor">
</section>
</section>
</section>
+ <section>
+ <h2 id="AudioWorklet">
+ The <dfn>AudioWorklet</dfn> interface
+ </h2>
+ <p>
+ The AudioWorklet object allows importing user-supplied Javascript code
@rtoy
rtoy Jun 29, 2016 Contributor

I think the style is to use either <code>AudioWorklet</code> or <a><code>AudioWorklet</code></a> if you want a link.

@hoch
hoch Jun 29, 2016 Member

This paragraph is about AudioWorklet. Does it still need to be linked to itself?

@hoch
hoch Jun 29, 2016 Member

I'll fix the rest of <a> to <code>.

@hoch
hoch Jun 29, 2016 Member

Done.

@rtoy rtoy and 1 other commented on an outdated diff Jun 29, 2016
@@ -4975,6 +4975,621 @@ <h2 id="AudioWorkerParamDescriptor">
</section>
</section>
</section>
+ <section>
+ <h2 id="AudioWorklet">
+ The <dfn>AudioWorklet</dfn> interface
+ </h2>
+ <p>
+ The AudioWorklet object allows importing user-supplied Javascript code
+ that runs on the audio rendering thread. This processing mechanism
+ ensures the aligned execution of the script code with other built-in
+ <a>AudioNode</a>s in the audio graph. The AudioWorklet object imports
+ and stores the definition of custom audio processor and then an
@rtoy
rtoy Jun 29, 2016 Contributor

"processor" -> "processors"? If you want singular, then "of custom" -> "of a custom audio".

@hoch
hoch Jun 29, 2016 Member

Rephrased.

@rtoy rtoy and 1 other commented on an outdated diff Jun 29, 2016
@@ -4975,6 +4975,621 @@ <h2 id="AudioWorkerParamDescriptor">
</section>
</section>
</section>
+ <section>
+ <h2 id="AudioWorklet">
+ The <dfn>AudioWorklet</dfn> interface
+ </h2>
+ <p>
+ The AudioWorklet object allows importing user-supplied Javascript code
+ that runs on the audio rendering thread. This processing mechanism
+ ensures the aligned execution of the script code with other built-in
+ <a>AudioNode</a>s in the audio graph. The AudioWorklet object imports
+ and stores the definition of custom audio processor and then an
+ <a>AudioWorkletNode</a> object can be constructed based on the
+ processor definition. Note that the registered definition in an
+ AudioWorklet is valid for the entire global scope, therefore any
+ <a>AudioContext</a> in the same global scope can be used to create the
@rtoy
rtoy Jun 29, 2016 edited Contributor

Add <code> for AudioContext.

@hoch
hoch Jun 29, 2016 Member

Done.

@rtoy rtoy and 1 other commented on an outdated diff Jun 29, 2016
+ </h2>
+ <p>
+ The AudioWorklet object allows importing user-supplied Javascript code
+ that runs on the audio rendering thread. This processing mechanism
+ ensures the aligned execution of the script code with other built-in
+ <a>AudioNode</a>s in the audio graph. The AudioWorklet object imports
+ and stores the definition of custom audio processor and then an
+ <a>AudioWorkletNode</a> object can be constructed based on the
+ processor definition. Note that the registered definition in an
+ AudioWorklet is valid for the entire global scope, therefore any
+ <a>AudioContext</a> in the same global scope can be used to create the
+ custom node.
+ </p>
+ <p>
+ An AudioWorklet object provides the capability to import module
+ scripts into its associated <a>AudioWorkletGlobalScope</a>. The user
@rtoy
rtoy Jun 29, 2016 Contributor

Line 4995-4996 is a bit redundant since you already said that in lines 4986.

@hoch
hoch Jun 29, 2016 Member

Rephrased.

@rtoy rtoy and 1 other commented on an outdated diff Jun 29, 2016
+ The AudioWorklet object allows importing user-supplied Javascript code
+ that runs on the audio rendering thread. This processing mechanism
+ ensures the aligned execution of the script code with other built-in
+ <a>AudioNode</a>s in the audio graph. The AudioWorklet object imports
+ and stores the definition of custom audio processor and then an
+ <a>AudioWorkletNode</a> object can be constructed based on the
+ processor definition. Note that the registered definition in an
+ AudioWorklet is valid for the entire global scope, therefore any
+ <a>AudioContext</a> in the same global scope can be used to create the
+ custom node.
+ </p>
+ <p>
+ An AudioWorklet object provides the capability to import module
+ scripts into its associated <a>AudioWorkletGlobalScope</a>. The user
+ agent can then create <a>AudioWorkletProcessor</a> classes registered
+ on the <a>AudioWorkletGlobalScopes</a> and construct their instances.
@rtoy
rtoy Jun 29, 2016 Contributor

Move the "s" of AudioWorkletGlobalScope outside the tag. The link won't work as is.

@hoch
hoch Jun 29, 2016 Member

Rephrased - does not exist anymore.

@rtoy rtoy and 1 other commented on an outdated diff Jun 29, 2016
+ <a>AudioNode</a>s in the audio graph. The AudioWorklet object imports
+ and stores the definition of custom audio processor and then an
+ <a>AudioWorkletNode</a> object can be constructed based on the
+ processor definition. Note that the registered definition in an
+ AudioWorklet is valid for the entire global scope, therefore any
+ <a>AudioContext</a> in the same global scope can be used to create the
+ custom node.
+ </p>
+ <p>
+ An AudioWorklet object provides the capability to import module
+ scripts into its associated <a>AudioWorkletGlobalScope</a>. The user
+ agent can then create <a>AudioWorkletProcessor</a> classes registered
+ on the <a>AudioWorkletGlobalScopes</a> and construct their instances.
+ A processor object represents an audio processing module that runs on
+ the audio <a>rendering thread</a>. After the processor definition is
+ successfully stored, an instance of <a>AudioWorkletNode</a> can be
@rtoy
rtoy Jun 29, 2016 Contributor

"instance of AudioWorkletNode" -> "instance of an AudioWorkletNode"

@hoch
hoch Jun 29, 2016 Member

Done.

@rtoy rtoy and 1 other commented on an outdated diff Jun 29, 2016
+ agent can then create <a>AudioWorkletProcessor</a> classes registered
+ on the <a>AudioWorkletGlobalScopes</a> and construct their instances.
+ A processor object represents an audio processing module that runs on
+ the audio <a>rendering thread</a>. After the processor definition is
+ successfully stored, an instance of <a>AudioWorkletNode</a> can be
+ created in the main global scope. This is the counterpart of the
+ processor but lives on the main <a>control thread</a>. These two
+ components can communicate via message passing.
+ </p>
+ <dl title="interface AudioWorklet : Worklet" class="idl">
+ <dt>
+ Promise&lt;void&gt; import(DOMString moduleUrl)
+ </dt>
+ <dd>
+ <p>
+ Imports a module script returns a promise once it is fully loaded.
@rtoy
rtoy Jun 29, 2016 Contributor

"script returns" -> "script and returns"
"promise once it is fully loaded" should be rephrased. Maybe returns a promise that resolves when fully loaded?

@hoch
hoch Jun 29, 2016 Member

Done.

@rtoy rtoy and 1 other commented on an outdated diff Jun 29, 2016
+ Promise&lt;void&gt; import(DOMString moduleUrl)
+ </dt>
+ <dd>
+ <p>
+ Imports a module script returns a promise once it is fully loaded.
+ </p>
+ </dd>
+ </dl>
+
+ <h3>
+ Construction Procedure of AudioWorkletNode and AudioWorkletProcessor
+ </h3>
+ <p>
+ The construction procedure of <a>AudioWokletNode</a> and the
+ corresponding <a>AudioWorkletProcessor</a> object consists of several
+ coordinated interactions and the following algorithm specifies such
@rtoy
rtoy Jun 29, 2016 Contributor

"such" -> "the"

@hoch
hoch Jun 29, 2016 Member

Done.

@rtoy rtoy and 1 other commented on an outdated diff Jun 29, 2016
+ </dd>
+ </dl>
+
+ <h3>
+ Construction Procedure of AudioWorkletNode and AudioWorkletProcessor
+ </h3>
+ <p>
+ The construction procedure of <a>AudioWokletNode</a> and the
+ corresponding <a>AudioWorkletProcessor</a> object consists of several
+ coordinated interactions and the following algorithm specifies such
+ procedure. Note that these steps must be performed in an atomic
+ fashion.
+ </p>
+ <ol>
+ <li>
+ <em>In the window scope</em>: Start AudioWorkletNode constructor.
@rtoy
rtoy Jun 29, 2016 Contributor

If each item is going to have <em> around the beginning phrase, then should this list be a dl list?

@hoch
hoch Jun 29, 2016 Member

I think this is a simple 'decorator', not the title of an item. Making it italic makes sense to me, but I am open to better alternatives.

@rtoy
rtoy Jun 30, 2016 Contributor

After seeing the full text, I'm ok with leaving this as is.

@rtoy rtoy and 1 other commented on an outdated diff Jun 29, 2016
+ Construction Procedure of AudioWorkletNode and AudioWorkletProcessor
+ </h3>
+ <p>
+ The construction procedure of <a>AudioWokletNode</a> and the
+ corresponding <a>AudioWorkletProcessor</a> object consists of several
+ coordinated interactions and the following algorithm specifies such
+ procedure. Note that these steps must be performed in an atomic
+ fashion.
+ </p>
+ <ol>
+ <li>
+ <em>In the window scope</em>: Start AudioWorkletNode constructor.
+ </li>
+ <li>
+ <em>In the AudioWorkletGlobalScope</em>: Locate a registered
+ AudioWorkletProcessor subclass based on name argument. If none is
@rtoy
rtoy Jun 29, 2016 Contributor

"on name" -> "on the name"

@rtoy
rtoy Jun 29, 2016 Contributor

AudioWorkletProcessor -> <a><code>AudioWorkletProcessor</code></a>?

@hoch
hoch Jun 29, 2016 Member

Done.

@rtoy rtoy and 1 other commented on an outdated diff Jun 29, 2016
+ coordinated interactions and the following algorithm specifies such
+ procedure. Note that these steps must be performed in an atomic
+ fashion.
+ </p>
+ <ol>
+ <li>
+ <em>In the window scope</em>: Start AudioWorkletNode constructor.
+ </li>
+ <li>
+ <em>In the AudioWorkletGlobalScope</em>: Locate a registered
+ AudioWorkletProcessor subclass based on name argument. If none is
+ found, or if subclass does not extend AudioWorkletProcessor, throw
+ an exception from the node constructor.
+ <ol>
+ <li>
+ Start registered constructor for custom processor subclass,
@rtoy
rtoy Jun 29, 2016 Contributor

What do you mean by "start" here? How do you "start" a constructor? Is this supposed to be some kind of async operation?

@hoch
hoch Jun 29, 2016 Member

By 'start' I meant beginning the constructor method. Is "invoke" or "initiate" better?

@rtoy
rtoy Jun 30, 2016 Contributor

If this start and the end (below) is meant to describe how to construct this, it might be clearer to do something like

  1. Construct Foo as follows:
    1. Do this
    2. Do that

Not sure if this is what you're trying to say.

@rtoy rtoy and 1 other commented on an outdated diff Jun 29, 2016
+ procedure. Note that these steps must be performed in an atomic
+ fashion.
+ </p>
+ <ol>
+ <li>
+ <em>In the window scope</em>: Start AudioWorkletNode constructor.
+ </li>
+ <li>
+ <em>In the AudioWorkletGlobalScope</em>: Locate a registered
+ AudioWorkletProcessor subclass based on name argument. If none is
+ found, or if subclass does not extend AudioWorkletProcessor, throw
+ an exception from the node constructor.
+ <ol>
+ <li>
+ Start registered constructor for custom processor subclass,
+ passing structured clone of the options object that was provided
@rtoy
rtoy Jun 29, 2016 Contributor

"passing structure" -> "passing a structured"

@hoch
hoch Jun 29, 2016 Member

Done.

@rtoy rtoy and 1 other commented on an outdated diff Jun 29, 2016
+ found, or if subclass does not extend AudioWorkletProcessor, throw
+ an exception from the node constructor.
+ <ol>
+ <li>
+ Start registered constructor for custom processor subclass,
+ passing structured clone of the options object that was provided
+ to AudioWorkletNode.
+ </li>
+ <li>
+ Start super constructor for AudioWorkletProcessor.
+ </li>
+ <li>
+ Initialize the processor’s states.
+ </li>
+ <li>
+ End the construction of an AudioWorkletProcessor and return to
@rtoy
rtoy Jun 29, 2016 Contributor

How do you "end" the construction?

@hoch
hoch Jun 29, 2016 Member

Is "the construction method ends" better?

@hoch
hoch Jun 29, 2016 Member

Done.

@rtoy rtoy and 1 other commented on an outdated diff Jun 29, 2016
+ to AudioWorkletNode.
+ </li>
+ <li>
+ Start super constructor for AudioWorkletProcessor.
+ </li>
+ <li>
+ Initialize the processor’s states.
+ </li>
+ <li>
+ End the construction of an AudioWorkletProcessor and return to
+ AudioWorkletNode constructor.
+ </li>
+ </ol>
+ </li>
+ <li>
+ <em>In the window scope</em>: Construct AudioParam objects in the node
@rtoy
rtoy Jun 29, 2016 Contributor

AudioParam -> <a><code>AudioParam</code></a>

@hoch
hoch Jun 29, 2016 Member

Done.

@rtoy rtoy and 1 other commented on an outdated diff Jun 29, 2016
+ <li>
+ Start super constructor for AudioWorkletProcessor.
+ </li>
+ <li>
+ Initialize the processor’s states.
+ </li>
+ <li>
+ End the construction of an AudioWorkletProcessor and return to
+ AudioWorkletNode constructor.
+ </li>
+ </ol>
+ </li>
+ <li>
+ <em>In the window scope</em>: Construct AudioParam objects in the node
+ based on the information from the processor’s
+ parameterDescriptors getter and initialize parameter values from
@rtoy
rtoy Jun 29, 2016 Contributor

parameterDescriptors -> <code>parameterDescriptors</code>. Maybe add a tag if there's a dfn for it.

@hoch
hoch Jun 29, 2016 Member

Done.

@rtoy rtoy and 1 other commented on an outdated diff Jun 29, 2016
+ </li>
+ <li>
+ Initialize the processor’s states.
+ </li>
+ <li>
+ End the construction of an AudioWorkletProcessor and return to
+ AudioWorkletNode constructor.
+ </li>
+ </ol>
+ </li>
+ <li>
+ <em>In the window scope</em>: Construct AudioParam objects in the node
+ based on the information from the processor’s
+ parameterDescriptors getter and initialize parameter values from
+ options where the keys match names declared in
+ AudioParamDescriptors.
@rtoy
rtoy Jun 29, 2016 Contributor

AudioParamDescriptors -> <code>AudioParamDescriptor</code>s. Maybe add <a> tag to create a link.

@hoch
hoch Jun 29, 2016 Member

It is rephrased and does not exist anymore.

@rtoy rtoy and 1 other commented on an outdated diff Jun 29, 2016
+ based on the information from the processor’s
+ parameterDescriptors getter and initialize parameter values from
+ options where the keys match names declared in
+ AudioParamDescriptors.
+ </li>
+ <li>
+ <em>In the window scope</em>: Return from the AudioWorkletNode
+ constructor.
+ </li>
+ </ol>
+ <section>
+ <h2 id="AudioWorkletNode">
+ The <dfn>AudioWorkletNode</dfn> interface
+ </h2>
+ <p>
+ This interface represens an <a>AudioNode</a> which lives on the main
@rtoy
rtoy Jun 29, 2016 Contributor

Typo: "represens"

@hoch
hoch Jun 29, 2016 Member

Done.

@rtoy rtoy and 1 other commented on an outdated diff Jun 29, 2016
+ options where the keys match names declared in
+ AudioParamDescriptors.
+ </li>
+ <li>
+ <em>In the window scope</em>: Return from the AudioWorkletNode
+ constructor.
+ </li>
+ </ol>
+ <section>
+ <h2 id="AudioWorkletNode">
+ The <dfn>AudioWorkletNode</dfn> interface
+ </h2>
+ <p>
+ This interface represens an <a>AudioNode</a> which lives on the main
+ control thread. The user can create this node from an instance of
+ <a>AudioContext</a> and such node can be connected with other built-in
@rtoy
rtoy Jun 29, 2016 Contributor

Add <code> around AudioContext.

"such node" -> "such a node"

@hoch
hoch Jun 29, 2016 Member

Done.

@rtoy rtoy and 1 other commented on an outdated diff Jun 29, 2016
+ <em>In the window scope</em>: Return from the AudioWorkletNode
+ constructor.
+ </li>
+ </ol>
+ <section>
+ <h2 id="AudioWorkletNode">
+ The <dfn>AudioWorkletNode</dfn> interface
+ </h2>
+ <p>
+ This interface represens an <a>AudioNode</a> which lives on the main
+ control thread. The user can create this node from an instance of
+ <a>AudioContext</a> and such node can be connected with other built-in
+ <a>AudioNode</a>s to form an audio graph.
+ </p>
+ <dl title=
+ "[Constructor(AudioContext context, DOMString name, optional AudioWorkletNodeOptions options)] interface AudioWorkletNode : AudioNode"
@rtoy
rtoy Jun 29, 2016 Contributor

Are we explicitly disallowing creating an audio worklet from an offline context?

@hoch
hoch Jun 29, 2016 Member

No. Then I should change it to 'BaseAudioContext context'.

@hoch
hoch Jun 29, 2016 Member

Done.

@rtoy rtoy and 1 other commented on an outdated diff Jun 29, 2016
+ </h2>
+ <p>
+ This interface represens an <a>AudioNode</a> which lives on the main
+ control thread. The user can create this node from an instance of
+ <a>AudioContext</a> and such node can be connected with other built-in
+ <a>AudioNode</a>s to form an audio graph.
+ </p>
+ <dl title=
+ "[Constructor(AudioContext context, DOMString name, optional AudioWorkletNodeOptions options)] interface AudioWorkletNode : AudioNode"
+ class="idl">
+ <dt>
+ attribute EventHandler onmessage
+ </dt>
+ <dd>
+ <p>
+ The onmessage handler is called whenever the associated
@rtoy
rtoy Jun 29, 2016 Contributor

"onmessage" -> <code>onmessage</code>

@hoch
hoch Jun 29, 2016 Member

Done.

@rtoy rtoy and 1 other commented on an outdated diff Jun 29, 2016
+ attribute EventHandler onmessage
+ </dt>
+ <dd>
+ <p>
+ The onmessage handler is called whenever the associated
+ <a>AudioWorkletProcessor</a> posts a message back to the main
+ thread.
+ </p>
+ </dd>
+ <dt>
+ void postMessage(any message, optional sequence&lt;Transferable&gt;
+ transfer)
+ </dt>
+ <dd>
+ <p>
+ postMessage May be called to send a message to the corresponding
@rtoy
rtoy Jun 29, 2016 Contributor

"postMessage" -> <code>postMessage</code>

Typo: "May" -> "may"

@hoch
hoch Jun 29, 2016 Member

Done.

@rtoy rtoy and 1 other commented on an outdated diff Jun 29, 2016
+ <dd>
+ <p>
+ The onmessage handler is called whenever the associated
+ <a>AudioWorkletProcessor</a> posts a message back to the main
+ thread.
+ </p>
+ </dd>
+ <dt>
+ void postMessage(any message, optional sequence&lt;Transferable&gt;
+ transfer)
+ </dt>
+ <dd>
+ <p>
+ postMessage May be called to send a message to the corresponding
+ <a>AudioWorkletProcessor</a> via the algorithm defined by the
+ Worker specification.
@rtoy
rtoy Jun 29, 2016 Contributor

A link to the work spec would be good. Don't know off-hand the appropriate magic to do this automatically (if even possible).

@hoch
hoch Jun 29, 2016 Member

Currently the respec guide is down, so I'll have to revisit this when the guide comes back on.

@rtoy rtoy and 1 other commented on an outdated diff Jun 29, 2016
+ </dt>
+ <dd>
+ <p>
+ postMessage May be called to send a message to the corresponding
+ <a>AudioWorkletProcessor</a> via the algorithm defined by the
+ Worker specification.
+ </p>
+ </dd>
+ </dl>
+
+ <section>
+ <h2 id="AudioWorkletNodeOptions">
+ AudioWorkletNodeOptions
+ </h2>
+ <p>
+ The AudioNodeOptions dictionary can be used for the custom
@rtoy
rtoy Jun 29, 2016 Contributor

AudioNodeOptions -> <a><code>AudioNodeOptions</code></a>

Did you really mean AudioNodeOptions and not AudioWorkletNodeOptions?

@hoch
hoch Jun 29, 2016 Member

Done.

@rtoy rtoy and 1 other commented on an outdated diff Jun 29, 2016
+ postMessage May be called to send a message to the corresponding
+ <a>AudioWorkletProcessor</a> via the algorithm defined by the
+ Worker specification.
+ </p>
+ </dd>
+ </dl>
+
+ <section>
+ <h2 id="AudioWorkletNodeOptions">
+ AudioWorkletNodeOptions
+ </h2>
+ <p>
+ The AudioNodeOptions dictionary can be used for the custom
+ initialization of <a>AudioNode</a> attributes in the
+ <a>AudioWorkletNode</a> constructor. Entries in this dictionary whose
+ names that correspond to <a>AudioParam</a>s in the class definition of
@rtoy
rtoy Jun 29, 2016 Contributor

"names that correspond" -> "names correspond"

@hoch
hoch Jun 29, 2016 Member

Done.

@rtoy rtoy and 1 other commented on an outdated diff Jun 29, 2016
+ AudioWorkletNodeOptions
+ </h2>
+ <p>
+ The AudioNodeOptions dictionary can be used for the custom
+ initialization of <a>AudioNode</a> attributes in the
+ <a>AudioWorkletNode</a> constructor. Entries in this dictionary whose
+ names that correspond to <a>AudioParam</a>s in the class definition of
+ an <a>AudioWorkletProcessor</a> are used to initialize the parameter
+ values upon the creation of a node.
+ </p>
+ <dl title="dictionary AudioWorkletNodeOptions" class="idl">
+ <dt>
+ unsigned long numberOfInputs
+ </dt>
+ <dd>
+ Similar to <a>numberOfInputs</a> in <a>AudioNode</a>.
@rtoy
rtoy Jun 29, 2016 edited Contributor

Should "similar" be "same"? "Similar" kind of suggests that it's somehow different.

Same comment applies to all of the following descriptions of the members.

Maybe just say these are used to initialize the corresponding attributes for an AudioNode. (Well, you can't actually set numberOfInputs/Outputs of any other AudioNode, so this needs to be phrased differently.)

@hoch
hoch Jun 29, 2016 Member

Yes, I think we still have a unsettled question on this part.

@rtoy rtoy and 1 other commented on an outdated diff Jun 29, 2016
+ </p>
+ <dl title="dictionary AudioWorkletNodeOptions" class="idl">
+ <dt>
+ unsigned long numberOfInputs
+ </dt>
+ <dd>
+ Similar to <a>numberOfInputs</a> in <a>AudioNode</a>.
+ </dd>
+ <dt>
+ unsigned long numberOfOutputs
+ </dt>
+ <dd>
+ Similar to <a>numberOfOutputs</a> in <a>AudioNode</a>.
+ </dd>
+ <dt>
+ unsigned long channelCount
@rtoy
rtoy Jun 29, 2016 Contributor

It would be nice to make AudioWorkletNodeOptions derive from AudioNodeChannelOptions/AudioNodeOptions so you don't have to describe these again. (But AudioNodeOptions isn't in the spec yet, but there is a PR for it.)

@rtoy rtoy and 1 other commented on an outdated diff Jun 29, 2016
+ <dt>
+ ChannelInterpretation channelInterpretation
+ </dt>
+ <dd>
+ Similar to <a>channelInterpretation</a> in <a>AudioNode</a>.
+ </dd>
+ </dl>
+ </section>
+ </section>
+ <section>
+ <h2 id="AudioWorkletGlobalScope">
+ The <dfn>AudioWorkletGlobalScope</dfn> interface
+ </h2>
+ <p>
+ This interface is derived from <a>WorkletGlobalScope</a>
+ representing a special execution context in which an audio
@rtoy
rtoy Jun 29, 2016 Contributor

"representing" -> "and represents" might be a bit better.

@hoch
hoch Jun 29, 2016 Member

Done.

@rtoy rtoy and 1 other commented on an outdated diff Jun 29, 2016
+ </dd>
+ </dl>
+ </section>
+ </section>
+ <section>
+ <h2 id="AudioWorkletGlobalScope">
+ The <dfn>AudioWorkletGlobalScope</dfn> interface
+ </h2>
+ <p>
+ This interface is derived from <a>WorkletGlobalScope</a>
+ representing a special execution context in which an audio
+ processing script is run. It it is designed to enable the
+ generation, processing, and analysis of audio data directly using
+ JavaScript in the audio <a>rendering thread</a>. The user-supplied
+ script code is evaluated in this scope to define
+ <a>AudioWorkletProcessor</a>.
@rtoy
rtoy Jun 29, 2016 edited Contributor

"to define" -> "to define an"

@hoch
hoch Jun 29, 2016 Member

Done.

@rtoy rtoy commented on an outdated diff Jun 29, 2016
+ class="idl">
+ <dt>
+ void registerAudioWorkletProcessor (DOMString name, Function classConstructor)
+ </dt>
+ <dd>
+ <p>
+ Registers a definition of a class that is derived from
+ <a>AudioWorkletProcessor</a>.
+ </p>
+ <dl class="parameters">
+ <dt>
+ DOMString name
+ </dt>
+ <dd>
+ A string key that represents a class definition to be
+ registered. <strong>ISSUE</strong>: The conflict between
@rtoy
rtoy Jun 29, 2016 Contributor

Maybe create an issue and actually link to it?

@rtoy
rtoy Jun 29, 2016 Contributor

Or maybe don't even say this at all in the spec?

@rtoy rtoy commented on an outdated diff Jun 29, 2016
+ </dt>
+ <dd>
+ <p>
+ Registers a definition of a class that is derived from
+ <a>AudioWorkletProcessor</a>.
+ </p>
+ <dl class="parameters">
+ <dt>
+ DOMString name
+ </dt>
+ <dd>
+ A string key that represents a class definition to be
+ registered. <strong>ISSUE</strong>: The conflict between
+ multiple class definitions under the same name needs to be
+ addressed. For the time being, WG’s resolution is to apply the
+ first-come-first- served policy.
@rtoy
rtoy Jun 29, 2016 Contributor

"first- served" -> "first-served" (Remove space)

@rtoy rtoy commented on an outdated diff Jun 29, 2016
+ <p>
+ This interface represents an audio processing module that runs on
+ the audio <a>rendering thread</a>. It is defined in an
+ <a>AudioWorkletGlobalScope</a> and the definition of such class
+ manifests the actual audio processing mechanism of an
+ <a>AudioWorkletNode</a>. <a>AudioWorkletProcessor</a> can only be
+ instantiated by the construction of an <a>AudioWorkletNode</a>
+ instance.
+ </p>
+ <dl title="interface AudioWorkletProcessor" class="idl">
+ <dt>
+ readonly attribute static sequence&lt;AudioParamDescriptor&gt;
+ </dt>
+ <dd>
+ <p>
+ This array contains <a>AudioParamDescriptors</a>, which are
@rtoy
rtoy Jun 29, 2016 Contributor

Move "s" out of the tag for AudioParamDescriptors.

@rtoy rtoy commented on an outdated diff Jun 29, 2016
+ the audio <a>rendering thread</a>. It is defined in an
+ <a>AudioWorkletGlobalScope</a> and the definition of such class
+ manifests the actual audio processing mechanism of an
+ <a>AudioWorkletNode</a>. <a>AudioWorkletProcessor</a> can only be
+ instantiated by the construction of an <a>AudioWorkletNode</a>
+ instance.
+ </p>
+ <dl title="interface AudioWorkletProcessor" class="idl">
+ <dt>
+ readonly attribute static sequence&lt;AudioParamDescriptor&gt;
+ </dt>
+ <dd>
+ <p>
+ This array contains <a>AudioParamDescriptors</a>, which are
+ descriptors for each controllable parameter on an
+ <a>AudioNode</a>. This static property is referred in the
@rtoy
rtoy Jun 29, 2016 Contributor

"referred" -> "referenced"

@rtoy rtoy commented on an outdated diff Jun 29, 2016
+ manifests the actual audio processing mechanism of an
+ <a>AudioWorkletNode</a>. <a>AudioWorkletProcessor</a> can only be
+ instantiated by the construction of an <a>AudioWorkletNode</a>
+ instance.
+ </p>
+ <dl title="interface AudioWorkletProcessor" class="idl">
+ <dt>
+ readonly attribute static sequence&lt;AudioParamDescriptor&gt;
+ </dt>
+ <dd>
+ <p>
+ This array contains <a>AudioParamDescriptors</a>, which are
+ descriptors for each controllable parameter on an
+ <a>AudioNode</a>. This static property is referred in the
+ construction of an <a>AudioWorkletNode</a> to create instances
+ of <a>AudioParam</a> in the node.
@rtoy
rtoy Jun 29, 2016 Contributor

"of AudioParam" -> "of an AudioParam"

@rtoy rtoy commented on an outdated diff Jun 29, 2016
+ </dt>
+ <dd>
+ <p>
+ This array contains <a>AudioParamDescriptors</a>, which are
+ descriptors for each controllable parameter on an
+ <a>AudioNode</a>. This static property is referred in the
+ construction of an <a>AudioWorkletNode</a> to create instances
+ of <a>AudioParam</a> in the node.
+ </p>
+ </dd>
+ <dt>
+ readonly attribute AudioContextInfo contextInfo
+ </dt>
+ <dd>
+ <p>
+ This getter provides an object contains the information of the
@rtoy
rtoy Jun 29, 2016 Contributor

"object contains" -> "object that contains"

@rtoy rtoy commented on an outdated diff Jun 29, 2016
+ <p>
+ This array contains <a>AudioParamDescriptors</a>, which are
+ descriptors for each controllable parameter on an
+ <a>AudioNode</a>. This static property is referred in the
+ construction of an <a>AudioWorkletNode</a> to create instances
+ of <a>AudioParam</a> in the node.
+ </p>
+ </dd>
+ <dt>
+ readonly attribute AudioContextInfo contextInfo
+ </dt>
+ <dd>
+ <p>
+ This getter provides an object contains the information of the
+ associated <a>AudioContext</a> such as the sample rate and the
+ current playback time when queried.
@rtoy
rtoy Jun 29, 2016 Contributor

Since AudioContextInfo object is described somewhere else, don't really need to describe here what it might contain. Leave this out.

@rtoy rtoy and 1 other commented on an outdated diff Jun 29, 2016
+ </p>
+ <dl title="interface AudioWorkletProcessor" class="idl">
+ <dt>
+ readonly attribute static sequence&lt;AudioParamDescriptor&gt;
+ </dt>
+ <dd>
+ <p>
+ This array contains <a>AudioParamDescriptors</a>, which are
+ descriptors for each controllable parameter on an
+ <a>AudioNode</a>. This static property is referred in the
+ construction of an <a>AudioWorkletNode</a> to create instances
+ of <a>AudioParam</a> in the node.
+ </p>
+ </dd>
+ <dt>
+ readonly attribute AudioContextInfo contextInfo
@rtoy
rtoy Jun 29, 2016 Contributor

Is "Info" ok? Should we use the full word?

@hoch
hoch Jun 29, 2016 Member

Good point. This never came up in the discussion yet.

@rtoy rtoy commented on an outdated diff Jun 29, 2016
+ <dt>
+ readonly attribute AudioContextInfo contextInfo
+ </dt>
+ <dd>
+ <p>
+ This getter provides an object contains the information of the
+ associated <a>AudioContext</a> such as the sample rate and the
+ current playback time when queried.
+ </p>
+ </dd>
+ <dt>
+ attribute EventHandler onmessage
+ </dt>
+ <dd>
+ <p>
+ The onmessage handler is called whenever the
@rtoy
rtoy Jun 29, 2016 Contributor

"onmessage" -> <code>onmessage</code>

@rtoy rtoy commented on an outdated diff Jun 29, 2016
+ readonly attribute AudioContextInfo contextInfo
+ </dt>
+ <dd>
+ <p>
+ This getter provides an object contains the information of the
+ associated <a>AudioContext</a> such as the sample rate and the
+ current playback time when queried.
+ </p>
+ </dd>
+ <dt>
+ attribute EventHandler onmessage
+ </dt>
+ <dd>
+ <p>
+ The onmessage handler is called whenever the
+ <a>AudioWorkletNode</a> posts a node message back to the
@rtoy
rtoy Jun 29, 2016 Contributor

Remove "node"?

@rtoy rtoy commented on an outdated diff Jun 29, 2016
+ <dd>
+ <p>
+ This getter provides an object contains the information of the
+ associated <a>AudioContext</a> such as the sample rate and the
+ current playback time when queried.
+ </p>
+ </dd>
+ <dt>
+ attribute EventHandler onmessage
+ </dt>
+ <dd>
+ <p>
+ The onmessage handler is called whenever the
+ <a>AudioWorkletNode</a> posts a node message back to the
+ corresponding processor object on the audio <a>rendering
+ thread</a>.
@rtoy
rtoy Jun 29, 2016 Contributor

Leave out the phrase "on the audio..."? The processor object is already defined to be existing on the appropriate thread.

@rtoy rtoy commented on an outdated diff Jun 29, 2016
+ current playback time when queried.
+ </p>
+ </dd>
+ <dt>
+ attribute EventHandler onmessage
+ </dt>
+ <dd>
+ <p>
+ The onmessage handler is called whenever the
+ <a>AudioWorkletNode</a> posts a node message back to the
+ corresponding processor object on the audio <a>rendering
+ thread</a>.
+ </p>
+ </dd>
+ <dt>
+ void process()
@rtoy
rtoy Jun 29, 2016 Contributor

Don't you need to include the parameters for the process method here? It looks process takes no parameters, but you describe them below.

@rtoy
rtoy Jun 29, 2016 Contributor

Never mind. ReSpec takes care of this; I forgot.

@rtoy rtoy commented on an outdated diff Jun 29, 2016
+ </dt>
+ <dd>
+ <p>
+ The onmessage handler is called whenever the
+ <a>AudioWorkletNode</a> posts a node message back to the
+ corresponding processor object on the audio <a>rendering
+ thread</a>.
+ </p>
+ </dd>
+ <dt>
+ void process()
+ </dt>
+ <dd>
+ <p>
+ This method gets executed isochronously by the audio rendering
+ thread along with the rest of an audio graph while the
@rtoy
rtoy Jun 29, 2016 Contributor

"rest of an" -> "rest of the"

@rtoy
rtoy Jun 29, 2016 Contributor

Actually, I'd consider removing the rest of the sentence starting at "along with the ..."

@rtoy rtoy commented on an outdated diff Jun 29, 2016
+ </dd>
+ <dt>
+ void process()
+ </dt>
+ <dd>
+ <p>
+ This method gets executed isochronously by the audio rendering
+ thread along with the rest of an audio graph while the
+ associated <a>AudioWorkletNode</a> is connected.
+ </p>
+ <dl class="parameters">
+ <dt>
+ Float32Array[][] inputs
+ </dt>
+ <dd>
+ Represents incoming data from inputs of the node. Each input
@rtoy
rtoy Jun 29, 2016 edited Contributor

I think this needs to be expanded upon here (unless you describe that elsewhere that's not an example). You need to describe what the two indices of the array mean.

Same for outputs below.

@rtoy rtoy commented on an outdated diff Jun 29, 2016
+ Represents incoming data from inputs of the node. Each input
+ can contain multiple channels.
+ </dd>
+ <dt>
+ Float32Array[][] outputs
+ </dt>
+ <dd>
+ Represents outgoing data from outputs of the node. Each output
+ can contain multiple channels.
+ </dd>
+ <dt>
+ Object parameters
+ </dt>
+ <dd>
+ Represents an object contains multiple arrays of
+ <a>AudioParam</a> data with the associated name as a key.
@rtoy
rtoy Jun 29, 2016 Contributor

If parameters is described as containing arrays, then should parameters be declared to be an array? Exactly what kind of object is parameters? Is it a dictionary?

@rtoy rtoy commented on an outdated diff Jun 29, 2016
+ <dd>
+ Represents incoming data from inputs of the node. Each input
+ can contain multiple channels.
+ </dd>
+ <dt>
+ Float32Array[][] outputs
+ </dt>
+ <dd>
+ Represents outgoing data from outputs of the node. Each output
+ can contain multiple channels.
+ </dd>
+ <dt>
+ Object parameters
+ </dt>
+ <dd>
+ Represents an object contains multiple arrays of
@rtoy
rtoy Jun 29, 2016 Contributor

"object contains" -> "object that contains"? But see following comment.

@rtoy rtoy commented on an outdated diff Jun 29, 2016
+ <dd>
+ </dd>
+ <dt>
+ optional sequence&lt;Transferable&gt; transfer
+ </dt>
+ <dd>
+ </dd>
+ </dl>
+ </dd>
+ </dl>
+ <section>
+ <h2 id="AudioParamDescriptor">
+ AudioParamDescriptor
+ </h2>
+ <p>
+ The AudioParamDescriptor dictionary is used to specify properties
@rtoy
rtoy Jun 29, 2016 Contributor

<code>AudioParamDescriptor</code>

@rtoy rtoy commented on an outdated diff Jun 29, 2016
+ </dl>
+ <section>
+ <h2 id="AudioParamDescriptor">
+ AudioParamDescriptor
+ </h2>
+ <p>
+ The AudioParamDescriptor dictionary is used to specify properties
+ for an <a>AudioParam</a> object that is used in an
+ <a>AudioWorkletNode</a>.
+ </p>
+ <dl title="dictionary AudioParamDescriptor" class="idl">
+ <dt>
+ DOMString name
+ </dt>
+ <dd>
+ Represents the name of a parameter. An exception will be thrown
@rtoy
rtoy Jun 29, 2016 Contributor

Need to specify what exception is thrown.

"will be" -> "MUST be"

@rtoy rtoy commented on an outdated diff Jun 29, 2016
+ <section>
+ <h2 id="AudioParamDescriptor">
+ AudioParamDescriptor
+ </h2>
+ <p>
+ The AudioParamDescriptor dictionary is used to specify properties
+ for an <a>AudioParam</a> object that is used in an
+ <a>AudioWorkletNode</a>.
+ </p>
+ <dl title="dictionary AudioParamDescriptor" class="idl">
+ <dt>
+ DOMString name
+ </dt>
+ <dd>
+ Represents the name of a parameter. An exception will be thrown
+ when the duplicated name is found when registering the class
@rtoy
rtoy Jun 29, 2016 Contributor

"when the" -> "when a"

@rtoy rtoy commented on an outdated diff Jun 29, 2016
+ <dl title="dictionary AudioParamDescriptor" class="idl">
+ <dt>
+ DOMString name
+ </dt>
+ <dd>
+ Represents the name of a parameter. An exception will be thrown
+ when the duplicated name is found when registering the class
+ definition.
+ </dd>
+ <dt>
+ float defaultValue = 0
+ </dt>
+ <dd>
+ Represents the default value of the parameter. If this value is
+ out of the range of float data type or the range defined by
+ minValue and maxValue, an exception will be thrown.
@rtoy
rtoy Jun 29, 2016 Contributor

"will be" -> "MUST be".

The exception type needs to be specified.

@rtoy
rtoy Jun 29, 2016 Contributor

Presumably minValue <= maxValue. What happens if they're not?

@rtoy rtoy commented on an outdated diff Jun 29, 2016
+ when the duplicated name is found when registering the class
+ definition.
+ </dd>
+ <dt>
+ float defaultValue = 0
+ </dt>
+ <dd>
+ Represents the default value of the parameter. If this value is
+ out of the range of float data type or the range defined by
+ minValue and maxValue, an exception will be thrown.
+ </dd>
+ <dt>
+ float minValue
+ </dt>
+ <dd>
+ Represents the minimum value. An exception will be thrown, if
@rtoy
rtoy Jun 29, 2016 Contributor

MUST be thrown. Exception type needs to be specified. More of the same below.

@rtoy rtoy commented on an outdated diff Jun 29, 2016
+ float maxValue
+ </dt>
+ <dd>
+ Represents the maximum value. An exception will be thrown, if
+ this value is out of range of float data type or it is smaller
+ than minValue.
+ </dd>
+ </dl>
+ </section>
+
+ <section>
+ <h2 id="AudioContextInfo">
+ AudioContextInfo
+ </h2>
+ <p>
+ The AudioContextInfo dictionary is used to query the current
@rtoy
rtoy Jun 29, 2016 edited Contributor

No. The dictionary is used the information from a query. Rephrase this somehow.

@rtoy rtoy commented on an outdated diff Jun 29, 2016
+ The AudioContextInfo dictionary is used to query the current
+ status of the associated <a>AudioContext</a> within the scope of
+ an <a>AudioWorkletProcessor</a>.
+ </p>
+ <dl title="dictionary AudioContextInfo" class="idl">
+ <dt>
+ float playbackTime
+ </dt>
+ <dd>
+ The starting time of the block of audio being processed in
+ response to this event. By definition this will be equal to the
+ value of <a>BaseAudioContext</a>'s <a>currentTime</a> attribute
+ that was most recently observable in the <a>control thread</a>.
+ </dd>
+ <dt>
+ unsigned long sampleRate
@rtoy
rtoy Jun 29, 2016 Contributor

Why unsigned long? Sample rates are floats everywhere else.

@rtoy rtoy commented on an outdated diff Jun 29, 2016
+ </dd>
+ </dl>
+ </section>
+ </section>
+ <section class="informative">
+ <h2 id="AudioWorklet-Examples">
+ AudioWorklet Examples
+ </h2>
+
+ <section>
+ <h3>
+ The BitCrusher Node
+ </h3>
+ <p>
+ Bitcrushing is a mechanism by which the audio quality of an audio
+ stream is reduced - both by quantizing the value (simulating lower
@rtoy
rtoy Jun 29, 2016 Contributor

I don't think there should be spaces around the hyphen. And typographically, I guess some character entity should be used. (emdash?)

@rtoy rtoy commented on an outdated diff Jun 29, 2016
+ <section class="informative">
+ <h2 id="AudioWorklet-Examples">
+ AudioWorklet Examples
+ </h2>
+
+ <section>
+ <h3>
+ The BitCrusher Node
+ </h3>
+ <p>
+ Bitcrushing is a mechanism by which the audio quality of an audio
+ stream is reduced - both by quantizing the value (simulating lower
+ bit-depth in integer-based audio), and by quantizing in time
+ (simulating a lower digital sample rate). This example shows how
+ to use <a>AudioParam</a>s (in this case, treated as
+ <em>a-rate</em>) inside an <a>AudioWorkletProcessor</a>.
@rtoy
rtoy Jun 29, 2016 Contributor

<a>a-rate<a>

@rtoy rtoy commented on an outdated diff Jun 29, 2016
+ </dd>
+ </dl>
+ </section>
+
+ <section>
+ <h2 id="AudioContextInfo">
+ AudioContextInfo
+ </h2>
+ <p>
+ The AudioContextInfo dictionary is used to query the current
+ status of the associated <a>AudioContext</a> within the scope of
+ an <a>AudioWorkletProcessor</a>.
+ </p>
+ <dl title="dictionary AudioContextInfo" class="idl">
+ <dt>
+ float playbackTime
@rtoy
rtoy Jun 29, 2016 Contributor

Time is usually represented by double every else in the spec.

@rtoy
Contributor
rtoy commented Jun 29, 2016

Could you create a page with this PR? It would be nice to be able to read the actual spec text instead of the diff.

@hoch
Member
hoch commented Jun 29, 2016

The preview is in my first comment: http://hoch.github.io/web-audio-api/#AudioWorklet

@padenot padenot commented on an outdated diff Jun 30, 2016
+ </dt>
+ <dd>
+ <p>
+ Imports a module script returns a promise once it is fully loaded.
+ </p>
+ </dd>
+ </dl>
+
+ <h3>
+ Construction Procedure of AudioWorkletNode and AudioWorkletProcessor
+ </h3>
+ <p>
+ The construction procedure of <a>AudioWokletNode</a> and the
+ corresponding <a>AudioWorkletProcessor</a> object consists of several
+ coordinated interactions and the following algorithm specifies such
+ procedure. Note that these steps must be performed in an atomic
@padenot
padenot Jun 30, 2016 Member

Link atomic to its definition.

@rtoy rtoy referenced this pull request Jun 30, 2016
Closed

Fix a couple of WebIDL bugs #884

@padenot padenot commented on an outdated diff Jun 30, 2016
+ ChannelInterpretation channelInterpretation
+ </dt>
+ <dd>
+ Similar to <a>channelInterpretation</a> in <a>AudioNode</a>.
+ </dd>
+ </dl>
+ </section>
+ </section>
+ <section>
+ <h2 id="AudioWorkletGlobalScope">
+ The <dfn>AudioWorkletGlobalScope</dfn> interface
+ </h2>
+ <p>
+ This interface is derived from <a>WorkletGlobalScope</a>
+ representing a special execution context in which an audio
+ processing script is run. It it is designed to enable the
@padenot
padenot Jun 30, 2016 Member

s/is run/runs/

@padenot padenot and 1 other commented on an outdated diff Jun 30, 2016
+ <li>
+ <em>In the window scope</em>: Start AudioWorkletNode constructor.
+ </li>
+ <li>
+ <em>In the AudioWorkletGlobalScope</em>: Locate a registered
+ AudioWorkletProcessor subclass based on name argument. If none is
+ found, or if subclass does not extend AudioWorkletProcessor, throw
+ an exception from the node constructor.
+ <ol>
+ <li>
+ Start registered constructor for custom processor subclass,
+ passing structured clone of the options object that was provided
+ to AudioWorkletNode.
+ </li>
+ <li>
+ Start super constructor for AudioWorkletProcessor.
@padenot
padenot Jun 30, 2016 Member

We should describe this "super" constructor. It's not obvious just yet what it does or why it's needed.

@hoch
hoch Jul 6, 2016 Member

Agree. Will return to it once the first pass is finished.

@padenot padenot and 2 others commented on an outdated diff Jun 30, 2016
+ Object parameters
+ </dt>
+ <dd>
+ Represents an object contains multiple arrays of
+ <a>AudioParam</a> data with the associated name as a key.
+ </dd>
+ </dl>
+ </dd>
+ <dt>
+ void postMessage()
+ </dt>
+ <dd>
+ <p>
+ It may be called to send a message to the
+ <a>AudioWorkletNode</a>, via the algorithm defined by the
+ Worker specification.
@padenot
padenot Jun 30, 2016 Member

Not sure this can work, we don't have an event loop in the rendering thread. We need to hook that up in the processing model chapter.

@padenot
padenot Jun 30, 2016 Member

In particular, when does it run, from the point of view of the rendering thread.

@bfgeek
bfgeek Jun 30, 2016

It's probably easy to say that a postMessage from (main->audio) just queues up the message in a buffer.

The buffer is then emptied right before the process method call is invoked.

I'm assuming the actual timing of the postMessage event isn't important? (if it is can add a time attribute).

@bfgeek
bfgeek Jun 30, 2016

This has the issue that if the onmessage is something like:

onmessage(data) {
  this.postMessage(response);
}

You'll get responses to your messages only once per audio frame. (This is probably acceptable?)

@hoch
hoch Jul 6, 2016 Member

The message passing here is asynchronous, so the timing is not guaranteed to be sample-accurate. Also we can queue up the messages and batch process them when before/after the audio rendering process. (which is something we already have in our architecture)

@rtoy rtoy commented on an outdated diff Jun 30, 2016
+ </p>
+ </dd>
+ </dl>
+ <h2>
+ Construction Procedure of AudioWorkletNode and AudioWorkletProcessor
+ </h2>
+ <p>
+ The construction procedure of <a><code>AudioWokletNode</code></a> and
+ the corresponding <a><code>AudioWorkletProcessor</code></a> object
+ consists of several coordinated interactions and the following
+ algorithm specifies the procedure. Note that these steps must be
+ performed in an atomic fashion.
+ </p>
+ <ol>
+ <li>
+ <em>In the <code>window</code> scope</em>: An
@rtoy
rtoy Jun 30, 2016 Contributor

I find this section rather confusing. I've discussed this with @hongchan on how it might be phrased in possible less confusing (to me) way.

@rtoy rtoy commented on an outdated diff Jun 30, 2016
+ </p>
+ </dd>
+ <dt>
+ void process()
+ </dt>
+ <dd>
+ <p>
+ This method gets executed isochronously by the audio
+ <a>rendering thread</a>.
+ </p>
+ <dl class="parameters">
+ <dt>
+ Float32Array[][] inputs
+ </dt>
+ <dd>
+ An Array of Arrays of <code>Float32Array</code>s. The top-
@rtoy
rtoy Jun 30, 2016 Contributor

Discussed this with @hongchan. I think this we be much clearer if you just said

inputs[n][m] is a Float32Array of audio samples for the m'th channel of the n'th input.

@rtoy
rtoy Jun 30, 2016 Contributor

I guess you still need text to note that the valid values for m can change dynamically (due to connections to input n). The valid values of n are fixed at construction since we can't dynamically change the number of inputs to a node.

@rtoy rtoy commented on an outdated diff Jun 30, 2016
+ level Array is organized by input; each input may contain
+ multiple channels; each channel contains a
+ <code>Float32Array</code> of sample data. The initial size of
+ the channel array will be determined by the number of
+ channels by the <a><code>channelCount</code></a> property in
+ the <a><code>AudioWorkletNodeOptions</code></a> object
+ supplied to the <a><code>AudioWorkletNode</code></a>
+ constructor. However, the number of channels may be altered
+ dynamically by the number of channels in the incoming audio
+ stream.
+ </dd>
+ <dt>
+ Float32Array[][] outputs
+ </dt>
+ <dd>
+ An Array of Arrays of <code>Float32Array</code>s. The top-
@rtoy
rtoy Jun 30, 2016 Contributor

Just say outputs is the same as inputs, except it contains the outputs of the audioworklet.

@rtoy rtoy commented on an outdated diff Jun 30, 2016
+ stream.
+ </dd>
+ <dt>
+ Float32Array[][] outputs
+ </dt>
+ <dd>
+ An Array of Arrays of <code>Float32Array</code>s. The top-
+ level Array is organized by output; each output may contain
+ multiple channels; each channel contains a
+ <code>Float32Array</code> of sample data.
+ </dd>
+ <dt>
+ Object parameters
+ </dt>
+ <dd>
+ This object attribute exposes a correspondingly-named
@rtoy
rtoy Jun 30, 2016 Contributor

I find it really hard to figure out what parameter really is. I discussed this with @hongchan to understand what this is. I think the following text is a bit easier to understand:

parameters provides an association between the names of an AudioParams specified by the AudioParamDescriptors during construction and the automation values for the AudioParam. Thus, parameters[name] returns a Float32Array of the automation values corresponding to the AudioParam named "name".

Probably still need a bit more text, but I think this captures what parameters really contains.

@rtoy rtoy commented on an outdated diff Jul 1, 2016
+ After importing a module script into the
+ <a><code>AudioWorkletGlobalScope</code></a>, an instance of
+ <a><code>AudioWorkletNode</code></a> can be created in the main
+ global scope. At the same time, the user agent automatically creates
+ an instance of <a><code>AudioWorkletProcessor</code></a>. This
+ counterpart represents an audio processing module that runs on the
+ audio <a>rendering thread</a>. These two components can communicate
+ via message passing.
+ </p>
+ <dl title="interface AudioWorklet : Worklet" class="idl">
+ <dt>
+ Promise&lt;void&gt; import(DOMString moduleUrl)
+ </dt>
+ <dd>
+ <p>
+ Imports a module script and returns a promise when fully loaded.
@rtoy
rtoy Jul 1, 2016 Contributor

I don't think you want "when fully loaded". I also think you need to describe what happens to cause the promise to be resolved or rejected. I assume it's resolved when the script is loaded successfully. and it's rejected if there are syntax errors or it doesn't exist or maybe some other conditions?

@rtoy rtoy commented on an outdated diff Jul 1, 2016
+ for the custom initialization of <a><code>AudioNode</code></a>
+ attributes in the <a><code>AudioWorkletNode</code></a>
+ constructor. Entries in this dictionary whose names correspond to
+ <a><code>AudioParam</code></a>s in the class definition of an
+ <a><code>AudioWorkletProcessor</code></a> are used to initialize
+ the parameter values upon the creation of a node.
+ </p>
+ <dl title="dictionary AudioWorkletNodeOptions" class="idl">
+ <dt>
+ unsigned long numberOfInputs
+ </dt>
+ <dd>
+ Same to <a>numberOfInputs</a> in <a>AudioNode</a>.
+ </dd>
+ <dt>
+ unsigned long numberOfOutputs
@rtoy
rtoy Jul 1, 2016 Contributor

Same comments as for numberOfInputs.

@rtoy rtoy commented on an outdated diff Jul 1, 2016
+ unsigned long numberOfInputs
+ </dt>
+ <dd>
+ Same to <a>numberOfInputs</a> in <a>AudioNode</a>.
+ </dd>
+ <dt>
+ unsigned long numberOfOutputs
+ </dt>
+ <dd>
+ Same to <a>numberOfOutputs</a> in <a>AudioNode</a>.
+ </dd>
+ <dt>
+ unsigned long channelCount
+ </dt>
+ <dd>
+ Same to <a>channelCount</a> in <a>AudioNode</a>.
@rtoy
rtoy Jul 1, 2016 Contributor

I really think this should be inherited from AudioNodeOptions/AudioNodeChannelOptions so we can just describe it once there instead of also here. But since that's not in the spec yet, just leave this in for now.

@rtoy
rtoy Jul 1, 2016 Contributor

Actually, maybe it should inherit from AudioNodeOptions AudioNodeOptions dictionary can't specify any defaults because each has its own set of defaults. So, for this to work out, I think you need to either make these members be required and/or specify a default value for each.

@rtoy rtoy commented on an outdated diff Jul 1, 2016
+ <section>
+ <h2 id="AudioWorkletProcessor">
+ The <dfn>AudioWorkletProcessor</dfn> interface
+ </h2>
+ <p>
+ This interface represents an audio processing module that runs on
+ the audio <a>rendering thread</a>. It is defined in an
+ <a><code>AudioWorkletGlobalScope</code></a> and the definition of
+ the class manifests the actual audio processing mechanism of a
+ custom audio node. <a><code>AudioWorkletProcessor</code></a> can
+ only be instantiated by the construction of an
+ <a><code>AudioWorkletNode</code></a> instance.
+ </p>
+ <dl title="interface AudioWorkletProcessor" class="idl">
+ <dt>
+ readonly attribute static sequence&lt;AudioParamDescriptor&gt;
@rtoy
rtoy Jul 1, 2016 Contributor

Is this really the right way to write this? What is the name of this attribute? Should it be something like

static sequence<AudioParamDescriptor> attributeName

@rtoy rtoy commented on an outdated diff Jul 1, 2016
+ // We don't need to look at options: only AudioParams are initialized,
+ // which were taken care of by the node.
+ super(options);
+ this.phase = 0;
+ this.lastSampleValue = 0;
+ }
+
+ process (inputs, outputs, parameters) {
+ var input = inputs[0];
+ var output = outputs[0];
+ var bitDepth = parameters.bitDepth;
+ var frequencyReduction = parameters.frequencyReduction;
+
+ for (var channel = 0; channel &lt; output.length; ++channel) {
+ for (var i = 0; i &lt; output[channel].length; ++i) {
+ let step = Math.pow(1 / 2, bitDepth[i]);
@rtoy
rtoy Jul 1, 2016 Contributor

Any particular reason to use 1/2 instead of 0.5?

@rtoy rtoy commented on an outdated diff Jul 1, 2016
+ <p>
+ This example demonstrates a simple sound level meter. It shows
+ how to exchange states (that do not require sample-accurate
+ scheduling) between <a><code>AudioWorkletNode</code></a> and
+ <a><code>AudioWorkletProcessor</code></a>. This node does not use
+ any output.
+ </p>
+ <h4>
+ Global Scope: vumeternode.js
+ </h4>
+ <pre>
+class VUMeterNode extends AudioWorkletNode {
+
+ constructor (context, options) {
+
+ // Defaulting from AudioNodeOptions
@rtoy
rtoy Jul 1, 2016 Contributor

What does "Defaulting from AudioNodeOptions" mean here?

@rtoy rtoy and 1 other commented on an outdated diff Jul 1, 2016
+ unsigned long numberOfOutputs
+ </dt>
+ <dd>
+ Same to <a>numberOfOutputs</a> in <a>AudioNode</a>.
+ </dd>
+ <dt>
+ unsigned long channelCount
+ </dt>
+ <dd>
+ Same to <a>channelCount</a> in <a>AudioNode</a>.
+ </dd>
+ <dt>
+ ChannelCountMode channelCountMode
+ </dt>
+ <dd>
+ Same to <a>channelCountMode</a> in <a>AudioNode</a>.
@rtoy
rtoy Jul 1, 2016 Contributor

Instead of this, maybe something like "Value used to initialize the <a>channelCountMode</a> attribute of an <a>AudioNode</a>. Is that better?

@hoch
hoch Jul 6, 2016 Member

This is AudioWorkletNode-specific, but I guess that is also up to the discussion.

@rtoy rtoy commented on an outdated diff Jul 1, 2016
+ // Mirrored states of AudioWorkletProcessor.
+ this.updatingInterval = options.updatingInterval;
+ this.volume = 0;
+ }
+
+ get updatingInterval() {
+ return this.updatingInterval;
+ }
+
+ set updatingInterval (intervalValue) {
+ this.updatingInterval = intervalValue;
+ this.postMessage({ updatingInterval: intervalValue });
+ }
+
+ draw () {
+ /** Draw the meter based on the volume value. **/
@rtoy
rtoy Jul 1, 2016 Contributor

Why /* */-style comments? You use // everywhere else.

@rtoy rtoy commented on an outdated diff Jul 1, 2016
+
+ onmessage (event) {
+ if (event.data.hasOwnProperty('updatingInterval'))
+ this.updatingInterval = event.data.updatingInterval;
+ }
+});
+ </pre>
+ <h4>
+ Main HTML file
+ </h4>
+ <pre>
+&lt;script src="vumeternode.js"&gt;&lt;/script&gt;
+&lt;script&gt;
+ importAudioWorkletNode.then(function () {
+ var context = new AudioContext();
+ var microphone = GET_MIRCOPHONE(); // e.g) a live input from getUserMedia().
@rtoy
rtoy Jul 1, 2016 Contributor

Typo: "GET_MIRCOPHONE" -> "GET_MICROPHONE", probably.

@rtoy
Contributor
rtoy commented Jul 1, 2016

Respec says there are two new warnings:

Found linkless element with text 'audiowokletnode' but no matching <dfn>.
Found linkless element with text 'parameterdescriptors' but no matching <dfn>.

@rtoy rtoy commented on an outdated diff Jul 8, 2016
@@ -5010,65 +5010,15 @@ <h2 id="AudioWorklet">
</dt>
<dd>
<p>
- Imports a module script and returns a promise when fully loaded.
+ Imports a module script at <code>moduleURL</code>. The returned
+ promise is resolved when the code is successfully imported and
+ parsed. It is rejected when the code contains an syntax error,
+ the file is not found at the specificied location or there is a
@rtoy
rtoy Jul 8, 2016 Contributor

"an syntax" -> "a syntax"

@rtoy
rtoy Jul 8, 2016 Contributor

"the specificied" -> "the specified"
"location or" -> "location, or"

@rtoy rtoy commented on an outdated diff Jul 8, 2016
@@ -5081,9 +5031,60 @@ <h2 id="AudioWorkletNode">
connected with other built-in <a><code>AudioNode</code></a>s to
form an audio graph.
</p>
- <dl title=
- "[Constructor(BaseAudioContext context, DOMString name, optional AudioWorkletNodeOptions options)] interface AudioWorkletNode : AudioNode"
- class="idl">
+ <dl title="interface AudioWorkletNode : AudioNode" class="idl">
@rtoy
rtoy Jul 8, 2016 edited Contributor

No constructor anymore?

Hmm. I don't know what the right respec way is to specify constructors.

@rtoy rtoy commented on the diff Jul 8, 2016
index.html
@@ -5081,9 +5031,60 @@ <h2 id="AudioWorkletNode">
connected with other built-in <a><code>AudioNode</code></a>s to
form an audio graph.
</p>
- <dl title=
- "[Constructor(BaseAudioContext context, DOMString name, optional AudioWorkletNodeOptions options)] interface AudioWorkletNode : AudioNode"
- class="idl">
+ <dl title="interface AudioWorkletNode : AudioNode" class="idl">
+ <dt>
+ Constructor(BaseAudioContext context, DOMString name, optional
+ AudioWorkletNodeOptions options)
+ </dt>
+ <dd>
+ <p>
@rtoy
rtoy Jul 8, 2016 Contributor

Not really sure this is the best place to describe the construction. I expect these to be relatively short descriptions of the item.

@hoch
hoch Jul 8, 2016 Member

I believe the constructor section should describe what should happen in the construction procedure. Currently we have something like this in the spec: https://webaudio.github.io/web-audio-api/#constructors.

@rtoy
rtoy Jul 8, 2016 Contributor

Ah, respec puts it in its own section. This is fine.

@rtoy rtoy commented on an outdated diff Jul 8, 2016
- class="idl">
+ <dl title="interface AudioWorkletNode : AudioNode" class="idl">
+ <dt>
+ Constructor(BaseAudioContext context, DOMString name, optional
+ AudioWorkletNodeOptions options)
+ </dt>
+ <dd>
+ <p>
+ The construction procedure of
+ <a><code>AudioWokletNode</code></a> and the corresponding
+ <a><code>AudioWorkletProcessor</code></a> object consists of
+ several coordinated interactions.
+ </p>
+ <p>
+ The following algorithm specifies the steps when the
+ <a><code>AudioWorkletNode</code></a> constructor invoked with
@rtoy
rtoy Jul 8, 2016 Contributor

"constructor invoked" -> "constructor is invoked" at least.

But maybe better phrased as

specifies the steps in constructing an AudioWorkletNode with the given parameters.

@rtoy rtoy and 1 other commented on an outdated diff Jul 8, 2016
@@ -5124,25 +5125,28 @@ <h2 id="AudioWorkletNodeOptions">
unsigned long numberOfInputs
</dt>
<dd>
- Same to <a>numberOfInputs</a> in <a>AudioNode</a>.
+ Same to <a>numberOfInputs</a> in <a><code>AudioNode</code></a>.
@rtoy
rtoy Jul 8, 2016 Contributor

"Same to" -> "Same as". But it's not really the same. It's the value to be assigned to. Not sure on the best way to phrase that.

@hoch
hoch Jul 12, 2016 Member

We have not figured out what this options object should look like, so I'll just leave as it is.

@rtoy rtoy commented on an outdated diff Jul 8, 2016
</dt>
<dd>
<p>
- This array contains <a>AudioParamDescriptor</a>s, which are
- descriptors for each controllable parameter on an
- <a>AudioNode</a>. This static property is referenced in the
- construction of an <a>AudioWorkletNode</a> to create instances
- of an <a>AudioParam</a> in the node.
+ This getter returns an array contains
@rtoy
rtoy Jul 8, 2016 Contributor

"array contains" -> "array containing"

@rtoy rtoy commented on an outdated diff Jul 8, 2016
</dt>
<dd>
<p>
- This array contains <a>AudioParamDescriptor</a>s, which are
- descriptors for each controllable parameter on an
- <a>AudioNode</a>. This static property is referenced in the
- construction of an <a>AudioWorkletNode</a> to create instances
- of an <a>AudioParam</a> in the node.
+ This getter returns an array contains
+ <a>AudioParamDescriptor</a>s, which are descriptors for each
+ controllable parameter on an <a>AudioNode</a>. This static
@rtoy
rtoy Jul 8, 2016 Contributor

"on"->"of"?

@rtoy rtoy commented on an outdated diff Jul 8, 2016
@@ -5254,40 +5260,32 @@ <h2 id="AudioWorkletProcessor">
Float32Array[][] inputs
</dt>
<dd>
- An Array of Arrays of <code>Float32Array</code>s. The top-
- level Array is organized by input; each input may contain
- multiple channels; each channel contains a
- <code>Float32Array</code> of sample data. The initial size of
- the channel array will be determined by the number of
- channels by the <a><code>channelCount</code></a> property in
- the <a><code>AudioWorkletNodeOptions</code></a> object
- supplied to the <a><code>AudioWorkletNode</code></a>
- constructor. However, the number of channels may be altered
- dynamically by the number of channels in the incoming audio
- stream.
+ <code>inputs[n][m]</code> is a <code>Float32Array</code> of
+ audio samples for <code>m</code>th channel of
@rtoy
rtoy Jul 8, 2016 Contributor

"samples for" -> "sample for the"

@rtoy rtoy commented on an outdated diff Jul 8, 2016
</dd>
<dt>
Float32Array[][] outputs
</dt>
<dd>
- An Array of Arrays of <code>Float32Array</code>s. The top-
- level Array is organized by output; each output may contain
- multiple channels; each channel contains a
- <code>Float32Array</code> of sample data.
+ <code>outputs[n][m]</code> is a Float32Array object for
@rtoy
rtoy Jul 8, 2016 Contributor

Probably want to say that the Float32Array contains the audio samples.

@rtoy rtoy commented on an outdated diff Jul 8, 2016
</dd>
<dt>
Object parameters
</dt>
<dd>
- This object attribute exposes a correspondingly-named
- readonly <code>Float32Array</code> for each parameter that
- has been registered to an AudioWorkletNode. As this is
- dynamic, this cannot be captured in IDL. The length of this
- <code>Float32Array</code> will correspond to the length of
- the channel data in the input. The contents of this
- <code>Float32Array</code> will be the values calculated by
- the <a><code>AudioParam</code></a> automation at the
- corresponding points in time.
+ Provides an association between the names of an
+ <a><code>AudioParam</code></a>s specified by the
@rtoy
rtoy Jul 8, 2016 Contributor

"names of an AudioParams" -> "names of the AudioParams"

@rtoy rtoy commented on an outdated diff Jul 8, 2016
@@ -5077,9 +5075,10 @@ <h2 id="AudioWorkletNode">
information from the processor's
<a><code>parameterDescriptors</code></a>.
<ol>
- <li>Initialize parameter values from the
- <code>options</code> object where the keys match names
- declared in descriptors.
+ <li>Initialize the value of AudioParam objects with
+ key-value pairs in the <code>option</code> parameter. Find
+ the key matches the name of AudioParam object and assign
@rtoy
rtoy Jul 8, 2016 Contributor

"key matches" -> "key that matches"

@hoch hoch assigned hoch and unassigned hoch Jul 12, 2016
@joeberkovitz joeberkovitz commented on an outdated diff Jul 18, 2016
@@ -4975,6 +4975,634 @@ <h2 id="AudioWorkerParamDescriptor">
</section>
</section>
</section>
+ <section>
+ <h2 id="AudioWorklet">
+ The <dfn>AudioWorklet</dfn> interface
+ </h2>
+ <p>
+ The <code>AudioWorklet</code> object allows importing user-supplied
+ Javascript code that runs on the audio <a>rendering thread</a>. This
+ processing mechanism ensures the synchronous execution of the script
@joeberkovitz
joeberkovitz Jul 18, 2016 Contributor

copy edit for clarity: "...allows developers to supply Javascript to process audio on the rendering thread, supporting custom AudioNodes."

@joeberkovitz joeberkovitz commented on an outdated diff Jul 18, 2016
@@ -4975,6 +4975,634 @@ <h2 id="AudioWorkerParamDescriptor">
</section>
</section>
</section>
+ <section>
+ <h2 id="AudioWorklet">
+ The <dfn>AudioWorklet</dfn> interface
+ </h2>
+ <p>
+ The <code>AudioWorklet</code> object allows importing user-supplied
+ Javascript code that runs on the audio <a>rendering thread</a>. This
+ processing mechanism ensures the synchronous execution of the script
+ code with other built-in <code>AudioNode</code>s in the audio graph.
+ </p>
+ <p>
+ The <code>AudioWorklet</code> object stores the definitions of a
+ custom audio processor and an <code>AudioWorkletNode</code> object
+ can be constructed based on the processor definition. Note that the
+ registered definition in an AudioWorklet is valid for the entire
@joeberkovitz
joeberkovitz Jul 18, 2016 Contributor

Omit "Note that" since this is an important feature of the spec

@joeberkovitz joeberkovitz commented on an outdated diff Jul 18, 2016
@@ -4975,6 +4975,634 @@ <h2 id="AudioWorkerParamDescriptor">
</section>
</section>
</section>
+ <section>
+ <h2 id="AudioWorklet">
+ The <dfn>AudioWorklet</dfn> interface
+ </h2>
+ <p>
+ The <code>AudioWorklet</code> object allows importing user-supplied
+ Javascript code that runs on the audio <a>rendering thread</a>. This
+ processing mechanism ensures the synchronous execution of the script
+ code with other built-in <code>AudioNode</code>s in the audio graph.
+ </p>
+ <p>
+ The <code>AudioWorklet</code> object stores the definitions of a
+ custom audio processor and an <code>AudioWorkletNode</code> object
@joeberkovitz
joeberkovitz Jul 18, 2016 Contributor

Consistent pluralization: "...of custom audio processors and AudioWorkletNodes can be constructed based on these definitions."

@joeberkovitz joeberkovitz commented on an outdated diff Jul 18, 2016
+ </p>
+ <p>
+ The <code>AudioWorklet</code> object stores the definitions of a
+ custom audio processor and an <code>AudioWorkletNode</code> object
+ can be constructed based on the processor definition. Note that the
+ registered definition in an AudioWorklet is valid for the entire
+ global scope (i.e. <code>window</code>), therefore any
+ <a><code>AudioContext</code></a> instance in the same global scope
+ can access the registered definition to create a custom node.
+ </p>
+ <p>
+ After importing a module script into the
+ <a><code>AudioWorkletGlobalScope</code></a>, an instance of
+ <a><code>AudioWorkletNode</code></a> can be created in the main
+ global scope. At the same time, the user agent automatically creates
+ an instance of <a><code>AudioWorkletProcessor</code></a>. This
@joeberkovitz
joeberkovitz Jul 18, 2016 Contributor

"...in the main global scope, based on any of the definitions in the script"

@joeberkovitz joeberkovitz and 1 other commented on an outdated diff Jul 18, 2016
+ audio <a>rendering thread</a>. These two components can communicate
+ via message passing.
+ </p>
+ <dl title="interface AudioWorklet : Worklet" class="idl">
+ <dt>
+ Promise&lt;void&gt; import(DOMString moduleUrl)
+ </dt>
+ <dd>
+ <p>
+ Imports a module script at <code>moduleURL</code>. The returned
+ promise is resolved when the code is successfully imported and
+ parsed. It is rejected when the code contains a syntax error, the
+ file is not found at the specified location, or there is a name
+ conflict between registered
+ <a><code>AudioWorkletProcessor</code></a> definitions.