Select Your Language

免責事項

  • 本サイトの情報の利用、内容、サービスによって、利用者にいかなる損害、被害が生じても、著者は一切の責任を負いません。ユーザーご自身の責任においてご利用いただきますようお願いいたします。

    本サイトで頒布している基板およびキットは、技術者、またはそれに準ずる電気的知識をお持ちの電子工作ファンの方のためのものです。一般のオーディオファンの方のためのものではありません。
    また、頒布基板およびキットは、いかなる条件でも動作を保証するものではございませんので、あらかじめご了承ください。

    電子工作では、火傷、感電、火災などの可能性があります。十分に注意をして作業して下さい。

    営利目的のご使用は認めておりません。 記事の転載や、基板・キットの商用利用の方は、ご連絡ください。学生やサークルの学習目的でまとめてご購入する場合は特別価格でご提供させていただきます。
無料ブログはココログ

スポンサー

« チップトランジスタのhfet測定ツール | トップページ | ラズパイPico USB-DDC Feedbackを機能するように実装(2) »

2024年8月22日 (木)

ラズパイPico USB-DDC Feedbackを機能するように実装(1)

USBオーディオの規格にはUSB Audio Class 1.0(UAC 1.0)とUSB Audio Class 2.0(UAC 2.0)があるというのはご存じの方も多いとは思いますが、今一度USBオーディオについておさらいしておきましょう。

Uac2_00_20240822221001

PCなどの「ホスト」とUSB-DACなどの「ペリフェラル」との間の同期にはこれら3つの方式が規定されています。

 

USBの転送方式

コントロール転送

USB接続したとき、どんなデバイスであるかを認識するために使われます。

 

バルク転送

USBメモリやUSB-HDDなど大容量のデータ転送に使われます。エラー時には再送されます。

 

インターラプト転送

キーボードやマウスなど小容量のデータ転送に使われます。インターラプトという名称ですがホスト側からポーリングされてデータを転送しています。

 

アイソクロナス転送

動画や音声などリアルタイム性が必要なデータ転送です。バルク転送などよりも優先的に帯域を確保して転送されます。Full-Speedでは1ms間隔。Hi-Speedでは125us間隔で一定のデータレートで送られます。エラーが発生しても再送しません。

 

 

USBオーディオの同期方式

ホストとペリフェラル機器はそれぞれ独立した基準クロックを持っていますので、音切れなく再生するには何かしらの方法で再生速度の同期が必要になります。

Asynchronous

USB-DAC内の高精度クロックを基準にDACを動作させることができて高音質化が望めます。ただし、非同期なのでデータのやり取りでペリフェラル側からFeedback値を返してホストに適切なパケット数のデータを送ってもらう必要があります。

Windowsでは、USB-DACのメーカーがそれぞれ専用ドライバを用意しなければならない時代が続きましたが、Win10にてやっと標準搭載されました。

 

Synchronous

1msのSOFを基準にペリフェラル側がPLLにて同期する方法です。ホスト側のUSBクロックが基準になります。これを実装しているUSBオーディオ機器を見たことありません。

 

Adaptive

ホスト側が送り出すサンプリング周波数が基準になります。ペリフェラル側はPLLにて同期クロックを生成します。USB-DAC ICであるPCM2704が採用していてUSBスピーカー黎明期では多くの機器に搭載されました。 現在も安いUSBスピーカー、USBドングル型オーディオ機器の多くがこの方式と思われます。(Windowsが長らくAsynchronous方式をサポートして来なかった影響もある)

 

どのUSBオーディオ通信もアイソクロナス転送が使われます。Full-Speed時は1ms間隔でパケットが転送され、

サンプリング周波数 48kHz時では、48,000 ÷ 1ms = 48サンプルですが、

44.1kHzでは割り切れないので、44サンプルが9回に45サンプルが1回という割合で送られます。(ここがイヤらしいデス)

 

Bulk Petだけはバルク転送を使ってオーディオデータを送信しています。

 

 

 

USB Audio Class 1.0 と USB Audio Class 2.0 の差

じつはAsynchronousもAdaptiveもUAC 1.0からあります。UAC 2.0との違いは対応するUSBバージョンとサポートする最大レートになります。

 UAC 1.0はUSB 1.1以上で、最大96kHz/24bit
 UAC 2.0はUSB 2.0以上で、最大192kHz/24bit らしいです。

らしいと書いたのはホントはチャンネル数やAC3、WMA、DTSなど圧縮データの条件もあってその限りではないっぽいです。

詳細を知りたい方はUSB本家から仕様をダウンロードして読んでください。

https://www.usb.org/document-library/audio-devices-rev-20-and-adopters-agreement

 

 

Asynchronousのfeedback

Asynchronous方式はデータ転送量が可変で、USB-DAC側のバッファの残量に応じて増減します。

Uac2_fb

1ms間隔で送られてくるバケツに例えるとこんな感じです。 USB-DAC側には一定で出力され続けるバッファがあり、バッファ残量を見てfeedback値を戻してバケツに入れる水の量を調整してもらうことでバッファのアンダーフロー、オーバフローを防ぎます。

実はパケット量の増減には規定があり通常時の±1サンプル分までです。

サンプリング周波数48kHzであれば1ms間に48サンプル±1サンプルです。つまり47~49サンプルまで可変できます。

同様に44.1kHzでは44サンプルと45サンプルなので、増減しても43~46サンプルです。

それ以上増減したfeedback値を返すとWindows側に無視されるらしいので気を付けなければいけません。

 

 

ラズパイ公式のUSB-DDCのソースは

https://github.com/raspberrypi/pico-playground/blob/master/apps/usb_sound_card/usb_sound_card.c

ラズパイ公式でのフィードバックは以下のように実装されています。

static void _as_sync_packet(struct usb_endpoint *ep) {
    struct usb_buffer *buffer = usb_current_in_packet_buffer(ep);
    buffer->data_len = 3;

    // todo lie thru our teeth for now
    uint feedback = (audio_state.freq << 14u) / 1000u;

    buffer->data[0] = feedback;
    buffer->data[1] = feedback >> 8u;
    buffer->data[2] = feedback >> 16u;

    // keep on truckin'
    usb_grow_transfer(ep->current_transfer, 1);
    usb_packet_done(ep);
}

 

デバッグコードを消すとシンプルです。ここで 赤文字の1行に注目です。

audio_state.freq が 48000 のとき、feedbackは「786432(0x0C0000)」

44100 のとき、「722534(0x0B0666)」という固定値が返されています。

 

あらら、バッファ残量をみてフィードバックしていませんね。「lie thru our teeth for now」ってコメントが悔しさを物語っているようです。

 

音を聴いていると、ホストとUSB-DACのクロックの差によるオーバーフロー、アンダーフローが発生して時々「プチっ」というノイズが確認できます。
私の自宅の環境ではPCは40~50秒で音とびが発生しますが、iPadは2~3分は平気なようです。頻度は低いけどレコードのパチって感じのノイズが時々発生します。

 

最近レコードが流行っているらしいので、そういう雰囲気を味わうのもいいか?

 

なんてね。

対策を考えます。

 

つづきはこちら

 

 

« チップトランジスタのhfet測定ツール | トップページ | ラズパイPico USB-DDC Feedbackを機能するように実装(2) »

Raspberry Pi pico」カテゴリの記事

コメント

コメントを書く

(ウェブ上には掲載しません)

« チップトランジスタのhfet測定ツール | トップページ | ラズパイPico USB-DDC Feedbackを機能するように実装(2) »

サイト内検索(new)

2024年9月
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30