This commit is contained in:
@@ -0,0 +1,56 @@
|
||||
/* Stateful box-filter resampling: phase and integration survive render quanta. */
|
||||
class TranscriptionPCM extends AudioWorkletProcessor {
|
||||
constructor() {
|
||||
super();
|
||||
this.ratio = sampleRate / 16000;
|
||||
this.weight = 0;
|
||||
this.sum = 0;
|
||||
this.samples = [];
|
||||
this.stopped = false;
|
||||
this.port.onmessage = ({ data }) => {
|
||||
if (data.type === 'flush') {
|
||||
this.stopped = true;
|
||||
if (this.weight > 0) this.samples.push(this.sum / this.weight);
|
||||
this.emit();
|
||||
this.port.postMessage({ type: 'flushed' });
|
||||
}
|
||||
};
|
||||
}
|
||||
emit() {
|
||||
if (!this.samples.length) return;
|
||||
const buffer = new ArrayBuffer(this.samples.length * 2);
|
||||
const view = new DataView(buffer);
|
||||
let energy = 0;
|
||||
this.samples.forEach((value, index) => {
|
||||
const sample = Math.max(-1, Math.min(1, value));
|
||||
view.setInt16(index * 2, Math.round(sample * (sample < 0 ? 32768 : 32767)), true);
|
||||
energy += sample * sample;
|
||||
});
|
||||
this.port.postMessage({ type: 'pcm', buffer, level: Math.sqrt(energy / this.samples.length) }, [buffer]);
|
||||
this.samples = [];
|
||||
}
|
||||
process(inputs) {
|
||||
if (this.stopped) return false;
|
||||
const channels = inputs[0];
|
||||
if (!channels?.length) return true;
|
||||
for (let i = 0; i < channels[0].length; i++) {
|
||||
let value = 0;
|
||||
for (const channel of channels) value += channel[i] / channels.length;
|
||||
let remaining = 1;
|
||||
while (remaining > 1e-9) {
|
||||
const take = Math.min(remaining, this.ratio - this.weight);
|
||||
this.sum += value * take;
|
||||
this.weight += take;
|
||||
remaining -= take;
|
||||
if (this.weight >= this.ratio - 1e-9) {
|
||||
this.samples.push(this.sum / this.ratio);
|
||||
this.sum = 0;
|
||||
this.weight = 0;
|
||||
if (this.samples.length >= 2400) this.emit();
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
registerProcessor('transcription-pcm', TranscriptionPCM);
|
||||
Reference in New Issue
Block a user