- Python 56.3%
- Shell 43.7%
| .gitignore | ||
| abaddon.py | ||
| abaddon.service | ||
| abaddon_logo.svg | ||
| config.py | ||
| install_abaddon.sh | ||
| README.md | ||
Abaddon — Voice Daemon
Servizio TTS offline per Raspberry Pi / totem x86. Sintetizza testo in MP3 e lo salva su disco.
Stack: Piper TTS · ffmpeg · mpg123 · Python stdlib (no dipendenze esterne)
Requisiti
- Linux x86_64 o Raspberry Pi 3/4 (aarch64/armv7l)
- Python 3.9+
- Connessione internet solo durante il setup — poi tutto offline
Installazione
git clone <repo> && cd abaddon
bash setup.sh
Lo script installa automaticamente:
ffmpegempg123tramite apt- Piper TTS binario in
./piper/ - Voce italiana it_IT-paola-medium (~50 MB) in
./piper/ - Voce inglese en_US-hfc_female-medium in
./piper/ - Systemd user service per l'utente
kipangacon il Python rilevato automaticamente (avvio automatico)
Durante il setup viene chiesta la cartella di salvataggio MP3:
==> Cartella di salvataggio file MP3 (cache)
Percorso [/var/www/kipanga/audios]:
Premi Invio per accettare il default o inserisci un percorso custom. La cartella viene creata automaticamente e scritta in config.py.
Configurazione
Modifica config.py per cambiare i parametri dopo l'installazione:
| Parametro | Default | Note |
|---|---|---|
PORT |
9966 |
porta <1024 richiede sudo |
CACHE_DIR |
/var/www/kipanga/audios |
impostato da setup.sh |
PIPER_BIN |
./piper/piper |
installato da setup.sh |
MODEL_PATH |
./piper/it_IT-paola-medium.onnx |
|
PIPER_HZ |
22050 |
sample rate del modello |
PAUSE_MS |
150 |
durata pausa |P| in millisecondi |
MP3_HZ |
48000 |
sample rate file MP3 di output |
MP3_BITRATE |
320k |
bitrate file MP3 di output |
Avvio
Manuale
python3 abaddon.py
# [TTS] Pronto → http://0.0.0.0:9966
# [TTS] Cache → /var/www/kipanga/audios (0 file)
Automatico all'avvio (systemd)
Gestito da setup.sh, che rileva il Python installato e genera il service con il path corretto nel profilo systemd user di kipanga. Per gestione manuale:
sudo -u kipanga XDG_RUNTIME_DIR=/run/user/$(id -u kipanga) systemctl --user status abaddon
sudo -u kipanga XDG_RUNTIME_DIR=/run/user/$(id -u kipanga) systemctl --user restart abaddon
sudo -u kipanga XDG_RUNTIME_DIR=/run/user/$(id -u kipanga) journalctl --user -u abaddon -f
setup.shabilita automaticamente il linger (loginctl enable-linger) così il servizio parte anche senza login attivo (headless/SSH).
API
Sintesi frase
GET /speak?text=<testo>[&lang=it|en][&folder=<percorso>]
Sintetizza il testo, salva il file MP3 nella cartella indicata (o in CACHE_DIR se omessa) e restituisce l'hash del file.
# Cartella default (CACHE_DIR), lingua italiana
curl "http://localhost:9966/speak?text=Serviamo+il+numero+A1+allo+sportello+3&lang=it"
# Lingua inglese
curl "http://localhost:9966/speak?text=Now+serving+A1+at+counter+3&lang=en"
# Cartella custom
curl "http://localhost:9966/speak?text=Serviamo+il+numero+A1&folder=/var/www/audio"
Risposta:
{ "hash": "33f40c2a...", "file": "33f40c2a....mp3" }
Il client conosce la cartella e recupera il file direttamente dal disco. Se il file è già in cache la risposta è istantanea (~5ms).
Marker di pausa |P|
Inserisci |P| nel testo per aggiungere silenzio (durata: PAUSE_MS in config.py):
curl "http://localhost:9966/speak?text=Serviamo+il+numero+%7CP%7C+A1+%7CP%7C+allo+sportello+3"
Il marker è case-insensitive. Frasi con pause diverse producono file MP3 distinti.
File in cache
curl http://localhost:9966/cache
{ "cached_files": 42, "folder": "/var/www/kipanga/audios" }
Cache
Ogni frase viene sintetizzata una sola volta:
<folder>/<sha1-del-testo>.mp3
La cache sopravvive ai riavvii. Per pre-generare tutte le frasi note:
python3 - <<'EOF'
from abaddon import synth_mp3
frasi = [l.strip() for l in open("frasi.txt") if l.strip()]
for i, f in enumerate(frasi, 1):
print(f"[{i}/{len(frasi)}] {f}")
synth_mp3(f)
print("Fatto.")
EOF
Troubleshooting
Piper non trovato / permission denied
ls -la ./piper/piper # deve mostrare -rwxr-xr-x
chmod +x ./piper/piper # se manca il bit eseguibile
Porta già in uso
ss -tlnp | grep 9966
# Cambia PORT in config.py
Log del daemon
sudo -u kipanga XDG_RUNTIME_DIR=/run/user/$(id -u kipanga) journalctl --user -u abaddon -f