Merge branch 'master' into c-ffi

This commit is contained in:
mcb2003 2021-03-06 08:59:25 +00:00
commit 9ab38f550f
9 changed files with 59 additions and 76 deletions

View File

@ -1,6 +1,6 @@
[package]
name = "tts"
version = "0.13.1"
version = "0.14.0"
authors = ["Nolan Darilek <nolan@thewordnerd.info>"]
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"
ndk-glue = "0.2"

View File

@ -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

View File

@ -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)]

View File

@ -1,4 +1,4 @@
#[cfg(all(windows, feature = "use_tolk"))]
#[cfg(all(windows, feature = "tolk"))]
use log::{info, trace};
use tolk::Tolk as TolkPtr;

View File

@ -13,8 +13,8 @@ use tts_winrt_bindings::windows::{foundation::TypedEventHandler, media::core::Me
use crate::{Backend, BackendId, Error, Features, UtteranceId, CALLBACKS};
impl From<winrt::Error> for Error {
fn from(e: winrt::Error) -> Self {
impl From<windows::Error> 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<MediaPlayer>, _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(())
},
))?;

View File

@ -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<TTS, Error> {
#[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);

View File

@ -1,13 +1,13 @@
[package]
name = "tts_winrt_bindings"
version = "0.2.0"
version = "0.3.0"
authors = ["Nolan Darilek <nolan@thewordnerd.info>"]
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"

View File

@ -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();
);
}

View File

@ -1 +1 @@
include!(concat!(env!("OUT_DIR"), "/winrt.rs"));
::windows::include_bindings!();