90 lines
2.9 KiB
JavaScript
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);
|