I dug deeper and found two working solutions, of which I'm fully satisfied with number 2.
Solution 1: Explicit alsa-sink
I realized that the first two subdevices listed by aplay -l
are both actually the S/PDIF, because playing sounds from Java (like I do in my own music player) works with output device set to either plughw:0,0
or plughw:0,1
with the LEDs on my DAC changing appropriately according to the sample rate.
To get one of them chosen by default, it works to add
load-module module-alsa-sink
load-module module-alsa-source device=hw:0,1
to my ~/.config/pulse/default.pa
(copied from /etc/pulse/
). This adds a ”Built-in Audio” option in the sound output menu, which gets chosen by default. This is then effectively an alias for the S/PDIF option (which is what I find slightly annoying with this solution).
Solution 2: set-card-profile
The Pulseaudio command list-cards reveals some interesting information. The pacmd list-cards
output lists a card named alsa_card.pci-0000_00_0e.0
which has a ports section that contains the line:
iec958-stereo-output: Digital Output (S/PDIF) (priority 0, latency offset 0 usec, available: unknown)
This is produced by module-udev-detect
, and must be where the sound settings gets the information about the output it lists as an S/PDIF. By looking at the list-cards output
with different output selections in the sound settings menu, I found that the difference was in what was set as “active profile”. This, I found, can be changed with set-card-profile
. Adding
set-card-profile alsa_card.pci-0000_00_0e.0 output:iec958-stereo+input:analog-stereo
to ~/.config/pulse/default.pa
worked in the sense that I would get the S/PDIF output after pulsaudio -k
, but after reboot and login, the sound output would still be set to HDMI. (Apparently, something else than Pulseaudio initialization alters the card profile setting.) So instead, I deleted my local default.pa
again and added the command
pacmd set-card-profile alsa_card.pci-0000_00_0e.0 output:iec958-stereo+input:analog-stereo
as a startup application. That seemed to have done the trick, until the screen saver kicked in… When the screen is awakened from the screensaver, the card profile is again changed to something else! The solution I found for this was to create a script that listens for screensaver events, checks the card profile setting when the screensaver is activated, and sets it back to that when the screensaver goes off. The script is a modified version of the one in this answer (which deals with setting the sink rather than the card profile), and looks like this:
#!/bin/bash
my_card="alsa_card.pci-0000_00_0e.0"
watch="type=signal,interface=org.gnome.ScreenSaver"
screen_locked_signal="boolean true"
screen_unlocked_signal="boolean false"
_get_active_profile() {
pacmd list-cards | sed -n 's/^\s[Aa]ctive\s\s[Pp]rofile:\s<([^>])>/\1/p'
}
last_profile=$(_get_active_profile)
Watch for screensaver D-Bus signals
dbus-monitor --session "$watch" | (
while read signal; do
if [[ "$signal" =~ "$screen_locked_signal" ]]; then
# Screen locked: remember the current profile
last_profile=$(_get_active_profile)
elif [[ "$signal" =~ "$screen_unlocked_signal" ]]; then
# Screen unlocked: restore the last profile
pacmd set-card-profile "$my_card $last_profile"
fi
done)
Adding this script as as well to the startup applications gets rid of the screensaver problem.