2023-06-11 19:17:50 +05:00
|
|
|
use once_cell::sync::OnceCell;
|
2023-04-29 14:58:16 +05:00
|
|
|
use vosk::{DecodingState, Model, Recognizer};
|
2023-04-27 00:28:36 +05:00
|
|
|
|
2023-06-11 19:17:50 +05:00
|
|
|
use std::sync::Mutex;
|
2023-04-27 00:28:36 +05:00
|
|
|
|
2023-06-11 19:17:50 +05:00
|
|
|
use crate::config::VOSK_MODEL_PATH;
|
2023-04-27 00:28:36 +05:00
|
|
|
|
2023-06-11 19:17:50 +05:00
|
|
|
static MODEL: OnceCell<Model> = OnceCell::new();
|
|
|
|
|
static RECOGNIZER: OnceCell<Mutex<Recognizer>> = OnceCell::new();
|
2023-04-27 00:28:36 +05:00
|
|
|
|
|
|
|
|
pub fn init_vosk() {
|
2026-01-04 06:14:05 +05:00
|
|
|
if RECOGNIZER.get().is_some() {
|
2025-12-11 23:43:50 +05:00
|
|
|
return;
|
|
|
|
|
} // already initialized
|
2023-06-11 19:17:50 +05:00
|
|
|
|
|
|
|
|
let model = Model::new(VOSK_MODEL_PATH).unwrap();
|
|
|
|
|
let mut recognizer = Recognizer::new(&model, 16000.0).unwrap();
|
|
|
|
|
|
|
|
|
|
recognizer.set_max_alternatives(10);
|
|
|
|
|
recognizer.set_words(true);
|
|
|
|
|
recognizer.set_partial_words(true);
|
|
|
|
|
|
|
|
|
|
MODEL.set(model);
|
|
|
|
|
RECOGNIZER.set(Mutex::new(recognizer));
|
2023-04-27 00:28:36 +05:00
|
|
|
}
|
|
|
|
|
|
2023-04-29 16:00:49 +05:00
|
|
|
pub fn recognize(data: &[i16], include_partial: bool) -> Option<String> {
|
2025-12-11 23:43:50 +05:00
|
|
|
let state = RECOGNIZER
|
|
|
|
|
.get()
|
|
|
|
|
.unwrap()
|
|
|
|
|
.lock()
|
|
|
|
|
.unwrap()
|
|
|
|
|
.accept_waveform(data);
|
2023-04-27 00:28:36 +05:00
|
|
|
|
|
|
|
|
match state {
|
2025-12-12 02:05:37 +05:00
|
|
|
Ok(ds) => {
|
|
|
|
|
match ds {
|
|
|
|
|
DecodingState::Running => {
|
|
|
|
|
if include_partial {
|
|
|
|
|
Some(
|
|
|
|
|
RECOGNIZER
|
|
|
|
|
.get()
|
|
|
|
|
.unwrap()
|
|
|
|
|
.lock()
|
|
|
|
|
.unwrap()
|
|
|
|
|
.partial_result()
|
|
|
|
|
.partial
|
|
|
|
|
.into(),
|
|
|
|
|
)
|
|
|
|
|
} else {
|
|
|
|
|
None
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
DecodingState::Finalized => {
|
|
|
|
|
// Result will always be multiple because we called set_max_alternatives
|
2026-01-04 06:14:05 +05:00
|
|
|
RECOGNIZER
|
|
|
|
|
.get()
|
|
|
|
|
.unwrap()
|
|
|
|
|
.lock()
|
|
|
|
|
.unwrap()
|
|
|
|
|
.result()
|
|
|
|
|
.multiple()
|
|
|
|
|
.and_then(|m| m.alternatives.first().map(|a| a.text.to_string()))
|
2025-12-12 02:05:37 +05:00
|
|
|
}
|
|
|
|
|
DecodingState::Failed => None,
|
2023-04-29 16:00:49 +05:00
|
|
|
}
|
2025-12-12 02:05:37 +05:00
|
|
|
},
|
|
|
|
|
Err(err) => {
|
|
|
|
|
error!("Vosk accept waveform error.\nError details: {}", err);
|
|
|
|
|
|
|
|
|
|
None
|
2023-04-27 00:28:36 +05:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-04-29 14:58:16 +05:00
|
|
|
// pub fn stereo_to_mono(input_data: &[i16]) -> Vec<i16> {
|
|
|
|
|
// let mut result = Vec::with_capacity(input_data.len() / 2);
|
|
|
|
|
// result.extend(
|
|
|
|
|
// input_data
|
|
|
|
|
// .chunks_exact(2)
|
|
|
|
|
// .map(|chunk| chunk[0] / 2 + chunk[1] / 2),
|
|
|
|
|
// );
|
2023-04-27 00:28:36 +05:00
|
|
|
|
2023-04-29 14:58:16 +05:00
|
|
|
// result
|
|
|
|
|
// }
|