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