この記事では、USB デジタル オーディオ、および関連する USB ベースのプロトコルに関する Android のサポートについて確認します。
この記事の対象ユーザー
この記事は、Android デバイスの OEM、SoC ベンダー、USB オーディオ周辺機器のサプライヤー、高度なオーディオ アプリケーションのデベロッパーなど、Android の USB デジタル オーディオの仕組みを詳しく理解したい方を対象としています。
Nexus デバイスのエンドユーザーは、Nexus ヘルプセンターで USB ホストモードを使用して、音声を録音および再生するを参照してください。この記事はエンドユーザーを対象としたものではありませんが、オーディオにこだわりのある方にとっては、興味深い説明も含まれています。
USB の概要
ユニバーサル シリアルバス(USB)については、ウィキペディアの記事「USB」に概説があります。USB 規格は USB Implementers Forum, Inc が公式に定め、公開しています。ここでは USB の基本概念を簡単に説明するに留めます。正式な情報に関しては規格を参照してください。
基本的なコンセプトと用語
USB は、データ転送オペレーションの単一のイニシエータ(「ホスト」)を備えたバスです。ホストはバスを介して周辺機器と通信します。
注: USB の文脈における「デバイス」および「アクセサリー」という用語は、通常は周辺機器を表します。Android デバイスおよび Android 固有のコンセプトであるアクセサリー モードとの混同を避けるため、ここでは「周辺機器」の意味でデバイスおよびアクセサリーの用語を使うことはありません。
ホストの重要な役割は列挙です。列挙は、バスに接続されている周辺機器を検出し、記述子で表されたプロパティを照会するプロセスです。
周辺機器は物理的に 1 つのオブジェクトと捉えれていますが、実際には複数の論理機能が実装されています。たとえば、周辺機器のウェブカメラには、カメラ機能とマイク音声機能の両方が搭載されていることがあります。
周辺機器の各機能には、外部と通信するためのプロトコルがインターフェースとして定義されています。
ホストは、パイプを介して周辺機器と通信し、周辺機器の機能によって提供されるエンドポイント、データソース、シンクに接続します。
パイプには、メッセージ パイプとストリーム パイプの 2 種類があります。 メッセージ パイプは、双方向の制御とステータスに使用します。 ストリーム パイプは、一方向のデータ転送に使用します。
すべてのデータ転送はホストによって開始されます。したがって、入力および出力という用語はホストとの関係に応じて使い分けられます。入力オペレーションでは周辺機器からホストにデータが転送され、出力オペレーションではホストから周辺機器にデータが転送されます。
主要なデータ転送モードには、割り込みモード、バルクモード、アイソクロナス モードの 3 つがあります。アイソクロナス モードについては、オーディオとの関連で詳しく説明します。
一部の周辺機器は、外部の世界と接続するための端子を備えています。この端子を通じて、周辺機器による USB プロトコルと実際のアナログ信号との変換が行われます。データ転送における端子は、機能を表現する論理オブジェクトになります。
Android USB モード
開発モード
開発モードは、Android の初期リリースから存在しました。 Linux、Mac OS X、Windows などパソコン用のオペレーティング システムを実行するホスト PC で、Android デバイスは USB 周辺機器として表示されます。表示される周辺機器の機能は、Android fastboot と Android Debug Bridge(adb)のみです。fastboot プロトコルと adb プロトコルは、USB の一括データ転送モードでレイヤ化されています。
ホストモード
ホストモードは Android 3.1(API レベル 12)で導入されました。
Android デバイスはホストとして動作する必要があります。ただ、一部の Android デバイスにはホストによる操作を直接許可しないマイクロ USB コネクタが搭載されているため、以下のような OTG(On-The-Go)アダプターが必要になります。
Android デバイスでは、周辺機器が必要とする電力と Android デバイス自体が供給できる電力量の兼ね合いにより、特定の周辺機器を動作させるうえで必要な電力を供給できない場合があります。十分な電力が利用可能な場合でも、Android デバイスのバッテリーを急激に消費する場合があります。このような場合には、以下のようなセルフパワー型ハブを使用します。
アクセサリー モード
アクセサリー モードは Android 3.1(API レベル 12)で導入された後、Android 2.3.4 に移植されました。 このモードで Android デバイスは USB 周辺機器として動作し、別のデバイス(ホストとして機能するドックなど)の制御下にあります。開発モードとアクセサリー モードの違いは、追加された USB の機能が adb を越えてホストに表示される点です。Android デバイスは開発モードで起動し、再ネゴシエーション プロセスを経てアクセサリー モードに移行します。
アクセサリー モードは Android 4.1 で拡張され、下記のオーディオ機能などが追加されました。
USB オーディオ
USB クラス
周辺機器の各機能には、その機能の標準プロトコルを指定するデバイスクラスドキュメントが関連づけられています。このため、クラス準拠のホストと周辺機器の各機能は、相互の動作に関する詳細な情報がなくとも相互運用が可能です。ホストを提供する主体と周辺機器を提供する主体が異なる場合は、クラス準拠していることが非常に重要です。
通常、「ドライバ不要」という用語はクラス準拠しているということを意味し、周辺機器の標準的な機能がオペレーティング システム固有のドライバをインストールすることなく使用できることを示します。主要なパソコン用オペレーティング システムであれば「ドライバ不要」だとする周辺機器は、ほぼクラス準拠だと想定できます。
USB Audio Class
ここでは、オーディオ機能を実装する周辺機器に絞って、オーディオ デバイスクラスについて説明します。USB Audio Class 仕様には、Class 1(UAC1)と Class 2(UAC2)の 2 つがあります。
他のクラスとの比較
USB にはその他にも多くのデバイスクラスがあり、一部に Audio Class と混同されるものもあります。マスストレージ クラス(MSC)はメディアへのセクタ指向のアクセスに使用され、メディア転送プロトコル(MTP)は、メディアへのフルファイル アクセスに用いられます。MSC と MTP はどちらもオーディオ ファイルの転送に使用できますが、リアルタイム ストリーミングに適しているのは USB Audio Class のみです。
オーディオ端子
オーディオ周辺機器の端子は一般にアナログです。 周辺機器の入力端子で扱われるアナログ信号は、アナログ デジタル変換器(ADC)によってデジタルに変換され、USB プロトコルを介してホストに送信されます。ADC はホストのデータソースです。同様に、ホストは USB プロトコルを介して周辺機器にデジタル オーディオ信号を送信し、その信号がデジタル アナログ変換器(DAC)によって変換されてアナログ出力端子に出力されます。DAC はホストのシンクです。
チャンネル
オーディオ機能を有する周辺機器には、ソース端子、シンク端子、またはその両方を搭載できます。 各方向に、1 チャンネル(モノラル)、2 チャンネル(ステレオ)、それ以上のチャンネルを持つことができます。3 チャンネル以上はマルチチャンネルと呼ばれます。 一般的に、ステレオ ストリームは左右 2 つのチャンネルで構成されると解釈されます。これをマルチチャンネル ストリームに当てはめると、チャンネルごとに空間ロケーションが保持されると解釈されます。しかし、各チャンネルに空間ロケーションをまったく割り当てない場合もあります(この傾向は HDMI よりも USB オーディオで顕著です)。このような場合には、アプリケーションとユーザーが各チャンネルの使用方法を定義します。たとえば、4 チャンネルの USB 入力ストリームでは、3 つのチャンネルを室内に設置された複数のマイクに割り当て、残りの 1 チャンネルで AM ラジオを受信している場合があります。
アイソクロナス転送モード
USB オーディオでは、エラーリカバリの代わりにリアルタイム性を優先する場合、アイソクロナス転送モードを使用します。アイソクロナス モードでは帯域幅が保証され、データ伝送エラーが巡回冗長検査(CRC)により検出されます。ただし、エラーが発生した場合も、パケットの確認応答や再送は行われません。
アイソクロナス転送は、Start Of Frame(SOF)の間に発生します。 SOF の時間は、Full-Speed の場合で 1 ミリ秒、High-Speed の場合で 125 マイクロ秒です。Full-Speed の各フレームは最大 1,023 バイトのペイロードを転送し、High-Speed のフレームは最大 1,024 バイトまでのペイロードを転送します。これらを合わせると、最大転送レートは 1,023,000 バイト毎秒または 8,192,000 バイト毎秒となります。この数値により、オーディオ サンプルレート、チャンネル数、ビット深度の組み合わせに理論上の上限が設定されます。実際の上限はこれよりも低くなります。
アイソクロナス モードには、次の 3 つのサブモードがあります。
- アダプティブ
- アシンクロナス
- シンクロナス
アダプティブ サブモードでは、ホストのサンプルレートが変動する場合にも周辺機器のシンクまたはソースが対応します。
アシンクロナス(暗黙的フィードバック)サブモードでは、シンクまたはソースがサンプルレートを決定し、ホストが対応します。アシンクロナス サブモードの主な理論上の利点は、ソースまたはシンクの USB クロックが、DAC または ADC が行われる場合のクロックに物理的にも電気的にも近接している(実際に等しいか、算出の基準となっている)点です。両者が近接しているため、アシンクロナス サブモードはクロック ジッターの影響を受けにくくなります。また、DAC または ADC で使用されるクロックは、ホストクロックより精度が高く、ドリフトが低くなるように設計される場合があります。
シンクロナス サブモードでは、SOF の間に一定のバイト数がその都度転送され、オーディオ サンプルレートが USB クロックから効率的に算出されます。 ホストと周辺機器の両方が USB クロックを使用するシンクロナス サブモードは、一般にオーディオの処理には使用されません。
下の表はアイソクロナス サブモードについてまとめたものです。
サブモード | パケットあたり バイト数 |
サンプルレート の決定 |
音声への使用 |
---|---|---|---|
アダプティブ | 可変 | ホスト | ○ |
アシンクロナス | 可変 | 周辺機器 | ○ |
シンクロナス | 固定 | USB クロック | × |
サブモードは重要です。ただし実運用では他の要素も考慮に入れる必要があります。
USB Audio Class の Android サポート
開発モード
開発モードでは USB オーディオはサポートされていません。
ホストモード
Android 5.0(API レベル 21)以降では、次の USB Audio Class 1(UAC1)機能のサブセットがサポートされています。
- Android デバイスがホストとして動作する
- 音声フォーマットが PCM(インターフェース タイプ I)である
- ビット深度が 16 ビット、24 ビット、32 ビットで、24 ビットの有効なオーディオ データが 32 ビットワードの最上位ビットの範囲で左詰めされている
- サンプルレートが、48、44.1、32、24、22.05、16、12、11.025、8 kHz のいずれかである
- チャンネル数が 1(モノラル)または 2(ステレオ)である
Android フレームワークのソースコードを詳細に確認すると、これらの機能をサポートするために最低限必要なコード以外にも、追加のコードの見つかる場合があります。しかしながら、このようなコードはまだ検証されておらず、そのコードによる高度な機能はまだ提供されていません。
アクセサリー モード
Android 4.1(API レベル 16)では、ホストへのオーディオ再生が制限付きでサポートされるようになりました。 アクセサリー モードでは、Android によりオーディオ出力が自動的に USB にルーティングされます。 つまり、Android デバイスが、Dock などのホストへのデータソースとして機能するということです。
アクセサリー モードのオーディオ機能は次のとおりです。
- Android デバイスは、十分な情報を保持したホストによって制御される必要があります。ホストは最初に Android デバイスを開発モードからアクセサリー モードに移行し、適切なエンドポイントから音声データを転送できなければなりません。そのため、ホストに対して、Android デバイスが「ドライバ不要」と表示されることはありません。
- 方向はホストへの入力である必要があります
- 音声フォーマットは 16 ビット PCM である必要があります
- サンプルレートは 44.1 kHz である必要があります
- チャンネル数は 2(ステレオ)である必要があります
アクセサリー モードの音声はまだ広く普及していないため、現時点では新しい設計には推奨されません。
USB デジタル オーディオの用途
名称に示されているとおり、USB デジタル オーディオ信号では、一般的な TRS ミニ ヘッドセット コネクタで使用されるアナログ信号ではなく、デジタルデータ ストリームが扱われます。 最終的には、デジタル信号がアナログに変換されて、聞こえるようになります。 変換する場所の選択によっては、トレードオフが発生します。
2 つの DAC に関する解説
下の図は、2 つの設計を比較したものです。1 つは、アプリケーション プロセッサ(AP)、オンボード DAC、アンプ、アナログ TRS コネクタ(ヘッドフォンを接続)付きのモバイル デバイスについて示しています。また、USB で USB DAC とアンプに接続し、ヘッドフォンにも接続されているモバイル デバイスについても確認します。
どちらの設計が優れているかと問われた場合、その答えは、ユーザーのニーズによって異なります。 それぞれの設計に長所と短所があります。
注: この比較は擬似的なものです。実際の Android デバイスでは、両方のオプションが用意されることが多いです。
1 つ目の A 設計は、シンプルかつ安価で消費電力が少なく、コンポーネントの信頼性が同等である限り、より信頼性の高い設計です。しかし、通常は、音質と他の要件がトレードオフの関係になります。 たとえば、大衆市場向けのデバイスであれば、一般的な消費者のニーズに合うよう設計されており、オーディオ志向の高いユーザーには適切ではない可能性があります。
2 つ目の設計では、外部オーディオ周辺機器 C を高音質および高出力になるように設計できます。大衆市場向けの基本的な設計の Android デバイス B にコスト面での影響を及ぼすことがありません。その分、設計コストは高価になります。ユーザーのニーズを満たすことができなければ、コストを回収できません。
モバイル デバイスには高密度回路基板が搭載されており、アナログ信号が隣接する場合に信号を劣化させるクロストークが発生しやすいと言われます。デジタル通信はノイズの影響を受けにくいことから、DAC を Android デバイス A から外部の回路基板である C に移行することで、最終的なアナログ通信を高密度でノイズの多い回路基板から物理的かつ電気的に分離でき、高い再現性を持った音声を実現できます。
ただし、2 つ目の設計は 1 つ目の設計より複雑です。複雑さが増すことで不具合が生じる可能性も高まります。また、USB コントローラでのレイテンシも増大します。
ホストモードのアプリケーション
一般的な USB ホストモードのオーディオ アプリケーションには、次のものが挙げられます。
- 音楽再生
- 通話
- インスタント メッセージとボイスチャット
- 録音
このようなアプリケーションでは、Android により、互換性のある USB デジタル オーディオ周辺機器が検出され、オーディオ ポリシールールに基づいてオーディオの再生と適切なキャプチャが自動的に行われます。ステレオ コンテンツの場合は、周辺機器の最初の 2 つのチャンネルで再生が行われます。
USB デジタル オーディオに特化した API はありません。 高度な用途に使用される場合、自動ルーティングが USB 対応のアプリケーションに干渉する場合があります。このようなアプリにおいては、[設定] の [開発者向けオプション] にある [メディア] の項目で、対応するコントロールによる自動ルーティングを無効にします。
ホストモードでのデバッグ
USB ホストモードでは、USB 経由の adb デバッグは使用できません。 代替方法については、Android Debug Bridge のワイヤレスでの使用のセクションをご覧ください。
USB オーディオを実装する
オーディオ周辺機器ベンダー向けの推奨事項
オーディオ周辺機器のベンダーは、Android デバイスとの相互運用のために以下を行う必要があります。
- Audio Class を遵守した設計。現在、Android では Class 1 をターゲットにしていますが、Class 2 で設計することをおすすめします。
- 極端な設計の回避
- リファレンスと一般的な Android デバイスを使用した相互運用性のテスト
- サポート対象機能、Audio Class の遵守内容、電力要件などの文書化。ユーザーが情報に基づいた意思決定を行えるように内容を明確にしてください。
Android デバイス OEM と SoC ベンダー向けの推奨事項
USB デジタル オーディオをサポートするには、デバイスの OEM と SoC ベンダーが次のことを行う必要があります。
- ハードウェア設計で USB ホストモードをサポート
android.hardware.usb.host.xml
機能のフラグを使用して、フレームワーク レベルでの汎用 USB ホストのサポートを有効化- 必要なカーネル機能(USB ホストモード、USB オーディオ、アイソクロナス転送モード)をすべて有効化。詳しくは、Android カーネル設定をご覧ください。
- カーネルのリリースやパッチについて最新情報を入手。オーディオ周辺機器によっては、クラス遵守をかかげながらも、極端な設計が行われているものが存在します。最新のカーネルであれば、このような極端な設計を回避する方法が用意されています。
- 以下の USB オーディオ ポリシーの有効化
- audio.usb.default を device.mk の PRODUCT_PACKAGES に追加
- 一般的な USB オーディオ周辺機器との相互運用性のテスト
USB オーディオ ポリシーの有効化
USB オーディオを有効にするには、オーディオ ポリシー構成ファイルにエントリを追加します。通常、このファイルは以下の場所にあります。
device/oem/codename/audio_policy.conf
パス名の「oem」の部分を Android デバイスを製造する OEM の名称に、「codename」の部分をデバイスコード名に置き換えてください。
エントリの例を次に示します。
audio_hw_modules { ... usb { outputs { usb_accessory { sampling_rates 44100 channel_masks AUDIO_CHANNEL_OUT_STEREO formats AUDIO_FORMAT_PCM_16_BIT devices AUDIO_DEVICE_OUT_USB_ACCESSORY } usb_device { sampling_rates dynamic channel_masks dynamic formats dynamic devices AUDIO_DEVICE_OUT_USB_DEVICE } } inputs { usb_device { sampling_rates dynamic channel_masks AUDIO_CHANNEL_IN_STEREO formats AUDIO_FORMAT_PCM_16_BIT devices AUDIO_DEVICE_IN_USB_DEVICE } } } ... }
ソースコード
USB オーディオ用のオーディオ Hardware Abstraction Layer(HAL)実装は、次の場所にあります。
hardware/libhardware/modules/usbaudio/
USB オーディオ HAL は、tinyalsa に大きく依存しています。tinyalsa については、オーディオ用語に説明があります。USB オーディオはアイソクロナス転送に依存しますが、ALSA 実装によって抽象化されています。そのため、USB オーディオ HAL と tinyalsa にとって、USB プロトコルのこの部分は問題にはなりません。
USB オーディオのテスト
USB オーディオの CTS テストについては、USB オーディオ CTS 検証ツールテストをご覧ください。