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:
@@ -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"
|
||||
|
||||
@@ -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) {}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user