Brain Phrye

code cooking diy fiction personal photos politics reviews tools 


Desktop Audio Source

[ Listen to article ]

One of the odd things about desktops these days is that they have loads of microphones and speakers. Which leads to the issue - which one to use?

In my case I change the speaker around a lot and that generally works fine. I have an Ocean Galaxy Light which I use most of the time. I kind of thought the Bluetooth speaker thing it had was silly when I got it, but now that’s pretty much my sole use of it. In addition I use Sennheiser HD 4.50 BTNC Bluetooth headphones for video calls but they’re a bit tight for longer use.

These two work really well - when I turn on the headphones they become the speakers and when I turn them off it defaults back to the Ocean Galaxy. Which is exactly what I want.

The issue is that when I turn on the headphones it also becomes my microphone. This isn’t ideal since I have a TONOR 777 USB microphone which has way better sound than the headphones (a low bar to clear admittedly). And sometimes when I turn the headphones off it switches to the webcam microphone.

Hunting around I found that sound on a default Ubuntu install is handled by pulse which seems to be the modern day nas. You can configure pulse on the command line and via a config file so to try and cover all my bases I did the following:

Added this to ~/.pulse/default.pa (see desktop audio revisited about editing this file):

1
set-default-source alsa_input.usb-C-Media_Electronics_Inc._TONOR_TC-777_Audio_Device-00.mono-fallback

I also added this to the list of startup applications in GNOME:

1
pactl set-default-source alsa_input.usb-C-Media_Electronics_Inc._TONOR_TC-777_Audio_Device-00.mono-fallback

However this wasn’t enough. When the headphones are turned on, pulse seems to want to switch the speakers and the microphone to the new hotness. So how to convince it not to?

The answer was udev rules, but first I had to find out how to address the device. There is likely a much easier way to do this, but this is what I did:

1
2
3
4
5
udevadm control --log-priority=debug
grep /sys/devices/virtual/input /var/log/syslog
udevadm info -ap "the device I found from that grep"
udevadm control --reload-rules
udevadm control --log-priority=info

With that done, I made the /etc/udev/rules.d/99-btnc-450.rules file:

1
2
ACTION=="add", SUBSYSTEM=="input", ATTRS{name}=="HD 4.50BTNC (AVRCP)", RUN+="/home/kevin/.config/home-desktop/btnc-4.50-pa-setup.sh"
ACTION=="remove", SUBSYSTEM=="input", ATTRS{name}=="HD 4.50BTNC (AVRCP)", RUN+="/home/kevin/.config/home-desktop/btnc-4.50-pa-setup.sh"

This means that each time my headphones appear, udev will run ~/.config/home-desktop/btnc-4.50-pa-setup.sh - the contents of which are here:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#!/bin/bash


user=kevin
uid="$(getent passwd $user | cut -d: -f 3)"
source="alsa_input.usb-C-Media_Electronics_Inc._TONOR_TC-777_Audio_Device-00.mono-fallback"

pactl_as_user() {
  su $user -c "XDG_RUNTIME_DIR=/run/user/$uid pactl $*"
}

# Wait till it changes and set it back.
i=0
while pactl_as_user info | grep "Default Source: $source"; do
  i=$(( i + 1 ))
  sleep 1
  test $i -gt 30 && break
done
pactl_as_user set-default-source $source

# Just in case we change it too quickly, wait ~30 more seconds to change
# it back again.
if [[ i -lt 3 ]]; then
  sleep 5
  while pactl_as_user info | grep "Default Source: $source"; do
    i=$(( i + 1 ))
    sleep 1
    test $i -gt 30 && break
  done
fi
pactl_as_user set-default-source $source

All in all a pain in the arse, but it is making sure my USB mic stays as my chosen mic.