- 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>
81 lines
3.0 KiB
Markdown
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`.
|