voicebot demo
This commit is contained in:
72
frontend/assets/audio-processor-worklet.js
Normal file
72
frontend/assets/audio-processor-worklet.js
Normal file
@@ -0,0 +1,72 @@
|
||||
class PCMAudioProcessor extends AudioWorkletProcessor {
|
||||
constructor() {
|
||||
super()
|
||||
this._inRate = sampleRate // z.B. 48000
|
||||
this._pos = 0 // Phase in Eingangssamples [0, step)
|
||||
this._carry = null // letztes Eingangssample des vorigen Blocks
|
||||
this._outRate = 24000
|
||||
}
|
||||
|
||||
process(inputs) {
|
||||
const chs = inputs[0]
|
||||
if (!chs || chs.length === 0) return true
|
||||
|
||||
const inF32 = chs[0] // mono Float32
|
||||
const step = this._inRate / this._outRate
|
||||
|
||||
// src ggf. mit carry präfixieren, damit i+1 existiert
|
||||
let src = inF32
|
||||
if (this._carry !== null) {
|
||||
const tmp = new Float32Array(1 + inF32.length)
|
||||
tmp[0] = this._carry
|
||||
tmp.set(inF32, 1)
|
||||
src = tmp
|
||||
}
|
||||
|
||||
// Anzahl ausgebbarer Samples (lineare Interp.: i+1 < src.length)
|
||||
const avail = src.length - 1 - this._pos
|
||||
const outLen = avail > 0 ? Math.ceil(avail / step) : 0
|
||||
|
||||
const outI16 = new Int16Array(outLen)
|
||||
|
||||
let pos = this._pos
|
||||
for (let k = 0; k < outLen; k++) {
|
||||
const i = Math.floor(pos)
|
||||
const frac = pos - i
|
||||
|
||||
const x0 = src[i]
|
||||
const x1 = src[i + 1] // existiert garantiert durch -1 in avail
|
||||
|
||||
// Linearinterp. + Clamping
|
||||
let y = x0 + frac * (x1 - x0)
|
||||
if (y > 1) y = 1
|
||||
else if (y < -1) y = -1
|
||||
|
||||
// Float32 -> int16 (runden, saturieren)
|
||||
const s = y <= -1 ? -0x8000 : Math.round(y * 0x7fff)
|
||||
outI16[k] = s
|
||||
|
||||
pos += step
|
||||
}
|
||||
|
||||
// Phase für nächsten Block relativ zu dessen src verschieben
|
||||
// (src[0] == letztes Sample des aktuellen Eingangs)
|
||||
this._pos = pos - (src.length - 1)
|
||||
if (this._pos < 0) this._pos = 0 // numerische Sicherheit
|
||||
|
||||
// letztes echtes Eingangssample als carry behalten
|
||||
this._carry = src[src.length - 1]
|
||||
|
||||
// zero-copy an die UI (Transfer des Buffers)
|
||||
try {
|
||||
this.port.postMessage(outI16, [outI16.buffer])
|
||||
} catch {
|
||||
// Fallback ohne Transferliste (z. B. in älteren Browsern)
|
||||
this.port.postMessage(outI16)
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
registerProcessor("audio-processor-worklet", PCMAudioProcessor)
|
||||
Reference in New Issue
Block a user