| /* pcm-worklet.js --------------------------------------------------------- | |
| * Down-samples the input to 16 kHz mono and posts Int16Array chunks back | |
| * to the main thread. Buffer size is 128 frames to keep latency < 10 ms. | |
| */ | |
| class PCMWorklet extends AudioWorkletProcessor { | |
| constructor() { | |
| super(); | |
| this._decimator = new Float32Array(0); | |
| this._ratio = sampleRate / 16000; // e.g. 48k / 16k = 3 | |
| this._chunk = 0; | |
| } | |
| process(inputs) { | |
| const input = inputs[0][0]; | |
| if (!input) return true; | |
| // Down-sample on the fly | |
| for (let i = 0; i < input.length; i += this._ratio) { | |
| this._decimator[this._chunk++] = input[i|0]; | |
| if (this._chunk === 160) { // 10 ms at 16 kHz | |
| // Convert to 16-bit PCM | |
| const i16 = new Int16Array(160); | |
| for (let j = 0; j < 160; ++j) { | |
| const s = Math.max(-1, Math.min(1, this._decimator[j])); | |
| i16[j] = s < 0 ? s * 0x8000 : s * 0x7FFF; | |
| } | |
| this.port.postMessage(i16.buffer); | |
| this._chunk = 0; | |
| } | |
| } | |
| return true; | |
| } | |
| } | |
| registerProcessor("pcm-worklet", PCMWorklet); | |