mpd - kinneko/BBBB GitHub Wiki

Angstromでリモートオーディオサーバーを作る

 BeagleBone BlackにプリインストールされたAngstrom環境を使って、離れたところからスマートフォンで操作できるリモート・オーディオサーバーを作ってみましょう。

 サーバーには、Linux用のリモート・オーディオサーバーとして実績のあるmpdを使います。mpdは、音楽再生とリモートコントロールを可能にするもので、対応するクライアントアプリケーションがオープンソースで多数開発されています。スマートフォン用としては、Android/iOSともにすでにマーケットで公開されているリモコンアプリがあり、独自に用意する必要がないのも魅力です。

 音楽データは、BeagleBone Black上のSD Card内に置いてもいいのですが、それでは容量に限りがありますので、市販のNASから読み出すことにします。


パッケージやAudioデバイスの状態確認

 内蔵eMMCのAngstrom環境で、mpdのパッケージがあるか確認してみます。

root@beaglebone:~# opkg search mpd

 ないようです。

 まさかと思いますが、インストール済みのパッケージに入っていないか探してみましょう。

root@beaglebone:~# opkg list | grep mpd
mpd - 0.17.1-r2.4
mpd-systemd - 0.17.1-r2.4

 入っとるやん... じゃなくて、入っていました。

 動作状態も確認します。

root@beaglebone:~# systemctl status mpd
mpd.service - Music Player Daemon
	  Loaded: loaded (/lib/systemd/system/mpd.service; enabled)
	  Active: active (running) since Sun 2000-01-02 03:50:30 UTC; 45min ago
	Main PID: 131 (mpd)
	  CGroup: name=systemd:/system/mpd.service
		  `-131 /usr/bin/mpd --no-daemon

Jan 02 03:50:42 beaglebone mpd[131]: listen: bind to '0.0.0.0:6600' failed:...d)

 動作しています。

 開いているポートを確認して、デフォルトの6600番が使われているのも確認できます。

root@beaglebone:~# netstat -ltn
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN
tcp        0      0 0.0.0.0:3000            0.0.0.0:*               LISTEN
tcp        0      0 0.0.0.0:443             0.0.0.0:*               LISTEN
tcp        0      0 :::53                   :::*                    LISTEN
tcp        0      0 :::443                  :::*                    LISTEN
tcp        0      0 :::6600                 :::*                    LISTEN

 音声出力のテスト用にaplayやmplayerも入っているかどうか確認します。

root@beaglebone:~# opkg list | grep aplay
alsa-utils-aplay - 1.0.25-r2.7

root@beaglebone:~# opkg list | grep mplayer
mplayer-common - 0.0.1-r1.2
mplayer2 - 2.0+gitrAUTOINC+e3f5043233336d8b4b0731c6a8b42a8fda5535ac-r13.10

 入っていました。

 オーディオのインターフェイスの状態を確認します。aplayコマンドでも、procの中身でもどちらでも確認できます。

root@beaglebone:~# aplay -l
**** List of PLAYBACK Hardware Devices ****
card 0: Black [TI BeagleBone Black], device 0: HDMI nxp-hdmi-hifi-0 []
  Subdevices: 1/1
  Subdevice #0: subdevice #0
root@beaglebone:~# cat /proc/asound/cards
 0 [Black          ]: TI_BeagleBone_B - TI BeagleBone Black
                      TI BeagleBone Black

 ALSAで、0番に"Black"という名前で利用できるようになっています。NXPのICを使っているようです。


mpdの設定

 mpdのデフォルト設定を確認します。コメント部分を入れるととても長いので、有効になっている設定だけを抜き出します。

root@beaglebone:~# cat /etc/mpd.conf
music_directory		"/var/lib/mpd/music"
playlist_directory		"/var/lib/mpd/playlists"
db_file			"/var/lib/mpd/mpd.db"
log_file			"/var/log/mpd.log"
state_file		"/var/lib/mpd/state"
user "mpd"
group				"audio"
bind_to_address		"any"
input {
        plugin "curl"
}

 基本はデフォルトを使うとして、末尾に必要な設定を追記しましょう。

 先ほどの、インターフェイスの状態を確認した情報を反映します。

root@beaglebone:~# vi /etc/mpd.conf
auto_update	"yes"
audio_output {
        type            "alsa"
        name            "Black"
        device          "hw:0,0"
}

 設定を反映するように、mpdを再起動しておきます。

root@beaglebone:~# systemctl restart mpd

サンプルデータの配置

 mpdの設定では、音楽データは、/var/lib/mpd/music/の下に置くようになっていますので、そこにサンプルデータをscpしておきます。

MacBook:~ kinneko$ scp ~/Music/iTunes/iTunes\ Music/BENI/Covers/* [email protected]:/var/lib/mpd/music/
[email protected]'s password:
01.Ti Amo.mp3                                 100%   14MB   1.3MB/s   00:11
02.LA LA LA LOVE SONG.mp3                     100% 5660KB   1.1MB/s   00:05
03.Hitomio Tojite.mp3                         100%   14MB   1.1MB/s   00:12
04.Kanade.mp3                                 100%   12MB   1.4MB/s   00:09
05.One More Time One More Chance.mp3          100%   13MB   1.3MB/s   00:10
06.Robinson.mp3                               100%   10MB   1.3MB/s   00:08
07.SUDDENLY.mp3                               100%   10MB   1.3MB/s   00:08
08.Mou Koinante Shinai.mp3                    100%   11MB   1.2MB/s   00:09
09.Sakurazaka.mp3                             100%   13MB   1.4MB/s   00:09
10.Kokonishika Sakanai Hana.mp3               100%   15MB   1.1MB/s   00:14
11.Imano Kimio Wasurenai.mp3                  100% 9778KB   1.1MB/s   00:09
12.Itoshino Erii.mp3                          100%   10MB   1.3MB/s   00:08
13.TRUE LOVE.mp3                              100% 9667KB   1.4MB/s   00:07

mpdクライアント

 クライアントを入れる。

Droid MPD Client https://play.google.com/store/apps/details?id=com.soreha.droidmpdclient&hl=ja ちょっとUIが古くてダサいですか。 でも、ほとんど何も権限がないので、クリーン。 サービスを自動で発見できず。設定から、サーバーのIPアドレスを投入する。 設定は英語。

MPDroid https://play.google.com/store/apps/details?id=com.namelessdev.mpdroid&hl=ja ちょっといろいろ権限さわるですね。 これも、サービスを自動で発見できず。設定から、サーバーのIPアドレスを投入する。 設定は英語。


負荷状態の確認

  CPUは35%前後使っている。切替時開始に42%くらい。

root@beaglebone:~# top | grep mpd
  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
  131 mpd       20   0 70968 7988 4084 S 32.2  1.6   0:50.31 mpd
  131 mpd       20   0 70968 7988 4084 S 35.6  1.6   0:51.39 mpd
  131 mpd       20   0 70968 7988 4084 S 35.6  1.6   0:52.47 mpd
  131 mpd       20   0 70968 7988 4084 S 35.6  1.6   0:53.55 mpd
  131 mpd       20   0 70968 7988 4084 S 35.6  1.6   0:54.63 mpd
  131 mpd       20   0 70968 7988 4084 S 35.6  1.6   0:55.71 mpd
  131 mpd       20   0 70968 7988 4084 S 35.6  1.6   0:56.79 mpd
  131 mpd       20   0 70968 7988 4084 S 36.0  1.6   0:57.88 mpd

 デコード処理は重い(負荷が高い処理である)が、おそらくNEON使っていないのではないか。

 まずは、アプリケーションのビルド時に、NEONオプションが有効でビルドされていたかどうかを確認してみる。

root@beaglebone:~# which mpd
/usr/bin/mpd

root@beaglebone:~# ldd /usr/bin/mpd
-sh: ldd: command not found

root@beaglebone:~# file /usr/bin/mpd
/usr/bin/mpd: ELF 32-bit LSB executable, ARM, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.16, stripped

root@beaglebone:~# uname -a
Linux beaglebone 3.8.13 #1 SMP Tue Jun 18 02:11:09 EDT 2013 armv7l GNU/Linux

これは、古いバイナリだわ。 再生はlibmadに依存しているのかな?

root@beaglebone:~# file /usr/lib/libmad.so.0.2.1
/usr/lib/libmad.so.0.2.1: ELF 32-bit LSB shared object, ARM, version 1 (SYSV), dynamically linked, stripped

http://www.angstrom-distribution.org/repo/?pkgname=ldd あるのにな。

root@beaglebone:~# opkg search ldd
root@beaglebone:~# opkg install ldd
Unknown package 'ldd'.
Collected errors:
 * opkg_install_cmd: Cannot install package ldd.

armv7a-vfp-neonなんだろうか? そうとも思えない。

root@beaglebone:~# opkg list mpd
mpd - 0.17.1-r2.4

root@beaglebone:~# opkg info mpd
Package: mpd
Version: 0.17.1-r2.4
Depends: libgcc1 (>= linaro-4.7), libcdio-paranoia0 (>= 0.82), libmad0 (>= 0.15.1b), libcdio-cdda0 (>= 0.82), libsamplerate0 (>= 0.1.8), libavahi-common3 (>= 0.6.31), libid3tag0 (>= 0.15.1b), libavahi-client3 (>= 0.6.31), libasound2 (>= 1.0.25), libmms0 (>= 0.6.2), libwrap0 (>= 7.6), libsoup-2.4 (>= 2.38.1), libavformat53 (>= 0.8.4+gitAUTOINC+2c8ce46250ff78191fe6565876ddc4bc03fdf519), libsystemd-daemon0 (>= v196-105-gdecd634), libglib-2.0-0 (>= 2.32.4), libogg0 (>= 1.3.0), libsndfile1 (>= 1.0.25), libfaad2 (>= 2.7), libaudiofile0 (>= 0.2.7), libc6 (>= 2.16), shadow, libcdio12 (>= 0.82), libavutil51 (>= 0.8.4+gitAUTOINC+2c8ce46250ff78191fe6565876ddc4bc03fdf519), libpulse0 (>= 2.1), libavcodec53 (>= 0.8.4+gitAUTOINC+2c8ce46250ff78191fe6565876ddc4bc03fdf519), base-passwd, libcurl5 (>= 7.26.0), libmp3lame0 (>= 3.99.5), libsqlite3-0 (>= 3.7.13), libvorbis (>= 1.3.3), libavahi-glib1 (>= 0.6.31), libflac8 (>= 1.2.1), libbz2-0 (>= 1.0.6)
Recommends: mpd-systemd
Provides:
Status: install user installed
Architecture: armv7a-vfp-neon
Installed-Time: 1371655407

なってるわ。

root@beaglebone:~# opkg info libmad0
Package: libmad0
Version: 0.15.1b-r0.4
Depends: libc6 (>= 2.16)
Provides:
Status: install ok installed
Architecture: armv7a-vfp-neon
Installed-Time: 1371655405

NEON使っててもこれか。


そもそもNEONが有効なソースだったのか?

libmadは27bit固定小数点演算だそうだ… orz http://jview.exblog.jp/264971/

libavはmp3はないみたい。 https://github.com/libav/libav/tree/master/libavcodec/arm

clipmp3やmpeg123

libmpg123は対応してるみたい。2010末くらいから。 http://sourceforge.net/mailarchive/message.php?msg_id=26741389

  • New optimization: ARM NEON (Cortex A series) -- kudos to Taihei, again!

MPD should support mpg123 for mp3 decoding https://trac.macports.org/ticket/34853 提案はあるのね。 portsには入っている。 https://trac.macports.org/changeset/99335

mDNS/DNS-SDによるサービスアナウンス

Avahi使うのだが、mpdにはサービスをクライアントから自動認識させるために、こんな設定もある。

zeroconf_enabled		"yes"
zeroconf_name			"BeagleBone Black"

設定を有効にして再起動しておく。

root@beaglebone:~# systemctl restart mpd

Androidでは対応クライアントがなく未調査。オープンソースのアプリの中に対応コードの入ったものを見たことあるような。

mDNSアナウンスについては、mpdで独自に機能を持っており、avahiと競合しているようにも思われる。

ルータの無線LANではマルチキャストが飛ばせなかったので、確認不良はそれも原因か?


NASとの接続

# vi /etc/fstab
//192.168.0.150/Music /var/lib/mpd/music cifs username=root,password=samba,uid=mpd,file_mode=0644,dir_mode=0755,iocharset=utf8 0 0
# mount -a