class GargiMicProcessor extends AudioWorkletProcessor { constructor() { super(); this.pending = new Float32Array(0); this.offset = 0; this.ratio = sampleRate / 16000; } process(inputs) { const input = inputs[0]?.[0]; if (!input?.length) return true; const joined = new Float32Array(this.pending.length + input.length); joined.set(this.pending); joined.set(input, this.pending.length); const samples = []; while (this.offset + 1 < joined.length) { const left = Math.floor(this.offset); const mix = this.offset - left; const value = joined[left] * (1 - mix) + joined[left + 1] * mix; samples.push(Math.max(-1, Math.min(1, value))); this.offset += this.ratio; } const consumed = Math.floor(this.offset); this.pending = joined.slice(consumed); this.offset -= consumed; if (samples.length) { const pcm = new Int16Array(samples.length); for (let index = 0; index < samples.length; index++) { pcm[index] = samples[index] < 0 ? samples[index] * 32768 : samples[index] * 32767; } this.port.postMessage(pcm.buffer, [pcm.buffer]); } return true; } } registerProcessor("gargi-mic-processor", GargiMicProcessor);