# TTS-Piper — Step 1: frasario audio Pre-renders four Italian phrases to WAV clips with [Piper](https://github.com/OHF-Voice/piper1-gpl) and plays them back. At runtime nothing is synthesized and nothing is decided: `play.py` just plays a WAV file that was rendered ahead of time. ## Project layout ``` . ├── README.md project overview (this file) ├── requirements.txt Python dependencies ├── .gitignore excludes generated/downloaded artifacts ├── config/ data & configuration (edited by humans) │ ├── config.json voice model path, voice config path, output directory │ └── phrases.json map: phrase_id -> Italian text ├── src/ source code │ └── tts/ the TTS component (one package per component) │ ├── __init__.py │ ├── render.py render phrases -> clips │ └── play.py play a pre-rendered clip ├── voices/ downloaded Piper voice models (gitignored) └── clips/ generated WAVs + .rendered.json (gitignored) ``` The structure is meant to grow: a new component (bus, dashboard, adapter…) gets its own package under `src/`, not bolted onto `tts/`. Paths in `config.json` are resolved relative to the project root (or absolute); nothing is hardcoded to an absolute path, so the scripts run from any working directory. ## Install Python 3 with pip. One dependency: ```bash python3 -m pip install -r requirements.txt ``` Download the Italian voice once (needs network; only at render time): ```bash python3 -m piper.download_voices it_IT-paola-medium --download-dir voices ``` This writes `voices/it_IT-paola-medium.onnx` and `voices/it_IT-paola-medium.onnx.json`. For playback you also need one audio player on the system; `play.py` looks for `paplay`, `aplay`, or `ffplay` (in that order). On Ubuntu these come from `pulseaudio-utils` / `alsa-utils` / `ffmpeg` and are usually already present. ## Render the clips ```bash python3 src/tts/render.py ``` Produces `clips/routine_started.wav`, `clips/obstacle_detected.wav`, `clips/object_lost.wav`, `clips/routine_finished.wav`. Re-runnable and incremental: edit a phrase in `config/phrases.json`, run `render.py` again, and only that phrase's WAV is regenerated (the others are reported as "up to date, skipped"). The `clips/.rendered.json` manifest records the text each clip was rendered from. Delete a WAV (or the manifest) to force a re-render. ## Play the clips (no network) ```bash python3 src/tts/play.py routine_started # one clip by phrase_id python3 src/tts/play.py --all # all clips, in phrases.json order ``` ## Voice used - **Voice:** `it_IT-paola-medium` (Italian, female, "medium" quality, 22.05 kHz). - **Source:** the Piper voices collection `rhasspy/piper-voices` on Hugging Face, fetched by `python3 -m piper.download_voices`. To use a different voice: download it into `voices/` and update `voice_model` / `voice_config` in `config/config.json`.