57 lines
1.4 KiB
JavaScript
57 lines
1.4 KiB
JavaScript
class PCMRecorderProcessor extends AudioWorkletProcessor {
|
|
constructor() {
|
|
super();
|
|
this.chunkSize = 4096;
|
|
this.buffer = new Int16Array(this.chunkSize);
|
|
this.offset = 0;
|
|
this.pendingFrames = 0;
|
|
this.maxPendingFrames = 10;
|
|
}
|
|
|
|
flushBuffer() {
|
|
if (this.offset === 0) {
|
|
return;
|
|
}
|
|
|
|
const chunk = new Int16Array(this.offset);
|
|
chunk.set(this.buffer.subarray(0, this.offset));
|
|
this.port.postMessage(chunk, [chunk.buffer]);
|
|
|
|
this.offset = 0;
|
|
this.pendingFrames = 0;
|
|
}
|
|
|
|
process(inputs) {
|
|
const input = inputs[0];
|
|
if (!input || input.length === 0) {
|
|
return true;
|
|
}
|
|
|
|
const channel = input[0];
|
|
if (!channel || channel.length === 0) {
|
|
return true;
|
|
}
|
|
|
|
for (let i = 0; i < channel.length; i++) {
|
|
let sample = channel[i];
|
|
sample = Math.max(-1, Math.min(1, sample));
|
|
this.buffer[this.offset++] = sample < 0 ? sample * 0x8000 : sample * 0x7fff;
|
|
|
|
if (this.offset === this.chunkSize) {
|
|
this.flushBuffer();
|
|
}
|
|
}
|
|
|
|
if (this.offset > 0) {
|
|
this.pendingFrames += 1;
|
|
if (this.pendingFrames >= this.maxPendingFrames) {
|
|
this.flushBuffer();
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
}
|
|
|
|
registerProcessor('pcm-recorder', PCMRecorderProcessor);
|