Articles

YouTube動画の貼り付け方

直前の記事でYouTube動画を貼り付けていますが、画面の中央に持ってくるのに悪戦苦闘したので、備忘録メモです。

YouTube動画の貼り付け方ですけど、やり方が変わったようですね。以前はembedタグを使う方式だったのにiframeタグを使う方式に昨年頃変更になったようです。
これは簡単で動画画面下の共有ボタンを押して、埋め込みコードというボタンが出てくるので、これを押せばコードが表示される。あとはCopy&Pasteで処理できるので、問題はありません。
コードはこんな具合です。

<iframe width="560" height="349" src="http://www.youtube.com/embed/QdM9vDA9NJI" frameborder="0" allowfullscreen></iframe>

問題なのはこの時ディフォルトでは画面の左端に表示されること。HTMLタグを調べたらiframeでもalign=“center”が有効らしいので、これを試してみたのですが、梃でも左から動かない。

<iframe align="center" width="560" height="349" src="http://www.youtube.com/embed/QdM9vDA9NJI" frameborder="0" allowfullscreen></iframe>

変だなぁと思ってググるが、日本語のサイトには答えはなくて、結局ここにありました。
スタイルシートと組み合わせて設定しないといけないのですね。
cssのbody句に以下のように追加設定する。

body {
  text-align:center;
}

次にiframeにスタイルを記述する。

<iframe style="margin:0 auto" width="560" height="349" src="http://www.youtube.com/embed/QdM9vDA9NJI" frameborder="0" allowfullscreen></iframe>

という具合です。

(internet)   2011/05/26

コメントする

10センチの穴

「やっぱりメルトダウンしていました」とか、「実は格納容器に10センチの穴が空いていました」とか、なんで突然、ペラペラ白状しだしたのかなと思ったら、海外(IAEA)からこわいオジサンたちがやってきて取り調べ中なのですね。


国内の甘いマスコミ相手ならバレないから、とぼけておいて、海外からの厳しい追求には耐えられなさそうと分かると、真実を明らにするとは。あきれた会社だねぇ。
「海水の注入を中断した、しなかった」にいたっては、首相を退陣に追い込むためのヘボな謀略とその失敗という感じがするけど、勘繰りすぎかなぁ。これじゃ、現場で必死に復旧に頑張っている方々がうかばれないなぁ。

(others)   2011/05/26

コメントする

耐えたケセン語聖書

今日の毎日新聞夕刊の記事。
『津波で全壊した岩手県大船渡市の出版社の倉庫から、新約聖書を地元の方言に訳した「ケンセ語訳 新約聖書」が見つかり、「大津波に耐えた聖書」と注目を集めている。
大船渡市のお医者さんが、陸前高田氏など気仙沼地方の方言を「ケセン語」と命名し、新約聖書の中の四つの福音書をギリシャ語の原典からケセン語に翻訳したもの。
旭川市の文化財団で「津波の洗礼を受けた聖書なんて聞いたことがない」として販売していくことになった。』
というような内容なのですが、面白かったのは翻訳の内容。

マタイ受難曲クライマックスの
『Eli; Eli; lama, lama asabthani! —- わが神、わが神、なぜわたしをお見捨てになったのですか』
という部分が
『神様んすぅ、神様んすぅ、なして(何故)おれ(俺)ぁどごぉ見捨てやりぁしたれ ? 』
となるのだそうです。

うーむ。、バッハの曲にピッタリではないか。誰か歌ってみませんかね。楽譜を引用しておきます。



E(かみ) -(さま) li(んすぅ) E(かみ) -(さま) li(んすぅ) la(なし)ma(て), la(お)ma(れぁ) a(どごぉ) -(み) sa(すて) tha(やりゃ) ni!(したれ)
という具合です。

(others)   2011/05/25

コメントする

「動機が不純」

『日本経団連の米倉弘昌会長は23日の記者会見で、電力会社の発送電分離について、「東京電力の賠償問題に絡むもので、動機が不純だ」と批判した。』

あきれはてましたね。「動機が不純」なのはどちらだろうか。
東京電力の賠償問題に絡んでも、絡まなくても、電力会社の発送電分離について議論するのは当たり前でしょ。「動機が不純」なのは経済的合理性の論議を無視して、既得権益を守ろうとする経団連(電力会社)じゃないの。

そもそもこの人、原発事故直後に「千年に1度の津波に耐えているのは素晴らしいこと。原子力行政はもっと胸を張るべきだ」と言っているらしいけど、かなり能天気だね。

まあ、東電介護(?)シフト、しょうがなしにこういう発言をしているのだろうけど、これじゃ逆効果ですね。

(others)   2011/05/24

コメントする

Alsaの最新版をビルド(2)

掲示板にやりとりが残っていますが、前回の内容ではヴァージョンメッセージが

root@voyage:~# cat /proc/asound/version 
Advanced Linux Sound Architecture Driver Version 1.0.24.
Compiled on May  7 2011 for kernel 2.6.33.7-rt29-voyage (SMP).

と表示できないようです。

asoyajiさんのレポートで「変だなぁ」と思い、テスト用の環境で試してみたら、同じ状態が再現。
configureは

・・・
configure: creating ./config.status
config.status: creating version
config.status: creating Makefile.conf
config.status: WARNING:  Makefile.conf.in seems to ignore the --datarootdir setting
config.status: creating snddevices
config.status: creating utils/alsa-driver.spec
config.status: creating utils/buildrpm
config.status: creating toplevel.config
config.status: creating utils/alsasound
config.status: creating utils/alsasound.posix
config.status: creating include/pci_ids_compat.h
config.status: creating include/i2c-id_compat.h
config.status: creating include/config.h
config.status: include/config.h is unchanged
config.status: creating include/config1.h
config.status: include/config1.h is unchanged
config.status: creating include/version.h
config.status: include/version.h is unchanged
config.status: creating include/autoconf-extra.h
config.status: include/autoconf-extra.h is unchanged
Hacking autoconf.h...

と終わります。最後のconfig.h、config1.h、version.h、autoconf-extra.hが「is unchanged」というのが変ですかね。
ただ、makeは

  Building modules, stage 2.
  MODPOST 10 modules
  LD [M]  /root/Alsa/alsa-driver-1.0.24/acore/oss/snd-mixer-oss.ko
  LD [M]  /root/Alsa/alsa-driver-1.0.24/acore/oss/snd-pcm-oss.ko
  LD [M]  /root/Alsa/alsa-driver-1.0.24/acore/snd-hwdep.ko
  LD [M]  /root/Alsa/alsa-driver-1.0.24/acore/snd-page-alloc.ko
  LD [M]  /root/Alsa/alsa-driver-1.0.24/acore/snd-pcm.ko
  CC      /root/Alsa/alsa-driver-1.0.24/acore/snd-rawmidi.mod.o
  LD [M]  /root/Alsa/alsa-driver-1.0.24/acore/snd-rawmidi.ko
  LD [M]  /root/Alsa/alsa-driver-1.0.24/acore/snd-timer.ko
  LD [M]  /root/Alsa/alsa-driver-1.0.24/acore/snd.ko
  LD [M]  /root/Alsa/alsa-driver-1.0.24/usb/snd-usb-audio.ko
  LD [M]  /root/Alsa/alsa-driver-1.0.24/usb/snd-usbmidi-lib.ko
make[1]:  `/usr/src/linux-headers-2.6.33.7-rt29-voyage' 
utils/link-modules /root/Alsa/alsa-driver-1.0.24

ALSA modules were successfully compiled.

make installは

・・・
mkdir -p /lib/modules/2.6.33.7-rt29-voyage/kernel/sound/usb
cp snd-usb-audio.ko snd-usbmidi-lib.ko /lib/modules/2.6.33.7-rt29-voyage/kernel/sound/usb
・・・

という具合に正常に終了します。 悩みましたが、ヴァージョンメッセージを正しく出力する時のビルドの古いログを眺めて、

root@voyage:~# apt-get remove alsa-base

というのに気が付きました。
この時のconfigureは

・・・
configure: creating ./config.status
config.status: creating version
config.status: creating Makefile.conf
config.status: WARNING:  Makefile.conf.in seems to ignore the --datarootdir setting
config.status: creating snddevices
config.status: creating utils/alsa-driver.spec
config.status: creating utils/buildrpm
config.status: creating toplevel.config
config.status: creating utils/alsasound
config.status: creating utils/alsasound.posix
config.status: creating include/pci_ids_compat.h
config.status: creating include/i2c-id_compat.h
config.status: creating include/config.h
config.status: creating include/config1.h
config.status: creating include/version.h
config.status: include/version.h is unchanged
config.status: creating include/autoconf-extra.h
Hacking autoconf.h...

となっていて、「is unchanged」なのはversion.hだけ。
どうもこれが原因でヴァージョンメッセージが正しく表示されなくなるようです。 以前の記事を書いた時、リムーブの必要性が分かっていないで、たまたまちゃんと処理していたのですね(^^;;;。

という次第で、ドライバをビルドする前に以下の操作を行って下さい。

root@voyage:~/Alsa/alsa-driver-1.0.24# pkill mpd
root@voyage:~/Alsa/alsa-driver-1.0.24# apt-get remove alsa-base
root@voyage:~/Alsa/alsa-driver-1.0.24# make clean

asoyajiさんに「ログを調べて頂戴」なんて返事している暇に、自分のログを調べるべきでしたね(^^;;。
ご協力いただいたasoyajiさんに感謝します。

(PC_Audio)   2011/05/22

コメントする

オーディオファイルのための Linux Tips

僕はれっきとした(?)Windowsユーザです。メインマシンのOSはWindows7。ブラウジングもメールのやりとりもサイトの更新もCDの取り込みも全てメインマシンでやっていて、VoyageMPDや玄柴MPDの操作もWin7のPuttyからです。カーソルキーなど特殊キーは大好きだし、キーボードよりマウスが好きだし、viは苦手だし、愛用のエディターは meadow/emacs ではないし、正規表現のコーディングも Windows の Rubyで使っています。
まあ、Windowsユーザ定番の IE、OE、Officeという世俗的(?)なソフトは嫌いですので、FireFox、EdMax、OpenOfficeを代わりに使っていますが、その程度です。
という次第で、以前にも、ちょっと書いたことがありますが、「(Windowsユーザが大部分である)オーディオファイルのためのLinux Tips」。自分自身のための備忘録ですが。

プログラムのインストール

Windowsの場合はプログラムはバイナリで提供され、インストラーが付いて提供されるのが当たり前ですが、Linuxの場合は大分違います。

Windowsユーザからみて最も手ごわいのはソースからコンパイルしないといけないやつ。普通、ダウンロードしたTarボールにReadmeなりInstall関連のドキュメントがあり、それを読めばやり方は書いてあります。ただ、解読にはある程度のLinux知識が必要です。
あと、プログラム名とbuild、compile、makeなどをキーワードにして、ググれば、それなりの情報をgetできることが多いです(僕はもっぱらこの方法でしのいでいます)。
まあ、いずれにしても大変ですので、どうしようもない場合を除いて、バイナリでインストールする方法に頼った方が楽です。

バイナリで提供される場合は簡単です。VoyageMPDの場合、Debian系列のLinuxですので、ネットワーク経由なら apt-get 又は aptitude、debファイルならば dpkg -i でインストールできます。
apt-get と aptitude の違いがいまいち分からないのですが(^^;;、apt-getでだめだったら、aptitude を使うという方法でやっています。
dpkg はインストール済のパッケージの内容を確認するのにも使えます。「dpkg -l」全パッケージを「dpkg -s パッケージ名」で指定したパッケージの詳細を確認できます。
注意しないといけないのは Linuxの場合はディストリビューションによってバイナリのインストールの方法が違うこと。従って、ググる時はdebianをキーワードに付けるといいです。
Voyageの初期状態ではaptitudeはインストールされていないので

apt-get install aptitude

しておく必要があります。

シェルプログラムの実行

Linuxの場合、実行の権限もアクセス権で管理されています。アクセス権につてはリンク先を読んで頂くとして、面倒なのはシェルスクリプトも実行権限を管理されること。エディターでテキストとして作成したものをいちいち 「chmod 755 シェルスクリプト名」しないといけない。
しかし、これは逃げ方があって、

sh ./xxxx.sh

読み出すことが許可されていれば、実行できます。

ファイルの圧縮と解凍、展開

Windowsの場合は圧縮解凍プログラムのアイコンにドラッグドロップですみますが、Linuxはコマンドで行います。
分かりにくいのは、圧縮解凍するプログラム(compress、gzip、bzip2)と書庫化展開するプログラム(tar)が分かれていること。ただし、コマンドとしてはtarを呼び出すだけで圧縮、展開できます。

書庫化するだけ

root@voyage:~# tar rvf /media/usb0/mpdbuild.tar ./mpdbuild_pre.sh ./mpdbuild_i386_tune.sh ./my-config.sh

上記を展開

root@voyage:~# tar xvf /media/usb0/mpdbuild.tar

gzip圧縮して書庫化

tar cvzf /media/usb0/mpdinstall.tgz ./mpd ./mpdinstall.sh

上記を解凍して展開

tar zxvf /media/usb0/mpdinstall.tgz

というところ。

「rvf」とか「xvf」とかいうオプションが複雑そうですが、仕組みを知れば、実は簡単。
「f」というのはtarがもともとディスクの内容を磁気テープに書き出す(バックアップ)するためのものだった時の名残で、ファイルを強制的に指定しています。これを指定しないと、磁気テープ装置を虚しく探しにいって、エラーで終わることになる。
「v」というのは多分viewの略で処理の過程を表示する。省略できますが、省略すると他のコマンドのように上手くいってもダンマリを決め込むことになります。
となると残りは「r x z c」となり、これで書庫化か展開かとか、圧縮方式とかを指定しているだけです。それぞれの意味についてはググれば山ほど紹介するサイトがあるので、そちらにお任せ。

USBデバイスの取り外し

最近のLinuxは進化していて、大抵のデバイスは自動的にマウントされるのですね。昔は大変だったのになぁ。それなのに、「Linuxは操作が複雑」などというのは時代錯誤のたわごとかもしれませんね。
という次第で、VoyageMPDもれっきとしたLinuxですから、USBデバイスは自動マウントします。
問題は取り外すとき。WindowsでもGUIでUSBデバイスの取り外しという操作を行いますが、Linuxでは以下の通りコマンド操作します。

root@voyage:~# sync
root@voyage:~# umount /media/usb0

sync というのはファイルの書き込みを強制的に行わせるコマンドです。これをやらないと更新したファイルが正しく保存されないことなりますので、ご注意下さい。
書き込みをしていなければ、umountだけでいいのもしれません。

05/16 追記
差し込んだUSBメモリのデバイス名を見つける方法(dfコマンド)を書き忘れましたので、追記します。

root@voyage:~# df
Filesystem           1K-blocks      Used Available Use% Mounted on
rootfs                 6214304   1111848   4786780  19% /
udev                     10240       172     10068   2% /dev
/dev/disk/by-uuid/8815092f-8841-4b3c-b131-9c93cac6cdd1
                       6214304   1111848   4786780  19% /
tmpfs                  1032520     19696   1012824   2% /lib/init/rw
varrun                 1032520        48   1032472   1% /var/run
varlock                1032520         0   1032520   0% /var/lock
tmpfs                  1032520         4   1032516   1% /dev/shm
tmpfs                  1032520         0   1032520   0% /tmp
tmpfs                  1032520     19696   1012824   2% /var/log
tmpfs                  1032520     19696   1012824   2% /var/tmp
tmpfs                  1032520     19696   1012824   2% /var/lib/mpd
//192.168.0.3/cd2/   1848286248 1655969196 192317052  90% /music1
/dev/sdb1              3835588   1454208   2186540  40% /media/usb0

容量(4GB)と名前(/media/usbn)から、一番下の/media/usb0が差し込んだメモリと分かります。
VoyageMPDでは、特に外付けディスクがなければ、通常は/media/usb0となります。

軽いエディター

jed(yanさんに教えてもらいました)とnano(玄柴のDebianでディフォルトで入っていました)があります。

apt-get install jed
apt-get install nano

でインストールできます。
jedはemacsの簡略版という感じ。
nanoはnotepad(Linuxユーザのために補足すると、Windows添付の簡易エディターです)のLinux版という感じ。
ですね。
「viはWindowsユーザの敵だ。だけど、emacsは複雑すぎてワケワカメ。これも敵だ」という方々にお勧めします。

(computer)   2011/05/14

コメントする

Alsaの最新版をビルド

際限がないという感じもしますが、やってみました。

直前の記事にあげたリンク先でAlsaを最新版にすると音が良くなるという記述があって、試してみたということです。
やり方は比較的簡単ですが、バックアップをとっていないと、元に戻す方法はないので、自己責任でお願いします。

参考にしたサイトは以下の二つです。

まず、関連するモジュールのインストール

root@voyage:~# apt-get install aptitude wget
root@voyage:~# aptitude install build-essential libncurses-dev gettext xmlto xmltoman linux-headers-`uname -r`


ドライバーソースをダウンロード、展開

root@voyage:~# mkdir -p Alsa
root@voyage:~# cd ./Alsa/
root@voyage:~/Alsa# wget ftp://ftp.alsa-project.org/pub/driver/alsa-driver-1.0.24.tar.bz2
root@voyage:~/Alsa# tar xjvf alsa-driver-1.0.24.tar.bz2
root@voyage:~/Alsa# cd alsa-driver-1.0.24/


ドライバーをビルド。
usb-audioのみをビルドし、不要な機能は取り込まないように指定(「./configure –help」でパラメータは確認できます)。

root@voyage:~/Alsa/alsa-driver-1.0.24# CFLAGS="-O2 -mtune=`uname -m`" ./configure --with-cards=usb-audio --with-sequencer=no --with-isapnp=no --with-kernel=/usr/src/linux-headers-$(uname -r)
root@voyage:~/Alsa/alsa-driver-1.0.24# make
root@voyage:~/Alsa/alsa-driver-1.0.24# make install
root@voyage:~/Alsa/alsa-driver-1.0.24# reboot


アップデートされたことを確認

root@voyage:~# cat /proc/asound/version 
Advanced Linux Sound Architecture Driver Version 1.0.24.
Compiled on May  7 2011 for kernel 2.6.33.7-rt29-voyage (SMP).


これだけです。簡単でしょ。
あと、ライブラリとユーティリティもビルドしたければ、

ドライバーソースをダウンロード、展開
root@voyage:~# cd Alsa/
root@voyage:~/Alsa# wget ftp://ftp.alsa-project.org/pub/lib/alsa-lib-1.0.24.1.tar.bz2
root@voyage:~/Alsa# wget ftp://ftp.alsa-project.org/pub/utils/alsa-utils-1.0.24.2.tar.bz2
root@voyage:~/Alsa# tar xjvf alsa-lib-1.0.24.1.tar.bz2
root@voyage:~/Alsa# tar xjvf alsa-utils-1.0.24.2.tar.bz2

ライブラリをビルド
root@voyage:~/Alsa# cd ./alsa-lib-1.0.24.1/
root@voyage:~/Alsa/alsa-lib-1.0.24.1# ./configure 
root@voyage:~/Alsa/alsa-lib-1.0.24.1# make
root@voyage:~/Alsa/alsa-lib-1.0.24.1# make install

ユーディリティをビルド
root@voyage:~/Alsa/alsa-lib-1.0.24.1# cd ../alsa-utils-1.0.24.2
root@voyage:~/Alsa/alsa-utils-1.0.24.2# ln -s libpanelw.so.5 /usr/lib/libpanelw.so
root@voyage:~/Alsa/alsa-utils-1.0.24.2# ln -s libformw.so.5 /usr/lib/libformw.so
root@voyage:~/Alsa/alsa-utils-1.0.24.2# ln -s libmenuw.so.5 /usr/lib/libmenuw.so
root@voyage:~/Alsa/alsa-utils-1.0.24.2# ln -s libncursesw.so.5 /lib/libncursesw.so
root@voyage:~/Alsa/alsa-utils-1.0.24.2# ./configure 
root@voyage:~/Alsa/alsa-utils-1.0.24.2# make
root@voyage:~/Alsa/alsa-utils-1.0.24.2# make install

で出来ます。
「ln -s」の意味はリンク先を参照して下さい。

肝心の音はですが、よく分からんです(^^;;。よくなったような気もするが、気のせいかもしれないというレベルですね。

あとは、いよいよカーネルのビルドしか残っていないなぁ(^^;;;。

05/08 追記
configure時にCの最適化オプション(CFLAGS)を指定を忘れていたので追加しておきました。

05/21 追記
「ドライバーソースをダウンロード、展開」の中で「tar」と「cd」の順序が逆だったのを修正しました。

(PC_Audio)   2011/05/08

コメントする

MPDの最新版をビルド(2)

前回の記事の内容だと一部のハードで音が出なくなるので、訂正しておきます。
このトラブルはyanさんのご協力で解決できました。ありがとうございました。

訂正は「MPDビルド時にlibsndfileがインストールされていると、24ビット(S24_3LE)対応のハードでwavファイルが再生できなくなるので、明に–disable-sndfileを設定する必要がある」という内容です。16ビット(S16_LE)及び32ビット(S32_LE)対応のハードではこの問題は発生しません。

S24_3LEというのはwavファイルのフォーマットのことで、24bit3byts構成で Little Endian形式のデータを意味です。音源のハードウェアがどのフォーマットかは以下の通りチェックできます。

root@voyage:~# cat /proc/asound/card0/stream0
 KYODO   Phase Tech HD-7A  at usb-0000:00:1d.0-1, full speed : USB Audio

Playback:
  Status: Stop
  Interface 1
    Altset 1
    Format: S24_3LE
    Channels: 2
    Endpoint: 1 OUT (ASYNC)
    Rates: 44100, 48000, 88200, 96000

これは僕の使っているフェーズテック社のUSBDAC(HD-7A)ですが、問題が起きるハードだと分かります。

次に、なぜ音が出なくなるかですが、話はVoyageMPD登場前にさかのぼります。

Computer AudiophileのNew mpd feature = cleaner signalという記事の情報によると、24-bit USB DAC に対する音質改善のため、mpdの改良が行われています。この記事はMPDの音質に関する大変興味深いやりとりがあり参考になります。例えば以下のような書き込みがあります。

S24_3LEハードでmpd.confのaudio_outputの「hw:n,n」を「plughw:n,n」と変えると(「hw:n,n」の行をコメントアウトしても同じ)、wavファイルは再生できるようなるのですが、音質は悪化します。これは上記の記事にあるように「plughw:n,n」を指定するとビットレートが48000、16ビットに固定されて、余分なフォーマット変換が入ってしまうためです。

本題に戻って、音が出なくなる理由です。

libsndfileというはC言語のライブラリで(libsndfileについてはWikipediaのlibsndfileの解説を参照して下さい)、wavファイル間のフォーマット変換に使用されます。MPDもこれを利用しています。wavファイル間のフォーマット変換とは例えば16ビットのデータを24ビットのデータに変え整合性をとることです。CDフォーマットのデータは16ビットですので、これを24ビットのハードに送り出すというような場合に変換が必要になります。

さて、このlibsndfileですが、MPDでwavファイルの 16 → 24 ビット変換時の動作に問題があるようです。デバッグ用のログを出力させてwavファイルを再生すると

root@voyage:~# /usr/local/bin/mpd --no-daemon --stderr --verbose /etc/mpd.conf
・・・
playlist: play 1:"music1/Mozart- Piano Concertos No. 20 & 27-Mitsuko Uchida- Cleveland Orchestra/01__Piano_Concert_No._20_In_D_Minor,_K466_-_I._Allegro.wav"
・・・
decoder: audio_format=44100:32:2, seekable=true
output: opened plugin=alsa name="My ALSA Device" audio_format=44100:24_3:2
output: converting from 44100:32:2

wavフォーマットを「audio_format=44100:32:2」と誤認識し、「converting from 44100:32:2」となりますので、何も再生されないことになります。
「/usr/local/bin/mpd –no-daemon –stderr –verbose /etc/mpd.conf」というのは、yanさんに教えて頂いたのですが、MPDの状態モニタになかなか便利な魔法の呪文です。
flacファイルでは

playlist: play 0:"music1/Salzburg Recital (1966.7.30,Orfeo C530001B)-バックハウス/10__Piano_Sonata_no.23_f-moll_'Appassionata'.flac"
・・・
decoder: audio_format=44100:16:2, seekable=true
output: opened plugin=alsa name="My ALSA Device" audio_format=44100:24_3:2
output: converting from 44100:16:2

こちらは正しく認識、処理されています。

面白いのは16ビット対応の音源(PS-Audio Digital Link)では次のようになること。

playlist: play 0:"music1/Takemitsu Complete Songs-坂本朱&福田進一/01__うたうだけ(福田進一編曲).wav"
・・・
decoder: audio_format=44100:32:2, seekable=true
output: opened plugin=alsa name="My ALSA Device" audio_format=44100:16:2
output: converting from 44100:32:2

wavフォーマットを「audio_format=44100:32:2」と誤認識しているのだけど、音はちゃんと再生できます。偶数倍だからうまくいくのですかね。
ちなみに、stream0は以下の通り。

root@voyage:~# cat /proc/asound/card0/stream0
Burr-Brown from TI               USB Audio CODEC  at usb-0000:00:1d.1-1, full s : USB Audio

Playback:
  Status: Running
    Interface = 1
    Altset = 1
    URBs = 3 [ 8 8 8 ]
    Packet Size = 192
    Momentary freq = 44100 Hz (0x2c.199a)
  Interface 1
    Altset 1
    Format: S16_LE
    Channels: 2
    Endpoint: 2 OUT (ADAPTIVE)
    Rates: 32000, 44100, 48000
以下省略



また脱線したので、本題にもどります。
この問題を回避するため、MPDは上記の音質改善対応で sndfileを使わないようにしているようです。
推定ですが、16→24ビットにするのに、実際には変換するわけでなく、ビットオフの下位8ビット(0x00)を付与するだけだと思います。

ところがMPDのビルドでsndfileのディフォルトはenableなので、libsndfileのインストールされたシステムで–disable-sndfileを指定しないでビルドすると上記の誤認識が発生してしまいます。
MPDのビルドのパラメータですが、tarボールを展開したディレクトリで

root@voyage:~/mpd# ./autogen.sh
root@voyage:~/mpd# ./configure --help | less

で表示させることができます。

このため、VoyageMPDはこの問題を回避するため「–disable-sndfile」を指定しているようです。

「/usr/local/bin/mpd -V」で確認するとビルド版は

[sndfile] wav aiff aif au snd paf iff svx sf voc w64 pvf xi htk caf sd2

と表示されますが、VoyageMPDに組み込まれている「/usr/bin/mpd -V」では何も表示されません。
ちなみに、「–disable-sndfile」を指定しビルドしたMPDでは

playlist: play 1:"BIS Sampler 1992/02__2,_RV_315,_'The_Four_Seasons_(Summer)'_-_3._Presto.wav"
・・・
decoder: audio_format=44100:16:2, seekable=true
output: opened plugin=alsa name="My ALSA Device" audio_format=44100:24_3:2
output: converting from 44100:16:2

という具合になり、flacと同じように正しく処理されていることが分かります。
尚、掲示板Head HiのBest MPD Setupという記事に情報がありますが、sndfileが組み込まれていても mpd.confに

decoder {
    plugin "sndfile"
    enabled "no"
}

を追加するという方法でも解決するようですが、どうせビルドするのだから、ビルドのパラメータの設定でやった方がよいと思います。

本題と関係ありませんが、上記「Best MPD Setup」のコメンツツリーはMPDのチューニングやハード、ソフトに関する興味深い記事が多く、お勧めです。「玄柴」の元になっているSheevaPlugの兄弟分のハードでMPDを動かしているなんて報告があってビックリ。「やっぱり、グローバルには、皆、同じようなことやっているのね」と感心しました。

説明がゴタゴタしましたが、要するにMPDのビルドで問題をおこさないためには、「–disable-sndfile」とすることです。

尚、ビルドのパラメータ設定については、「MPDのチューニング・パッチ(2)」で紹介した yanさんの mpd-rtopt-2 に含まれるmy-config.shを使うと楽です。使い方はreadme.txtにある通りですが、

apt-get install libgoogle-perftools-dev

として、libgoogle-perftoolsをインストールしておいた方がよいでしょう。ただし、libgoogle-perftoolsでビルドすると同じライブラリの入っている環境のみでしかモジュールが動かなくなるので、要注意です(バイナリの配布には使えない)。

前回の記事とmpdinstall.tgz、mpdbuild.tarは修正しておきました。
mpdbuild.tarをお使いの方はmy-config.shの修正版(mpdinstall.tgz作成用に使ったもの、–disable-sndfile設定済)を同封してありますので、そちらで、再度、ビルド作業を行って下さい。
古いmpdinstall.tgz(日付が4月のもの)でインストールして、新しいmpdinstall.tgzでインストールする場合は同封のmpdinstall.shは使用せず、rootでログインし、

/etc/init.d/mpd stop
tar zxvf /media/usb0/mpdinstall.tgz
cp ./mpd /usr/local/bin
/etc/init.d/mpd start

としてください(/media/usb0の部分はtarボールの置いてある場所で変わります)。

(PC_Audio)   2011/05/03

コメントする

世界で一番美しい「元素図鑑」

著者は米国のサイエンスライタにして元素コレクタ。

100番までの全ての元素を解説し、関連する写真を集めた本です。とても上手くまとめられいて、眺めているだけでも楽しい。

LPレコードよりちょっと小さめ。縦25cm横25cm位の正方形、厚さ4cm、重さは出来の悪いノートパソコンより重いです。3Kg位あるかな。とても寝ころがって持てない。でも、楽しく読めて、読みごたえのある本です。
内容はエロティックな要素の無い(^^;;「大人の絵本」というところ。

今、話題の(^^;;;、水素とか、ホウ素とか、ウランとか、プルトニウムとか、に関しても丁寧に解説されています。

ちなみに、プルトニウムについて。

「プルトニウム核爆弾は、一見簡単に作れそうに思えるかもしれません。たしかに、十分な量のプルトニウムを得るのはそんなに難しくはありません。原子炉が一基必要ですが、ウラン同位体の分離に比べれば子供のお遊びみたいなものです。事実、ひとりの少年が本気でそれをやろうとしたことがあります。1995年、デイビッド・ハーンという高校生が自宅裏に増殖炉を作って、大騒ぎになりました。彼のミニ原子炉は実際にうまく作動しただろうと考える人もいます。
それはともかく、信じがたい偶然の恩寵により、プロルトニウムを作るのは比較的簡単でも爆弾にするのはおそろしく難しいのです。プルトニウムはウラン235よりずっと分裂しやすく、臨界未満の固まりを二つ衝突させようとしても、接触する前に反応が始まってその反動で飛び散ってしまい、連鎖反応はおきません。広範囲に放射能がまき散らされはしますが、都市を焼き尽くすのは無理です。」

福島で起きていることって、これなのかしら。ちょっと違うのかな。

「プルトニウムで核爆発を起こさせるには、完璧に近い「爆縮レンズ」を使って球体を表面から内破させ、臨界量のプルトニウムを一転に集める必要があります。衝撃波の加わり方がわずかでも非対称になれば、プルトニウムはその抜け道を通って逃げてしまいます。現代ですら、プルトニウム核分裂型爆弾の製造は最高の金属工学、爆破技術、製造技術を結集しないとできません。素人が作っても、まず間違いなく不発でしょう。」
だそうです。

直前の記事のVoyageMPDのチューニングしながら、読んでいたのですがなかなかいいです。集中して音楽を聴いた後のリラックス用に。
こんな元素、知らなかったなぁというのが大部分だけど、ヴィジュアルに、かつ簡潔、丁寧な解説で何か分かったような気がする(^^;;。楽しく読みました。

(review)   2011/05/01

コメントする

MPDのチューニング・パッチ(5)

「OSがその配下で動くプログラムをどうコントロールしているか」なんて情報は普通は知る必要のないことですが、チューニングするためにはある程度の知識が必要です。この記事はなるべく前提となる知識なしで理解できるように書くつもりですが、参考にした情報源を以下にあげておきます。


VoyageMPDのチューニング

どれだけ安定的に音楽データを音源に送ることができるかで音の良いソフトは決まるはずです。

「そんなもん、ハードを速くすれば問題ないだろう」というご意見はあるかもしれませんが、大震災の翌週に起きた某銀行のトラブルを思い出して頂ければと思います。最高速のハードとネッワークをもってしても、ちょっとしたデータ量の増大に対処できず、一週間トラブルったわけだから。

OSのマルチタスク処理

音を鳴らす(音楽データを音源に送る)処理は、

  • 音楽データを読み出す
  • 読み出したデータを音源が再生できるフォーマットに変換する
  • 変換したデータを音源に送り出す

という要素からなり、シーケンシャルには処理できないので(シーケンシャルに処理すると演奏開始まで長時間待たされることになる)、通常、これらは同時に並行して処理されます。
Linuxの場合これらの個々の処理はプロセス又はスレッドと呼ばれる単位で管理され、OSが定めたルールで全ての処理が「なるべく円滑に」行われるようコントロールされています。

この「なるべく円滑に」を担保するキーワードが「優先度」、「割り込み」、「占有時間」、「プリエンプティブ」です。

「優先度」とは
個々の処理を行うプロセス又はスレッド毎に付けられる優先度の数値です。OSは優先度の高いプロセス又はスレッドを優先的に動かします。優先度は Voyageのようなリアルタイムカーネルではマイナスで表現されマイナスの数が大きい程優先度は高くなります。
yanさんパッチはここに着目したもので、この優先度の設定をMPDのスレッド単位に可能にして、「なるべく円滑に」音楽再生処理を行わせ、音を良くしようというものです。
「割り込み」とは
OSに今やっている処理を一時中断させ、緊急処理させるための信号のことです。音楽の再生では、NASやUSBと絶え間なくデータのやりとりを行っています。「USB音源に100バイト分データを送り終わったよ」、「NASから100バイト分データを受け終わったよ」というようなタイミングで、ハード(ファームウェア)は次の処理を促すため、OSに信号を送ります。これが「割り込み」です。OSはこれを受けて適当なプロセス/スレッドを動かし、ハードに対する次の処理を優先的に行うという仕組みになっています。

一般にこの割り込みで制御を渡されるプロセス/スレッドの優先度は高いです。Voyageの場合、ハードウェアの割り込み処理のディフォルトの優先度は全て-51です。この値は、RTレベル(絶対に割り込まれないで処理が終わるまで動き続ける)で動くプロセスを除くと、最優先となります。

root@voyage:~# ps -eLo pid,lwp,priority,cmd
  PID   LWP PRI CMD
・・・
 1226  1226 -51 [irq/14-ide0]
 1227  1227 -51 [irq/23-ehci_hcd]
 1228  1228 -51 [irq/23-uhci_hcd]
 1229  1229 -51 [irq/19-uhci_hcd]
 1232  1232 -51 [irq/19-ata_piix]
・・・
 1240  1240 -51 [irq/18-uhci_hcd]
 1242  1242 -51 [irq/16-uhci_hcd]
・・・
 1949  1949 -51 [irq/16-eth0]
・・・ 

また、割り込み処理にはソフトウェアによるものがあります。これはメモリとかCPUの管理のため、ソフトで意図的に割り込みを発生させ、優先処理しようとするための仕組みです。プロセス番号の若い並びで sirq-XXXXn と表示されるものはソフトウェア割り込みのプロセスです。Voyageの場合、こちらも優先度は高く設定されていて、ハード割り込みに次ぐ-50という数値です。

・・・
    3     3 -100 [migration/0]
    4     4 -50 [sirq-high/0]
    5     5 -50 [sirq-timer/0]
    6     6 -50 [sirq-net-tx/0]
    7     7 -50 [sirq-net-rx/0]
    8     8 -50 [sirq-block/0]
    9     9 -50 [sirq-block-iopo]
   10    10 -50 [sirq-tasklet/0]
   11    11 -50 [sirq-sched/0]
   12    12 -50 [sirq-hrtimer/0]
   13    13 -50 [sirq-rcu/0]
   14    14 -100 [posixcputmr/0]
   15    15  10 [desched/0]
・・・ 僕のAtom機では同じものが4組あります。
「占有時間」とは
OSはプロセス/スレッド毎にどれだけのCPU時間を使ったか監視しています。これは複数のプロセス/スレッドが多重に処理する時、特定のプロセス/スレッドがCPU時間を独占しないようにするためです。OSはあるプロセス/スレッドのCPU占有時間が一定の時間連続したら、そのプロセス/スレッドを止めて、別のプロセス/スレッドを動かします。
リアルタイムレベルの優先度で動くプロセス/スレッドについてはこの仕組みが働かないことに注意する必要があります。
リアルタイムレベルでCPUを大量に使うプロセス/スレッドの優先度を高くしすぎると、他のプロセス/スレッドが動けなくなります。音楽再生で長時間CPUを占有する処理はデコード処理です。
「プリエンプティブ」とは
プリエンプティブ」とは差し替え可能なという意味。OSがプロセスやスレッドを必要に応じて自在に入れ換える仕組みのことをいいます。リアルタイムカーネルでプロセス/スレッドを処理する場合、この入れ換えのルールは単純です。
OSはハード又はソフトで割り込まれた時。各プロセス/スレッドの優先度をチェック。一番優先度の高いプロセス/スレッドを実行します。
リアルタイムでないプロセス/スレッドのCPU占有時間も考慮され、もっと複雑なルールになっていますが、リアルタイムレベルの優先度が指定されているプロセス/スレッドの場合は上記のルールだけです。


基本的なルールはこれだけです。従ってリアルタイムカーネルでプロセス/スレッドがリアルタイムの優先度を設定されている場合、話は単純で、優先度をプロセス/スレッドの処理の内容とCPU占有度を考慮してどう設定するかが勝負となります。

音楽再生に関するプロセス/スレッド

以下は、NAS接続で音楽データを読み込み、USB接続の音楽デバイスを鳴らすという条件で解説します。

最初に音楽再生に関するプロセス/スレッドを洗い出します。

まず、ハード割り込み処理するプロセスを調べます。

root@voyage:~# cat /proc/interrupts
           CPU0       CPU1       CPU2       CPU3
  0:        145          0          0          0   IO-APIC-edge      timer
  1:          8          0          0          0   IO-APIC-edge      i8042
  9:          0          0          0          0   IO-APIC-fasteoi   acpi
 14:          0          0          0          0   IO-APIC-edge      ide0
 16:     241921          0          0          0   IO-APIC-fasteoi   uhci_hcd:usb5, eth0
 18:          0          0          0          0   IO-APIC-fasteoi   uhci_hcd:usb4
 19:       2319          0          0          0   IO-APIC-fasteoi   ata_piix, uhci_hcd:usb3
 23:     603168          0          0          0   IO-APIC-fasteoi   ehci_hcd:usb1, uhci_hcd:usb2
NMI:          0          0          0          0   Non-maskable interrupts
LOC:     108459      78283      55140     623350   Local timer interrupts

一時間位音楽再生した状態ですが、CPU0の16、19、timerの割り込みだけが動作していることが分かります(CPUnの部分に表示される数値が割り込み回数です)。
割り込み番号(左端)の16はNAS、23は音源のようです。
USB音源の割り込み回数は60万回ありますから一秒間に200回位割り込まれていることになります(5msに一回)。
タイマーの割り込みの回数はもっと多いことも分かります。
またNASの割り込み回数はUSBの半分以下ですから、データのやりとりの単位は倍以上なのですかね。
何をいっているかというと、優先度を割りつける時、USBとタイマーの優先度を高くするのが方が賢明ということです。

0508追記
「USBとタイマーの優先度を高くするのが方が賢明」はどうも誤りであったようです。コメントを参照して下さい。

次に対応するプロセスの名前と優先度を調べます。

root@voyage:~# ps -eLo pid,lwp,rtprio,priority,cmd
  PID   LWP RTPRIO PRI CMD
・・・
 1285  1285     50 -51 [irq/23-ehci_hcd]
 1293  1293     50 -51 [irq/23-uhci_hcd]
 1296  1296     50 -51 [irq/16-uhci_hcd]
 2005  2005     50 -51 [irq/16-eth0]

ハード割り込みですのでディフォルトの -51となっています。
次にソフト割り込み処理のプロセスですが、タイマー処理は以下の通り。

・・・
    5     5     49 -50 [sirq-timer/0]
   19    19     49 -50 [sirq-timer/1]
   32    32     49 -50 [sirq-timer/2]
   45    45     49 -50 [sirq-timer/3]
・・・

こちらはディフォルトが -50です。
次に演奏中のtop画面を観察。

一回目
root@voyage:~# top
  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
 4623 mpd       20   0 58996  56m  14m S    1  2.8   0:04.37 mpd
 1227 root     -51   0     0    0    0 S    1  0.0   1:15.33 irq/23-ehci_hcd
    5 root     -50   0     0    0    0 S    0  0.0   0:02.37 sirq-timer/0
 1228 root     -51   0     0    0    0 S    0  0.0   0:05.63 irq/23-uhci_hcd
 1242 root     -51   0     0    0    0 S    0  0.0   0:06.06 irq/16-uhci_hcd
 1949 root     -51   0     0    0    0 S    0  0.0   0:07.30 irq/16-eth0
二回目
root@voyage:~# top
  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
 4623 mpd       20   0 58996  56m  14m S    1  2.8   0:12.37 mpd
 1227 root     -51   0     0    0    0 S    1  0.0   1:19.72 irq/23-ehci_hcd
   32 root     -50   0     0    0    0 S    0  0.0   0:02.49 sirq-timer/2
   45 root     -50   0     0    0    0 S    0  0.0   0:06.09 sirq-timer/3
   53 root     -50   0     0    0    0 S    0  0.0   0:02.60 sirq-rcu/3
 1949 root     -51   0     0    0    0 S    0  0.0   0:07.69 irq/16-eth0
 2009 root      20   0     0    0    0 S    0  0.0   0:10.52 cifsd

TIME+ は累積の稼働時間です。
演奏中に動いているアプリケーションはmpdとcifsd(NASとのデータの送受信に関するデーモン)と確認できます。この二つのプロセスを調べます。 TIME+の数値は興味深いですね。irq/23が全体の75%位の時間を使っていることになります。mpdの数字が案外少ないのは、この時再生していたデータがWAVEファイルだったから(デコード処理が入らない)だと思います。タイマーのCPU消費時間は確かに多少多めです。合計するとLANと同じ位です。

  PID   LWP RTPRIO PRI CMD
 2065  2065      -  20 [cifsd]
・・・
 2681  2681      -  20 /usr/local/bin/mpd /etc/mpd.conf
 2681  2682      -  20 /usr/local/bin/mpd /etc/mpd.conf
 2681  2684      -  20 /usr/local/bin/mpd /etc/mpd.conf
 2681  2687      -  20 /usr/local/bin/mpd /etc/mpd.conf

RTPRIOというのはリアルタイムプロセス(スレッド)の優先度(数値が大きい方が優先度は高い、設定されていない時は上のように「-」と表示されます)、PRIというのは全てのプロセスの優先度(数値の小さい方が優先度は高い)。top画面のPRは上記のPRIと同じです。
PIDはプロセス番号、LWPはスレッド番号です。再起動されると番号は変わります。
cifsdはプロセス=スレッドで動いていますが、mpdは四つのスレッドに分かれて動いています。
Voyageのディフォルトではアプリケーションのリアルタイムの優先度は設定されていないことが分かります。
mpdのスレッドは上から順番に

  • main
  • player
  • decoder
  • output

となります。 mpdのスレッドの構成とチューニングの基本については、yanさんのreadme.txtの「5. mpdのスレッド」に詳しく解説されていますので、そちらを参照して下さい。

これで役者は出揃いました。

優先度の設定方法

次に優先度の設定方法です。

MPDのスレッドについては、優先度は mpd.confに設定することになります。yanさんのreadme.txtの「4. 設定方法」に解説されていますのでそちらを参照して下さい。
僕は修正を楽にするため以下のようにmpd.confの頭に関連するパラメータを集めました。

# An example configuration file for MPD
# realtime option
realtime_option {
    memlock              "yes"
    stack_reserve        "1024"
    heap_reserve         "10240"

    main_priority        "OTHER:0"
    player_priority      "FIFO:50"
    decoder_priority     "FIFO:47"
    update_priority      "OTHER:0"
}
audio_output {
        type            "alsa"
        name            "My ALSA Device"
        device          "hw:0,0"        # optional
        priority        "FIFO:52"
#       format          "44100:16:2"    # optional
#       mixer_device    "default"       # optional
#       mixer_control   "PCM"           # optional
#       mixer_index     "0"             # optional
}
audio_buffer_size               "1024"
buffer_before_play              "30%"

・・・

例はAlsaのものですが、OSSを使っている場合はそちらにpriorityを指定します。
その他のハード、ソフト割り込み処理と cifsd の優先度の設定については chrt (change rt levlの略か?)というコマンドを使います。このコマンドの書式は

chrt - manipulate real-time attributes of a process.

Set policy:
  chrt [options]   { |  [ ...]}

Get policy:
  chrt [options] { |  [ ...]}


Scheduling policies:
  -b | --batch         set policy to SCHED_BATCH
  -f | --fifo          set policy to SCHED_FIFO
  -i | --idle          set policy to SCHED_IDLE
  -o | --other         set policy to SCHED_OTHER
  -r | --rr            set policy to SCHED_RR (default)

Options:
  -h | --help          display this help
  -p | --pid           operate on existing given pid
  -m | --max           show min and max valid priorities
  -v | --verbose       display status information
  -V | --version       output version information

となります。
従って、

chrt -f -p 優先度 プロセス番号

とすれば良いのですが、困ったことが一つあります。プロセス番号はOSが毎回ダイナミックに決めるので固定しないということ。
そこで、プロセス番号をプロセス名から変換するコマンドを組み合わせ使います。

chrt -f -p 52 `pgrep irq/23-uhci_hcd`

という具合です。
セットするプロセスの数が多いので、いちいちコマンドを打ち込むよりシェルスクリプリトにした方が楽です。

#!/bin/bash
# chrtset.sh  リアルタイム優先度設定用スクリプト
chrt -f -p 50 `pgrep sirq-timer/0`
chrt -f -p 50 `pgrep sirq-timer/1`
chrt -f -p 50 `pgrep sirq-timer/2`
chrt -f -p 50 `pgrep sirq-timer/3`
chrt -f -p 52 `pgrep irq/23-uhci_hcd`
chrt -f -p 52 `pgrep irq/23-ehci_hcd`
chrt -f -p 52 `pgrep irq/16-uhci_hcd`
chrt -f -p 52 `pgrep irq/16-eth0`
chrt -f -p 48 `pgrep cifsd`

このスクリプトをrc.localから呼ぶという形にしておけば、起動時に自動的に設定されます。

root@voyage:~# emacs ./chrtset.sh      # 新規ファイル
上記内容を編集、保存
root@voyage:~# chmod 755 ./chrtset.sh  # 実行権を設定
root@voyage:~# emacs /etc/rc.local     # 以下の行を挿入、保存
/root/chrtset.sh


これで舞台も整いました。

チューニングの方法

あとは実際に設定を変え、音を聴きながら最適値を探るということになります。

  decoder   cifsd   player   sirq-timer    output   irq/23/16 

をどういう順番に並べると一番良い音になるのか。


05/05 追加 ここから

ユングさんから「『decoder cifsd player sirq-timer output irq/23/16』とその前の『realtime_option』、『audio_output』と『chrt -f -p 50 ….』の関連が分からん」というご指摘がありましたので、補足しておきます。

『decoder player output』はMPD内部のスレッドのことです。スレッドというのはOSがプログラムを管理するための最小単位で、スレッド毎に優先度を設定することができます。

『decoder』、『player』は『realtime_option』の

    player_priority      "FIFO:50"
    decoder_priority     "FIFO:47"

に対応します。
『FIFO:50』の50がリアルタイムのプロセスの優先度(RTPRIO)です。この数字を変えてチューニングします。大きくすれば、優先度は高くなります。

『output』は『audio_output』の

        priority        "FIFO:52"

に対応します。

FIFOというのは「first in first out」の意味で、待ち行列の理論で先に入って来たものから順番に処理することです。OSのプロセス(スレッド)管理の基本はこれです。このパラメータも変更可能ですが、普通は変更不要です。

0508追記
「普通は変更不要」と書きましたが、変えた方がいい場合もあるようです。コメントを参照して下さい。

次に『cifsd sirq-timer irq/23/16』というのはプロセスの名前で

cifsd
Windowsとのファイル共用をするためのデーモン
sirq-timer
ソフトウェアタイマの割り込み処理をするプロセス
irq/23/16
ハードウェアの割り込み処理をするプロセス。23と16はハードウェアの割り込み番号。

これらのリアルタイムの優先度はchrtコマンドを使います。chrtは

chrt -f -p 50 `pgrep sirq-timer/0`

という具合に使いますが、50というのがリアルタイムの優先度。これを変えてチューニングします。
『sirq-timer/0』というのがプロセスの名前です。プロセスの名前の調べ方は本文「音楽再生に関するプロセス/スレッド」の直後にあります。

このchrtで優先度を設定するプロセスは自分の環境に合わせて探す必要があります。『cifsd sirq-timer irq/23/16』というのは僕の環境の例であって、他の環境では変わります。例えば『cifsd』は音楽データをSamba接続のNASから受け取っているから設定した訳で、ハードディスクから読み出すのであれば、そのハードディスクの割り込み処理プロセスに変えることになります。またソフトタイマ割り込みの数は使用するCPU数で変わります。
この割り込み捜しを簡単に行う方法は、音楽を再生しながら、top画面を表示し、よく動いているプロセスを探し出すという方法です。これも本文に書きましたので、そちらを参照して下さい。

要注意なのはtop画面で表示されるPRは通常の優先度を表示しますので、

通常の優先度 = -1 - リアルタムの優先度

と表示されることです。ビックリしないように。

あと

root@voyage:~# ps -eLo pid,lwp,rtprio,priority,cmd

はいっぱいプロセスが表示されてワケワカメになるということなら、例えば割り込みに関連するプロセスだけ表示にするには

root@voyage:~# ps -eLo pid,rtprio,priority,cmd | grep irq
    4     49 -50 [sirq-high/0]
    5     54 -55 [sirq-timer/0]
    6     49 -50 [sirq-net-tx/0]
    7     49 -50 [sirq-net-rx/0]
    8     49 -50 [sirq-block/0]
    9     49 -50 [sirq-block-iopo]
   10     49 -50 [sirq-tasklet/0]
   11     49 -50 [sirq-sched/0]
   12     49 -50 [sirq-hrtimer/0]
   13     49 -50 [sirq-rcu/0]
  120     50 -51 [irq/9-acpi]
  942     50 -51 [irq/1-i8042]
 1137     50 -51 [irq/14-ide0]
 1138     53 -54 [irq/23-ehci_hcd]
 1139     50 -51 [irq/19-ata_piix]
 1146     53 -54 [irq/23-uhci_hcd]
 1147     50 -51 [irq/19-uhci_hcd]
 1148     50 -51 [irq/18-uhci_hcd]
 1149     52 -53 [irq/16-uhci_hcd]
 1824     52 -53 [irq/16-eth0]
 2284      -  20 grep irq

とすればいいです。
ソフト割り込みはシンさんの掲示板でのアドバイスを頂戴してシングルCPUモードを指定したので一種類だけとなりました(grub.cfgにmaxcpus=1を指定)。
優先度を指定しているプロセス、スレッドだけを表示したければ、

root@voyage:~# ps -eLo pid,lwp,rtprio,priority,time,cmd | egrep "sirq-ti|irq/16|irq/23|mpd|cifsd"
    5     5     54 -55 00:00:00 [sirq-timer/0]
 1138  1138     53 -54 00:00:09 [irq/23-ehci_hcd]
 1146  1146     53 -54 00:00:01 [irq/23-uhci_hcd]
 1149  1149     52 -53 00:00:01 [irq/16-uhci_hcd]
 1824  1824     52 -53 00:00:02 [irq/16-eth0]
 1884  1884     48 -49 00:00:03 [cifsd]
 2095  2095     47 -48 00:00:00 /usr/local/bin/mpd /etc/mpd.conf
 2095  2097     49 -50 00:00:01 /usr/local/bin/mpd /etc/mpd.conf
 2095  2098     47 -48 00:00:05 /usr/local/bin/mpd /etc/mpd.conf
 2095  2135     51 -52 00:00:01 /usr/local/bin/mpd /etc/mpd.conf
 2293  2293      -  20 00:00:00 egrep sirq-ti|irq/16|irq/23|mpd|cifsd

とすればいいです。
只今、チューニング中なので、下の記述とは違う設定になっています。
egrepというのは正規表現の使えるgrepで、“sirq-ti|irq/16|irq/23|mpd|cifsd”は『|』で区切りられた文字列を含む全ての行を表示しなさいという意味です。
こういう具合にコマンドを組み合わせ、自分のやりたいことが自在に出来るのが、Linuxのいいところです(Windowsだと、大変だと思います)。

05/05 追加 ここまで
05/08 追加 以下の記述は最初にチューニングしていた時のものです。その後の経緯は掲示板にありますのでそちらも参照して下さい。


以下は僕のとっている方法を紹介します。

まず、最初に基本したルール

  • ハード割り込み(irq)とソフト割り込み(sirq)の中で音楽再生に関係ないものはディフォル(-51,-50)のまま
  • cpu占有率の高い decoder処理は最下位の -48 に固定(上位に動かしても良い結果は出なかったので)

次に試してみて、固定化したルール

  • 明らかに音が悪くなる設定は避ける(具体的には下の並びでdecoderを右端にとか、outputを左端に)
  • cifsdはcpu占有率は高いので、低めの優先度(-49)にする
  • playerはmpd-buffer-c.diffがかかっているならばソフト割り込みディフォルト(-50)同じかそれ以上の優先度にするのが良い

残りの三種類のプロセス/スレッド(sirq-timer, output, irq/23/16)の優先度は

  • 音楽の種類(オーケストラ、室内楽、声楽、現代曲、古楽など)
  • 録音(デジタル、アナログ、古い録音、マルチマイク録音、ワンポイント録音など)
  • 環境(パソコン、0SS/Alsa、音源など)
  • その時の気分(^^;;;

次第でベストのポイントはころころと変わります。

現時点で僕の設定方法は

  decoder(48) < cifsd(49) < sirq-*(51) < sirq-timer(52) = player(52) = irq/*(52) < output(53) = irq/16(53) < irq/23(54)

です。
考え方としては、USBにデータを送り出す処理(irq/23)を最優先させる。ソフト割り込み、playerを同じグループで管理。output、irq/16を同じグループにしてUSB出力の次の優先度をつける。タイマーはどう効くかいろいろ試してみる。というところです。
この状態を固定しながらソフトタイマーの優先度を順に変えていくと、音が微妙に変化します。解像度を高くしたいのだったら、ソフトタイマーの優先度を高めにした方がよさそうです。

他にもいろいろなやり方がありそうです。面白い組み合わせが見つかったら、是非、掲示板で教えて下さい。

(PC_Audio)   2011/04/27

コメントする

MPDのチューニング・パッチ(4)


MPD 0.17.0 コンパイル済バイナリとインストール用シェルスクリプト(mpdinstall.tgz)


「gccだの、makeだの、gitだの、sqliteだの訳の分からんLinuxツールをインストールするのは不愉快だ」という方にはこちらをお勧めします。

yanさんから

あと、非linuxユーザにはコンパイルの敷居は高いかもしれないので、
コンパイル済みのバイナリーもアップしたほうがいいかもしれません。
CFLAGSの'-m***'を取ればx86系のCPUなら動作すると思います。

という提案を頂きました。よいアイディアだと思いますので、前掲した readme.txt にある my_install.sh を使って、バイナリー版を作成。インストール用のシェルスクリプトと一緒に tarボールにしました。二つのパッチはかかっています。

MPDの設定は以下の通りです。

########### MPD CONFIGURATION ############

Archive support:
        (-bzip2) (-ISO9660) (-ZIP)
Client support:
        (-IPv6) (+TCP) (+UNIX Domain Sockets)
File format support:
        (-AAC) (-C64 SID) (+FFMPEG) (+FLAC) (-FluidSynth) (-GME) (-libsndfile)
        (-MikMod) (-MODPLUG) (-MAD) (-MPG123) (-MP4) (-Musepack) (-OggFLAC)
        (-OggTremor) (+OggVorbis) (+WAVE) (-WavPack) (-WildMidi)
Other features:
        (+libsamplerate) (-inotify) (+SQLite) (+rtopt)
Metadata support:
        (-cue) (+ID3)
Playback support:
        (+ALSA) (-ROAR) (-FFADO) (+FIFO) (-File Recorder) (-HTTP Daemon) (-RAOP) (-JACK) (-libao) (+OSS)
        (-OpenAL) (-OS X) (+Pipeline) (-PulseAudio) (-Media MVP) (-SHOUTcast)
        (-Solaris) (-WinMM)
Streaming support:
        (-CURL) (-Last.FM) (-MMS) (-CDIO_PARANOIA) (-Despotify)

##########################################


インストールの仕方は root でログインして(USBメモリ渡しでデータを移す場合)

tar zxvf /media/usb0/mpdinstall.tgz
./mpdinstall.sh

tarボールを展開、インストール用シェルを起動するだけです。

インストール用のシェルスクリプトの内容は以下の通りです。

#!/bin/bash
# mpdinstall.sh  MPD 最新版(17.0) インストール用スクリプト
/etc/init.d/mpd stop
cp ./mpd /usr/local/bin
echo DAEMON=/usr/local/bin/mpd >>/etc/default/mpd
sed -i "s/^\([\t ]\+device[\t ]\+\"hw:[0-9]\+,[0-9]\+\".*\)$/\1\n\tpriority\t\"FIFO:52\"/" /etc/mpd.conf
cat <<EOF>>/etc/mpd.conf
# realtime option
realtime_option {
    memlock              "yes"
    stack_reserve        "1024"
    heap_reserve         "10240"

    main_priority        "OTHER:0"
    player_priority      "FIFO:47"
    decoder_priority     "FIFO:48"
    update_priority      "OTHER:0"
}
EOF
/etc/init.d/mpd start

MPDをとめて、バイナリをコピー。/etc/default/mpdへのMPDの場所の変更、/etc/mpd.confに対するリアルタイムオプションの設定を行い、MPDを再開させています。優先度などは必要に応じて修正してお使いください。
都合で<<EOF>>の«»は全角です。

(PC_Audio)   2011/04/23

コメントする

MPDのチューニング・パッチ(3)


yanさんから、メールを頂戴しました。

yoさん こんばんは

player > decoder とすると曲の頭出しがうまくいかない件が解決しましたの
で、パッチを添付します。

mpdのソースがあるディレクトリで
# zcat mpd-buffer-c.diff.gz | patch -p1

でパッチをあってて下さい。

このパッチは0.16.1 やrealtime_option のパッチがあたってない
場合でも有効です。
このパッチをあてると早送りなども前よりスムーズになります。
また、個人的にはplayer > decoderの方が好ましく感じます。

パッチは以下からダウンロードできます。

MPD のチューニング・パッチ(buffer.cの変更 mmpd-buffer-c.diff.gz)   by yan


試してみましたが、とても効果的です。とくに player > decoder とした場合、解像度があがり、臨場感が増すという感じで、お勧めします。
前回のパッチとは違うプログラムのパッチですので、無関係に処理できるようです。
前回のパッチがかかっている場合は

root@voyage:~# cd ./mpd
root@voyage:~# zcat /media/usb0/mpd-buffer-c.diff.gz | patch -p1
root@voyage:~# sh ./my-config.sh
root@voyage:~# make
root@voyage:~# make install

でOK。
my-config.shがSQliteがないとエラーになる場合は

aptitude install sqlite3 libsqlite3-dev

でインストールして下さい。

(PC_Audio)   2011/04/22

コメントする

MPDのチューニング・パッチ(2)

以下の内容を実行する時はすべて自己責任でお願いします。yanさんも僕も内容について一切の保証はしません。

パッチというのはソフトウェアの変更を修正部分だけ提供し、原本のソースコードに対して簡単に変更できるようにする仕組みのことです。Linuxではソフトのアップデートでよくとられる方法です。パッチをかけたソースコードをコンパイルしなおして、最新版にする。Linuxそのものの修正もカーネルアップデートという形のパッチで提供されていて、OS本体をコンパイルするのは当たり前です。「マイクロソフトのOSは神聖にして不可侵(^^;;;」という環境の Windowsユーザにはとまどう世界ですが。

yanさんのパッチはMPDのヴァージョンが0.17.0に対応したものです。VoyageMPDのMPDのヴァージョンは16.0です。従って、パッチをかけるには、まずMPDを0.17.0にアップデートする必要があります。この方法もビルドといってソースコードからコンパイルする必要があります。やり方は以前の記事「MPDの最新版をビルド」を参照して下さい。
Windows 環境でのLinux用シェルスクリプトの編集は面倒なので、僕が今回使ったものを yanさんのチューニングパッチといっしょに置いておきます。スクリプト内容は以前の記事とほぼ一緒ですが、パッチをかけるために二つに分割し、realtime_optionの指定を追加しました。また「libmad mp3 decoder plugin」はdisableにしてあります。

MPD 0.17.0 のチューニング・パッチ(mpd-rtopt-2.tgz)   by yan

MPD 0.17.0 ビルド用シェルスクリプト(mpdbuild.tar)


簡単にパッチをかける手順を紹介します。
ダウンロードしたtarボールはUSBメモリでVoyageMPDシステムにもってくるとします。

rootでログイン
root@voyage:~# tar xvf /media/usb0/mpdbuild.tar        # シェルスクリプトの展開(usb0機番はdfなどで要確認)
root@voyage:~# tar zxvf /media/usb0/mpd-rtopt-2.tgz    # パッチファイルの展開
root@voyage:~# ./mpdbuild_pre.sh                       # MPDビルドを準備するシェルスクリプトを実行
この後の問い合わせに全て改行で答える。いっぱい出ます。
root@voyage:~# cd ./mpd
root@voyage:~# patch -p1 < ../mpd-0.17-0414-rtopt.diff
root@voyage:~# ../mpdbuild_i386_tune.sh                # MPDチューン版ビルドシェルスクリプトを実行

Mpod対応を有効にしたい場合は最後のスクリプトの実行はやめて、yanさんの readme.txt に従って下さい。
これでパッチのかかったMPDが作成され、切り替わります。
切り替わっているかの確認は

root@voyage:~# mpc version                             # 0.17.0 と表示されれば OK

で出来ます。 後は yanさんの readme.txt に丁寧な解説がありますので、そちらに従って下さい。

参考のため、yanさんの readme.txt 以下にを引用します。
テキストはMPDの動作の仕組みを見事に謎解きし、何故VoyageMPDが良い音で音楽を再生できるかを解明する素晴らしい内容です。パッチをかけない方にもご一読をお勧めします。 buffer_before_play が25%以上だと音に変化は発生しないはずとか、audio_buffer_size はエンコード処理のCPU負荷分散という形で音に影響している(従って、outputスレッドの優先度をencodeスレッドの優先度より高くすれば大きさは関係なくなる)というような考察はソースコードをハックしないと分からない内容で、実に興味深いです。


MPDのチューニング・パッチ readme.txt     by yan

1. はじめに

 このパッチはmpd-0.17に対してrealtime_optionを追加するためのパッチです。
 realtime_optionとは

   a. mpdを構成するスレッドのスケジュール方法、優先順位
   b. mpdの仮想空間を実メモリに割り当て(memlock)

  をmpd.confより設定可能とするものです。

2. パッチの当て方

 配布ファイルを展開すると以下のファイルが作成されます。
    readme.txt                 このドキュメント
    mpd-0.17-0414-rtopt.diff   realtime option のパッチ

 mpd-0.17のソースが展開されているディレクトリで以下のコマンドを実行します。

   patch -p1 < mpd-0.17-0414-rtopt.diff

   
 念のため 

   find . -name "*.rej" -print

  でrejectされたファイルがないか確認してください。
 あった、場合は連絡をお願いします。

3. コンパイル方法

  パッチがあったたら、autogen.shを実行してconfigureを作成してください。
 configureができたら改めてconfigureを実行してください。
  configureのパラメータで --enable-rtoptを指定するとrealtime_option が
 有効になります。
 configureのMPD CONFIGURATIONメッセージのOther features: 欄に(+rtopt)が
 あればrealtime_optionは有効になります。

 この後でmakeします。

 [補足]
   パッチを当てるとmy-config.shというファイルが新たに追加されます。
 これはconfigureのパラメータの指定例です。このようにしておくと
 ライブラリのインストール状態によらずにいつも同じmpdが作成できます。
 必要なライブラリがないときはエラーが表示されるので、その時インストールします。
  sh my-config.shで実行します。

  my-config.shの LIBS=-ltcmalloc_minimal はgoogle-perftools内のmallocを
 使うために指定してあります。google-perftoolsのmalloc(メモリを動的に割り当てるプログラム)
 は通常のmallocに比べて最大で300倍程度高速であるとされています。別に音には関係しないと
 思いますが気分がいいので私は使用しています。
 google-perftoolsを使う場合は、コンパイルするマシーン及び実行するマシーンに以下の
 パッケージをインストールしておく必要があります。

 http://code.google.com/p/google-perftools/downloads/detail?name=libgoogle-perftools-dev_1.7-1_i386.deb

 CFLAGSの-DFOR_MPOD_DBはipod touchで動作するmpodというクライアントの為のパッチです。
 mpodではアルバムタイトルに同じ物があるとマージして扱われます。FOR_MPOD_DB を指定すると
 アルバムタイトルを"本来のアルバムタイトル / アーチスト名"にします。
 mpodやmpadを使っていない場合はこのflagは削除してください。


4. 設定方法
  mpd.confに以下のパラメータを追加しました。
    ○ realtime_optionブロックパラメータ
     memlockやaudio_output以外のスレッドのスケジュール方法、優先順位を指定します。

    ○ audio_outputのpriorityパラメータ
     audio_output毎に生成されるスレッドのスケジュール方法、優先順位を指定します。

4-1. realtime_option

 mpd.confにrealtime_option のブロックパラメータを指定することで
 realtime_optionが有効になります。

  realtime_option で指定できるパラメータは以下のとおりです。

  realtime_option {
    memlock              "yes"
    stack_reserve        "1024"
    heap_reserve         "10240"
    
    main_priority        "OTHER:0"
    player_priority      "FIFO:47"
    decoder_priority     "FIFO:48"
    update_priority      "OTHER:0"
  }


 (1) memlock
     "yes"を指定するとmpdが使用するメモリをロック(仮想空間を実メモリに割り当てる)します。
     linuxのプロセスは起動時にメモリの領域を確保しますが、その領域は実メモリに割り当てられません。
   プログラムが実行中にメモリの割付が行われていない領域をアクセスするとpage faultという信号が発生し
   kernelがメモリを割り当てます。
   リアルタイムアプリケーションでは実行中になるべくkernelに介入されたくない場合にメモリをロックしたりします。
   また、lockされた領域はswap outされません。(swapの無いvoyageでは関係ありませんが)

     memlockを指定すると、実際に使われない領域まで実メモリが割り付けられるので
     メモリの量が少ない場合は"no"にしてロックを行わないようにします。

 (2) stack_reserve
     スタックに使う領域をあらかじめ実メモリに割り当てておくサイズを指定します。
   単位はkbです。これは1024固定にしておいてください。

 (3) heap_reserve
     プログラムが実行時に使うメモリのうちあらかじめ実メモリに割り当てておくサイズを
   指定します。単位はkbです。
   memlockを"no"にした場合はこれで実メモリを割り当てておきます。但し、swapoutされる場合があります。

  (4) main_priority,player_priority,decoder_priority,update_priority
     各スレッドの優先順位とスケジューリングの方法を指定します。
   指定は

    "スケジューリング方法:優先順位"

     で行います。

   スケジューリング方法は以下のものが指定できます。
   linuxのスケジューリングについては sched_setscheduler(2)のmanを参照してください。

      a. OTHER
        通常のLinuxのプロセスのスケジュール方法。
     この場合は優先順位は0を指定します。

      b. FIFO
        優先順位にしたがったスケジューリングを行う。

     一度実行権を獲得すると次のいずれかの条件が成立するまで実行権利を奪われることはない
         ○上位の優先順位を持つプロセスが実行可能になった場合
         ○自ら実行権を放棄(yield)した場合
         ○sleep(実行条件が成立するまで待つ)した場合

     同一優先順位を持つ複数のプロセスが実行可能になっている場合は早い者順に実行される。
     実行を放棄した場合やsleepしているプロセスがwakeupした場合は待ち行列の最後尾に
     つながれる。

       c. RR
        優先順位にしたがったスケジューリングを行う。

     一度実行権を獲得するとより次のいずれかの条件が成立するまで実行権利を奪われることはない
      ○上位の優先順位を持つプロセスが実行可能になった場合
          ○yield(自ら実行権を放棄)した場合
          ○sleep(実行条件が成立するまで待つ)した場合
          ○一定時間経過しても上記の条件が成立しなかった場合

     同一優先順位を持つ複数のプロセスが実行可能になっている場合は早い者順に実行される。
     実行を放棄した場合,sleepしているプロセスがwakeupした場合は、実行権を取り上げられた
     場合は待ち行列の最後尾につながれる。


       d. BATCH
     よく分からない。


   通常はFIFOを使います。
         
   優先順位はFIFO,RRの場合は1から99の範囲で設定します。数が大きくなるほど優先順位は
   高くなります。(topとは逆です)

4-2. outputのpriority

  audio_outputブロックパラメータ内にpriorityパラメータを記述する事により
  スケジューリング方法、優先順位を指定します。

  [例]

   audio_output {
        type            "alsa"
        name            "alsa-xmos"
        device          "x20"
        priority        "FIFO:81"
      }

  複数のaudio_outputがある場合、各audio_output毎に指定します。


4-3. 起動時の注意
  realtime_optionを指定した場合、limits値を解除しています。これはroot以外実行できない
 システムコールをつかいます。従って、起動はrootで行ってください。
 また、/etc/security/limits.confは参照しません。(セキュリティホールになるかもしれません)



ここから技術メモになります。

5. mpdのスレッド

  mpdは以下のスレッドで構成される。

    a. main thread
       各スレッドを起動後、クライアントとの通信を行う

    b. player thread
       プレーヤーのコマンド(再生、ストップなど)を管理する。
       また、decoder,output間のバッファーを監視しdecoder,output間の調停を行う。
       player thread がdecoder thread,output threadを起動する。

    c. decoder thread
       audio ファイルを読み込みpcmへ変換し、バッファーを介してoutput threadへ受け渡す。

    d. output thread
       decoder threadが受け渡されたpcmデータをドライバーに受け渡す。

    e. update thread
       tag_cacheのアップデートを行う。

  
  各スレッドの優先順位

    main,updateスレッドは直接音楽再生に関与しないと思われるので"OTHER:0"とする。

   decoder threadはflacやalacなどの圧縮されたファイルを処理する場合、比較的CPUを使う。
   このスレッドの優先順位をあげると他のスレッド、プロセスに長時間CPUが割り当てられない
  状態ができるのでこのスレッドの優先順位は比較的低くしたほうがよいように思う。

   decoderが生産者、outputが消費者になるがoutputは音楽ファイルのサンプリング速度に同期して
  動作し、またCPUも消費しない。outputスレッドの動作が乱れると音にも影響がでそうなので
  (根拠無し、単なる私の想像)このスレッドは優先順位を比較的高くした方がいいと思う。

    player スレッドはdecoderより優先順位を高くすると、頭出しがうまくいかない場合があるので、
  decoderより低くする。(要調査)

    player < decoder < output

   になるように設定する。


  その他のプロセスとの関係

  オーディオ出力に関係しそうなプロセスとして
     irq/12-ehci_hcd            USBの割り込みハンドラー
     irq/12-ohci_hcd            USBの割り込みハンドラー
     sirq-timer,sirq-hrtimer  タイマー関連の割り込み
     上記以外の割り込みハンドラー(sirq-**,irq-**)

     decoderが長時間CPU使っていると上記割り込みハンドラーの動作が乱されるおそれがある。
   また、USBにオーディオデバイスがつながっている場合、USBの割り込みハンドラーの動作も
   乱されたくない。
   タイマーはプログラムがタイミングを調整する時に使用されるのでタイマー割り込みもあまり
   乱されたくない。。但し、sirq-timerはCPUを使うプロセスなのでこれの優先順位を
   あまり高くするのは望ましくない。
   以上により以下のように設定するのがいいように思う。

    player < decoder < sirq-**,irq-** < output = usbの割り込みハンドラー = sirq-hrtimer

    または

    player < decoder < sirq-**,irq-** < usbの割り込みハンドラー = sirq-hrtimer < output

  プロセスの優先順位は相対的な物なので関連すると思われるプロセス間で調整を取る必要があり、当然他の組み合わ
  も考えられる。


[memo]
  audio_buffer_size,buffer_before_playについて

 decoderとoutputとの間にFIFOのバッファーが設けられこれを介してdecoderからPCMデータが
 outputに引き渡される。bufferの空き具合を監視してdecoderを起動するのはplayer thread。
 このバッファーはmusic_bufferと呼ばれている。

 music_bufferは4kbのチャンクという単位で管理される。
 audio_buffer_size / 4kb でチャンクの個数が求まる。 --> chunks
 before_playもチャンクの数に置き換えられる。   (chunks * buffer_before_play) / 100
  
 
 player threadではmusic_bufferの空きを監視しある程度空きができるとdecoderへデータの転送を指示する。
 その空きは以下の式で決めてる
 
   現在バッファーにあるchunkの数 < (before_play + (chunks * 3) / 4)

  before_playが0(buffer_before_playに100%を設定した場合)の時はmusic_bufferに1/4の空きが
 出来た時にdecoderへ転送の指示を行う。
 befor_playが25%以上である時は1個でも空きが生じればdecoderへ転送の指示を行う。

  一方、decoderはdecoder内部に変換用のバッファーを持っておりplayer threadから要求を受けると
 変換用のバッファーをmusic_bufferが満杯になるまで追加する。その間に変換用バッファーが 空になれば、
 データをfileから読込,変換を行う。

  以上の事から、buffer_before_play が25%以上ならば動作は同じに成るはず。
  また、この時decoderがこまめに起動されるのでcpuの負荷としては分散される。
 buffer_befor_playを0にすると、まとまった量の変換をdecoderが行うのでbuffer_sizeによっては間に合わなくなる
 場合がある。
 ハイビット、ハイサンプルのデータの場合より条件は厳しくなる。

 audio_buffer_sizeを変更すると音に影響があることが知られているが、それがdecoderの動作によって
 outputスレッドの動作が乱されるのが原因なら decoder < output とする事によってoutputはdecoder
 に影響されなくなり、audio_buffer_sizeの大きさを変えても音に影響が出なくなるはず。


6. 設定例

 現在は以下の設定にしている。

--------  mpd.conf --------
realtime_option {
    memlock              "yes"
    stack_reserve        "1024"
    heap_reserve         "10240"
    
    main_priority        "OTHER:0"
    player_priority      "FIFO:47"
    decoder_priority     "FIFO:48"
    update_priority      "OTHER:0"
}

audio_output {
        type            "alsa"
        name            "alsa-xmos"
        device          "x20"

        priority        "FIFO:99"
}
-------------------------------
--------- /etc/rc.local --------

chrt -p -f 98 `pgrep sirq-hrtimer`
#chrt -p -f 97 `pgrep sirq-timer`
chrt -p -f 98 `pgrep irq/12-ehci_hcd`
chrt -p -f 98 `pgrep irq/12-ohci_hcd`
---------------------------------------


7. 確認方法
7-1. 優先順位の確認
  以下のコマンドで行う。

   ps -eLo pid,lwp,rtprio,priority,cmd

  pid + lwpでスレッドを特定出来る。

  lwp は

     main < player < decoder < output

   になる。
  outputが複数ある場合は判断がつかない。

   rtprioは優先度。
   priorityはTOPのPRと同じ。 rtprioが99の場合、TOPでは"RT"と表示される。

  rtprio,priorityに関しては
   http://www.mazn.net/blog/2010/09/18/311.html

   が参考になる。

7-2. メモリの状態
 プロセスIDがpidのプロセスの状態は

   # cat /proc/pid/status

  で確認できる。

[例]
上記設定例のmpd.confでmpdを起動した場合

# cat /proc/1726/status

Name:   mpd
State:  S (sleeping)
Tgid:   1726
Pid:    1726
PPid:   1
TracerPid:      0
Uid:    103     103     103     103
Gid:    29      29      29      29
FDSize: 32
Groups: 29 
VmPeak:    60152 kB
VmSize:    60148 kB
VmLck:     60148 kB
VmHWM:     60136 kB
VmRSS:     60132 kB
VmData:    40836 kB
VmStk:      1032 kB
VmExe:       268 kB
VmLib:     17664 kB
VmPTE:        72 kB
 略

VmSizeが仮想空間の大きさ。
VmLckがロックされている仮想空間の大きさ。
VmRssは割り当てられている物理メモリの大きさ
VmDataは未初期化データの大きさ
VmStkはstackの大きさ

VmSize = VmLckなので仮想空間全体がロック(物理メモリに固定される)されている事がわかる。

mpdをrealtime_optionを指定しないで起動した場合は

VmPeak:    51920 kB
VmSize:    51920 kB
VmLck:         0 kB
VmHWM:     14160 kB
VmRSS:     14160 kB
VmData:    30596 kB   <-- heap_reserve分小さくなっている
VmStk:        84 kB   <-- stackも小さくなっている
VmExe:       268 kB
VmLib:     20624 kB
VmPTE:        52 kB

となる。

VmRss < VmData なのでプログラム未初期化データ部のうちまだ物理メモリが割り当てられていない
箇所がある。

上記設定例でmemlockを"no"にした場合、

VmPeak:    63108 kB
VmSize:    63108 kB
VmLck:         0 kB
VmHWM:     25416 kB
VmRSS:     25416 kB   <- heap_reserve分増加する
VmData:    40836 kB     <- heap_reserve分増加する
VmStk:      1032 kB
VmExe:       268 kB
VmLib:     20624 kB
VmPTE:        60 kB

heap_reserveで指定した分は物理メモリが割り当てられるが、まだ割り当てられていない箇所がある。
従って、memlockは行った方がよいと思われる。

heap_reserveにVmSizeとVmDataの差以上を指定するとVmSizeを大きくする事ができる。

heap_reserveを"102400"にした場合

VmPeak:   155272 kB
VmSize:   155272 kB
VmLck:    155272 kB
VmHWM:    155256 kB
VmRSS:    155256 kB
VmData:   132996 kB
VmStk:      1036 kB
VmExe:       268 kB
VmLib:     20624 kB
VmPTE:       164 kB

実行中にVmSize,VmPeakが大ききなる場合はheap_reserveであらかじめVmSizeを
大きくしておくとよい。

ご意見は掲示板にお願いします。yanさんもチェックしていらっしゃいますので、コメントしてもらえると思います。

しかし、こういう具合にネットワークを通してオーディオ環境の改良ができるのもオープンソースLinux環境下でのネットワークオーディオならですね。

(PC_Audio)   2011/04/21

コメントする

MPDのチューニング・パッチ(1)

掲示板にやりとりが残っていますが、yanさんからMPDのチューニング用のパッチを送って頂きました。
パッチは MPDを構成するスレッドのスケジュール方法、優先順位の自由な設定と MPDの仮想空間を実メモリへの割り当てを可能にするものです。また、パッチと一緒に yanさんがパッチを作られた背景となる技術知識を詳述した興味深いドキュメント(readme.txt)が付けられていました。どちらも素晴らしい内容ですので、VoyageMPD を使う方々が共有するといいのじゃないかなと考え、yanさんにお願いし、公開する許可を頂きました。以下、紹介します。


yo様

mpdのパッチファイルが出来たのでこのメールに添付しました。

添付ファイルを解凍すると
readme.txt
mpd-0.17-0414-rtopt.diff

が展開されます。
mpd-0.17-0414-rtopt.diffがパッチファイルです。
パッチのあて方、コンパイル方法、設定方法はreademe.txt
を参照して下さい。


yan様

早速試してみました。問題なく修正できたようです。
只今、音出ししているところですが、なかなか興味深いですね。
確かに、パラメータをいじると音は変わりますね。
丁寧に聴いてみないと結論は出せそうもないので、しばらく
時間をおいて改めて感想をメールしたいと思います。

readme.txt を拝見しました。素晴らしい内容ですね。
いままで、yanさんがあちこちで書かれていた内容の背景が
クリアにわかりました。
「MPDの音の良さの秘密が綺麗に謎解きされているなぁ」と
思いました。
player、decoder、outputをスレッドを分けて構成して、バッファを
介して互いの処理をできるだけディスターブしないように動作させる
という仕組みが見事に解説されています。
これが、例えばaplayなどよりMPDを使った方が音が良くなる理由
でしょうね。

これは、是非、パッチファイルと共に公開されて VoyageMPD を使う
方々が共有するといいのじゃないかなと考えます。

公開する手間が面倒だとということであれば、僕のサイトを使って
ダウンロードできるようお手伝いいたします。


yo様

> 早速試してみました。問題なく修正できたようです。
> 只今、音出ししているところですが、なかなか興味深いですね。
> 確かに、パラメータをいじると音は変わりますね。
> 丁寧に聴いてみないと結論は出せそうもないので、しばらく
> 時間をおいて改めて感想をメールしたいと思います。

優先順位はいろんなプロセスとの関係で決めなければいけないので
なかなかこれだといいきれないので大変だなと感じています。

> player、decoder、outputをスレッドを分けて構成して、バッファを
> 介して互いの処理をできるだけディスターブしないように動作させる
> という仕組みが見事に解説されています。
> これが、例えばaplayなどよりMPDを使った方が音が良くなる理由
> でしょうね。

mpdはクライアントからスキップや巻き戻しが等ができるようになっているので
それを実現するだけでも結構複雑になっています。
通常のソフトならテストが通れば完成ですが、MPDのようなソフトの場合は
テストが通ってから音質のテストもあるのですから大変だと思います。

> これは、是非、パッチファイルと共に公開されて VoyageMPD を使う
> 方々が共有するといいのじゃないかなと考えます。
> 
> 公開する手間が面倒だとということであれば、僕のサイトを使って
> ダウンロードできるようお手伝いいたします。

なるべく多くの人に評価してもらったほうがいいと思うので、公開の件
是非お願いします。
多くの人に評価してもらえば、プロセスの優先度と音質に相関があるかないかが
はっきりするかもしれません。
ubuntu studioを使っている人の間では優先度を上げたりメモリをロックすると
音質が向上するのが定説になっているようです。

一部修正したい箇所(スレッド関連ではなくMPOD対応の部分)があるので
その修正したものを送りますので、それの公開をお願いします。


yo様

mpd-rtopの修正版です。
mpod対応の修正でスレッド関連には修正はありません。
mpod対応を使っていない場合は変更する必要はありません。
readme.txtも一部修正してあります。

お言葉に甘えて配布をお願いします。今回添付したファイルを配布して下さい。
ライセンスなどは一切主張しませんので、勝手に改造配布はしてかまいません。


yan様

新しいパッチありがとうございます。早速公開の準備にかかりたいと思います。

パッチをかけたシステムでいろいろなCDを聴き比べてみました。

メモリのロックについてはロックした方がいいなと思いました。
ロックしない音は多少乾いた感じで、ロックした音の方が繊細なニュアンスを
より伝えてくれるなという感じですね。
もちろん、パッチをかける前はロックしないで聴いていたわけですから、
比較しないと気が付かないレベルではありますが。

プロセスの優先度ですが、これは判断が難しいですね。
いじりまわして、最終的な rc.local と mpd.conf の内容は以下の通りです。

chrt -f -p 53 `pgrep sirq-timer/0`
chrt -f -p 53 `pgrep sirq-timer/1`
chrt -f -p 53 `pgrep sirq-timer/2`
chrt -f -p 53 `pgrep sirq-timer/3`
#chrt -f -p 53 `pgrep sirq-hrtimer/0`
#chrt -f -p 53 `pgrep sirq-hrtimer/1`
chrt -f -p 52 `pgrep irq/23-uhci_hcd`
chrt -f -p 52 `pgrep irq/23-ehci_hcd`
chrt -f -p 52 `pgrep irq/16-uhci_hcd`
chrt -f -p 52 `pgrep irq/16-eth0`
chrt -f -p 47 `pgrep mpd`
chrt -f -p 48 `pgrep cifsd`

realtime_option {
    memlock              "yes"
    stack_reserve        "1024"
    heap_reserve         "10240"

    main_priority        "OTHER:0"
    player_priority      "FIFO:47"
    decoder_priority     "FIFO:48"
    update_priority      "OTHER:0"
}
audio_output {
        type            "alsa"
        name            "My ALSA Device"
        device          "hw:0,0"
        priority        "FIFO:49"
}
audio_buffer_size               "1024"
buffer_before_play              "25%"

ps -eLo pid,lwp,rtprio,priority,cmd は以下の通り。

  PID   LWP RTPRIO PRI CMD
    1     1      -  20 init [2]
    2     2      -  20 [kthreadd]
    3     3     99 -100 [migration/0]
    4     4     49 -50 [sirq-high/0]
    5     5     53 -54 [sirq-timer/0]
    6     6     49 -50 [sirq-net-tx/0]
    7     7     49 -50 [sirq-net-rx/0]
    8     8     49 -50 [sirq-block/0]
    9     9     49 -50 [sirq-block-iopo]
   10    10     49 -50 [sirq-tasklet/0]
   11    11     49 -50 [sirq-sched/0]
   12    12     49 -50 [sirq-hrtimer/0]
   13    13     49 -50 [sirq-rcu/0]
   14    14     99 -100 [posixcputmr/0]
   15    15      -  10 [desched/0]
以下、3-15と同じ内容で右端の数字が1-3に変わったものが続きます。
その後しばらくは関係ないプロセスなので省略。

 1231  1231     52 -53 [irq/23-ehci_hcd]
 1232  1232     50 -51 [irq/19-ata_piix]
 1239  1239     52 -53 [irq/23-uhci_hcd]
 1240  1240     50 -51 [irq/19-uhci_hcd]
 1241  1241     50 -51 [irq/18-uhci_hcd]
 1242  1242     52 -53 [irq/16-uhci_hcd]
 1928  1928     52 -53 [irq/16-eth0]

 1988  1988     48 -49 [cifsd]

 2545  2545      -  20 /usr/local/bin/mpd /etc/mpd.conf
 2545  2546     47 -48 /usr/local/bin/mpd /etc/mpd.conf
 2545  2548     48 -49 /usr/local/bin/mpd /etc/mpd.conf
 2545  2554     49 -50 /usr/local/bin/mpd /etc/mpd.conf

音楽ファイルは玄柴サーバ(Samba接続)に置いてあります。
この状態で top 画面は以下のような感じです。

Tasks: 128 total,   1 running, 127 sleeping,   0 stopped,   0 zombie
Cpu(s):  0.2%us,  0.2%sy,  0.0%ni, 99.6%id,  0.0%wa,  0.1%hi,  0.0%si,  0.0%st
Mem:   2065044k total,   398060k used,  1666984k free,     1744k buffers
Swap:        0k total,        0k used,        0k free,   306932k cached

  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
 1244 root     -53   0     0    0    0 S    1  0.0   0:08.67 irq/23-ehci_hcd
 1250 root     -53   0     0    0    0 S    0  0.0   0:00.64 irq/23-uhci_hcd
 1253 root     -53   0     0    0    0 S    0  0.0   0:01.28 irq/16-uhci_hcd
 1956 root     -53   0     0    0    0 S    0  0.0   0:01.92 irq/16-eth0    
 2016 root     -49   0     0    0    0 S    0  0.0   0:02.58 cifsd          
 2224 mpd      -48   0 62864  60m  18m S    0  3.0   0:06.39 mpd            
 2354 root      20   0  2452 1156  872 R    0  0.1   0:00.10 top            
    1 root      20   0  2020  704  612 S    0  0.0   0:00.83 init           
    2 root      20   0     0    0    0 S    0  0.0   0:00.00 kthreadd       
    3 root      RT   0     0    0    0 S    0  0.0   0:00.00 migration/0    
    4 root     -50   0     0    0    0 S    0  0.0   0:00.00 sirq-high/0    
    5 root     -54   0     0    0    0 S    0  0.0   0:00.29 sirq-timer/0   
    6 root     -50   0     0    0    0 S    0  0.0   0:00.00 sirq-net-tx/0  
    7 root     -50   0     0    0    0 S    0  0.0   0:00.21 sirq-net-rx/0  
    8 root     -50   0     0    0    0 S    0  0.0   0:00.04 sirq-block/0   
    9 root     -50   0     0    0    0 S    0  0.0   0:00.00 sirq-block-iopo
   10 root     -50   0     0    0    0 S    0  0.0   0:00.00 sirq-tasklet/0 
   11 root     -50   0     0    0    0 S    0  0.0   0:00.04 sirq-sched/0   
   12 root     -50   0     0    0    0 S    0  0.0   0:00.00 sirq-hrtimer/0 
   13 root     -50   0     0    0    0 S    0  0.0   0:00.21 sirq-rcu/0     
   14 root      RT   0     0    0    0 S    0  0.0   0:00.00 posixcputmr/0  
   15 root      10 -10     0    0    0 S    0  0.0   0:00.00 desched/0      
   16 root      RT   0     0    0    0 S    0  0.0   0:00.00 migration/1    
   17 root      RT   0     0    0    0 S    0  0.0   0:00.00 posixcputmr/1  
   18 root     -50   0     0    0    0 S    0  0.0   0:00.00 sirq-high/1    
   19 root     -54   0     0    0    0 S    0  0.0   0:00.16 sirq-timer/1   
   20 root     -50   0     0    0    0 S    0  0.0   0:00.00 sirq-net-tx/1  
   21 root     -50   0     0    0    0 S    0  0.0   0:00.14 sirq-net-rx/1  
   22 root     -50   0     0    0    0 S    0  0.0   0:00.07 sirq-block/1   
   23 root     -50   0     0    0    0 S    0  0.0   0:00.00 sirq-block-iopo
   24 root     -50   0     0    0    0 S    0  0.0   0:00.00 sirq-tasklet/1 
   25 root     -50   0     0    0    0 S    0  0.0   0:00.02 sirq-sched/1   
   26 root     -50   0     0    0    0 S    0  0.0   0:00.00 sirq-hrtimer/1 
   27 root     -50   0     0    0    0 S    0  0.0   0:00.13 sirq-rcu/1     
   28 root      10 -10     0    0    0 S    0  0.0   0:00.00 desched/1      
以降省略

cat /proc/interrupts は以下の通りです。
           CPU0       CPU1       CPU2       CPU3
  0:        138          0          0          0   IO-APIC-edge      timer
  1:          8          0          0          0   IO-APIC-edge      i8042
  9:          0          0          0          0   IO-APIC-fasteoi   acpi
 14:          0          0          0          0   IO-APIC-edge      ide0
 16:     333581          0          0          0   IO-APIC-fasteoi   uhci_hcd:usb5, eth0
 18:          0          0          0          0   IO-APIC-fasteoi   uhci_hcd:usb4
 19:       2252          0          0          0   IO-APIC-fasteoi   ata_piix, uhci_hcd:usb3
 23:     372612          0          0          0   IO-APIC-fasteoi   ehci_hcd:usb1, uhci_hcd:usb2
NMI:          0          0          0          0   Non-maskable interrupts
LOC:      77965      37081      18441     362632   Local timer interrupts
SPU:          0          0          0          0   Spurious interrupts
PMI:          0          0          0          0   Performance monitoring interrupts
PND:          0          0          0          0   Performance pending work
RES:       2648       3367       3434       4059   Rescheduling interrupts
CAL:       4041       4735       3224       2301   Function call interrupts
TLB:        189        162        432        302   TLB shootdowns
以降省略
割り込みの16番がLAN、23番がUSB音源ということです。

yanさんのドキュメントの表現で記述すると

player < decoder < sirq-**,irq-** = output < usbの割り込みハンドラー < sirq-timer

となります。
sirq-timer は Top で見てこちらが動いているようなので
この優先度を最高にしています。

yanさんのドキュメントを参考にしていろいろパラメータを変えてみたのですが、
明らかに問題があるという設定(「outputを左端に」、「decoderを右端に」など)
では音がやせて(デュアルコアのためか音切れまでは発生しません)、これはダメ
だなと分かりますが、それ以外の違いは微妙ですね。
outputの優先度を高くする(右にもってくる)と音はよりクリアになり、低くすると
雰囲気のある音になるような感じがします。
まあ、好みでいろいろやってみるという世界ですね。もう少し試してみようと
思っています。


長くなったので、ダウンロードと使い方は次の記事に。

(PC_Audio)   2011/04/20

コメントする

top page     previous page     next page

mail