From c24c1d323098a6d72761f3c6ac32c91cef6d3400 Mon Sep 17 00:00:00 2001 From: Nolan Darilek Date: Tue, 2 Jun 2020 14:53:14 -0500 Subject: [PATCH] Implement support for detecting when TTS is speaking. --- src/backends/speech_dispatcher.rs | 5 +++++ src/backends/tolk.rs | 5 +++++ src/backends/web.rs | 13 +++++++++++++ src/backends/winrt.rs | 5 +++++ src/lib.rs | 18 ++++++++++++++++++ 5 files changed, 46 insertions(+) diff --git a/src/backends/speech_dispatcher.rs b/src/backends/speech_dispatcher.rs index e9615d3..0d7252c 100644 --- a/src/backends/speech_dispatcher.rs +++ b/src/backends/speech_dispatcher.rs @@ -21,6 +21,7 @@ impl Backend for SpeechDispatcher { rate: true, pitch: true, volume: true, + is_speaking: false, } } @@ -108,4 +109,8 @@ impl Backend for SpeechDispatcher { self.0.set_volume(volume as i32); Ok(()) } + + fn is_speaking(&self) -> Result { + unimplemented!() + } } diff --git a/src/backends/tolk.rs b/src/backends/tolk.rs index 4b9d747..18ccd13 100644 --- a/src/backends/tolk.rs +++ b/src/backends/tolk.rs @@ -22,6 +22,7 @@ impl Backend for Tolk { rate: false, pitch: false, volume: false, + is_speaking: false, } } @@ -96,4 +97,8 @@ impl Backend for Tolk { fn set_volume(&mut self, _volume: f32) -> Result<(), Error> { unimplemented!(); } + + fn is_speaking(&self) -> Result { + unimplemented!() + } } diff --git a/src/backends/web.rs b/src/backends/web.rs index fe79d5a..7367f80 100644 --- a/src/backends/web.rs +++ b/src/backends/web.rs @@ -28,6 +28,7 @@ impl Backend for Web { rate: true, pitch: true, volume: true, + is_speaking: true, } } @@ -118,4 +119,16 @@ impl Backend for Web { self.volume = volume; Ok(()) } + + fn is_speaking(&self) -> Result { + trace!("is_speaking()"); + if let Some(window) = web_sys::window() { + match window.speech_synthesis() { + Ok(speech_synthesis) => Ok(speech_synthesis.speaking()), + Err(e) => Err(Error::JavaScriptError(e)), + } + } else { + Err(Error::NoneError) + } + } } diff --git a/src/backends/winrt.rs b/src/backends/winrt.rs index d23480e..a915dfd 100644 --- a/src/backends/winrt.rs +++ b/src/backends/winrt.rs @@ -51,6 +51,7 @@ impl Backend for WinRT { rate: true, pitch: true, volume: true, + is_speaking: false, } } @@ -136,4 +137,8 @@ impl Backend for WinRT { self.synth.options()?.set_audio_volume(volume.into())?; Ok(()) } + + fn is_speaking(&self) -> Result { + unimplemented!() + } } diff --git a/src/lib.rs b/src/lib.rs index d363a1d..6c71641 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -28,12 +28,17 @@ pub struct Features { pub rate: bool, pub pitch: bool, pub volume: bool, + pub is_speaking: bool, } #[derive(Debug, Error)] pub enum Error { #[error("IO error: {0}")] IO(#[from] std::io::Error), + #[error("Value not received")] + NoneError, + #[error("JavaScript error: [0])]")] + JavaScriptError(wasm_bindgen::JsValue), #[cfg(windows)] #[error("WinRT error")] WinRT(winrt::Error), @@ -62,6 +67,7 @@ pub trait Backend { fn normal_volume(&self) -> f32; fn get_volume(&self) -> Result; fn set_volume(&mut self, volume: f32) -> Result<(), Error>; + fn is_speaking(&self) -> Result; } pub struct TTS(Box); @@ -298,4 +304,16 @@ impl TTS { Err(Error::UnsupportedFeature) } } + + /** + * Returns whether this speech synthesizer is speaking. + */ + pub fn is_speaking(&self) -> Result { + let Features { is_speaking, .. } = self.supported_features(); + if is_speaking { + self.0.is_speaking() + } else { + Err(Error::UnsupportedFeature) + } + } }