Fix silence timeout never firing — gate on audio amplitude

on_audio was resetting the timer on every chunk including silence,
so the timeout never fired. Now passes the raw chunk and checks RMS;
only resets if energy is above 0.02 (speech, not ambient silence).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-30 05:09:20 +00:00
parent 778672ebfe
commit 9d2ffd1b0d
2 changed files with 10 additions and 2 deletions

View File

@@ -132,7 +132,7 @@ export class Stt {
let pending = Buffer.alloc(0) let pending = Buffer.alloc(0)
mic.stdout.on('data', (chunk) => { mic.stdout.on('data', (chunk) => {
if (on_audio) on_audio() if (on_audio) on_audio(chunk)
pending = Buffer.concat([pending, chunk]) pending = Buffer.concat([pending, chunk])
// Feed complete VAD windows // Feed complete VAD windows

View File

@@ -121,4 +121,12 @@ stt.listen(async (text) => {
accumulated = '' accumulated = ''
await submit(query) await submit(query)
}, { on_audio: () => { if (accumulated) reset_silence_timer() } }) }, { on_audio: (chunk) => {
if (!accumulated) return
// Only reset silence timer if audio has significant energy (not silence)
const samples = new Int16Array(chunk.buffer, chunk.byteOffset, chunk.byteLength >> 1)
let sum = 0
for (let i = 0; i < samples.length; i++) sum += samples[i] * samples[i]
const rms = Math.sqrt(sum / samples.length) / 32768
if (rms > 0.02) reset_silence_timer()
} })