JI3GAB/blog

ラジオに関する話題を中心につらつらと

Linuxカーネルのレイテンシ

2007-05-18 01:21:50 | サウンドカード/ドライバ
先のエントリで、最近の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パッチを当てたカーネルに関しても最近ではパッケージが提供されているようです。
コメント (3)
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

PCオーディオのレイテンシとソフトウェアラジオ

2007-05-17 01:14:58 | サウンドカード/ドライバ
PCのサウンドカードと汎用OS(WindowsやLinux)の上で信号処理を行うSDRでは、実際に使用していると遅延(レイテンシ)が気になります。そういう議論の中で、suikanさんはx86プラットフォームでリアルタイムOSを走らせるという検討をされているようです。正直に言って私にはその内容は興味がありますが、すぐに理解できるようなものではありません。

そこで、というわけでもないのですが、汎用OS(WinXPとLinuxのみ)でどのくらいまでレイテンシを下げることができるのかということを調べてみようかなと思っています。
ちょっとまだ色々理解できていないこともありますし、自分で実際に測定してみたいとも思っているのですが、WindowsのASIOや最近のLinux(alsa)では、だいたい数msecというオーダーのレイテンシで納まるようです。MMEやずっと以前のLinuxでは数10~100msec程度の遅れがあったことを思えば非常に良い値です。

WinXPでDELTA44のDMAバッファサイズを128 samplesに下げて、自作のSSB変調プログラム(サンプリングレートは48kHz、ASIO使用)を動かしていますが、通常使用している範囲では特に音が途切れたりすることはないようです。バッファサイズだけで考えると、レイテンシは128 / 48kHz = 2.67msecとなります。Linuxでも同様のバッファサイズで問題なく動作しています。実際モニターしてみても、この程度ならほとんど問題ないと言ってもいいのかなという感じがします。

が、しかし、これまではあくまでOSのサウンドシステムのレイテンシの話です。現在使用している自作の変調プログラムでは、FIRフィルタを使用しており、その形状というかシャープさを変化させることができます。そして、シャープなフィルタを実現しようとすればそれだけFIRフィルタのタップ数が多くなり、そこでの遅延が大きくなります。実際モニターしているのが段々不自然になってくるのがわかります。
設定できるパラメータは、「帯域外減衰量」と「cut off周波数から設定した減衰量に落ちるまでの幅(transition BW)」の二つです。一番初期の頃は減衰量を60dB、trans. BWを500Hzと甘く設定していました。このときタップ数は88で、ここで生じる遅延は、88 / 2 / 12kHz = 3.67msecとなります(FIRフィルタはサンプリングレート12kHzの処理)。
その後、より低音まで出したときに逆サイドへの漏れを少なくするためにパラメータを自由に変えられるようにしたのですが、パラメータを変えたときにタップ数がどう変化するかの例を以下に示します。

FIR フィルタ (Kaiser窓)
12kHz sampling

tr_bw	attn	n_taps
-----------------------
500Hz	60dB	88
300Hz	80dB	202
200Hz	60dB	218
200Hz	80dB	302
100Hz	60dB	436
100Hz	80dB	604
 40Hz	60dB	1088
 40Hz	80dB	1506


100Hzまで低域を伸ばして、サイドバンドを含めた不要な信号を-60dB程度に抑えたいとなるとフィルタによる遅延は、436 / 2 / 12kHz = 18.17msec、さらに40Hzまで伸ばしておまけに減衰も目一杯と考えると、1506 / 2 / 12kHz = 62.75msecとなります。これではプラットフォームのレイテンシが下がってきても、処理全体としての遅延はかなり気になってしまいます。

うーん、やはり単純な実装ではこんなものなんでしょうか。FIRフィルタには線形位相であるとか安定であるとか、いい性質がありますが、たとえば昔のKenwoodのDSP機はIIRフィルタを使って90度位相差を作っていました。今の機械はどういう処理になっているのでしょうかね。群遅延をうるさく言わなければ、IIRでLPF作ってWeaverの方がいいとか?

と、ここまで書いて、以前他の方から実測していただいた遅延のデータを見返したら、40Hz/80dBの設定で36msecとなっていました。何か考え違いをしてるのかな、私は。
コメント
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

portaudio再び(その2)

2007-05-13 23:22:50 | サウンドカード/ドライバ
suikanさんからレイテンシに関してトラバを頂いていますが、それついてはまたあらためて書くとして、とりあえずコンパイル時に問題になった点をもう少し詳しく書いておきます。あまりまとまりはないですが、メモということで(このエントリを編集中に一度消えてしまった(泣))。

・環境はWinXP上でMinGW+MSYS。ソースはpa_stable_v19_061121.tgz。

・コンパイルのやり方は普通にconfigureしてmake。対応したいドライバのAPI(hostapi)ごとに
configureスクリプトに必要なオプションを与える。

・Makefile中で、*-recursiveのように、サブディレクトリに対して処理を行おうとするところがあるが、SUBDIRSが空(実際サブディレクトリはあるが、Makefileはトップにしか無い)なので失敗する。とりあえず外しておく。

・wmmeに関してはほとんど問題なし。

- ./configure --with-winapi でOK。

・asio

- asio対応のコンパイルを行うためには、まずasiosdkをSteinberg社から入手する必要がある(asiosdkは再配布は許可されていないはず)。これを適当なディレクトリに展開する。その上で、たとえば

./configure --with-winapi --with-asiodir=/c/asiosdk2.1

とする。しかし、元のままではコンパイルは通らない。portaudioのasio関係のソースのパスが以前と変わっているのにMakefileでは昔のままだからである。

pa_asio/ --> src/hostapi/asio/ と変更する。

- asioコンパイル時のみC++のソースをコンパイルすることになるので、Makefile中でもそれなりの対応が必要になる。ライブラリ作成時にもg++を使用するように変更。

- tests/pa_devsコマンドを作成するときに、'PaAsio_'ではじまる関数が見つからないと怒られる。portaudioライブラリ作成時にPaAsio_*もexportするように変更。

・DirectSound

- MicrosoftからDirectX SDKを入手して設定しておく。最新版を使えば良いのだろうが、私の環境ではうまく行かず、以前実績のある2004年10月版を使っている。展開したディレクトリをconfigureスクリプト実行時に指定する。たとえば

./configure --with-winapi=directx --with-dxdir=/c/dx9sdk

- 'src/hostapi/dsound/pa_win_ds_dynlink.h'でインクルードしている

'DSound.h'を小文字の'dsound.h'に変更。

・wdmks

- 同じくDirectX SDKが必要。

./configure --with-winapi=wdmks --with-dxdir=/c/dx9sdk

- pa_win_hostapis.cの中の、PaUtilHostApiInitializerの配列の中で、

#ifndef PA_NO_WDMKS
       PaWinWdm_Initialize,
#endif


がコメントアウトされているので、外す。

以上。

まだ細かいことはありますが、だいたいこんなところでコンパイルは通るようになります。また、wdmks以外はテストプログラムを実行するとそれなりに動作しているようです。
wdmksはbin/pa_devsコマンドでデバイスのリストは出ますが、音の入出力はまるでダメです。

ここまでの変更を施したものを、こちらに置いておきますので、興味のある方は試してみてください。お約束ですがat your own riskでお願いします。また、もっといい対処法などがありましたら是非教えてください。
変更したのはconfigure.in, Makefile.in, 'src/hostapi/dsound/pa_win_ds_dynlink.h', 'src/os/win/pa_win_hostapis.c'のみです。

しかし、poraudioのWikiやMLのアーカイブをざっと見たのですが、configureスクリプトの問題やwdmksが動かないという話題は見つけられませんでした。何か間違ってるのかなあ。一度MLで質問してみようかと思っています。

それから、今のconfigureスクリプトでは、一つのhostapi(ASIOならASIOだけ)しかコンパイルされませんが、すべてに対応したライブラリをコンパイルすることは出来るはずです。実際以前のバージョンでは出来ていましたから。
コメント
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

portaudio再び(その1?)

2007-05-02 02:15:57 | サウンドカード/ドライバ
昨年暮れに、portaudioでWDM kernel streamingを使いたいと思って、そのときの(今も)最新の安定版であるpa_stable_v19_061121というバージョンをmingw環境でコンパイルしようとしたのですが、WDMどころか他のドライバ用もソースもコンパイルできないような状態でした。今回休みということもあって再度トライしようとしています。
いくつか問題はあるのですが、基本的にはconfigureスクリプトで出来るMakefileが不完全のようです。そこは大体解決できて、WMME、ASIOの動作は確認しましたが、WDMについては、やはりうまく動作しません。どなたかWDMKSでうまく動いている方がいらっしゃったら教えていただけないでしょうか。
Makefileの変更等については、のちほどまとめて報告したいと思います。また、最新のsnapshotも試してみようかと考えています。
コメント
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする