use rust_whisper_lib; use rust_whisper_baked_lib; use clap::Parser; use listen_lib; use std::thread; fn main() { let flags = rust_whisper_lib::Flags::parse(); match flags.wav.clone() { Some(_) => wav_channel(flags), None => channel(flags), }; } fn wav_channel(flags: rust_whisper_lib::Flags) { let mut w = new_destutterer(); rust_whisper_baked_lib::wav_channel( flags.clone(), move |result: Result| { match result { Ok(transcribed) => { let s = w.step(transcribed.to_string()); println!("{}", s); }, Err(msg) => { eprintln!("error: {}", msg); }, }; }, ); } fn wav(flags: rust_whisper_lib::Flags, _path: String) { let mut w = new_destutterer(); rust_whisper_baked_lib::wav(flags, move |result: Result| { match result { Ok(transcribed) => { let s = w.step(transcribed.to_string()); println!("{}", s); }, Err(msg) => { eprintln!("error: {}", msg); }, }; }, ); } fn channel(flags: rust_whisper_lib::Flags) { let (send, recv) = std::sync::mpsc::sync_channel(100); eprintln!("rust whisper baked lib channel..."); thread::spawn(move || { rust_whisper_baked_lib::channel( flags.clone(), |result: Result| { match result { Ok(transcribed) => { println!("{}", transcribed.to_string()); }, Err(msg) => { eprintln!("error: {}", msg); }, }; }, recv, ); }); eprintln!("listen lib main..."); let flags = rust_whisper_lib::Flags::parse(); match flags.stream_device { Some(device_name) => { if device_name == "" { for device in listen_lib::devices() { eprintln!("{}", device); } } else { listen_lib::main_with(|data| { send.send(data).unwrap(); }, device_name); } }, None => { listen_lib::main(|data| { send.send(data).unwrap(); }); } } eprintln!("/listen lib main..."); } struct Destutterer { prevs: Vec, } fn new_destutterer() -> Destutterer { Destutterer{prevs: vec![]} } impl Destutterer { fn step(&mut self, next: String) -> String { if next.len() == 0 { return next; } let nexts = Word::from_string(next.clone()); let mut n = self.prevs.len().clamp(0, nexts.len()); while n > 0 { let prev_s = Word::to_comparable_string(self.prevs[self.prevs.len() - n..].to_vec()); let next_s = Word::to_comparable_string(nexts[..n].to_vec()); if prev_s == next_s { break; } n -= 1; } self.prevs = nexts.clone(); Word::to_string(nexts[n..].to_vec()) } } #[derive(Clone)] struct Word { raw: String, } impl Word { fn from_string(s: String) -> Vec { let mut result = vec![]; for word in s.split(" ") { let word = word.trim(); if word.len() > 0 { result.push(Word{raw: word.to_string()}); } } result } fn to_comparable_string(v: Vec) -> String { v.iter() .map(|x| x.raw.chars().filter(|c| c.is_ascii_alphanumeric()).collect()) .collect::>() .join(" ") } fn to_string(v: Vec) -> String { v.iter() .map(|x| x.raw.clone()) .collect::>() .join(" ") } } #[cfg(test)] mod tests { use super::*; #[test] fn test_destutterer_punctuation() { let mut w = new_destutterer(); assert_eq!("a, b. c? d!".to_string(), w.step("a, b. c? d!".to_string())); assert_eq!("e! f g".to_string(), w.step("d, e! f g".to_string())); assert_eq!("hij".to_string(), w.step("f g hij".to_string())); } #[test] fn test_destutterer_letters() { let mut w = new_destutterer(); assert_eq!("a b c d e".to_string(), w.step("a b c d e".to_string())); assert_eq!("f g".to_string(), w.step(" c d e f g".to_string())); assert_eq!("h i j".to_string(), w.step("f g h i j ".to_string())); assert_eq!("a g h i j".to_string(), w.step("a g h i j".to_string())); } }