Great music from an eclectic library
blended by technology
Midtempo is an automated radio station. There is no playlist and no schedule - a purpose-built system listens to whatever is playing and, in real time, chooses the next track it thinks will sound best alongside it.
It reads the shape of the current song - key, tempo, intensity, mood, the harmonics in the final bars - and looks for another that should follow gracefully, then works out how to blend or sequence the two so you barely notice the join. It doesn't get it right every time, but it's getting there.
Unlike other services, Midtempo has no tracking, no advertising, and nothing harvested from your visit. My goal is exploring how to make the selection and the transitions improve - I find it too distracting to worry about an audience.
About
Midtempo, the station and the underlying technology, is a solo non-commercial project. My name is Chris, and this place is a mix of what I do and love.
The station is built to be...
Autonomous - broadcast constantly, without fail, and without oversight.
Elegant - sound like it is carefully curated by a great DJ with a deep understanding of the music they play. It should flow, evolve, and feel both professional and effortless.
Unpredictable - no discernible patterns or awareness of what may play next. That means selections have to happen real-time (so no advance scheduling) with carefully balanced rules; great sounding choices yet relaxed enough for surprises.
It's easy to blend a 120bpm dance track into another 120bpm dance track. What's more difficult is mixing dance into swing, or dub into psychedelia. The library is all of that and more, purposely eclectic to test what's possible.
Midtempo has been the name of a few online and offline projects of mine, all the way back to '95. It fits as a description of the music style too - I was always more comfortable as a Sunday-afternoon DJ. Blues, electronic, ambient, soul, hip-hop, swing, folk, dub, R&B, psychedelia, jazz, funk, reggae... if you're here for the music, hello.
The station is free of ads and sponsorship. The development - server costs, music license fees, bandwidth - is mostly self-funded. I'm conscious that the costs rise as the audience develops so, if you find yourself listening for any length of time, any financial support is most welcome.
Technology
Other automated streaming services play a file and move on to the next, following a playlist ("radio clock"). Midtempo does something harder: it decides what should play next while the current track is still on air, then reshapes the audio in real time so the two pieces of music meet cleanly. To do that it has three core services:
The Orchestrator
The control centre - the brain that decides what plays next and how. It holds the music library, runs the selection algorithm, and provides the management interface that oversees everything.
- The algorithm scores the next potential track on harmonic, tempo, energy, and timbral compatibility, then balances that against rotation fairness so the library stays unpredictable.
- It then calculates the crossfade for the winning transition - fade curves, entry gain, tempo ramps, and the exact moment the next track should start.
- All overseen through a Management system with library, track, and schedule controls, and a complete testing workbench to expose every algorithm decision for review, understanding, and adjustment.
TypeScript · Express · React · PostgreSQL
The Fingerprinter
The microscope - every uploaded track is normalised (same volume, same format), split into a segments, and analysed chunk by chunk to produce the Orchestrator's "fingerprint" data.
- It extracts musical key and Camelot wheel position, tempo and beat grid, loudness, and a weighted intensity rating, focussing on the start and end segments of each track, in half-second increments.
- Interprets mood (happy/sad, relaxed/aggressive, quiet/party), and adds timbral vectors and beat-aligned harmonics so tracks can be matched on how they actually sound.
- Identifies where the vocals start and end - which drops spoken station idents into the mix, finishing so they never crash over a song's opening lyrics.
Python · Flask · FFmpeg · Essentia
The Streaming Server
The transmitter - and the part that makes the live blending possible. It runs the player on a remote server, inside a server-side browser and captures the result as a broadcast stream.
- Chrome, running headless, loads a private page which constantly calls the Orchestrator for instructions, then constructs and plays the audio.
- A virtual (pretend) soundcard captures that audio, an encoder packages it and passes through a limiter/compressor (so that the overall volume stays more-or-less constant), and a streaming server makes it available to the world.
- Because playback happens in a browser, volume and tempo can be adjusted live - this is the trick the whole project is built around.
Headless Chrome · Puppeteer · PulseAudio · DarkIce · Icecast
How it fits together
The only manual step is uploading each song, everything else follows automagically. The fingerprint service picks it up, analyses, and hands 1500 different data points back to the Orchestrator. It then validates and stores the track in the library, and the song is ready to play.
When a song is playing on air the Orchestrator asks - in real time - "what should follow this track, and how?", scores the candidates, and returns the winner plus a precise set of crossfade instructions.
The browser on the streaming server reads the new instructions and carries them out: fading, tempo-matching, and triggering the next track, all down to the closest millisecond.
Tuning it by ear
In order to define the rules, everything needs to be configurable and audible. A set of tools in the management system closes the loop between what the algorithm decides and what each setting needs to sound good. Over 60 different selection settings can be tuned in a separate development "sandbox", used to generate hours of simulated playlists - so I can review how the overall shape changes before pushing any configuration changes live.
The Presenter
Blending two very different songs is the hard part, and the algorithm doesn't always land it cleanly. When it looks at a join and isn't confident - a big jump in musical key, a lower blend score, a pairing it would rather not force - it now has another option: hand the moment to a presenter.
The Presenter is the station's voice. Exactly like a radio DJ talking across the gap between two records, it drops a short spoken station ident over the join - covering the transition the algorithm was unsure of, and turning a slightly awkward mix into something that sounds intentional.
It works in two steps. First, an AI language model writes a short script for that exact moment - the station name, the track just finishing, what's coming next, even the time of day - kept deliberately brief, a line or two at most. Then a text-to-speech voice reads it aloud, in a chosen character and pace.
The result is a short piece of audio, timed for precise length. The system drops the clip into the crossfade and lowers ("ducks") the music underneath the voice, finishing just before the next song's vocals begin so the "presenter" never talks over the lyrics. The Fingerprinter has an advanced vocal detection process for this very reason.
It's completely configurable and always safe. The voice only appears when it's wanted, and if anything can't be produced in time, the station quietly falls back to the ordinary transition. Trigger thresholds, the voice, the pace, and a set of presenter "personas" matched to the music's mood and tempo are all tunable, with a dedicated page for auditioning the output while I tune the settings.
Infrastructure & hosting
The whole thing runs on Google Cloud, self-funded and kept deliberately lean. Each service is hosted to match its shape:
- The Stream and the Orchestrator share one small VM (virtual machine). A radio listener holds a single connection open permanently, on a modest GCP Compute Engine. Because that box has spare headroom the Orchestrator is co-located for almost no extra cost. CPU-priority weighting guarantees the live audio always wins under load, and co-location means communication between the two services is invisible and unbreakable.
- The Fingerprinter and Presenter runs serverless, on demand. Audio analysis is heavy but occasional, so it sits on Cloud Run: idle and costing nothing until a track needs processing or an ident needs generation. When wanted, it spins up with several gigabytes of memory, does the work, and shuts back down. Rarely enough to trip cost thresholds.
- Data and audio stay private. The library lives in a managed database reached only through an authenticated proxy, and the audio files sit in a private storage bucket that are served as time-limited signed links and only read by the streaming service. The one public artefact is the small "now playing" feed this very page reads.
Finally...
The current version of the service has taken +5 years to get to this point. Getting dynamic, real-time audio changes to work, with sophisticated sequencing and blending algorithms hasn't been straight-forward.
What you're hearing has evolved from a lifetime of music collecting, months of manual track processing, and years of test and learn. Thanks for taking the time to listen.
Contact
Any questions, please email me at chris@midtempo.net.
I post (very) occasionally on Mastodon, or LinkedIn for the more business minded.
Oh, and another reminder that your financial support would be most welcome!