sapi_lite/tts/synthesizer/
mod.rs

1use windows as Windows;
2use Windows::core::IUnknown;
3use Windows::Win32::Media::Speech::{ISpVoice, SpVoice};
4use Windows::Win32::System::Com::{CoCreateInstance, CLSCTX_ALL};
5
6use crate::audio::AudioStream;
7use crate::com_util::{out_to_ret, Intf};
8use crate::token::Token;
9use crate::Result;
10
11use super::{Rate, Speech, Voice, Volume};
12
13mod event;
14mod sync;
15
16pub use event::{EventHandler, EventfulSynthesizer};
17pub use sync::SyncSynthesizer;
18
19/// Specifies where the output of speech synthesis should go.
20pub enum SpeechOutput {
21    /// Output to the default audio device on the system
22    Default,
23    /// Write to the given stream
24    Stream(AudioStream),
25}
26
27impl SpeechOutput {
28    fn to_sapi(self) -> Option<IUnknown> {
29        match self {
30            Self::Default => None,
31            Self::Stream(stream) => Some(stream.to_sapi().0),
32        }
33    }
34}
35
36/// Provides the common speech synthesis API shared across different kinds of synthesizers.
37pub struct Synthesizer {
38    intf: Intf<ISpVoice>,
39}
40
41impl Synthesizer {
42    fn new() -> Result<Self> {
43        unsafe { CoCreateInstance(&SpVoice, None, CLSCTX_ALL) }
44            .map(|intf| Self { intf: Intf(intf) })
45    }
46
47    /// Configures the synthesizer to render its speech to the given output destination.
48    pub fn set_output(&self, output: SpeechOutput, allow_fmt_changes: bool) -> Result<()> {
49        unsafe { self.intf.SetOutput(output.to_sapi(), allow_fmt_changes) }
50    }
51
52    /// Returns the default rate of speech for this synthesizer.
53    pub fn rate(&self) -> Result<Rate> {
54        unsafe { out_to_ret(|out| self.intf.GetRate(out)) }.map(Rate::new)
55    }
56
57    /// Returns the default voice this synthesizer will use to render speech.
58    pub fn voice(&self) -> Result<Voice> {
59        unsafe { self.intf.GetVoice() }.map(|intf| Voice {
60            token: Token::from_sapi(intf),
61        })
62    }
63
64    /// Returns the default speech volume for this synthesizer.
65    pub fn volume(&self) -> Result<Volume> {
66        unsafe { out_to_ret(|out| self.intf.GetVolume(out)) }.map(Volume::from_sapi)
67    }
68
69    /// Sets the default rate of speech for this synthesizer.
70    pub fn set_rate<R: Into<Rate>>(&self, rate: R) -> Result<()> {
71        unsafe { self.intf.SetRate(rate.into().value()) }
72    }
73
74    /// Sets the default voice this synthesizer will use to render speech.
75    pub fn set_voice(&self, voice: &Voice) -> Result<()> {
76        unsafe { self.intf.SetVoice(&voice.token) }
77    }
78
79    /// Sets the default speech volume for this synthesizer.
80    pub fn set_volume<V: Into<Volume>>(&self, volume: V) -> Result<()> {
81        unsafe { self.intf.SetVolume(volume.into().sapi_value()) }
82    }
83
84    fn speak<'s, S: Into<Speech<'s>>>(&self, speech: S, base_flags: u32) -> Result<u32> {
85        let speech = speech.into();
86        unsafe {
87            self.intf
88                .Speak(speech.contents(), speech.flags() | base_flags)
89        }
90    }
91}