- From: Hongchan Choi <hongchan@google.com>
- Date: Mon, 30 May 2016 15:25:07 +0000
- To: Joe Berkovitz <joe@noteflight.com>
- Cc: Audio Working Group <public-audio@w3.org>
- Message-ID: <CAGJqXNusn7vaHCBWpX_yNVXt7RaaTXUVEh6nkj+EjHn0w5KocQ@mail.gmail.com>
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