まとめ記事(コンテンツ)

2021/07/09

直結ネットワークオーディオ(実用化編) - MinimServer2 on OpenWrt/RaspberryPi3 -

前回製作した「直結(ハブレス)」ネットワークオーディオ。とりあえず動いたものの、ソフトウェアルーターとして実装したWi-Fiの安定性がイマイチなのが気に入らず・・・今回が実用化編となります。








みん友さんのコメントから始まった前回のプランです。私はシステムアップしただけ。
alt
サーバーとレンダラーをHUBレスで直結しています。当然ですが対向接続でつながるのは2台で、これだけではコントロールポイントともインターネットとも通信できません。サーバー役のラズパイにルーター機能を実装し、Wi-FiとEthernetをソフトウェア的に接続(ブリッジ)、上位のLANとはセグメントを分けてルーティングすることにより、非オーディオパケットがレンダラーに流れ込まないよう遮断します。

アナログ的な物量は別として、理屈ではかなり理想的なオーディオサーバーになっていると思うので構成はそのまま、ソフトウェアルーターの部分を1からやり直しました。


OS選定

使用したのはタイトル画像のOpenWrt
オープンソースのルーター用OSで、主に市販ルーターのファームウェアに上書きして使うものですが、ラズベリーパイでも動作します。Linuxベースであるのと、豊富な機能拡張用パッケージでカスタマイズできることから、今回のようにモニターもキーボードも接続しない「ヘッドレス」用途では汎用OSに近い感覚で使うことができます。

汎用OSにルーター機能を実装して苦労するなら、ルーター用OSでサーバーアプリを動かす方が近道では?
という発想です。ラズパイ用のセットアップガイドはこちら


OSのビルド

え、ビルドから始まるの?
サーバーアプリのMinimServer2用にOSの構成(ビルドオプション)を変更します。
これ近道なのか?いきなり怪しくなりました・・・

もちろん公式サイトには機種ごとのインストールイメージが掲載されていて、ラズパイの場合それをダウンロードしてmicroSDカードに書き込むだけで普通はOKです。
サーバーアプリもパッケージで簡単にインストールできるminiDLNAがあり、そちらを使えばビルド不要で簡単そうですが・・・自分はMinimServerを使いたいので、こちらの道を行きます。

ビルド環境としてLinuxが必要です。WindowsPC上にホスト型仮想化環境のVMware Workstation Playerを、その上にUbuntuをインストールしました。
alt
Ubuntu Japanese Team公式サイトからダウンロードしたISOイメージをVMに食わせるだけでセットアップがサクっと進みます。Windowsとのファイルのやり取りはドラッグ&ドロップでできますし、ハードウェアが仮想化されるおかげでUbuntu側に特別なドライバとか必要なし。DVDを焼いて素のPCにインストールするより快適ですね。

HDDの容量はビルド終了後にこのくらい膨らむので、仮想マシンに最低30GBほど割り当てておきます。他のマシン設定はデフォルトで大丈夫です。
alt

公式サイトのクイックガイドはこちら
[OpenWrt Wiki] Quick Image Building Guide

ちょうどラズパイ3B用のOpenWrtをビルドする解説記事があり参考になりました。ありがとうございます!

ガイド(「Debian / Ubuntu」の部分だけでOK)に従い、GitやSubversionなど開発系パッケージをインストールしてから以下の手順でOpenWrtのソースコードを取得します。
~/xxxxxx$ cd 
~/$ git clone https://git.openwrt.org/openwrt/openwrt.git 
~/$ cd openwrt 
~/openwrt$ git fetch --tags 
~/openwrt$ git tag -l      (Ctrl-Z to exit) 
~/openwrt$ git checkout v19.07.7 
~/openwrt$ ./scripts/feeds update -a 
~/openwrt$ ./scripts/feeds install -a 

~/openwrt$ make menuconfig 

とするとメニュー形式の設定画面になります。

上から3行でターゲットを指定。ラズパイ3Bでは64bit版と32bit版から選べ、今回は32bit版を選択しました。4行目のターゲットイメージではsquashfsを外していいです。
alt
Advanced configuration options => Toolchain optionsからUse glibcを選択します。これがビルドの目的です(後述)。
alt
OpenWrtにはaptやyumに相当するopkgというパッケージ管理システムがありますが、この選択により標準のパッケージの多くは使えなくなります。後で必要になる機能は全てここで追加してコンパイルします。
Base system --->
[*] block-mount
[*] libstdcpp
Kernel modules --->
    Filesystems --->
[*]     kmod-fs-exfat
[*]     kmod-fuse
    USB Support --->
[*]     kmod-usb-storage
[*]     kmod-usb-storage-extras
[*]     kmod-usb-storage-uas
[*]     kmod-usb-uhci
[*]     kmod-usb2
    Wireless Drivers --->
[*]     kmod-mt76x2u
LuCI --->
    1. Collections --->
[*]     luci
Multimedia --->
[*] ffmpeg
Utilities --->
    Disc --->
[*]     blkid
[*]     lsblk
    Editors --->
[*]     nano
    Filesystem --->
[*]     fuse-utils
[*] dmesg
[*] ldd
[*] tar
[*] usbutils


(2021/7/13追記)UPSのjuice4haltを使う場合は以下も追加。
Base system --->
    busybox --->
        coreutils --->
[*]         usleep


設定を保存して終了。夜寝る前に
~/openwrt$ make V=sc 
しておけば、翌朝にはbin/targetsディレクトリにイメージが出来て(またはエラーでコケて)います。

ビルドして出来たインストール用イメージ(gz形式)からimgファイルを展開しmicroSDカードに書き込みます。書き込みアプリはWin32DiskImagerRufusなどで、Raspberry Pi Imagerも使えます。


ルートパーティション拡張

初期状態のルートパーティションは256MBでした。サーバーアプリ導入用に拡張しておきます。
Gparted(Gnome PARTition EDitor)を使います。ビルド環境にインストールするか、CDやUSBメモリーから起動できるLive版もあります。
alt
画像は公式サイトより。右上のプルダウンでmicroSDカードを選択、ext4フォーマットの領域を空き領域全体に拡張、最後に適用(チェックのボタン)すれば完了です。誤ってPCのHDDを操作して起動不能にしないよう注意。
(2021/7/17追記)8GBのカードでは問題ありませんでしたが、もっと大容量のカードで空き領域いっぱいまで拡張するとエラーになることがあります。確保するサイズは1GBもあれば不足することはないでしょう。


OS起動

ローカルのコンソールはなく、PCからネットワーク経由で操作します。
初期状態ではLANポートに固定IPアドレス「192.168.1.1」とDHCPサーバーが設定されており、そのままホームネットワークに接続すると障害が発生する可能性大です。PCのLANケーブルを家のルーターから抜きラズパイと直結します。他の接続はまだ行いません。
alt

(注)ラズパイは出荷状態では内蔵Wi-Fiの地域コードが設定されておらず、設定するまで電波が出ません。しかしラズパイ3B用のOpenWrt(19.07)ではこの設定が機能していないため、インストール前に別のOS(Raspberry Pi OSのraspi-configなど)でコードを「JP」に設定する必要があります。
Wi-Fiは地域コードを元に出力レベルや周波数を制限することで、国ごとの規制に対応しています。誤った設定だと国内法を逸脱した電波を出力する可能性があるので、他の国に設定するのは「ご法度」です。設定はハードウェア(EEPROM)に記憶され、OSを変更しても上書きしない限り維持されます。

コンソールとして
alt
SSH接続によるCUIと(画像のアプリはPuTTY)、
alt
ブラウザで操作する「LuCI」というWebGUIが用意されています。見た目は市販ルーターの管理画面のようなこのLuCIが強力で、画面をつついているだけでご飯3杯いけそうです。この感覚わかる方は是非。

ラズパイ版のファイルシステムは普通のext4のため、電源を落とすときはSSHコンソールからコマンドを入力します。面倒なので最後にUPSを導入して自動化します。
# poweroff 

(注)外部からラズパイに侵入されないよう、ホームルーターの設定を必ず確認します。プロバイダーとの契約内容によっては、ラズパイのポートがIPv6で外部から丸見えになる場合があります。しかも最大手のフレッツなどデフォルトの設定でそうなっているところもあり危険です。NATとかプライベートアドレスとかv4時代の生半可な知識は罠ですよ、というのは自分の話。


OpenWrtの用語

以下の用語を理解しておくと設定がやりやすいと思います。

デバイス(radio0, eth0など)
:物理的なネットワーク用ハードウェア。LANやWi-Fiアダプター。

インターフェース(wlan0, br-lanなど)
:デバイスを設定することによって作成される「接続」。デバイスと1対1とは限らず、複数のインターフェースを束ねた仮想的なインターフェースもある。

ゾーン(wan, lanなど)
:インターフェースをWAN側やLAN側に割り当てた「まとまり」。

例えば、radio0 という「デバイス」で上位のルーターに接続すると「インターフェース」wlan0 になり、それを「ゾーン」wan に所属させる、といった感じ。
LANポートをローカル側にしたりインターネット側にしたりといった設定が柔軟にできるようになっており、なるほど良く出来ています。


Wi-Fiネットワークに接続

ラズパイの内蔵Wi-Fiでインターネットに接続します。
alt

LuCIなら市販ルーターの感覚で簡単に設定できると思います 。ユーザーガイドはこちら。
[OpenWrt Wiki] Connect to client Wi-Fi network

「Network」-「Interface」画面を開き、EditボタンからLAN側IPアドレスを上位のネットワークと別のアドレス(冒頭のシステム図では192.168.13.1)に変更。いったんPCの接続が切れ、90秒以内にブラウザorSSHを開きなおして再接続すると有効化されます。
alt
「Network」-「Wireless」画面を開き、デバイス「radio n」(n=0,1,2...)でネットワークのスキャンを実行。見つかったアクセスポイントに接続すると、インターフェース「wlan n」が作成されます。ゾーンやルーティングは自動で入力されるので確認だけ。
alt
alt


ローカルネットワーク構築
alt
現在のOpenWrtでは、ラズパイの内蔵Wi-Fiを使ったAP-STAモード(アクセスポイントとクライアントの同時利用)は動作しないようです。USB接続のWi-Fiアダプターを1個追加し、有線LANとブリッジを構成します。

(参考情報)
GitHub - USB WiFi Adapter Information for Linux

公式にドライバーが用意されている機種でもアクセスポイントとしては使えない場合があります。いくつか失敗して落ち着いたのがこれ。
alt
A6210-100JPS(NETGEAR)
WiFi 無線LAN USBアダプター 子機 AC1200 867+300Mbps 高性能アンテナ USB延長ケーブル付き


ちょっと大柄ですが、OpenWrtで動作実績のある機種を購入しました。

搭載チップを確認。
# lsusb
Bus 001 Device 004: ID 0846:9053 NetGear, Inc.

チップは MediaTek MT7612U です。

Wi-Fiの機能を確認。
# iw list -A 4 "interface combinations" 
    valid interface combinations: 
        * #{ IBSS } <= 1, #{
managed, AP, mesh point } <= 2, 
          total <= 2,
#channels <= 1, STA/AP BI must match 
ハードウェアとしてはAP-STAモード対応で、実際に設定もできましたが安定動作しませんでした。単機能で使う分には安定しているので、アクセスポイント専用に使用します。

「Network」-「Wireless」画面を開くと、接続したデバイスが増えています。Editボタンから「アクセスポイント」モードのインターフェースを追加。
alt
alt
追加したインターフェースはデフォルトで「lan」ゾーンに割り当てられています。
alt
br-lanという仮想インターフェースが最初から設定されていて、ここに追加されたインターフェースはルーターのローカルネット側端子のようにブリッジされて同一ネットワークになります。前回のようにインターフェースやデーモンの起動順序を気にする必要もなく、LuCIのGUIで直感的に設定できます。

これでネットワークが構成できました。さすがはルーター用OS、この種の設定はお手のもの。
反面ここから先はルーター用OSにルーター以外の仕事をさせるためちょっと面倒になります。GUIは使えずコマンドラインで操作します。


USBディスクのマウント
alt
サーバーを構築するため、USBストレージを接続します。
alt
ポータブルSSD 480GB SSD-PL480U3-BK/N (バッファロー)

exFAT形式でフォーマットし楽曲ファイルを入れたSSDを接続し、認識されることを確認します。
# blkid 
/dev/sda1
: LABEL="SSD-PLU3" UUID="C2C4-9374" TYPE="exfat" PARTUUID="dd3dafec-01"

以下のコマンドでマウントします。マウント名usbhdd1は任意です。(19.07では、exfat形式のストレージをfstabで自動マウントさせることはできませんでした。この方法だと接続するUSBポートを変えるとマウントに失敗することがあるので、以降つなぐ場所は変更しません。)
# mkdir /mnt/usbhdd1 
# mount -t exfat -o sync,dev,noatime,noexec
/dev/sda1 /mnt/usbhdd1 
# ls /mnt/usbhdd1 

ファイルが表示されればOK。

起動時にマウントするようスクリプトを設定します。/etc/rc.localファイルを直接編集するか、LuCIでも可能です。
alt


Javaのインストール

この後で入れるMinimServer2を動かすためにJavaの実行環境を準備します。
MinimServer2の要求はJava8以上。OpenWrtには「JamVM」という軽量のランタイムが用意されていますが、MinimServer2とはバージョンが合わず使えません。

ならば、とフルセットのJDK(Java開発キット)をインストールしようとしたところ、OpenJDKやOracleJDKはOpenWrtに未対応でした。
これは、OpenWrtがCのライブラリとして軽量のmusl-libcを採用しており標準的なglibcを使っていないためです。そこでOpenWrtのビルドオプションを変更してglibcを使えるようにした、というわけです。

Oracle JDK8(Java SE Development Kit)を公式サイトよりダウンロード。OSを32bitで構成したので、Javaも32bit版の「Linux ARM 32 Hard Float ABI」を使います。

PCでダウンロードしたJDKをSSDに入れてラズパイに移動し、/usr/share ディレクトリに展開します。
# cp /mnt/usbhdd1/oraclejdk-8u291-linux-arm32-vfp-hflt.tar.gz /usr/share 
# cd /usr/share 
# tar xzvf oraclejdk-8u291-linux-arm32-vfp-hflt.tar.gz 

tarで展開されたファイルのオーナー設定が正しくない?chownコマンドで修正しました。パスの通ったディレクトリにリンクを張って起動確認します。
# chown -hR root:root jdk1.8.0_291 
# ln -s /usr/share/jdk1.8.0_291/bin/java /usr/sbin 
# java -version 
Java(TM) SE Runtime Environment (build 1.8.0_291-b10) 
Java HotSpot(TM) Client VM (build 25.291-b10, mixed mode) 



MinimServer2のインストール

UPnP/DLNAサーバーのMinimServer2をインストールします。ラズパイ用は32bitのarmhf(ARMハードフロート)版です。

SSDに入れておいたMinimServerのインストールパッケージを/usr/shareディレクトリに展開します。
# cp /mnt/usbhdd1/MinimServer-2.0.18-linux-armhf.tar.gz /usr/share 
# cd /usr/share 
# tar xvf MinimServer-2.0.18-linux-armhf.tar.gz 


MinimServerのセットアッププログラムを実行。OpenWrt用にrootのシングルユーザーとして設定します。
# minimserver/bin/setup root 
MinimServer desktop integration is not available 
MinimServer automatic startup is not available 

エラーとなった自動起動は後で設定します。

MinimServerの初期設定を行うため、コマンドライン版のstartcで起動します。
# minimserver/bin/startc 
初回だけライブラリの場所を聞かれるので入力する
(ここでは /mnt/usbhdd1/Music)
alt
やったぜ。ゴールが見えてきたか?
ライブラリのスキャンが始まり、しばらく経って「MinimServer is running」と表示されれば起動完了。
alt
MinimWatch(とJava)をインストールしたPCに同じ内容が通知され、アイコンが緑色になります。ならない場合はPCのファイアウォールがJavaをブロックしていないかチェック。パブリックネットワークあるある。

startcによる起動ではコンソールを閉じるとMinimServerも止まってしまうので、いったん終了します。
>exit 
デーモン(サービス)として起動させるのは次のコマンドです。
# /usr/share/minimserver/bin/startd 
/etc/rc.localファイルに追加して自動起動させます。
alt
リブートしてPCのタスクトレイにあるMinimWatchのアイコンが再度緑色になれば成功です。
# reboot 


MinimStreamerのインストール

ここまでで通常の再生は可能になっていますが、MinimServerの特徴であるトランスコード配信を行うにはMinimStreamer(有償)をインストールします。設定方法は以前のブログをご覧ください。ffmpegはOSビルド時に追加済みのためインストール不要です。
ネットワークオーディオ自作(8) ラズパイサーバーを改良する
alt


UPSの接続とシャットダウン用スクリプトのインストール

電源を落としたら自動でシャットダウンするようUPS(無停電電源)を追加し、あわせて電源を12V化します。ハードウェアは
alt
Juice4halt J4H-HV-TRM(Nelectra)
です。こちらも上のブログで紹介しました。

UPSで自動シャットダウンさせるためのスクリプトをセットアップします。ダウンロードはこちら

/usr/shareディレクトリにjuice4haltディレクトリを作成し、SSD経由でスクリプトをコピーします。
# cd /usr/share 
# mkdir juice4halt 
# cd juice4halt 
# cp /mnt/usbhdd1/shutdown_script /usr/share/juice4halt 
# nano shutdown_script 

(2021/7/13追記)スクリプトを修正します。
・先頭のbashをshに変更
・パラメータが小数点となっているsleepをusleepで置換
 例:sleep 0.1s -> usleep 100000
・sudoを削除

/etc/rc.localの最後(exit 0の手前)に次の1行を追加。
/usr/share/juice4halt/shutdown_script & 
alt
スクリプトに実行権限を設定。
# chmod 755 shutdown_script 
電源を切断・再投入し、機能を確認します。
# poweroff 

もう一つのスクリプト、rebootj4hは標準のrebootコマンドの代わりに使用します。rebootコマンドで再起動した場合、その後の自動シャットダウンは無効となります。
# cp /mnt/usbhdd1/rebootj4h /usr/share/juice4halt 
# chmod 755 rebootj4h 
# ln -s /usr/share/juice4halt/rebootj4h /usr/sbin 
# nano rebootj4h 

こちらも同様に修正します。




以上で完成です。ネットワーク再生システムに移行し動作確認します。
設定に使ったPCをレンダラーに変更し、USB-DACを接続します。lightMPDなら同じPCをUSBメモリーから起動させればOKです。LANポートにはDHCPサーバーを設定していますがlightMPDのIPアドレスは固定のため、lightmpd.confでサーバーと通信可能なアドレスに設定しておきます。
スマホを作成したアクセスポイントにWi-Fi接続し、UPnP/DLNAコントロールアプリで再生します。
alt
この状態で24h連続再生させ特に問題なく安定動作しているので、実用化「合格」とします。結構トラブルシュートが必要でしたね。




ネットワークオーディオを、ネットワークの性能に特化したOSで動かす。いい音出そうな気がしません?
また、世の「オーディオ用HUB」が一般のHUBより高音質だとするなら、「HUBレス」の音質はどこに位置するのか?これもちょっと面白いテーマです。

64bit版も作ってみたいし、SFPも試したいところですが今はお腹いっぱい。しばらくは「聴き専」に回ることにします。


讃美歌320番「主よ、御許に近づかん」

天界まで召される見通せるような音が出てくると良いなぁ。
疲れたよパトラッシュ・・・


ネットワークオーディオ関係の記事をまとめてみました。よかったらこちらもご覧くださいませ。
ネットワークオーディオを楽しもう




(2021/7/14追記)ホームでの動作確認を終え、車載運用を開始しました。カーオーディオでの第一印象は「硬質で明確」。鮮度感のある生きた音が出てきました。

(2021/7/23追記)間違いなく楽しい音にはなったのですが、ちょっとキツいというかデジタルっぽい?これはアレだな、と
alt
iPurifier DC (iFi-Audio)
を12V化したラズパイの電源ラインに入れてみたら正解でした。ハブレスにしたことにより、ハブからのノイズ混入が無くなった一方で、サーバー側の信号品質が影響するようになった・・・のか?
いよいよ禁断のオーディオ用LANケーブルでも試してみますかね。1本で済むシステムになりましたし。

(2021/8/1追記)
LANケーブルにSAECのSLA-500を使ったところ効果あり。電源の対策と合わせて音のキツさは消えクリア・ダイナミックなメリットが残りました。HUBやネットワーク分離のためのサブルーター・それらの電源が不要な点も使いやすく、主力音源として正式採用します。
それにしてもサーバーで音が変わるなんて面白い。

(2021/7/18追記)
64bit版のOpenWrtをビルドしてみました。MinimServer2やJavaも64bit版を使用する以外、今回と同じ手順でいけます。しかし現在の19.07ではCPUのクロック制御に不具合があり、次の安定版となる21.02(今はrc3)を待った方が良さそうです。

(2021/10/17追記)
21.02がリリースとなったので、再度64bit版をビルドしました。JavaはOracle JDK8の64bit版、MinimServer2もAarch64版を使用。このバージョンでは特に目立った不具合もなく普通に使えるようになりました。逆にメモリ1GBのラズパイ3Bで64bit化したところで機能・性能的なメリットも感じませんでしたが、音質は32bit版と完全に同じではなく比べてみるのも楽しいかと。
Posted at 2021/07/09 23:52:32

イイね!0件

はてブに送る
はてブに送る

オススメ関連まとめ

マイページでカーライフを便利に楽しく!!

ログインするとお気に入りの保存や燃費記録など様々な管理が出来るようになります

まずは会員登録をしてはじめよう

みんカラ+新登場

カーライフビューティーラボ

ニュース