Linux raspberry Pi シェルコマンド シェルスクリプト

Raspberry Piに繋いだUSBスピーカーの音量・ミュートボタンを使えるようにする

USBスピーカーには2種類ある

Raspberry Piから音を出すときにUSBスピーカーを使うことがあります。

Raspberry Pi5のように音声出力端子が無いモデルでは、電源だけでなく、音声信号もUSBで送るタイプを使います。

USBスピーカーから音を出す設定は、sudo raspi-configで行うのが一番簡単です。Sysmtem optionsAudioUSB Audio Deviceを選択します。

USBスピーカーには音量調節用のツマミやボタンが付いた物があります。この音量調節の方式には2種類あります。

ひとつはUSBスピーカー自身のアンプのゲインを調節するタイプ。この場合はマイコン側は音声出力だけ考えれば良いので単純です。

私が使っている製品では、以下のものがそうです。

もうひとつは、スピーカー内蔵アンプのゲインは一定で、操作ボタンはマイコン側に押されたキーの情報を送っているだけの場合です。

今回使った以下の製品がこのタイプです。

手持ちのUSBスピーカーでは、ボタンを押して送られるのは、キーボードの音量調節キーと同じコードでした。

パソコンの場合は、OS側でUSBスピーカーへの出力や操作スイッチに対応しているので、繋ぐだけでキー操作に応じて音量が変わります。

しかし、Raspberry Piの場合は、ユーザー側でキー操作に対応して音量を変えるように設定する必要があります。(もしかすると、私がLITE版のRaspberry Pi OSを使っているせいかもしれませんが)

そんなわけで、以下は、Raspberry PiにUSBスピーカーを繋いで操作ボタンを有効化する手順の記録です。ChatGPTと相談しながら紆余曲折を経て成功しました。

apcidを使用してキー操作に対応したスクリプトを起動する

いくつかの方法があるようですが、今回はacpidを使った方法です。

acpid(Advanced Configuration and Power Interface daemon) は、Raspberry Pi や Linux がボタンやハードウェアイベントを受け取ったときに、任意の動作を実行するための仕組みです。

具体的には、次のようなイベントを監視します。

  • 電源ボタンを押した
  • 蓋を閉じた(ノートPC)
  • 音量ボタンを押した
  • ミュートボタンを押した
  • AC アダプタを抜いた/挿した

などの ACPI イベント を受け取り、対応するスクリプトを実行します。

作業ではイベントとそれに対応するスクリプトを登録します。

ちなみに、ChatGPTからは最初にudevを使った方法を提案されましたが、上手くいかなかったので、代替案としてacpidを使用しました。

手順

1.接続したUSBスピーカーが認識されているかの確認

aplay -l

**** ハードウェアデバイス PLAYBACK のリスト ****
カード 0: Headphones [bcm2835 Headphones], デバイス 0: bcm2835 Headphones [bcm2835 Headphones]
  サブデバイス: 8/8
  サブデバイス #0: subdevice #0
  サブデバイス #1: subdevice #1
  サブデバイス #2: subdevice #2
  サブデバイス #3: subdevice #3
  サブデバイス #4: subdevice #4
  サブデバイス #5: subdevice #5
  サブデバイス #6: subdevice #6
  サブデバイス #7: subdevice #7
カード 1: Device [MosArt USB Audio Device], デバイス 0: USB Audio [USB Audio]
  サブデバイス: 1/1
  サブデバイス #0: subdevice #0
カード 2: vc4hdmi [vc4-hdmi], デバイス 0: MAI PCM i2s-hifi-0 [MAI PCM i2s-hifi-0]
  サブデバイス: 1/1
  サブデバイス #0: subdevice #0

USBスピーカーの繋がっているカード番号を控えておく。この場合は"カード1"。

音量を制御できるコントロール名を確認

amixer -c 1 scontrols

Simple mixer control 'PCM',0

この場合は"PCM"

acpid の導入と起動

sudo apt update
sudo apt install -y acpid acpi-support-base
sudo systemctl enable acpid
sudo systemctl start acpid

イベント名の確認

sudo systemctl stop acpid

sudo acpid -d -f -l

ボタンを押すとイベント名が
received input layer event "button/volumedown VOLDN 00000080 00000000 K"
のような形で出る。"button/volumedown"がイベント名。

後でACPIイベント定義で使う。

ACPI イベント定義(イベント別ファイルを作成)

# Volume Up
sudo tee /etc/acpi/events/usb-volup >/dev/null <<'EOF'
event=^button/volumeup
action=/etc/acpi/usb-volup.sh
EOF

# Volume Down
sudo tee /etc/acpi/events/usb-voldown >/dev/null <<'EOF'
event=^button/volumedown
action=/etc/acpi/usb-voldown.sh
EOF

# Mute
sudo tee /etc/acpi/events/usb-mute >/dev/null <<'EOF'
event=^button/mute
action=/etc/acpi/usb-mute.sh
EOF

event=の文は、部分一致でないと上手く動かないことがある。これでもうまくマッチしない個体では event=^button/volumeup.* のように末尾に .* を付けると動くかもしれない。

実行スクリプトを作成(amixer をフルパスで呼ぶ)

注1:-c 1 は USB スピーカーが card 1 の前提。違う場合は番号を合わせてください。
注2:PCMamixer -c 1 scontrolsで調べたコントロール名。個体によって MasterSpeaker など他の名前の場合がある。

# 音量ステップ(%)は必要に応じて変更可(例:5 → 3)
STEP=5

# volup
sudo tee /etc/acpi/usb-volup.sh >/dev/null <<'EOF'
#!/bin/bash
/usr/bin/amixer -q -c 1 set PCM 5%+
EOF

# voldown
sudo tee /etc/acpi/usb-voldown.sh >/dev/null <<'EOF'
#!/bin/bash
/usr/bin/amixer -q -c 1 set PCM 5%-
EOF

# mute
sudo tee /etc/acpi/usb-mute.sh >/dev/null <<'EOF'
#!/bin/bash
/usr/bin/amixer -q -c 1 set PCM toggle
EOF

# 実行権限
sudo chmod +x /etc/acpi/usb-*.sh

acpid を再起動

sudo systemctl restart acpid

動作確認

# 再生(例)
aplay -D plughw:1,0 /usr/share/sounds/alsa/Front_Center.wav

再生しながらキーを操作して音量が変われば成功。

うまく行かなかったらChatGPTに相談しましょう。

-Linux, raspberry Pi, シェルコマンド, シェルスクリプト