Skip to main content
Marcin Morawski

Home audio with HiFiBerryOS

Introduction #

I use GrapheneOS on my phone, which only supports recent Google Pixels. When I needed to get a new device, I realised that it came without an audio jack. Until now, I played music by just plugging my phone (or laptop) into my amp with an aux cable, but this change forced me to look into adding some sort of digital input to my setup. Even if I still had an audio jack, I would have needed to do that anyway, because many of my friends don't use audio jacks anymore.

Bluetooth #

The first thing I looked into was just using a bluetooth audio transmitter. They can be bought pretty cheaply, but:

  1. The audio quality is not great (or so people say, I haven't done a blind test to see if I can actually tell the difference on my mid-range audio setup).
  2. Connecting can sometimes be a pain. They often pair with random people's phones; my adapter turns off after 15min of inactivity, which is pretty annoying.
  3. There is some (barely noticeable) latency, which I don't mind at the moment, but I may if I get back into watching movies.

WiFi #

So I looked into options based on WiFi. I wanted something that basically the functionality of a Bluetooth adapter (transparently streaming music/audio from a computer to an analog audio output), but at higher quality. It proved surprisingly difficult to find. A Chromecast would have fit the bill, but they're pretty expensive, and discontinued. Sonos devices are way more than I need, and they lock you into their ecosystem. It seems like in 2023, the best way to stream good-quality music on a budget is to use a Raspberry Pi with an external DAC. So that's what I did.

Raspberry Pi #

The stock sound chip on the Raspberry Pi is very low quality, so to stream music from it, you need an external Digital to Analog Converter (DAC). You can either use one that connects to a Pi over USB, or one that goes on top of the Pi board as a HAT. I chose to go with the latter. Raspberry Pi foundation provides a Pi DAC Pro, which is apparently pretty good, but I chose to go with another option, dictated by my choice of software.

Software choice #

I didn't want to fiddle with installing and configuring the packages required to make audio streaming work on Raspbian, so I looked into prepackaged distributions which (claim to) work out of the box. The two main options seem to be Balena Sound and HiFiBerryOS. HiFiBerryOS only works with DACs made by HiFiBerry, while Balena Sound works with most DAC boards, so I decided to get a HiFiBerry DAC to keep my options open. I also liked the philosophy of HiFiBerryOS more. It's designed for audio playback only. The system image is 291MB, it doesn't even come with a package manager. There are fewer things to manage than with Balena Sound, which is part of Balena's IoT ecosystem, with its OTA update functionality etc.

Hardware choice #

I chose to use the DAC Zero, because it's was the cheapest, and I didn't care too much about the more advanced features of the more expensive boards. I ordered it directly from HiFiBerry, because I wanted to support the project. That was a mistake - boards get shipped from Switzerland, so it may take up to six weeks for them to arrive in continental Europe. I also got charged over 50% extra in duty and import processing charges by the German postal carrier.

For the computer, I used a Raspberry Pi 4, because I had one lying around from the time when they could be bought for £30 on ebay.

Setup #

I followed the instructions on the HiFiBerry OS website, which were pretty straightforward.

  1. I copied the disk image to an SD card (using Gnome Disks instead of the recommended Balena Etcher, because there's no reason to install it when the native OS utility does a good enough job).
  2. After inserting the SD card and supplying power to the Pi, I waited 2 minutes for a "HiFiBerry_Setup_xxxxxx" WLAN access point to appear. HiFiBerry recommends using Ethernet for the initial setup, but WiFi worked OK for me.
  3. After going to HiFiBerry.local, I was immediately greeted with a setup screen. The setup was very straightforward, I just provided it with a WiFi password and changed the name of the system. It's important to adjust the min and max levels of the volume slider to match the output of your amp. When using a more advanced board with a DSP system, you may want to take room measurements to optimise the setup.

Usage #

Bluetooth #

Bluetooth pairing worked immediately out of the box. It connected to my phone and my laptop, and switching audio between them (while staying connected) worked seamlessly. I used the SBC-XQ codec, because it came by default with my Ubuntu installation, worked well enough, and is supposed to be pretty high quality.

UPnP/DLNA #

HiFiBerryOS runs a DLNA renderer, which means that to play audio over your local network, you need a DLNA controller. On my phone, playing songs worked without any issues using BubbleUPnP (which I only used for testing, because it's closed-source and full of ads), but I couldn't find a way to stream phone audio from e.g. playing audio in the browser, so I may end up using Bluetooth on the phone anyway. On my computer the situation was a little better, but not much. Streaming DLNA content worked just fine using upplay, but streaming system sound is much more complicated.

I run Ubuntu, and it seems like both Airplay and DLNA streaming used to work well here (using pulseaudio-rotp and pulseaudio-dlna plugins for PulseAudio). However, Ubuntu has just moved to PipeWire, DLNA and AirPlay support for which is still in active development. See these two. On Ubuntu 22.10, I couldn't get either AirPlay or DLNA to work. This prompted me to update to 23.04 (which I should have done anyway), where AirPlay works OK.

AirPlay #

Ubuntu 23.04, at the time of writing, ships with PipeWire 0.3.65, which includes AirPlay support. To enable it, run:

pactl load-module module-raop-discovery

Now the Pi should be listed as a sound output in PulseAudio configs, under the name you assigned to it when setting it up. This change will not persist across restarts, and I haven't figured out a decent way to make it persist.

UX #

The web user interface of HiFiBerry OS is nice and simple, and works well. However, I have experienced some annoying issues.

  1. Switching between devices is pretty clunky and slow. If I disconnect from my laptop, and connect on my phone (or vice versa), it can take 30-60s for the new device to start playing.
  2. The Web UI often takes a long time (also 30-60s to load), and sometimes the device cannot be reached at all.
  3. Sometimes the HiFiBerry can be reached from one device on the network, but not from another.

Conclusions #

Given my use-case (streaming system audio wirelessly), it seems like Bluetooth is still the way to go. Linux audio is still complicated, and required much more fiddling than I am willing to do. I may give Balena Sound a go at some point, but their installation instructions seem to involve editing dockerfiles to enable UPnP, so I'll pass for now. After spending 70EUR on components, I ended up with a really nice, high quality Bluetooth audio dongle with a radio function. It's not the worst deal.