Initial commit.

This commit is contained in:
Nolan Darilek 2018-12-14 19:35:49 +00:00
parent d2fc607df0
commit bac4b7555f
5 changed files with 125 additions and 0 deletions

14
Cargo.toml Normal file
View File

@ -0,0 +1,14 @@
[package]
name = "tts"
version = "0.1.0"
authors = ["Nolan Darilek <nolan@thewordnerd.info>"]
edition = "2018"
[dependencies]
log = "0.4"
[dev-dependencies]
env_logger = "0.6"
[target.'cfg(target_os = "linux")'.dependencies]
speech-dispatcher = "0.2"

15
examples/hello_world.rs Normal file
View File

@ -0,0 +1,15 @@
use tts::TTS;
fn main() {
env_logger::init();
let tts: TTS = Default::default();
tts.speak("Hello, world.", false);
let original_rate = tts.get_rate();
tts.speak(format!("Current rate: {}", original_rate), false);
tts.set_rate(std::u8::MAX);
tts.speak("This is very fast.", false);
tts.set_rate(0);
tts.speak("This is very slow.", false);
tts.set_rate(original_rate);
tts.speak("Goodbye.", false);
}

5
src/backends/mod.rs Normal file
View File

@ -0,0 +1,5 @@
#[cfg(target_os = "linux")]
mod speech_dispatcher;
#[cfg(target_os = "linux")]
pub use self::speech_dispatcher::*;

View File

@ -0,0 +1,45 @@
#[cfg(target_os = "linux")]
use std::u8;
use log::{info, trace};
use speech_dispatcher::*;
use crate::Backend;
pub struct SpeechDispatcher(Connection);
impl SpeechDispatcher {
pub fn new() -> impl Backend {
info!("Initializing SpeechDispatcher backend");
let connection = speech_dispatcher::Connection::open("tts", "tts", "tts", Mode::Single);
SpeechDispatcher(connection)
}
}
impl Backend for SpeechDispatcher {
fn speak(&self, text: &str, interrupt: bool) {
trace!("speak({}, {})", text, interrupt);
if interrupt {
self.0.cancel();
}
self.0.say(Priority::Important, text);
}
fn get_rate(&self) -> u8 {
let rate = self.0.get_voice_rate() as f32;
trace!("get_voice_rate() = {}", rate);
let ratio: f32 = (rate + 100.) / 200.;
trace!("ratio = {}", ratio);
let rate = ratio * u8::MAX as f32;
trace!("rate = {}", rate);
rate as u8
}
fn set_rate(&self, rate: u8) {
trace!("set_rate({})", rate);
let ratio: f32 = rate as f32/u8::MAX as f32;
let rate = ratio * 200. - 100.;
self.0.set_voice_rate(rate as i32);
}
}

46
src/lib.rs Normal file
View File

@ -0,0 +1,46 @@
use std::boxed::Box;
mod backends;
pub enum Backends {
#[cfg(target_os = "linux")]
SpeechDispatcher,
}
trait Backend {
fn speak(&self, text: &str, interrupt: bool);
fn get_rate(&self) -> u8;
fn set_rate(&self, rate: u8);
}
pub struct TTS(Box<Backend>);
impl TTS {
pub fn new(backend: Backends) -> TTS {
match backend {
#[cfg(target_os = "linux")]
Backends::SpeechDispatcher => TTS(Box::new(backends::SpeechDispatcher::new())),
}
}
pub fn speak<S: Into<String>>(&self, text: S, interrupt: bool) -> &Self {
self.0.speak(text.into().as_str(), interrupt);
self
}
pub fn get_rate(&self) -> u8 {
self.0.get_rate()
}
pub fn set_rate(&self, rate: u8) -> &Self {
self.0.set_rate(rate);
self
}
}
impl Default for TTS {
fn default() -> TTS {
#[cfg(target_os = "linux")]
TTS::new(Backends::SpeechDispatcher)
}
}