Home Audio Using HifiBerry And Raspberry Pi
Table of content
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
alsamixeris set to 100. Fire upalsamixerand 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)