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
cpal = "0.17"
# Voice activity detection (Silero VAD V5)
voice_activity_detector = "0.2"
# Voice activity detection — deferred until ort version conflict between
# 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)
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::error::{KonError, Result};
use kon_core::constants::VAD_SPEECH_THRESHOLD;
/// VAD chunk size for 16kHz audio (required by Silero VAD V5).
const VAD_CHUNK_SIZE: usize = 512;
/// Wraps Silero VAD V5 for speech detection.
/// Stub speech detector. Treats all audio as speech.
#[derive(Default)]
pub struct SpeechDetector {
vad: VoiceActivityDetector,
threshold: f64,
}
impl SpeechDetector {
/// Create a new speech detector with the default threshold.
pub fn new() -> Result<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,
pub fn new() -> Self {
Self {
threshold: VAD_SPEECH_THRESHOLD,
})
}
}
/// Predict whether a chunk of 16kHz f32 audio contains speech.
/// Returns the speech probability (0.0 to 1.0).
pub fn predict(&mut self, samples: &[f32]) -> f32 {
self.vad.predict(samples.iter().copied())
/// Always returns true (no VAD filtering until ort conflict resolved).
pub fn is_speech(&self, _samples: &[f32]) -> bool {
true
}
/// Returns true if the chunk contains speech above the threshold.
pub fn is_speech(&mut self, samples: &[f32]) -> bool {
self.predict(samples) > self.threshold as f32
pub fn threshold(&self) -> f64 {
self.threshold
}
/// Reset the internal VAD state (call between recording sessions).
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
}
pub fn reset(&mut self) {}
}