site  contact  subhomenews

How pulseaudio is implemented in EasyOS

November 13, 2021 — BarryK

The road to move from an ALSA-only system to pulseaudio has been a bumpy ride. I had a go back in 2020 then reverted to ALSA. Late in 2021 have had another go, here are blog posts:

Here is a post from the pulseaudio experiment in 2020:

Right now, just before releasing EasyOS 3.1.10, pulseaudio is looking good. I big problem for me has been moving on from my "ALSA oriented" understandings. There are scripts, such as Multiple Sound Card Wizard (/usr/sbin/mscw) that were written for ALSA, then I bolted on support for bluez-alsa, then pulseaudio ...a bit messy.

While I remember what I have done to get pulseaudio working, and to play nicely with ALSA, especially the ALSA-only apps, here are some notes. Not a complete guide, just some notes...

Most vital are the files in packages-templates/pulseaudio in woofQ:

./usr/bin/start-pulseaudio-x11
./etc/pulse/daemon.conf
./etc/pulse/default.pa
./etc/pulse/client.conf
./etc/profile.d/pulseaudio
./root/Startup/pulseaudio

File usr/bin/start-pulseaudio-x11 is actually part of the pulseaudio package. I put it into the template just in case it is missing from any binary pulseaudio package.

Files daemon.conf, default.conf and client.conf will override if exist in the binary package. For daemon.conf, here are the changes:

allow-exit = no
exit-idle-time = -1

...these are so that the pulseaudio daemon will run continuously. Here are the changes in default.pa, relative to earlier attempts:

#BK  20211111 comment-out
#load-module module-alsa-sink device=dmix
#load-module module-alsa-source device=dsnoop

#BK 20211111 un-comment
#### Automatically load driver modules depending on the hardware available
#.ifexists module-udev-detect.so
load-module module-udev-detect
#.else
#### Use the static hardware detection module (for systems that lack udev support)
#load-module module-detect
#.endif

#BK 20211103 see also /etc/pulse/client.conf
load-module module-native-protocol-unix
# ...creates a socket /run/pulse/native
# ref: https://dhole.github.io/post/pulseaudio_multiple_users/
#unfortunately the daemon changes permissions of pulse folder in /run/pulse to 700,
# so non-root users cannot access it. so have to create another socket elsewhere:
load-module module-native-protocol-unix auth-group=audio socket=/tmp/pulse-socket

Here are the changes to client.conf:

#20211103 /etc/pulse/daemon.conf has disabled idle-exit, so leave these as "no"...
autospawn = no
allow-autospawn-for-root = no

#20211103
#ref: https://dhole.github.io/post/pulseaudio_multiple_users/
enable-memfd = yes

File etc/profile.d/pulseaudio:

#need this so pavucontrol can find pulseaudio daemon socket...
export PULSE_RUNTIME_PATH=/run/pulse

#pipewire-pulse daemon will create /run/pulse/pulse
# and pavucontrol won't know where socket is (/run is symlink to /tmp/run)...
if [ ! -d /run/pulse ];then
mkdir -p /run/pulse
chmod 755 /run/pulse
fi
if [ ! -e /run/pulse/pulse ];then
ln -s . /run/pulse/pulse 2>/dev/null
fi

Here is root/Startup/pulseaudio:

#!/bin/sh
#20211102 /etc/pulse/client.conf may have been changed if ran pw.
#20211103 note that user and group 'pulse' is only when start pulseaudio with --system.
# so code below about 'pulse' group not required. however, see /etc/pulse/default.pa
# -- users must belong to group 'audio'.
#20211109 10alsa wait.

which pulseaudio >/dev/null
[ $? -ne 0 ] && exit

#run start-pulseaudio-x11 in blueman_tray...
[ -x /root/Startup/blueman_tray ] && exit

#20211109 wait until /etc/init.d/10alsa has exited...
PIDa="$(cat /tmp/10alsa-PID)"
tail --pid=${PIDa} -f /dev/null

#20211109 bluetoothd will only start if pup_event detects bt hardware.
# don't hang around here waiting for it...
#wait for bluetoothd...
if [ -x /etc/init.d/bluetooth ];then
for CNT in 0 1 2 #3 4 5 6 7 8 9 10 11 12 13 14
do
pidof bluetoothd >/dev/null
[ $? -eq 0 ] && break
sleep 1
done
echo "/root/Startup/pulseaudio: waited ${CNT} seconds for bluetoothd"
fi

echo "/root/Startup/pulseaudio: starting pulseaudio daemon"
#i have configured /etc/pulse/daemon.conf so that it doesn't exit.
# (so probably don't need respawning enabled)
#note, --system mode, daemon changes user and group to 'pulse', and users have to
# be in that group to use audio. The pulse user needs to be in the audio and
# bluetooth groups in order to be able to use ALSA and bluetooth devices.
# All users that need access to PulseAudio have to be in the pulse-access group, even root.
# /usr/bin/pulseaudio --start --log-target=syslog --system --disallow-exit
#20211103 no, run as user root,
# see ref: http://billauer.co.il/blog/2014/01/pa-multiple-users/
# ...unix socket, changes to /etc/pulse/default.pa and for non-root users ~/.config/pulse/defaut.pa
# see also /usr/local/clients/setup-client, /etc/pulse/daemon.conf,
# /etc/pulse/default.pa, /etc/pulse/client.conf
#note, --start also implies --daemonize
#note, --disallow-exit --exit-idle-time=-1 are already specified in /etc/pulse/daemon.conf
/usr/bin/pulseaudio --start --log-target=syslog --disallow-exit --exit-idle-time=-1

echo "/root/Startup/pulseaudio: executing start-pulseaudio-x11"
exec start-pulseaudio-x11

It might seem odd that the pulseaudio daemon is started here, after Xorg desktop has started. I did it this way because that's how Slackware guys do it. They created .desktop file in /etc/xdg/autostart, that launch when X starts. Ref:

https://docs.slackware.com/howtos:multimedia:pulseaudio

A vital configuration file is packages-templates/alsa-plugins/FIXUPHACK:

#20211112
grep -q '^yes|pulseaudio' ../../DISTRO_PKGS_SPECS-*-*
if [ $? -eq 0 ];then
rm -f etc/alsa/conf.d/50-oss.conf 2>/dev/null
rm -f etc/alsa/conf.d/99-pulseaudio-default.conf 2>/dev/null
echo '# Default to PulseAudio

pcm.!default {
type pulse
hint {
show on
description "Default ALSA Output (currently PulseAudio Sound Server)"
}
}

ctl.!default {
type pulse
}' > etc/alsa/conf.d/99-pulseaudio-default.conf

fi

...this causes ALSA to use the pulseaudio daemon. It also means that ALSA utilities, such as 'amixer', will not work until the pulseaudio daemon is running. It took me awhile before I realised this.

Previously, /etc/init.d/10alsa would set the volume levels at first bootup, using amixer. That cannot be done, the volume levels have to be set later ...I have done that in /usr/sbin/delayedrun, which executes after Xorg is running.

Ditto for the Multiple Sound Card Wizard, the pa daemon must be running. MSCW is still very "ALSA-oriented" and needs more work. But for now it is functional.

There are more details in earlier blog posts, see links at top of this post.

Oh, one little fix, that many users will appreciate: the default sound level at first bootup is now at 100%. Previously, there were complaints that it was too low.        

Tags: easy