64 lines
1.5 KiB
JavaScript
64 lines
1.5 KiB
JavaScript
const SAMPLE_RATE = 48000;
|
|
const PACKET_MS = 20;
|
|
const PACKET_FRAMES = PACKET_MS / 1000 * SAMPLE_RATE;
|
|
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,
|
|
numberOfChannels: 1,
|
|
timestamp: this.timestamp,
|
|
data: this.buffer.slice(0, this.buffer_offset),
|
|
};
|
|
this.port.postMessage(data);
|
|
this.buffer_offset = 0;
|
|
this.timestamp = null;
|
|
}
|
|
|
|
process(inputs) {
|
|
const input = inputs[0];
|
|
if (input.length == 0) {
|
|
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);
|