Files
TTS-Piper/README.md
T
Labotics RobotandClaude Opus 4.8 d3164e2e96 Step 1: frasario audio Piper (render + play) con struttura a componenti
- config/: phrases.json (mappa phrase_id->testo) e config.json (voce, output dir)
- src/tts/: render.py (render incrementale) e play.py (riproduzione, no rete)
- clips/ e voices/ gitignorati (artefatti generati / modelli scaricati)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-19 15:46:58 +02:00

81 lines
3.0 KiB
Markdown

# 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`.