Dispatch
A field guide to putting your library on air
From a folder of FLACs to a 24/7 broadcast with an AI DJ: the minimal path through Navidrome, Docker, and the SUB/WAVE stack — and the three mistakes everyone makes on night one.
There is a particular pleasure in hearing your own library announced back to you by a DJ at three in the morning. Getting there takes one evening, one machine that stays on, and a music folder you actually care about. This is the short route, with the potholes marked.
What you're actually assembling
Four pieces, each replaceable, none optional:
| Piece | Job | The default |
|---|---|---|
| Library | Serves your music over Subsonic API | Navidrome |
| Controller | Picks tracks, builds the DJ's context | SUB/WAVE |
| Voice | Turns DJ text into speech | Any TTS engine |
| Transmitter | One shared stream for every listener | Icecast |
The important architectural fact: SUB/WAVE never touches your files. It asks Navidrome for them the way any Subsonic client would, which means your library stays wherever it already lives.
Night one
Point it at your music
services:
navidrome:
image: deluan/navidrome:latest
ports:
- '4533:4533'
volumes:
- ./music:/music:ro
- ./data:/dataThe :ro on the music mount is not decoration — nothing in this stack should ever need write access to your library.
Wire up the station
git clone https://github.com/perminder-klair/subwave
cd subwave
cp .env.example .env
# set NAVIDROME_URL, NAVIDROME_USER, NAVIDROME_PASS, LLM + TTS keys
docker compose up -dThen open the admin, run the library scan, and wait for the tag report. Which brings us to the potholes.
Hear it
# the stream is just an Icecast mount — anything can play it
mpv http://localhost:8000/radioIf you hear music, then a voice, then music — you're a broadcaster now.
The parts people over-think
Hardware. A used mini-PC or a Raspberry Pi 5 is plenty. The heavy lifting is the LLM and TTS, and both can be API calls; the box itself just moves audio.
The reverse proxy. It's one Icecast port and one web port. Whatever you already use — Caddy, nginx, Traefik — the config is ten lines.
Uptime. This is a radio station, not a bank. If it goes down overnight, the morning show simply starts with a slightly embarrassed DJ. There's something honest about that.
Why bother
You could open any streaming app and get more music with less effort. But it wouldn't be yours — not the library, not the voice, not the 3 a.m. programming decisions. Self-hosting a station is the difference between owning records and renting a mood. The stack above is one evening of work; the feeling of your own call sign is surprisingly permanent.
Full documentation lives at getsubwave.com/setup, and the whole stack is open source.