# sg-announcer – utrop på høyttaleranlegget (Sauda Gathering) Liten Flask-app: tekst inn i nettleseren → forhåndslytt → «Send ut på anlegget» spiller lyden lokalt på **denne** maskinen med `pw-play`. TTS er Piper (`piper-tts`, onnx, helt lokalt). Alt ligger i to filer: `announcer.py` (server + kø) og `index.html` (sida). Dokumentasjon for Kent: Athena-notatet `30 Ressurser/Teknologi/Sauda Gathering - announcer.md`. Oppdater det, ikke denne fila, når noe som er verdt å huske endres. ## Kjøring Tjenesten er en systemd-brukerenhet: `~/.config/systemd/user/sg-announcer.service` (enabled, port 8090). `systemctl --user restart sg-announcer` etter endringer i koden. Manuelt: `uv run announcer.py --port 8090`. Miljøvariabler (settes i enheten): `ANNOUNCER_PORT`, `ANNOUNCER_PIN` (tom = ingen PIN), `ANNOUNCER_SINK` (pw-play `--target`; tom = standard utgang). ## Hvordan det henger sammen - `/api/preview` syntetiserer og returnerer WAV til nettleseren. Ingen lyd på PC-en. - `/api/announce` legger meldingen i én FIFO-kø; en bakgrunnstråd spiller én om gangen med `pw-play`. `/api/stop` dreper gjeldende avspilling, `/api/clear` tømmer køen. - Knappen «Send ut» er låst til nøyaktig den teksten/stemmen/hastigheten som sist ble forhåndslyttet. Det er med vilje: ingen skal sende noe de ikke har hørt. - Ferdige WAV-er bufres i `cache/` etter innholdshash. Trygt å slette. - Chimen («ding-dong») genereres i Python, ingen lydfil. ## Stemmer `VOICES_LIST` i `announcer.py` er eneste sted en stemme legges til: egen kort `id`, visningsnavn, gruppe (optgroup i menyen), Piper-modell (`--`) og evt. `speaker` for flerstemmemodeller. Modellene lastes ned fra rhasspy/piper-voices ved første oppstart til `voices/` (gitignored, 63–120 MB per modell). Fullstendig liste: `https://huggingface.co/rhasspy/piper-voices/resolve/main/voices.json`. Norsk finnes bare i to modeller: `talesyntese-medium` (én nøytral stemme) og `nvcc-medium` (ti talere i én modell, kodene KNN/MSV osv. er fra datasettet, K = kvinne, M = mann). Ingen av dem er «morsomme» stemmer; vil noen ha Vader/robot må det legges effekter på etterpå (ffmpeg-filter i `synthesize`). ## Feller - **ufw**: appen kjører nativt, så Docker-smutthullet gjelder ikke. Porten må åpnes eksplisitt for LAN-et (`sudo ufw allow from 10.20.70.0/23 to any port 8090 proto tcp`). - `pkill -f announcer.py` fra et skall som selv har `announcer.py` i kommandolinja dreper skallet. Bruk `systemctl --user`. - Piper 1.8 bruker `SynthesisConfig(length_scale=…)`; lavere = raskere.