mwss/rawpcmworklet.js

90 lines
2.9 KiB
JavaScript

// 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);