static/audio-processor.js
Rama main · réplica de lectura del repositorio original.
/**
* AudioWorklet Processor for Remote Mic
* Captures audio samples from the browser microphone and sends them to the main thread
* for transmission to the server via Socket.IO
*
* Audio Format: 16kHz, mono, 16-bit signed integer PCM
*/
class AudioProcessor extends AudioWorkletProcessor {
constructor() {
super();
this.bufferSize = 1600; // 100ms at 16kHz
this.buffer = new Float32Array(this.bufferSize);
this.bufferIndex = 0;
}
process(inputs, outputs, parameters) {
const input = inputs[0];
if (!input || !input[0]) {
return true;
}
const channelData = input[0]; // Mono channel
for (let i = 0; i < channelData.length; i++) {
this.buffer[this.bufferIndex++] = channelData[i];
// When buffer is full, convert to Int16 and send
if (this.bufferIndex >= this.bufferSize) {
const int16Buffer = this.float32ToInt16(this.buffer);
try {
this.port.postMessage(int16Buffer.buffer, [int16Buffer.buffer]);
} catch (e) {
// Port may be disconnected; ignore and continue
}
// Reset buffer
this.buffer = new Float32Array(this.bufferSize);
this.bufferIndex = 0;
}
}
return true;
}
/**
* Convert Float32 audio samples to Int16 PCM
* Float32 range: -1.0 to 1.0
* Int16 range: -32768 to 32767
*/
float32ToInt16(float32Array) {
const int16Array = new Int16Array(float32Array.length);
for (let i = 0; i < float32Array.length; i++) {
// Clamp to -1.0 to 1.0 range
const sample = Math.max(-1, Math.min(1, float32Array[i]));
// Convert to Int16
int16Array[i] = Math.round(sample * 32767);
}
return int16Array;
}
}
registerProcessor('audio-processor', AudioProcessor);