const SAMPLE_RATE = 48000; const PACKET_MS = 10; const PACKET_FRAMES = PACKET_MS / 1000 * SAMPLE_RATE; //const PACKET_FRAMES = 2400; console.log("Frames per packet:", PACKET_FRAMES); class RustWorklet extends AudioWorkletProcessor { constructor(options) { super(); this.module = options.processorOptions; this.timestamp = null; this.buffer = new Float32Array(PACKET_FRAMES); this.buffer_offset = 0; if (sampleRate != SAMPLE_RATE) { throw Error(`sample rate ${sampleRate} should be ${SAMPLE_RATE}`); } console.log('RustWorklet:', this); } do_send() { const data = { format: 'f32', sampleRate: SAMPLE_RATE, //numberOfFrames: this.buffer_offset, numberOfFrames: this.buffer_offset, numberOfChannels: 1, timestamp: this.timestamp, //timestamp: null, data: this.buffer.slice(0, this.buffer_offset), }; this.port.postMessage(data); this.buffer_offset = 0; this.timestamp = null; } process(inputs) { //console.log(inputs); if (inputs.length != 1) { console.log("We got " + inputs.length + " heads?") } const input = inputs[0]; if (input.length == 0) { console.log("We got no ears?") return true } if (this.timestamp == null) { this.timestamp = currentFrame / SAMPLE_RATE * 1e6; } const frames = input[0]; if (this.buffer_offset + frames.length > this.buffer.length) { // too full, send now this.do_send(); } this.buffer.set(frames, this.buffer_offset); this.buffer_offset += frames.length; if (this.buffer_offset + 128 > this.buffer.length) { // full enough, send now this.do_send(); } return true; } }; registerProcessor("rust_mic_worklet", RustWorklet);