Naming Audio interfaces in Linux
Post created: 6. Oct. 2024
tl;dr
- I didn’t find a way to make it work just with udev rules
- So I use a bash script
- Requires fixed, unchanging use of physical USB ports for each device (radio)
- Requires pulseaudio (or at least the pa-tools, like pacmd)
- You cannot use my script directly, you have to adopt it to your situation.
- Doesn’t work for some software (WSJT-X notably)
- Not my work, but I lost the information who did this first. Sorry.
longer version
Usually, audio devices in Linux show up with a technical name which does not help to indentify each device. Since I have three or four radios connected to my computer all the time, I needed something to differentiate them - clear and easy audio names which show up in software like in the image below.
Here the currently three connected radios show up with properly readable names like IC-7300-sink (the destination for TX audio) or IC-R8600, the source of received audio. This is achieved by running a short bash script after booting the computer. Here it is:
pacmd update-sink-proplist $(pacmd list-sinks | grep -E "name:.*Burr-Brown*|1-6.4" | grep -B 1 sysfs.path | grep name | sed "s/.*<\(.*\)>/\1/") device.description=IC-705
pacmd update-source-proplist $(pacmd list-sources | grep -E "name:.*Burr-Brown*|1-6.4" | grep -B 1 sysfs.path | grep name | sed "s/.*<\(.*\)>/\1/" | grep -v monitor) device.description=IC-705
pacmd update-source-proplist $(pacmd list-sources | grep -E "name:.*Burr-Brown*|1-2.3" | grep -B 1 sysfs.path | grep name | sed "s/.*<\(.*\)>/\1/" | grep -v monitor) device.description=IC-R8600
pacmd update-sink-proplist $(pacmd list-sinks | grep -E "name:.*Burr-Brown*|1-3.4" | grep -B 1 sysfs.path | grep name | sed "s/.*<\(.*\)>/\1/") device.description=IC-9700
pacmd update-source-proplist $(pacmd list-sources | grep -E "name:.*Burr-Brown*|1-3.4" | grep -B 1 sysfs.path | grep name | sed "s/.*<\(.*\)>/\1/" | grep -v monitor) device.description=IC-9700
pacmd update-sink-proplist $(pacmd list-sinks | grep -E "name:.*Burr-Brown*|1-1.4" | grep -B 1 sysfs.path | grep name | sed "s/.*<\(.*\)>/\1/") device.description=IC-7300-Sink
pacmd update-source-proplist $(pacmd list-sources | grep -E "name:.*Burr-Brown*|1-1.4" | grep -B 1 sysfs.path | grep name | sed "s/.*<\(.*\)>/\1/" | grep -v monitor) device.description=IC-7300-Source
This script has two lines for each device, one line for input, one line for output (where applicable). Let’s brake it down, so we understand what it does.
The outermost command is pacmd <command> <device> <property
. Here the command is update-sink-list
or update-source-list
, and the property is device.description=IC-R8600
.
But in this case, the <device>
item on this command is constructed by the inner expression:
$(pacmd list-sinks | grep -E "name:.*Burr-Brown*|1-6.4" | grep -B 1 sysfs.path | grep name | sed "s/.*<\(.*\)>/\1/")
The first part pacmd list-sinks
gives us a long output, a list of all audio sinks known to pulseaudio.
This long list is “piped” (using the “|” symbol) to grep, a filter program, asking it to filter only lines which contain the strings “Burr-Brown” or “1-2.3”. The output looks like this on my computer.
name: <alsa_output.usb-Burr-Brown_from_TI_USB_Audio_CODEC-00.analog-stereo>
name: <alsa_output.usb-Burr-Brown_from_TI_USB_Audio_CODEC-00.analog-stereo.2>
sysfs.path = "/devices/pci0000:00/0000:00:14.0/usb1/1-2/1-2.3/1-2.3:1.0/sound/card2"
name: <alsa_output.usb-Burr-Brown_from_TI_USB_Audio_CODEC-00.analog-stereo.3>
So there are three lines containing the string “Burr-Brown” and one containing “1-2.3”.
This output is again piped to the next part of the command. This again uses ‘grep’ to filter, now it looks for the line containing ‘sysfs.path’, and additionally display the previous line above that one containing ‘sysfs.path’ (thats what the ‘-B 1’ option to grep does.). The output looks like this on my computer:
name: <alsa_output.usb-Burr-Brown_from_TI_USB_Audio_CODEC-00.analog-stereo.2>
sysfs.path = "/devices/pci0000:00/0000:00:14.0/usb1/1-2/1-2.3/1-2.3:1.0/sound/card2"
So we are down to two lines. Again, this output is piped to the next filter expression. Now grep is instructed to look for the line containing the string ’name’. So the final filter result (so far) looks like this:
name: <alsa_output.usb-Burr-Brown_from_TI_USB_Audio_CODEC-00.analog-stereo.2>
And again, this result is piped to the next command: sed. sed is the stream editor. This program is able to ’edit’ (change) parts of the input. Here it looks for a string enclosed in angular brackets <…>, extracts the inner part and returns this as a result. So the result looks like this:
alsa_output.usb-Burr-Brown_from_TI_USB_Audio_CODEC-00.analog-stereo.2
And that is the technical name of the interface on the USB connection “1-2.3”. This name is returnd as the second parameter to ‘pacmd update-sink-proplist’, the third parameter is the proper name we would like to see rather.
So after all the final command looks like this:
pacmd update-sink-list alsa_output.usb-Burr-Brown_from_TI_USB_Audio_CODEC-00.analog-stereo.2 device.despription=IC-R8600
The final effect is that this interface now shows up as “IC-R8600” in most other audio software, like Pavucontrol and others. There are notable exceptions with programs like WSJT-X. Unfortunately this software always uses the technical name of the interface, never the device.description. The better approach would be to look at device.description and use that if it is not empty. If it is empty use the technical name of the interface.
How to find the USB path of a device?
Using cyme
Use cyme -vv
to see all USB devices. Look for names like “USB Audio CODEC”. In the vicinity of this line you will find the USB bus and interface your device is connected to. Example:
Using pacmd list-sinks
Use pacmd list-sinks
to list all sinks. Use a pager (like ’less’) and look for lines with “USB Audio CODEC”. Somewhere in the vicinity you will find the ‘sysfs-path’ property. Look for identifiers like 1-2.3. Sinks and source of the device will use the same path.
Notes
-
This will only work if you have pulseaudio installed, because that’s where the
pacmd
tool is coming from. I am still on pulseaudio instead of the newer pipewire, because of this script and another dependency to pulseaudio (SDRangel). Pipewire does have a compatibility layer to pulseaudio, but I haven’t tried this. -
This will only work if you connect your audio device (radio or whatever) alsways to the same physical port of your computer. I have an IC-705 which is not always connected to my PC, but it has it’s reserved, otherwise unused USB port. So when I connect it next time, it will be found by the script at the same USB location (the sysfs path).
-
Of course you will have to adjust the script to your situation. The path names of the USB interfaces will be much different, as will be the names of the devices you connect.
-
This is not my work. I found a script like that, which I adapted to my needs. Unfortunately I have lost the information where I found this. All kudos to that person, not me.