lightMPDのrootイメージの作成をdigifi laboに公開しました

1,742 views
Skip to first unread message

digi...@gmail.com

unread,
Jan 25, 2017, 10:56:15 AM1/25/17
to ligh...@googlegroups.com
まだ暫定版ですが、buildrootからu-bootでロード出来るrootイメージは作成できると思います。
合わせて、このイメージを含んだbeaglebone用のv1.0.3も公開しました。

2017.01.27
lightmpd-buildroot-beaglebone.tgzに誤りがありましたので再度アップロードしました。
再ダウンロードをお願いします。


もうすでにbuildをおこなっている場合は下記のように対処して下さい。

cd  ****/buildroot-2016.11.1
cp -a packages/* package
rm -rf packages

再度makeを実行して下さい。

Message has been deleted
Message has been deleted
Message has been deleted
Message has been deleted

takobozu

unread,
Jan 26, 2017, 12:52:45 AM1/26/17
to lightMPD
digififanさん
やっとこの時が来ましたね。公開ありがとうございます。
私のところで追試してみました結果気づいた点をご報告させていただきます。
ligtmpd-buildroot-bbb.tgzにあるlightmpd_beaglebone_defconfigなんですが
以下のところを修正しないと途中でエラーとなります。

BR2_PACKAGE_BUSYBOX_CONFIG="package/busybox/lightMPD-busybox-config"

BR2_PACKAGE_BUSYBOX_CONFIG="packages/busybox/lightMPD-busybox-config" に修正


takobozu

kubo...@nifty.com

unread,
Jan 26, 2017, 5:49:33 PM1/26/17
to lightMPD
‎digififan さん

lightMPDのrootイメージの作成方法の公開ありがとうございました。BBBベースで書かれているのも助かります。
以前、「lightMPDは何もいじれないから苦手だ」と思っていたのですが、とんでもない勘違いでした。これだけ公開度の高いディストリビューションはありませんね。
とりあえず公開している Boticized lightmpd のrootfs部分をこれに入れ換えるつもりです。

Message has been deleted

digi...@gmail.com

unread,
Jan 27, 2017, 1:08:19 AM1/27/17
to ligh...@googlegroups.com
takobozuさん

ご指摘ありがとうございました。
調べたら
    package
でなければならないのに
   packages
になっていました。

lightmpd-buildroot-beaglebone.tgz を再アップロードしましたので再度ダウンロードをお願いします。
takobozuさんの修正方法だとmpd-native-dsdでもエラーになります。


takobozu

unread,
Jan 27, 2017, 2:03:39 AM1/27/17
to lightMPD
digififanさん

再度アップロード、お手数をお掛け致しました。

こちらの環境でも、romfsのビルドできることを確認いたしました。
mpd-0.20rt-dsdを作って、入れ替えたり、romfs丸ごと手順に従って
作成したものと入れ替えたりして遊んでおりますが、しっかり起動いたします。
ありがとうございました。

takobozu

aki2...@gmail.com

unread,
Feb 1, 2017, 8:39:44 AM2/1/17
to lightMPD
はじめまして。動作報告?というか感想を書かせていただきます。

以前からlightMPDに使われているbuildrootに興味があったところ、今回digififanさんのイメージの作成方法が公開されたので色々試してみました。なお私は、たかじんさんのB4-dacを使っています。

手順どおりに作業して一度環境が整えば、lightMPDに足したり引いたり、簡単にカスタマイズできますね。ちなみにstable版buildrootで試してから、その設定をgit版にも持って行って試しました。

たとえばmpdパッケージについては、package/mpdやpackage/mpd-native-dsdの中のmpd.mkの設定を書きかえるなりして自分用にコンフィグ・オプションを選んでmakeもできるわけですね。私はmpd-0.20.3に20用のrtパッチを当てて、自分の必要なオプションだけでmakeしてみました。
makeの後に output/target/usr/bin/mpd に生成されるのをSDカードに持って行くわけです。(output/build/mpd-0.20.3/src/mpd にも実行ファイルがあるんですが、なぜかファイルサイズが違ったりします。まあ output/target/usr/bin/mpd の方を使うので良いのでしょうか。)

ここからの話は趣味的になりますが、uInitrdの減量も試して5.8M程にしました。自分が使わないものひたすら除いて、たとえば ffmpeg を外したり、Gaucheが生成したsetup.shを直接使うことにしてGaucheも外したり、あと/usr/share/sounds/alsaにテスト用のwavがあったりしたのでそれも一応除きました。
なお、kernelについてもbuildrootで生成しましたが、私には下手に設定をいじれないのであまりサイズは小さくできませんでした(usb関係を外したくらい)。

ついでにrpi1B+を引っぱり出して、音楽再生とは違う目的で make raspberrypi_defconfig から作ってみようと思ったんですが、こっちは今のところブートすらできず…お手本があることの有難さが身にしみます。

digi...@gmail.com

unread,
Feb 1, 2017, 10:34:00 PM2/1/17
to lightMPD
aki2muraさん

> たとえばmpdパッケージについては、package/mpdやpackage/mpd-native-dsdの中のmpd.mkの設定を書きかえるなりして自分用にコンフィグ・オプションを選んでmakeもできるわけですね。私はmpd-0.20.3に20用のrtパッチを当てて、自分の必要なオプションだけでmakeしてみました。
mpdとmpd-native-dsdはその構成がちょっと違います。
mpdはインストールの指定がされているライブラリからmenuconfigで必要なライブラリを選択出来るようになっています。
mpd-native-dsdはライブラリの選択はできません。直接mpd-native-dsd.mkのMPD_NATIVE_DSD_CONF_OPTS を変更します。
mpd-0.20.xを作る場合はmpd-native-dsdを変更したほうがいいかもしれません

> makeの後に output/target/usr/bin/mpd に生成されるのをSDカードに持って行くわけです。(output/build/mpd-0.20.3/src/mpd にも実行ファイルがあるんですが、なぜかファイルサイズが違ったりします。まあ output/target/usr/bin/mpd の方を使うので良いのでしょうか。)
output/build/mpd-0.20.3/src/mpdが正解です。
beaglebone用のconfigではmpdとmpd-native-dsdの両方をbuildするようになっています。/usr/bin/mpdにはどちらかの一方のmpdになります。
lightMPDではmpdはrootイメージからは外付けなのでこれでもいいのですが/usr/bin/mpdを使う場合はmpd,mad-native-dsdの使う方だけをbuildして下さい。

> ここからの話は趣味的になりますが、uInitrdの減量も試して5.8M程にしました。自分が使わないものひたすら除いて、たとえば ffmpeg を外したり、Gaucheが生成したsetup.shを直接使うことにしてGaucheも外したり、あと/usr/share/sounds/alsaにテスト用のwavがあったりしたのでそれも一応除きました。
殆どの場合、flac,alac,mp3,wavだけで十分なのでlightMPDでもffmpeg を外したいのですが、一度サポートした物を削除するのはなかなか難しいのと、tagの解析はffmpegが優れているようなので残してあります。
setup.shを直接使うという事は、ipアドレス、nasの設定は固定になると思いますが、それならlightmpd-root はインストールしないで直接/etc/network/interfacesや/etc/fstabを編集してしまったほうがいいと思います。
lightMPDを発表するまでは私もこのようにして使っていました。しかし、5.8Mというのはすごいですね。可能ならdot.configをみせてもらえないでしょうか?

提案ですが、設定が固定でいい場合はboot deviceをマウントする必要がないのでkernelからusbのmmcやfat関連のドライバーも削除できます。
upnpgwのクライアントとして使う場合は、これに加えて、nfs,cifs,notify-inodeなど相当のドライバーをkernelから削除できます。rootイメージに合わせてkernelのスリム化にも挑戦
して見て下さい。

> なお、kernelについてもbuildrootで生成しましたが、私には下手に設定をいじれないのであまりサイズは小さくできませんでした(usb関係を外したくらい)。
lightmpdを起動すると/proc/config.gz にlightmpdのkernelのconfigが格納されています。
これを元にkernelをbuildしたらいいと思います。

> ついでにrpi1B+を引っぱり出して、音楽再生とは違う目的で make raspberrypi_defconfig から作ってみようと思ったんですが、こっちは今のところブートすらできず…お手本があることの有難さが身にしみます。
raspi等のarm系の場合はlightmpdのconfigを修正した方が早いです。
menuconfigでの変更箇所は


Target options

   Target Architecture (ARM (little endian))  --->
   Target Binary Format (ELF)  --->
   Target Architecture Variant (arm1176jzf-s)  --->
   Target ABI (EABI)  --->
   Floating point strategy (VFPv2)  --->
   ARM instruction set (ARM)  --->

System configuration > Run a getty (login prompt) after boot

   --- Run a getty (login prompt) after boot
   (ttyAMA0) TTY port
         Baudrate (115200)  --->
   (vt100) TERM environment variable
   ()    other options to pass to getty

です。
なぜかraspberrypi_defconfigでは gettyのttyが違っています。

さらにmpd-native-dsd.mkのMPD_NATIVE_DSD_CONF_OPTSのCFLAGS,CXXFLAGを
     CFLAGS="-O2 -DHAVE_DECODER_SELECTOR -DUSE_EXTEND_AUDIO_FORMAT" \
    CXXFLAGS="-O2 -DHAVE_DECODER_SELECTOR -DUSE_EXTEND_AUDIO_FORMAT" 

に変更して下さい。

実際にbuildしたわけではないのですが、これでbuildできると思います。

Message has been deleted

takobozu

unread,
Feb 2, 2017, 1:40:55 AM2/2/17
to lightMPD
digififanさん

mpd-native-dsd.mkのお話が出てましたので質問させてください。

CFLAGS=やCXXFLAGS=を明示されてますが、buildrootはここでこの指定をしてやらないと
いけないのでしょうか?それとも、この、mpd-native-dsd.mkに限ったことで、
通常のmpdディレクトリにあるmpd.mkに関してはこのような設定はする必要はないんでしょうか?

あと、ビルドされたmpdについてですが、私はtartgetディレクトリにある/usr/bin/mpdを
使っています。これはファイルサイズが小さく(stripで小さくするみたいのことを聞いた
ことがあります。)、これが本来romfsに含まれるものだと思っていましたので。
実際、この小さい方のファイルでmpdの着せ替えをしておりますが、ちゃんと起動して
おります。なのであまり疑問に思ったことがございませんでした。

takobozu

digi...@gmail.com

unread,
Feb 3, 2017, 2:16:26 AM2/3/17
to lightMPD
takobozuさん

> CFLAGS=やCXXFLAGS=を明示されてますが、buildrootはここでこの指定をしてやらないと
> いけないのでしょうか?それとも、この、mpd-native-dsd.mkに限ったことで、
> 通常のmpdディレクトリにあるmpd.mkに関してはこのような設定はする必要はないんでしょうか?
mpd-native-dsdではlightMPDで作成したパッチを有効にするために

 -DHAVE_DECODER_SELECTOR ...

を指定します。この指定はmpd-native-dsd.mkでしか行えません。
CFLAGS,CXXFLAGSには -march=.. のように最適化のオプションも指定してあります。
このような最適化の指定はtoolchain のoptimize options で指定すべきものと思いますが、ここできつい最適化を
指定するとコンパイルエラーになるパッケージがあったり、実行時に不可解な動作する場合があったのでlightMPDでは
-O2 としか指定していません。(これはlightMPD開発当初にあった現象でいまでは直っているかもしれません。)
そこで、mpd-native-dsdで最適化のオプションを指定しました。
lithtMPDではオリジナルのmpdを使わないので弄っていません。

> あと、ビルドされたmpdについてですが、私はtartgetディレクトリにある/usr/bin/mpdを
> 使っています。これはファイルサイズが小さく(stripで小さくするみたいのことを聞いた
> ことがあります。)、これが本来romfsに含まれるものだと思っていましたので。
/usr/bin/mpdでもoutput/build/mpd.../src/mpd でもどちらも動きますからどちらでもいいです。
公開したコンフィグではmpdとmpd-native-dsdの両方をbuild指定してあります。/usr/bin/mpdには mpd-native-dsdのmpdになります。
aki2muraさんはオリジナルのmpd(内容は0.20.xに変更)のmpdを使いたいようなので目的の物はoutput/build/mpd/src/mpdだと説明しました。

aki2...@gmail.com

unread,
Feb 3, 2017, 6:19:57 AM2/3/17
to lightMPD

digififanさん

詳細なコメントをいただき助かります。

>setup.shを直接使うという事は、ipアドレス、nasの設定は固定になると思いますが、それならlightmpd-root はインストールしないで直接/etc/network/interfacesや/etc/fstabを編集してしまったほうがいいと思います。

たしかにそうするのが素直かと思いました。見直してみると、標準のbuildrootからの変更点も私の場合多くないので、overlay機能で付け加えるのでも良さそうに感じてきました。このへん検討してみます。

>lightMPDを発表するまでは私もこのようにして使っていました。しかし、5.8Mというのはすごいですね。可能ならdot.configをみせてもらえないでしょうか?

後ほどメールでお送りします。BBG+B4dacでの再生のため自分用に設定してるので汎用性はないですけれども…

>提案ですが、設定が固定でいい場合はboot deviceをマウントする必要がないのでkernelからusbのmmcやfat関連のドライバーも削除できます。

ブート後に必要なければ、kernelやuInitrdにはディスク関連の機能はなくて良いのですね。現状ではnfsだけ使ってるので、他を外す形で試そうかと思います。

ただ、SDのマウントができないとなると、アップデートにはSDを抜くなりして別のシステムでの編集が必要で、ちょっと手間です(今はSDをマウントして、nfsからuInitrd等をコピーしてます。)
その点ではnfsブートできるなら楽かな、と思うのですがuEnvあたりの設定で可能だったりするんでしょうか?

>upnpgwのクライアントとして使う場合は、これに加えて、nfs,cifs,notify-inodeなど相当のドライバーをkernelから削除できます。rootイメージに合わせてkernelのスリム化にも挑戦して見て下さい。

BBGをクライアントにして完全に再生専用にするのはおもしろそうです。
今のところupnpの環境がないので試せないのですが、2つのpolipo同士を接続するなどは興味があります(apuも持ってなんですが…少し安めのapu2c0というのもあるんですね)。

あるいは、raspiなどにmpdを入れてoutputをhttpdして、BBGのmpdで受け、さらにpolipoを挟むとupnpっぽくなるかな?とも考えているんですが、まだ実行してません。

>> ついでにrpi1B+を引っぱり出して、音楽再生とは違う目的で make raspberrypi_defconfig から作ってみようと思ったんですが、こっちは今のところブートすらできず…お手本があることの有難さが身にしみます。
>raspi等のarm系の場合はlightmpdのconfigを修正した方が早いです。

>(中略)
>実際にbuildしたわけではないのですが、これでbuildできると思います。

情報ありがとうございます。raspiについても、やはり動くことがわかってるlightmpdをベースにするのが簡単なのでしょうね。こちらもそのうち試してみたいと思います。

digi...@gmail.com

unread,
Feb 5, 2017, 8:36:30 AM2/5/17
to ligh...@googlegroups.com
aki2muraさん

>  たしかにそうするのが素直かと思いました。見直してみると、標準のbuildrootからの変更点も私の場合多くないので、overlay機能で付け加えるのでも良さそうに感じてきました。このへん検討してみます。
この前のレスは舌足らずでした。romfsの場合/var等もread only に成りますのでlightMPDがやっているように起動時に/varを構築する必要があります。
rootfs.cpioの場合は読み書きできるので/varの構築は必要ありませんが、ext2ファイルシステムを使うのでkernelにext2のドライバーが必要になります。
いろいろ試して見て下さい。

2017.02.06 下線部分は間違ってました。
rootfs.cpioはrootfsというファイルシステム上に展開されます。rootfsは読み書き可能です。

> その点ではnfsブートできるなら楽かな、と思うのですがuEnvあたりの設定で可能だったりするんでしょうか?
nfsというかnetwork経由のbootですね。これならuEnvの設定で可能です。

> 今のところupnpの環境がないので試せないのですが、2つのpolipo同士を接続するなどは興味があります(apuも持ってなんですが…少し安めのapu2c0というのもあるんですね)。
>
>あるいは、raspiなどにmpdを入れてoutputをhttpdして、BBGのmpdで受け、さらにpolipoを挟むとupnpっぽくなるかな?とも考えているんですが、まだ実行してません。
upnpgwにはルータの機能があってちょっと複雑になりますが、upnpの機能に絞ればそれほど難しくありません。
raspi2 にusb -> ether アダプターを接続してルータにしたことがあるのですが、十分実用になってました。

今の状態が落ち着けば upnpgwの設定ファイルも公開する予定です。
それを使えばbeagelboneやraspiなどにusb-etherアダプターをつなげてupnpgwにしたてる事ができます。
kernelもupnpgwの機能に絞れば、いまのkernelにusb-etherのドライバーを追加するだけになります。
すでにraspiやbbbを余分に持っている場合はこの方がいいと思います。

aki2...@gmail.com

unread,
Feb 5, 2017, 11:38:33 AM2/5/17
to lightMPD
digififanさん。

前回もあわせて様々にアドバイスいただき有難うございます。buildrootを最近私は使い始めたばかりということもあるので(その点では、configの件もそのつもりで見ていただければと…)、大変参考になります。

> すでにraspiやbbbを余分に持っている場合はこの方がいいと思います。

私もraspiについては、1B+、2B、3B と持ってます(しかし動いてるのは2Bだけ…)。普通のPCにくらべると安いと思って買ってしまうんですよね。

アドバイス頂いた件は、まずは一つづつ試して行きたいと思います。区切りがつけば、結果報告させていただくかもしれません。

hidefu...@gmail.com

unread,
Feb 6, 2017, 8:35:21 AM2/6/17
to lightMPD
いつもありがとうございます。

手順どおりにやっているつもりですが、以下のところでエラーとなります。

# roofsを initrd.romfsに戻します。
sudo genromfs -f ../initrd.romfs

のところで、genromfs「コマンドが見つかりません」となります。単純なミスをしているのだ
ろうと思うのですが、見当がつきません。お手数をお掛けしますが何方か教えてやってください。

digi...@gmail.com

unread,
Feb 6, 2017, 9:02:37 AM2/6/17
to lightMPD
hidefuku1956さん

genromfsコマンドはdebianやubuntuなら

sudo apt-get install genromfs

でインストールできます。
それ以外のディストリビューションの場合はちょっとわかりません。

hidefu...@gmail.com

unread,
Feb 6, 2017, 7:12:12 PM2/6/17
to lightMPD
お忙しい中、ありがとうございます。

そう云えば、VMware環境にUbntuを導入しておりますが、インストール後の
updateなどを失念しており、初期状態のまま操作しておりました。

初歩的なミスでお手数をおかけいたしました。

takobozu

unread,
Feb 6, 2017, 8:16:50 PM2/6/17
to lightMPD
digififanさん

ご回答いただきありがとうございます。勉強になります。
私は今回公開されているやり方でlightmpdbbbv1.03に
upmpdcli+polipoを組み込んでみました。

/lighmtMPD/mpd.confには

input {
plugin "curl"
proxy "127.0.0.1:8123"
}

を追加した状態です。

/lightMPD/lightmpd.confはnfsをマウントするように設定してあります。


まず、cantata(mpdclieant)から再生をしてみました。
topで/usr/bin/polipoのvszを観察します。
再生を開始するともちろん音はでます。
polipoのvszは全く変化はありません。もちろん、upmpdcliのvszも変化なしです。
今までどおりの再生をしているわけですから当然ですね。

次に、cantataを停止し、LUMINを起動します。
LUMINにはcantataで再生していた曲目が表示されています。当然ですが。
LUMINを起動した瞬間からupmpdcliのvszが跳ね上がり、一定の値で止まります。
LUMINで再生を開始します。
もちろん、音がでます。
しかし、polipoのvszには変化がありません。

今度は、LUMINで表示されているplaylistの曲目を削除し、あらためてLUMINで
選曲した曲を再生します。
今度は、polipoのvszも跳ね上がり出しました。音もちゃんと出ております。

以上のような状態ですが、これで通常のnfsの再生とupnpレンダラーの再生
両方ともできていると解釈してよろしいんでしょうか?

takobozu

digi...@gmail.com

unread,
Feb 7, 2017, 6:59:51 AM2/7/17
to lightMPD
takobozuさん

> 以上のような状態ですが、これで通常のnfsの再生とupnpレンダラーの再生
> 両方ともできていると解釈してよろしいんでしょうか?
いいと思います。

前後しますが、

> LUMINを起動した瞬間からupmpdcliのvszが跳ね上がり、一定の値で止まります。
> LUMINで再生を開始します。
> もちろん、音がでます。
> しかし、polipoのvszには変化がありません。

これはcantataで再生を開始した状態でLUMINでplaylistを除いたという状態ですね?
これでupmpdcliのvszが跳ね上がるというのが解りませんが、この状態ではまだnasからのデータを再生しています。
LUMINで再生を指示するとpolipoを経由するのでpolipoのvszは増えると思います。

mpdクライアントの動作は

  mpdから tag_cacheを受信
      tag_cacheから曲を選択
      playlistに登録

になります。
playlistにはファイル名(nas上のファイル)が登録されます。

一方dlnaコントロールポイントの動作は

     dlnaサーバーから楽曲のurlを取得
     upmpdcliにdlnaコマンドでplayを指示
        upmpdcliはplay指示をmpdのplaylistに登録

になります。
playlistにはdlnaサーバー内の楽曲のurlが登録されます。

mpdクライアントもdlnaコントロールポイント(upmpdcli)も同一のplaylist を参照して
再生状態を表示しますので、このような動作になります。

Message has been deleted

aki2...@gmail.com

unread,
Feb 11, 2017, 1:41:37 AM2/11/17
to lightMPD
こんにちは。いくつか試してみたことを報告します。

(1) buildrootでの減量の件ですが、nfs利用のみにしぼって、uInitrd が 3.5M、 zImage が 2.4M になりました。いちおう動いてます。
これには/usr/lib/*.so*のうち、不要そうなものを削除したりもしました。たとえば telnet でログインして:

for i in /usr/lib/*.so; do test "`grep $i /proc/*/maps`" = "" && echo -n "$i "; done; echo

の様にすると、現在のプロセスで利用されてない*.soが分かります。ただ、libeventなど、たぶん利用されてるはずのものも混るので、名前から類推して必要そうなものは残してあります。
このへんのconfig等の設定については、システムの様子をしばらく見てから、みなさんの参考までにGoogle driveにでも上げてみようかと思っています(たぶん2月末?)。

(2) 話が脱線ぎみですが、前にシステムA(raspiなど)でhttpdでoutputして、システムB(BBGなど)でcurlで受けて、その間にpolipoを挟めるか、ということを書いたのですが、curlで受けるところまではOKでした。
ただし、たとえばシステムB側にpolipoを挟もうとすると、

CURL failed: The requested URL returned error: 502 Unknown server HTTP version

というメッセージが出て上手く行きませんでした。そういうわけでイマイチな結果ですが、参考までにA側のhttpdの設定を書いておきます:

audio_output {
type "httpd"
name "Stream A"
encoder "flac"
compresion "0" #0(least compresion)-8(most compresion)
port "8000"
}

encoderの部分はwaveやnullもマニュアルによるとありますが、なぜかB側で受けられませんでした。なお、再生に関してはB側のaudio_buffer_sizeの設定がだいぶ影響します。
結局polipoを使うなら、素直にupnpにした方がよさそうです。

3. mpd本体を改造すると、再生の前に自動でデータをRAM上(あるいはSD上)にコピーして再生する、という動作をさせられるようです(いわゆるramplay(volumioに関し、たかじんさんの記事で見ました)、メモリ再生)。
上の2を試してる内、mpdはinputもプラグインで行なっていて、ファイル読み込みに関しても同じと気づいたので、そこのコードを見て改造してみました。以下がそのパッチです:

################################################################################
diff -ruN a/src/fs/io/FileReader.cxx b/src/fs/io/FileReader.cxx
--- a/src/fs/io/FileReader.cxx 2017-01-27 16:46:51.000000000 +0900
+++ b/src/fs/io/FileReader.cxx 2017-02-11 14:09:00.735098365 +0900
@@ -24,6 +24,9 @@

#include <assert.h>

+#include <stdio.h>
+#include <stdlib.h>
+
#ifdef WIN32

FileReader::FileReader(Path _path)
@@ -87,12 +90,21 @@

#else

-FileReader::FileReader(Path _path)
+FileReader::FileReader(Path _path, bool ramplay)
:path(_path)
{
fd.OpenReadOnly(path.c_str());
if (!fd.IsDefined())
throw FormatErrno("Failed to open %s", path.ToUTF8().c_str());
+ if (ramplay && fd.GetSize() < 200000000) {
+ char tdir[] = "/tmp/mpd-temp-file";
+ char cmd [256];
+ memset(cmd, 0, sizeof(cmd));
+ snprintf(cmd, sizeof(cmd), "cp \"%s\" %s", path.c_str(), tdir);
+ system(cmd);
+ fd.Close();
+ fd.OpenReadOnly(tdir);
+ }
}

FileInfo
diff -ruN a/src/fs/io/FileReader.hxx b/src/fs/io/FileReader.hxx
--- a/src/fs/io/FileReader.hxx 2017-01-27 16:46:51.000000000 +0900
+++ b/src/fs/io/FileReader.hxx 2017-02-11 04:51:03.744126028 +0900
@@ -46,7 +46,7 @@
#endif

public:
- explicit FileReader(Path _path);
+ explicit FileReader(Path _path, bool ramplay=false);

#ifdef WIN32
FileReader(FileReader &&other)
diff -ruN a/src/input/plugins/FileInputPlugin.cxx b/src/input/plugins/FileInputPlugin.cxx
--- a/src/input/plugins/FileInputPlugin.cxx 2017-01-27 16:46:51.000000000 +0900
+++ b/src/input/plugins/FileInputPlugin.cxx 2017-02-11 04:51:03.744126028 +0900
@@ -57,7 +57,7 @@
OpenFileInputStream(Path path,
Mutex &mutex, Cond &cond)
{
- FileReader reader(path);
+ FileReader reader(path, true);

const FileInfo info = reader.GetFileInfo();
################################################################################

cxxの中でshellを呼ぶという手抜きですが、お試しと言うことで…。
これを当ててmakeしたmpdを使うと、ファイル読み込みして普通に再生する場合(input に file pluginを使う場合)は、すべて自動でramplayになります。
lightMPDの様にtmpfsを使っているのが前提です。パッチ内の /tmp/mpd-temp-file をSDの場所に変えればSD再生になります。BBG はメモリが512MBなので、fd.GetSize() < 200000000 と制限をつけてます(もっとメモリの大きいシステムや、SD再生にすれば不要でしょう。ただ転送時間はどうか?)。
データをコピーしてから再生するので、再生中にネットワークへのアクセスがなくなり、その影響を受けなくなると思われます。なお、ramplay関係については、他にもaudio_buffer_sizeを大きくする話があったと思います。

joecoo...@gmail.com

unread,
Feb 11, 2017, 2:24:41 AM2/11/17
to lightMPD
横から失礼します。

現状、「playerのpolipoとupnpgwのpolipoをカスケードにする」と再生が上手くいかない問題があったと思うのですが、upnpgwではpolipoを使い、playerではaki2muraさんが見つけられたramplayの設定を使えば、polipoのカスケードと同じ効果が得られるのではないでしょうか?

Linuxやプログラミングの知識がないので、見当違いかもしれませんが。

aki2...@gmail.com

unread,
Feb 11, 2017, 8:07:27 AM2/11/17
to lightMPD
joecoolさん、こんばんは。

私はupnpの理解が浅く、カスケード問題も良くわかってないんですが、たぶん上の(3)では直接の解決にならないと思います。もしかすると(2)と(3)をつづけて書いたので誤解が生まれたかもしれません。

上の(3)の話は、「wav・flac等のファイルをRAM(or SD)に普通にコピーして再生する手続き」を自動化する話です。
一方で、私の大雑把な理解ですが、upnpはファイルをストリームにして受け渡しするのだと思います。プラグインもcurl受けなので、(3)で改造したfile pluginと違ってきます。ストリームをcurl pluginの改造でRAMにキャッシュできるかは、ちょっと分かりません。

joecoo...@gmail.com

unread,
Feb 11, 2017, 8:29:25 AM2/11/17
to lightMPD
aki2muraさま

横から失礼をしました。
無知ながらもなんとなく違いがわかりました。
そう都合よくいかないものですね。

digi...@gmail.com

unread,
Feb 11, 2017, 10:56:44 AM2/11/17
to lightMPD
aki2muraさん

> (1) buildrootでの減量の件ですが、nfs利用のみにしぼって、uInitrd が 3.5M、 zImage が 2.4M になりました。いちおう動いてます。
ゲッ、これはすごいですね。

> このへんのconfig等の設定については、システムの様子をしばらく見てから、みなさんの参考までにGoogle driveにでも上げてみようかと思っています(たぶん2月末?)。
upされるのを楽しみにしています。

> ただし、たとえばシステムB側にpolipoを挟もうとすると、
> CURL failed: The requested URL returned error: 502 Unknown server HTTP version
> というメッセージが出て上手く行きませんでした。そういうわけでイマイチな結果ですが、参考までにA側のhttpdの設定を書いておきます:
polipoを挟むとネットラジオで再生出来ない局があるという報告がありました。
その時の調査ではネットラジオにつないだときにヘッダーが付いている局といきなりバイナリーのデータが流れてくる局の
2通りがありました。ヘッダーの付いていない局はpolipoがエラーをcurlに通知し502のエラーが出てました。
多分output http もヘッダーがついていないと思われます。
局によってヘッダーの内容も違うはずなのでpolipoで対応するのは困難ですが、ouput http でヘッダーをつけることは出来るかもしれません。
output httpの出力の内容を確認するには curlコマンドで mpdにつなぐことでできます。

ramplayはアイデアですね。おもしろいです。

aki2...@gmail.com

unread,
Feb 12, 2017, 10:57:15 AM2/12/17
to lightMPD
digififanさんにヒントを頂いたので、もう少しhttpd->curl&polipoを試したところ上手く行きました。

* 構成
A: raspi(いまのところ普通のdebian)、eth0をBに接続、eth1はホーム・ネットワークに接続。
B: BBG(buildroot)、eth0をAに接続。

mpd A (httpd output) --> polipo A --> eth0 A --> eth0 B --> polipo B --> mpd B (curl input) --> dac..

の構成で、Bにあらかじめ mpc add http://.. などでAのアドレスを渡す。曲の選択・操作などはAのmpdで行う。

* やったこと。
ヒントを元に、Aのマシンで curl --head 127.0.0.1:8000 とすると、以下の出力を得ました。

HTTP/1.1 200 OK
Content-Type: audio/flac
Connection: close
Pragma: no-cache
Cache-Control: no-cache, no-store

どの辺がpolipoにとって足りないのか、これだけだと私にはわからず、またhttpdの構成も把握できてないので、mpd側の改造はちょっと難しそうでした。しかし一方で、digififanさんのコメントからすると、ちょっとしたことの様にも思えます。
そこで思い立ち、polipoのエラー箇所をコードの中から探すと server.c というファイル中にみつかりました。そこでは、

if(version != HTTP_10 && version != HTTP_11) {
...

のような部分があって、ここで version が取れてないとエラーで止まる仕様。物は試しと、この中を書きかえて、エラー処理を消してかわりに「version = HTTP_11」と代入する形にしました。荒っぽい対処ですが、まあとりあえずということで…
この改造でmakeしたpolipoをA、Bにおいて、上手く繋がるようになりました。htop等で動作も確認したのでOKだと思います。
この構成だとB側はmpd+flac(+polipo)だけあれば良く、SD・nfsのマウントも必要ないので、相当サイズを小さくできそうです。

digi...@gmail.com

unread,
Feb 13, 2017, 10:22:54 PM2/13/17
to lightMPD
aki2muraさん

> ヒントを元に、Aのマシンで curl --head 127.0.0.1:8000 とすると、以下の出力を得ました。
> HTTP/1.1 200 OK


> if(version != HTTP_10 && version != HTTP_11) {

versionはhttpParseServerFirstLine(http_parse.c)でセットされます。
ヘッダーとしては

> HTTP/1.1 200 OK

がかえってきているのでこのエラーが出るはずはないのですが、おかしいですね。

mpdのhttp outputはHTTP/1.1を出力しているのでaki2muraさんの修正でも問題なさそうですが、ちょっと気持ち悪いです。

aki2muraさんに刺激されてmpdのhttp outputについて調べて見ました。

null エンコダーはdecoder から渡されたデータをそのまま送ってます。decoderからはpcmが送られてくるのでhttpにpcmデータが
流れるのですが、pcmのスペックは渡りません。これを使う場合は44.1/16などに固定する必要があります。
今のところmpdのcurlではこれを受けるのは難しそうです。

dsdを使わない場合はhttp outputは有効だと思います。
しかしencoderにflacを指定した場合、flacやalacを再生するとdecoderでflac(またはalac)->pcmの変換が行われ,http oupputで
pcm->flacの変換が行われる事になり不効率です。

なんとかencoderにwaveが使えるといいのですが、

aki2...@gmail.com

unread,
Feb 15, 2017, 10:11:05 AM2/15/17
to lightMPD
digififanさん、調査ありがとうございます。

確かにpolipoの件は奇妙な様なので、http_parse.c等が今回の場合にどう動いてるか、時間のある時にもう少し調べたいと思っています。

A->Bの間のencoder->decoderの件も気になるところです。実は先週末に、nullやwaveについて多少テストしました。outputのencoderでnullを使った場合、curlで読んだとき、

Content-Type: application/octet-stream

と表示されるので、input側のpcm decoderのコードPcmDecoderPlugin.cxx中のpcm_mime_typesに、"application/octet-stream"を追加すると、44.1kHzの音楽ファイルであれば再生できました。ただし48kHzでは雑音になります。
これは、pcm_stream_decodeという関数中でaudio_formatに44100などのデフォルト設定を決めてるためと思われ、digififanさんの書いた事情の通りかと思います。
同じ関数のなかで、データを読み取ってaudio_formatを再設定をしているので、この辺にちゃんと値を渡せればあるいはnullも使えるのかとは思ったんですが、具体的なところは分かりませんでした。

なお、waveの場合は、たとえばaudiofileのaudiofile_mime_typesに、同じ様にcurlで出てきた"audio/wav"を安直に追加してみましたが、再生もダメでした。

なんとなく、flacはmpd中でもコード量が多く手厚い雰囲気で、httpdのことも考慮されてるのかもと感じます。ところで先程調べたところ、flacは無圧縮?にできるそうで、コマンドとしては、

flac --disable-constant-subframes --disable-fixed-subframes --no-seektable -l 0 -b 4608 -V a.wav

などが見つかります。実際wavをflacに変換しても、ファイルサイズが変わりません。これを使うので良ければ、FlacEncoderPlugin.cxx中のflac_encoder_setupで

FLAC__stream_encoder_set_compression_level (libFLACの関数)

を呼んでる部分をコメントアウトして、代わりに

FLAC__stream_encoder_disable_constant_subframes

など対応する関数を書けば良さそうに見えます。(出張中なもので、試すとしても週末になりますが…)

http渡しでA->Bで役割を分離できるのは、なかなか楽しいかもしれません。特に、B側をBBGなどにするとCPUの処理能力は低いので、代わりにA側に高性能なraspi 3Bなどのシステムを使って補う、という使い方もできそうです。たとえばAで整数倍アップサンプリングしてBに渡す、など試してみたいと思いました。

aki2...@gmail.com

unread,
Mar 3, 2017, 8:49:40 AM3/3/17
to lightMPD
こんばんは。しばらく間が空いてしまいましたが、http output(A)->curl input(B)の構成(polipoつき)のことで、わかったことなど報告します。

(1) mpdのhttp outをpolipoで受けるには改造が必要という話ですが、コードにprintfをくっくけ出力を見て、原因がわかった気がします。
polipoのhttp_parse.cのhttpParseServerFirstLineは、HTTP 1.1 OK..というヘッダを期待しています。一方、mpdはこの ServerFirstLine (curl --headでは出てこない?)で、mpdのIcyMetaDataServer.cxxのicy_server_metadata_headerによるヘッダICY 200 OK..を渡してる様で、ここで問題が起きる様でした。

(2) また、別の問題なのですが、http outで数曲再生していると、polipoが突然ダウンすることがあります。どうも、polipoが想定してない使い方のせいか、offset(object.cのobjectAddData内だとか、lockChunkのiなど)がC言語の整数型の最大値を越えてマイナスになりエラーが起きるようです。
対策として、曲と曲の合間に、B側に mpc で stop・play を自動で送って繋ぎ直す形にすると、offsetがリセットされる様子で一応大丈夫になりました。ただ、もっと良い方法があるかもしれません。

(3) 出力のencodeをどうするかという件は、結局、Null encoder (A側)で素のPCMデータを送ってPCM decoder(B側)で受ける形にしました。これだとaudioformatを別に渡す必要があるわけですが、mpdの中で完結させるにはちょっと知識が足りなかったので、もう一つ通信を開いてデータを渡すことにしました(busyboxのnetcatを利用)。
ちなみに、
ramplay->オーバーサンプリング->polipo(A)->polipo(B)->dac..
と全部盛ってみて使ってます。なお、A:raspi 3B で B:BBG にして、両方ともbuildroot 2017.2 にしましたが、すんなり移行できました。一度形が決まれば、新しい環境でもすぐ試せるのはbuildrootの良いところですね。

(4) raspi3Bで、2ベキ倍のオーバーサンプリングをしようと思ったんですが、lightMPDについてるパッチはmpd0.20系では使えないんですね。調べたところ、src/output/OutputThread.cxxの中でフィルター(soxr)を当てる前の部分を変更すればよさそうなので、次のパッチの様にしました:

--- a/src/output/OutputThread.cxx 2017-01-27 16:46:51.000000000 +0900
+++ e/src/output/OutputThread.cxx 2017-03-02 00:21:47.750285083 +0900
@@ -121,7 +121,16 @@
name, plugin.name));
}

- const auto cf = f.WithMask(config_audio_format);
+ int mult = 1;
+
+ while (2*mult*f.sample_rate <= config_audio_format.sample_rate)
+ mult = 2*mult;
+
+ AudioFormat cfx = config_audio_format;
+ cfx.sample_rate = mult*f.sample_rate;
+
+ const auto cf = f.WithMask(cfx);
+ // const auto cf = f.WithMask(config_audio_format);

if (open && cf != filter_audio_format) {
/* if the filter's output format changes, the output

mpd.confで指定したformatの値を越えない範囲の最大値で2ベキ倍されます。たとえば format 364000:32:2 の様に指定すると、44100系については8倍の352800になると思います。(このへん私の理解が足りず、何か変な部分があるかもしれませんが…)
また、buildrootは標準ではlibsoxr.mkでopenmpが無効になってるため、有効にしてビルドしました。

digi...@gmail.com

unread,
Mar 3, 2017, 10:07:51 PM3/3/17
to lightMPD
aki2muraさん

いろいろと報告ありがとうございます。非常に参考になります。

> (2) また、別の問題なのですが、http outで数曲再生していると、polipoが突然ダウンすることがあります。どうも、polipoが想定してない使い方のせいか、offset(object.cのobjectAddData内だとか、lockChunkのiなど)がC言語の整数型の最大値を越えてマイナスになりエラーが起きるようです。
> 対策として、曲と曲の合間に、B側に mpc で stop・play を自動で送って繋ぎ直す形にすると、offsetがリセットされる様子で一応大丈夫になりました。ただ、もっと良い方法があるかもしれません。

polipoは設計が古い為か、インデックス系がint で定義されているます。その為、オブジェクト(今の場合は楽曲ファイル)が2g以下という制限がでてきます。将来この制限はなくしたいと思います。
が、stream系ではこのoffsetの問題は致命的になります。テストしてないのですが、インターネットラジオでも同様な問題がでるかもしれません。

> (3) 出力のencodeをどうするかという件は、結局、Null encoder (A側)で素のPCMデータを送ってPCM decoder(B側)で受ける形にしました。これだとaudioformatを別に渡す必要があるわけですが、mpdの中で完結させるにはちょっと知識が足りなかったので、もう一つ通信を開いてデータを渡すことにしました(busyboxのnetcatを利用)。
stream系のプロトルに知識がないのでよく解らないのですが、mpd内で完結するには曲が変わるたびにそのフォーマットの情報が渡らないと無理のような気がします。

> 4) raspi3Bで、2ベキ倍のオーバーサンプリングをしようと思ったんですが、lightMPDについてるパッチはmpd0.20系では使えないんですね。調べたところ、src/output/OutputThread.cxxの中でフィルター(soxr)を当てる前の部分を変更すればよさそうなので、次のパッチの様にしました:
mpd-0.20.x用の拡張フォーマットのパッチはすでに出来ています。次のバージョンを出すときに公開します。
aki2muraさんとは仕様が違いますが、実用的にはaki2muraさんの方法で十分だと思います。

但し、mpd-0.20.xからaudio_output_formatとoutputのformatを統一的にあつかうように変更されたので、ここを修正するよりAudioFormat::ApplyMask(AudioFormat::WithMaskから呼ばれる)を修正したほうがいいです。
また、やはり96000に固定したいとの要望もありますから、audio_output_formatの書式を変更して整数倍、非整数倍の切り分けがでた方がいいと思います。

こちらの進捗ですが、mpd-020xへのパッチの作成などを行っています。
また、polipoのwavのノイズ問題も進捗があったので近々rootイメージを公開する予定です。

aki2...@gmail.com

unread,
Mar 7, 2017, 9:30:44 AM3/7/17
to lightMPD
digififanさん、コメントいただき有難うございます。

polipoの制限については除く予定があったのですね。そうなると確かに助かります(個人的には、どんな風に改修するのかも興味あります。コード全体に渡るものと思うので、だいぶ大変そうですね)。
自分の使い方では、先に述べたように繋ぎ直しで一応しのげるので、とりあえずはそれで回避しておきます。ちなみに、src/player/Thread.cxx に Player::SongBorder という関数があって、名前のとおり曲と曲の間に呼ばれるようなのでそこに処理を挟んでいます。

また、0.20系の拡張フォーマットについても公開予定だったのですね。先走ったようで済みません。
ApplyMask(WithMask)のことですが、気になっていたのは src/decoder/DecoderControl.cxx の中でWithMaskが呼ばれていることでした。このあたりのdecorder関係の動作をイマイチ把握できず、修正の影響が出て良いかわからなかったので、上に挙げたパッチでは OutputThread の filter の手前だけを修正する形にしてました。

Reply all
Reply to author
Forward
0 new messages