Another old project of mine has recently come back to life.
RoomTunes is a native Sonos controller that I originally developed for BlackBerry 10, back in 2012. It went on to become one of the most successful music apps on the platform for a while, and did considerably better than I ever expected. Up until now though, I don’t think anyone knows that I wrote it.

At the time I was working at BlackBerry, and RoomTunes was something I developed in my spare time. As far as I know, my name has never been associated with the application until now.
Fourteen years later I’ve resurrected the original code, ported it to Qt6 and started turning it into a modern, cross-platform Sonos application. It now runs natively on Linux and Windows, with macOS and mobile versions to follow. And this time, it’s open source.
Back To BlackBerry
The original motivation for developing RoomTunes was actually quite simple: I wanted to learn how to write applications for the newly released BlackBerry 10 platform, and BlackBerry were offering $10,000 for any new app that went on to earn $1,000 in the first year of release. Employees were excluded though (·•᷄_•᷅ )
I was working at BlackBerry while BB10 was being developed, and the new phones were genuinely exciting. They were a complete break from the traditional Java-based BlackBerry platform: native C++ with Qt4, and a lovely fluid Cascades layer designed specifically for touch screen and the fabulous blackberry UX that properly integrated with the operating system. It’s such a shame that BB10 ultimately failed :(
I wanted to understand how all of this worked properly from a developer’s POV, rather than just doing security reviews of the code. At home I also had a Sonos system, and there were no Sonos applications at all for BlackBerry 10 - no official Sonos app, and certainly no 3rd-party applications.
What started as an exercise in learning the platform gradually turned into something much more ambitious. I released RoomTunes through BlackBerry World in 2012, with fairly modest expectations about whether anyone would actually buy it. I assumed that if I were lucky, that RoomTunes might just make the required $1000 over the course of the year. It passed that figure in the first month.
RoomTunes subsequently qualified for the programme and, for a period, became one of the most successful music applications in BlackBerry World. It continued to generate a surprisingly healthy amount of money until support for Android applications on later BlackBerry devices changed the market rather suddenly.
Reverse engineering Sonos
There were no useful public Sonos developer documentation available when I started RoomTunes, so the first version was built almost entirely through reverse engineering.
At a basic level Sonos devices aren’t particularly difficult to control. Speakers advertise themselves over the network using SSDP and exposed a collection of SOAP/UPnP services for things like playback control, volume and device information. Reverse engineering the local Sonos traffic with Wireshark was simple enough.
But a Sonos system is distributed, and building an actual Sonos controller is an entirely different proposition. Speakers can be grouped and ungrouped dynamically, one player becomes the coordinator for a group, queues belong to particular devices, and events have to be subscribed to, so that every controller remains synchronised with the state of the system. None of those individual pieces is especially exotic, but taken together they make for a surprisingly complicated amount of code.
Then there are the music services. Most of the more interesting communication happens over HTTPS, making inspecting the traffic considerably difficult. The official controller pins its certificates, so simply dropping a proxy in the middle wasn’t going to get very far. That took rather more work.
By far the most difficult part, though, was understanding ThirdPartyMediaServersX: the obscure data structure that Sonos uses to tie together the music services configured on a system with the user’s credentials needed to access them. It was utterly opaque, with no clues as to the nature of what was inside. I knew there must be something there though, because the mystery surrounding music services were the only missing piece of the puzzle left to uncover.
This was the point where RoomTunes stopped being a case of discovering SOAP calls and started becoming a proper reverse-engineering project. The ThirdPartyMediaServersX data was (and still is) encrypted using a custom scheme, and I needed to work out both how that structure was built and how to decrypt it before RoomTunes could behave like a real controller.
After a long time pouring over IDA disassembly output, I eventually cracked the puzzle, discovered the encryption algorithms, the decryption keys, and uncovered something a little alarming.

Credentials, associated with the user’s configured music services, were recoverable in cleartext. In hindsight there wasn’t really another practical way for the old architecture to work: a Sonos player ultimately needed to present those credentials to the third-party service, so somewhere within the system they had to be recoverable. The fact remained, though, that once you understood the custom encryption scheme you could get at them. So can anybody on your local network who knows the same trick. Sonos sacrificed security for seamless connectivity.
That left me with a slightly awkward decision. From a reverse-engineering and security point of view this was a significant discovery, but publishing code which turned an opaque Sonos data structure into a collection of music-service usernames and passwords would quite reasonably have been interpreted as publishing a vulnerability.
That is one of the main reasons I’ve never written about this part of RoomTunes in detail before.
The situation today is rather different. Sonos now supports AppLink-style authentication for music services, so modern configurations no longer rely on storing the the user’s credentials in this structure. That removes most of the reason I had for keeping the old implementation to myself, and makes me a little more comfortable about releasing the code out in the open.
As far as I could determine at the time, RoomTunes was the only third-party Sonos application which had independently implemented the full protocol, including the ThirdPartyMediaServersX awkward encryption scheme.
A very long pause
Eventually BlackBerry 10 disappeared and RoomTunes disappeared with it.
The source code remained sitting in one of my private repositories, along with the various other projects that accumulate over twenty or thirty years of hobby programming. Every few years I would open it, rediscover an elderly Qt4 project intertwined with BlackBerry Cascades, remind myself how much work would be involved in doing anything useful with it, and quietly close it again.
The Sonos protocol implementation was still valuable, but the UI was completely tied to a platform which no longer existed. Porting RoomTunes meant separating a fairly substantial amount of C++ from Cascades, replacing BlackBerry-specific APIs and rebuilding the application around a modern version of Qt.
It was one of those jobs which is always possible, but never quite interesting enough to justify the amount of work involved. AI coding tools have changed things dramatically. It took me just a couple of days to port the core parts of the app over.
From Cascades to Qt6
The most important parts of the original application were already C++. The Sonos networking code, service abstractions, music browsing and much of the application model did not need to be rewritten from scratch. Most of the effort in 2012 was reverse engineering, and trying to design a C++ class framework around something with no published protocol. What was needed now was a simple code lift - extracting C++ and QML from the old Cascades codebase, modernising, and reconnecting to a new UI. Codex smashed through it, very impressively it should be said.
There is therefore quite a lot of original 2012-era RoomTunes still buried inside the current application. Whilst some classes have changed considerably; others have survived the journey from Qt4 to Qt6 with surprisingly little modification. LLMs are great for refactoring, and the original code wasn’t great in the first place; the new version is significantly improved.
Whilst LLMs are generally pretty good now, hallucinations are still a thing. We have to be very careful to review the output, and the agents can still go completely mad at times. One of the more memorable moments came when Codex reached the old TPMSX implementation. The original code used OpenSSL to perform the AES decryption. At some point Codex looked at the openssl library, decided that was unnecessary, and replaced it with its own hand-rolled AES-128-CBC implementation.
I was slightly speechless. I still am tbh. Codex still insists that it made the right decision. Sigh.
That episode is also a useful illustration of how I’ve been using AI on RoomTunes. Codex has made resurrecting this codebase practical in a way it probably wasn’t before, and it can perform an enormous amount of tedious porting work very quickly. But it still needs reviewing, and sometimes quite carefully.
A new interface
The UI is new. The main motivation for re-creating this project is simply how bad the official Sonos controller is - on both desktop and mobile. RoomTunes was always superior imho, and I wanted a proper Linux version.

The aim is to keep what RoomTunes 2012 abd Cascades did well - clear navigation, sensible hierarchy, touch-friendly controls and an interface that gets out of the way of the music - while making the new version work properly across desktop and, hopefully, mobile once again.
Qt6 gives me a much better foundation for that. The current version runs natively on Linux and Windows, macOS is next, and mobile versions should follow after that without requiring another complete rewrite. At least that’s the theory.
Native, not web
One deliberate choice is that RoomTunes remains a native application.
It would undoubtedly have been quicker to build another Electron application and put a web interface around the Sonos code. I think the Sonos app is React-native now. There are plenty of good reasons for doing that, and for many applications, it is probably the pragmatic choice.
But RoomTunes already had a substantial native C++ codebase, and throwing that away didn’t make much sense. Qt/QML is also really, really good. I’d forgotton how good it was tbh, and Qt6 is a great choice for maintaining modern & consistent UX across different platforms.
RoomTunes starts quickly, integrates with the operating system, talks directly to Sonos devices on the local network and doesn’t require a browser engine to display a list of albums. Qt gives me a single codebase that feels “native”, and doesn’t make the application itself feel like a website.
There is something satisfying about bringing a native application from 2012 forward without replacing everything merely because the technology underneath it is old. It worked well then, and it well works now - better in fact.
Open source
The other significant change is that RoomTunes is now open source.
The original application was commercial software, sold through BlackBerry World. That obviously isn’t particularly relevant any more, and opening the source makes much more sense for the project today. It also means the Sonos protocol implementation is finally available rather than being hidden inside a long-dead BlackBerry application.
Some parts of that implementation are inevitably historical. Sonos itself has evolved considerably since 2012, new services and device capabilities have appeared, and there are areas of the protocol which RoomTunes either doesn’t understand yet, or hasn’t needed to understand.
But the basic architecture has held up remarkably well. The idea is to make versions available for Mac, iOS and Android. Sadly a BlackBerry version of RoomTunes is unlikely to materalise any time soon though.
For now, though, I’d simply like to introduce RoomTunes. Once again ;-)