1

I don't believe this is a duplicate of Ubuntu changing default audio output after suspend, because I'm not suspending the PC.

I've got 3 audio outputs (analogue headphones, USB digital amp, USB headset) and 2 audio inputs (headset, webcam mike) on my desktop PC.

When I unlock the PC, it has switched the default audio output to the USB headset, even though I'd prefer to use the analogue headphones.

Oddly, however, music (via Clementine) continues to come out of my headphones; it's just that the volume controls on my keyboard change the volume on the USB headset.

I suspect (but don't know) that it might be because the USB headset is connected via the hub on my monitor, which powers off when the PC is locked, and presumably results in a USB connection event when powered back on.

How can I fix this?

(Ubuntu 18.04)

Roger Lipscombe
  • 437
  • 6
  • 16

3 Answers3

5

tl;dr? Scroll to the end.

Monitoring for screen lock/unlock

Adapted from here, this monitors for screen lock/unlock:

#!/bin/bash

watch="type=signal,interface=org.gnome.ScreenSaver" screen_locked_signal="boolean true" screen_unlocked_signal="boolean false"

dbus-monitor --session "$watch" | (
while read signal; do if [[ "$signal" =~ "$screen_locked_signal" ]]; then echo "Screen Locked" elif [[ "$signal" =~ "$screen_unlocked_signal" ]]; then echo "Screen Unlocked" fi done)


PulseAudio

You can find out which source and sink are currently being used as follows:

$ pactl info | grep -E 'Default (Source|Sink):'
Default Sink: alsa_output.usb-Logitech_Inc._Logitech_USB_Headset_H340-00.analog-stereo
Default Source: alsa_input.usb-Logitech_Inc._Logitech_USB_Headset_H340-00.analog-stereo

(This is my USB headset)

You can switch source and sink as follows:

$ pactl set-default-sink alsa_output.pci-0000_00_1b.0.analog-stereo
$ pactl set-default-source alsa_input.pci-0000_00_1b.0.analog-stereo

(Use analogue output and input)

You can get a complete list of sources and sinks with pactl list short sinks and pactl list short sources, but there are extra entries in there. It's probably best to switch using the UI tools and then use pactl info to discover the appropriate ones.


Final script

It results in a script that looks like this:

#!/bin/bash

GNOME

watch="type=signal,interface=org.gnome.ScreenSaver"

XFCE

watch="type='signal',interface='org.xfce.ScreenSaver'"

screen_locked_signal="boolean true" screen_unlocked_signal="boolean false"

PulseAudio: use pactl

_get_default_sink() { pactl info | sed -n 's/^Default Sink: (.*)/\1/p' }

_get_default_source() { pactl info | sed -n 's/^Default Source: (.*)/\1/p' }

_set_default_sink() { pactl set-default-sink "$1" }

_set_default_source() { pactl set-default-source "$1" }

last_sink=$(_get_default_sink) last_source=$(_get_default_source) echo "sink is $last_sink; source is $last_source"

Watch for screensaver D-Bus signals

dbus-monitor --session "$watch" | (
while read signal; do if [[ "$signal" =~ "$screen_locked_signal" ]]; then # Screen locked: remember the current default sink and source last_sink=$(_get_default_sink) last_source=$(_get_default_source) echo "Screen Locked; sink was $last_sink; source was $last_source" elif [[ "$signal" =~ "$screen_unlocked_signal" ]]; then # Screen unlocked: restore the last default sink and source _set_default_sink "$last_sink" _set_default_source "$last_source" echo "Screen Unlocked; sink is $(_get_default_sink); source is $(_get_default_source)" fi done)


Automatically starting the script

To ensure that this script runs as soon as you log in, you can use gnome-session-properties and add a startup application (I called mine "Monitor Screensaver") pointing to the script. It'll create a ~/.config/autostart/monitor-screensaver.desktop file containing the following:

[Desktop Entry]
Type=Application
Exec=/home/roger/bin/monitor-screensaver
Hidden=false
NoDisplay=false
X-GNOME-Autostart-enabled=true
Name[en_GB]=Monitor Screensaver
Name=Monitor Screensaver
Comment[en_GB]=
Comment=
Svenv
  • 103
Roger Lipscombe
  • 437
  • 6
  • 16
  • 1
    If you use xfce4-screensaver (in latest Xubuntu) then you could use watch="type='signal',interface='org.xfce.ScreenSaver'" in the script, but maybe that is not needed as the screensaver might not affect to pulseaudio in any way. – jarno Jan 19 '20 at 20:48
  • I suspect that my problem is this: The screensaver immediately sends my monitor into standby, which disconnects the USB hub. When the monitor comes out of standby, the USB reconnection causes the "new" audio devices to be chosen.

    I don't know whether the standby behaviour is specific to the GNOME screensaver, but knowing the D-Bus filters for other screensavers might be useful to those using them.

    – Roger Lipscombe Jan 19 '20 at 21:11
  • I wonder, if using the commands I gave in my answer instead of the _get and _set commands in yours in the script would work or is there some race condition? – jarno Jan 21 '20 at 08:44
  • I don't know; once I'd got my solution working, I didn't feel the need to try yours. It's a good idea, though, which is why I upvoted it. – Roger Lipscombe Jan 21 '20 at 10:35
  • Thanks! I had the same problem, except that in my case it wasn't the sink that needed setting but the card profile, so I needed to modify the script. My version for this is here: https://askubuntu.com/a/1450325/339875 – njlarsson Jan 15 '23 at 20:27
1

Another way to deal with this is via PulseAudio configuration.

You could run

pactl unload-module module-switch-on-connect

before locking, and

pactl load-module module-switch-on-connect

after unlocking. (pacmd could be used instead of pactl.)

Alternatively, you could disable (read: comment out) loading the module on default.pa configuration file; see man 5 default.pa. Then you have to switch default device manually.

jarno
  • 5,600
1

An easier solution is to comment line load-module module-switch-on-port-available from /etc/pulse/default.pa and then restart pulse with pulseaudio -k

Source : https://askubuntu.com/a/228623/654555

TikTaZ
  • 131