FIFOアンダーフローが2秒に1度ぐらい起きてるんだ、と先日書いた.
これを回避する仕組みがUSBにある、ということが判ってきた.意外にめんどくさいやり方だ.
audio streamの転送モードについて先に述べる.
USBホストは1msとかの定期的にSOF packetというのをデバイスへ向けて送信する.データはSOF周期で送出される(SOF1周期をUSBフレームとも呼ぶらしい).SOF周期を44.1kHzにまでupしてやればFIFOアンダーフローを起こさずに済む.これをSynchronous転送モードと呼ぶのだそうだ.しかしこんなjitterありまくりな音なんか聞いたら耳血が出て死んじゃうよまったくもう.
Asynchronous転送モードはSOFと無関係にデータ送出されるらしい.44.1kHzはデバイスが持つ優秀なclockを使えるから良音が出る.なのだがFIFOアンダーフローが起きる可能性を払拭できない.
その問題を解決する仕組みが「feedback endpoint」というものである.
audio streamの行先がendpoint2番(OUT)だったとする.
それに対応するfeedback endpoint(IN)を8番だとする.
2番と8番はdecriptorに関係ありと記述しておく.
8番は何をするのかというと、streamが多過ぎか少なすぎかをホストに知らせるのである.
例えばFs=44.1kHzだとする.SOF周期が1msだとする.8番は1msに44.1kHzが何発入っているかを実測してホストに逐次知らせるのである.逐次というのは4ms毎とかそんなだ.概算で44.1発になるであろうが、有効数字3桁程度では不足で、有効数字10桁ぐらいの精度で計るのだそうだ.つまり、44.1309384761発みたいなイメージ.
44.1309384761発を受領したホストPCは、平均転送データ量をチビチビと上げ下げすることでFIFOアンダーフローもFIFOオーバーフローも防ぐ.
はぁ~、たかがオーディオでかったるいことをやってるもんだね.UACではなくてUSB標準仕様に書かれていることなので本家本元のissueなのでしょう.
(USB Specification Revision 2.0 → 5.12.4.2 Feedback を参照)
ひら的にはこう予想してたんだよ.
「ホストPCが多めに送ろうとするけれどデバイスが時々待ったをかける」
これなら簡単なのにな.でもこれだと何か問題があったのでしょう.
どうやって実装するんだかねぇ?
SOF割り込みは必須だろう.
EZ-USBのTimerをSOF割り込みでON/OFFし、Fsの発数を計る.
そんなのを考えているのだけれどうまくいくのかしら?
かしこ
→INDEXページへ
0 件のコメント:
コメントを投稿