Home‎ > ‎digifi labo‎ > ‎

lightMPDの拡張機能

lightMPDではmpd-0.18xとmpd-019xの2つのバージョンのmpdを用意してあります。それぞれのmpdにはlightMPD独自の機能拡張を行っています。各mpdの説明および拡張機能について説明します。

mpd-0.18.x

2014.10.15現在mpd-0.18.xの最新版は0.18.16です。
mpd-0.18xには長らく一部のDSDファイルの最後でmpdがループするというバグが放置されていました。このバグは0.17.xから引き継いでものです。

mpdではdsdをdopでDACに送出します。dopの1フレームは16サンプルで構成されますが、dsdファイルの中にはサンプル数が16の倍数でない物があります(注1)。このようなファイルを再生すると最終フレームが16サンプルにならず、この部分でループしてしまいます。日本ではrt_optでアウトプットスレッドのプライオリティを上げている場合がほどんどで、この場合はシェルも反応しなくなるためOSがハングアップしたように見えます。

注1]
この制限はDSF,DIFFにも無かったと思います、DOPでの制限になります。

これに対応する為には最終フレームが16サンプルに満たない場合そのフレームを切り捨てるしかありません。そのパッチをdsd対応を行ったJurgen Kramerさんに送った事があるのですが、Jurgen Kramerさん自身、このバグには気づいていて独自の対応を行っているようでした。

このバグはmpdのメーリングリストで話題になったことがあります。jurgen kramerさんがパッチを投稿したのですが、mpdの開発側のdsdに対する不理解により採用されませんでした。どうも余分なサンプルデータを切り捨てるのが気に入らなかったようです。それいらい放置状態になっていました。

jurgen kramerさんは  lintewaker/mpd-dsd-0.18でmpdのDSDの拡張を行うようになりました。これを以降lintweaker版と呼ぶことにします。

その拡張は
  • DOP最終フレームでループするバグ対応
  • DSDの早送り、巻き戻しの操作が行える
  • Native DSDの対応
  • DSD128,256,512(44.1K,48.0Kとも)に対応
です。

一方、本家ではこのバグはmpd-0.18.13で対応されました。lintweaker版の方法は曲の再生前にサンプル数を調整しますが、mpd-0.18.13でとられた方法は再生中に不正なフレームを取り除く方法をとっています。いずれも最終フレームが16サンプルに満たない場合にそれを破棄しています。

lintweaker版の方法はdecoderで曲を再生する前に一度だけ、mpd-0.18.13は再生中にdsdからdopチャンク(dopフレームの集まり)を作成する毎に検査されます。mpd-0.18.13の方法ははDSDだけではなくPCM再生時にも追加部分を通ります。これがどれほど音質に影響するかは不明でしたので、試しにこの検査部分(if分1個)を取り除いて両者を比較しましたが、両者の違いを聞き分けることはできませんでした。

尚、lintweaker版でも0.18.16を拡張した物には本家のバグ修正箇所は残っています。

上記の説明で分かるように、mpd-0.18.16ではlintweaker版はオリジナルと音質はと変わりませんので、lightMPDではDSDの早送り、巻き戻しができるlintweaker版のmpd-0.18.16を採用しました。


mpd-0.19

2014.10.10にmpd-0.19が正式にリリースされました。mpd-0.19では、DSDの早送り、巻き戻しが出来るようになりました。実装方法はlintweaker版の方法とは異なります。DSDに関してはlintweaker版とは別に行われているようです。

インターネットラジオ

mpd-0.19およびその後継のmpd-0.19.1ではインターネットラジオでmpdがアポートしてしまうことがあります。mpdがsegmentaion fault しているのでmpdの問題と思われます。segmentation faultを発生しているのが奥深い箇所で原因の特定は困難です。

インターネットラジオを利用される方はmpd-0.19xではなくmpd-0.18系を使って下さい。この問題が解消された時にmpd-0.19xを更新するつもりです。

インターネットラジオがアボートする原因はdecoder-selecterでした。
apu1cのv0.08で修正しました。その他の機種もv0.08で修正します。

storage plugins, database proxy

mpd-0.19ではいろいろ興味深い機能が追加されました。そのうち最も興味深い機能は storage plugins です。storage pluginsはlocalfile,nfs,cifsのプラグインが用意されており、これらを使うとマウントしていなくてもnfs,cifsプロトコルでリモートマシーン上のファイルを再生する事ができます。

lightMPDではシステム起動時nas上のディレクトリをマウントしlightMPDが起動中は常時マンウントしています。システム起動時にnasにマウントをかける場合、nasの起動確認をしてからでないとlightMPDの電源を入れられません。また、lightMPDの稼働中はnasの電源を切ることができません。これはlightMPDの欠点と考えています。このような問題があるためlightMPDをネットワークプレーヤーとは言えませんでした。それでlightMPDでは「ネットワークプレーヤー的」としていました。

一般にネットワークプレヤーと呼ばれているsqueeze player やその他のDLNA プレーヤーはメディアサーバー(NAS)と独自なプロトコルで繋がっているのでこのような事はありません。

storage plugins を使うとマウントしていないサーバーからmpd自信がnfsプロトコルでデータを読み込みます。従って、上記のような問題は発生しませんし、squeeze player やDLNAサーバーと同じようにネットワークプレーヤーと言えるようになります。

ドキュメントによるとmusic_directoryを以下の様に記述する様です。

music_directory              "nfs://servername/path"

ドキュメントには記述がないのですが、

db_file                      "nfs://servername/tag_cache"

の様な記述ができれば完璧なのですが、これは出来ないのかもしれません。


これを補間する機能としてdatabase proxyというプラグインも用意されています。こはれ別のマシーンで動作しているmpdが管理しているdb_fileを取り込む機能です。

例えばnas上でmpdを動作させdb_fileの作成をこのmpdで行うとリモートアクセスするmpdで行うより高速に行えます。

これらの機能をうまく使うとdb_fileがリモートアクセス出来ない場合でもnasにマウントをかける必要がなくなります。但し、この方法ではカバーアートを取り出す事が出来ない、複数のnasをサポートできないなどの問題もあります。

lightMPDではこれらの問題を解決し、storage plugin,database proxyの機能を使ってnasにマウントしないシステムを実現したいと考えています。


lightMPDの独自機能

lightMPDではオリジナルのMPDに対していくつかの拡張を行っています。

realtime option

mpdの各スレッドの優先順位を任意に設定出来るようにする物です。優先順位を変更して動作の安定化および高音質化の為のチューニングが行えるようになります。

lintweaker版にはrt_optのパッチがあたったブランチもあるのですが、lightMPDでは本家の0.18.16にmpd-0.19git-rtopt20140327を当てました

rtカーネルでは各デバイスの割り込みハンドラーがOSの外側に出されていて、割り込みハンドラーの優先順位も変更できます。lightMPDでははmpdのスレッドの優先順位の他USBの割り込みハンドラーの優先順位も変更しています。

プロセスの優先順位を設定に際してはいろいろな考えがあります。lightMPDでは以下のような考えに基づいて設定しています。

lightMPDではDACをUSBで接続します。USBへの転送は周期的に行われます。これを遅延させると音切れやプチノイズになるので高く設定します。一方入力はMPD内にある程度のバッファーがあるのと入力デバイスであるイーサネットにはフロー制御があり送り側をある程度待たせる事ができるのでイーサネットの割り込みハンドラーはデフォルト(FIFO:50)のままつかいます。mpdのoutput,playerスレッドがイーサネットを含む他のデバイスから割り込まれないように割り込みハンドラーのデフォルト値より大きな値を設定します。

lightMPDでは優先順位を以下のように設定しています。

  USB割り込みハンドラー      FIFO:99
  mpd  output スレッド      FIFO:54
  mpd  player スレッド      FIFO:52
  mpd  main スレッド        OTHER
  mpd  decoder スレッド     OTHER
  mpd  update スレッド      OTHER
  mpd  io スレッド          OTHER


FIFOの数字が大きい程優先順位が高くなります。割り込みハンドラーのデフォルトの優先順位はFIFO:50です。

USBへのデータ転送はUSB割り込みハンドラーで行われます。USBの転送モードがDMAの場合はDMAのチャネルを操作するだけですが、PIOモードの場合はプログラムで転送します。PIOモードを処理するプログラムはCPUがどんなに早くてもUSBへの転送が終わる期間CPUを使います。この間に他のスレッドへディスパッチされると音切れします。そうよう事がないように優先順位を最高にしてあります。

現在のところPIOモードで動作するのはbeaglebone,beaglebone blackだけです。これらのボードはkernelのconfigでDMAを指定してもDMAモードでは動作せずPIOモードで動作します。



decoder selecter

mpdではbuild時に指定すると複数種類のデコーダーを組み込む事ができます。どのデコーダーが組み込まれているかはmpd -V コマンドで確認できます。

1つのファイル種別に対して複数のデコーダが組み込まれている場合はDecoders plugins: に示されている順で走査されます。
例えば、上記の様なdecoder構成の場合、"wav"ファイルに対してはsndfileが使用されます。"wav"のデコーダーとしてaudiofileを使いたい場合は、mpd.confでsndfileを取り除きます。sndfileを取り除いたので"aiff","aif"もaudiofileでデコードされることになります。

このように、mpdではデコーダー単位のon/offは出来てもファイル種別毎にデコーダーを指定する事が出来ません。それを可能にするためにdecoder_selector機能を追加しました。

decoder_selectorはmpd.confでファイル種別毎にデコーダー及びタグデータをスキャンするデコードを指定します。

decoder_selector {
     suffix            "wav"
     plugin           "sndfile"
     scan_plugin   "sndfile"
}

decoder_selector {
     suffix            "m4a"
     plugin           "audiofile"
     scan_plugin   "ffmpeg"
}

主なファイル種別で使えるデコーダーは以下の通りです。
  • mp3
    mad,ffmpeg
  • ogg
    vorbis,oggflac
  • flac
    flac,audiofile,ffmpeg
    audiofileデコーダはタグのスキャンは出来ません。
  • m4a
    audiofile,ffmpeg,mp4ff(0.18.6では未サポート)
    但し、audiofile,mp4ffデコーダではiTunesで作成したm4aは再生出来ませんでした。
    audiofileデコーダはタグのスキャンは出来ません。
  • aac
    faad,ffmpeg
パッチ

4096バイト以上のid3tag

mpdではid3tagを扱えますが、4096バイト以上あるid3tagは無視する仕様になっています。しかし、id3tagにはカバーアートも格納する事ができ、カバーアートを含んだid3tagは無視されてしまいます。lightMPDではその制限を外しました。

これで、e-onkyoのDSFファイルのタグも反映されます。e-onkyoのDSFにはカバーアートも含まれています。しかし、e-onkyoのタグは何とかならないでしょうか? わざわざ英語のタイトルをカタカナにする必要があるのでしょうか?

パッチ

拡張オーディオフォーマット

v0.07で新設した機能です。

掲示板でapu.1cのcpuパワーを生かしてアップサンプリングして高音質を追求する試みをされた方がいらっしゃいました。libsamplerate,soxrとも最高音質でもアップアンプリングが可能のようです。

しかし、mpdではaudio_output_formatで指定できるのはサンプリング周波数であるため、例えばサンプリング周波数に96000を指定した場合44.1K系列の入力に対しても96000に変換してしまいます。また、audio_output_formatを指定するとdsdに対しても行ってしまうためdsdの再生はできませんでした。

そこで、lightMPDではmpd.confのaudio_output_format のサンプル周波数の指定方法を拡張しました。従来のサンプリング周波数を指定する方法の他、入力信号の周波数を任意倍数に指定する事ができます。さらにDSD信号に対してはフォーマットの変換を行わないようにしました。

アップサンプルの指定形式

          XnLm

の形式で指定します。

X,Lは拡張オーディオフォーマットであることを示す識別子です。先頭文字がXの時拡張オーディオフォーマットと見なします。
  • n :  入力信号のサンプリング周波数をn倍にアップサンプリングします。
  • m :  アップサンプリング後の周波数の最大値を指定します。44.1 * m , 48.0 * m 。

1.  "X2L2"
     
 入力サンプリング周波数 アップサンプリング後の周波数
 44.1K    88.2K
48.0K   96.0K
88.2K 88.2K 
96.0K 96.0K 
176.4K 88.2K 
192.0K 96.0K 


2.  "X2L4"
     
 入力サンプリング周波数 アップサンプリング後の周波数
 44.1K    88.2K
48.0K   96.0K
88.2K 176.4K 
96.0K 192.0K 
176.4K 176.4K 
192.0K 192.0K 


3. "X4L4"
     
 入力サンプリング周波数 アップサンプリング後の周波数
 44.1K    176.4K
48.0K   192.0K
88.2K 176.4K 
96.0K 192.0K
176.4K 176.4K
192.0K 192.0K
   
mpd.confの記述例

audio_output_format "X2L2:24:*"


注意
拡張オーディオフォーマットを使う場合はaudio_outputのformat は指定しないで下さい。

パッチ



Comments