diff --git a/Cargo.toml b/Cargo.toml index 96d49c5..7b8c389 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "tts" -version = "0.13.1" +version = "0.14.0" authors = ["Nolan Darilek "] repository = "https://github.com/ndarilek/tts-rs" description = "High-level Text-To-Speech (TTS) interface" @@ -27,8 +27,8 @@ env_logger = "0.8" [target.'cfg(windows)'.dependencies] tolk = { version = "0.3", optional = true } -winrt = "0.7" -tts_winrt_bindings = { version = "0.2", path="winrt_bindings" } +windows = "0.2" +tts_winrt_bindings = { version = "0.3", path="winrt_bindings" } [target.'cfg(target_os = "linux")'.dependencies] speech-dispatcher = "0.7" @@ -44,4 +44,4 @@ web-sys = { version = "0.3", features = ["EventTarget", "SpeechSynthesis", "Spee [target.'cfg(target_os="android")'.dependencies] jni = "0.18" -ndk-glue = "0.2" \ No newline at end of file +ndk-glue = "0.2" diff --git a/README.md b/README.md index 90fab74..790e4f2 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ This library provides a high-level Text-To-Speech (TTS) interface supporting various backends. Currently supported backends are: * Windows - * Screen readers/SAPI via Tolk (requires `use_tolk` Cargo feature) + * Screen readers/SAPI via Tolk (requires `tolk` Cargo feature) * WinRT * Linux via [Speech Dispatcher](https://freebsoft.org/speechd) * MacOS/iOS diff --git a/src/backends/mod.rs b/src/backends/mod.rs index a40ca57..eefdff6 100644 --- a/src/backends/mod.rs +++ b/src/backends/mod.rs @@ -1,7 +1,7 @@ #[cfg(target_os = "linux")] mod speech_dispatcher; -#[cfg(all(windows, feature = "use_tolk"))] +#[cfg(all(windows, feature = "tolk"))] mod tolk; #[cfg(windows)] @@ -23,7 +23,7 @@ mod android; #[cfg(target_os = "linux")] pub(crate) use self::speech_dispatcher::*; -#[cfg(all(windows, feature = "use_tolk"))] +#[cfg(all(windows, feature = "tolk"))] pub(crate) use self::tolk::*; #[cfg(windows)] diff --git a/src/backends/tolk.rs b/src/backends/tolk.rs index f9281f7..ae16e4f 100644 --- a/src/backends/tolk.rs +++ b/src/backends/tolk.rs @@ -1,4 +1,4 @@ -#[cfg(all(windows, feature = "use_tolk"))] +#[cfg(all(windows, feature = "tolk"))] use log::{info, trace}; use tolk::Tolk as TolkPtr; diff --git a/src/backends/winrt.rs b/src/backends/winrt.rs index 890ef63..d9b7704 100644 --- a/src/backends/winrt.rs +++ b/src/backends/winrt.rs @@ -13,8 +13,8 @@ use tts_winrt_bindings::windows::{foundation::TypedEventHandler, media::core::Me use crate::{Backend, BackendId, Error, Features, UtteranceId, CALLBACKS}; -impl From for Error { - fn from(e: winrt::Error) -> Self { +impl From for Error { + fn from(e: windows::Error) -> Self { Error::WinRT(e) } } @@ -77,60 +77,48 @@ impl WinRT { drop(backend_to_speech_synthesizer); let bid_clone = bid; player.media_ended(TypedEventHandler::new( - move |sender: &MediaPlayer, _args| { - let backend_to_media_player = BACKEND_TO_MEDIA_PLAYER.lock().unwrap(); - let id = backend_to_media_player.iter().find(|v| v.1 == sender); - if let Some((id, _)) = id { - let mut utterances = UTTERANCES.lock().unwrap(); - if let Some(utterances) = utterances.get_mut(id) { - if let Some(utterance) = utterances.pop_front() { - let mut callbacks = CALLBACKS.lock().unwrap(); - let callbacks = callbacks.get_mut(id).unwrap(); - if let Some(callback) = callbacks.utterance_end.as_mut() { - callback(utterance.id); - } - if let Some(utterance) = utterances.front() { - let backend_to_speech_synthesizer = - BACKEND_TO_SPEECH_SYNTHESIZER.lock().unwrap(); - let id = backend_to_speech_synthesizer - .iter() - .find(|v| *v.0 == bid_clone); - if let Some((_, tts)) = id { - tts.options()?.set_speaking_rate(utterance.rate.into())?; - tts.options()?.set_audio_pitch(utterance.pitch.into())?; - tts.options()?.set_audio_volume(utterance.volume.into())?; - let stream = tts - .synthesize_text_to_stream_async(utterance.text.as_str())? - .get()?; - let content_type = stream.content_type()?; - let source = - MediaSource::create_from_stream(stream, content_type)?; - sender.set_source(source)?; - sender.play()?; - if let Some(callback) = callbacks.utterance_begin.as_mut() { - callback(utterance.id); + move |sender: &Option, _args| { + if let Some(sender) = sender { + let backend_to_media_player = BACKEND_TO_MEDIA_PLAYER.lock().unwrap(); + let id = backend_to_media_player.iter().find(|v| v.1 == sender); + if let Some((id, _)) = id { + let mut utterances = UTTERANCES.lock().unwrap(); + if let Some(utterances) = utterances.get_mut(id) { + if let Some(utterance) = utterances.pop_front() { + let mut callbacks = CALLBACKS.lock().unwrap(); + let callbacks = callbacks.get_mut(id).unwrap(); + if let Some(callback) = callbacks.utterance_end.as_mut() { + callback(utterance.id); + } + if let Some(utterance) = utterances.front() { + let backend_to_speech_synthesizer = + BACKEND_TO_SPEECH_SYNTHESIZER.lock().unwrap(); + let id = backend_to_speech_synthesizer + .iter() + .find(|v| *v.0 == bid_clone); + if let Some((_, tts)) = id { + tts.options()?.set_speaking_rate(utterance.rate.into())?; + tts.options()?.set_audio_pitch(utterance.pitch.into())?; + tts.options()?.set_audio_volume(utterance.volume.into())?; + let stream = tts + .synthesize_text_to_stream_async( + utterance.text.as_str(), + )? + .get()?; + let content_type = stream.content_type()?; + let source = + MediaSource::create_from_stream(stream, content_type)?; + sender.set_source(source)?; + sender.play()?; + if let Some(callback) = callbacks.utterance_begin.as_mut() { + callback(utterance.id); + } } } } } } } - /*let source = sender.source()?; - let source: MediaPlaybackList = source.try_into()?; - source.items()?.clear()?; - let backend_to_media_player = BACKEND_TO_MEDIA_PLAYER.lock().unwrap(); - let id = backend_to_media_player.iter().find(|v| v.1 == sender); - if let Some(id) = id { - let id = id.0; - let mut callbacks = CALLBACKS.lock().unwrap(); - let callbacks = callbacks.get_mut(&id).unwrap(); - if let Some(callback) = callbacks.utterance_end.as_mut() { - let last_spoken_utterance = LAST_SPOKEN_UTTERANCE.lock().unwrap(); - if let Some(utterance_id) = last_spoken_utterance.get(&id) { - callback(*utterance_id); - } - } - }*/ Ok(()) }, ))?; diff --git a/src/lib.rs b/src/lib.rs index 648be45..0ce01c8 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -2,7 +2,7 @@ * a Text-To-Speech (TTS) library providing high-level interfaces to a variety of backends. * Currently supported backends are: * * Windows - * * Screen readers/SAPI via Tolk (requires `use_tolk` Cargo feature) + * * Screen readers/SAPI via Tolk (requires `tolk` Cargo feature) * * WinRT * * Linux via [Speech Dispatcher](https://freebsoft.org/speechd) * * MacOS/iOS @@ -39,7 +39,7 @@ pub enum Backends { SpeechDispatcher, #[cfg(target_arch = "wasm32")] Web, - #[cfg(all(windows, feature = "use_tolk"))] + #[cfg(all(windows, feature = "tolk"))] Tolk, #[cfg(windows)] WinRT, @@ -119,7 +119,7 @@ pub enum Error { JavaScriptError(wasm_bindgen::JsValue), #[cfg(windows)] #[error("WinRT error")] - WinRT(winrt::Error), + WinRT(windows::Error), #[error("Unsupported feature")] UnsupportedFeature, #[error("Out of range")] @@ -191,7 +191,7 @@ impl TTS { let tts = backends::Web::new()?; Ok(TTS(Box::new(tts))) } - #[cfg(all(windows, feature = "use_tolk"))] + #[cfg(all(windows, feature = "tolk"))] Backends::Tolk => { let tts = backends::Tolk::new(); if let Some(tts) = tts { @@ -229,13 +229,13 @@ impl TTS { pub fn default() -> Result { #[cfg(target_os = "linux")] let tts = TTS::new(Backends::SpeechDispatcher); - #[cfg(all(windows, feature = "use_tolk"))] + #[cfg(all(windows, feature = "tolk"))] let tts = if let Ok(tts) = TTS::new(Backends::Tolk) { Ok(tts) } else { TTS::new(Backends::WinRT) }; - #[cfg(all(windows, not(feature = "use_tolk")))] + #[cfg(all(windows, not(feature = "tolk")))] let tts = TTS::new(Backends::WinRT); #[cfg(target_arch = "wasm32")] let tts = TTS::new(Backends::Web); diff --git a/winrt_bindings/Cargo.toml b/winrt_bindings/Cargo.toml index c0afe2c..eaf4bb2 100644 --- a/winrt_bindings/Cargo.toml +++ b/winrt_bindings/Cargo.toml @@ -1,13 +1,13 @@ [package] name = "tts_winrt_bindings" -version = "0.2.0" +version = "0.3.0" authors = ["Nolan Darilek "] description = "Internal crate used by `tts`" license = "MIT" edition = "2018" [dependencies] -winrt = "0.7" +windows = "0.2" [build-dependencies] -winrt = "0.7" +windows = "0.2" diff --git a/winrt_bindings/build.rs b/winrt_bindings/build.rs index 2cd927d..654291a 100644 --- a/winrt_bindings/build.rs +++ b/winrt_bindings/build.rs @@ -1,12 +1,7 @@ -winrt::build!( - dependencies - os - types +fn main() { + windows::build!( windows::media::core::MediaSource windows::media::playback::{MediaPlaybackState, MediaPlayer} windows::media::speech_synthesis::SpeechSynthesizer -); - -fn main() { - build(); + ); } diff --git a/winrt_bindings/src/lib.rs b/winrt_bindings/src/lib.rs index 056780e..42af6ba 100644 --- a/winrt_bindings/src/lib.rs +++ b/winrt_bindings/src/lib.rs @@ -1 +1 @@ -include!(concat!(env!("OUT_DIR"), "/winrt.rs")); +::windows::include_bindings!();