The track, the artist, the booth.
The player opens on whatever is on air — cover art pulled straight from your library, title, artist, album, and elapsed time. A waveform tracks the audio underneath. It is not your queue. It is the station’s.
A REAL INTERNET RADIO STATION
One stream, an LLM behind the desk, and a music library that already belongs to you. We spent a week tuned in to find out what a personal radio station actually feels like.
PART ONE · THE PLAYER
Open the player and you join a broadcast already in progress. Here is what a listener actually sees.
The player opens on whatever is on air — cover art pulled straight from your library, title, artist, album, and elapsed time. A waveform tracks the audio underneath. It is not your queue. It is the station’s.
Two drawers slide out from the side. The Timeline shows tracks queued and recently played; the Booth is a live log of every word the DJ has spoken — station IDs, time checks, weather, the links between songs.
There is no skip control for listeners — a stray double-tap on someone’s headphones should not change the song for everyone else. Track-end is the only natural transition. It is radio, so it behaves like radio.
SUB/WAVE installs as a PWA — a home-screen icon, full-screen, offline-aware. The OS media controls wire straight through, so the lock screen, your headphones, and the car display all show the station and pause it cleanly.
PART TWO · THE DJ
The voice between the tracks is not air talent. It is a persona — a name, a soul, a voice engine, and a talk frequency — driven by a language model.

The DJ reads the time, the weather, the season, festivals on the calendar, what just played, and any listener requests — then asks an LLM what should come next and pulls a real song from the library.
Intros, time checks, weather reads, and station idents are all written live in the DJ’s voice, then spoken aloud and ducked under the music. Nothing is pre-recorded.
A scheduled show can hand the hour to a different persona — each with its own name, personality, voice, and how often it speaks. The 3am host is not the 8am host.
The model behind it is the operator’s choice — a local Ollama box, or a hosted provider like Anthropic, OpenAI, or Google. The voice is just as swappable: bundled Piper and Kokoro run on-device, or a cloud voice from OpenAI or ElevenLabs. Change either one in the console and the next spoken line uses it. No redeploy.
PART THREE · REQUESTS
Requests are the one place a listener steers the broadcast — and it works the way calling a radio station always should have.
Open the request drawer and type what you want — a song title, an artist, a vibe. No exact spelling, no library browsing. Add your name if you want the DJ to use it on air.
“Got it — taking it to the booth.” The acknowledgement is immediate while the matching happens in the background, so the drawer never just sits there.
An LLM reads your request, searches the library, and picks the closest real track. Suggestion chips — built from the current artist, the time of day, the weather — give you a head start if you are undecided.
When the match lands, the drawer shows the track and the DJ’s spoken intro. Your request joins the one queue everyone is hearing — and the DJ may say your name as it goes out.

PART FOUR · THE CONSOLE
Everything a listener hears is shaped from one place — a gated admin console with eight panels. This is where the operator actually runs the station.

Live status — who is on air, the mood, listener count, weather. See the queue, read the booth log, skip a track, fire a station ID, or send your own words to air as raw or styled voice.
Up to twelve DJ identities — name, soul, tagline, talk frequency, voice, and which skills each one may use. One persona is on air at a time; a show can hand it the hour.
Each skill is an autonomous segment — a weather check, a news headline, an absurd traffic update, an oddly-specific fact. Toggle each one on, assign it to a persona, or run any one now as an operator override.

A 24×7 grid you brush shows onto. Each show carries a persona, a music mood, and a topic brief — genres, eras, the host’s tone. Autonomous hours fill whatever you leave blank.

Search the Navidrome library by text, mood, and energy, queue any track, and browse recent additions. The mood tagger walks the library album-by-album and classifies every track.
Debug and Stats show health, Liquidsoap logs, LLM call history, and usage at a glance. Settings — TTS, LLM, mixer, jingles — and a danger zone that starts, stops, and restarts the broadcast.


PART FIVE · UNDER THE HOOD
No subscriptions, no round-trip to a data center, no algorithm tuned to keep you scrolling. The whole source is open — so you can run your own with a different DJ persona, a different library, and a different city on the dateline.
Streaming apps gave everyone their own private channel. A playlist tuned to you, shuffled for you, paused the second you look away. SUB/WAVE goes the other direction entirely. It is one Icecast stream — a single broadcast every listener hears at the same moment — picked, announced, and mixed by software running on a single box in someone's home. There is no skip button. There is no “for you.” You tune in, and you hear whatever is on the air right now, the same as everyone else.
WORKS WITH YOUR LIBRARY
SUB/WAVE is the DJ, the mixer, and the broadcast layer. The music comes from your Navidrome — the self-hosted music server with a Subsonic API. Run Navidrome on your homelab, point SUB/WAVE at it, and the DJ picks from your collection. Nobody else's algorithm. Nobody else's catalogue.
ALSO WORKS WITHNavidromeSubsonicAirsonicGonicFunkwhaleNextcloud Musicanything Subsonic-API compatible
END OF FEATURE
There is nothing to scroll and nothing to pick. Tune in and hear what the DJ is playing — or stand up your own frequency from the source.