Как назвать USB-устройства Pulseaudio по физическому местоположению в дереве USB?

Обратите внимание :, изменяя переменную num, вы можете регулировать количество элементов.

gawk -v num=5 '
BEGIN {
    PROCINFO["sorted_in"] = "@ind_str_asc"
}
{
    ### 
    # Traverse throught input.txt from first to last line
    # and store all elements in the two-dimensional array - table
    # along the way, maintain the array of counters for each letter
    ###

    # The array of counters for each unique element from the first column.
    # In our case the indexes of array are capital letters (A, B, C, D)
    # and values are the amount of each letter occurrences.
    cnt_arr[$1]++

    # Two dimension array - table
    # it looks like chess board - rows named by letters (A, B, C, D)
    # and columns named by numbers (1, 2, 3, 4, 5... etc).
    # Its cells contains numbers from the second column.
    # For example, if letter A occurrences 5 times in the input.txt
    # then, the table will have the A row with 5 columns 
    table[$1][cnt_arr[$1]] = $2
}
# At this point, all lines from input.txt are processed
# and stored in the table
END {
    # Do needed number of iterations - specified by the num variable
    for(i = 0; i < num; i++) {

        # On each iteration run the inner loop,
        # which iterating through all rows in the table
        for(row_name in table) {

            # Check each cell - if it is non-empty
            # add its value to the result_arr[row_name], separated by OFS.
            # OFS - output field separator, the space by default
            if(table[row_name][i]) {
                result_arr[row_name] = result_arr[row_name] OFS table[row_name][i]
                # and count the number of succesful occurences
                cnt++
            }

            # If count of non-empty cells equals to the num variable
            # or equals to the NR (number of records|lines)
            # print the result_arr and exit
            if(cnt == num || cnt >= NR) {
                for(i in result_arr) {
                    print i result_arr[i]
                }
                exit
            }
        }
    }
}' input.txt

Информация о строке PROCINFO["sorted_in"] = "@ind_str_asc"находится здесь .


Вход

A 1
B 2
C 9
D 1
A 5
B 3
C 9
A 6
C 7
A 5
C 1

Выход

A 1 5
B 2
C 9
D 1

0
31.01.2020, 09:50
1 ответ

Вот что я придумал:

$ cat /etc/udev/rules.d/99-usb-audio.rules
ACTION=="change", SUBSYSTEM=="sound", DEVPATH=="/devices/*/usb*/sound/card?", ENV{PULSE_NAME}="$env{ID_ID}.$env{ID_PATH_TAG}"

Значение 99 важно, потому что ID_PATH_TAGустанавливается более ранним правилом (Я не уверен, каким именно ); использование меньшего числа привело к тому, что моя первоначальная попытка не сработала.

Теперь имя приемника содержит ID_PATH_TAG, которое идентифицирует карту по физическому местоположению:

$ pactl list sinks | grep Name
        Name: alsa_output.usb-C-Media_Electronics_Inc._USB_Audio_Device-00.pci-0000_06_00_3-usb-0_2_4_2_1_1_0.analog-stereo
        Name: alsa_output.usb-C-Media_Electronics_Inc._USB_Audio_Device-00.pci-0000_06_00_3-usb-0_2_4_2_3_1_0.analog-stereo

Местоположение закодировано в подстроках:

usb-0_2_4_2_1_1_0
usb-0_2_4_2_3_1_0

что, по-видимому, означает, что к порту 2 моего ноутбука подключен USB-концентратор; в порт 4 этого хаба подключен другой хаб; и третий концентратор в порт 2 второго концентратора. Аудиоустройства подключаются к портам 1 и 3 последнего концентратора. Я не уверен насчет префикса "-0 _" или суффикса "_1 _0".

$ lsusb -t
/:  Bus 02.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/4p, 480M
    |__ Port 2: Dev 2, If 0, Class=Hub, Driver=hub/4p, 480M
        |__ Port 4: Dev 4, If 0, Class=Hub, Driver=hub/4p, 480M
            |__ Port 2: Dev 26, If 0, Class=Hub, Driver=hub/4p, 480M
                |__ Port 3: Dev 28, If 0, Class=Audio, Driver=snd-usb-audio, 12M
                |__ Port 1: Dev 27, If 0, Class=Audio, Driver=snd-usb-audio, 12M
1
28.04.2021, 23:25

Теги

Похожие вопросы