Pipewire with UAC2 external DAC - Volume control

Hi !

I’m using Kubuntu 24.04 on my computer, and I use a raspberry PI zero as an USB sound card. The raspberry pi side is configured as an USB Audio Class 2 (UAC2) external DACs, and is correctly detected by ubuntu. But, I want the raspberry side to be able to control the volume ( to control loundness for example). And that isn’t working anymore since ubuntu now use pipewire ( I handled that issue when using pulseaudio).

Using alsamixer, I can observe that when I manually change the volume of my USB sound card, the volume is retrieved on the raspbery side and is correctly handled. But when I change the global system volume( using the knob on my keyboard), this mixer volume doesn’t change and the volume seems to be softwarely applied.

I tried to change the profile of my USB sound card with pavucontrol to " Digital Audio(IEC958) Output" but It didn’t change anything.

How to force the system to just change the volume of my sound card mixer, and not change the volume by software ?

Regards :slight_smile:

How ? You should note that pipewire has pretty much all the same knobs pulse did, often just hidden in another place or config file …

Technically all the same things you did with pulse should be achievable with pipewire too …

1 Like

You could try disabling the software volume control and instead manipulate the ALSA mixer control directly using a drop in configuration like,

~/.config/wireplumber.conf.d/pi0_volume.conf

{
  "monitor.alsa.rules": [
    {
      "matches": [
        {
          "device.api.alsa.card.name": "<USB CARD NAME  FROM aplay -l>"
        }
      ],
      "actions": {
        "update-props": {
          "api.alsa.soft-mixer": false,
          "api.alsa.mixer-name": "<MIXER_NAME YOU CHANGED IN ALSAMIXER>"
        }
      }
    }
  ]
}

Basicaly I made what is written in this post : https://www.diyaudio.com/community/threads/linux-usb-audio-gadget-rpi4-otg.342070/post-7459331

Ie: Force pulseaudio to use a mixer name which differs from the standard one. And I try to do the same thing today with pipewire/wireplumber.

I made some step forward with this. Like I said, I want pipewire/wireplumber to use a mixer which doesn’t have a standard name.

With wpctl, I retrieved some infos about my device :

$ wpctl inspect 50

id 50, type PipeWire:Interface:Device
    alsa.card = "1"
    alsa.card_name = "UAC2Gadget48000"
    alsa.components = "USB1d6b:0104"
    alsa.driver_name = "snd_usb_audio"
    alsa.id = "UAC2Gadget48000"
    alsa.long_card_name = "USBDAC UAC2Gadget48000 at usb-0000:66:00.4-1, high speed"
    **alsa.mixer_name = "USB Mixer"**
    api.acp.auto-port = "false"
    api.acp.auto-profile = "false"
    api.alsa.card = "1"
    api.alsa.card.longname = "USBDAC UAC2Gadget48000 at usb-0000:66:00.4-1, high speed"
    api.alsa.card.name = "UAC2Gadget48000"
    api.alsa.path = "hw:1"
    api.alsa.soft-mixer = "false"
    api.alsa.use-acp = "true"
    api.dbus.ReserveDevice1 = "Audio1"
  * client.id = "35"
  * device.api = "alsa"
    device.bus = "usb"
    device.bus-id = "usb-USBDAC_UAC2Gadget48000_000001-00"
    device.bus-path = "pci-0000:66:00.4-usb-0:1:1.0"
  * device.description = "Multifunction Composite Gadget"
    device.enum.api = "udev"
    device.icon-name = "audio-card-analog-usb"
  * device.name = "alsa_card.usb-USBDAC_UAC2Gadget48000_000001-00"
  * device.nick = "AudioGadget"
    device.plugged.usec = "5722964"
    device.product.id = "0x0104"
    device.product.name = "Multifunction Composite Gadget"
    device.serial = "USBDAC_UAC2Gadget48000_000001"
    device.string = "1"
    device.subsystem = "sound"
    device.sysfs.path = "/devices/pci0000:00/0000:00:08.3/0000:66:00.4/usb7/7-1/7-1:1.0/sound/card1"
    device.vendor.id = "0x1d6b"
    device.vendor.name = "Linux Foundation"
  * factory.id = "14"
  * media.class = "Audio/Device"
    object.path = "alsa:pcm:1"
  * object.serial = "51"

I managed to disable soft-mixer, but I noticed that using “USB Mixer” as mixer name is wrong, as it is “Playback Volume”. I tried to modified the value alsa.mixer_name, but it didn’t work :-/
Any idea?

Regards

Hrm, can you take a screenshot of the alsamixer pane for your DAC?

Try saving this as ~/.config/wireplumber.conf.d/90-pi0-volume.conf to try and make sure nothing stomps over it (remove the old pi0_volume.conf)

{
  "monitor.alsa.rules": [
    {
      "matches": [
        {
          "device.api.alsa.card.name": "UAC2Gadget48000"
        }
      ],
      "actions": {
        "update-props": {
          "api.alsa.soft-mixer": false,
          "api.alsa.mixer-name": "Playback Volume"
        }
      }
    }
  ]
}

Once you have it saved, make sure to restart all the audio services with systemctl --user restart pipewire pipewire-pulse wireplumber.

Sorry, I tried multiple solution with an wireplumber configuration. It seems not be possible for now to change the mixer-name after it was autodected.
I can only change it if I disable alsa card profile ( with alsa.use-acp = false), but in this case nothing works anymore :-/

At the end, the only way I found was to rebuild the UAC2 module on my raspberry PI to correct the default mixer name :


static struct usb_string strings_fn[] = {
    [...]
	[STR_FU_OUT].s = "PCM",
};

Ouch! Glad you got it working. Potentially related: https://gitlab.freedesktop.org/pipewire/pipewire/-/issues/4934