Skip to content

agent: keep the command that follows the wake word - #27

Merged
yawaflua merged 1 commit into
yawaflua:stagefrom
ryysel:pr/agent-hearing
Nov 5, 2026
Merged

yawaflua merged 1 commit into
yawaflua:stagefrom
ryysel:pr/agent-hearing

Conversation

@ryysel

@ryysel ryysel commented Nov 2, 2026

Copy link
Copy Markdown
Contributor

What

Two fixes in the agent's microphone path, found while debugging «the ring shows listening, but the speaker answers nothing».

  1. The agent now keeps the last five seconds of idle audio and replays it through the endpointer when a turn starts.
  2. A one-pole 180 Hz high-pass filter runs before the VAD, and «no speech detected» logs the loudest frame and the noise floor.

Why

The wake spotter verifies a candidate with the full Vosk vocabulary before reporting a hit, which adds about a second. If the whole phrase is «Маруся, который час», the audio is over before the agent starts listening, so the recorded turn is silence and the transcription is empty. A pause after the wake word hid the problem. Replaying the idle buffer recovers the phrase.

The filter addresses a quiet room where rumble sat only 6–9 dB below speech: the endpointer compares speech with the noise floor, and a quiet speaker could stay under the threshold forever. The new log fields separate a quiet speaker from a muted or broken microphone.

Testing

  • go test ./internal/audio/ ./internal/agent/
  • On a VK Capsula Mini: a phrase said in one breath is transcribed as «маруся который час» and answered; silence still ends with «no speech detected».
  • The replay path is a no-op when the buffer is empty, so remote turns and announcements are unaffected.

The wake spotter verifies a candidate before reporting it, so on a loaded
host the server asks the speaker to listen about a second after the wake
word. A command said without a pause after it («Маруся, который час») is
over by then: the turn is transcribed as empty and the speaker stays
silent. A pause after the wake word hid the problem.

Keep the last five seconds of idle microphone audio and replay it through
the endpointer when listening starts. The buffered frames already passed
the noise floor and the high-pass filter, so the buffered speech goes out
with the turn as usual.

The high-pass filter is new as well: room rumble can sit only a few dB
below speech in a quiet room, and the endpointer compares speech with the
floor. Filtering below 180 Hz gives quiet speech more headroom, and the
«no speech detected» log now includes the peak and the floor in dBFS, so
a muted microphone is not mistaken for a quiet one.
@yawaflua
yawaflua merged commit 6d772a7 into yawaflua:stage Nov 5, 2026
7 checks passed
@yawaflua yawaflua mentioned this pull request Nov 10, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants