df4or

Naming Audio interfaces in Linux

Post created: 6. Oct. 2024

tl;dr

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.

Pavucontrol Screenshot

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:

cyme Screenshot

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.

pacmd Screenshot

Notes