Adjusting PulseAudio Volume from the Command-Line (or a Window Manager) (Shallow Thoughts)

Akkana's Musings on Open Source Computing and Technology, Science, and Nature.

Thu, 17 Oct 2019

Adjusting PulseAudio Volume from the Command-Line (or a Window Manager)

I have a new laptop, a birthday present to myself last month. For once, rather than buying a cut-rate netbook, I decided to treat myself to a fancy Lenovo Carbon X1 with an up-to-date processor and lots of RAM.

I decided that since I have way more resources than I'm used to, I'd try installing a full Ubuntu. Not that I'm running a GNOME desktop: I'm very happy with my lightweight, fast, highly configurable Openbox setup, which does just what I tell it and no more, and doesn't surprise me with random redesigns or features that work on one version but not another. But I did let it install some system utilities I've always had problems with in the past, like NetworkManager and PulseAudio. I decided I'd give them a chance, see if they've gotten better since I last checked.

They have, though they're still a bit of a hassle to deal with. NetworkManager can be controlled through nmcli, which is poorly documented but works okay if you google long enough to find the proper incancations. PulseAudio gave me a bit more trouble, though.

The standard GUI for controlling PulseAudio is called pavucontrol. I first tried it with my laptop docked through a Totu tt-hb003a 11-in-1 USB-C hub, which lets me connect to the charger, external monitor, ethernet, SD and micro-SD slots, and extra USB ports without juggling a lot of extra cables. Totu was one of the few USB hubs that claimed Linux support, and everything I've tried on it works fine, including DVI, ethernet, SD, micro SD and USB; I haven't tried the VGA port but I assume that works too.

Oh, but wait: turns out there's another aspect of the hub I hadn't tried. pavucontrol showed two audio devices: "USB PnP Audio Device Analog Stereo" and "Built-in Audio Analog Stereo". It turned out, after much fiddling, that the "USB PnP" device was part of the hub. Pulse assumes (probably reasonably, though it's wrong in this case) that if I have a USB audio device plugged in, I probably want to use it in preference to the laptop's built-in audio. That would make sense if I actually owned any speakers I could plug in to the Totu, but I left all my computer speakers behind when I moved in 2014.

Mute/Unmute via the Keyboard

The Lenovo, like most laptops, has a dedicated key for muting, Fn-F1. It even has a little light on it to show whether it's muted. In Openbox, pressing Fn-F1 actually muted the sound, and even turned on the light. This is probably because on my previous laptop I'd set key="XF86AudioMute" to run amixer set Master toggle in .config/openbox/rc.xml. The problem is that pressing it again didn't unmute it. Instead, it was unmuting the Totu's external USB audio. Clicking "Set as fallback" on the built-in audio in pavucontrol didn't help.

It turns out that it is virtually impossible to persuade PulseAudio to use "Built-in Audio" when a "USB PnP Audio Device" is available. I finally found the secret: in pavucontrol's Configuration tab, set Profile for the USB device to Off. Now only the built-in device shows up in the other tabs.

But that amixer command still wasn't unmuting properly, so the next step was to find a command I could have Openbox run that would properly unmute. Someone on #linux suggested pactl set-sink-mute @DEFAULT_SINK@ toggle which worked great from the command line, but didn't work from an openbox key. I still don't understand why that is; I wasted a lot of time comparing my shell environment to openbox's environment, to no enlightenment.

Finally I went back to web searching, and found an askbuntu thread suggesting some Openbox stanzas. In particular, it seems it works better to use alsamixer rather than pactl. This worked for toggling mute:

    <keybind key="XF86AudioMute">
        <action name="Execute">
            <command>amixer -q -D pulse sset Master toggle</command>
        </action>
    </keybind>

Volume Controls via Function Keys

Partial success! Unfortunately, the volume control commands in that same askbuntu post, amixer -q -D pulse sset Master 3%+ unmute, didn't work; they did nothing. But I had already noticed that in pavucontrol, the volume controls didn't work either. In fact, if I started some music playing and then called up alsamixer, channels like Master and Speaker didn't do anything; the only channel that affected volume was PCM. After some fiddling, I discovered that I had to change Master to PCM and remove the -D pulse:

    <keybind key="XF86AudioRaiseVolume">
      <action name="Execute">
            <command>amixer sset PCM 4%+ unmute</command>
        </action>
    </keybind>
    <keybind key="XF86AudioLowerVolume">
        <action name="Execute">
            <command>amixer sset PCM 4%- unmute</command>
        </action>
    </keybind>

I'm sure I'll eventually need to fiddle some more; for one thing, if I ever want to use audio during a talk (as I did briefly at my Stonehenge talk earlier this year) I'll need to figure out how to enable a HDMI sound sink temporarily. But for now, I'm happy to have the basic laptop audio keys working.

Tags: , ,
[ 14:09 Oct 17, 2019    More linux | permalink to this entry | comments ]