Ich habe ein paar Amateurfunkgeräte, die ich über USB an meinen Linux-Computer anschließe. Die Funkgeräte stellen sich als Soundkarten dar und sind folgendermaßen sichtbar:
$ 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
Sie werden auf dem USB wie folgt angezeigt:
$ 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
Das Problem dabei ist, dass ich eine Software habe, die mit einem von ihnen sprechen möchte, aber nicht weiß, mit welchem. Die Software (js8call und wsjtx) erlaubt mir einfach, den Namen aus einer Dropdown-Liste auszuwählen, und merkt sich den gewählten Namen.
Die Namen in dieser Dropdown-Liste sind:
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
Andere Software (z. B. Direwolf) möchte das Gerät im Format „plughw:2,0“, während das andere Radio „plughw:1,0“ ist.
Aber es ist nicht einheitlich, was was ist. Es hängt davon ab, wann Linux sie erkannt hat, was im besten Fall die Reihenfolge ist, in der ich sie eingesteckt habe, und im Normalfall ist es ein Race Condition, da beide eingesteckt sind und dasselbe Netzteil verwenden, sodass sie gleichzeitig hochfahren, wenn ich den Strom einschalte.
Wie kann ich also erreichen, dass Linux diese beiden Soundgeräte einheitlich benennt, sodass ich nicht jedes Mal, wenn sie in einer anderen Reihenfolge erkannt werden, Konfigurationsdateien bearbeiten und Einstellungen in einer Benutzeroberfläche ändern muss?
Antwort1
Die Namen in der Dropdown-Liste sehen aus wie PulseAudio-Quellnamen: siehe pacmd dump
. Sie würden eine Seriennummer des USB-Soundgeräts enthalten, das im Standard-USB-Gerätedeskriptor vorhanden ist (siehe lsusb -d 08bb:2901 -v | grep iSerial
). Wenn die Radios keine eindeutige, von Linux erkennbare Kennung haben, kann es schwierig sein, ihnen einheitliche Namen zu geben.
ID_ID
Die PulseAudio-Namen scheinen basierend auf der Eigenschaft generiert zu werden . Sehen Sie udevadm info -q property -p /sys/class/sound/card<N>
, wo <N>
sich die Nummer des betreffenden Soundgeräts befindet (beginnend bei card0
).
Möglicherweise können Sie eine benutzerdefinierte Udev-Regel erstellen, die beispielsweise die ID_PATH
Eigenschaft zum Identifizieren der Funkgeräte basierend auf dem physischen USB-Anschluss verwendet, an den sie angeschlossen sind, und die ENV{ID_ID}
Eigenschaft basierend darauf anpassen, um eine eindeutige Identifizierung der Schnittstelle jedes Funkgeräts zu ermöglichen.
plughw:N,0
Namen sind ALSA / .asoundrc
/ /etc/alsa/conf.d
Gerätenamen, siehe arecord -L
(HinweisGroßbuchstabenL). Die N
Nummer entspricht dem udev-Attribut ATTR{number}
, sichtbar mit udevadm info -q all -a -p /sys/class/sound/card<N>
.
plughw:CARD=<name>,DEV=0
Wenn die Betriebssystemversion nicht zu alt ist, können Sie stattdessen möglicherweise Namen wie verwenden . Der <name>
Teil basiert auf dem Udev-Attribut ATTR{id}
und ist mit sichtbar udevadm info -q all -a -p /sys/class/sound/card<N>
.
Ob Sie die ATTR{number}
- oder ATTR{id}
-Attribute mithilfe von Udev-Regeln ändern können, scheint davon abzuhängen, über welche Udev-Version Ihr System verfügt: Die neueren Versionen von Udev scheinen strenger zu sein als ältere, oder möglicherweise verfügen neuere Systeme über kompliziertere Udev-Regelsätze und ich habe einfach noch nicht die richtige Möglichkeit gefunden, diese festzulegen.
Die Reihenfolge der udev-Regeln ist wichtig: Sie müssen möglicherweise die vorhandenen udev-Regeln Ihrer Linux-Distribution studieren, um herauszufinden, ob Sie Ihre eigenen Regeln festlegen sollten, umVorodernachdie Standardregeln der Distribution, damit Ihre Regeln tatsächlich wirksam werden. Alte Distributionen hatten alle udev-Regeln in einem einzigen Verzeichnis: Moderne Distributionen haben . /etc/udev/rules.d/
für lokale Anpassungen, während die Standardregeln des Systems in liegen [/usr]/lib/udev/rules.d/
.
Wenn bei modernen Distributionen eine Regeldatei mit demselben Namen sowohl im /etc/udev/rules.d/
als auch im Standardregelverzeichnis des Systems vorhanden ist, /etc/udev/rules.d/
überschreibt die Datei dort die entsprechende Standarddatei. Sie müssen daher niemals Dateien im Standardregelverzeichnis ändern ... und Ihre Anpassungen werden auch niemals durch Paketaktualisierungen überschrieben.
Wenn Sie feststellen, dass Sie die erforderlichen Udev-Attribute nicht ändern können, können Sie als alternative Lösung für ALSA udev so einrichten, dass es eine systemweite /etc/alsa/conf.d/*.conf
Datei für Sie generiert, die geeignete benutzerdefinierte ALSA-Gerätenamen für Ihre Radios definiert, nachdem diese durch ein geeignetes Udev-Attribut identifiziert wurden.
In der ALSA-Dokumentation finden Sie ein altes Beispiel für die Zuweisung von ALSA-Gerätenummern zu USB-Geräten anhand des USB-Anschlusses, an den sie angeschlossen sind:
https://alsa.opensrc.org/Udev#A_working_example
Es ist ziemlich komplex und erfordert die Kompilierung eines kleinen Programms, das als Udev-Helfer fungiert. Es ist für die Handhabung von Audioausgaben und nicht von Eingabegeräten konzipiert, sollte aber ein brauchbarer Ausgangspunkt sein. Es enthält auch einige Funktionen, die Sie nicht benötigen, z. B. das Einrichten eines kombinierten Ausgabegeräts, das alle angeschlossenen USB-Soundgeräte umfasst.
Antwort2
Die einfachste Lösung besteht darin, das id
Attribut basierend auf dem USB-Pfad zu überschreiben.
Die einfache Lösung scheint darin zu bestehen, dies hier einzufügen /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"
Nehmen Sie das KERNELS
von udevadm info -ap /sys/class/sound/controlC2
, wobei 2
der Index der Audiokarte ist.
Das Obige ist die kurze Antwort und löst das Problem für Programme mit einem Dropdown-Menü, das die ID anzeigt.
Gute Fragen und Antworten in diesen anderen Threads:
- Gleicher Gerätename für identische USB-Soundkarten nach jedem Neustart
- Udev-Regeln für scheinbar nicht unterscheidbare Geräte
Dadurch wird zwar keine einheitliche ALSA-Soundkartennummer festgelegt, es ist jedoch klar, welche welche ist. Per 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
Wenn Sie noch weiter gehen und eine konsistente ALSA-Nummerierung erreichen möchten, können Sie einen Satz symbolischer Links erstellen. Beispiel:
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"
Und haben Sie ein Skript, das den Pfad überprüft und einen passenden Namen zurückgibt. Beispiel:
#!/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"
Sie können dann ein konsistentes PulseAudio-Gerät wie folgt erstellen:
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