From 187cd71eeb2df2c2d040074670b818e03af6cf1f Mon Sep 17 00:00:00 2001 From: Nolan Darilek Date: Sun, 27 Dec 2020 10:42:41 -0600 Subject: [PATCH] Add Android example. --- Cargo.toml | 7 ++- examples/hello_world_android.rs | 89 +++++++++++++++++++++++++++++++++ 2 files changed, 95 insertions(+), 1 deletion(-) create mode 100644 examples/hello_world_android.rs diff --git a/Cargo.toml b/Cargo.toml index 16cfdc2..7682ed5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -41,4 +41,9 @@ wasm-bindgen = "0.2" web-sys = { version = "0.3", features = ["EventTarget", "SpeechSynthesis", "SpeechSynthesisErrorCode", "SpeechSynthesisErrorEvent", "SpeechSynthesisEvent", "SpeechSynthesisUtterance", "Window", ] } [target.'cfg(target_os="android")'.dependencies] -jni = "0.18" \ No newline at end of file +jni = "0.18" +ndk-glue = "0.2" + +[[example]] +name = "hello_world_android" +crate-type = ["cdylib"] diff --git a/examples/hello_world_android.rs b/examples/hello_world_android.rs new file mode 100644 index 0000000..8243936 --- /dev/null +++ b/examples/hello_world_android.rs @@ -0,0 +1,89 @@ +use std::io; + +#[cfg(target_os = "macos")] +use cocoa_foundation::base::id; +#[cfg(target_os = "macos")] +use cocoa_foundation::foundation::NSRunLoop; +#[cfg(target_os = "macos")] +use objc::{msg_send, sel, sel_impl}; + +use tts::*; + +// Use a separate function so the same examples run everywhere. +fn run() -> Result<(), Error> { + env_logger::init(); + let mut tts = TTS::default()?; + let Features { + utterance_callbacks, + .. + } = tts.supported_features(); + if utterance_callbacks { + tts.on_utterance_begin(Some(Box::new(|utterance| { + println!("Started speaking {:?}", utterance) + })))?; + tts.on_utterance_end(Some(Box::new(|utterance| { + println!("Finished speaking {:?}", utterance) + })))?; + tts.on_utterance_stop(Some(Box::new(|utterance| { + println!("Stopped speaking {:?}", utterance) + })))?; + } + let Features { is_speaking, .. } = tts.supported_features(); + if is_speaking { + println!("Are we speaking? {}", tts.is_speaking()?); + } + tts.speak("Hello, world.", false)?; + let Features { rate, .. } = tts.supported_features(); + if rate { + let original_rate = tts.get_rate()?; + tts.speak(format!("Current rate: {}", original_rate), false)?; + tts.set_rate(tts.max_rate())?; + tts.speak("This is very fast.", false)?; + tts.set_rate(tts.min_rate())?; + tts.speak("This is very slow.", false)?; + tts.set_rate(tts.normal_rate())?; + tts.speak("This is the normal rate.", false)?; + tts.set_rate(original_rate)?; + } + let Features { pitch, .. } = tts.supported_features(); + if pitch { + let original_pitch = tts.get_pitch()?; + tts.set_pitch(tts.max_pitch())?; + tts.speak("This is high-pitch.", false)?; + tts.set_pitch(tts.min_pitch())?; + tts.speak("This is low pitch.", false)?; + tts.set_pitch(tts.normal_pitch())?; + tts.speak("This is normal pitch.", false)?; + tts.set_pitch(original_pitch)?; + } + let Features { volume, .. } = tts.supported_features(); + if volume { + let original_volume = tts.get_volume()?; + tts.set_volume(tts.max_volume())?; + tts.speak("This is loud!", false)?; + tts.set_volume(tts.min_volume())?; + tts.speak("This is quiet.", false)?; + tts.set_volume(tts.normal_volume())?; + tts.speak("This is normal volume.", false)?; + tts.set_volume(original_volume)?; + } + tts.speak("Goodbye.", false)?; + let mut _input = String::new(); + // The below is only needed to make the example run on MacOS because there is no NSRunLoop in this context. + // It shouldn't be needed in an app or game that almost certainly has one already. + #[cfg(target_os = "macos")] + { + let run_loop: id = unsafe { NSRunLoop::currentRunLoop() }; + unsafe { + let _: () = msg_send![run_loop, run]; + } + } + io::stdin().read_line(&mut _input)?; + Ok(()) +} + +#[cfg(target_os = "android")] +#[cfg_attr(target_os = "android", ndk_glue::main(backtrace = "on"))] +fn main() { + run().expect("Failed to run"); +}