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.

Sun, 24 Nov 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.

Since I have way more resources than I'm used to, I decided I'd try installing a full Ubuntu and not trying to pare it down to a super lightweight system. I'm still running the lightweight, fast, highly configurable Openbox window manager instead of a full Gnome desktop: Openbox does just what I tell it and no more, and doesn't surprise me with random redesigns. But I did let Ubuntu install some system utilities I've always avoided 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.

The standard GUI for controlling PulseAudio is pavucontrol. It showed two audio devices: "USB PnP Audio Device Analog Stereo" and "Built-in Audio Analog Stereo". Turns out the USB PnP option is a sound card built into the USB hub, a Totu tt-hb003a 11-in-1 USB-C hub that lets me connect to a charger, external monitor, SD and micro-SD slots, and extra USB ports without juggling a lot of extra cables.

Pulse assumes -- probably reasonably, though it's wrong in this case -- that if I have a USB audio device connected, I probably want to use it in preference to the laptop's built-in audio. That would make sense if I had external speakers plugged in, but I left all my computer speakers behind when I moved. I should probably order some speakers. But meanwhile, I needed to persuade PulseAudio to ignore the hub and use the laptop's built-in sound system.

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 I'd previously set key="XF86AudioMute" to run amixer set Master toggle in .config/openbox/rc.xml, which worked on my Pulse-free pared-down Debian netbook. The problem is that pressing iFn-F1 again didn't bring the sound back. Instead, it was unmuting the USB hub's audio. Clicking "Set as fallback" on the built-in audio in pavucontrol made no difference.

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 PnP 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 that would actually unmute. Someone on #linux suggested pactl set-sink-mute @DEFAULT_SINK@ toggle and that worked great from the command line. But when I tried to bind it in Openbox to the XF86AudioMute key, it did nothing. I still don't understand why not; I wasted a lot of time comparing my shell environment to openbox's environment and never found the difference.

Back to web searching, I found an askbuntu thread suggesting some Openbox stanzas. In particular, it apparently works better to use alsamixer rather than pactl. This finally 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, did nothing. 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 ALSA 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 temporary HDMI sound sink quickly without needing to fiddle with pavucontrol. But for now, I'm happy to have the basic laptop volume and mute keys working.

Tags: , , ,
[ 15:43 Nov 24, 2019    More linux | permalink to this entry | comments ]