Oct 31, 2023

アップサンプリングの設定を変えてmpdサーバーの負荷を減らしてみる

現在のうちの環境では、Daphileでmpdサーバーに送るDeezerの音は、同じCD水準のデータでもNAS音源の音には及ばない。

前回のエントリーで、ストリーミング音源はupmpdcliがボトルネックになっていると考えたら、mpdサーバーへの対策が有効ではないか、銅メッシュをmpdサーバーのノイズ対策に使えば負荷が減るのではないか、と考えた。
ここでふと、mpdの負荷を減らしたいなら、アップサンプリングしなければいいんじゃないか、と思い付いた。

Daphileからmpdに送られるのは44.1kHz/16bitのPCMだ。それを何もせずPPAPで送れば、どう聴こえるだろう。
mpdサーバーの負担は減ると思う。
過去に試したときは、アップサンプリングした方が良かった。
今はどうだろう、ストリーミング、いや、UPnP音源だったら、どうなのか。

もともと、僕がアップサンプリングを使うようになったのは、コンピューターをオーディオに使い始めた頃に、SRC2496という機器を使ってアップコンバートして鳴らしていたことがある。これは音が良くなった。あと、壊れかけたNASの音源は、mpdによる非力なアップサンプリングでも音が良くなった。

こうしたことから、ジッターが多い環境では、アップサンプリングしたほうが音が良いのではないか、という仮説を思い付いた。なんでアップサンプリングで音が良くなるんだろう、というところから考え始めている。
つまり、そうした現実の理由付けとして考え始めた仮説だ。

そのうち、アップサンプリングと一言で言ってもいろんな手法があり、音も違うことが分かった。
手法で音が違うということは、DACに入力されるデータが異なっているということだ。
そして、DACチップ内でアップサンプリングするという知識も得る。

アップサンプリングによる音質改善の根拠は、DACチップ自体でアップサンプリング(オーバーサンプリング)するより、良質なアップサンプリングが出来る高スペックのPC等で代行したほうが良いという説明に、比重が移った。
というか、世の中でそういう説明が見られるようになった。
SRC(libsamplerate)などを使って良質なアップサンプリングを行うと音が良くなるのはなぜなのか、という問いの答えが、DACチップはナイキスト定理通りの理想的なDA変換が出来ないのでオーバーサンプリングして精度を高めるより他なく、DACへのデジタル入力前に、より良質なアップサンプリングを行うことが可能なら、そのほうがDA変換の精度が上がるから、ということに現在はなっている。
というのが僕の理解。

音の情報量自体はCDで充分だが、DA再生で充分な精度を出すには技術的限界があるから、理論だけで固めた理想論では済まない。だから高品質なアルゴリズムでアップサンプリングすることが有効ということだ。
精度が要らないなら、この限りではない。精度が出てなくても良い音はざらにある。精度が出ていさえすれば良いというものでもない。

そういうわけでアップサンプリングの品質は重要だと思うけど、ジッターを如何にして減らすかも同時に重要だ。
以前は、アップサンプリングすることでジッターの影響を少なく出来るのではと考えていたけど、今はそれだけで事足りるとは考えない。
ジッター対策は音色に効いてくる気がする。
というか、映画に例えてみると、サンプリング周波数やビット深度がフィルムの大きさ、つまり情報量に影響し、ジッター対策はピントに効いてくるとでもいうか、出てくる音の鮮度、色彩感、陰影に影響する。
両方を高めるのが、今のデジタルオーディオで高音質を得る近道だと思う。

正攻法は、安定して高精度なクロックだ。
しかしクロックを生かすには、ノイズや電源の対策が必須になる。ノイズや電源の上でクロック素子が動いているからだ。当然、デジタル信号そのものも、それらの上で動いている。デジタルで01だと言っても実体は電圧変動なのだから、ノイズや電源の影響を受けないわけがない。その影響こそがジッターということだ。

話が広がりすぎか。話を戻す。
何が言いたいのかというと、アップサンプリングを止めることで、音質は低下する。
しかしmpdサーバーの負担、仕事量が減るので、ジッターの減少、音質の向上に繋がるのではないか、ということ。

逆も言えることで、アップサンプリングを行えば音質は向上する。
しかしmpdサーバーの負担、仕事量が増えるので、ジッターの増加、音質の低下に繋がる。

では、どうすれば一番良い音になるのか、良好なバランスとなるのはどんな設定なのか、という考え方だ。
実際に聴いてみて、確かめるしか術はない。

さて。
うちでは2台のmpdサーバーが動いていて、1台はメイン使用で384kHzへのアップサンプリング用、もう1台はテスト用兼768kHzへのアップサンプリング用になっている。なんでわざわざ2台なのかというと、そのほうが設定切り替えの手間がないからだ。
PPAP Back-Endで両方の設定に対応するコマンドが動いていて、どちらのFrontからでも直ぐに音を出すことが出来る。
Back-Endでtopを打つとこんな感じ。

Mem: 93208K used, 3936688K free, 18376K shrd, 5560K buff, 34180K cached
CPU:  0.0% usr  0.0% sys  0.0% nic 99.9% idle  0.0% io  0.0% irq  0.0% sirq
Load average: 0.00 0.00 0.00 2/109 1319
  PID  PPID USER 	STAT   VSZ %VSZ CPU %CPU COMMAND
 1318  1290 tc   	R 	4016  0.1   0  0.0 top
 1208  1092 root 	S	15484  0.3   0  0.0 /usr/local/bin/ncat -kl 4400 -e /usr/local/bin/aplay -D hw:0,0 -M --period-size=2048 --buffer-size=16384 -t raw -f S32_LE -r384000 -c2
 1242 	1 tc   	S	15484  0.3   1  0.0 /usr/local/bin/ncat -kl 4444 -e /usr/local/bin/aplay -D hw:0,0 -M --period-size=4096 --buffer-size=32768 -t raw -f S32_LE -r768000 -c2
 1286  1202 root 	S 	5872  0.1   0  0.0 sshd: tc [priv]

まず、テスト用サーバーの設定をいじって、アップサンプリング無しの音を出すことにした。
mpdサーバー(Front)をアップサンプリングしない設定に変更。
Back-Endでは、上記のtop表示だったら「kill 1242」で、テスト用のデータを受信するコマンドを止める。
改めて以下、コマンドを打つ。

/usr/local/bin/ncat -kl 4444 -e "/usr/local/bin/aplay -D plughw:0,0 -M --period-size=64 --buffer-size=512 -t raw -f cd" &
うまくいかない。
音が出るまで時間が掛かり、音が出始めた後のコントロール、音量の調整や再生停止などの操作にすごく時間がかかる。数十秒もかかる。768kHzのデータの方が重そうなのに何でなのか、考えるうちに、もしかしたら、バッファーの設定が影響しているのではと思い付いた。

メインサーバーからのデータを受けるコマンドはrootで起動。テスト用サーバーからのはtc(ログインユーザー)で起動している。
コマンドは2つだが、aplay自体は、もともとひとつだ。

音源がCD同等だと、バッファーの数値はずっと小さくなる。音源データが小さいのでコマンドの設定もそれに合わせている。
しかしメイン用の方はもともと、大きい数値がバッファーに振られている。
多分、テスト用からの音源を鳴らしている時も、メイン用のコマンドが同時に動いているから、バッファーの設定がそっちのまま、大きいままなのではないか。
CD相等の音源にとって、それは過剰なバッファーとなる。
結果、操作に対する反応が遅くなる。mpdサーバーの出音を止めても、バッファーに溜まったデータが切れるまで、暫く音が出続けるのだろう。それが20秒前後にもなる。

どうするか。
そもそもの目的、サーバーの負荷を落とすということなら、アップサンプリングの「質」の設定を落とせばいいという考えもある。
テストサーバーのlibsamplerateの設定は「Medium」なので「Fastest」にしたら負荷は下がる。
そしてメインの384kHzに近い値で低めに設定したら、バッファー数値の影響は回避できないだろうか。
ままよ、やってみた。

/usr/local/bin/ncat -kl 4444 -e "/usr/local/bin/aplay -D hw:0,0 -M --period-size=1024 --buffer-size=8192 -t raw -f S32_LE -r192000 -c2" &

これだと反応の遅れは数秒で、使用に耐える。
音色は良い。
768kHzよりも艶っぽい気がする。
しかし情報量は少なくなる。音像間で分離していた空間が、グラデーションで埋まる。まあ、768kHzと192kHzでは、デジタルデータの情報量は4倍の差があるので、仕方がない。768kHzは良くも悪くもモニター的になる。これは、どちらがいいのかという話になりそう。
テスト用といいながら僕が768kHzで鳴らす環境を維持しているのは、これはこれで捨てがたい面があるからだ。

しかし192kHzだと、USB-HDD音源とストリーミング音源の音の差は、かなり縮まったような気がする。
いや、ほんまかいな、と自分でも思うけど、たぶん縮まってるんじゃないかな(でも、こういうときの自分ってあてにならないんだよな、、)。
Fastest、192kHzの設定だけで比較したら、もうストリーミング中心でいいかもと思うかもしれない。

Back-Endで、メイン用の設定のほうを見直すという方法論もある。
大きいバッファーを小さく出来たら、テスト系への影響を小さく出来るのではないか。

そもそもなぜ、「--period-size=2048 --buffer-size=16384」という設定になっているのか、記憶にない。
たぶん、アップサンプリングするmpdサーバーの増大したバッファーの設定に、合わせて増やしただけだと思うのだ。
減らせるかもしれない。
とりあえず、「--period-size=512 --buffer-size=2048」まで減らした。
問題なく音は出ている。あらー、、、

この状態で、テスト系のアップサンプリングをやめて、まともに使えるかどうか、試してみる。
音の出方は、以前よりは良くなった。
しかし、不安定だ。途切れやすい。
mpdサーバーの方を調整。「audio_buffer_size」を増量、"2048"に。多少は安定したが、再生停止に10秒程かかる。
なんでかわからんが、mpdが音源データをどんどん先走って取り込んでいるようなのだ。Daphileなどのインターフェイスで見ると、曲の時間表示が実際よりもどんどん先に進んでいく。
これでは困る。

結局、多少はアップサンプリングしないと安定しないという、よくわからない状態で、今回はけりをつけることにした。
libsamplerateは「Fastest」、負荷軽減優先だ。
サンプリング周波数は、とりあえず192kHz。
テスト系を受けるBack-Endの設定は「--period-size=256 --buffer-size=2048」に、今はしている。
なんだか、あちこちバランス取りながらの設定で、詰めきれないままのことが今までにもよくあったような気がする。

気のせいかもしれないけど、Fastest、192kHzは、昔よりも良い音が出ている気がする。
ノイズ対策などを経て、ジッターが減っている分、改善があるのかもしれない。
USB-HDD音源とストリーミング音源の音の差も、Fastest、192kHzだったら前述したとおり、差異が少ない。なんとなく、バランスがいい音という印象で安心感がある気がする。

もともと、差異が少なければいいというものではない。
ストリーミングの音を底上げするにはどうしたらいいか、というところから始まった話だ。
しかしここに来て、設定による音の違いは無視できないような気がしている。ノイズ対策が落ち着いたら、どのような設定でどのような音になるのか、ゆっくり時間がある時に、確認したいと思うが、設定の要素が多いので、比較すると言っても単純な話ではない。
大仕事になる。あんまり突っ込んだことはしないかもしれない。

最後にちょっと、温度の比較(CPUだと思うんだけど、はっきりしない)。
テスト用サーバーでコマンドを打って確認してみた。

tc@box:~$ cat /sys/class/thermal/thermal_zone0/temp
44000

こんな感じ。
ただ、今回確認してみて、音を出している時の温度は、かなり変動することが分かった。負荷が多いときは上がるのだろう。

データ取得のために下記コマンドを使用。
5分間のデータを取得する。

tc@box:~$ watch -t -n 3 cat /sys/class/thermal/thermal_zone0/temp > temp.txt

数値だけ得られるならよかったんだけど、行頭に余計な文字列が付くのが残念。
このファイルを、普段使いのノートPCに移して、エディタで要らない文字列を削除して、下記のコマンドで数値を合計して、電卓で平均を計算する(小数点以下は四捨五入した)。
せっかくLinux使ってるんだから、もう少しスマートにやれそうだけど、スキルがない。

[ab@fedora1 Documents]$ awk '{sum+=$1}END{print sum}' temp.txt
44000

Fastest、192kHz
47267 (min:47000 max:48000)

Fastest、768kHz
53019 (min:47000 max:58000)

Medium、768kHz
59670 (min:51000 max:65000)

一番上は音を出していないとき、続いて、それぞれの設定で音を出したときの温度だ。
アップサンプリングの設定、負荷の違いで大きく温度が違うのが分かる。
驚いたのは、音を出していないときの温度は、ずっと44000で5分間一定だったこと。そういうものなんだろうか。あと、負荷が少ないと温度の変動も小さい。

メイン用サーバーは、Best、384kHzの設定で固定している。こっちも少し測ってみた。
データは載せないが、テスト用よりも若干温度が高いようだ。

早々に追記だけど、テスト用サーバー下記設定でデータを取ってみた。
アップサンプリングの周波数が低いと、温度の変動が少ないのかな。負荷の大きさとの関連は小さいのか。どうなんだろう。

Best、192kHz
58452 (min:57000 max:62000)
Edit this entry...

wikieditish message: Ready to edit this entry.
















A quick preview will be rendered here when you click "Preview" button.