43 lines
1.2 KiB
JavaScript
43 lines
1.2 KiB
JavaScript
/**
|
|
* AudioWorkletProcessor that collects 512-sample chunks of PCM audio
|
|
* and posts them to the main thread for WebSocket transmission.
|
|
*/
|
|
class PCMProcessor extends AudioWorkletProcessor {
|
|
constructor() {
|
|
super();
|
|
this.buffer = new Float32Array(0);
|
|
this.chunkSize = 512; // 512 samples at 16kHz = 32ms
|
|
}
|
|
|
|
process(inputs) {
|
|
const input = inputs[0];
|
|
if (!input || !input[0]) return true;
|
|
|
|
const channelData = input[0]; // mono
|
|
|
|
// Append to buffer
|
|
const newBuffer = new Float32Array(this.buffer.length + channelData.length);
|
|
newBuffer.set(this.buffer);
|
|
newBuffer.set(channelData, this.buffer.length);
|
|
this.buffer = newBuffer;
|
|
|
|
// Send complete chunks
|
|
while (this.buffer.length >= this.chunkSize) {
|
|
const chunk = this.buffer.slice(0, this.chunkSize);
|
|
this.buffer = this.buffer.slice(this.chunkSize);
|
|
|
|
// Convert float32 to int16 for transmission
|
|
const int16 = new Int16Array(chunk.length);
|
|
for (let i = 0; i < chunk.length; i++) {
|
|
const s = Math.max(-1, Math.min(1, chunk[i]));
|
|
int16[i] = s < 0 ? s * 0x8000 : s * 0x7fff;
|
|
}
|
|
this.port.postMessage(int16.buffer, [int16.buffer]);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
}
|
|
|
|
registerProcessor("pcm-processor", PCMProcessor);
|