¿Cómo nombro consistentemente los dispositivos de audio?

¿Cómo nombro consistentemente los dispositivos de audio?

Tengo un par de radioaficionados que conecto a mi computadora Linux a través de USB. Las radios se presentan como tarjetas de sonido y son visibles así:

$ 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

Aparecen en USB como:

$ 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

El problema aquí es que tengo un software que quiere hablar con uno de ellos, pero no sabe cuál. El software (js8call y wsjtx) simplemente me permite seleccionar el nombre de un menú desplegable y recuerda el nombre elegido.

Los nombres en este menú desplegable son:

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

Otro software (por ejemplo, direwolf) quiere el dispositivo en formato "plughw:2,0", mientras que la otra radio es "plughw:1,0".

Pero no es consistente cuál es cuál. Depende de cuando Linux los detectó, que en el mejor de los casos es el orden en que los conecté, y en el caso normal es una condición de carrera, ya que ambos están enchufados y están usando la misma fuente de alimentación, por lo que arrancan en al mismo tiempo cuando enciendo la alimentación.

Entonces, ¿cómo puedo hacer para que Linux nombre estos dos dispositivos de sonido de manera consistente, de modo que no tenga que editar archivos de configuración y cambiar las configuraciones en una interfaz de usuario cada vez que se hayan detectado en un orden diferente?

Respuesta1

Los nombres en el menú desplegable se parecen a los nombres de fuentes de PulseAudio: consulte pacmd dump. Incluirían un número de serie del dispositivo de sonido USB que se encuentra en el descriptor de dispositivo USB estándar (ver lsusb -d 08bb:2901 -v | grep iSerial). Si las radios no tienen un identificador único detectable por Linux, puede resultar complicado darles nombres consistentes.

Los nombres de PulseAudio parecen generarse en función de la ID_IDpropiedad; consulte udevadm info -q property -p /sys/class/sound/card<N>dónde <N>está el número del dispositivo de sonido en cuestión (comenzando desde card0).

Es posible que pueda crear una regla udev personalizada que utilice, por ejemplo, la ID_PATHpropiedad para identificar las radios en función del puerto USB físico al que están conectadas y ajustar la ENV{ID_ID}propiedad en función de eso para permitir que la interfaz de cada radio se identifique de forma única.


plughw:N,0Los nombres son ALSA // .asoundrcnombres /etc/alsa/conf.dde dispositivos, consulte arecord -L(notamayúsculasl). El Nnúmero es igual al atributo udev ATTR{number}, visible con udevadm info -q all -a -p /sys/class/sound/card<N>.

Es posible que puedas utilizar nombres como plughw:CARD=<name>,DEV=0si la versión del sistema operativo no es demasiado antigua. La <name>parte se basa en el atributo udev ATTR{id}, visible con udevadm info -q all -a -p /sys/class/sound/card<N>.

El hecho de que pueda o no modificar los atributos ATTR{number}o ATTR{id}mediante las reglas de udev parece depender de la versión de udev que tenga su sistema: las versiones más nuevas de udev parecen ser más estrictas que las anteriores, o tal vez los sistemas más nuevos tienen conjuntos de reglas de udev más complicados y yo simplemente tengo No encontré la forma correcta de configurarlos.

El orden de las reglas udev es importante: es posible que necesites estudiar las reglas udev existentes en tu distribución de Linux para saber si debes establecer tus propias reglas para activarlas.antesodespuéslas reglas estándar de la distribución para que sus reglas realmente entren en vigor. Las distribuciones antiguas solían tener todas las reglas de udev en un solo directorio: las modernas las tienen /etc/udev/rules.d/para personalizaciones locales, mientras que las reglas estándar del sistema se encuentran en [/usr]/lib/udev/rules.d/.

Con las distribuciones modernas, si existe un archivo de reglas con el mismo nombre tanto en /etc/udev/rules.d/como en el directorio de reglas estándar del sistema, el archivo /etc/udev/rules.d/anulará el archivo estándar correspondiente, por lo que nunca debería necesitar modificar ningún archivo en el directorio de reglas estándar. . Por lo tanto, las actualizaciones de paquetes tampoco sobrescribirán nunca sus personalizaciones.

Como solución alternativa para ALSA, si descubre que no puede modificar los atributos udev requeridos, puede hacer que udev genere un /etc/alsa/conf.d/*.confarchivo para todo el sistema, que defina nombres de dispositivos ALSA personalizados adecuados para sus radios después de identificarlos mediante algún atributo udev adecuado.


La documentación de ALSA tiene un ejemplo antiguo sobre cómo asignar números de dispositivo ALSA a dispositivos USB por puerto USB al que están conectados:
https://alsa.opensrc.org/Udev#A_working_example

Es bastante complejo y requiere compilar un pequeño programa para que actúe como ayudante de udev, y está diseñado para manejar salida de audio en lugar de dispositivos de entrada, pero debería ser un punto de partida viable. También incluye algunas funciones que no necesita, es decir, configurar un dispositivo de salida combinado que incluye todos los dispositivos de sonido USB conectados.

Respuesta2

La solución más sencilla es sobrescribir el idatributo según la ruta USB.

Parece que la solución sencilla es colocar esto en /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"

Tome el KERNELSorigen udevadm info -ap /sys/class/sound/controlC2, donde 2está el índice de la tarjeta de audio.

Lo anterior es la respuesta corta y la resuelve para programas con un menú desplegable que expone la ID.

Buenas preguntas y respuestas en estos otros hilos:

Si bien esto no establece un número consistente de tarjeta de sonido ALSA, sí deja claro cuál es cuál. Por 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

Si desea ir más allá y obtener una numeración ALSA coherente, puede crear un conjunto de enlaces simbólicos. P.ej

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"

Y tenga un script que verifique la ruta y devuelva un nombre adecuado. P.ej

#!/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"

Luego puedes crear un dispositivo PulseAudio consistente así:

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


información relacionada