// To explain succinctly, the people who designed AudioWorklet and // deprecated ScriptProcessorNode are retarded and we need a worklet // that does basically nothing // Must be careful to create as little garbage as possible otherwise // even this will produce cracks/pops/clicks/blips. // It was like this on Firefox; Chromium managed. class RawPCMWorklet extends AudioWorkletProcessor { constructor() { super() this.ringL = new Float32Array(65536) this.ringR = new Float32Array(65536) this.ringWrite = 0 this.ringRead = 0 for(var z = 0; z < 65536; z++) { this.ringL[z] = Math.sin(z / 128 * 2 * Math.PI) * 0.3 } this.port.onmessage = (event) => { var newaudioframes = event.data var newlen = newaudioframes.left.length if(newaudioframes.left.length > this.ringL.length) { newaudioframes.left = newaudioframes.left.slice(newaudioframes.left.length - this.ringL.length) newaudioframes.right = newaudioframes.right.slice(newaudioframes.right.length - this.ringL.length) } if(this.ringWrite % this.ringL.length + newaudioframes.left.length <= this.ringL.length) { this.ringL.set(newaudioframes.left, this.ringWrite % this.ringL.length) this.ringR.set(newaudioframes.right, this.ringWrite % this.ringL.length) } else { var boundary = this.ringL.length - this.ringWrite % this.ringL.length this.ringL.set(newaudioframes.left.slice(0, boundary), this.ringWrite % this.ringL.length) this.ringL.set(newaudioframes.left.slice(boundary), 0) this.ringR.set(newaudioframes.right.slice(0, boundary), this.ringWrite % this.ringL.length) this.ringR.set(newaudioframes.right.slice(boundary), 0) } this.ringWrite += newlen console.log(this.ringWrite - this.ringRead) } } process(inputs, outputs, parameters) { const output = outputs[0] var left = output[0] var right = output[1] /*if(this.ringWrite < 16384) { return true }*/ var available = Math.min(left.length, Math.max(0, this.ringWrite - this.ringRead)) if(this.ringRead % this.ringL.length + available <= this.ringL.length) { left.set(this.ringL.slice(this.ringRead % this.ringL.length, this.ringRead % this.ringL.length + available)) right.set(this.ringR.slice(this.ringRead % this.ringL.length, this.ringRead % this.ringL.length + available)) } else { left.set(this.ringL.slice(this.ringRead % this.ringL.length)) right.set(this.ringR.slice(this.ringRead % this.ringL.length)) var boundary = this.ringL.length - this.ringRead % this.ringL.length left.set(this.ringL.slice(0, available - boundary), boundary) right.set(this.ringR.slice(0, available - boundary), boundary) } this.ringRead += left.length /*for(var s = 0; s < available; s++) { var sw = Math.sin((this.debug + s) / 48000 * 440 * 2 * 3.1415926) * 0.3 left[s] = sw right[s] = sw } this.debug += available*/ return true } } registerProcessor('rawpcmworklet', RawPCMWorklet);