#ChiroruLab

趣味と日々の雑記録

【2021】Raspberry PiでBluetooth(A2DP)オーディオレシーバーを作る


起動しない、繋がらない、音が出ない、出てもぶつぶつノイズと大遅延。
ggってもサイトごとに対処が違う、真似しても治らない、そもそもソースが少ない。
そんな絶望的状況から30回以上のクリーンインストールを得て、やっとたどり着いた最適解。

備忘録としてここに残します。



全面的に参考にさせて頂いたサイト群

Raspberry Pi で Bluetooth レシーバー (オーディオ:A2DP) を作成するための設定方法解説 - 公開技術情報
Raspberry Piを使って無線ヘッドホンを複数入力から同時に出力出来るようにする | Developers.IO
Bluetooth, BlueALSA and Buster
Using a USB Audio Device with the Raspberry Pi - Raspberry Pi Spy
Raspberry Pi | 合成音声をUSBスピーカーから出力したい!(ハマったポイント) – たぷん日記
Raspberry piをbluetoothスピーカーにする – ぷちのいず
※特に一番最後の記事が参考になったため、ほぼその手順通りです。


環境

  • 2021-01-11-raspios-buster-armhf
  • RaspberryPi Model 3B+
  • SSDブート
    • Raspberry Pi Imagerを使って作成→balenaetcherだと起動しない場合がある

用語の整理

  • Bluez Bluetoothを使うのに必要な説明書
  • A2DP Bluetoothプロファイルの一種、音声データの通信に使う
  • PulseAudio バックグラウンドで動作し、音声入出力を行うサーバ。
  • ALSA スピーカーに信号を送るためのサウンドシステム

動作のイメージ

Bluetoothモジュールから入ったデータが、BluezからPulseAudioに伝わり、処理されたデータがALSAを経由してスピーカーを鳴らす

ただしBluez単体では、A2DPをサポートしていないため、別途A2DPを読み込むためのプラグインが必要になる。
そこで出てくるのが、以下のプラグインになるが、ラズパイのOSによって安定性がことなる。

Stretch以前の場合は、前者で対応できたが、Buster以降は遅延とぶちぶちとノイズが酷い。Bluealsaであれば、0.数秒程度の遅延で安定動作する。
これは設定を見直せばもう少し改善するかもしれないが、試行錯誤した結果力尽きた。

ぼくのかんがえたさいきょうの構成

WebOS搭載プロジェクターで動画を再生し、bluetooth接続したラズパイから、USBDAC経由でアンプへ音声出力。
ラズパイにはHomebridgeを構築し、音量調節などをiPhoneで行う。

背景

  1. Raspbian StretchからBuster(Raspberry Pi OS)に更新したところ動作が不安定になり、再インストールしたところ音が出ない、ぶちぶち切れる、5秒以上遅延が起きるなどまともに使えなくなった
  2. 以前がSD+SSDブート環境だったため純粋なSSDブートで使いたかった
  3. 自粛で暇なのでRasPi(Linux)の仕組みを少し勉強したかった


導入方法

初期設定

インストーラーに沿って言語やパスワードの設定を済ませ、その後メニューからSSHを有効にする。

$ sudo nano /etc/ssh/sshd_config
#ポート番号変更
Port XXXXX

# sshを再起動
$ sudo /etc/init.d/ssh restart

必要なファイルのインストール、設定など

  • SSHで接続してコピペしながら行う

$ ssh -p ポート番号 pi@IPアドレス

PulseAudio関連

PulseAudioのインストール(busterであればインスール済み、一応実行)

$ sudo apt install pulseaudio pulseaudio-utils

PulseAudioのデーモンを作り自動起動に登録

$ sudo nano /etc/systemd/system/pulseaudio.service
[Unit] 
Description=Pulse Audio 

[Service] 
Type=simple 
ExecStart=/usr/bin/pulseaudio --system --disallow-exit --disable-shm

[Install]
WantedBy=multi-user.target

$ sudo systemctl start pulseaudio.service
$ sudo systemctl enable pulseaudio.service


PulseAudioにアクセスできるユーザを追加

$ sudo usermod -a -G pulse-access pi
$ sudo usermod -a -G pulse-access root


PulseAudioデーモンが不意に起動しないように設定する

$ sudo nano /etc/pulse/client.conf
#最後に追加
default-server = /var/run/pulse/native


Pulseaudioを強制的にステレオ出力に変更する

$ sudo nano /usr/share/pulseaudio/alsa-mixer/profile-sets/default.conf
[Mapping analog-stereo]
;device-strings = front:%f         # 変更前
device-strings = front:%f hw:%f    # 変更後

ノイズと音飛び対策

$ sudo nano /etc/pulse/daemon.conf
resample-method = trivial
default-fragments = 8
default-fragment-size-msec = 125


bluealsa関連

bluealsaをインストールし、オプションを指定してA2DPを有効化

$ sudo apt install bluealsa
$ sudo nano /lib/systemd/system/bluealsa.service
[Service]
# ExecStart=/usr/bin/bluealsa
ExecStart=/usr/bin/bluealsa -p a2dp-sink

$ sudo systemctl restart bluealsa.service
$ sudo bluetoothctl show
#UUID: Audio Sinkが表示されればおk


bluealsa-aplayを起動し再生できるようにするサービスを作る

$ sudo nano /etc/systemd/system/bluealsa-aplay.service
[Unit]
Description=BlueALSA aplay service
After=bluetooth.service
Requires=bluetooth.service

[Service]
ExecStart=/usr/bin/bluealsa-aplay 00:00:00:00:00:00

[Install]
WantedBy=multi-user.target


自動起動に登録

$ sudo systemctl start bluealsa-aplay.service
$ sudo systemctl enable bluealsa-aplay.service


Bluetooth関連

初期値ではペアリングできないクライアントがあるためクラスを指定

$ sudo nano /etc/bluetooth/main.conf
Class = 0x240404


デフォルトだとエラーが出るので対処

$ sudo nano /lib/systemd/system/bluetooth.service
#ExecStart=/usr/lib/bluetooth/bluetoothd
ExecStart=/usr/lib/bluetooth/bluetoothd --noplugin=sap

$ sudo nano /lib/systemd/system/bthelper@.service
[Service]
Type=simple
ExecStartPre=/bin/sleep 2 #追加
ExecStart=/usr/bin/bthelper %I


Wi-Fiが有効だと干渉してノイズがのる(らしい)ので、メニューバーのアイコンからオフにする(Wi-Fiを使わない場合)

  • ネットワークアイコンをクリックし「Turn Off Wi-Fi」で切り替え


ペアリングし音が出るか確認する

  1. Bluetoothアイコンをクリックし、make discoverable
  2. クライアント側に"raspberrypi"が表示されたら選択し、認証画面がでたらそのまま接続
  3. 適当にYouTubeでも流して問題なく音が流れれば完了


Homebridge関連

公式を参考にHomebridgeを構築し、プラグインでhomebridge-pc-volumeを入れる
github.com

PulseAudioにアクセスできるようにユーザを追加

$ sudo usermod -a -G pulse-access homebridge

iPhoneでブリッジを登録して、アクセサリーからインジケータを調整して音量が変われば完了



適当にアップデートはするもんじゃない・・・

いい勉強になった。これで安心してNetflixなりYouTubeなり見れるね。
以上、@chiroru_27 でした。

デモ用動画

https://www.youtube.com/watch?v=OaO8xKEL-Jc