Raspberry Pi B+ の lightMPD を無線LAN接続

以前に Raspberry Pi B+ に SabreBerry+ で lightMPD という記事を書いたが最後に無線化したいけど自分では出来ないと書いていた.

RaspberryPiModelB+ と GW-USNANO2A
RaspberryPiModelB+ と GW-USNANO2A

それがつい先日,Interface 2015年12月号 に「ラズパイ・オーディオの Wi-Fi 化」という記事が出ているのを見かけた.
おぉ!と思い,早速買った.
記事にしていただいてありがとうございます!

この記事では RaspberryPi2 で無線USB子機は GW-450D KATANA という機種だった.

私のは PaspberryPi B+GW-USNANO2Aという組み合わせで,最終的には動いたのだが,割とというか,かなり苦労したので備忘録として残しておく.

自分で見直して再度構築できるようにと思って書いているので本を参照したほうが何をやっているかはよく分かると思います.
(もし,以下の記事の内容に問題あれば削除します.)

詳しくはあくまでも Interface を見てください.
また,あの Interface の記事とは本体もUSBドングルも違うため,ところどころ違っていることに注意してください.

事前準備

まず,クロスコンパイルの環境が必要.
VMWare を使ったことがあるので,今回もそれで行った.

※ちなみに,うちは Windows10 64bit の OS を使っている.

VMware Workstation 12.0.1 Player for Windows 64-bit operating systems. というのをダウンロードしてインストールする.

Ubuntu 15.04 64bit をダウンロードして,VMWare 上でインストールする.
ハードディスクは16GBで作ったが,ディスクがあるなら,20GBの方がよいかもしれない.
「System program problem detected」というダイアログがたまに出ていたが,そのせいかもしれない.(無視しても問題はなかったが.)
基本的に terminal か xterm で作業を行うことになる.

私が使っている lightMPD は raspberry pi b+ なので lightMPDraspi-v1.0.1.zip である.

share などの名前で共有フォルダを作り,以下のファイルをそこに入れておく.
native-dsd再生時のポップノイズに対応したkernelを公開しました
native-dsd-noise-linux-4.0.8.patch

クロスコンパイル環境での準備

sudo apt-get install git
sudo apt-get install libncurses-dev
windows のディスクを見たい場合は
sudo apt-get install cifs-utilsを入れておく.
sudo mount -t cifs -o username=ユーザ名,password=パスワード //WindowsのIPアドレス/share /mnt/windowsなどのように使う.

マウント用ディレクトリの作成.
mkdir /mnt
mkdir /mnt/sd
mkdir /mnt/rootfs

カーネルの再構築

準備

cd
git clone git://github.com/raspberrypi/linux.git
git clone --depth=1 git://github.com/raspberrypi/tools.git
wget https://www.kernel.org/pub/linux/kernel/projects/rt/4.0/older/patch-4.0.5-rt3.patch.xz
cp /mnt/windows/share/native-dsd-noise-linux-4.0.8.patch .
(先ほどダウンロードしたもの)
cd linux
git checkout 520cdbcef82822ae91772297ce4d87ea6f4bedb6 -b lightmpd
(※デバイスドライバの追加)
xzcat ../patch-4.0.5-rt3.patch.xz | patch -p1
vi sound/soc/bcm/bcm2708-i2s.c
(「mash = BCM2708...」の行をコメントアウト)
patch -p1 < ../native-dsd-noise-linux-4.0.8.patch

.config の取り出し

lightMPD の設定を変更し,telnet 出来るようにする.
root でログイン.パスワードはなし.
mount /dev/mmcblk0p1 /mnt
cp /proc/config.gz /mnt
umount /mnt
これで lightMPD の入っている MicroSD のルートに config.gz が保存されるので,これを持ってくる.
この MicroSD を ubuntu を立ち上げた状態の PC に差せば自動でマウントされるが,されない場合は右上のアイコンをクリックして,「接続」を選ぶ./dev/sdb1 に自動でマウントされる.
されない場合は,
mount /dev/sdb1 /mnt/sdなどしてマウント.
cp /mnt/sd/config.gz ~などして,自分のホームディレクトリに持ってくる.

カーネルコンフィグファイルの作成とカーネルコンパイル

(2015/12/22追記:佐藤様からのコメント.下記CROSS_COMPILEの指定で32bitOSを使っている場合は,-x64を削除)
cd ~/linux
zcat ../config.gz > .config
export ARCH=arm
export CROSS_COMPILE=../tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian-x64/bin/arm-linux-gnueabihf-
make menuconfig

GW-USNANO2A のデバイスのモジュールを入れる.
これは RTL8192CU のドライバを入れればよいことがいろいろ調べてみたら分かった.

以下のドライバである.
Device Drivers > Network device support > Wireless LAN > Realtek 8192C USB Wifi
このモジュールを入れたいのだが,最初表示されない.
そこで,設定画面上で / を打って, 8192 を入れて探す.
そうすると,
Symbol: RTL8192CU [=n] │
│ Type : tristate │
│ Prompt: Realtek 8192C USB WiFi │
│ Location: │
│ -> Device Drivers │
│ -> Network device support (NETDEVICES [=y]) │
│ (1) -> Wireless LAN (WLAN [=y]) │
│ Defined at drivers/net/wireless/rtl8192cu/Kconfig:1 │
│ Depends on: NETDEVICES [=y] && WLAN [=y] && MAC80211 [=n] && USB [=y] │
│ Selects: CFG80211_WEXT [=n] && WIRELESS_EXT [=y] && WEXT_PRIV [=y]
のような感じの表示が出るので,Depends on が全部 y になるように / を使って探しては y にしていく.
モジュールとして入れるので,8192CU は「m」にする.

make -j4 zImage
cp arch/arm/boot/zImage /mnt/sd/boot
(lightMPD の入っている SD の /boot にコピー)

モジュールの作成

上記のように 8192cu のモジュールを入れれば全く問題ないのだが,備忘録で別のドライバのインストール方法も書いておく.この部分は不要.
通常は不要部分.
—ここから—cd ~
git clone https://github.com/dz0ny/rt8192cu.git
cd rt8192cu
sudo bash
export KERNEL_VERSION=`cat include/config/kernel.release`
export INSTALL_MOD_PATH=../$KERNEL_VERSION
make ARCH=arm CROSS_COMPILE=../tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian-x64/bin/arm-linux-gnueabihf- -C $INSTALL_MOD_PATH/lib/modules/$KERNEL_VERSION/build M=~/rt8192cu
これでカレントディレクトリに 8192cu.ko が出来る.
(違うドライバは以下のようにコピーする.下で tar する直前)
cp 8192cu.ko $INSTALL_MOD_PATH/lib/modules/$KERNEL_VERSION/drivers/net/wireless/rtl8192cu
—ここまで通常は不要—

モジュールをまとめる.
make modules
export KERNEL_VERSION=`cat include/config/kernel.release`
export INSTALL_MOD_PATH=../$KERNEL_VERSION
make modules_install
/bin/bash ./scripts/depmod.sh /sbin/depmod $KERNEL_VERSION ""
cd $INSTALL_MOD_PATH/lib/modules
(違うドライバを使いたい場合はここでコピーする.)
tar cvzf kmodules.tgz $KERNEL_VERSION
cp kmodules.tgz /mnt/sd/boot
(lightMPD の入っている SD の /boot にコピー)

RAM に入る lightMPD 本体の再作成

initrd.romfs.gz というのがそれである.

buildroot により,wpa_supplicant を作成

cd ~
git clone git://git.buildroot.net/buildroot
cd buildroot/
git checkout -b 2015.05 2015.05
make raspberrypi_dt_defconfig (raspberry piなので)
make menuconfig
Kernel -> Linux Kernel []
Toolchain -> C Library -> glibc
Target package -> Networking applications -> wpa_supplicant [*]
Target package -> Networking applications -> wpa_supplicant -> Install wpa_cli binary [*]
Target package -> Networking applications -> wpa_supplicant -> Install wpa_passphrase binary [*]
make -j4

initrd.romfs.gz の作成

initrd.romfs.gz を展開

cp /mnt/sd/boot/initrd.romfs.gz ~
cd ~
gzip -d initrd.romfs.gz
sudo bash
mount -o loop,ro initrd.romfs /mnt/rootfs
mkdir rootfs
cd rootfs
(cd /mnt/rootfs; tar cf - *) | tar xfBp -

wpa関連ファイルのコピー

cp ../buildroot/output/target/usr/sbin/wpa_* usr/sbin/
head -3 ../buildroot/output/target/etc/wpa_supplicant.conf > etc/wpa_supplicant.conf
wpa_passphrase SSID 事前共有キー >> etc/wpa_supplicant.conf

注意事項:
このファイルに余計なものは加えない.
ネットでググると,
・psk= の先を ” でくくるとうまくいった.
・proto=WPA を設定する.
とかあるが,これらを入れると私の環境では繋がらなくなった.
ここでかなりハマる

SSIDを隠蔽している場合には以下のようにする必要がある.(etc/wpa_supplicant.conf)
...
ap_scan=1
network={
scan_ssid=1
...
scan_ssid=1 を追加するだけでなく,ap_scan=1とnetwork={の間にある改行も削除.head -3 でくっつけると改行が空くがこれがあるせいでなぜか動かない.

システム設定ファイル作成スクリプトを変更

var.rom/lightMPD/bin/syssetup.scm
を以下のように変更
(GW-USNano2(8192cu) は wlan0 になる.)
- (let ((interface (hash-table-get param "interface" "eth0"))
+ (let ((interface (hash-table-get param "interface" "wlan0"))
----
(format port "iface ~a inet static\n" interface)
+ (format port "\t pre-up\t wpa_supplicant -B -i wlan0 -c /etc/wpa_supplicant.conf\n")
+ (format port "\t post-up\t sleep 5\n")
+ (format port "\t post-down\t killall -q wpa_supplicant\n")
----
(format port "#!/bin/sh\n\n")
+ (format port "### GW-USNano2 usb Wi-Fi\n")
+ (format port "modprobe 8192cu\n\n")

SSIDを隠蔽している場合には以下のようにする必要がある.
etc/modprobe.d/blacklist.conf
blacklist rtl8192cu

不要ファイルの削除

ここでも大いにハマった
元々あった initrd.romfs.gz を展開して,wpa 関連の実行ファイルをコピーしただけなのにネットワークに接続できなくなるのである.
なぜ動かないのか,2日考えたのだが,どうやら容量オーバーらしい.
Paspberry Pi Model B+ の RAM は 512MB なのだが,initrd.romfs.gz を展開するとこの容量を超えてしまうようなのだ.(正確には512MBではないようだが.)
Raspberry Pi 2 は 1GB なので少々のことでは溢れなさそうだが.

で必要のないファイルは極限まで削ることにする.

rm -rf usr/share/zoneinfo/posix/Pacific
rm -rf usr/share/zoneinfo/posix/Europe
rm -rf usr/share/zoneinfo/posix/Arctic
rm -rf usr/share/zoneinfo/posix/Australia
rm -rf usr/share/zoneinfo/posix/Indian
rm -rf usr/share/zoneinfo/posix/Atlantic
rm -rf usr/share/zoneinfo/posix/America
rm -rf usr/share/zoneinfo/posix/Africa
rm -rf usr/share/zoneinfo/posix/Antarctica
rm -rf usr/share/zoneinfo/posix/US
rm -rf usr/share/zoneinfo/right/Pacific
rm -rf usr/share/zoneinfo/right/Europe
rm -rf usr/share/zoneinfo/right/Arctic
rm -rf usr/share/zoneinfo/right/Australia
rm -rf usr/share/zoneinfo/right/Indian
rm -rf usr/share/zoneinfo/right/Atlantic
rm -rf usr/share/zoneinfo/right/America
rm -rf usr/share/zoneinfo/right/Africa
rm -rf usr/share/zoneinfo/right/Antarctica
rm -rf usr/share/zoneinfo/right/US
rm usr/share/zoneinfo/Africa
rm usr/share/zoneinfo/Atlantic
rm usr/share/zoneinfo/America
rm usr/share/zoneinfo/Australia
rm usr/share/zoneinfo/Antarctica
rm usr/share/zoneinfo/Arctic
rm usr/share/zoneinfo/Europe
rm usr/share/zoneinfo/Indian
rm usr/share/zoneinfo/Pacific
rm usr/share/zoneinfo/US
rm -rf usr/share/locale/de
rm -rf usr/share/locale/fr

initrd.romfs.gz の作成

不要なファイルを削除してスリムになったら,改めてイメージの作成.
genromfs -f ../initrd.romfs
cd ..
gzip initrd.romfs.gz (※オプションの -9 を入れるとSSID隠蔽時に動かない.)
cp initrd.romfs.gz /mnt/sd/boot
(lightMPD の入っている SD の /boot にコピー)

設定ファイルの書き換え

RaspberryPi 用の lightMPD は vmlinux を使うようになっているので,config.txt で zImage を使うように修正する.
#kernel=/boot/zImage

kernel=/boot/zImage
にして,
kernel=/boot/vmlinux

#kernel=/boot/vmlinux
にコメントアウトする.

また,lightmpd.conf の中の eth0 は wlan0 に変更する.

無線ルーターでステルスSSIDを設定している場合

「無線ネットワーク名(SSID)の隠蔽(ANY接続拒否)」を通常「する」で使っていたのだが,これを「する」にすると無線がつながらなくて3日ほど悩んだ.
結局,文中の赤字の部分を設定すればなぜか繋がる.
今回,ここが一番ハマった.
しかも,今でも意味不明な部分もある...偶然見つけた.

Raspberry Pi B+ に SabreBerry+ で lightMPD

だいぶ前にハイレゾ音楽を cubox で聴いている話を書いたが,実はこの後割とすぐに,lightMPD に乗り換えていた.

これの良いところは何と言っても電源ブチ切りが可能なこと.
lightMPD はコンセプトが素晴らしい

また,たまにノイズが乗っていた.原因が結局分からなかったのだが,lightMPD に代えるとそのプチプチがほぼなくなった.
で,それでしばらく運用していたのだが,先日の asterisk を QNAP に入れた時点で raspbery pi の使い道がなくなってしまっていた.
ちょうど余っているし,Raspberry Pi の I2S 端子と直結する DAC 基板がいろいろ出ていることに気づいたので,いろいろ物色してみた.
DAC に PCM5102A を使っているものと,ES9023 を使っているものがある.
hiFace Evo が 5102 らしいので,同じのは面白くないと思い,ES9023 で探すとよさそうなものを発見.既に使っているケースにも収まりそうだ.
それで,SabreBerry+ を購入.

はんだ付けの必要があるが,ケースにちょうど収めるためには半田付けは自分でやったほうがよい.
Rasberry Pi B+ に SabreBerry+
実際にはこんな感じ.上の画像のリンク先で購入したがすぐに来た.

前回,6万ぐらいでネットワークプレーヤーが出来たという話を書いたが,今回は
Raspberry Pi MODEL B (PLUS) &専用ケース¥6,380
TAKAZINE-004 SabreBerry+ ¥6,480
だったので,正味 13000円ぐらいである.
ACアダプタは最初PHS用の550mAのものを使っていたのだが,どうも途中で曲によってはちゃんと再生できないもの(ノイズが入る)があり,仕方がないので,1.35Aのものに代えた.

それで,当然のように lightMPD を載せたが,
いやぁ~,値段からは信じられないほど普通にいい音である.
いろんなブログで紹介されているのは当然だなと思う.
またもや,皆様に感謝である.

これにより,アンプに連動させて Raspberry Pi の電源を入れるようにしたので,終わるときもアンプを切って終了できるのでスイッチ一つになり,嫁さんにも操作できるようになった.すごい世の中になったものである.

ちなみに lightMPD 最高なのだが,無線LANに対応してもらえると家の中のLANの来ていない部屋にも持っていけるようになるのでさらに最高なんですよね.
lightMPD はちょっと見た限りいじれなさそうなのでそれが少し残念.

今は仕方なく,
RaspberryPi と QNAP
な感じ.

RuneAudio で無線のUSBを付けたらノイズが乗ったという話がどこかに出ていたが,私のところで試したところ大丈夫だったので,lightMPD が eth0 だけでなく,wlan0 に対応して,適当な無線LAN子機(USBアダプター型)のドライバーを積んでくれたらいいなあ!と思う.

他力本願なのだが,ネットワークの分離とか書かれているから,やっぱり音質面で却下かなあ?
うーん,別バージョンでもいいから欲しいなあと思う今日この頃である.

ちなみに,RuneAudio で問題なく動いた私の購入した無線LAN子機はGW-USNANO2Aである.
これのドライバーも搭載しておいていただけないかな~.(しつこい)

追記) 2015/11/6
LightMPD で USB の wifi 子機を使った無線接続に成功

MPD と MPaD, MPoD で快適音楽

(前々回からの「簡単にいい音で音楽を聴きたい.」の続きです.一応,完結編.)

Linux


話を CuBox に戻す.
参考にしたのは,みみず工房さん.本当に感謝です.

最初は上のサイトで配布されているイメージをそのまま突っ込み動作を確認.(Cubox 最高!のページなどを参考にされると簡単!感謝です.)
そうそう,最初どうやってmicroSDカードを取り出すのか分からなかったが,自分の場合はピンセットでmicroSDカードの突起に引っ掛けて取り出している.(これ,みんな常識なのだろうか?結構最初焦った.)

この時,USBでシリアルコンソールを触れるようにしておくと何かと楽.

問題なく音が出ていたので,改めて自分でも Windows 上に VMWare Player でクロスコンパイル環境を作り,コンパイルしてみた.
(現在は「cubox カーネル3.8+RTPatchのビルド方法」の記事を参考にしたものを入れている.)
それほど問題もなく動いた.

一応,設定だけ備忘録.(※うちの環境.xxx.xxx.xxx.xxx はプロバイダのDNS)
/etc/network/interfaces
# The primary network interface
auto eth0
iface eth0 inet static
address 192.168.0.150
netmask 255.255.255.0
gateway 192.168.0.1
dns-nameservers 192.168.0.1 xxx.xxx.xxx.xxx

/etc/resolv.conf
nameserver 192.168.0.1 xxx.xxx.xxx.xxx
nameserver 127.0.0.1
search localdomain

/etc/rc.local (突然,音が鳴り出すとびっくりするので毎回初期化)
/usr/bin/mpc clear

ソースの違いによる音の違いは私には正直分からなかったが,そんなことは気にしない.
ブラボ?!である.

CDの取り込み方


いろいろあってどうしようか悩んだが,結局NASに放り込むのは flac 形式にした.
ただし,バックアップとしては tak 形式にしておいた.これの方がいざという時戻しやすいかなと思ったからである.flac でファイルがバラバラになるより,tak で一つのファイルとしていた方が管理も楽だし.

まず,Exact Audio Copy をダウンロード
さらに,TAK もダウンロード
そして,Exact Audio Copy を立ち上げ,外部エンコードとして TAK を指定する.
Exact Audio Copy でCDから音楽をTAKで取り込む方法を参照.感謝です.

曲目リストはボタン一つでネットから取り込まれ,ジャケット写真が見つからない場合は,適当にネットから探して,画像のドラッグアンドドロップで取り込める.

メニューの「アクション」→「CDイメージをコピーしCUEシートを作成」→「圧縮」でファイル保存すると,tak と cue が出来る.画像ファイルも一緒に作られる.

foobar2000 をダウンロード,インストールしておく.
foobar2000 を立ち上げ, playlist に cue ファイルを放り込む.
アルバムに含まれているファイル全部を選択状態にしたまま,右クリックでメニューを出し,「convert」→「…」 を選択する.
設定画面が現れるので Output format を flac にして,Destination を自分の環境に合わせて設定する.私の場合,Output style and file name formatting は
%album artist%/%album%/[%discnumber%.]%tracknumber%. %title%
としている.これを「flac」などと名前をつけて保存しておく.
ここで一度登録しておけば,次回からは「flac」を選択するだけで変換できる.

MPoD と MPaD


LINN を見に行った時に店員さんが,
「LINN を聴いて『いいなあ』といわれたお客さんはかならず1週間ぐらいしたら,またご来店されて購入されます.」
と不敵な笑みで言っていたが,LINN の良さは音だけでなく,iPad で簡単に操作が出来るところにもある.

だが,しかし Linux で動く MPD にも良いクライアントソフトが存在する.
iPod Touch では,MPoD. iPad では MPaD というソフトがあって,MPaD は有料であるが,それだけの価値はある.(といっても 250円だが.)
(スクリーンショットはリンク先を確認してください.)

これを使うと簡単にアルバムや曲を選べて,自分で好きなプレイリストも作れる.
ジャケットの写真も一緒に確認できるので,とても快適.

どれくらい快適かというと,このシステムを構築してから2ヶ月ぐらいの間にCDを30枚ほど借りに行ったぐらい快適だった.

電源オフの仕方


いきなり切ってもそれほど問題はなさそうな気もするが,やはりちょっと気持ち悪い.そこで iPad や iPodTouch に ssh のクライアントを入れて,電源オフのマクロを登録しておく.
このマクロを起動して電源が切れたことを確認してから,全ての電源を落とすことにした.
具体的には SSH Mobile Free というアプリを入れた.
Site List にサーバーを登録し,Macro List に Site List にいれた Profile を使い,shutdown -h now というコマンドを入れておいて,そのマクロをクリックすれば電源オフに出来る.
これで電源オフにしてから,CuBox の電源を切れば問題ない.