1/** 2 * AudioWorkletProcessor that captures mic input and emits 20ms chunks 3 * of 16-bit PCM at 16kHz via postMessage. 4 * 5 * The AudioContext should be created at 16kHz sample rate so no 6 * resampling is needed inside the worklet. 7 * 8 * Each chunk = 320 samples (20ms at 16kHz) = 640 bytes of Int16 PCM. 9 */ 10class PCMChunkProcessor extends AudioWorkletProcessor { 11 constructor() { 12 super(); 13 this._buffer = new Float32Array(0); 14 this._chunkSize = 320; // 20ms at 16kHz 15 } 16 17 process(inputs) { 18 const input = inputs[0]; 19 if (!input || !input[0] || input[0].length === 0) { 20 return true; 21 } 22 23 const channelData = input[0]; // mono 24 25 // Append to buffer 26 const newBuffer = new Float32Array(this._buffer.length + channelData.length); 27 newBuffer.set(this._buffer); 28 newBuffer.set(channelData, this._buffer.length); 29 this._buffer = newBuffer; 30 31 // Emit complete 20ms chunks 32 while (this._buffer.length >= this._chunkSize) { 33 const chunk = this._buffer.slice(0, this._chunkSize); 34 this._buffer = this._buffer.slice(this._chunkSize); 35 36 // Convert Float32 [-1, 1] to Int16 37 const int16 = new Int16Array(chunk.length); 38 for (let i = 0; i < chunk.length; i++) { 39 const s = Math.max(-1, Math.min(1, chunk[i])); 40 int16[i] = s < 0 ? s * 0x8000 : s * 0x7fff; 41 } 42 43 this.port.postMessage(int16.buffer, [int16.buffer]); 44 } 45 46 return true; 47 } 48} 49 50registerProcessor('pcm-capture-processor', PCMChunkProcessor);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.