Closed charlieschwabacher closed 4 years ago
In the case of an AudioWorkletNode output connected to an AudioParam, the AudioParam can be set to k-rate so as to use only the first sample of the render quantum.
For the case of connecting an AudioWorkletNode output to an (indexed) input of an AudioNode, a ConstantSourceNode with node.offset.automationRate
set to "k-rate" can be used to fill all 128 samples with the value of the first.
Ahh - so w/ that approach, the only cost is the extra 508 bytes of memory and whatever it cpu it costs to zero out or reallocate the 128 sample buffer each frame? I'm coming at this from the javascript side and don't have the best intuition on how to weigh that cost. Do you have a clear idea of the relative costs of:
1) A worklet processor w/ k rate output filling a one sample output buffer 2) A worklet processor filling the first sample of a 128 sample buffer 3) A worklet processing filling all 128 samples of its buffer w/ the same value 4) Some other node (say an oscillator) filling its 128 sample buffer
If the difference between 1/2/3 is insignificant, I agree this proposal doesn't make sense. If the difference between 1 and 2 or 2 and 3 is significant, it does seem worth having first class support for the k rate output to me. Needing to stick a ConstantSourceNode in between connections feels like an API usability issue.
I did some benchmarking, creating the following processors representing cases 2 and 3 above
registerProcessor(
"AllSamplesProcessor",
class AllSamplesProcessor extends AudioWorkletProcessor {
process(_, [output]) {
output.fill(1);
}
}
);
registerProcessor(
"FirstSampleProcessor",
class FirstSampleProcessor extends AudioWorkletProcessor {
process(_, [output]) {
output[0] = 1;
}
}
);
There doesn't seem to be a significant difference in performance between the two.
Virtual F2F:
A nice feature of this API is the ability to write custom nodes for modulation - things like parameterized envelopes or step sequencers w/ parameterized slew. This can be achieved now with a-rate outputs, but often k-rate would work just as well and it would be significantly more efficient.
This could be accomplished by adding outputRate alongside outputChannelCount to AudioWorkletNode options:
Connecting a k-rate output to an a-rate param or to the input of another AudioNode could cause the value to be upscaled by filling a 128 length buffer.