Compare commits

...

3 Commits

Author SHA1 Message Date
databasedav 2a72c58a48
Merge 2211818bc5 into 3bc16f0c6f 2024-04-22 10:11:34 +05:30
Nolan Darilek 3bc16f0c6f Bump version and windows dependency. 2024-04-19 09:17:08 -05:00
avi 2211818bc5 init 2023-04-13 01:07:05 -07:00
3 changed files with 62 additions and 2 deletions

View File

@ -1,6 +1,6 @@
[package] [package]
name = "tts" name = "tts"
version = "0.26.0" version = "0.26.1"
authors = ["Nolan Darilek <nolan@thewordnerd.info>"] authors = ["Nolan Darilek <nolan@thewordnerd.info>"]
repository = "https://github.com/ndarilek/tts-rs" repository = "https://github.com/ndarilek/tts-rs"
description = "High-level Text-To-Speech (TTS) interface" description = "High-level Text-To-Speech (TTS) interface"
@ -31,7 +31,7 @@ env_logger = "0.11"
[target.'cfg(windows)'.dependencies] [target.'cfg(windows)'.dependencies]
tolk = { version = "0.5", optional = true } tolk = { version = "0.5", optional = true }
windows = { version = "0.52", features = [ windows = { version = "0.56", features = [
"Foundation", "Foundation",
"Foundation_Collections", "Foundation_Collections",
"Media_Core", "Media_Core",

View File

@ -59,6 +59,7 @@ impl Backend for Web {
voice: true, voice: true,
get_voice: true, get_voice: true,
utterance_callbacks: true, utterance_callbacks: true,
pause_resume: true,
} }
} }
@ -109,6 +110,22 @@ impl Backend for Web {
mappings.retain(|v| v.1 != utterance_id); mappings.retain(|v| v.1 != utterance_id);
}) as Box<dyn Fn(_)>); }) as Box<dyn Fn(_)>);
utterance.set_onerror(Some(callback.as_ref().unchecked_ref())); utterance.set_onerror(Some(callback.as_ref().unchecked_ref()));
let callback = Closure::wrap(Box::new(move |evt: SpeechSynthesisErrorEvent| {
let mut callbacks = CALLBACKS.lock().unwrap();
let callback = callbacks.get_mut(&id).unwrap();
if let Some(f) = callback.utterance_pause.as_mut() {
f(utterance_id);
}
}) as Box<dyn Fn(_)>);
utterance.set_onpause(Some(callback.as_ref().unchecked_ref()));
let callback = Closure::wrap(Box::new(move |evt: SpeechSynthesisErrorEvent| {
let mut callbacks = CALLBACKS.lock().unwrap();
let callback = callbacks.get_mut(&id).unwrap();
if let Some(f) = callback.utterance_resume.as_mut() {
f(utterance_id);
}
}) as Box<dyn Fn(_)>);
utterance.set_onresume(Some(callback.as_ref().unchecked_ref()));
if interrupt { if interrupt {
self.stop()?; self.stop()?;
} }
@ -130,6 +147,24 @@ impl Backend for Web {
Ok(()) Ok(())
} }
fn pause(&mut self) -> Result<(), Error> {
trace!("pause()");
if let Some(window) = web_sys::window() {
let speech_synthesis = window.speech_synthesis().unwrap();
speech_synthesis.pause();
}
Ok(())
}
fn resume(&mut self) -> Result<(), Error> {
trace!("resume()");
if let Some(window) = web_sys::window() {
let speech_synthesis = window.speech_synthesis().unwrap();
speech_synthesis.resume();
}
Ok(())
}
fn min_rate(&self) -> f32 { fn min_rate(&self) -> f32 {
0.1 0.1
} }

View File

@ -170,6 +170,7 @@ pub struct Features {
pub voice: bool, pub voice: bool,
pub get_voice: bool, pub get_voice: bool,
pub volume: bool, pub volume: bool,
pub pause_resume: bool,
} }
impl fmt::Display for Features { impl fmt::Display for Features {
@ -245,6 +246,8 @@ struct Callbacks {
utterance_begin: Option<Box<dyn FnMut(UtteranceId)>>, utterance_begin: Option<Box<dyn FnMut(UtteranceId)>>,
utterance_end: Option<Box<dyn FnMut(UtteranceId)>>, utterance_end: Option<Box<dyn FnMut(UtteranceId)>>,
utterance_stop: Option<Box<dyn FnMut(UtteranceId)>>, utterance_stop: Option<Box<dyn FnMut(UtteranceId)>>,
utterance_pause: Option<Box<dyn FnMut(UtteranceId)>>,
utterance_resume: Option<Box<dyn FnMut(UtteranceId)>>,
} }
unsafe impl Send for Callbacks {} unsafe impl Send for Callbacks {}
@ -386,6 +389,28 @@ impl Tts {
} }
} }
/// Pauses current speech.
pub fn pause(&mut self) -> Result<&Self, Error> {
let Features { pause, .. } = self.supported_features();
if pause {
self.0.write().unwrap().pause()?;
Ok(self)
} else {
Err(Error::UnsupportedFeature)
}
}
/// Resumes current speech.
pub fn resume(&mut self) -> Result<&Self, Error> {
let Features { resume, .. } = self.supported_features();
if resume {
self.0.write().unwrap().resume()?;
Ok(self)
} else {
Err(Error::UnsupportedFeature)
}
}
/// Returns the minimum rate for this speech synthesizer. /// Returns the minimum rate for this speech synthesizer.
pub fn min_rate(&self) -> f32 { pub fn min_rate(&self) -> f32 {
self.0.read().unwrap().min_rate() self.0.read().unwrap().min_rate()