Here are some guidelines how to make most of your Raspberry Pi when it comes to remote audio playback. This article is part 1 of 3, where I cover pulseaudio. Parts 2 and 3 focus on adding DLNA renderer capability for remote playback to the same Pi, and a bluetooth audio A2DP accessory role respectively. In the end you get a multi-protocol audio-playing Pi.
The following actions apply to a Raspbian Wheezy installation. Your mileage may vary with other distributions and systems. For an SD card image see the downloads section of Raspberry Pi site. Needless to say you should connect some speakers or earphones to your Pi, either via HDMI or audio-out jack. Check out my Pi overview for insight on the connectors.
Pulseaudio – Theory
We will start with something quite simple and pretty straightforward, but first let’s get some basic background. Pulseaudio is a sound subsystem for Linux aimed mostly at desktop environments. Its features (among many others) include live mixing of audio streams, routing those streams, and running it over network. There are playback/recording devices, audio sinks and sources, and clients connect to these. Moreover, it is present and running by default in most Linux desktop distributions today, so probably you do not need to do anything here – on the sending/playing side – but enabling network operation (see below). Audio stream re-routing can be accomplished with pavucontrol (gui) and pacmd (cli), but the former is much easier to use – no need to remember indexes of things. Aside from routing an audio stream over network, you can also have combined playback to two or more devices if you load module-combine-sink into pulseaudio with proper options – see this for reference. I cover this in the last paragraph of this article.
Long story short – you can play your music to a set of local and remote speakers to have your music playing around your home – with just a few mouse clicks when set up properly 🙂
Pulseaudio – Installation
Raspberry Pi can run pulseaudio and Raspbian repositories have a package for it. You will also appreciate the zeroconf module, so that Pi audio device is announced on your network.
pi@raspberrypi ~ $ sudo aptitude -P install pulseaudio pulseaudio-module-zeroconf
Pulseaudio – Configuration
At this point we are making a design decision to use pulseaudio in per-user mode (not system mode). While this is a somewhat embedded setup that could just use system mode I have chosen the other, usual way, which is much more common and thus has better community support for when there are any issues. Next step is to configure the network part; here are relevant /etc/pulse/default.pa lines:
#load-module module-native-protocol-tcp #load-module module-zeroconf-publish load-module module-native-protocol-tcp auth-ip-acl=127.0.0.1;192.168.0.0/24 auth-anonymous=1 load-module module-zeroconf-publish
The auth-ip-acl clause should contain your local network specification, and if this is a network you trust completely you can use auth-anonymous=1. This way any other pulseaudio on your network can play and record anything without an authentication cookie. For less trusted environments this is not recommended (anyone can record your mic if you use a standalone audio dongle with mic input) and you should sync your $HOME/.pulse-cookie across your installations.
As we are using the user mode of pulseaudio, the default init script is not exactly the way to go. To keep things simple you could add this to your /etc/rc.local to start pulseaudio at boot (put it just before “exit 0” line):
su - pi -c '/usr/bin/pulseaudio --start --log-target=syslog --system=false'
Having done these changes you should sync your disks (always a good idea) and reboot to make sure everything starts up as it should. An elegant init script is left as an exercise for the reader (ok, you can just modify the original script). Time for testing!
Pulseaudio – Testing
Setting up pulseaudio on your PC/laptop is a bit beyond the scope of this article, so just make sure it is network-enabled (run paprefs for that or adapt /etc/pulse/default.pa as required).
Then, to verify check the output of pactl on the PC (player):
$ pactl list sinks short | grep tunnel 38 tunnel.raspberrypi.local.alsa_output.platform-bcm2835_AUD0.0.analog-stereo module-tunnel.c s16le 2ch 44100Hz SUSPENDED $
If you get output similar to the one above, things are good, it sees your Pi on the network (read it as: tunnel over IP). If it is not there, check your firewall settings (look for 4713/tcp – pulseaudio, and 5353/udp – avahi/zeroconf broadcasts). You might also need to check if avahi daemon is running. If things are good: Start playing something with audacious/vlc/… now, then run pavucontrol, and take a look at audacious‘/vlc‘s audio stream in the Playback pane. On the right there’s a button, possibly displaying “Internal audio”, when you click it – you will see a menu with options where to route the audio stream. You can choose your Pi there, now, when the playback is running.
A minor audio dropout might appear, but it will stabilize in a few seconds. And congratulations, you should now be hearing your music through Raspberry Pi!
Note: Your pulseaudio will remember this stream assignment. To verify, stop and start playback again.
Pulseaudio – Hints
Time for two hints. I strongly recommend at least the second one.
Hint 1: To use combined output you will need to load module-combine-sink with correct slaves parameter. Check out the output of:
$ pactl list sinks short
Column 2 contains sink names you can select for combining (yes, these are long names). Then loading the module would look like:
$ pacmd load-module module-combine-sink slaves=<your-sink-one>,<your-sink-two>[,...] sink_name=my_combined_sink
When the module is loaded you will spot a new sink to choose from in pavucontrol, named “Simultaneous output to (…)”.
Note: The joint sinks are likely to be a bit out of sync, to say mildly. Pulseaudio tries very hard to compensate for what is happening and auto-adjusts over time (default: every 10 seconds). Nevertheless you should take it with a grain of salt and avoid being positioned between the sources where you most clearly hear the echo. One room is OK, the other one too, but the middle area can be uncomfortable to listen. To date I have not seen any elegant solution to this problem, but not all my pulseaudio daemons are the latest versions.
Hint 2: To avoid unpleasant clicks and pops when playback changes, run on the Pi:
pi@raspberrypi ~ $ pacat /dev/zero &
You can put this hack in /etc/rc.local after pulseaudio is started (10 seconds for pulse startup allowed):
su - pi -c 'sleep 10 ; pacat /dev/zero' &
This will keep playing silence, so that the audio device is kept busy. More elegant solution is to use module-suspend-on-idle (actually to remove it from the config to stop using it), but this would potentially keep all streams running the other way (Pi->network) up if used at least once (USB audio mic?) and abuse network and Pi’s ethernet unnecessarily. And personally I had some stability issues with that one. Try for yourself, maybe it will work for you.
Note: if you run pacat, pulseaudio should start up automatically if it was not running, so the pacat line without sleep command would be the minimal startup command required, but I left it as is for clarity.
- Raspberry Pi overview – 3.5 Watt Linux board (rootprompt.apatsch.net)
- Raspberry Pi network audio player: pulseaudio, DLNA and bluetooth A2DP – part 2: DLNA (rootprompt.apatsch.net)