私は USB 経由で Linux コンピューターに接続するアマチュア無線機をいくつか持っています。無線機はサウンド カードとして表示され、次のように表示されます。
$ 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
ここでの問題は、そのうちの 1 つと通信したいソフトウェアがあるが、それがどれなのかがわからないことです。ソフトウェア (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 がそれらを検出したタイミングによって決まります。最良のケースでは、それらを接続した順序になりますが、通常のケースでは、両方が接続され、同じ電源を使用しているため、電源をオンにすると同時に起動するため、競合状態になります。
では、異なる順序で検出された場合に毎回設定ファイルを編集したり、UI で設定を変更したりしなくても済むように、Linux でこれら 2 つのサウンド デバイスに一貫した名前を付けるにはどうすればよいでしょうか。
答え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
たとえば、ID_PATH
プロパティを使用して、無線が接続されている物理 USB ポートに基づいて無線を識別し、ENV{ID_ID}
それに基づいてプロパティを調整して、各無線のインターフェイスを一意に識別できるようにするカスタム udev ルールを作成できる可能性があります。
plughw:N,0
名前はALSA // デバイス名です.asoundrc
。/etc/alsa/conf.d
(arecord -L
注)大文字L)。このN
番号は udev 属性 と等しくATTR{number}
、 で表示されます udevadm info -q all -a -p /sys/class/sound/card<N>
。
plughw:CARD=<name>,DEV=0
OS のバージョンがそれほど古くない場合は、代わりにのような名前を使用できる可能性があります。<name>
の部分は udev 属性に基づいておりATTR{id}
、 で表示されますudevadm info -q all -a -p /sys/class/sound/card<N>
。
ATTR{number}
udev ルールによってまたは属性を変更できるかどうかは、ATTR{id}
システムにインストールされている udev のバージョンによって異なるようです。新しいバージョンの udev は古いバージョンよりも厳格であるように思われます。あるいは、新しいシステムにはより複雑な udev ルールセットがあり、それらを設定するための正しい方法がまだ見つかっていないだけかもしれません。
udevルールの順序は重要です。Linuxディストリビューションの既存のudevルールを調べて、独自のルールを設定して有効にする必要があるかどうかを調べる必要があるかもしれません。前にまたは後ルールを実際に有効にするには、ディストリビューションの標準ルールを にコピーする必要があります。古いディストリビューションでは、すべての udev ルールが 1 つのディレクトリにありました。最近のディストリビューションでは、/etc/udev/rules.d/
ローカルカスタマイズ用に が、システム標準ルールは にあります[/usr]/lib/udev/rules.d/
。
/etc/udev/rules.d/
最新のディストリビューションでは、システム標準ルール ディレクトリとの両方に同じ名前のルール ファイルが存在する場合、 のファイル/etc/udev/rules.d/
によって対応する標準ファイルが上書きされるため、標準ルール ディレクトリ内のファイルを変更する必要はまったくありません。また、パッケージの更新によってカスタマイズが上書きされることもありません。
ALSA の代替ソリューションとして、必要な udev 属性を変更できない場合は、/etc/alsa/conf.d/*.conf
適切な udev 属性で無線を識別した後、無線に適したカスタム ALSA デバイス名を定義するシステム全体のファイルを udev で生成することができます。
ALSA ドキュメントには、接続されている USB ポートによって USB デバイスに ALSA デバイス番号を割り当てる方法に関する古い例が記載されています。
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"
KERNELS
から を取得しますudevadm info -ap /sys/class/sound/controlC2
。 は2
オーディオ カードのインデックスです。
上記は短い答えであり、ID を公開するドロップダウンを持つプログラムの場合は問題を解決します。
以下の他のスレッドに良い質問と回答があります:
aplay -l
これにより、一貫した ALSA サウンド カード番号が設定されませんが、どのカードがどれであるかが明確になります。
**** 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