fix(kon): resolve ort version conflict — stub VAD, fix audio crate

- VAD stubbed: voice_activity_detector and silero-vad-rust both pin ort rc.10
  which conflicts with transcribe-rs requiring ort rc.12. Stubbed until ort
  ecosystem aligns at 2.0.0 stable. All audio treated as speech (matches v0.2).
- Refreshed Cargo.lock to resolve ort rc.12 + whisper-rs 0.16 correctly
- clippy clean

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
jake
2026-03-16 21:09:38 +00:00
parent a83eafdc82
commit 0646c75de7
2 changed files with 23 additions and 37 deletions

View File

@@ -10,8 +10,9 @@ kon-core = { path = "../core" }
# Microphone capture # Microphone capture
cpal = "0.17" cpal = "0.17"
# Voice activity detection (Silero VAD V5) # Voice activity detection — deferred until ort version conflict between
voice_activity_detector = "0.2" # VAD crates (ort rc.10) and transcribe-rs (ort rc.12) is resolved upstream.
# silero-vad-rust = { version = "6", default-features = false }
# High-quality resampling (sinc interpolation) # High-quality resampling (sinc interpolation)
rubato = "0.15" rubato = "0.15"

View File

@@ -1,50 +1,35 @@
use voice_activity_detector::VoiceActivityDetector; // Voice Activity Detection — stubbed.
//
// Both `voice_activity_detector` and `silero-vad-rust` pin ort 2.0.0-rc.10
// which conflicts with transcribe-rs requiring ort 2.0.0-rc.12.
// When the ort ecosystem aligns (likely at 2.0.0 stable), add Silero VAD here.
//
// For now, all audio is treated as speech. This matches v0.2 behaviour
// (no VAD) and doesn't affect core functionality.
use kon_core::constants::{VAD_SPEECH_THRESHOLD, WHISPER_SAMPLE_RATE}; use kon_core::constants::VAD_SPEECH_THRESHOLD;
use kon_core::error::{KonError, Result};
/// VAD chunk size for 16kHz audio (required by Silero VAD V5). /// Stub speech detector. Treats all audio as speech.
const VAD_CHUNK_SIZE: usize = 512; #[derive(Default)]
/// Wraps Silero VAD V5 for speech detection.
pub struct SpeechDetector { pub struct SpeechDetector {
vad: VoiceActivityDetector,
threshold: f64, threshold: f64,
} }
impl SpeechDetector { impl SpeechDetector {
/// Create a new speech detector with the default threshold. pub fn new() -> Self {
pub fn new() -> Result<Self> { Self {
let vad = VoiceActivityDetector::builder()
.sample_rate(WHISPER_SAMPLE_RATE as i64)
.chunk_size(VAD_CHUNK_SIZE)
.build()
.map_err(|e| KonError::AudioCaptureFailed(format!("VAD init failed: {e}")))?;
Ok(Self {
vad,
threshold: VAD_SPEECH_THRESHOLD, threshold: VAD_SPEECH_THRESHOLD,
}) }
} }
/// Predict whether a chunk of 16kHz f32 audio contains speech. /// Always returns true (no VAD filtering until ort conflict resolved).
/// Returns the speech probability (0.0 to 1.0). pub fn is_speech(&self, _samples: &[f32]) -> bool {
pub fn predict(&mut self, samples: &[f32]) -> f32 { true
self.vad.predict(samples.iter().copied())
} }
/// Returns true if the chunk contains speech above the threshold. pub fn threshold(&self) -> f64 {
pub fn is_speech(&mut self, samples: &[f32]) -> bool { self.threshold
self.predict(samples) > self.threshold as f32
} }
/// Reset the internal VAD state (call between recording sessions). pub fn reset(&mut self) {}
pub fn reset(&mut self) {
self.vad.reset();
}
/// The required chunk size for this VAD instance.
pub fn chunk_size(&self) -> usize {
VAD_CHUNK_SIZE
}
} }