mirror of
https://github.com/ndarilek/tts-rs.git
synced 2024-11-17 11:29:37 +00:00
Make speak calls return an utterance ID, where possible.
This commit is contained in:
parent
d6508edd12
commit
4816ec575c
|
@ -6,7 +6,7 @@ use lazy_static::*;
|
|||
use log::{info, trace};
|
||||
use speech_dispatcher::*;
|
||||
|
||||
use crate::{Backend, Error, Features};
|
||||
use crate::{Backend, Error, Features, UtteranceId};
|
||||
|
||||
pub struct SpeechDispatcher(Connection);
|
||||
|
||||
|
@ -59,7 +59,7 @@ impl Backend for SpeechDispatcher {
|
|||
}
|
||||
}
|
||||
|
||||
fn speak(&mut self, text: &str, interrupt: bool) -> Result<(), Error> {
|
||||
fn speak(&mut self, text: &str, interrupt: bool) -> Result<Option<UtteranceId>, Error> {
|
||||
trace!("speak({}, {})", text, interrupt);
|
||||
if interrupt {
|
||||
self.stop()?;
|
||||
|
@ -68,11 +68,15 @@ impl Backend for SpeechDispatcher {
|
|||
if single_char {
|
||||
self.0.set_punctuation(Punctuation::All);
|
||||
}
|
||||
self.0.say(Priority::Important, text);
|
||||
let id = self.0.say(Priority::Important, text);
|
||||
if single_char {
|
||||
self.0.set_punctuation(Punctuation::None);
|
||||
}
|
||||
Ok(())
|
||||
if let Some(id) = id {
|
||||
Ok(Some(UtteranceId::SpeechDispatcher(id)))
|
||||
} else {
|
||||
Err(Error::NoneError)
|
||||
}
|
||||
}
|
||||
|
||||
fn stop(&mut self) -> Result<(), Error> {
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
use log::{info, trace};
|
||||
use tolk::Tolk as TolkPtr;
|
||||
|
||||
use crate::{Backend, Error, Features};
|
||||
use crate::{Backend, Error, Features, UtteranceId};
|
||||
|
||||
pub struct Tolk(TolkPtr);
|
||||
|
||||
|
@ -26,10 +26,10 @@ impl Backend for Tolk {
|
|||
}
|
||||
}
|
||||
|
||||
fn speak(&mut self, text: &str, interrupt: bool) -> Result<(), Error> {
|
||||
fn speak(&mut self, text: &str, interrupt: bool) -> Result<Option<UtteranceId>, Error> {
|
||||
trace!("speak({}, {})", text, interrupt);
|
||||
self.0.speak(text, interrupt);
|
||||
Ok(())
|
||||
Ok(None)
|
||||
}
|
||||
|
||||
fn stop(&mut self) -> Result<(), Error> {
|
||||
|
|
|
@ -1,8 +1,11 @@
|
|||
#[cfg(target_arch = "wasm32")]
|
||||
use std::sync::Mutex;
|
||||
|
||||
use lazy_static::lazy_static;
|
||||
use log::{info, trace};
|
||||
use web_sys::SpeechSynthesisUtterance;
|
||||
|
||||
use crate::{Backend, Error, Features};
|
||||
use crate::{Backend, Error, Features, UtteranceId};
|
||||
|
||||
pub struct Web {
|
||||
rate: f32,
|
||||
|
@ -10,6 +13,10 @@ pub struct Web {
|
|||
volume: f32,
|
||||
}
|
||||
|
||||
lazy_static! {
|
||||
static ref NEXT_UTTERANCE_ID: Mutex<u64> = Mutex::new(0);
|
||||
}
|
||||
|
||||
impl Web {
|
||||
pub fn new() -> Result<Self, Error> {
|
||||
info!("Initializing Web backend");
|
||||
|
@ -32,7 +39,7 @@ impl Backend for Web {
|
|||
}
|
||||
}
|
||||
|
||||
fn speak(&mut self, text: &str, interrupt: bool) -> Result<(), Error> {
|
||||
fn speak(&mut self, text: &str, interrupt: bool) -> Result<Option<UtteranceId>, Error> {
|
||||
trace!("speak({}, {})", text, interrupt);
|
||||
let utterance = SpeechSynthesisUtterance::new_with_text(text).unwrap();
|
||||
utterance.set_rate(self.rate);
|
||||
|
@ -44,8 +51,12 @@ impl Backend for Web {
|
|||
if let Some(window) = web_sys::window() {
|
||||
let speech_synthesis = window.speech_synthesis().unwrap();
|
||||
speech_synthesis.speak(&utterance);
|
||||
let mut utterance_id = NEXT_UTTERANCE_ID.lock().unwrap();
|
||||
*utterance_id += 1;
|
||||
Ok(Some(UtteranceId::Web(*utterance_id)))
|
||||
} else {
|
||||
Err(Error::NoneError)
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn stop(&mut self) -> Result<(), Error> {
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
#[cfg(windows)]
|
||||
use std::sync::Mutex;
|
||||
|
||||
use lazy_static::lazy_static;
|
||||
use log::{info, trace};
|
||||
|
||||
use tts_winrt_bindings::windows::media::core::MediaSource;
|
||||
|
@ -7,7 +10,7 @@ use tts_winrt_bindings::windows::media::playback::{
|
|||
};
|
||||
use tts_winrt_bindings::windows::media::speech_synthesis::SpeechSynthesizer;
|
||||
|
||||
use crate::{Backend, Error, Features};
|
||||
use crate::{Backend, Error, Features, UtteranceId};
|
||||
|
||||
impl From<winrt::Error> for Error {
|
||||
fn from(e: winrt::Error) -> Self {
|
||||
|
@ -21,6 +24,10 @@ pub struct WinRT {
|
|||
playback_list: MediaPlaybackList,
|
||||
}
|
||||
|
||||
lazy_static! {
|
||||
static ref NEXT_UTTERANCE_ID: Mutex<u64> = Mutex::new(0);
|
||||
}
|
||||
|
||||
impl WinRT {
|
||||
pub fn new() -> std::result::Result<Self, Error> {
|
||||
info!("Initializing WinRT backend");
|
||||
|
@ -55,7 +62,11 @@ impl Backend for WinRT {
|
|||
}
|
||||
}
|
||||
|
||||
fn speak(&mut self, text: &str, interrupt: bool) -> std::result::Result<(), Error> {
|
||||
fn speak(
|
||||
&mut self,
|
||||
text: &str,
|
||||
interrupt: bool,
|
||||
) -> std::result::Result<Option<UtteranceId>, Error> {
|
||||
trace!("speak({}, {})", text, interrupt);
|
||||
if interrupt {
|
||||
self.stop()?;
|
||||
|
@ -76,7 +87,9 @@ impl Backend for WinRT {
|
|||
if !self.is_speaking()? {
|
||||
self.player.play()?;
|
||||
}
|
||||
Ok(())
|
||||
let mut utterance_id = NEXT_UTTERANCE_ID.lock().unwrap();
|
||||
*utterance_id += 1;
|
||||
Ok(Some(UtteranceId::WinRT(*utterance_id)))
|
||||
}
|
||||
|
||||
fn stop(&mut self) -> std::result::Result<(), Error> {
|
||||
|
|
21
src/lib.rs
21
src/lib.rs
|
@ -40,6 +40,16 @@ pub enum Backends {
|
|||
AvFoundation,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||
pub enum UtteranceId {
|
||||
#[cfg(target_os = "linux")]
|
||||
SpeechDispatcher(i32),
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
Web(u64),
|
||||
#[cfg(windows)]
|
||||
WinRT(u64),
|
||||
}
|
||||
|
||||
pub struct Features {
|
||||
pub stop: bool,
|
||||
pub rate: bool,
|
||||
|
@ -80,7 +90,7 @@ pub enum Error {
|
|||
|
||||
pub trait Backend {
|
||||
fn supported_features(&self) -> Features;
|
||||
fn speak(&mut self, text: &str, interrupt: bool) -> Result<(), Error>;
|
||||
fn speak(&mut self, text: &str, interrupt: bool) -> Result<Option<UtteranceId>, Error>;
|
||||
fn stop(&mut self) -> Result<(), Error>;
|
||||
fn min_rate(&self) -> f32;
|
||||
fn max_rate(&self) -> f32;
|
||||
|
@ -184,9 +194,12 @@ impl TTS {
|
|||
/**
|
||||
* Speaks the specified text, optionally interrupting current speech.
|
||||
*/
|
||||
pub fn speak<S: Into<String>>(&mut self, text: S, interrupt: bool) -> Result<&Self, Error> {
|
||||
self.0.speak(text.into().as_str(), interrupt)?;
|
||||
Ok(self)
|
||||
pub fn speak<S: Into<String>>(
|
||||
&mut self,
|
||||
text: S,
|
||||
interrupt: bool,
|
||||
) -> Result<Option<UtteranceId>, Error> {
|
||||
self.0.speak(text.into().as_str(), interrupt)
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue
Block a user