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

View File

@ -59,6 +59,7 @@ impl Backend for Web {
voice: true,
get_voice: true,
utterance_callbacks: true,
pause_resume: true,
}
}
@ -109,6 +110,22 @@ impl Backend for Web {
mappings.retain(|v| v.1 != utterance_id);
}) as Box<dyn Fn(_)>);
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 {
self.stop()?;
}
@ -130,6 +147,24 @@ impl Backend for Web {
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 {
0.1
}

View File

@ -170,6 +170,7 @@ pub struct Features {
pub voice: bool,
pub get_voice: bool,
pub volume: bool,
pub pause_resume: bool,
}
impl fmt::Display for Features {
@ -245,6 +246,8 @@ struct Callbacks {
utterance_begin: Option<Box<dyn FnMut(UtteranceId)>>,
utterance_end: 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 {}
@ -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.
pub fn min_rate(&self) -> f32 {
self.0.read().unwrap().min_rate()