Home audio using HifiBerry & Raspberry Pi
In this post I’ll describe how to set up the audio system that has been doing its work happily in my living room for about a year now.
My initial requirements when I set it up were:
- Any device should be able to connect to it (tablets, windows phone, notebook)
- Not too expensive
- Always-On (low power usage, no noise)
Those requirements led me to a Raspberry Pi based system. Tablets and phones can connect via bluetooth to use the Raspberry’s speakers. And with MPD it becomes a headless music station.
- A Raspberry Pi 2 Model B (Raspberry 1 works too)
- A HifiBerry DAC+
- A Bluetooth Dongle (If you buy the new Raspberry Pi 3 this won’t be needed!)
- Some PC speakers
I initially tried the setup without a HifiBerry. Don’t make the same mistake. It is a waste of time. Without the HifiBerry the setup was mind bogglingly unstable. Audio streams would cut off randomly and resume minutes later. It was so bad that I thought the HifiBerry couldn’t possible help. Luckily I was wrong.
I chose Archlinux because it’s my daily driver on the Desktop and therefore I’m familiar with it.
I won’t go into details on how to install Archlinux ARM because it’s documented somewhere on their site.
To use the HifiBerry instead of the built-in audio the
snd-bcm2835 module has
to be disabled. Edit
/etc/modules-load.d/raspberrypi.conf with your favorite
/boot/config.txt uncomment the following line:
The required packages can be installed using pacman:
pacman -S bluez bluez-utils pulseaudio pulseaudio-bluetooth screen dbus
Pulseaudio and bluez are required to connect a phone or tablet via bluetooth (A2DP).
Besides that, with pulseaudio the raspberry can also be set up as an audio sink for other (also pulseaudio enabled) computers.
The default configuration that ships with the packages under Archlinux will
mostly do. Only one modification should be made in
exit-idle-time = -1
-1. This will prevent Pulseaudio from shutting down
if it has been idle for a while.
Getting Pulseaudio to play nicely with Bluez
Of course, simply installing all the required packages isn’t going to do the trick. Something always gets in the way.
Pulseaudio’s main use case is a desktop environment. It is usually launched within a dbus session (which in turn is launched if a user logs into his desktop environment).
Without this dbus session the communication between the bluetooth stack and pulseaudio won’t work correctly.
Having a desktop environment on the Raspberry would be a waste of resources.
And it’s not required at all - it’s possible to create a dbus session anyway.
dbus-launch command and
tmux works too if you prefer that).
Inside the screen session
pulseaudio can be started:
pulseaudio -v --high-priority
And in another
tab of screen use
power on the adapter and
pair the devices.
bluetoothctl doesn’t react to any input there is another issue that need
The user doesn’t have the required permissions. To fix that add the user to the
usermod -a lp
And add the following in
<!-- allow users of lp group (printing subsystem) to communicate with bluetoothd --> <policy group="lp"> <allow send_destination="org.bluez"/> <allow own="org.bluez"/> <allow send_interface="org.bluez.Agent1"/> <allow send_interface="org.bluez.MediaEndpoint1"/> <allow send_interface="org.bluez.MediaPlayer1"/> <allow send_interface="org.bluez.ThermometerWatcher1"/> <allow send_interface="org.bluez.AlertAgent1"/> <allow send_interface="org.bluez.Profile1"/> <allow send_interface="org.bluez.HeartRateWatcher1"/> <allow send_interface="org.bluez.CyclingSpeedWatcher1"/> <allow send_interface="org.bluez.GattCharacteristic1"/> <allow send_interface="org.bluez.GattDescriptor1"/> <allow send_interface="org.freedesktop.DBus.ObjectManager"/> <allow send_interface="org.freedesktop.DBus.Properties"/> </policy>
Other minor troubles along the way
- Audio quality might be bad if the volume in
alsamixeris set to 100. Fire up
alsamixerand turn it down.
With this it should be possible to pair devices using
bluetoothctl and have
them play music on the Raspberry’s speakers.
(And once everything else is running, installing one of those two
should be straight forward anyway)