I want to play the AudioBuffer
that I have gotten from AudioContext.decodeAudioData()
with AudioWorklet
. I'm currently able to play decoded audio buffer with AudioBufferSourceNode
but as you know this method will execute the task on the main thread which is not what I want, the thing I want is to play audio in the background which seems it's only possible to do with workers. but workers can't access the Web Audio Api. so the only way is AudioWorklet
setup worklet :
var audioContext = new AudioContext()
await audioContext.audioWorklet.addModule("./playing-audio-processor.js");
PlayingAudioProcessor= new AudioWorkletNode(
audioContext,
"playing-audio-processor"
);
PlayingAudioProcessor.connect(audioContext.destination);
audioContext.resume();
decoding and sending it to the worklet (I'm sure that the passed audioBuffer
does not have any problem and can be easily played with AudioBufferSourceNode
)
let ctx = new AudioContext();
ctx.decodeAudioData(new Uint8Array(audioData).buffer, (audioBuffer) => {
//set `audioData` of worklet to a float32array
myAudioWorklet.port.postMessage(audioBuffer.getChannelData(0))
})
the length of passed audio data array (audioBuffer.getChannelData(0)
) is 960
which is greater than the length of outputs[0][0]
so I splitted it (actully it doesn't seem to be a good idea and I think this is why I have not expected audio output)
class PlayingAudioProcessor extends AudioWorkletProcessor {
audioData = []
constructor() {
super();
//set listener to receive audio data
this.port.onmessage = (data) => {
this.audioData = data.data
}
}
process(inputs, outputs, parameters) {
//playing each 128 floats of 960 floats
for (let i = 0; i < this.audioData.length / 128; i++) {
for (let b = 0; b < 128; b++) {
if ((i * 128) + b <= this.audioData.length) {
outputs[0][0][b] = this.audioData[(i * 128) + b];
}
}
}
return true;
}
}
registerProcessor("playing-audio-processor", PlayingAudioProcessor);
the problem is now that the audio result is nothing but a meaningless noisy sound that depends on the loudness of the input data.
I really need to solve this, please put anything that might be helpful for me. thank you.
It looks like you're writing all the samples within a single
process()
call. You would instead need to write only 128 samples perprocess()
call to achieve the desired result.The first invocation would need to write sample 1 to 128 out of your
AudioBuffer
, the second invocation would need to write sample 129 to 256, and so on...