Override PipeWire files (fix audio by assigning volume control to PCM channel)

Hey everyone,

Problem

After installing NixOS on my new Lenovo Yoga Pro 7 14APH8, Audio does work, but both using PipeWire and PulseAudio the sound is either muted or 100%.

First I tried to search information about the codec not working, but that proved to be a dead end. (There’s other people having trouble with this ALC3306/ALC287)

I managed to find a lead by changing the PCM channel using alsamixer, which did change the audio level and led me to this topic about overriding PulseAudio files.

PulseAudio

I managed to get it working with PulseAudio, which I’m very happy with. I used the following code snippet and assign it to hardware.pulseaudio.package:

Code Snippet
pkgs.pulseaudio.overrideAttrs (old: {
  pname = "${old.pname}-patched-with-pcm-control";
  # Instead of overriding some post-build action, which would require a
  # pulseaudio rebuild, we override the entire `buildCommand` to produce
  # its outputs by copying the original package's files (much faster).
  buildCommand = ''
    set -euo pipefail

    ${# Copy original files, for each split-output (`out`, `dev` etc.).
      lib.concatStringsSep "\n"
        (map
          (outputName:
            ''
              echo "Copying output ${outputName}"
              set -x
              cp -a ${pkgs.pulseaudio.${outputName}} ''$${outputName}
              set +x
            ''
          )
          old.outputs
        )
    }

    # Find this file: share/pulseaudio/alsa-mixer/paths/analog-output.conf.common
    #   and add these three lines:
    # 
    #   [Element Master]
    #   switch = mute
    #   volume = ignore
    # 
    # Directly above of this part of code:
    # 
    #   [Element PCM]
    #   switch = mute
    #   volume = merge
    #   override-map.1 = all
    #   override-map.2 = all-left,all-right

    set -x
    INFILE=$out/share/pulseaudio/alsa-mixer/paths/analog-output.conf.common
    sed 's/\[Element PCM\]/\[Element Master\]\nswitch = mute\nvolume = ignore\n\n[Element PCM]/' $INFILE > tmp.conf
    # Ensure file changed (something was replaced)
    ! cmp tmp.conf $INFILE
    chmod +w $out/share/pulseaudio/alsa-mixer/paths/analog-output.conf.common
    cp tmp.conf $INFILE
    set +x
  '';
})

PipeWire

However, using PipeWire, if I use the following code snippet and assign it to services.pipewire.package, it does not work.

Code Snippet
pkgs.pipewire.overrideAttrs (old: {
  # name = "pulseaudio-patched";
  pname = "${old.pname}-patched-with-pcm-control";
  # Instead of overriding some post-build action, which would require a
  # pulseaudio rebuild, we override the entire `buildCommand` to produce
  # its outputs by copying the original package's files (much faster).
  buildCommand = ''
    set -euo pipefail

    ${# Copy original files, for each split-output (`out`, `dev` etc.).
      lib.concatStringsSep "\n"
        (map
          (outputName:
            ''
              echo "Copying output ${outputName}"
              set -x
              cp -a ${pkgs.pipewire.${outputName}} ''$${outputName}
              set +x
            ''
          )
          old.outputs
        )
    } 
      
    # Find this file: /nix/store/vr4mv8jppbvr96ml2chlgikmy6f9crb7-pipewire-0.3.80-lib/share/alsa-card-profile/mixer/paths/analog-output.conf.common 
    #   and add these three lines:
    # 
    #   [Element Master]
    #   switch = mute
    #   volume = ignore
    # 
    # Directly above of this part of code:
    # 
    #   [Element PCM]
    #   switch = mute
    #   volume = merge
    #   override-map.1 = all
    #   override-map.2 = all-left,all-right
    set -x
    INFILE=$lib/share/alsa-card-profile/mixer/paths/analog-output.conf.common
    sed 's/\[Element PCM\]/\[Element Master\]\nswitch = mute\nvolume = ignore\n\n[Element PCM]/' $INFILE > tmp.conf
    # Ensure file changed (something was replaced)
    ! cmp tmp.conf $INFILE
    chmod +w $lib/share/alsa-card-profile/mixer/paths/analog-output.conf.common
    cp tmp.conf $INFILE
    set +x
  '';
})

After applying the last code snippet, I see two new pipewire folders being added to the nix store (of which one my modified one), and I see pulseaudio is also added to the nix store, but nothing seems to change for my audio settings.

In the PipeWire wiki page I saw that editing these configuration options (package = [...]) shouldn’t work and that one should put drop-in files in /etc/pipewire/pipewire.conf.d/. I don’t know how I would achieve the same using these configuration files, would anyone be able to help? I saw this topic (and this one) that might be of help. In the end, that person uses alsa-card-profiles to fix the issue, but that won’t help us, because it’s also a part of pipewire-lib
Actually, I just ran into this patch, which I might just try and see if it works. (Although it didn’t fix the issue for the OP).

Question

How should I go about fixing this for PipeWire?
Should I report this issue perhaps somewhere? A workaround should perhaps be only temporary until the issue is resolved.

Curious to hear what you think of the way I solved it for PulseAudio and what you think is the best way to try to fix this for PipeWire!

Thanks in advance :slight_smile:

Applying the patch in this post (or well, a slightly modified version) unfortunately did not resolve the issue for me.

Hey i have the exact same problem, same laptop, same everything. Did you manage to get it working with pipewire ?

Hey @Bee_R ,

Unfortunately, I have not managed to get it working yet with Pipewire, nor have I invested any more time in it.