USBスピーカーには2種類ある
Raspberry Piから音を出すときにUSBスピーカーを使うことがあります。
Raspberry Pi5のように音声出力端子が無いモデルでは、電源だけでなく、音声信号もUSBで送るタイプを使います。
USBスピーカーから音を出す設定は、sudo raspi-configで行うのが一番簡単です。Sysmtem optionsのAudioでUSB 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:PCM はamixer -c 1 scontrolsで調べたコントロール名。個体によって Master や Speaker など他の名前の場合がある。
# 音量ステップ(%)は必要に応じて変更可(例: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に相談しましょう。