NixOS / nixpkgs

Nix Packages collection & NixOS
MIT License
17.85k stars 13.93k forks source link

Issue with ALSA when enabled via PipeWire #330606

Open kamoshi opened 2 months ago

kamoshi commented 2 months ago

Here's a thread where this problem was originally posted: https://discourse.nixos.org/t/issue-after-sound-option-was-removed-in-unstable/49394

When enabling PipeWire, we can also enable ALSA support using the option services.pipewire.alsa.enable. However, this setting does not include sound card state persistence, potentially leading to various hardware issues.

To fix this problem, the option hardware.alsa.enablePersistence = true; needs to be included in the configuration.

The current NixOS Wiki lacks information about the potential problems caused by not saving sound card state when using PipeWire, which may cause confusion among users: https://wiki.nixos.org/wiki/PipeWire

The ALSA article does mention state persistence, but the information is outdated since sound.enable = true; is being deprecated. https://wiki.nixos.org/wiki/ALSA

It might be beneficial to update the Wiki documentation, add details in the option descriptions, or include the persistence option as part of services.pipewire.alsa.enable to prevent hardware issues and/or point users in the right direction.


Add a :+1: reaction to issues you find important.

nixos-discourse commented 2 months ago

This issue has been mentioned on NixOS Discourse. There might be relevant details there:

https://discourse.nixos.org/t/issue-after-sound-option-was-removed-in-unstable/49394/9

eureka-cpu commented 2 months ago

Seems to me the logical thing to do would be to add an option for pipewire services.pipewire.alsa.enablePersistence which would enable the hardware.alsa.enablePersistence option, and have the default set to true, since anyone enabling alsa through pipewire would expect the behaviour that enablePersistence provides, now that sound.enable is deprecated. The error when building that states sound.enable no longer does anything is also misleading and could be updated, since that module enabled alsa-utils and services.alsa-store as stated in the discourse issue.

Frontear commented 2 months ago

Seems to me the logical thing to do would be to add an option for pipewire services.pipewire.alsa.enablePersistence which would enable the hardware.alsa.enablePersistence option, and have the default set to true, since anyone enabling alsa through pipewire would expect the behaviour that enablePersistence provides, now that sound.enable is deprecated. The error when building that states sound.enable no longer does anything is also misleading and could be updated, since that module enabled alsa-utils and services.alsa-store as stated in the discourse issue.

I think this type of thing is prone to cause a lot of confusion by having the same option aliased in different places.

+1 on the overall issue though. Even the old sound.enable was insufficiently documented and a lot of conflicting info around it existed, such as needing to set it to false to make pipewire/pulseaudio work.

EDIT: On a slightly different note, I was under the impression that PipeWire had a sound state saving mechanism that clashed with ALSA's. Is that not the case?

0n-s commented 2 months ago

TL;DR: PipeWire does handle persistence on its own without ALSA, but it is probably broken for many cards (see link below); enabling ALSA persistence is not the solution.

EDIT: On a slightly different note, I was under the impression that PipeWire had a sound state saving mechanism that clashed with ALSA's. Is that not the case?

One can consult ~/.local/state/wireplumber to see what data it stores. & at least for me it seems it is storing volumes in default-routes. So to answer the question, yes, but…

There is this problem where many (especially USB) devices have mixer controls with names PipeWire doesn't recognize. With cards that don't suffer from this, when you set the volume in PipeWire, you can observe this:

  1. open alsamixer to the card in question
  2. set volume in a PipeWire native tool (e.g. your DE's tool)
  3. volume of the underlying card should change

E.g. this is the case for my builtin Intel HDA audio, but not for my USB DAC, which simply has one control named "PCM". So I think this, & potentially other issues similar to it (if any), are the crux of the problem, as exemplified by PipeWire handling persistence on its own for my Intel HDA card just fine & not for my USB DAC.

So yes, PipeWire does have persistence, just…make sure it's actually working with your hardware!

EDIT: simpler test for whether your card may not be using PipeWire volume persistence:

  1. find your card number with aplay -L
  2. amixer -c <card #> controls | grep -F 'Master Playback Volume'
  3. if the above returns nothing, PipeWire persistence isn't working for your card.

This tests for the existence of SINK_VOL_NAME in the PipeWire source, which is the control it uses to set the card's volume. If it can't find it, it will not be able to store its volume.

taranarmo commented 2 months ago

Recently I updated my flake configuration inputs and lost any sound devices with pipewire, probably it's the same problem. BTW option hardware.alsa.enablePersistence is now deleted from 24.05 but not from unstable.

Update: found an issue #330685, kernel update solved no sound devices

ovitus commented 2 months ago

I'm haven't tried PipeWire yet, still using ALSA and PulseAudio, however after sound.enable was deprecated, I was having to go into alsamixer every time I rebooted my PC to unmute and turn volume up. hardware.alsa.enablePersistence = true; fixes this but every time I do a rebuild of NixOS I get this error:

warning: the following units failed: alsa-store.service

× alsa-store.service - Store Sound Card State
     Loaded: loaded (/etc/systemd/system/alsa-store.service; enabled; preset: enabled)
     Active: failed (Result: exit-code) since Sun 2024-08-11 11:37:38 EDT; 160ms ago
 Invocation: 7abcdd93411644cebc0d394b82d35c08
    Process: 48275 ExecStartPre=/nix/store/cnknp3yxfibxjhila0sjd1v3yglqssng-coreutils-9.5/bin/mkdir -p /var/lib/alsa (code=exited, status=0/SUCCESS)
    Process: 48276 ExecStart=/nix/store/ci53xg2rsd2c73rhz9rf2nrdh7i73xdp-alsa-utils-1.2.10/sbin/alsactl restore --ignore (code=exited, status=99)
   Main PID: 48276 (code=exited, status=99)
         IP: 0B in, 0B out
   Mem peak: 1.5M
        CPU: 8ms

Aug 11 11:37:38 nixos alsactl[48276]: Hardware is initialized using a generic method
Aug 11 11:37:38 nixos alsactl[48276]: alsa-lib main.c:1554:(snd_use_case_mgr_open) error: failed to import hw:3 use case configuration -2
Aug 11 11:37:38 nixos alsactl[48276]: Found hardware: "VirMIDI" "" "" "" ""
Aug 11 11:37:38 nixos alsactl[48276]: Hardware is initialized using a generic method
Aug 11 11:37:38 nixos alsactl[48276]: alsa-lib main.c:1554:(snd_use_case_mgr_open) error: failed to import hw:10 use case configuration -2
Aug 11 11:37:38 nixos alsactl[48276]: Found hardware: "Loopback" "Loopback Mixer" "" "" ""
Aug 11 11:37:38 nixos alsactl[48276]: Hardware is initialized using a generic method
Aug 11 11:37:38 nixos systemd[1]: alsa-store.service: Main process exited, code=exited, status=99/n/a
Aug 11 11:37:38 nixos systemd[1]: alsa-store.service: Failed with result 'exit-code'.
Aug 11 11:37:38 nixos systemd[1]: Failed to start Store Sound Card State.

EDIT: Well, I've switched over to PipeWire and so far so good. Audio levels persist after reboot.