many users - one machine

multiseat linux : system-wide pulseaudio for routing sounds

When using a multi-seat linux – multiseat : I really mean there are several users using one machine with numerous keyboards, mice and screens, each user having its own X at the same time – it used to be rather difficult to route sounds towards the proper output devices, or even to share the (very often only) available sound card ; pulseaudio system-wide daemon is an elegant solution …

Obviously any process wants its  own sound device. That’s why sound servers were introduced after the inititial oss design. From the past, I used to tweak multiseat configs a lot with every last trend of sound servers, oss, esd, alsa, even tried jackd which isn’t really suited for general use. Finally, when I switched from debian to ubuntu for desktop use, I took a glance at pulseaudio.

Pulseaudio has one main point against the others : it is ubuntu’s current choice and it comes with a rather simple and convenient front-end for setting processes sound-volume individually (pavucontrol – Pulse Audio Volume Control).

With the multiseat constraints, I could not get a decent stable system keeping the initial per-user design ; this document mainly details most tricks needed to switch from a per-user to a system-wide pulseaudio daemon.

/etc/default/pulseaudio

The system-wide daemon is started once for all at the starting of the machine by it’s /etc/init.d/pulseaudio startup script.

PULSEAUDIO_SYSTEM_START=1

/etc/group

One main trouble when sharing sound devices is all those old binaries that try to steal /dev/dsp one to each other, but the same trouble may occur on /dev/snd/*/* device files ; that’s why I finally choosed to

  • remove all users from audio group except pulse
  • put back all users into pulse-access group

this way, stealing to each other is much more difficult (though pulseaudio daemon is a setuid application so some more has to be done, see below).

/etc/pulse/system.pa

load-module module-alsa-sink device="front:Intel" sink_name=global
load-module module-remap-sink sink_name=big channels=2 channel_map=right,left master_channel_map=right,left remix=no
load-module module-remap-sink sink_name=small channels=2 channel_map=right,left master_channel_map=rear-left,rear-right remix=no
; those three lines permit splitting a unique common multi-channel sound card to a pair of stereo sinks
; one using the front jack, the other the rear output jack.

.../...

# pulseaudio system-wide deamon keep the sound card for himself ...
# load-module module-suspend-on-idle

/etc/pulse/daemon.conf

# on my box, 2.6.33 introduced some troubles around there ...
no-cpu-limit = yes
# this one is for enabling four channel on the global sink (for watching movies ?)
default-sample-channels = 4

/etc/pulse/client.conf

; don't let user launch pulseaudio deamons at need, there's already one
autospawn=no

/etc/profile.d/pulseaudio-client.sh

as the environment variable $PULSE_SINK takes precedence over global or file tunings, another entry into /etc/profile.d sounds efficient :

#!/bin/sh

# in oder to match a screen-set to a pulseaudio sink :
# pour le cas ou l'on veut faire correspondre a un terminal un canal pulseaudio :
if [ "$DISPLAY" ]
then
    if [ "$DISPLAY" = ":0" ]
    then
        PULSE_SINK="big"
    fi
    if [ "$DISPLAY" = ":1" ]
    then
        PULSE_SINK="small"
    fi
fi

this script has to be usable by anyone :

# chmod 755 /etc/profile.d/pulseaudio-client.sh

update all ~users/.asoundrc

I confess I’m not (yet) sure for that one, I should start over with a clean ubuntu to check about it, anyway it shouldn’t hurt much : for each user, play :

> asoundconf set-pulseaudio

in order to get a default alsa mapping to pulse.

~/.pulse/client.conf

Any user may have its own additional settings, but should take care of eventually erasing the $PULSE_SINK var if needed (for example, my children have sound following their seats whilst I always have the big loudspeakers).

default-sink=small
; probablement mieux de ne pas avoir de pulseaudio lancés par les users
autospawn=no

there we are

Eventually /etc/group changes won’t be effective before X-session endings, the system-wide daemon has to be launched after killing anything in the way to soundcards, but at this point things should work, no more “release the sound for me please” battleground !

multiseat linux : system-wide pulseaudio for routing sounds