BobbyQuineのブログ(備忘録)

Linux関係の備忘録、その他タバコ、Vape関連なんかも。

Arch Linuxで、USBスピーカーを抜き刺ししたときに自動的に音声出力先を変える。

ども、BobbyQuineです。今までUSBスピーカーはWindowsマシンの方で使っていたのでとくには弄って無かったのですが、色々あってArchマシンの方で使うことになったのでちょいと弄ってみました。

 

※2019/01/14追記:/etc/asound.confを編集するように書かれていますがこれだとシステム全体に適応されます。また、後の方に書いてあるシェルスクリプトを実行するにはsudoが必要になってしまいます。なのでユーザーごとの設定ファイルである~/.asoundrcに読み替えたほうがよいかと思われます。

 

まずは以前やったこちらについて、

http://bobbyquine.hatenablog.com/entry/2018/01/29/225506

この " /etc/modprobe.d/alsa-base.conf "と言うファイルはいらないので削除します。

と言うか邪魔です。

 

$ sudo rm /etc/modprobe.d/alsa-base.conf

 

次にここ( Advanced Linux Sound Architecture - ArchWiki )を参考に " /etc/udev/rules.d/00-local.rules " を編集します。と言うかコピペです。

 

$ sudo vim /etc/udev/rules.d/00-local.rules

KERNEL=="pcmC[D0-9cp]*", ACTION=="add", PROGRAM="/bin/sh -c 'K=%k ; K=$${K#pcmC}; K=$${K%%D*}; echo defaults.ctl.card $$K > /etc/asound.conf; echo defaults.pcm.card $$K >>/etc/asound.conf'"
KERNEL=="pcmC[D0-9cp]*", ACTION=="remove", PROGRAM="/bin/sh -c 'echo defaults.ctl.card 0 > /etc/asound.conf; echo defaults.pcm.card 0 >>/etc/asound.conf'"

 

2018/10/17追記

上記設定だと、USBスピーカーをつないだまま再起動すると発生するデバイスナンバリングの変化に対応できないのでこうした。

 

KERNEL=="pcmC[D0-9cp]*", ACTION=="add", PROGRAM="/bin/sh -c 'cat /proc/asound/modules|grep usb|sed -e s/^/defaults.ctl.card/ -e s/\ snd_usb_audio// > /etc/asound.conf; cat /proc/asound/modules|grep usb|sed -e s/^/defaults.pcm.card/ -e s/\ snd_usb_audio// >>/etc/asound.conf'"
KERNEL=="pcmC[D0-9cp]*", ACTION=="remove", PROGRAM="/bin/sh -c 'cat /proc/asound/modules|grep intel|sed -e s/^/defaults.ctl.card/ -e s/\ snd_hda_intel// > /etc/asound.conf; cat /proc/asound/modules|grep intel|sed -e s/^/defaults.pcm.card/ -e s/\ snd_hda_intel// >>/etc/asound.conf'"

 

こういうところでシェル芸やってたのが役にたつね。

追記以上

 

まぁそのまんまですね。カーネルまわりはよく分からないのでアレですが要するにUSBサウンドカードが追加されたら " /etc/asound.conf " を編集してるってだけですね。

 

でもこれ、自動化したぶんCPU食ってるのよね、ってことでこんなものも作ってみた。

 

vim ~/Command/usbaudio

#!/bin/bash
if test $1 = "0" ;then
  echo "defaults.ctl.card 0" > /etc/asound.conf
  echo "defaults.pcm.card 0" >> /etc/asound.conf
  echo "set audio output Headphone"
else

 if cat /proc/asound/modules|grep 1 > /dev/null ; then
  echo "defaults.ctl.card 1" > /etc/asound.conf
  echo "defaults.pcm.card 1" >> /etc/asound.conf
  echo "set audio output USB Speaker"

 else
   echo "defaults.ctl.card 0" > /etc/asound.conf
   echo "defaults.pcm.card 0" >> /etc/asound.conf
   echo "set audio output Headphone"
  fi
fi

 

まぁUSBスピーカーを抜き差ししたときにこれ実行すれば出力デバイス変えてくれるよね、ってことで。しかもこいつを使えばUSBスピーカー刺した状態でも内蔵チップ出力に変えられる。

http://bobbyquine.hatenablog.com/entry/2018/03/24/164602

こんな風にコマンド化して

 

$ usbaudio 0

 

ってね。

 

ちなみに余談だけどこのシェルスクリプト入れ子のif文に使ってる条件式、

cat /proc/asound/modules|grep 1 > /dev/null

って部分、いつだったかツイッターで見かけて気に入って使ってるやり方。

順を追って説明すると

$ cat /proc/asound/modules

ってしたときにUSBスピーカーが刺さっていると当環境下だと

 0 snd_hda_intel
1 snd_usb_audio

って出力され、USBスピーカーが刺さってないと

 0 snd_hda_intel

って出力される。まぁ/dev化が監視されてて自動で書き換わるようにできてる(/proc下だから云々ってのはめんどいからry)。

んで、だ。こいつの標準出力をgrepに渡してやって " 1 " って条件で検索してやる。

で、検索結果は/dev/nullに捨てちゃう。欲しいのは処理が成功したか失敗したかだけだから。

USBスピーカーが刺さってればgrepは成功したとOS側に返す。刺さって無ければ失敗したって返す。これを横取りしてif文に渡してやればスピーカー刺さってる刺さってないが分けられる。

っていうかgrepって検索結果が無いときはエラーコード返してるのね、今回の収穫はそこだわ。

このやり方初めて見たときはめっちゃ感動したなぁ。

というわけでいつも通りグダグダな記事でした。