My Multi-Room Music Setup
For much too long, I wanted to write about how I completely overhauled our multi-room audio setup at home about a year ago.
Previously, the setup was as follows: We had four sets of speakers, distributed in the different rooms of our apartment, and they were all connected to the HP Microserver that played the music using MPD and Pulseaudio via a copper cable and a USB DAC. The obvious downside to this approach is its lack of scalability: Each room required a dedicated cable to the server, and the 7.1 USB DAC that I tricked into playing the same stereo stream on every of its four mini jack plugs. The less obvious downside is the lack of surge protection on copper audio cables.
So when I decided to move the server to another place in the apartment and equip it with a UPS (and thus surge protection, on the power line as well as on the Ethernet side), I was looking for a new solution. The main requirement was synchronicity: While standing in the hallway, I want to have exactly synchronous audio from all rooms. That’s what Pulseaudio was for in the old setup, as I couldn’t get ALSA to do the job well enough.
Secondly, to achieve surge protection on all wires towards the server, it seemed like a good idea to use something Ethernet-based (obviously requiring some playing device in every room).
Enter Snapcast. In a traditional server-client architecture, this little piece of software offers exactly that: Streaming time-synchronized audio from a FIFO on the server to multiple clients’ speakers. The performance is topped off by an Android app that can be used as both, a client and a remote control for the various volume levels. And with the buffers all tuned to low, the delay when starting and stopping music is only minimal.
Dusting off some old Raspberry Pis model B, the (far from hi-fi) playback hardware was settled. But because I don’t want to update a couple of Raspbians every day for no apparent reason (remember, they run a single daemon in a sealed off network and only every connect to my own server), I went ahead and toyed around with Buildroot and its Snapcast-addon SnapOS. And for a software guy like myself, that’s where the real fun began: How fast can I get the Pis to play music after powering them up? Or, as next best optimization goal: How small can I get the image?
Well, I won’t say that I’ve attained the optimum, but I’m satisfied by the current solution: My snapcast satellite configuration (currently) produces a 1.1 MiB kernel (XZ compressed) and a 3.9 MiB initramfs (uncompressed) that takes around 15 seconds to boot and play music, fetching all its configuration (network details, hostname, NTP and Snapcast servers) via DHCP. Only my SSH key is “hardcoded”.
So two of the rooms now have Rasberry Pis for playback, the workroom uses my laptop and – what I like most – the living room the Amazon FireTV (the Android app also is a client, remember?).
I was a bit disappointed that I actually needed wired Ethernet for decent synchronicity, but for some reason I couldn’t get a satisfactory result using Wifi links. Oh well.