Re: Comments on AudioWorklet examples

Hi Joe,

Thanks for investigating this. I really wanted to have some opinion from
the group. Please find my responses inline:


> 1. You're passing initial values for the params "bitDepth" and
> "frequencyReduction" into the AudioWorkletNode constructor via
> AudioNodeOptions. This is fine, but someone might assume that these values
> are magically propagated into the corresponding AudioParams.
>

I agree with the point. In general, what I have in the example lacks the
clear illustration of the interaction between a node and a processor.


Based on our previous discussion, I'd expect that there needs to be a
> subclass constructor that explicitly copies these values out of the
> AudioNodeOptions into the new node's AudioParams, like this:
>
> class BitcrusherNode extends AudioWorkletNode {
>   constructor(ctx, options) {
>     super(ctx, 'Bitcrusher', options);
>     if (options.hasOwnProperty('bitDepth') {
>       this.bitDepth.value = options.bitDepth;
>     }
>     // ...initialize other params, initial state up front, possibly
> utilizing postMessage()...
> }
>

Just to confirm: so this is a node definition, not the processor?
Initializing these values from the main thread is a definitely better idea,
but the pattern here is quite involved and verbose. I think we can start
from this idea and try to simplify the syntax to find a sweet spot. I
really need to think about having two definitions for both threads. Very
explicit, but that also makes us diverge from Worklet infrastructure which
I am a bit afraid of.


2. When are the params for a node determined, and when can they change?
> We've changed up the lifecycle quite a bit now, so I'm not sure what the
> answer is. I recall that we went to some trouble before to ensure that the
> set of params was known at the actual time that an AudioWorkerNode was
> instantiated, just like they would be for a native node.
>

We can introduce event like `created` for the instance-specific
initialization. I find this pattern is very useful when using Polymer.

class BitCrusherProcessor extends AudioWorkletProcessor {
  constructor () { /* this is called when the instance is created. */ }
  created () { /* this is called the initialization for both threads is
done. */ }
  process () {...}
}



> The only opportunity we have to discover parameter descriptors is before
> the success of the promise from the script import for a node type.
>
  So *maybe* it works like this: after the script is imported for an
> AudioWorkletProcessor, the Processor gets instantiated once prior to the
> success of the Promise and its paramDescriptors getter is examined; the
> result determines the set of parameters exposed by subsequent nodes of that
> type. The Processor instance is then thrown away; its only purpose was to
> figure out what params exist for this node type.
>

Can you elaborate on this a bit more? I am not sure if I am following you.


This would make it hard to add/remove parameters on the fly. But I don't
> know that this is important.
>

I am opposing to the idea of adding/removing parameters on the fly. The
current AudioNodes do not support this, so I guess this is where we draw
the line for V1.



> 3. In the actual spec, I think it would be a good idea to mock up a
> complete node that not only has a couple of AudioParams but also has some
> non-param aspects, like a read-only attribute reflecting the state of the
> audio side (like "clip" and "volume" for the VU meter), or a method that
> mutates the state of the audio side (say, to reset the accumulated
> smoothing state of the VU meter). A pass-through VU meter that acts as a
> pass-through GainNode would fit the bill.
>

It seems like you already wrote the VU meter example? I will take a look at
it.

Thanks for your insight. This is helpful!

Best,
Hongchan

>

Received on Monday, 30 May 2016 15:25:47 UTC