1

My ThinkPad T450s runs Manjaro. As a scrum master, I frequently move between my desk with two external displays, meeting rooms with no displays, and meeting rooms with one external display. I've installed autorandr so that the laptop automatically sets up my workspaces according to the available hardware. I love it so much!

But I would also love a similar solution for audio. When at my desk, I want the "fallback devices for both input to be my Bluetooth Jabra headset and for output to be my "simultaneous output to all devices" pseudo-device, but in meeting rooms I will usually connect a USB (Jabra or Logitech) meeting room speakerphone device -- and then I need to go into the Volume Control panel and set up the default devices.

If I could have the whole thing automated, so that newly connected devices would be automatically selected as fallback input/output, that would be so neat!

Caveat: To win the bounty, the answer must describe a solution that works automatically when hardware is plugged in/out. It would be acceptable to trigger a script to run whenever autorandr runs (but autorandr itself has no such slipstreaming capability).

Volume Control panel

Edit: Inspired by @telcoM's answer, I can now include the list of sources and sinks recognized by my system (except the ones in the meeting rooms which I am not currently connected to):

$ pactl list | grep -B 2 'ame:' | grep -A 2 'Sink #'
Sink #0
    State: SUSPENDED
    Name: alsa_output.pci-0000_00_1b.0.analog-stereo
--
Sink #1
    State: SUSPENDED
    Name: combined
--
Sink #43
    State: SUSPENDED
    Name: alsa_output.usb-GN_Netcom_A_S_Jabra_PRO_9470_026D0D98A805-00.analog-mono
--
Sink #93
    State: SUSPENDED
    Name: alsa_output.pci-0000_00_03.0.hdmi-stereo-extra1

and also

$ pactl list | grep -B 2 'ame:' | grep -A 2 'Source #'
Source #0
    State: SUSPENDED
    Name: alsa_output.pci-0000_00_1b.0.analog-stereo.monitor
--
Source #1
    State: SUSPENDED
    Name: alsa_input.pci-0000_00_1b.0.analog-stereo
--
Source #2
    State: SUSPENDED
    Name: combined.monitor
--
Source #46
    State: SUSPENDED
    Name: alsa_output.usb-GN_Netcom_A_S_Jabra_PRO_9470_026D0D98A805-00.analog-mono.monitor
--
Source #47
    State: SUSPENDED
    Name: alsa_input.usb-GN_Netcom_A_S_Jabra_PRO_9470_026D0D98A805-00.analog-mono
--
Source #97
    State: SUSPENDED
    Name: alsa_output.pci-0000_00_03.0.hdmi-stereo-extra1.monitor
1
+50

By default, Pulseaudio remembers which output device each playback source was associated with, and likewise for input devices and recording software. This is the primary source of device associations for vanilla Pulseaudio.

The fallback device is only used when e.g. a playback source has no record of previous association, or the previously-associated device is no longer available.

At least KDE has a multimedia settings dialog you can use to set a priority order for your audio input/output devices, separately for each type of audio input/output (communications vs. audio or video playing/recording, for example). This seems to modify the behavior of Pulseaudio.

This blog and the mentioned paswitch utility might be useful for you:

https://www.tablix.org/~avian/blog/archives/2012/06/switching_pulseaudio_output_device/

Git repository for paswitch: https://www.tablix.org/~avian/git/paswitch.git

I earlier had a script for this purpose, but paswitch is better as it switches both active and previously-remembered sources to a new output in addition to switching the default/fallback output. Unfortunately it only handles the output side.

To switch active clients that have already started to use a particular microphone, you'll need to do something like this:

pacmd set-default-source "$SOURCEID"
if ! pacmd list-source-outputs | head -1 | grep -q "^0 source output"
then
    # active input clients, switch them to new mic
    for idx in $(pacmd list-source-outputs | awk '/index:/{print $2;}')
    do
        # sources include monitor sources that cannot be moved
        pacmd move-source-output $idx $SOURCEID >/dev/null
    done
fi

This first changes the default microphone to the one specified in $SOURCEID, and then moves any active applications to this new mic.

But if an application was run before using a different audio source device, and this source is still available on the system, Pulseaudio will by default connect it to its old source instead of the new default source, unless its persistence feature is switched off.

  • This is a GREAT starting point, thank you! With this I can, however, only change outputs, and I also need to do the same with inputs. (Also, I'm confused by the output of pactl list and what is a sink or a source.) – KlaymenDK Aug 14 '18 at 15:02
  • In Pulseaudio lingo, a source is something that provides audio data: either a program that wants to play a sound, or a microphone. A sink is something that can accept audio data: a sound output device, or a program that wants to record audio. – telcoM Aug 14 '18 at 15:07
  • Yeah that was what I expected, but until I applied the right amount of grep I thought the list was inconsistent. Thanks. – KlaymenDK Aug 14 '18 at 15:10
0

Oho! I found the correct commands to obtain the names of the inputs and outputs! This is mainly from this answer to another question, but really credit goes to telcoM for pointing me towards pactl.

$ pactl list short sources
0   alsa_output.pci-0000_00_1b.0.analog-stereo.monitor  module-alsa-card.c  s16le 2ch 44100Hz   RUNNING
1   alsa_input.pci-0000_00_1b.0.analog-stereo   module-alsa-card.c  s16le 2ch 44100Hz   RUNNING
2   combined.monitor    module-combine-sink.c   s16le 2ch 44100Hz   RUNNING
144 alsa_output.usb-GN_Netcom_A_S_Jabra_PRO_9470_026D0D98A805-00.analog-mono.monitor    module-alsa-card.c  s16le 1ch 16000Hz   RUNNING
145 alsa_input.usb-GN_Netcom_A_S_Jabra_PRO_9470_026D0D98A805-00.analog-mono module-alsa-card.c  s16le 1ch 16000Hz   RUNNING
152 alsa_output.pci-0000_00_03.0.hdmi-stereo-extra1.monitor module-alsa-card.c  s16le 2ch 44100Hz   RUNNING

and

$ pactl list short sinks
0   alsa_output.pci-0000_00_1b.0.analog-stereo  module-alsa-card.c  s16le 2ch 44100Hz   RUNNING
1   combined    module-combine-sink.c   s16le 2ch 44100Hz   RUNNING
136 alsa_output.usb-GN_Netcom_A_S_Jabra_PRO_9470_026D0D98A805-00.analog-mono    module-alsa-card.c  s16le 1ch 16000Hz   RUNNING
143 alsa_output.pci-0000_00_03.0.hdmi-stereo-extra1 module-alsa-card.c  s16le 2ch 44100Hz   RUNNING

This allows me to set the sources:

$ pactl set-default-source alsa_input.usb-GN_Netcom_A_S_Jabra_PRO_9470_026D0D98A805-00.analog-mono
$ pactl set-default-source alsa_input.pci-0000_00_1b.0.analog-stereo

And also the sinks:

$ pactl set-default-sink alsa_output.usb-GN_Netcom_A_S_Jabra_PRO_9470_026D0D98A805-00.analog-mono
$ pactl set-default-sink combined

These commands, then, I can put in "hook scripts" for autorandr to trigger. I just need to connect the USB audio devices before the video cables, and everything will be awesome!

  • I updated my answer to include a snippet from my old scripts for handling microphone switching. Setting the default sink/source may not be enough: you may also want to switch the active audio applications to the new source: my snippet covers that for the microphone/input side, and the output side can be handled similarly. – telcoM Aug 16 '18 at 11:20

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.