Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

No audio in plain ALSA system (since last Steam update?) #707

Open
clinew opened this issue Nov 11, 2024 · 13 comments
Open

No audio in plain ALSA system (since last Steam update?) #707

clinew opened this issue Nov 11, 2024 · 13 comments

Comments

@clinew
Copy link

clinew commented Nov 11, 2024

Your system information

  • Steam client version (build number or date):
    Steam Beta Branch: Stable Client
    Steam Version: 1730853027
    Steam Client Build Date: Tue, Nov 5 1:33 PM UTC -08:00
    Steam Web Build Date: Tue, Nov 5 4:21 PM UTC -08:00
    Steam API Version: SteamClient021
  • Distribution (e.g. Ubuntu): Gentoo
  • Opted into Steam client beta?: No
  • Have you checked for system updates?: Yes
  • Steam Logs: steam-logs.tar.gz
  • GPU: AMD

Please describe your issue in as much detail as possible:

No audio in any games ("Old World" and "Valheim" tested).
System is plain ALSA (no PulseAudio, no Pipewire).
I ran into this issue late in the week and I did not make any changes or system updates between when I did not have this issue and when I first experienced this issue. Suspect issue triggered by a Steam update.
Audio is working fine in mplayer and minetest, so audio equipment and system configuration is fine.
I went into "Big Picture" mode and no audio device was detected (?!).

Steps for reproducing this issue:

  1. Play any game, no audio

I don't see any useful information in the client that can help me debug what audio device(s) Steam thinks exists and which ones it's using.

@clinew
Copy link
Author

clinew commented Nov 11, 2024

Found out a little bit more. Under Help -> System Information the "loopback" audio device was being selected:
sound
This is incorrect, since /etc/asound.conf did not select this sound card as the default.

I worked around this by re-compiling the kernel with the loopback audio device no longer built-in. Now the audio device is detected as "Realtek Generic" and audio works in "Valheim" (yay) but not in "Old World" (aww).

@kisak-valve kisak-valve transferred this issue from ValveSoftware/steam-for-linux Nov 11, 2024
@smcv
Copy link
Contributor

smcv commented Nov 11, 2024

plain ALSA (no PulseAudio, no Pipewire)

What do you mean by that, more specifically? A hw:something device, or ALSA dmix, or something else?

The recommended audio system for Steam on Linux is PulseAudio, or Pipewire with PulseAudio compatibility. Using an ALSA-only sound system, either directly to hardware or via dmix, is not really supported; sometimes it works anyway, but sometimes it does not (and the specifics do matter).

Part of the problem is that ALSA means different things to different people: the same term "ALSA" describes a userspace-to-kernel interface, and also a userspace client library libasound.so.2. The client library has a plugin architecture, which means that different programs use it differently. PulseAudio and Pipewire bypass most of the plugins and go directly to the hardware, but if PulseAudio and Pipewire are not in use, application-level software tends to go via arbitrary plugins whose behaviour is not always straightforward to predict.

Found out a little bit more. Under Help -> System Information the "loopback" audio device was being selected

If this is part of the root cause, that would indicate that there's potentially a problem with defaults and devices even outside the Steam Linux Runtime environment. In the past, Help → System Information came from components that do not run in the container (although I'm not sure whether that's still true now that steamwebhelper runs inside a container).

The default device that is shown in that window is the one that Steam thinks is the default, and that doesn't necessarily match up with what each game is using. Do you have any more diagnostic information from Old World?

@clinew
Copy link
Author

clinew commented Nov 12, 2024

Thanks for the detailed response!

What do you mean by that, more specifically? A hw:something device, or ALSA dmix, or something else?

I wasn't aware of ALSA dmix. Almost certainly hw:0:

frostsnow@seneca ~ $ cat /proc/asound/cards 
 0 [PCH            ]: HDA-Intel - HDA Intel PCH
                      HDA Intel PCH at 0xf7f10000 irq 30
 1 [HDMI           ]: HDA-Intel - HDA ATI HDMI
                      HDA ATI HDMI at 0xf7e60000 irq 31

The recommended audio system for Steam on Linux is PulseAudio, or Pipewire with PulseAudio compatibility. Using an ALSA-only sound system, either directly to hardware or via dmix, is not really supported; sometimes it works anyway, but sometimes it does not (and the specifics do matter).

I was afraid of that. My experience with PulseAudio has always been:

  1. Install PulseAudio
  2. Follow configuration instructions
  3. Audio doesn't work

While ALSA has always just worked... except when trying to capture, which, coincidentally, is the feature that was just added to Steam. I might give Pipewire with PulseAudio a try, though.

If this is part of the root cause, that would indicate that there's potentially a problem with defaults and devices even outside the Steam Linux Runtime environment. In the past, Help → System Information came from components that do not run in the container (although I'm not sure whether that's still true now that steamwebhelper runs inside a container).

I doubt that as this set-up has been working for over a decade now. Though the ALSA docs aren't exactly comprehensible.

The default device that is shown in that window is the one that Steam thinks is the default, and that doesn't necessarily match up with what each game is using. Do you have any more diagnostic information from Old World?

Nothing I can find in the UI. Using lsof shows nothing using the audio device in contrast with mplayer and Valheim:

seneca /home/frostsnow # lsof /dev/snd/*
COMMAND  PID      USER  FD   TYPE DEVICE SIZE/OFF NODE NAME
mplayer 8907 frostsnow mem    CHR 116,16           131 /dev/snd/pcmC0D0p
mplayer 8907 frostsnow   8r   CHR 116,33      0t0  121 /dev/snd/timer
mplayer 8907 frostsnow   9u   CHR 116,16      0t0  131 /dev/snd/pcmC0D0p
mplayer 8907 frostsnow  10u   CHR  116,0      0t0  146 /dev/snd/controlC0
- Something with "Valheim"
seneca /home/frostsnow # lsof /dev/snd/*
COMMAND    PID      USER  FD   TYPE DEVICE SIZE/OFF NODE NAME
valheim.x 9256 frostsnow mem    CHR 116,16           131 /dev/snd/pcmC0D0p
valheim.x 9256 frostsnow  26r   CHR 116,33      0t0  121 /dev/snd/timer
valheim.x 9256 frostsnow  27u   CHR 116,16      0t0  131 /dev/snd/pcmC0D0p
valheim.x 9256 frostsnow  28u   CHR  116,0      0t0  146 /dev/snd/controlC0
seneca /home/frostsnow # lsof /dev/snd/*
seneca /home/frostsnow #

Looking at the mappings shows... everything mapped?

seneca /proc/6558 # cat maps  | grep -P '(pulse|asound|alsa)'
7fb75f6e4000-7fb75f6f8000 r--p 00000000 09:00 13241049                   /usr/lib/x86_64-linux-gnu/pulseaudio/libpulsecommon-12.2.so
7fb75f6f8000-7fb75f740000 r-xp 00014000 09:00 13241049                   /usr/lib/x86_64-linux-gnu/pulseaudio/libpulsecommon-12.2.so
7fb75f740000-7fb75f766000 r--p 0005c000 09:00 13241049                   /usr/lib/x86_64-linux-gnu/pulseaudio/libpulsecommon-12.2.so
7fb75f766000-7fb75f767000 ---p 00082000 09:00 13241049                   /usr/lib/x86_64-linux-gnu/pulseaudio/libpulsecommon-12.2.so
7fb75f767000-7fb75f769000 r--p 00082000 09:00 13241049                   /usr/lib/x86_64-linux-gnu/pulseaudio/libpulsecommon-12.2.so
7fb75f769000-7fb75f76a000 rw-p 00084000 09:00 13241049                   /usr/lib/x86_64-linux-gnu/pulseaudio/libpulsecommon-12.2.so
7fb75f7ac000-7fb75f7b8000 r--p 00000000 09:00 13240831                   /usr/lib/x86_64-linux-gnu/libpulse.so.0.20.3
7fb75f7b8000-7fb75f7e7000 r-xp 0000c000 09:00 13240831                   /usr/lib/x86_64-linux-gnu/libpulse.so.0.20.3
7fb75f7e7000-7fb75f7fc000 r--p 0003b000 09:00 13240831                   /usr/lib/x86_64-linux-gnu/libpulse.so.0.20.3
7fb75f7fc000-7fb75f7fd000 ---p 00050000 09:00 13240831                   /usr/lib/x86_64-linux-gnu/libpulse.so.0.20.3
7fb75f7fd000-7fb75f7ff000 r--p 00050000 09:00 13240831                   /usr/lib/x86_64-linux-gnu/libpulse.so.0.20.3
7fb75f7ff000-7fb75f800000 rw-p 00052000 09:00 13240831                   /usr/lib/x86_64-linux-gnu/libpulse.so.0.20.3
7fb75fe1f000-7fb75fe4c000 r--p 00000000 09:00 13240436                   /usr/lib/x86_64-linux-gnu/libasound.so.2.0.0
7fb75fe4c000-7fb75fedc000 r-xp 0002d000 09:00 13240436                   /usr/lib/x86_64-linux-gnu/libasound.so.2.0.0
7fb75fedc000-7fb75ff16000 r--p 000bd000 09:00 13240436                   /usr/lib/x86_64-linux-gnu/libasound.so.2.0.0
7fb75ff16000-7fb75ff17000 ---p 000f7000 09:00 13240436                   /usr/lib/x86_64-linux-gnu/libasound.so.2.0.0
7fb75ff17000-7fb75ff1f000 r--p 000f7000 09:00 13240436                   /usr/lib/x86_64-linux-gnu/libasound.so.2.0.0
7fb75ff1f000-7fb75ff20000 rw-p 000ff000 09:00 13240436                   /usr/lib/x86_64-linux-gnu/libasound.so.2.0.0

I tried to investigate the container with PRESSURE_VESSEL_WRAP_GUI=1 based on your 2020 FOSDEM video, but didn't get a pop-up (perhaps because I'm launching via steam.sh?). I didn't have any luck changing into the namespace directly:

seneca /home/frostsnow # nsenter -a -t 7267 ldd "/home/frostsnow/steam/SteamApps/common/Old World/OldWorld"
nsenter: setgid failed: Invalid argument
seneca /home/frostsnow # nsenter -a --preserve-credentials -t 7267 ldd "/home/frostsnow/steam/SteamApps/common/Old World/OldWorld"
/bin/bash: error while loading shared libraries: libtinfo.so.6: cannot open shared object file: No such file or directory

I wonder why setgid is failing... could it be a permissions issue with the audio group that prevents opening the device?

@clinew
Copy link
Author

clinew commented Nov 12, 2024

If I enter into the mount namespace of the process my /etc/asound.conf file isn't there; perhaps that's why I'm having issues?

seneca /home/frostsnow # ps aux | grep Old
frostsn+  7181  0.0  0.0  28008  5724 pts/1    S    16:48   0:00 /home/frostsnow/steam/ubuntu12_32/reaper SteamLaunch AppId=597180 -- /home/frostsnow/steam/SteamApps/common/SteamLinuxRuntime_soldier/_v2-entry-point --verb=waitforexitandrun -- /home/frostsnow/steam/SteamApps/common/SteamLinuxRuntime/scout-on-soldier-entry-point-v2 -- /home/frostsnow/steam/SteamApps/common/Old World/OldWorld
frostsn+  7182  0.0  0.0   4516  1096 pts/1    S    16:48   0:00 /home/frostsnow/steam/SteamApps/common/SteamLinuxRuntime_soldier/pressure-vessel/libexec/steam-runtime-tools-0/srt-bwrap --args 19 /usr/lib/pressure-vessel/from-host/bin/pressure-vessel-adverb --generate-locales --fd 13 --regenerate-ld.so-cache /var/pressure-vessel/ldso --add-ld.so-path /usr/lib/pressure-vessel/overrides/lib/x86_64-linux-gnu --add-ld.so-path /usr/lib/pressure-vessel/overrides/lib/i386-linux-gnu --set-ld-library-path /usr/lib/pressure-vessel/overrides/lib/x86_64-linux-gnu/aliases:/usr/lib/pressure-vessel/overrides/lib/i386-linux-gnu/aliases --exit-with-parent --subreaper --assign-fd=1=3 --assign-fd=2=4 --shell=none --terminal=none --ld-preload=/home/frostsnow/steam/ubuntu12_32/gameoverlayrenderer.so --ld-preload=/home/frostsnow/steam/ubuntu12_64/gameoverlayrenderer.so -- /home/frostsnow/steam/SteamApps/common/SteamLinuxRuntime_soldier/pressure-vessel/bin/steam-runtime-launcher-interface-0 container-runtime /home/frostsnow/steam/SteamApps/common/SteamLinuxRuntime/scout-on-soldier-entry-point-v2 -- /home/frostsnow/steam/SteamApps/common/Old World/OldWorld
frostsn+  7244  0.0  0.0  23356  4416 ?        Ss   16:48   0:00 /usr/lib/pressure-vessel/from-host/bin/pressure-vessel-adverb --generate-locales --fd 13 --regenerate-ld.so-cache /var/pressure-vessel/ldso --add-ld.so-path /usr/lib/pressure-vessel/overrides/lib/x86_64-linux-gnu --add-ld.so-path /usr/lib/pressure-vessel/overrides/lib/i386-linux-gnu --set-ld-library-path /usr/lib/pressure-vessel/overrides/lib/x86_64-linux-gnu/aliases:/usr/lib/pressure-vessel/overrides/lib/i386-linux-gnu/aliases --exit-with-parent --subreaper --assign-fd=1=3 --assign-fd=2=4 --shell=none --terminal=none --ld-preload=/home/frostsnow/steam/ubuntu12_32/gameoverlayrenderer.so --ld-preload=/home/frostsnow/steam/ubuntu12_64/gameoverlayrenderer.so -- /home/frostsnow/steam/SteamApps/common/SteamLinuxRuntime_soldier/pressure-vessel/bin/steam-runtime-launcher-interface-0 container-runtime /home/frostsnow/steam/SteamApps/common/SteamLinuxRuntime/scout-on-soldier-entry-point-v2 -- /home/frostsnow/steam/SteamApps/common/Old World/OldWorld
frostsn+  7267 65.5 13.8 10304860 2266412 ?    Sl   16:48  11:46 /home/frostsnow/steam/SteamApps/common/Old World/OldWorld
root     12543  0.0  0.0   3232  1512 pts/2    S+   17:06   0:00 grep --color=auto Old
seneca /home/frostsnow # cat /etc/asound.conf 
# https://www.alsa-project.org/wiki/Setting_the_default_device
# cat /proc/asound/cards
defaults.pcm.card 0
defaults.ctl.card 0
seneca /home/frostsnow # nsenter -m -t 7267
-bash: /usr/lib/pressure-vessel/overrides/lib/x86_64-linux-gnu/libtinfo.so.6: no version information available (required by -bash)
(steamrt soldier 0.20241008.104209)root@seneca:/# cat /etc/asound.conf
cat: /etc/asound.conf: No such file or directory
(steamrt soldier 0.20241008.104209)root@seneca:/# ls /etc/
X11   bash.bashrc      ca-certificates.conf  debian_version  fonts  gss      gtk-3.0    hosts    ld-i686-pc-linux-gnu.cache    ld.so.cache  ld.so.conf.d  locale.gen  machine-id  magic.mime  nsswitch.conf  os-release  profile    protocols  python3    resolv.conf  sensors3.conf  ssl       vdpau_wrapper.cfg  xattr.conf
alsa  ca-certificates  debian_chroot         environment     group  gtk-2.0  host.conf  inputrc  ld-x86_64-pc-linux-gnu.cache  ld.so.conf   locale.alias  localtime   magic       mime.types  openal         passwd      profile.d  pulse      python3.7  sensors.d    services       timezone  vulkan
(steamrt soldier 0.20241008.104209)root@seneca:/# 

EDIT: This would explain why "loopback" was being shown as the default device; before I disabled the kernel module the loopback card was number 0 and I had the default PCM and control card set to 1. I edited the file after disabling the kernel module.

@clinew
Copy link
Author

clinew commented Nov 12, 2024

I might give Pipewire with PulseAudio a try, though.

Tried this and now my system has no audio whatsoever. Will have to debug more later; need to sleep now.

@smcv
Copy link
Contributor

smcv commented Nov 12, 2024

Though the ALSA docs aren't exactly comprehensible

Right, that's a large part of why we generally recommend PulseAudio or Pipewire. The other reasons are that one of those is normally the default in a well-integrated distribution anyway, and with PulseAudio or Pipewire, the setup required to get audio across the container boundary simplifies down to making one AF_UNIX socket available and asking games to use it.

You've said that you're using Gentoo, which in many ways is less like an OS distribution and more like a kit from which you can build a unique OS distribution of your own. Sorry, debugging the result of that is not something that we are really able to support.

If I enter into the mount namespace of the process my /etc/asound.conf file isn't there

Yes. Unfortunately, this is intentional: the host system and the container are using a different ALSA client library libasound.so.2 with different plugins available, and the ALSA library's configuration language is very powerful (perhaps too powerful), so in general we can't expect that a configuration that works as intended on your host system will still work as intended inside the container.

For configuration as simple as what you quoted:

defaults.pcm.card 0
defaults.ctl.card 0

it would probably be sufficient to replicate it in ~/.asoundrc, which is shared with the container.

I wonder why setgid is failing... could it be a permissions issue with the audio group that prevents opening the device?

Perhaps. Because of kernel limitations on the way we create the container, we can only have one uid (yours) and one gid (your primary group) inside the container, with all other uids and all other gids mapped to the kernel's overflow uid/gid, which is typically nobody/nogroup.

If this is a group access problem, it might work to set a POSIX ACL on the audio devices. On most systems, systemd-logind and udev work together to set this up automatically via the uaccess mechanism for the duration of each user's GUI login session - but if you're using Gentoo, and you're not using PulseAudio or Pipewire, do I guess correctly that you might also not be using systemd/udev?

The ACLs that are normally set up by uaccess look something like this, where in this case my username is smcv:

$ getfacl /dev/snd/pcmC0D3p 
getfacl: Removing leading '/' from absolute path names
# file: dev/snd/pcmC0D3p
# owner: root
# group: audio
user::rw-
user:smcv:rw-
group::rw-
mask::rw-
other::---

If your system doesn't do this automatically, you could try setting up something similar manually, and see whether that helps?

Or, if this is a group access problem, it might work to ensure that Steam's primary gid is audio, by running it like sg audio -c 'steam'.

@Chiitoo
Copy link

Chiitoo commented Nov 12, 2024

For what it is worth, indeed, for me Steam shows an actual hardware device (which is card 0 in arecord -l), but games launched through it may or may not respect my $HOME/.asoundrc.

For example VVVVVV seems to use what I set in my configuration, while Amnesia: The Dark Descent grabs the hardware directly, meaning nothing else can use that device while it is running, unless something is already using the device before launching (maybe it tries the next device in line, and then uses my loopback device instead... it's not clear from the terminal output).

I'm also running Gentoo Linux, plain ALSA with custom configuration (no PulseAudio or PipeWire installed), and no ACL support enabled and no systemd installed (but yes udev to some extent).

(Interestingly, been a while since I've launched anything via Steam, and something seems to have changed so that it is messing with mouse pointer device sensitivity... possibly VVVVVV since there seems to be some new controller settings there, but that's a story for another place, and another time.)

@smcv
Copy link
Contributor

smcv commented Nov 12, 2024

games launched through it may or may not respect my $HOME/.asoundrc

If they use libasound.so.2 directly, they'll usually read your ~/.asoundrc and use whatever device it designates as the default. If they use a higher-level audio abstraction layer like SDL or OpenAL, they're more likely to bypass the ALSA-level default and use a hardware device directly. Because the ALSA client library is so flexible (arguably too flexible), all we can say in general is "it depends".

Amnesia: The Dark Descent grabs the hardware directly, meaning nothing else can use that device while it is running

Yes, this is one of the major problems with using ALSA device nodes directly (hw:). Typically distributions solve this with a sound server like PulseAudio or Pipewire that multiplexes access to the underlying hardware (that's the purpose of these sound servers).

ALSA's dmix (#501) provides sound-server-like multiplexing functionality without a centralized server, but precisely how it does this is not documented or obvious. The container runtime does not intentionally break this, but also does not do anything special to make it work. There is presumably some sort of inter-process communication involved, but we don't know the specifics of how that communication happens. If you are using dmix and can help to describe the mechanics of how it works, please follow up on #501 with that information.

plain ALSA with custom configuration

We cannot assume that all "plain ALSA" systems are the same, especially if there is custom configuration: the devil is in the details. Some use direct device access, some use dmix, in principle some could even be using a sound-server behind the scenes: the ALSA client library's plugin architecture means that in general, we cannot know what is happening. This means we cannot ever provide a one-size-fits-all solution to "plain ALSA", and we need to deal with each scenario individually.

@clinew says they are not using dmix, so let's reserve #707 to represent the scenario where every game accesses the device nodes directly, and use #501 for any further discussion of dmix.

@clinew
Copy link
Author

clinew commented Nov 13, 2024

do I guess correctly that you might also not be using systemd/udev?

systemd: No; OpenRC. udev: yes, via sys-apps/systemd-utils.

Right, that's a large part of why we generally recommend PulseAudio or Pipewire. The other reasons are that one of those is normally the default in a well-integrated distribution anyway, and with PulseAudio or Pipewire, the setup required to get audio across the container boundary simplifies down to making one AF_UNIX socket available and asking games to use it.

The problem is that setting up PulseAudio and Pipewire is convoluted and incomprehensible for mere mortals. Though I actually got Pipewire working today after 3+ hours; mplayer, "Valheim", and "OldWorld" all appear to be working as expected!

You've said that you're using Gentoo, which in many ways is less like an OS distribution and more like a kit from which you can build a unique OS distribution of your own. Sorry, debugging the result of that is not something that we are really able to support.

Understood. This is a problem I made for myself by using Gentoo, and I appreciate the detailed help you've given so far!

I need to contribute some docs upstream, then I want to play around with my Pipewire config some more, then revert (taking careful note how to restore) and see if I can get ALSA working again. Basically, slim down until I can't slim down anymore. Will keep you posted and respond to your other suggestions as I go (it took ~4 hours to recompile for PulseAudio support, so I have to execute in serial), but it will likely take a few days as I slog through the work week.

@clinew
Copy link
Author

clinew commented Nov 18, 2024

For configuration as simple as what you quoted:

defaults.pcm.card 0
defaults.ctl.card 0

While this might have solved the issue with "loopback" being selected as the default, it wasn't enough to get audio working consistently across all games.

The ACLs that are normally set up by uaccess look something like this, where in this case my username is smcv:

$ getfacl /dev/snd/pcmC0D3p 
getfacl: Removing leading '/' from absolute path names
# file: dev/snd/pcmC0D3p
# owner: root
# group: audio
user::rw-
user:smcv:rw-
group::rw-
mask::rw-
other::---

I did a hack test of this by giving the device files ownership of my user's group and it didn't help, but I didn't spend a lot of time since I don't think access is the issue; I was just having trouble getting into the container in order to debug. The following seems to work well: nsenter -t ${PID} -a -S ${MYUID} -G ${MYGUID}

If they use a higher-level audio abstraction layer like SDL or OpenAL, they're more likely to bypass the ALSA-level default and use a hardware device directly.

One of the interesting things I found out while using Pipewire is that the Valheim's audio stream is identified as FMOD Ex App and OldWorld's audio stream is identified as Wwise.

Unrelatedly, one interesting issue I ran into moving back from Pipewire to ALSA was that I was able to set the "default" card with:

    pcm.!default {
           type hw
           card 0
    }
    ctl.!default {
           type hw
           card 0
    }

but audio formats were restricted to S16_LE and S32_LE which caused errors with running audio; workaround was to remove /var/lib/alsa/asound.state and restart alsasound.

ALSA's dmix (#501) provides sound-server-like multiplexing functionality without a centralized server, but precisely how it does this is not documented or obvious. The container runtime does not intentionally break this, but also does not do anything special to make it work. There is presumably some sort of inter-process communication involved, but we don't know the specifics of how that communication happens. If you are using dmix and can help to describe the mechanics of how it works, please follow up on #501 with that information.

plain ALSA with custom configuration

We cannot assume that all "plain ALSA" systems are the same, especially if there is custom configuration: the devil is in the details. Some use direct device access, some use dmix, in principle some could even be using a sound-server behind the scenes: the ALSA client library's plugin architecture means that in general, we cannot know what is happening. This means we cannot ever provide a one-size-fits-all solution to "plain ALSA", and we need to deal with each scenario individually.

One thing I noticed while trying to debug (strace) programs was that OldWorld would Segmentation Fault unless I had apulse installed (which I did before I began troubleshooting this issue); while looking at its GitHub page I noticed that it mentions it uses dmix, dsnoop, and plug! So much for "plain" ALSA, I suppose.

Though when I invoke OldWorld directly with apulse installed, audio does work correctly; when I then invoke OldWorld via Steam, I have no audio. Attaching strace to the Steam-invoked process post-startup (I haven't figured out how to strace at startup when launching via Steam) OldWorld appears to continually spawn processes trying to connect to PulseAudio, and fails because the UNIX socket file native isn't available:

7677  readlink("/run", 0x7f4cd4086270, 1023) = -1 EINVAL (Invalid argument)
7677  readlink("/run/user", 0x7f4cd4086270, 1023) = -1 EINVAL (Invalid argument)
7677  readlink("/run/user/1000", 0x7f4cd4086270, 1023) = -1 EINVAL (Invalid argument)
7677  readlink("/run/user/1000/pulse", 0x7f4cd4086270, 1023) = -1 EINVAL (Invalid argument)
7677  socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0) = 93
7677  fcntl(93, F_GETFD)                = 0x1 (flags FD_CLOEXEC)
7677  setsockopt(93, SOL_SOCKET, SO_PRIORITY, [6], 4) = 0
7677  fcntl(93, F_GETFL)                = 0x2 (flags O_RDWR)
7677  fcntl(93, F_SETFL, O_RDWR|O_NONBLOCK) = 0
7677  connect(93, {sa_family=AF_UNIX, sun_path="/run/user/1000/pulse/native"}, 110) = -1 ENOENT (No such file or directory)
7677  close(93)                         = 0
7677  socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0) = 93
7677  fcntl(93, F_GETFD)                = 0x1 (flags FD_CLOEXEC)
7677  setsockopt(93, SOL_SOCKET, SO_PRIORITY, [6], 4) = 0
7677  fcntl(93, F_GETFL)                = 0x2 (flags O_RDWR)
7677  fcntl(93, F_SETFL, O_RDWR|O_NONBLOCK) = 0
7677  connect(93, {sa_family=AF_UNIX, sun_path="/var/run/pulse/native"}, 110) = -1 ENOENT (No such file or directory)
7677  close(93)                         = 0

When I invoke Valheim directly with this set-up, it crashes consistently after the splash screen; when I then invoke Valheim via Steam, it sometimes works. By "sometimes" I mean if I move my saved game data at ~/.config/unity3d/IronGate somewhere else Valheim consistently starts up with audio but it seems that the saved data has something causing a "sticky" crash until I prod it enough (cleaning backup files...?). The crash when directly invoking may or may not be audio related. Looking at strace of the directly invoked Valheim shows system calls for both PulseAudio and ALSA.

mplayer continues to function as expected.

So it's very interesting how OldWorld fails but Valheim doesn't. I'd hypothesize thus: OldWorld (Wwise) has a hard requirement on PulseAudio APIs; this works with apulse but in SLR apulse doesn't work. Valheim (FMod) tries PulseAudio in the SLR and falls back to ALSA if PulseAudio fails; this is why Valheim audio still works in the SLR. Though this doesn't explain why I'm having trouble running Valheim directly. I'm not currently sure how to confirm or disprove these hypothesis.

That being said, I can consistently play OldWorld by invoking it directly, and Valheim by launching it through Steam, and I'm okay to call that "good enough" for now. If you'd like to keep this open for tracking, or if there's anything you'd like me to test/provide info on that's fine, otherwise feel free to close the ticket, and thanks again for the support!

@smcv
Copy link
Contributor

smcv commented Nov 18, 2024

by giving the device files ownership of my user's group

This is not the same as having an ACL that gives access to your user by uid, and will not necessarily have the same results - although it seems that you have been able to get past any permissions issues that might have existed.

To minimize divergence between what would happen on the systems with systemd-logind that are used by most Steam-on-Linux users, and what happens on your system, I would suggest setting up an ACL that is equivalent to the one that logind/udev would set up, which is something like this (untested):

setfacl -m user:$(id -nu):rw /dev/snd/{control,hw,pcm,seq,timer}*

That should result in ACLs that are shown by getfacl as similar to the one I quoted in #707 (comment), and avoids needing to think about which of your group IDs is the primary group and which ones are supplementary groups.

The combination of systemd-logind and udev would normally set up an ACL like this on every device that has the udev tag uaccess (which by default includes ALSA audio device nodes) for the user that is logged-in on the active local console. But, because you are not using systemd-logind, there is probably nothing telling udev that you are the logged-in user on the active local console, so this probably doesn't happen.

@smcv
Copy link
Contributor

smcv commented Nov 18, 2024

One of the interesting things I found out while using Pipewire is that the Valheim's audio stream is identified as FMOD Ex App and OldWorld's audio stream is identified as Wwise.

Those presumably indicate the audio middleware libraries that are built in to in each of these games. FMOD is relatively common, so any workarounds that you might find for Valheim are likely to be applicable to other games. Wwise is less common, I think.

I noticed that [apulse documentation] mentions it uses dmix, dsnoop, and plug! So much for "plain" ALSA, I suppose.

This is exactly the sort of thing I was concerned about when I said "ALSA means different things to different people". ALSA-the-kernel-interface and ALSA-the-user-space-library have very different scopes and interact with container technologies differently, but both are generally referred to as simply "ALSA", and users, developers and documentation often don't distinguish clearly between them.

One of the properties of PulseAudio and Pipewire that is useful for the Steam Runtime is that they bypass the upper layers of the ALSA user-space library, and only use it as an API for lower-level interactions with the kernel interface, which cuts out a lot of the complexity of the ALSA user-space library and its plugin architecture.

when I invoke OldWorld directly with apulse installed, audio does work correctly; when I then invoke OldWorld via Steam, I have no audio

This will most likely be because apulse provides replacements / shims for the PulseAudio client libraries (libpulse.so.0, libpulse-simple.so.0 and libpulse-mainloop-glib.so.0) on your host system, but a large part of the purpose of the Steam Linux Runtime container is that it provides its own application-level libraries which insulate games from whatever arbitrary things might be going on in your host system. In particular, it provides its own libpulse.so.0, libpulse-simple.so.0 and libpulse-mainloop-glib.so.0, which are the "real" versions of those libraries as provided by PulseAudio itself. So installing apulse will have no effect on games that run in a Steam Linux Runtime container.

OldWorld appears to continually spawn processes trying to connect to PulseAudio, and fails because the UNIX socket file native isn't available

I would be surprised if it's continually forking new processes (doing audio in a subprocess is not a programming model that I've encountered), but maybe it's continually starting new threads that try to connect to PulseAudio? And, yes, if that's what it's doing, it is correct that they try to connect to AF_UNIX sockets at $XDG_RUNTIME_DIR/pulse/native and /var/run/pulse/native, because that's how a PulseAudio client connects to a per-user pulseaudio instance or a system-wide pulseaudio instance, respectively.

When I invoke Valheim directly with this set-up

Invoking Steam games directly (not via Steam, and not via the runtime library stacks that Steam provides) is not generally a supported use-case. It can sometimes work as a debugging step or as a workaround, but often will not, depending on the game and its needs. So we would not consider it to be inherently a bug if bypassing Steam and launching Valheim directly doesn't work.

OldWorld (Wwise) has a hard requirement on PulseAudio APIs; this works with apulse but in SLR apulse doesn't work.

I don't have specific information about the Wwise audio middleware, but that seems plausible to me. The vast majority of gaming-capable Linux systems provide the PulseAudio protocol on its AF_UNIX socket, either via "real PulseAudio" or provided by Pipewire for compatibility with PulseAudio, so it does not seem unlikely that the authors of the Wwise audio middleware have treated the PulseAudio protocol as "the" Linux audio API and not implemented any other.

Valheim (FMod) tries PulseAudio in the SLR and falls back to ALSA if PulseAudio fails; this is why Valheim audio still works in the SLR.

That also seems completely plausible to me. Audio middleware libraries often have a design with multiple backends and a graceful fallback between them in priority/preference order: SDL and OpenAL are prominent examples of open-source audio libraries with that design. (But, often the highest-priority/most-preferred backends are the only ones that get extensive real-world testing, so the lower-priority/less-preferred backends can easily regress without anyone really noticing.)

@Chiitoo
Copy link

Chiitoo commented Nov 18, 2024

What do you mean by that, more specifically? A hw:something device, or ALSA dmix, or something else?

I wasn't aware of ALSA dmix. Almost certainly hw:0:

By default, ALSA should use dmix as far as I'm aware, so if you're not specifying anyhing yourself, you're most likely using dmix.

And yes, I use it in my custom configuration as well, along with some plug here and there in the pcms. Otherwise running multiple applications producing audio at the same time would most definitely be... less than successful. :]

I do remember FMOD at times being pretty difficult to get to go through dmix instead of grabbing hardware directly, and I went pretty low level on it, but that might have been close to ~11 years ago, and I haven't seen these issues in a while (not that I've looked around for them too much). That being said, I did not remember Amnesia having these issues as well.

This is exactly the sort of thing I was concerned about when I said "ALSA means different things to different people". ALSA-the-kernel-interface and ALSA-the-user-space-library have very different scopes and interact with container technologies differently, but both are generally referred to as simply "ALSA", and users, developers and documentation often don't distinguish clearly between them.

In user-support related conversations, I can't remember encountering confusion regarding "plain ALSA", which I've always thought to mean just ALSA without PulseAudio and friends. It may include custom ALSA configuration files, or the defaults.

In developer-support related conversations, I can imagine that being the case though, and will definitely keep it in mind going forward! :]

And yes, ALSA can be a beast, and I definitely understand that not everyone will want to support a configuration without PulseAudio and friends.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants