PulseAudio

Play Music over your LAN



This artical covers how to make PulseAudio send music to all computers attached to the LAN via a TCP connection.

Description
PulseAudio is a sound system layer which sits between your sound applications, like mplayer or Rhythmbox, and ALSA (Advanced Linux Sound Architecture).

ALSA is the underlaying sound architechure that handles sending data to the physical sound card. Without PulseAudio, your applications send to ALSA which sends out your sound card. With PulseAudio between the applications and ALSA, you can do much more with the sound, such as sending it not only to the sound card and speakers, but also send the sound out the network so other PulseAudio enabled systems can play the music (without needing to start any sound applications on the remote system). There are a lot of possibilities since you can direct and control the audio stream with a reasonable amount of granularity.

The setup described below is using the default setup for PulseAudio, except to push it out the network. This means the daemon starts when the user logs in so there is no sound from a server unless you are logged in so the PulseAudio daemon starts.

PulseAudio can also be configured to run as a system wide daemon for systems runing headless or other specific setups. That is the approach I originally used in the CouchMan project, however it is generally considered not as stable and not recommended unless required.


Assumptions


PulseAudio Terminology
Client
-the PulseAudio Client generates the music data for playback on one or more servers, so the box you start your music application on (mplayer, rhythmbox, etc) is the client.
Server
-Pulseaudio Servers are computers with speakers attached to them.
source
-The sound source can be a microphone, an application, or a remote PulseAudio client.
sink
-The sink is the target output for sound such as your local soundcard or a remote PulseAudio server.
Note: Tested with:

** Fedora 11 required adding $USER (logged in user) to be in all pulse groups plus the audio group.



Packages (RPMs)
Required Packages
(most will already be installed) Optional Packages

** Do not install "PulseAudio Preferences" RPM Package: paprefs

Any changes made with the PulseAudio Preferences graphical tool are saved in $HOME/.config/pulse and $HOME/.config/gconf/system/pulseaudio/ inside your HOME dir and over ride the global settings.
The problem is that if you are needing to troubleshoot, you'll likely have conflicting information between the two sets of files.



Checking what you need

The following should give you a clean list of what is installed. I included a bit to strip out version info and duplicates (in case you have 32 & 64 bit libraries installed)

run:

 rpm -qa | egrep "pulseaudio|pavucontrol" | sed -r 's/\-[0-9\-]+\.[0-9\.\-]+fc19.[a-z0-9_]+//' |sort -u
 

Results should look like:
If you are missing any of these packages they are easily added with yum:
You must be user root to install packages. Just enter "su -", hit enter and you will be prompted for the root password.

yum install missing_package_name

for example, to add the zeroconf module run:

 yum -y install pulseaudio-module-zeroconf
 

Be sure to return to your regular user when packages are all installed.
type "exit", hit enter to return to your regular user account.


Check for PulseAudio

ALSA should already be set up to use pulseaudio by default (or by alsa-plugins-pulseaudio).
Check to make sure PulseAudio daemon is running:

 ps -ef|grep [p]ulseaudio
 
Results should look similar to:
 pete  14775  1  0  Oct20  ?  00:04:23  /usr/bin/pulseaudio --start --log-target=syslog
 
As long as it returns with something containing "/usr/bin/pulseaudio"

If it is not running, try to start it by typing:
 pulseaudio -D
 
This should start it as a daemon (so you get the prompt back)
Confirm it is working by retrying the above 'ps' command.

Now with the default audio system running under pulseaudio, we need to know how to reference our local soundcard so we can play music on the main client box (as a server) as well as the remote servers.
run:
 pacmd list-sinks |grep name:
That will output the name to use for this client box when we glue all the outputs together into a "combined sink" to all boxes.
example output:
    name: <alsa_output.pci-0000_00_1b.0.analog-stereo>
You will use the part between the < > for the combine-sink slaves string (under client changes below)


Changes
The files we need to work on are in /etc/pulse/ so they need to be modified by the root user.
As before, enter "su -", hit enter and you wil be prompted for the root password
Then enter "cd /etc/pulse/" and hit enter

CLIENT Changes
In this example I have used 3 remote servers as well as this local box (the client box)
Remote machine IP's are 192.168.1.100   192.168.1.103   192.168.1.105
The local sound card string was discovered using pacmd list-sinks as described earlier.

Open default.pa
vi default.pa
Use 'shift + g' to go to the end of the file, then add the following lines
load-module module-native-protocol-tcp
load-module module-zeroconf-discover

load-module module-tunnel-sink server=<server 1 IP or hostname>
 #(repeat for each server)

load-module module-combine-sink sink_name=combined slaves="tunnel-sink.<server 1 IP or hostname>,<alsa output string>"
set-default-sink combined


Here is an example with 3 servers:
load-module module-native-protocol-tcp
load-module module-zeroconf-discover

load-module module-tunnel-sink server=192.168.1.100
load-module module-tunnel-sink server=192.168.1.103
load-module module-tunnel-sink server=192.168.1.105

load-module module-combine-sink sink_name=combined slaves="tunnel-sink.192.168.1.100,tunnel-sink.192.168.1.103,tunnel-sink.192.168.1.105,alsa_output.pci-0000_00_1b.0.analog-stereo"
set-default-sink combined



The next file was modified to fix an issue where the playback on the client was out of sync with the other servers, so you may want to wait to see if you will need it.
Open daemon.conf by entering vi default.pa and add the following lines
realtime-scheduling = yes
realtime-priority = 5
You may also need user root to add your user id to group audio to have access to use real-time scheduling.
To be safe you can add yourself to all pulse groups as well.

Here, as root, I add user 'pete' to the audio and pulse groups.
usermod -a -G audio,pulse,pulse-access pete

To determine the pulseaudio related groups on your system, run:
grep pulse /etc/group
The results may vary slightly from my particular install and may include pulse-rt or similar. Add them all to be safe.
You should log out and back in to make the new groups available.


SERVER Changes
Note: this applies to all servers (boxes with speakers) except the client

Open default.pa
vi default.pa
Use 'shift + g' to go to the end of the file, then add the following lines
load-module module-native-protocol-tcp auth-ip-acl=<IP or host name of PulseAudio Client>
load-module module-zeroconf-publish
The following is an example using a client IP of 192.168.1.101
load-module module-native-protocol-tcp auth-ip-acl=192.168.1.101
load-module module-zeroconf-publish


Important Note:
You must either log out and back in again, or kill and restart the daemon to properly test your changes on each system.
To kill the runing instance and check that it restarted, run these commands:
  1. ps -ef|grep [p]ulseaudio
     pete  14775  1  0  Oct20  ?  00:04:23  /usr/bin/pulseaudio --start --log-target=syslog
      
    Note the process id, 14775 in this case.

  2. killall pulseaudio

  3. ps -ef|grep [p]ulseaudio
     pete  14933  1  0  Oct20  ?  00:06:52  /usr/bin/pulseaudio --start --log-target=syslog
      
    Note that the process id has changed meaning the deamon started a new instance.

  4. after 30 seconds or so, to ensure all is well, the process id should still be the same (14933)
    If the id number has changed, then PulseAudio is repeatedly trying to restart but cannot.
    In this case, recheck your changes to the default.pa file, go back to original if necessary and try each step until the problem shows up again and correct that line or add a missing module.

    Errors are sent to /var/log/messages log.


Firewalls and SElinux
Fedora has recently changed the firewall daemon from iptables to the new firewalld. The new firewall, quite different from iptables, has both permanent and dynamic rules.
The required rules are simple enough: Here are the commands to load the rules into firewalld:

This example uses a client IP of 192.168.1.101 and servers in network 192.168.1.0/24

Client:
 firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.1.0/24" port port="5353" protocol="udp" accept'
 firewall-cmd --reload
 firewall-cmd --list-all

Servers:
 firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.1.101" port port="4713" protocol="tcp" accept'
 firewall-cmd --reload
 firewall-cmd --list-all


For testing, you may want to stop the firewall. Remember to turn it back on.


SElinux is a kernel level security providing extensive security protection to Linux. It is enabled by default although it could be argued that it is not required on an internal home system.

I have tested PulseAudio over the network with the client running SElinux (install default) and it ran fine.

If you wish to disable SElinux, as root, follow these steps:
  1. open /etc/selinux/config
  2. change the line
  3. save the file and reboot


Pulseaudio Volume Control
This is more than a graphical volume control Initially it may be somewhat confusing, but the main tab "Playback" is where all the output streams are selected.

At the bottom of most pages, under "Show" select All Streams to see all connected servers.


Pulseaudio Equalizer
(this may have been patched but was not when I installed test box)
My version is pulseaudio-equalizer-2.7-11.fc19.noarch and the app fails to start.

The problem is that it is looking for a ~/.pulse dir but it is actually in ~/.config/pulse

If Pule Eqalizer will not start, edit these two files:

open /usr/bin/pulseaudio-equalizer
Change this line
  PRESET_DIR1=$HOME/.pulse/presets
to read
    PRESET_DIR1=$HOME/.config/pulse/presets

Change this line
  CONFIG_NAME=$HOME/.pulse/equalizerrc
to read
  CONFIG_NAME=$HOME/.config/pulse/equalizerrc

Change this line
  LOG_NAME=$HOME/Desktop/pulseaudio-equalizer.log
to read
  LOG_NAME=$HOME/pulseaudio-equalizer.log


Next, open /usr/share/pulseaudio-equalizer/pulseaudio-equalizer.py
Change this line
  configdir = os.getenv('HOME') + "/.pulse"
to read
    configdir = os.getenv('HOME') + "/.config/pulse"



Pulseaudio Command Line Tool
The pacmd command allows you to load modules on the fly, see what modules, sinks and sources are in use, change sink or source, and many more tasks including playing sound clips.

View the details in the man/help page with man pacmd

original document created by Pete Nesbitt, October 2013