先のエントリで、最近のLinuxではレイテンシは数msecらしいと書きましたが、その元情報は、ネットで見つけた "Realtime Audio vs. Linux 2.6"という論文です。
これは、昨年4月に開かれたLAC(Linux Audio Conference)2006という会議でLee Revellという人が発表したもので、2.6カーネルでのレイテンシの改善に向けた開発がどのように行われてきたかという内容になっています。オーディオコミュニティとカーネル開発者との協力によって、論文発表時点での最新カーネル(2.6.17-rc2)では、worst caseで1-2msec程度にレイテンシを抑えることが出来ているとのことです。また、さらに低レイテンシを実現するためのrealtimeパッチも開発されていて、これを用いると50μsec近くまで縮めることができると述べられています。
他にも実測データなどを含め、ネット上で多くの情報が見つかりますが、まだよく飲み込めていません。
一方、dttsp-linuxというメーリングリストで、Ubuntuには2.6.xx-lowlantencyというカーネルのパッケージがあって、なかなかいいよ、という投稿がありました。ちなみにdttspというのは、PowerSDRの信号処理のコアとなっているライブラリで、dttsp-linux MLでは、それに関する話題の他にも色々面白い議論や情報も出ますので、SDRのソフトウェアに興味のある方は是非参加されると良いと思います。
さっそく私もそのパッケージをインストールしてみました。インストールは普通にアップデートマネージャから出来ますし、デフォルトのカーネルとどちらでもブートできるようになるので特にリスクもありません。
MLの投稿ではjackdをsampling rate = 48kHz, frames/period = 64, periods/buffer = 2で起動して、ほぼ取りこぼしがなかったと報告されていました。このバッファリングによるレイテンシは、2.67msecということになります。
私も同じようにjackdを起動し、dttsp(sdr-core)を動かそうとしたのですが、まともに動作させることができていません。jackd自体はbuffer overrunしていないようなのですが、dttspの方とのやりとりで取りこぼしているような感じです。結局いまのところ通常のカーネルのときと同じようにframes/period = 2048で動作させています。
ところで、デフォルトカーネルとlowlatencyカーネルとconfigの何が違うのかをざっと見たのですが、カーネルプリエンプションの設定が違うようです。
Ubuntuデフォルトのカーネルでは、
CONFIG_PREEMPT_VOLUNTARY=y
であるのに対して、
lowlantencyカーネルでは、
CONFIG_PREEMPT_VOLUNTARY=n
CONFIG_PREEMPT=y
CONFIG_PREEMPT_BKL=y
となっています。どういう違いがあるのかを簡単に説明する能力は無いのですが、lowlatencyカーネルの方が、カーネルモードでのプリエンプション(タスク切り替え)がより細かい粒度で行われるので、低いレイテンシが期待できるということのようです。
また、OSADLのページ によると、realtimeパッチを当てたカーネルに関しても最近ではパッケージが提供されているようです。
これは、昨年4月に開かれたLAC(Linux Audio Conference)2006という会議でLee Revellという人が発表したもので、2.6カーネルでのレイテンシの改善に向けた開発がどのように行われてきたかという内容になっています。オーディオコミュニティとカーネル開発者との協力によって、論文発表時点での最新カーネル(2.6.17-rc2)では、worst caseで1-2msec程度にレイテンシを抑えることが出来ているとのことです。また、さらに低レイテンシを実現するためのrealtimeパッチも開発されていて、これを用いると50μsec近くまで縮めることができると述べられています。
他にも実測データなどを含め、ネット上で多くの情報が見つかりますが、まだよく飲み込めていません。
一方、dttsp-linuxというメーリングリストで、Ubuntuには2.6.xx-lowlantencyというカーネルのパッケージがあって、なかなかいいよ、という投稿がありました。ちなみにdttspというのは、PowerSDRの信号処理のコアとなっているライブラリで、dttsp-linux MLでは、それに関する話題の他にも色々面白い議論や情報も出ますので、SDRのソフトウェアに興味のある方は是非参加されると良いと思います。
さっそく私もそのパッケージをインストールしてみました。インストールは普通にアップデートマネージャから出来ますし、デフォルトのカーネルとどちらでもブートできるようになるので特にリスクもありません。
MLの投稿ではjackdをsampling rate = 48kHz, frames/period = 64, periods/buffer = 2で起動して、ほぼ取りこぼしがなかったと報告されていました。このバッファリングによるレイテンシは、2.67msecということになります。
私も同じようにjackdを起動し、dttsp(sdr-core)を動かそうとしたのですが、まともに動作させることができていません。jackd自体はbuffer overrunしていないようなのですが、dttspの方とのやりとりで取りこぼしているような感じです。結局いまのところ通常のカーネルのときと同じようにframes/period = 2048で動作させています。
ところで、デフォルトカーネルとlowlatencyカーネルとconfigの何が違うのかをざっと見たのですが、カーネルプリエンプションの設定が違うようです。
Ubuntuデフォルトのカーネルでは、
CONFIG_PREEMPT_VOLUNTARY=y
であるのに対して、
lowlantencyカーネルでは、
CONFIG_PREEMPT_VOLUNTARY=n
CONFIG_PREEMPT=y
CONFIG_PREEMPT_BKL=y
となっています。どういう違いがあるのかを簡単に説明する能力は無いのですが、lowlatencyカーネルの方が、カーネルモードでのプリエンプション(タスク切り替え)がより細かい粒度で行われるので、低いレイテンシが期待できるということのようです。
また、OSADLのページ によると、realtimeパッチを当てたカーネルに関しても最近ではパッケージが提供されているようです。
DMAのプリフェッチですが、TXとRXを同じ割り込みハンドラで処理しようとすると、時間的なずれが大きすぎてわけがわからなくなると言う問題です。解決策としては、RX-TX間に適切な長さのバッファを入れるか、プリフェッチ量より十分長いバッファを入れる、あるいはトリプルバッファにすると言う手があります。
いずれも遅延が増えますが、数百uS程度です。
PCでは前にも書いたように128サンプルくらいでやっています。これだけの遅延で済めば実用上十分な感じです。アナログの狭帯域クリスタルフィルタなんかでも数msecの遅延はあるそうですし。ただ、LPFもそうですし、他の処理を色々入れようとすると全体的に遅延が無視できなくなりますね。
コメントに気づかず、申し訳ありません。最近アクティビティが無く、自分のブログすら見ていませんでした。K2はその後どうされていますか? 私も欲しいのですが、結構高いですし組み立てる気力も今はちょっと無いかな。誰か組み立ててくれませんかね Hi。
おっしゃるようにLPFの遅延のほうが大きいので、2mSくらいの遅延は問題ないと思っています。