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
- Hackable
- 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.
Hardware ΒΆ
- 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.
Software ΒΆ
- Archlinux ARM
- Pulseaudio
- Bluez
- (MPD)
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.
HifiBerry Setup ΒΆ
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
version of vim
from:
snd-bcm2835
to
#snd-bcm2835
And in /boot/config.txt
uncomment the following line:
device_tree_overlay=hifiberry-dacplus
Pulseaudio Configuration ΒΆ
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 /etc/pulse/daemon.confg
:
exit-idle-time = -1
Set exit-idle-time
to -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.
Using the dbus-launch
command and screen
(tmux
works too if you prefer that).
dbus-launch screen
Inside the screen session pulseaudio
can be started:
pulseaudio -v --high-priority
And in another tab
of screen use bluetoothctl
to power on
the adapter and
pair the devices.
Bluetoothctl permissions ΒΆ
If bluetoothctl
doesn’t react to any input there is another issue that need
fixing.
The user doesn’t have the required permissions. To fix that add the user to the
lp
group:
usermod -a lp
And add the following in /etc/dbus-1/system.d/bluetooth.conf
between <busconfig>
and </busconfig>
:
<!-- 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
alsamixer
is set to 100. Fire upalsamixer
and turn it down.
Enjoy ΒΆ
With this it should be possible to pair devices using bluetoothctl
and have
them play music on the Raspberry’s speakers.
To get the most out of the setup it makes sense to also install MPD or Mopidy but this is out of scope for this post.
(And once everything else is running, installing one of those two is
should be straight forward anyway)