1#![doc = include_str!("../README.md")]
2
3use crate::asr::{AutomaticSpeechRecognition, AutomaticSpeechRecognitionConfig};
4use crate::error::*;
5use crate::input::{AudioInput, AudioInputConfig};
6use crate::vad::{VoiceActivityDetection, VoiceActivityDetectionConfig};
7use serde::{Deserialize, Serialize};
8use tokio::sync::broadcast::Receiver;
9
10pub mod asr;
11pub mod error;
12pub mod input;
13pub mod utils;
14pub mod vad;
15
16#[derive(Debug, Clone, Serialize, Deserialize, Default)]
18pub struct NihilityListenerConfig {
19 pub audio_input: AudioInputConfig,
20 pub vad: VoiceActivityDetectionConfig,
21 pub asr: AutomaticSpeechRecognitionConfig,
22}
23
24pub struct NihilityListener {
26 input: AudioInput,
27 vad: VoiceActivityDetection,
28 asr: AutomaticSpeechRecognition,
29}
30
31impl NihilityListener {
32 pub fn init_from_file_config() -> Result<Self> {
34 Self::init(nihility_config::get_config::<NihilityListenerConfig>(
35 env!("CARGO_PKG_NAME"),
36 )?)
37 }
38
39 pub fn init(config: NihilityListenerConfig) -> Result<Self> {
41 let input = AudioInput::init(config.audio_input.clone())?;
42 let vad = VoiceActivityDetection::init(config.vad.clone(), input.get_sample_receiver())?;
43 let asr = AutomaticSpeechRecognition::init(config.asr.clone(), vad.get_speech_receiver())?;
44 Ok(Self { input, vad, asr })
45 }
46
47 pub fn get_sample_receiver(&self) -> Receiver<f32> {
49 self.input.get_sample_receiver()
50 }
51
52 pub fn get_probability_receiver(&self) -> Result<Receiver<f32>> {
54 self.vad.get_probability_receiver()
55 }
56
57 pub fn get_speech_receiver(&self) -> Receiver<Vec<f32>> {
59 self.vad.get_speech_receiver()
60 }
61
62 pub fn get_text_receiver(&self) -> Receiver<String> {
64 self.asr.get_text_receiver()
65 }
66
67 pub async fn run(&mut self) -> Result<()> {
69 tokio::try_join!(self.asr.run(), self.vad.run(), self.input.run())?;
70 Ok(())
71 }
72}