Как единообразно называть аудиоустройства?

Как единообразно называть аудиоустройства?

У меня есть пара любительских радиостанций, которые я подключаю к своему компьютеру Linux через USB. Радиостанции представляются как звуковые карты и видны вот так:

$ aplay -l
[...]
card 1: CODEC [USB Audio CODEC], device 0: USB Audio [USB Audio]
  Subdevices: 1/1
  Subdevice #0: subdevice #0
card 2: CODEC_1 [USB Audio CODEC], device 0: USB Audio [USB Audio]
  Subdevices: 1/1
  Subdevice #0: subdevice #0

$ arecord -l
**** List of CAPTURE Hardware Devices ****
card 1: CODEC [USB Audio CODEC], device 0: USB Audio [USB Audio]
  Subdevices: 1/1
  Subdevice #0: subdevice #0
card 2: CODEC_1 [USB Audio CODEC], device 0: USB Audio [USB Audio]
  Subdevices: 0/1
  Subdevice #0: subdevice #0

На USB-накопителе они отображаются как:

$ lsusb | grep Audio
$ lsusb | grep Aud
Bus 001 Device 102: ID 08bb:2901 Texas Instruments PCM2901 Audio Codec
Bus 001 Device 099: ID 08bb:2901 Texas Instruments PCM2901 Audio Codec

Проблема в том, что у меня есть программное обеспечение, которое хочет общаться с одним из них, но не знает, с каким именно. Программное обеспечение (js8call и wsjtx) просто позволяет мне выбрать имя из раскрывающегося списка и запоминает выбранное имя.

Имена в этом раскрывающемся списке:

alsa_input.usb-Burr-Brown_from_TI_USB_Audio_CODEC-00.analog-stereo
alsa_input.usb-Burr-Brown_from_TI_USB_Audio_CODEC-00.analog-stereo.2

Другому программному обеспечению (например, direwolf) требуется устройство в формате «plughw:2,0», тогда как другое радио — «plughw:1,0».

Но это не согласовано, что есть что. Это зависит от того, когда Linux их обнаружил, что в лучшем случае является порядком, в котором я их подключал, а в обычном случае это состояние гонки, поскольку оба подключены и используют один и тот же блок питания, поэтому они загружаются одновременно, когда я включаю питание.

Итак, как мне заставить Linux называть эти два звуковых устройства согласованным образом, чтобы мне не приходилось редактировать файлы конфигурации и менять настройки в пользовательском интерфейсе каждый раз, когда они обнаруживаются в другом порядке?

решение1

Имена в раскрывающемся списке выглядят как имена источников PulseAudio: см. pacmd dump. Они будут включать серийный номер звукового устройства USB, если он есть в стандартном дескрипторе устройства USB (см. lsusb -d 08bb:2901 -v | grep iSerial). Если у радиоприемников нет уникального идентификатора, обнаруживаемого Linux, может быть сложно получить для них единообразные имена.

Имена PulseAudio, по-видимому, генерируются на основе ID_IDсвойства, см. udevadm info -q property -p /sys/class/sound/card<N>где <N>находится номер соответствующего звукового устройства (начиная с card0).

Вы можете создать пользовательское правило udev, которое, например, использует ID_PATHсвойство для идентификации радиоустройств на основе того, к какому физическому порту USB они подключены, и настроить ENV{ID_ID}свойство на его основе, чтобы обеспечить уникальную идентификацию интерфейса каждого радиоустройства.


plughw:N,0имена - это имена устройств ALSA //, см. .asoundrc( примечание/etc/alsa/conf.darecord -Lверхний регистрL). NЧисло равно атрибуту udev ATTR{number}, который виден с помощью udevadm info -q all -a -p /sys/class/sound/card<N>.

Вы могли бы использовать имена вроде , plughw:CARD=<name>,DEV=0если версия ОС не слишком старая. <name>Часть основана на атрибуте udev ATTR{id}, видимом с udevadm info -q all -a -p /sys/class/sound/card<N>.

Возможность изменения атрибутов ATTR{number}или ATTR{id}с помощью правил udev, по-видимому, зависит от того, какая версия udev установлена ​​в вашей системе: новые версии udev, по-видимому, строже старых, или, возможно, в новых системах более сложные наборы правил udev, и я просто не нашел правильного способа их задать.

Порядок правил udev важен: вам может потребоваться изучить существующие правила udev вашего дистрибутива Linux, чтобы выяснить, следует ли вам устанавливать собственные правила для активациидоилипослестандартные правила дистрибутива, чтобы ваши правила действительно вступили в силу. В старых дистрибутивах все правила udev находились в одном каталоге: в современных — /etc/udev/rules.d/для локальных настроек, а стандартные правила системы находятся в [/usr]/lib/udev/rules.d/.

В современных дистрибутивах, если файл правил с одинаковым именем существует как в /etc/udev/rules.d/системном каталоге стандартных правил, так и в нем, файл в нем /etc/udev/rules.d/перезапишет соответствующий стандартный файл, поэтому вам никогда не придется изменять какие-либо файлы в стандартном каталоге правил... и ваши настройки никогда не будут перезаписаны обновлениями пакетов.

В качестве альтернативного решения для ALSA, если вы обнаружите, что не можете изменить требуемые атрибуты udev, вы можете заставить udev сгенерировать для вас общесистемный /etc/alsa/conf.d/*.confфайл, который определяет подходящие пользовательские имена устройств ALSA для ваших радиоустройств после их идентификации с помощью некоторого подходящего атрибута udev.


В документации ALSA есть старый пример того, как назначать номера устройств ALSA USB-устройствам по USB-порту, к которому они подключены:
https://alsa.opensrc.org/Udev#A_working_example

Он довольно сложен и требует компиляции небольшой программы, которая будет работать как помощник udev, и предназначен для обработки аудиовыхода, а не входных устройств, но он должен быть работоспособной отправной точкой. Он также включает некоторые функции, которые вам не нужны, например, настройку комбинированного выходного устройства, включающего все подключенные USB-звуковые устройства.

решение2

Самое простое решение — перезаписать idатрибут на основе пути USB.

Кажется, что самое простое решение — поместить это в /etc/udev/rules.d/99-myrules.conf:

SUBSYSTEM=="sound",KERNELS=="1-1.4.4:1.0",ATTR{id}="CODEC_7300"
SUBSYSTEM=="sound",KERNELS=="1-1.3.4:1.0",ATTR{id}="CODEC_9700"

Возьмите KERNELSfrom udevadm info -ap /sys/class/sound/controlC2, где 2находится индекс звуковой карты.

Выше приведен краткий ответ, который решает эту проблему для программ с раскрывающимся списком, отображающим идентификатор.

Хорошие вопросы и ответы в этих других темах:

Хотя это не устанавливает постоянный номер звуковой карты ALSA, это делает очевидным, что есть что aplay -l.

**** List of PLAYBACK Hardware Devices ****
[...]
card 2: CODEC_7300 [USB Audio CODEC], device 0: USB Audio [USB Audio]
  Subdevices: 1/1
  Subdevice #0: subdevice #0
card 3: CODEC_9700 [USB Audio CODEC], device 0: USB Audio [USB Audio]
  Subdevices: 1/1
  Subdevice #0: subdevice #0

Если вы хотите пойти дальше и получить согласованную нумерацию ALSA, вы можете создать набор символических ссылок. Например:

KERNEL=="controlC[0-9]*", DRIVERS=="usb", PROGRAM="/usr/bin/alsa_name.sh %k", SYMLINK+="%c"
KERNEL=="hwC[D0-9]*", DRIVERS=="usb", PROGRAM="/usr/bin/alsa_name.sh %k", SYMLINK+="%c"
KERNEL=="midiC[D0-9]*", DRIVERS=="usb", PROGRAM="/usr/bin/alsa_name.sh %k", SYMLINK+="%c"
KERNEL=="pcmC[D0-9cp]*", DRIVERS=="usb", PROGRAM="/usr/bin/alsa_name.sh %k", SYMLINK+="%c"

И иметь скрипт, который проверяет путь и возвращает подходящее имя. Например

#!/bin/bash
NAME="$1"
if echo "$DEVPATH" | grep 1-1.4; then
    NAME="$(echo "$NAME" | sed -r 's/(.*)C([0-9]+)(.*)/\1C11\3/')"
fi
if echo "$DEVPATH" | grep 1-1.3; then
    NAME="$(echo "$NAME" | sed -r 's/(.*)C([0-9]+)(.*)/\1C12\3/')"
fi
exec echo "snd/$NAME"

Затем вы можете создать согласованное устройство PulseAudio следующим образом:

N=11
DEV="radio-7300"
pacmd load-module module-alsa-card \
      device_id="${N}" name="${DEV}" \
      card_name="alsa_card.platform-${DEV}_audio" \
      namereg_fail=false tsched=no fixed_latency_range=no \
      ignore_dB=no deferred_volume=yes use_ucm=yes \
      card_properties="module-udev-detect.discovered=1"
pacmd suspend-sink alsa_output.${DEV}.analog-stereo no
pacmd suspend-source alsa_input.${DEV}.analog-stereo no


Связанный контент