Skip to content

feat(vad): expose last_vad_speech_instant on BackendStream trait#110

Open
JMLX42 wants to merge 7 commits into
itsmontoya:mainfrom
lx-industries:feat/expose-vad-speech-instant
Open

feat(vad): expose last_vad_speech_instant on BackendStream trait#110
JMLX42 wants to merge 7 commits into
itsmontoya:mainfrom
lx-industries:feat/expose-vad-speech-instant

Conversation

@JMLX42

@JMLX42 JMLX42 commented Jan 20, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Tracks last_speech_instant in VadStream for timing information
  • Exposes last_vad_speech_instant on the BackendStream trait
  • Allows consumers to know when speech was last detected

Dependencies

Context

This feature is used by the Friday project.


This PR was created with the assistance of an AI assistant (Claude).

Add pass-through features for GPU backends:
- cuda: NVIDIA CUDA
- metal: Apple Metal
- hipblas: AMD ROCm
- vulkan: Cross-platform Vulkan
- coreml: Apple CoreML

This allows consumers to enable GPU acceleration by adding
the appropriate feature to their Cargo.toml, e.g.:

    scribble = { version = "0.5", features = ["cuda"] }
…cases

By default, the incremental transcriber waits for 2+ segments before
emitting, treating the last segment as potentially incomplete. This
adds latency for short utterances like voice assistant commands.

The new `emit_single_segments` option (default: false) allows emitting
single segments immediately when detected. This is useful for:
- Voice assistants
- Real-time transcription
- Any application where low latency is more important than waiting
  for natural sentence boundaries

When enabled, single segments are emitted as soon as Whisper produces
them, rather than waiting for a second segment or the 30-second
force-flush timeout.
When VAD detects no speech in an audio window, skip forwarding it to
Whisper entirely. This prevents hallucinations like "Merci" or "Thank
you for watching" that Whisper produces from silence with high
confidence.

Changes:
- process_ready_windows(): skip windows where VAD returns false
- flush(): only forward final buffer if VAD detects speech

Also fixes pre-existing test compilation (missing emit_single_segments
field) and formatting issues.
Move VAD filtering from the high-level Scribble API into the backend
stream. This ensures VAD works regardless of which API consumers use
(direct backend access or high-level Scribble::transcribe).

Changes:
- WhisperStream now optionally wraps audio with VadStream when
  enable_voice_activity_detection is true
- Remove VAD wrapping from Scribble::transcribe_with_encoder() to
  avoid double-filtering
- Export VadProcessor, VadStream, VadStreamReceiver publicly
- Make VadStream methods public for use in backend

This fixes the issue where friday-daemon's direct backend usage
bypassed VAD filtering entirely.
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.

1 participant