This library provides a high-level Text-To-Speech (TTS) interface supporting various backends. Currently supported backends are:
- Windows
- NVDA via the NVDA Controller Client (requires shipping
nvdaControllerClient.dllwith your application) - Screen readers/SAPI via Tolk (requires
tolkCargo feature) - WinRT
- NVDA via the NVDA Controller Client (requires shipping
- Linux via Speech Dispatcher
- macOS/iOS/tvOS/watchOS/visionOS via AVFoundation (macOS 10.14 and above)
- Android
- WebAssembly
Plug-and-play like the other platforms — no Java sources, Gradle plugin, or manifest entries in your app — given two things:
minSdkVersion26 or above. TheUtteranceProgressListenersubclass Android callbacks need ships as an embedded dex, loaded withInMemoryDexClassLoader.- A
Contextsupplied before the firstTts, one of two ways.ndk-contextis consulted by default;android-activitypublishes there for you, including by way ofwinitor a game engine. Or calltts::android::set_contextwith aJavaVMandContextof your choosing — it takes precedence overndk-contextand is the right entry point when the process outlives itsActivityor never has one, such as speech from a foreground service:ndk-context's slot is typically owned by theActivity's glue and released when it's destroyed, whileset_contextholds its own reference for as long as backends need it. Either way the supplied context is traded for its application context, so noActivityis pinned.
Nothing here waits for the engine. Android reports it ready on the app's Java main thread, so a
backend that blocked for that would deadlock any app whose main thread is itself waiting on the
caller — which is every NativeActivity app, since android-activity holds the main thread until
the event loop acknowledges each lifecycle callback. Tts::default() therefore returns as soon as
the engine has been asked to connect, and anything spoken before it answers is queued and replayed
in order. The one exception is synthesize, which returns audio and so has to wait for it; call
that off your event-loop thread.
See examples/android_hello_world.rs, built with cargo-apk:
cargo apk run --example android_hello_world
adb logcat -s ttsEditing android/Bridge.java needs a JDK and ANDROID_HOME; build.rs rebuilds the checked-in dex
from it.