GoogleChromeLabs / audioworklet-polyfill

🔊 Polyfill AudioWorklet using the legacy ScriptProcessor API.
https://googlechromelabs.github.io/audioworklet-polyfill/
Apache License 2.0
196 stars 20 forks source link

How do I get the buffer size? #13

Closed aatishb closed 5 years ago

aatishb commented 6 years ago

In Chrome using AudioWorklet, the buffer size (i.e. the length of the output in process()) is 128. However, when using this polyfill in Firefox, it looks like the buffer size is 4096, and in Safari it's 256. My question is: how can I get the value of this buffer size outside of the process() loop of the worklet? i.e. is there a way to access the buffer size either from within the constructor function, or from outside the worklet?

developit commented 6 years ago

Buffer size is calculated automatically. You should be able to use the sampleRate variable in your Worklet (eg self.sampleRate) to figure out the value.

JohnWeisz commented 6 years ago

@aatishb This is because this polyfill leaves it to the implementation to decide on a good bufferSize for the used ScriptProcessorNode (which I think is a really good idea, at least in real-time AudioContext).

Since a recent update, the AudioWorkletNode constructor actually returns a ScriptProcessorNode object (it's just decorated with AudioWorkletNode properties and methods):

instanceof new AudioWorkletNode(...) // ScriptProcessorNode

So what you can do here, is the following:

aatishb commented 6 years ago

Thanks, this is helpful.

I guess part of my question is even more basic. I don't know the syntax for accessing these variables from within the scope of the audioWorklet. So for example self.bufferSize, this.bufferSize, bufferSize are all undefined if I call them from within the audioWorklet constructor. Similarly, I don't know how to tell if an AudioWorkletNode is a ScriptProcessorNode from inside the worklet (would I inspect the this variable to do that?).

class AudioProcessor extends AudioWorkletProcessor {
  constructor() {
    super();
    // what do I put here to access bufferSize?
  }

  process(inputs, outputs, parameters) {
    // audio processing code here.
  }
}

Would appreciate any help. Currently I'm using a workaround where I just use the length of the outputs[0][0] in process() to get the bufferSize, which works fine, but I was wondering if there's a better way to go about this.

aatishb commented 5 years ago

Hi, just wanted to follow up on this. I was confused earlier because I was trying to access the bufferSize from within the worklet thread rather than from the main thread.

So now I understand that you can do this:

node = new AudioWorkletNode(audioCtx, processorName);
if (node.bufferSize) {
  console.log('buffer size: ', node.bufferSize);
}

which works, giving me a buffer size when the polyfill is being used.

I'm still getting some inconsistent behavior between browsers, so I'm wondering if the sample rate that the worklet uses is the same as the audio context sample rate (44.1 kHz)? Or is it different? And if so, how do I access the worklet sample rate?

aatishb commented 5 years ago

Ok, so this gives me the sample rate & current time when the polyfill is being used.

class AudioProcessor extends AudioWorkletProcessor {
  constructor() {
    super();
  }

  process(inputs, outputs, parameters) {
    if (typeof self !== 'undefined') {
      console.log('sample rate: ', self.sampleRate);
      console.log('time: ', self.currentTime);
    }
  }
}

and it shows me a 44.1 kHz sample rate throughout.

Hmm.. still trying to work out why my example sounds different in Chrome and other browsers.

aatishb commented 5 years ago

I think this is probably not a polyfill issue so am closing this thread.

developit commented 5 years ago

Thanks for updating @aatishb