ラズパイI2S出力のクロックタイミングを弄ってみよう

shapeimage_1-41

Raspberry pi3でミュージックプレーヤー2

ラズベリーパイが出力するI2Sのクロックに含まれる時間軸の揺らぎ(ジッター)はとても小さい(実はXMOSのそれより小さかったりする)ことが、理屈的にも先進層による実測でも明らかになっています。

あわせて、小さいながらも周期的な揺らぎが含まれていることも知られています。

周期的な揺らぎが含まれる原因はOSのサウンドドライバーにあるD-PLL(デジタルPLL)による補正ロジックです。
ラズパイのサウンドドライバーが使うシステムクロックは500MHzです。
必要な周波数はこれを分周して得るので、整数分の1の周波数しか出力できません。
これでは再生するPCMデータのサンプリング周波数にぴったり合わずピッチと時間がズレてしまうので、補正ロジックがピッチと時間を維持するために「時々クロックタイミングをズラして」おり、このタイミングのズレがジッターとして現れます。

ラズパイの揺らぎがXMOSより小さいのは、XMOSが400MHzクロック動作でタイミングの最小調整幅が2.5nsec(10億分の2.5秒)なのに対し、ラズパイが500MHz動作で最小調整幅が2nsec(10億分の2秒)になるためで、実測された方の結果ともよく符合しています。

そして、この揺らぎの存在とその発生原因を見つけた方が、ラズパイのクロック出力の時間揺らぎを止める方法(補正を止める方法)と、その機能を含むカーネルとMPDのセットでバイナリを公開されています。

ただしこの方法には大きな副作用があります。
ここまでの記述でお分かり頂けると思いますが、クロックタイミングの揺らぎ止めるということは、揺らぎを起こさない代わりにピッチ(音程)と時間の正確性を捨てることになります。
(逆に言うと、ラズパイのD-PLLロジックはクロックタイミングの等間隔性を捨ててピッチと時間を正確に保っているともいえます。)

加えて、公開されているバイナリはラズパイ3では動かないVolumio1.55ベースです。
LightMPDも同じ機能が入ったカーネルが公開されていますが、最新版(1.0.2)にはうまく組み込めない様です。
(ここでもラズパイ3にした影響が。。。)

とは言え、ここまで来て引き下がりたくありません。
やり方は公開されているので、ソースを弄ってカーネルの再構築にチャレンジです。
(Linuxのブログじゃないので説明はざっくりいきます。)

Linuxカーネルの構築(コンパイル)は、実機でセルフコンパイルするか別のマシンでクロスコンパイルするかどちらかですが、ラズパイ3でCPUパワーが上がったと言えどもデスクトップマシンから見ればまだまだ非力ですので、iMacのParallels(仮想マシン)でUbuntuLinuxを動かしてクロスコンパイル環境を作りましょう。

開発環境、ラズパイ用のソースなどをネットから持ってきて展開、ソースを書き換え、動作中のVolumio2のカーネルコンフィグを抜き、これを引きつぎ、新規項目はデフォルトとしておき、割り込みタイミングなどいくつかの既存項目を調整します。

そしてコンパイル実行。
出来上がったカーネルとモジュールをVolumio2のSDカードにコピーしていざ起動!

しません。。。。(苦笑

コンパイルは通ってるのに起動しません。

いろいろやってもVolumio2 RC1ではうまくいきません。

ラズパイにモニターもキーボードもつながずやってるので、起動してネットワーク接続可能になるまで何が起きてるかわからんっていうのはカーネル弄る時にやることじゃないですね。(言い訳モード)

仕方がないので、LightMPDのカーネルコンフィグを使ってコンパイルし直してみたら、こちらはあっけなく成功。

動作確認はクロックタイミングのズレを観測するのが一番ですが、我が家のオシロスコープでは性能不足で観測不能です。
ではどうするかというと、改造カーネルのLightMPDで1kHzのテストトーンを再生してiPhoneの楽器チューニング用のAPPで拾って周波数を表示させ、想定通りにピッチ(再生周波数)が変化しているかを確認します。

44.1kHzサンプリングで1001Hz
img_4321

48kHzサンプリングで1005Hz
img_4323

192kHzサンプリングで1018Hz
img_4325

と表示されますので、どうやら動作しているようです。

さて、サウンドはどうでしょうか。
ES9023は非同期のMCKで動作し、ASRC、ジッタークリーニング機能を持っていますが、どの程度のジッターをどの程度抑圧するのかは公開されていません。
また、私自身ジッタークリーニング機能がサウンドに与える影響についての知見がありませんので、変化を感じなければES9023のジッタークリーニング機能の勝ち、変化を感じればD-PLL補正機能停止の効果ありということで、気楽に確認してみましょう。

サーバーのiTunesに取り込んだCD(44.1kHz/16bit)のロスレス圧縮(ALAC)ファイルをLightMPD1.0.2の通常版と改造カーネル版で比較してみましたところ。。。

なんでしょこれ。
どう表現すればよいモノか。
静かで滑らかでしなやかで力強くてガッツがあって。。
なんだかアナログを聞いてるみたいな感覚になります。
これは凄い。

ラズパイのクロックタイミングの揺れ排除はとても効果が大きい(当社比)です。

私の場合、絶対音感を持っていませんので44.1kHz〜176.4kHzサンプリングならピッチのズレは気になりませんでした。
特に44.1kHzは0.09%のズレ(20分で1秒進む程度)で、音を重ねてやっとわかる程度。
48k、96kは0.47%、88.2k、176.4kは0.66%で、ピッチが上がるというよりテンポが少し上がったかも?という感じです。
192kだと1.7%ズレになり、さすがにピッチもテンポもなんか違う感じになります。

もっとも、私のiTunesライブラリはほとんどがCD取り込みの44.1kHzサンプリングで、高くても96kHzサンプリングのデータしかありませんので問題ありませんね。。(苦笑)

なお、今回「D-PLLによる補正機能を停止」して効果を得ていますが、これをもってPLLやD-PLL全体を悪者扱いしてはいけません。
DACチップの技術資料などにも、PLLを使わずジッターが少ない特性の良いクロックを使いましょう。的な記述があったりするので、PLLは悪の根源と思われている方もいるようですが、Silicon LaboratoriesのSi5317など、数100fsec(10兆分の数秒)オーダーのジッター性能を持つ高性能なPLLもあります。
ジッタークリーナーも高性能なPLLがなければ実現しません。
PLLもNFBも適材適所な使い方があります。
 
 
冒頭の写真は、電源周りの各電圧ライン(1.2V、1.8V、3.3V、5V)にデカップリングコンデンサとしてESRの低い高分子コンデンサを追加して実験中の図です。