Skip to main content

sapi_lite/tts/synthesizer/
sync.rs

1use std::ops::Deref;
2use std::time::Duration;
3
4use windows as Windows;
5use Windows::Win32::Media::Speech::SPF_ASYNC;
6use Windows::Win32::System::WindowsProgramming::INFINITE;
7
8use crate::tts::Speech;
9use crate::Result;
10
11use super::Synthesizer;
12
13/// A speech synthesizer that blocks the current thread while rendering speech.
14pub struct SyncSynthesizer {
15    base: Synthesizer,
16}
17
18impl SyncSynthesizer {
19    /// Creates a new synthesizer, configured to output its speech to the default audio device.
20    pub fn new() -> Result<Self> {
21        Ok(Self {
22            base: Synthesizer::new()?,
23        })
24    }
25
26    /// Renders the given speech, blocking the thread until done or until the given timeout expires.
27    pub fn speak<'s, S: Into<Speech<'s>>>(
28        &self,
29        speech: S,
30        timeout: Option<Duration>,
31    ) -> Result<()> {
32        self.base.speak(speech, SPF_ASYNC.0 as _)?;
33        unsafe {
34            self.base.intf.WaitUntilDone(
35                timeout
36                    .map(|dur| dur.as_millis() as u32)
37                    .unwrap_or(INFINITE),
38            )
39        }
40    }
41}
42
43impl Deref for SyncSynthesizer {
44    type Target = Synthesizer;
45    fn deref(&self) -> &Self::Target {
46        &self.base
47    }
48}