Raspbian を LDAC と AAC に対応させる備忘録です.
はじめに
Raspbian on Raspberry pi zero WH を LDAC, apt-X HD, apt-X, AAC などの高音質なコーデックに対応させてみた覚え書きです.
Ubuntu とか Fedora などの x86 な環境だとパッケージが
に公開されているので,これをインストールするだけで済むのですが,残念ながら arm な Raspbian 向けのものはありません.しかし,
にソースコードは公開されていますので,これを利用して使えるようになるまでの覚え書きです.なお,Raspbian 以外の例えば armbian とかでもところどころ適切に読み替えすれば同じように対応できるとは思いますが,実際に試してはいません.また,以下の手順は Rasbian の導入と初期設定から記していますので,導入済みの方は読み飛ばして下さい.
Raspbian の ver. と microSD への書き込み
使ったのは本記事執筆時点の最新の Raspbian Buster Lite のイメージ(2020年2月13日公開のもの)です.Buster なら以前のものでもアップデートさえすれば大丈夫だと思いますが,Buster 以前の Jessie とかのものだと pulseaudio とか Bluez の ver. が古くてダメだと思います.
なお,以下の手順は全て elementary OS (Ubuntu) のものです.Windows とか MacOS とかの場合をお知りになりたい方は色々なところに手順が紹介されていますので,そちらを参照されてください.
まず,Raspbian のイメージを取得します.念の為チェックサムも確認しています.
$ wget https://downloads.raspberrypi.org/raspbian_lite/images/raspbian_lite-2020-02-14/2020-02-13-raspbian-buster-lite.zip $ diff <(sha256sum 2020-02-13-raspbian-buster-lite.zip| cut -d" " -f1) <(echo 12ae6e17bf95b6ba83beca61e7394e7411b45eba7e6a520f434b0748ea7370e8) $ unzip 2020-02-13-raspbian-buster-lite.zip
次に,microSD に Raspbian のイメージを書き込みますが,書き込み先を間違わないようにして下さい(私の場合は /dev/sdb ですがこれはシステムによって色々だと思います).
$ df -h Filesystem Size Used Avail Use% Mounted on udev 1.9G 0 1.9G 0% /dev tmpfs 389M 12M 378M 3% /run /dev/sda2 111G 51G 54G 49% / tmpfs 1.9G 77M 1.9G 4% /dev/shm tmpfs 5.0M 4.0K 5.0M 1% /run/lock tmpfs 1.9G 0 1.9G 0% /sys/fs/cgroup /dev/loop0 55M 55M 0 100% /snap/core18/1668 /dev/loop2 55M 55M 0 100% /snap/core18/1650 /dev/loop1 90M 90M 0 100% /snap/core/8268 /dev/loop3 92M 92M 0 100% /snap/core/8592 /dev/sda1 511M 5.9M 506M 2% /boot/efi tmpfs 389M 88K 389M 1% /run/user/1000 /dev/sdb1 60G 66M 60G 1% /media/(userhomedir)/SD_CARD $ sudo dd bs=4M if=2020-02-13-raspbian-buster-lite.img of=/dev/sdb 441+0 レコード入力 441+0 レコード出力 1849688064 bytes (1.8 GB, 1.7 GiB) copied, 48.8144 s, 37.9 MB/s
Raspbian の初期設定
Raspberry pi zero WH にキーボードやモニターを接続するのは面倒なので,ヘッドレスのまま作業できるよう USB OTG 経由でアクセスできるように設定します.
elementary OS の場合は標準のファイルマネージャーから以下のように microSD の boot パーティションを簡単に /media/(userhomedir) 以下にマウントできますが,boot パーティションは FAT16 フォーマットなのでその他の OS の場合も簡単に参照できると思います.
$ df -h Filesystem Size Used Avail Use% Mounted on udev 1.9G 0 1.9G 0% /dev tmpfs 389M 12M 378M 3% /run /dev/sda2 111G 53G 53G 51% / tmpfs 1.9G 75M 1.9G 4% /dev/shm tmpfs 5.0M 4.0K 5.0M 1% /run/lock tmpfs 1.9G 0 1.9G 0% /sys/fs/cgroup /dev/loop0 55M 55M 0 100% /snap/core18/1668 /dev/loop2 55M 55M 0 100% /snap/core18/1650 /dev/loop1 90M 90M 0 100% /snap/core/8268 /dev/loop3 92M 92M 0 100% /snap/core/8592 /dev/sda1 511M 5.9M 506M 2% /boot/efi tmpfs 389M 80K 389M 1% /run/user/1000 /dev/sdb1 253M 53M 200M 21% /media/(userhomedir)/boot /dev/sdb2 1.5G 1.1G 276M 80% /media/(userhomedir)/rootfs
USB-OTG でアクセスできるようにするために,/boot/config.txt に dtoverlay=dwc2 を, /boot/cmdline.txt に modules-load=dwc2,g_ether を以下のように追記します.また,空の /boot/ssh を作り,ssh 経由でアクセスできるよう設定します.
$ echo "dtoverlay=dwc2" >> /media/(userhomedir)/boot/config.txt $ vi /media/(userhomedir)/boot/cmdline.txt console=serial0,115200 console=tty1 root=PARTUUID=738a4d67-02 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait modules-load=dwc2,g_ether quiet init=/usr/lib/ra $ touch /media/(userhomedir)/boot/ssh $ umount /media/(userhomedir)/boot
Raspbian のイメージを書き込んだ microSD カードを Raspberry pi zero WH に挿し,
のように PC に接続し boot させます.なお,このとき Raspberry pi zero WH 側は電源供給用ではなく,HDMI ポートに近い方の microUSB ポートを使って下さい.
しばらく待ってから dmesg でカーネルからのメッセージを参照すると,
$ dmesg ... [12548.321902] FAT-fs (sdb1): unable to read boot sector to mark fs as dirty [12581.589799] usb 1-2: new high-speed USB device number 8 using xhci_hcd [12581.738670] usb 1-2: New USB device found, idVendor=0525, idProduct=a4a2 [12581.738673] usb 1-2: New USB device strings: Mfr=1, Product=2, SerialNumber=0 [12581.738676] usb 1-2: Product: RNDIS/Ethernet Gadget [12581.738677] usb 1-2: Manufacturer: Linux 4.19.97+ with 20980000.usb [12582.298453] cdc_ether 1-2:1.0 usb0: register 'cdc_ether' at usb-0000:00:14.0-2, CDC Ethernet Device, 26:02:87:45:0e:67 [12582.298732] usbcore: registered new interface driver cdc_ether [12582.299768] usbcore: registered new interface driver cdc_subset [12582.317031] cdc_ether 1-2:1.0 enp0s20u2: renamed from usb0 [12582.378943] IPv6: ADDRCONF(NETDEV_UP): enp0s20u2: link is not ready [12582.431114] IPv6: ADDRCONF(NETDEV_UP): enp0s20u2: link is not ready
のような感じで USB-OTG で Ethernet の認識が行われていることが確認できます(私の場合は enp0s20u2 という名前で認識されている).この Ethernet 経由で Raspbian がインターネットと通信できるように以下のように設定します.
$ sudo nmcli c add type ethernet con-name rbpz1-usb ifname enp0s20u2 $ sudo nmcli c modify rbpz1-usb ipv4.method shared $ sudo nmcli c up rbpz1-usb
少し待ってから,
$ sudo arp-scan -I enp0s20u2 -l Interface: enp0s20u2, datalink type: EN10MB (Ethernet) Starting arp-scan 1.9 with 256 hosts (http://www.nta-monitor.com/tools/arp-scan/) 10.42.0.211 aa:aa:aa:aa:aa:aa (Unknown) 1 packets received by filter, 0 packets dropped by kernel Ending arp-scan 1.9: 256 hosts scanned in 2.423 seconds (105.65 hosts/sec). 1 responded
のようにすれば,Raspbian の IP アドレスが分かります(arp-scan が入ってない場合は apt install arp-scan のような感じで入れて下さい).ダメな場合は Raspberry pi zero WH の電源を入れ直し,それでもダメな場合は設定全体を見直して下さい.
最後に,ssh で接続し,Raspbian のアップデートと raspi-config で最低限の初期設定を行います.
$ ssh -l pi 10.42.0.211 pi@raspberrypi:~ $ sudo apt update pi@raspberrypi:~ $ sudo apt upgrade pi@raspberrypi:~ $ raspi-config
私の場合は raspi-config で,
- hostname を rbpz1 に変更
- Timezone を Asia/Tokyo に変更
- Wi-Fi の有効化
を行いました.
必要な標準パッケージの導入
初期設定後,再起動してから,最低限必要な標準パッケージを以下の通り Raspbian に導入します.
pi@rbpz1:~ $ sudo apt install pulseaudio libpulse-dev libbluetooth-dev libdbus-1-dev libsbc-dev libavcodec-dev libavutil-dev dh-autoreconf git cmake
fdk-aac の導入
次は fdk-aac ライブラリを導入します.元ページによると AAC-LC に対応させるためだけにしか使ってないとのことで,導入は OPTIONAL です.なお,Raspberry pi zero WH の場合,コンパイルにはかなり長時間(1時間程度)はかかります.
pi@rbpz1:~/ $ mkdir src pi@rbpz1:~/ $ cd src pi@rbpz1:~/src $ git clone https://github.com/mstorsjo/fdk-aac pi@rbpz1:~/src $ cd fdk-aac/ pi@rbpz1:~/src/fdk-aac $ ./autogen.sh pi@rbpz1:~/src/fdk-aac $ ./configure pi@rbpz1:~/src/fdk-aac $ sudo make install
ldacBT/libldac の導入
LDAC に対応させるためのライブラリを導入します.これはそれほどの時間はかかりません.なお,元サイトは以下の通りです.
pi@rbpz1:~ $ cd src pi@rbpz1:~/src $ git clone https://github.com/EHfive/ldacBT.git pi@rbpz1:~/src $ cd ldacBT/ pi@rbpz1:~/src/ldacBT $ git submodule update --init pi@rbpz1:~/src/ldacBT $ mkdir build && cd build pi@rbpz1:~/src/ldacBT/build $ cmake -DCMAKE_INSTALL_PREFIX=/usr/local -DINSTALL_LIBDIR=/usr/local/lib -DLDAC_SOFT_FLOAT=OFF ../ pi@rbpz1:~/src/ldacBT/build $ sudo make DESTDIR=$DEST_DIR install
pulseaudio-modules-bt の導入
今回の主目的である pulseaudio-modules-bt を導入します.導入手順は元サイト
にある通りですが,Raspbian Buster の場合,pulseaudio が ver12.2 であることに注意する必要があります(cmake -DFORCE_LARGEST_PA_VERSION=ON … は pulseaudio 最新版向けのコンパイルオプションです.これを設定してもコンパイルは通りますが,実行時エラーで停止します).また,出来る限り全てのコーデックに対応するようコンパイルオプションを設定しています.
pi@rbpz1:~/src $ MODDIR=`pkg-config --variable=modlibexecdir libpulse` pi@rbpz1:~/src $ sudo find $MODDIR -regex ".*\(bluez5\|bluetooth\).*\.so" -exec cp {} {}.bak \; pi@rbpz1:~/src $ git clone https://github.com/EHfive/pulseaudio-modules-bt.git pi@rbpz1:~/src $ cd pulseaudio-modules-bt/ pi@rbpz1:~/src/pulseaudio-modules-bt $ git submodule update --init pi@rbpz1:~/src/pulseaudio-modules-bt $ git -C pa/ checkout v`pkg-config libpulse --modversion|sed 's/[^0-9.]*\([0-9.]*\).*/\1/'` pi@rbpz1:~/src/pulseaudio-modules-bt $ mkdir build && cd build pi@rbpz1:~/src/pulseaudio-modules-bt/build $ cmake -DCODEC_APTX_FF=ON -DCODEC_APTX_HD_FF=ON -DCODEC_AAC_FDK=ON -DCODEC_LDAC=ON .. pi@rbpz1:~/src/pulseaudio-modules-bt/build $ make pi@rbpz1:~/src/pulseaudio-modules-bt/build $ sudo make install
ofono パッケージの導入(OPTIONAL)
必須ではないのですが pulseaudio のエラーメッセージが気になる場合は,ofono パッケージを以下の通り導入します.
pi@rbpz1:~ $ sudo apt install ofono pi@rbpz1:~ $ sudo systemctl enable ofono pi@rbpz1:~ $ sudo systemctl start ofono pi@rbpz1:~ $ sudo vi /etc/dbus-1/system.d/ofono.conf ... <policy group="pulse-access"> <allow send_destination="org.ofono"/> </policy> </busconfig>
なお,最後の ofono.conf ファイルの設定は pulse-access グループからの ofono へのアクセスを許可する設定です.
実行許可と自動起動の設定
一般ユーザーである pi が bluetooth と pulseaudio にアクセスできるように設定します.
pi@rbpz1:~ $ sudo adduser pi bluetooth pi@rbpz1:~ $ sudo adduser pi audio pi@rbpz1:~ $ sudo adduser pi pulse-access
また,/usr/local/lib 以下のパッケージを適切に検索できるようにライブラリのキャッシュを設定し直します.また,念の為,再起動します.
pi@rbpz1:~ $ sudo ldconfig pi@rbpz1:~ $ ldconfig -p | grep local libldacBT_enc.so.2 (libc6,hard-float) => /usr/local/lib/libldacBT_enc.so.2 libldacBT_enc.so (libc6,hard-float) => /usr/local/lib/libldacBT_enc.so libldacBT_abr.so.2 (libc6,hard-float) => /usr/local/lib/libldacBT_abr.so.2 libldacBT_abr.so (libc6,hard-float) => /usr/local/lib/libldacBT_abr.so libfdk-aac.so.2 (libc6,hard-float) => /usr/local/lib/libfdk-aac.so.2 libfdk-aac.so (libc6,hard-float) => /usr/local/lib/libfdk-aac.so $ reboot
再起動後,更に,ログイン時に pulseaudio が自動実行されるよう設定します.なお,起動時にエラーが出ないよう,pulseaudio の起動設定を一部変更します.
pi@rbpz1:~ $ sudo vi /lib/systemd/system/bluetooth.service ... ExecStart=/usr/lib/bluetooth/bluetoothd -E --noplugin=sap ... pi@rbpz1:~ $ systemctl --user enable pulseaudio pi@rbpz1:~ $ systemctl --user start pulseaudio
使い方とトラブルシューティング
使い方については,過去の記事,
をご覧ください.
なお,うまく動かない場合は,以下をチェックしてみて下さい.
まず,pulseaudio-modules-bt の module が以下のように適切に読み込まれているかどうかは以下のようにすれば確かめることが出来ます.
pi@rbpz1:~ $ pacmd list-modules | grep blue name: <module-bluetooth-policy> module.description = "Policy module to make using bluetooth devices out-of-the-box easier" name: <module-bluetooth-discover> name: <module-bluez5-discover>
もし読み込まれていない場合は,sudo ldconfig でライブラリのキャッシュを再作成してみて下さい.ライブラリの読み込みが適切に行われているなら,Bluetooth スピーカー等への接続は行えるはずです.
Bluetooth スピーカー等に接続はできるけれど,すぐ接続が切断される場合は,
$ systemctl --user stop pulseaudio $ pulseaudio -vvv
として再度接続を試してみると良いと思います.もし,接続された瞬間にエラーで pulseaudio が停止する場合は,pulseaudio-module-bt のコンパイルオプションを誤って最新版の pulseaudio に対応したものにしている可能性があります(上記 pulseaudio-module-bt の導入の節を再度ご覧ください).
この場合は pulseaudio-module-bt を適切なコンパイルオプションで再コンパイルして導入し直してやればエラーは出なくなるはずです.
なお,Bluetooth スピーカー等によっては相性問題もあるかも知れませんが,少なくとも私の持っている機器だとどれも問題なく使えています.
おわりに
上記は Raspbian Buster Lite での手順ですが,デスクトップ環境等含まれませんのでこのままだと LDAC とか AAC なんかが使えてもあまり面白くはありません.
実は,こんなことやろうと思ったのは,Raspberry pi zero WH を LDAC, AAC, apt-X HD に対応した USB to Bluetooth トランスミッターとして使おうと思ったからです.逆に言うとだから非力だけど小さな Raspberry pi zero WH を使った訳です.
という事で,次回は今回設定した Raspberry pi zero WH を USB to Bluetooth トランスミッターとして使う方法についてご紹介したいと思います.ちなみに WALKMAN はこれと同じこと出来そうで出来ません.この辺りについては,過去記事,
をご覧ください.
以上