The terminal app Alsa allows you to audio volume programmatically. You can use it from within XMonad as a workaround when
On Ubuntu 18.04 there two terminal apps to control the volume, amixer
and pactl
. I use pactl
(and amixer
as a second option) as a workaround when i use XMonad on my Ubuntu notebook, because my FN function keys don’t work by default. The amixer
app comes from the Alsa framework, which is an abstraction to use every sound card in more or less the same way, while pactl
is part of PulseAudio, which is a sound server on top of Alsa to send sound-data from any input to any output, e.g., from your music app through an internet network to a remote speaker.
The amixer
app comes preinstalled on Ubuntu 18.04 so you don’t have to install it manually. The pactl
app should come preinstalled as well, but if it doesn’t, you can install it with
sudo apt install pulseaudio-utils pavucontrol
To see and select which audio devices the sound is coming from and send to, you should also install the graphical “PulseAudio Volume Control” pavucontrol
app.
Just to make sure that that amixer
is indeed installed, run in a terminal
amixer
You should see a an output like this:
Simple mixer control 'IEC958',0
Capabilities: pswitch pswitch-joined
Playback channels: Mono
Mono: Playback [on]
...
To make sure that that pactl
is indeed installed, run in a terminal
pactl
You should see a an output like this:
pactl [options] stat
pactl [options] info
pactl [options] list [short] [TYPE]
pactl [options] exit
pactl [options] upload-sample FILENAME [NAME]
...
Configure XMonad to use pactl or amixer
To actually use pactl
within XMonad, add these lines into the list of keymaps in your XMonad config file:
import Graphics.X11.ExtraTypes.XF86
= [
myKeys -- ...
0, xF86XK_AudioMute), spawn "pactl set-sink-mute @DEFAULT_SINK@ toggle")
, ((0, xF86XK_AudioLowerVolume), spawn "pactl set-sink-volume @DEFAULT_SINK@ -10%")
, ((0, xF86XK_AudioRaiseVolume), spawn "pactl set-sink-volume @DEFAULT_SINK@ +10%")
, ((-- ...
]
If you use the EZ keymap notation, use these lines:
= [
myKeys -- ...
"<XF86AudioMute>", spawn "pactl set-sink-mute @DEFAULT_SINK@ toggle")
, ("<XF86AudioLowerVolume>", spawn "pactl set-sink-volume @DEFAULT_SINK@ -10%")
, ("<XF86AudioRaiseVolume>", spawn "pactl set-sink-volume @DEFAULT_SINK@ +10%")
, (-- ...
]
Explain the code
Code | Note |
---|---|
import ...
|
Make the functions and constants from a module available. |
...XF86
|
Module that includes Haskell representations of multimedia keyboard keys. |
xF86XK_AudioRaiseVolume
|
Haskell representation of the “Brightness up” multimedia keyboard key. |
spawn ".."
|
Run an app or script. You can run anything that you can run in a terminal. |
DEFAULT_SINK
|
Device/Channel where audio data is sent to by default. Use pavucontrol to change the default device.
|
If you can’t control the volume, try this workaround.
To use amixer
instead of pactl
within XMonad (it still requires that you have the PulseAudio server installed), add these lines into the list of keymaps in your XMonad config file:
import Graphics.X11.ExtraTypes.XF86
= [
myKeys -- ...
0, xF86XK_AudioMute), spawn "amixer -D pulse set Master 1+ toggle")
, ((0, xF86XK_AudioLowerVolume), spawn "amixer -D pulse set Master 10%-")
, ((0, xF86XK_AudioRaiseVolume), spawn "amixer -D pulse set Master 10%+")
, ((-- ...
]
If you use the EZ keymap notation, use these lines:
= [
myKeys -- ...
"<XF86AudioMute>", spawn "amixer -D pulse set Master 1+ toggle")
, ("<XF86AudioLowerVolume>", spawn "amixer -D pulse set Master 10%-")
, ("<XF86AudioRaiseVolume>", spawn "amixer -D pulse set Master 10%+")
, (-- ...
]
If you still can’t control the volume, try this workaround.
To use amixer
instead of pactl
within XMonad (without the PulseAudio server at all), add these lines into the list of keymaps in your XMonad config file:
import Graphics.X11.ExtraTypes.XF86
= [
myKeys -- ...
0, xF86XK_AudioMute), spawn "amixer -q set PCM toggle")
, ((0, xF86XK_AudioLowerVolume), spawn "amixer -q set PCM 1-")
, ((0, xF86XK_AudioRaiseVolume), spawn "amixer -q set PCM 1+")
, ((-- ...
]
If you use the EZ keymap notation, use these lines:
= [
myKeys -- ...
"<XF86AudioMute>", spawn "amixer -q set PCM toggle")
, ("<XF86AudioLowerVolume>", spawn "amixer -q set PCM 1-")
, ("<XF86AudioRaiseVolume>", spawn "amixer -q set PCM 1+")
, (-- ...
]