- Rust 99.4%
- Dockerfile 0.6%
tts-service
A TTS engine for Scripty.
This will only ever support offline engines! Do not request support be added for any sort of engine that requires network access at runtime.
Self-hosting
Warning
If you are accepting user input, you must restrict this service's access to the host!
espeak-nghas a very unsafe memory space and has had several prior-documented vulnerabilities. On top of that, there could easily be memory vulnerabilities in any of the other TTS engines used as the C FFI they use is not inherently safe.The systemd service in util/scripty-tts-service.service will provide sufficient hardening.
(yes, all these warnings still apply even though we're using
hardened_malloc!)
Make sure your distro has ONNX Runtime 1.22 or newer. Arch is known to be fine. Install the ONNX Runtime headers. On Arch, this is
pacman -S onnxruntime-cpu # for running on CPU, this is probably all you need anyways
You'll also need protobuf and espeak-ng:
pacman -S protobuf espeak-ng
It should just compile now:
cargo build --release
If you're going to use the systemd service, copy target/release/tts_service to /usr/local/bin/tts_service.
You'll almost definitely want some Piper voices: find them here https://huggingface.co/rhasspy/piper-voices/tree/main.
Be sure to use Git LFS when cloning that way you actually get their contents.
If you're going to use the systemd service, copy this directory to /usr/share/piper-voices.
Optionally you can grab some Flite voices, although these are significantly lower quality and sometimes slower than
Piper.
I host some downloads at https://data.niko.lgbt/flite-voices/. You'll probably want them all if you choose.
Again, if you use the systemd service, copy these all to /usr/share/flite-voices.
Ensure /usr/share/espeak-ng-data exists before proceeding. If it doesn't, figure out where your distro holds ESpeakNG
voices.
Copy config.example.toml to config.toml and open it in an editor.
You will need to change piper.model_dir, and flite.voice_path. If you're using the systemd service, these are
/usr/share/piper-voices and /usr/share/flite-voices, respectively.
If you are not running under systemd, you will almost certainly want to disable listeners.fail_if_no_service and
uncomment listeners.address in the config file.
Copy util/scripty_tts_service.{socket,service} to /etc/systemd/system. Copy your modified config to
/etc/scripty-stt-service/config.toml.
After this, you should be able to run sudo systemctl enable --now scripty_tts_service.socket and then run the testing
binary (this specific command assumes you have the piper voice en_GB-jenny_dioco-medium installed):
cargo run --release --bin tts_service_testing -- run "hello, how are you?" "en_GB-jenny_dioco-medium" /tmp/output.wav piper
If it fails to start a few times, restart the socket until it eventually succeeds. There's some sort of race condition
in onnxruntime that crashes it upon start.
Development
Due to fucky dependency versions with the ONNX Runtime,
your best method of developing is going to be using an Arch Linux distrobox container.
You don't need to pick Arch, anything with ONNX Runtime version 1.22 or newer should work.
distrobox create --image docker.io/library/archlinux --name tts-service-distrobox
distrobox enter tts-service-distrobox
# Install all dependencies
# This is a 1GB download and four gigabytes on disk!
sudo pacman -S gcc clang cmake make onnxruntime git protobuf espeak-ng
# Afterwards, this should ✨ just work ✨
cargo run --release
Testing
The test binary can be run without any distrobox container as it's entirely self-contained. You will need to specify it explicitly as a binary target:
cargo build --release --bin tts_service_testing