mirror of
https://github.com/ndarilek/tts-rs.git
synced 2024-11-25 10:29:36 +00:00
Merge branch 'master' into c-ffi
This commit is contained in:
commit
9ab38f550f
|
@ -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"
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)]
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#[cfg(all(windows, feature = "use_tolk"))]
|
||||
#[cfg(all(windows, feature = "tolk"))]
|
||||
use log::{info, trace};
|
||||
use tolk::Tolk as TolkPtr;
|
||||
|
||||
|
|
|
@ -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(())
|
||||
},
|
||||
))?;
|
||||
|
|
12
src/lib.rs
12
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<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);
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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();
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1 +1 @@
|
|||
include!(concat!(env!("OUT_DIR"), "/winrt.rs"));
|
||||
::windows::include_bindings!();
|
||||
|
|
Loading…
Reference in New Issue
Block a user