sapi_lite/tts/synthesizer/
event.rs1use std::ops::Deref;
2
3use windows as Windows;
4use Windows::core::Interface;
5use Windows::Win32::Media::Speech::{SPEI_END_INPUT_STREAM, SPF_ASYNC};
6
7use crate::event::{Event, EventSink, EventSource};
8use crate::tts::Speech;
9use crate::Result;
10
11use super::Synthesizer;
12
13pub trait EventHandler: Sync {
15 fn on_speech_finished(&self, id: u32);
17}
18
19impl<F: Fn(u32) + Sync> EventHandler for F {
20 fn on_speech_finished(&self, id: u32) {
21 self(id)
22 }
23}
24
25pub struct EventfulSynthesizer {
28 base: Synthesizer,
29}
30
31impl EventfulSynthesizer {
32 pub fn new<E: EventHandler + 'static>(handler: E) -> Result<Self> {
35 let base = Synthesizer::new()?;
36 EventSink::new(EventSource::from_sapi(base.intf.0.cast()?), move |event| {
37 if let Event::SpeechFinished(id) = event {
38 handler.on_speech_finished(id);
39 }
40 Ok(())
41 })
42 .install(Some(&[SPEI_END_INPUT_STREAM]))?;
43 Ok(Self { base })
44 }
45
46 pub fn speak<'s, S: Into<Speech<'s>>>(&self, speech: S) -> Result<u32> {
49 self.base.speak(speech, SPF_ASYNC.0 as _)
50 }
51}
52
53impl Deref for EventfulSynthesizer {
54 type Target = Synthesizer;
55 fn deref(&self) -> &Self::Target {
56 &self.base
57 }
58}