PulseAudio

Read about PulseAudio and have a look at its operational flow chart: File:Pulseaudio-diagram.svg.

Preparations

Routing

Routing describes the way which the Audio-Signal take when traversing your OS. Here a couple of routing configurations that make sense: (it is always a good idea to configure the soundsource (e.g. audio player) specifically to use the correct output interface)

The shortest path:

Device
Soundsource → ALSA driver → Hardware

Many programs can communicate directly with PulseAudio:

Device
Soundsource → PulseAudio → ALSA driver → Hardware

In case the sound source cannot communicate directly with PA, it takes a detour:

Device
Soundsource → ALSA → PulseAudio → ALSA driver → Hardware

PulseAudio works over the network:

Device 1 ~ Device 2
Soundsource → PulseAudio → Network → PulseAudio → ALSA driver → Hardware

Hardware

  • Device 2 requires a Sound card (Hardware), Device 1 does not; Loudspeakers are connected to the sound card

OpenWrt

  1. a libc with NPTL is required (uClibc-0.9.32 in trunk includes this)
  2. libtool2 is required (also available in trunk only, since 2011-01-30)
  3. usb.audio support or a native soundcard-driver is only needed if the device should play audio locally.

OpenWrt Backfire-10.03.1 doesn't have the necessary uClibc-NPTL/libtool2 stuff. Therefore you can't use pulseaudio with backfire.

Required Packages

  • pulseaudio-daemon manpage for PulseAudio (751k on ar71xx)
    • alsa-lib (302k on ar71xx)
    • libsndfile (130k on ar71xx)
  • pulseaudio-daemon 4.01 (on ar71xx: 841KiB);
    • Dependencies:
      opkg info pulseaudio-daemon | awk '/Depends/ {gsub(/\,/, "");$1="";print}'|tr -d '\n' | awk '{ while(++i<=NF) printf (!a[$i]++) ? $i FS : ""; i=split("",a); print "" }'

      libc libspeexdsp libsndfile libltdl libpthread librt alsa-lib libjson libopenssl libwrap
    • Size of Dependencies on ar71xx:
      num=$((37352+ 145705+ 13497+ 31307+ 5445+ 309011+ 1613+ 666919+ 11265));echo $num
      = 1.222.114Bytes ~ 1193 KiB
  • pulseaudio-daemon-avahi: 4.01 (compiled against dbus and avahi) (on ar71xx: 957 KiB)
    • Dependencies:
    • Size of Dependencies on ar71xx:
  • pulseaudio-profiles 4.01 (on ar71xx: 15 KiB) Profiles for Pulseaudio
    • Dependencies:
    • Size of Dependencies on ar71xx:
  • pulseaudio-tools 4.01 (on ar71xx: 44 KiB) Tools for Pulseaudio
    • Dependencies:
    • Size of Dependencies on ar71xx:

pulseaudio

Configuration

With PulseAudio it's possible to send audio over the network. There are several ways to achieve that, here's the "tunnel"-approach described. For other solutions see the PulseAudio wiki.

Server configuration

For sound from the network, something like this is needed:

/etc/pulse/system.pa:

load-module module-alsa-sink load-module module-esound-protocol-tcp auth-anonymous=1 load-module module-native-protocol-tcp auth-anonymous=1

There is an issue (#14175) with permissions in system mode with alsa. This is an workaround which does not support hotplug. In system mode pulseaudio runs under user pulse but it does not have the permissions to access alsa. Add this line to /etc/init.d/pulseaudio

chown -R :51 /dev/snd ; chmod -R g+rw /dev/snd

Client configuration

You can enter network-sinks manually (which is described below) or discover them automatically with Avahi/Zeroconf

Linux

Load a new tunnel-sink:

pacmd load-module module-tunnel-sink server=<IP_OPENWRT>

Now it can be controlled with eg gnome-volume-control:

To play one stream simultaneously to a local and a remote sink create a combined sink:

pacmd load-module module-combine sink_name=combined slaves="tunnel.<IP_OPENWRT>,alsa_output.usb-0ccd_0077-00-U0xccd0x77.analog-stereo" pacmd set-default-sink combined

The local sink (in this case alsa_output.usb-0ccd_0077-00-U0xccd0x77.analog-stereo) can be obtained via pacmd:

$ pacmd list-sinks |grep name: name: <alsa_output.pci-0000_00_1b.0.analog-stereo> name: <alsa_output.usb-0ccd_0077-00-U0xccd0x77.analog-stereo>

Examples

Notes

MPD

0.16.1 of MPD is needed. It needs to be build with support for PulseAudio:

Index: sound/mpd/Makefile =================================================================== — sound/mpd/Makefile (Revision 25082) +++ sound/mpd/Makefile (Arbeitskopie) @@ -63,7 +63,6 @@ –disable-cue \ –disable-jack \ –disable-modplug \ - –disable-pulse \ –disable-sidplay \ –disable-sqlite \ –enable-shout \

Avahi/ZeroConf

If you want to automatically discover new Pulseaudio devices on your network, you can install pulseaudio-daemon-avahi. This will pull in dbus and avahi. You are then able to use padevchooser on the client to find and connect to Pulseaudio sinks in the local network.

opkg install pulseaudio-daemon-avahi

Add module-zeroconf-publish to /etc/pulse/system.pa:

### Publish local soundcards on the network load-module module-zeroconf-publish

Avahi-browse or avahi-discover on the client should list the sinks:

[jan@jan ~]$ avahi-browse -a + wlan0 IPv4 root@OpenWrt: Intel 82801DB-ICH4 PulseAudio Sound Sink local + wlan0 IPv4 root@OpenWrt PulseAudio Sound Server local + wlan0 IPv4 Secure Shell on OpenWrt SSH-Fernzugriff local + wlan0 IPv4 Music Player Daemon on OpenWrt Music Player Daemon local

Make sure module-zeroconf-discover is loaded on the client (pacmd load-module module-zeroconf-discover). The new sink should show up in gnome-control-center sound:

Issues

Some people experienced issues with fadvise (see https://forum.openwrt.org/viewtopic.php?pid=118528#p118528). Building PulseAudio with ac_cv_func_posix_fadvise=no seems to help:

- –without-caps + –without-caps \ + ac_cv_func_posix_fadvise=no

This seems to help on systems with low resources:

/etc/pulse/daemon.conf:

high-priority = yes nice-level = -11 realtime-scheduling = yes resample-method = trivial default-sample-format = s16le default-sample-rate = 48000 default-sample-channels = 2 default-channel-map = front-left,front-right

Alternative configuration for forwarding sound

The approach taken above might not produce acceptable results depending on the hardware. It can lead to lagging, unpredictable, distorted sound. Here's a different method, that uses ssh to forward a tcp port from the client to the router and then uses socat to listen to this port on the router and connect it to pulseaudio's native unix socket. The idea for this was found on Joshua Tauberer’s Blog.

Required Packages

  • pulseaudio-daemon manpage for PulseAudio (751k on ar71xx)
    • alsa-lib (302k on ar71xx)
    • libsndfile (130k on ar71xx)
    • socat (82k on ar71xx)

Server configuration

For sound from the network, something like this is needed:

/etc/pulse/system.pa:

load-module module-native-protocol-unix auth-anonymous=1

The module will already be in system.pa by default, just make sure that the auth-anonymous=1 option is given, to avoid an access denied error, when you later try to stream sound.

Sometimes it helps to start udevd before pulseaudio to avoid problems. (install the udev package, if you run into problems with pulseaudio)

udevd --daemon

If you still have problems, you can also try:

chmod 0777 /dev/snd/*

Pulseaudio also likes to complain that /var/lib/pulse is missing, so we create it:

mkdir -p /var/lib/pulse

Run pulseaudio as follows:

pulseaudio --system --disallow-module-loading --disallow-exit --no-cpu-limit &

It will complain that pulseaudio shouldn't be run in system mode, but on many routers this is the only mode that will actually work.

Now run socat to listen on the port that will be forwarded to the router and let it redirect to the native unix socket that pulseaudio is using on the router:

socat TCP-LISTEN:4000,fork UNIX-CONNECT:/tmp/run/pulse/native &

You have to keep this running to keep the connection going.

You can put all of these commands in a script:

#!/bin/sh udevd --daemon chmod 0777 /dev/snd/* mkdir -p /var/lib/pulse pulseaudio --system --disallow-module-loading --disallow-exit --no-cpu-limit & socat TCP-LISTEN:4000,fork UNIX-CONNECT:/tmp/run/pulse/native &

Save the upper script as /root/pulseaudioserver.sh, make sure it is executable and add the following line in /etc/rc.local before the exit statement:

/root/pulseaudioserver.sh
exit 0
Pulseaudio should now be running after reboot.

Client configuration

The first step is to forward a tcp port to the router using ssh. In this example we've decided to use port 4000.

ssh -f -N -L4000:localhost:4000 root@openwrt

Option |-f| puts the ssh session the background, because we don't need to actively work with the session anyways. Option |-N| let's ssh know that we don't want the shell to run any programs, since forwarding a port is all we want to do. Enter your root password and the port should be forwarded.

To actually stream sound over the network open a terminal and type

export PULSE_SERVER=localhost:4000

Any pulseaudio application started from that same terminal will automatically stream its sound over the network. Note that with this solution you won't see a second audio-output-device in pulseaudio-tools like padevchooser, so you can't move streams back and forth between devices.

If you don't want to type as much every time you are going to use the remote pulseaudio, you can add this to your ~/.bashrc:

function P {
	C=`netstat -ntap 2> /dev/null | grep -c ":4000"`
	if [ "$C" = "0" ]
	then
		ssh -f -N -L4000:localhost:4000 root@openwrt 2> /dev/null
	fi
	export PULSE_SERVER=localhost:4000
}
This will check wether the port is already forwarded and forward it if needed. Then it will set the PULSE_SERVER environment variable, so that sound will be streamed over the network. All you have to type in a terminal is P.

Now you can do something like this to stream over the network:

P; mplayer *.ogg

Forwarding the port with ssh is not neccessary if your client can access the openWRT server directly (no firewall in between). For mpd you can use the following output configuration:

audio_output {
        type            "pulse"
        name            "openWRT Network Sink"
        server          "openWRT:4000"
        format          "48000:16:2"
}

For console applications you can simply set the PULSE_SERVER environment variable

export PULSE_SERVER='openWRT:4000'

PulseAudio: Why software mixing?

"Many people wonder why have software mixing at all if you have hardware mixing? The thing is, hardware mixing is a thing of the past, modern soundcards don't do it anymore. Precisely for doing things like mixing in software SIMD CPU extensions like SSE have been invented. Modern sound cards these days are kind of "dumbed" down, high-quality DACs. They don't do mixing anymore, many modern chips don't even do volume control anymore. Remember the days where having a Wavetable chip was a killer feature of a sound card? Those days are gone, today wavetable synthesizing is done almost exclusively in software – and that's exactly what happened to hardware mixing too. And it is good that way. In software mixing is is much easier to do fancier stuff like DRC which will increase quality of mixing. And modern CPUs provide all the necessary SIMD command sets to implement this efficiently." – Lennart Poettering

Back to top

doc/howto/pulseaudio.txt · Last modified: 2014/08/20 05:07 by thecubeisalie