スマートフォンなどの音源を、Bluetooth経由でラズベリーパイ3からならす。 OSはいつもどおりyoctoprojectを使用して作成。
BluetoothではA2DPを使用し、sinkとなるようにする。 実際に音を鳴らすのはpulseaudioで、ラズベリーパイ3が他の端末からオーディオに見えるようにするための設定も pulseaudioのbluetooth-discoverモジュールで行う。
そのため、bluez5自体の設定ファイルはいらない。
ラズベリーパイ3上でBluetoothで接続された音源と音を鳴らすためのデバイスをloopbackしたり、経路を作る必要があり、 よそのサイトではこの部分にudevのルールを書いたりpythonでスクリプトを書いたりしているのを見かけたが、 これもpulseaudioのbluetooth-policyモジュールで行うため今回は不要。
使用するyoctoprojectのバージョンはpyro(2.3) すでにrocko(2.4)が出ているが、今回は古いので行く。
環境構築
ソースの取得
$ git clone git://git.yoctoproject.org/poky.git -b pyro $ git clone git://git.openembedded.org/meta-openembedded -b pyro $ git clone git://git.yoctoproject.org/meta-raspberrypi -b pyro
環境変数設定
$ cd .. $ source poky/oe-init-build-env
ビルド対象のレイヤを追加
$ bitbake-layers add-layer ../poky/meta-raspberrypi $ bitbake-layers add-layer ../poky/meta-openembedded/meta-oe $ bitbake-layers add-layer ../poky/meta-openembedded/meta-python
local.confの変更
下記をlocal.confに追加する
MACHINE = "raspberrypi3" # systemd DISTRO_FEATURES_append = " systemd" VIRTUAL-RUNTIME_init_manager = "systemd" DISTRO_FEATURES_BACKFILL_CONSIDERED = "sysvinit" VIRTUAL-RUNTIME_initscripts = "" IMAGE_INSTALL_append = " systemd-bash-completion \ " # pulseaudio DISTRO_FEATURES_append = " pulseaudio pam" IMAGE_INSTALL_append = " pulseaudio \ pulseaudio-server \ pulseaudio-misc \ pulseaudio-module-systemd-login \ pulseaudio-module-bluez5-discover \ pulseaudio-module-bluez5-device \ pulseaudio-module-bluetooth-policy \ pulseaudio-module-bluetooth-discover \ pulseaudio-module-loopback \ pulseaudio-bash-completion \ " # bluez5 IMAGE_INSTALL_append = " bluez5" IMAGE_INSTALL_append = " bluez5-testtools" # connman IMAGE_INSTALL_append = " connman connman-client" # avahi IMAGE_INSTALL_append = " avahi-daemon" FETCHCMD_wget = "/usr/bin/env wget -t 2 -T 3000 -nv --passive-ftp --no-check-certificate" # automount DISTRO_FEATURES_append = " automount" # util-linux IMAGE_INSTALL_append = " util-linux-bash-completion \ util-linux-lsblk" # Enable UART for debug console ENABLE_UART = "1" # ALSA IMAGE_INSTALL_append = " alsa-utils \ alsa-utils-speakertest \ " # sudo IMAGE_INSTALL_append = " sudo"
若干不要なパッケージや設定も含まれているが気にしない。
pulseaudioのbluetoothモジュールのロード設定
/etc/pulse/system.pa
に下記を追加
### Automatically load driver modules for Bluetooth hardware .ifexists module-bluetooth-policy.so load-module module-bluetooth-policy .endif .ifexists module-bluetooth-discover.so load-module module-bluetooth-discover .endif
今回のケースでは、module-bluetooth-discoverはBluetoothの設定を自動化し module-bluetooth-policyはa2dp_sourceとsinkのloopbackを自動化する。
pulseaudioのシステムサーバ化
/etc/systemd/system/pulseaudio.service
を下記の内容で作成
[Unit] Description=PulseAudio system server [Service] Type=notify ExecStart=/usr/bin/pulseaudio --daemonize=no --system --realtime --log-target=journal [Install] WantedBy=multi-user.target
サービスの登録、起動
$ systemctl --system enable pulseaudio.service $ systemctl --system start pulseaudio.service
dbus設定
/etc/dbus-1/system.d/pulseaudio-system.conf
に下記の行を追加
<busconfig> <!-- System-wide PulseAudio runs as 'pulse' user. This fragment is not necessary for user PulseAudio instances. --> <policy user="pulse"> <allow own="org.pulseaudio.Server"/> + <allow send_destination="org.bluez"/> + <allow send_interface="org.bluez.Manager"/> </policy> </busconfig>
pactlの使い方
sudo でpulseユーザーを指定して実行する
$ sudo -u pulse pactl list short sinks
blueoothの設定
discoverableを有効にする。
$ connmanctl enable bluetooth $ bluetoothctl > power on > discoverable on > agent on > quit
ここまででペアリング可能になる。
このままではAccessDeniedが発生し接続できないが、相手のデバイスをtrustすることで接続できるようになる。
自動化
bluetoothctlではバッチ処理に不向であることと、相手のデバイスをtrustする手順が煩雑になるため、 bluez5-testtoolsに含まれるスクリプトを使用し、ある程度自動化できるようにする。
まずはバグフィックス
$ cd /usr/lib/bluez/test/ $ find -type f | xargs sed -i 's/iteritems/items/g'
次のコマンドを実行する。
$ cd /usr/lib/bluez/test $ ./test-adapter discoverable on $ ./simple-agent -c NoInputNoOutput
simple-agentがtrustまで行ってくれるので、bluetoothctlの手順よりも多少は簡略化できる。 これでも、相手とのペアリングのタイミングでプロンプトがでるため、完全にヘッドレスでの運用はできない。 一度、接続が成功し相手の端末に接続設定が保存されてしまえば、ヘッドレス運用もできると思う。
その場合はシステム起動時にsimple-agentを起動し、 GPIOで物理ボタンなどをつけて、押されたタイミングでdiscoverable onを行うなど工夫が必要になる。
内蔵オーディオについて
ラズベリーパイ内蔵のオーディオを使用するためにはsnd_bcm2835
ドライバを組み込む必要がある。
SDカードのブートパーティションにあるconfig.txtに下記を追加すると、ブート時にドライバが組み込まれるようになる。
dtparam=audio=on
まとめ
ここまでの設定を行った後で再起動してsimple-agentを立ち上げると、 スマートフォンやipodなどとBluetoothで接続して、音源を鳴らすことが出来るようになる。