概要
MPDで音楽再生サーバを構築し、再生中の曲名、アーティスト名、アルバム名と、ジャケットイメージをOLEDに表示する。もちろん、日本語でOK!!
そして、3つのボタンで「前の曲」「再生/一時停止」「次の曲」も出来たりする。
おそらくSingleBoardComputingにおけるMPDの完成形の一つになるのではなかろうか(笑
せっかくなので環境構築含めた完全版でお送りする。
左側が NEO2 Complete Starter Kit. ずぅ~っとOutOfStockの状態で、5/26に一瞬InStockになった瞬間に巡り合い奇跡的?にゲットできた逸品。
右側が、NanoPi-NEO + NanoHat PCM5102a + NanoHat OLED の組み合わせ。
今回メインとなるPythonによるOLEDへの各種情報表示のコードは下記に登録してあります。
https://github.com/blue777/NanoPi-NEO_OLED_MPD
関連シリーズ紹介
- NanoPi-NEOとMPDとLCDとI2S-DACとTDA7297で音楽再生サーバ(完全体)
- NanoPi-NEO2 の I2SでMCLK出力 & 384kHz, 768kHz, 1536kHz, 8kHz対応
必要なもの
ハードウェア
- NanoPi NEO ($7.99) もしくは NanoPi NEO2 ($14.99)
- NanoHat OLED ($6.99)
- NanoHat PCM5102a ($9.99) か USB DAC か 3.5mmジャック
あるいは
- NEO Complete Starter Kit ($29)
- USB DAC
あるいは
- NEO2 Complete Starter Kit ($34)
- USB DAC
ソフトウェア
NanoPi NEO
- nanopi-neo_ubuntu-core-xenial_3.4.39_20170523.img.zip
- nanopi-neo_ubuntu-core-xenial_4.11.2_20170605.img.zip
のいずれかを前提にしています。
※イメージによってはNanoHat PCM5102a 動かなかったりします。
NanoPi NEO2
- nanopi-neo2_ubuntu-core-xenial_3.10.65_20170523.img.zip
- nanopi-neo2_ubuntu-core-xenial_4.11.2_20170605.img.zip
のいずれかを前提にしています。
※イメージによってはNanoHat PCM5102a 動かなかったりします。というより、未検証です。
サーバー側構築手順
BootImageをMicroSDに転送して起動した状態を前提にしています。
1. 初期セットアップ
timedatectl set-timezone Asia/Tokyo
apt-get update
apt-get upgrade
npi-config
あたりで下準備します。
固定IPが良い場合は下のような感じです。
nano /etc/network/interfaces
allow-hotplug eth0
# iface eth0 inet dhcp
iface eth0 inet static
address 192.168.1.100
netmask 255.255.255.0
gateway 192.168.1.1
dns-nameservers 192.168.1.1
2. MPD (Music Player Daemon) のインストール
次のコマンドでインストールします。
インストール終わったら設定変更していきます。
apt-get install mpd
nano /etc/mpd.conf
音楽ディレクトリの変更
該当行を探して、以下にします。(下記を前提に説明していきます)
music_directory "/media/"
音声出力の設定
まず、
cat /proc/asound/cards
で、サウンドカードの一覧を出力します。
こんな感じででたりします。
とりあえずありったけ繋いだ状態です(笑
root@NanoPi-NEO:~# cat /proc/asound/cards
0 [Pcm5102a ]: Pcm5102a - Pcm5102a
Pcm5102a
1 [sndhdmi ]: sndhdmi - sndhdmi
sndhdmi
2 [DAC ]: USB-Audio - USB Audio DAC
Burr-Brown from TI USB Audio DAC at usb-sunxi-ehci-1.2, full speed
3 [J20 ]: USB-Audio - JAVS USB Audio 2.0
JAVS JAVS USB Audio 2.0 at usb-sunxi-ehci-1.3, high speed
4 [N2 ]: USB-Audio - NuForce µDAC 2
NuForce, Inc. NuForce µDAC 2 at usb-sunxi-ehci-1.4, full speed
5 [AI301DA ]: USB-Audio - TEAC AI-301DA
TEAC Corporation TEAC AI-301DA at usb-sunxi-ehci-1.1, high speed
root@NanoPi-NEO:~# uname -a
Linux NanoPi-NEO 3.4.39-h3 #3 SMP PREEMPT Tue May 23 17:37:51 CST 2017 armv7l armv7l armv7l GNU/Linux
root@NanoPi-NEO2:~# cat /proc/asound/cards
0 [Codec ]: H3_Audio_Codec - H3 Audio Codec
H3 Audio Codec
1 [USBCamera ]: USB-Audio - USB_Camera
KYE Systems Corp. USB_Camera at usb-1c1d000.usb-1, high speed
root@NanoPi-NEO2:~# uname -a
Linux NanoPi-NEO2 4.11.2 #1 SMP Wed Jun 7 03:24:53 PDT 2017 aarch64 aarch64 aarch64 GNU/Linux
上から順番に説明していくと、
InstanceNo. | DeviceName | 解説 |
---|---|---|
0 | Pcm5102a | NanoHat Pcm5102aです。NanoPi-NEO Kernel=3.4.39の場合の表示名です。KernelVer変わると表示名も変わったりします |
1 | sndhdmi | HDMIのAudio信号出力だと思いますが、HDMIコネクタ無いので使えません |
2 | DAC | USB DACです。 |
3 | J20 | USB DDCです。JAVS X-DDC というUSB→SPDIF変換器です。 |
4 | N2 | USB DACです。NuForce μDACです。 |
5 | AI301DA | USB DACです。Teac AI-301DAです。 |
0 | Codec | NanoPi-NEO2 の基板上のLineOutです。はんだ付けすると使えるはずです。H5なのにH3なのはドライバが共通のためと思われます。 |
1 | USBCamera | マイク入力ついているカメラです。音声出力は出来ないので使えません。 |
それぞれに対する基本的な書き方です。
こんな感じで書きます。audio_output のタグは複数あってもOKです。
複数あると、同時出力指定もできます。
audio_output {
type "alsa"
name "HanoHat PCM5102a"
device "hw:Pcm5102a,0"
mixer_type "software"
format "*:32:2"
replay_gain_handler "software"
}
※PCM5102aはI2S接続されており、24bitフォーマットの時に音が極端に小さくなる現象がでます。これはデータが24bitのまま32bit出力されているためのようです。その対策のため、formatを強制指定の上、mixer_type,replay_gain_handlerも設定します。
audio_output {
type "alsa"
name "JAVS X-DDC"
device "hw:J20,0"
mixer_type "none"
}
※BitPerfect出力したいためmixer_typeにnone設定します。その代わり、ソフトウェア上からの音量調整ができなくなります。
audio_output {
type "alsa"
name "NanoPi-NEO2 LineOut"
device "hw:Codec,0"
mixer_type "software"
}
それぞれ、name に指定したものが、MPDクライアントからの表示名になります。
device の 「hw:XXXX,0」 の XXXX の部分には、InstanceNo. もしくはDeviceNameを入れます。
USB接続で自動認識させたい場合は、最後尾となるInstanceNo. などを入れたりします。が、InstanceNo.による割り当て、接続順により変わったりするため、DeviceNameによる指定がおすすめです。
(ALSAでの番号割り当て順を変更することもできますが、割愛します)
3. 音楽データの準備
microSD を共有フォルダ化する場合
OSをインストールしたmicroSDを共有フォルダにして、
外部PC等から音楽データをNanopiNEOにアップロードする形になります。
Sambaのインストールおよび、
/media/local のディレクトリを作成し、共有設定します。
共有設定は、フルアクセス設定です。(笑
apt-get install samba
mkdir /media/local
chmod 777 /media/local
nano /etc/samba/smb.conf
・
・
・
[Music]
comment = share folder
path = /media/local
public = yes
writable = yes
guest ok = yes
guest only = yes
create mode = 0777
directory mode = 0777
※最後尾に追加します。Musicが共有フォルダ名として見えます。
設定完了したら、Sambaの共有を開始させます。
systemctl enable smbd
systemctl start smbd
NASなど外部の共有フォルダを使う場合
Windowsファイル共有やNASをマウントして使う場合です。
apt-get install cifs-utils
mkdir /media/nas
nano /etc/fstab
・
・
・
//192.168.1.9/Public /media/nas cifs username=guest,password=,uid=root,iocharset=utf8 0 0
※最後尾にでも追加します。
※DNS使えなかったりするので、IP直指定です。
設定後、
mount -a
df
で正しくマウントされることを確認します。
※iocharset=utf8はKernelVerやディストリビューションにより使えなかったりします。
そんなときは、
・あきらめて違うディストリビューション使うか、
・日本語のファイル名を諦めるか、
・カーネルオプション変えてカーネルビルドするか、
・mpd.confを「music_directory "smb://192.168.1.9/Public"」としてサンバ直アクセス
にしたりします。
4. OLED表示のセットアップ
曲名表示やジャケットイメージの取得・表示をPythonで書いてみました。
今回Pythonを初めて使ったのですが、2日ほどでこれが仕上がりました。。。
途中、タブとスペースの混在に苦しめられたり、紆余曲折ありましたが、
思いのほか出来が良かったため、この記事書くきっかけになったりもしてます。
2017/08/31追記: 続編 「NanoPi-NEOとMPDとLCDとI2S-DACとTDA7297で音楽再生サーバ(完全体)」にてOLED表示のほかLCD表示にも対応しました。お好みの表示ソフトウェアをご利用ください。
主な仕様
- 曲名の表示。長い場合は自動スクロールします。
- アーティスト名・アルバム名の表示
- 現在の再生位置の表示 (タイトルの下のアンダーバーです)
- Freq,BitDepth,Ch の表示
- アルバムジャケットイメージの表示(mutagen使用)
- 物理ボタンで、「前の曲」、「再生・一時停止」、「次の曲」が操作可能
- 一時停止中は、現在日時を表示
- 日本語表示OK
仕組み他
- ボタンの押下検出は、NanoPi Officialのプログラム(C言語)を使います。ボタン押したのを検知して、Python側にイベント飛ばしてくれます。
- NanoPi OfficialのOLED表示プログラムを参考にして作ってましたが、表示データを1バイトずつ親切丁寧にI2C書き込みしてましたので、32バイト単位転送に全面書き直しています。表示速度が2,3倍に速くなりました。
- ジャケットイメージは、mutagenによりローカルファイルアクセスして埋め込み済み画像を取ってきます。画像が無い場合は、同じディレクトリ内にある front.jpg が使用されます。
- mpdからの情報取得は、TCP経由で行っています。制御もまたしかりです。
- OSによってI2C通信が100kだったり400kだったりします。これにより表示速度が大きく変わります。
- タイトルのスクロール速度を調整する場合は、oled_mpd.pyの scroll_unit = 3 で調整可能です。
それでは、本題のインストール手順に行きます
NanoHat OLED関係を入れる
参考: http://wiki.friendlyarm.com/wiki/index.php/NanoHat_OLED
下記手順でインストールします。(インストール先は/root にしてます)
NanoHat OLEDは、CプログラムとPythonプログラムの2本構成で動いていて、OLEDの表示自体はPythonで閉じていますが、キー操作はCプログラム側で受信後、Python側に通知する仕組みになっていました。
そして、Cプログラム側ではPythonプログラムの起動も行っており、標準品を起動しないようにします。とりあえず、下記の例ではコメントアウトしています。
(代わりのPythonコードの起動はrc.localからやってます)
cd /root
git clone https://github.com/friendlyarm/NanoHatOLED.git
nano /root/NanoHatOLED/Source/main.c
・
・
・
int load_python_view() {
/*
int ret;
char* cmd = (char*)malloc(255);
sprintf(cmd, "cd %s/BakeBit/Software/Python && python %s 2>&1 | tee /tmp/nanoled-python.log", workpath, python_file);
ret = pthread_create(&view_thread_id, NULL, (void*)threadfunc,cmd);
if(ret) {
log2file("create pthread error \n");
return 1;
}
//*/
return 0;
}
・
・
・
cd NanoHatOLED
./install.sh
本題(OLED表示)を入れる
外部依存パッケージが含めインストールし、rc.localで自動起動するようにします。
すでに、NanoHatOLEDの自動起動(oled-start)が書き込まれていますので、
その次の行に起動コマンドを追加してあげます。
apt-get install fonts-takao-pgothic
apt-get install python-mutagen python3-mutagen
cd /root
git clone https://github.com/blue777/NanoPi-NEO_OLED_MPD
nano /etc/rc.local
・
・
・
/usr/local/bin/oled-start &
cd /root/NanoPi-NEO_OLED_MPD
python oled_mpd.py &
・
・
・
5. ympd (MPD Web GUI)をインストールする
ネットワーク上の各クライアントからhttpアクセスし、コントロールできるようにympdを入れてみます。
apt install cmake
apt install libmpdclient-dev
apt install libssl-dev
cd /usr/lib
git clone https://github.com/notandy/ympd
cd ympd
mkdir -p build
cd build
cmake .. -DCMAKE_INSTALL_PREFIX_PATH=/usr
make
make install
./ympd で起動しますが、都度起動も大変なので自動起動するように、rc.localを編集します。
nano /etc/rc.local
・
・
・
/usr/lib/ympd/build/ympd &
アクセスポートは8080 になるので、
http://YourMpdServer:8080/
のような形でアクセスします。
port80が良い場合は、以下のような指定を行います。
./ympd -w 80
これにてサーバー側は終了です。リブートしてお楽しみください。
reboot
クライアント側の準備
Webアクセスにて再生制御できますが、やはり専用アプリがいい!というときには、お好きな MPDクライアントを入れて下さい。
iOS, Windows, Androidなど各種MPDクライアントが出ています。MPDクライアントで検索すればいろいろ出てきますので、好きなものをインストールします。
当方はWindows機のため gmpc を使っています。
https://gmpclient.org/
audio_output で設定した項目は、Serverメニューから選択できます。
おまけ
NanoHat PCM5102a について
標準状態ではハードウェア的に、De-Emphasis, Low-Latency 状態になっています。
特にDe-Emphasisは、44.1KHz において高域カットされてしまい、若干のこもり気味に聞こえます。
De-emphasis, Low-Latencyの個所のハンダ付けがお勧めします。
音質については、普通に良いです。
10万クラスのCDプレイヤは太刀打ちできないでしょう。
ただ、(フルオケのピークなど)音が複雑に絡み合ったりすると、解像度低下が目立ち団子になります。
といっても、電源がスイッチング電源で、かつ、NanoPi-NEO共用の状態ですので、別電源など改造すればきっと覚醒してくれることでしょう。
NanoPi-NEO, NEO2 のI2S信号について
参照先
http://wiki.friendlyarm.com/wiki/index.php/NanoPi_NEO2
NanoPi-NEOで出力されるI2S信号は
- I2S0_LRC I2S/PCM Sample Rate Clock/Sync
- I2S0_BCK I2S/PCM Sample Rate Clock
- I2S0_SDOUT I2S/PCM Serial Data Output
の3つが出力されますが、NanoPi-NEO2は、上記に加え
- I2S_MCLK
も出力可能になっており、GPIOA6 に出力されます。
これは、H5のみの仕様で、H3では対応していないようです。(データシート見る限り)
そして、さらに見るとGPIOA6にPWMと書いていますが、H3/H5ともにPWMの出力先にはなれません。どこから来た誤植なのかが気になります(H2+とか?)
ひそかに I2S_MCLK 出力できるドライバ提供を期待していたりします。
■2018/01/13追加
ついに出力できました!
NanoPi-NEO2 のI2SでMCLK出力&384kHz対応
NanoPiNEO系とBeagleBone系の音質
SBC(SingleBoardComputing)でMPDを使用する理由は、まぎれもなく音質追及である。
ですので、NanoPiシリーズと、BeagleBoneシリーズの音質の個人的主観評価は、こんな感じです。
※NanoPi系はOLED取り付けていない状態です
NanoPi-NEO < NanoPi-NEO2 << BeagleBoneBlack <= BeagleBoneGreen
いずれも、SBC ---(USB)--> JAVS X-DDC(改) ---(Coaxial spdif)--> DAC とつないでの評価で、SBC, X-DDCにはInfineonのSiC SBDでブリッジ整流で組んだシリーズ電源(SBC側にはLM350、X-DDCには CreeのSiC FETでディスクリート)使用しています。
この場合において、BeagleBone系の方か、レースカーテン1枚分鮮明に出てきます。音も細かいです。
また、NanoPi-NEOおよびNanoPi-NEO2において、MPD専用ディストリビューションである lightMPDが対応してくれたのはとても喜ばしいことです。
#最後に
思いのほか出来が良かったとか、いろいろ書いたOLEDの表示回りですが、自分の本番?環境では、使われません。(笑