Bluetooth LE を使用した補聴器の音声サポート

Bluetooth Low Energy(BLE)を介した接続指向の L2CAP チャンネル(CoC)を使用することにより、Android 搭載モバイル デバイスで補聴器(HA)のアクセシビリティを改善できます。CoC では、複数の音声パケットのエラスティック バッファを使用することで、パケット損失が発生しても安定した音声フローを維持できます。エラスティック バッファでは、レイテンシと引き換えに補聴器の音質を高めます。

CoC は、Bluetooth のコア仕様バージョン 5(BT)に沿って設計されており、同仕様をふまえて、このページのマルチバイト値はすべてリトル エンディアンとして読む必要があります。

用語

  • セントラル - Bluetooth を介してアドバタイズメントをスキャンする Android デバイス。
  • ペリフェラル - Bluetooth を介してアドバタイズメント パケットを送信する補聴器。

ネットワーク トポロジとシステム アーキテクチャ

補聴器に CoC を使用する場合は、ネットワーク トポロジに 1 つのセントラルと 2 つのペリフェラル(左右 1 つずつ)があることが前提となります(図 1 を参照)。Bluetooth オーディオ システムは、左右のペリフェラルを単一のオーディオ シンクとみなします。ペリフェラルの一方がモノラル専用または接続の不具合のために使用できない場合、セントラルは左右の音声チャンネルを組み合わせて問題ない方のペリフェラルに音声を送信します。セントラルが両方のペリフェラルへの接続を失った場合は、オーディオ シンクへのリンク自体が失われたとみなされます。この場合、セントラルは音声を別の出力にルーティングします。


図 1. BLE 経由の CoC を使用した補聴器と Android モバイル デバイスのペア設定のトポロジ

セントラルがペリフェラルへの音声データ ストリーミングを行っていなくても、BLE 接続を維持できている場合、セントラルをペリフェラルから切断する必要はありません。接続を維持することで、ペリフェラルで動作している GATT サーバーへのデータ通信が可能になります。

補聴器をペア設定して接続するときには、セントラルで次の処理を行う必要があります。

  • ペア設定された左右の最新のペリフェラルをトラッキングします。
  • 有効なペア設定が存在する場合には、ペリフェラルが使用中であると想定します。接続が失われた場合、セントラルはペア設定されたデバイスとの接続または再接続を試みます。
  • ペア設定が取り消された場合、ペリフェラルが使用されなくなったと想定します。

ここでの「ペア設定」とは、Bluetooth のペア設定プロセスではなく、所定の UUID と左右の指示子を使用して OS 上で補聴器のセットを登録する操作を指しています。

システム要件

CoC を適切に実装して優れたユーザー エクスペリエンスを実現するには、セントラル デバイスとペリフェラル デバイスで Bluetooth システムが次の要件を満たす必要があります。

  • 規格に準拠した BT 4.2 以上のコントローラを実装している。LE セキュア接続を強くおすすめします。
  • セントラルで少なくとも 2 つの同時 LE リンクをサポートしている。音声パケットの形式とタイミングに記載されているパラメータを使用します。
  • ペリフェラルで少なくとも 1 つの LE リンクをサポートしている。音声パケットの形式とタイミングに記載されているパラメータを使用します。
  • LE クレジット ベースのフロー制御 [BT ボリューム 3、パート A、セクション 10.1] を備えている。デバイスは、CoC で少なくとも 167 バイトの MTU および MPS サイズをサポートし、最大 8 パケットをバッファリングできることが必要です。
  • 少なくとも 167 バイトのペイロードを持つ LE データ長の拡張 [BT ボリューム 6、パート B、セクション 5.1.9] を備えている。
  • セントラル デバイスが HCI LE 接続更新コマンドをサポートしており、ゼロでない maximum_CE_Length および minimum_CE_Length パラメータに対応している。
  • セントラルで 2 つの異なるペリフェラルへの 2 つの LE CoC 接続のデータ スループットが維持されている。音声パケットの形式とタイミングに記載されている接続間隔とペイロード サイズを使用します。
  • ペリフェラルで、LL_LENGTH_REQ または LL_LENGTH_RSP フレームの MaxRxOctets および MaxRxTime パラメータが仕様上必要な必須の最小値に設定されている。これにより、フレームの受信に必要な時間を計算する際に、セントラルがタイム スケジューラを最適化できるようになります。

BT 5.0 仕様で規定されている 2MB PHY をセントラルとペリフェラルでサポートすることを強くおすすめします。セントラルでは、1M PHY と 2M PHY の両方で 64 kbit/s 以上の音声リンクをサポートする必要があります。BLE のロングレンジ PHY は使用しないでください。

CoC では、リンクレイヤの暗号化と周波数ホッピングに標準の Bluetooth メカニズムが使用されます。

ASHA GATT サービス

ペリフェラルでは、以下の Audio Streaming for Hearing Aid(ASHA)GATT サーバー サービスを実装する必要があります。セントラルにオーディオ シンクを認識させるため、通常の検出可能モードにあるときに、このサービスをアドバタイズする必要があります。LE 音声ストリーミング オペレーションには、暗号化が必要です。BLE 音声ストリーミングは、次の特性で構成されています。

特性 プロパティ 説明
ReadOnlyProperties 読み取り ReadOnlyProperties を参照。
AudioControlPoint 書き込みとレスポンスなしの書き込み 音声ストリームのコントロール ポイント。AudioControlPoint を参照。
AudioStatusPoint 読み取り / 通知 音声コントロール ポイントのステータス レポート フィールド。AudioStatusPoint を参照。
音量 レスポンスなしの書き込み -128~0 のバイトは、ストリーミング オーディオ信号に適用される減衰量(範囲は -48 dB~0 dB)を示します。-128 に設定すると、完全なミュートと解釈されます。つまり、ミュートされない最小の音量レベルは -127 で、これは -47.625 dB の減衰に相当します。0 に設定すると、ストリーミングされるレール間のサイントーンが補聴器の 100 dBSPL の入力に相当することを意味します。セントラルは、名目上のフルスケールでストリーミングを行い、この変数を使用してペリフェラルで望ましいプレゼンテーション レベルを設定する必要があります。
LE_PSM_OUT 読み取り 音声チャンネルの接続に使用する PSM。ダイナミック レンジ [BT ボリューム 3、パート A、セクション 4.22] から選択します。

サービスと特性に割り当てられた UUID:

サービス UUID: {0xFDF0}

特性 UUID
ReadOnlyProperties {6333651e-c481-4a3e-9169-7c902aad37bb}
AudioControlPoint {f0d4de7e-4a88-476c-9d9f-1937b0996cc0}
AudioStatus {38663f1a-e711-4cac-b641-326b56404837}
音量 {00e4ca9e-ab14-41e4-8823-f9e70c7e91df}
LE_PSM_OUT {2d410339-82b6-42aa-b34e-e2e01df8cc1a}

ペリフェラルでは、ASHA GATT サービスに加えて、セントラルでペリフェラルのメーカー名とデバイス名を検出するためのデバイス情報サービスも実装する必要があります。

ReadOnlyProperties

ReadOnlyProperties の値は次のとおりです。

バイト 説明
0 バージョン - 0x01 であることが必要です。
1 DeviceCapabilities を参照。
2-9 HiSyncId を参照。
10 FeatureMap を参照。
11-12 RenderDelay。ペリフェラルが音声フレームを受信してから出力をレンダリングするまでの時間(ミリ秒単位)。これらのバイトを使用して、動画を遅延させて音声と同期させることができます。
13-14 将来の使用のために予約済み。ゼロに初期化されています。
15-16 サポートされているコーデック ID。サポートされているコーデック ID のビットマスクです。サポート対象のコーデックに対応するビットに 1 が入ります。たとえば、0x0002 は G.722 が 16 kHz でサポートされていることを示します。他のすべてのビットは 0 に設定する必要があります。

DeviceCapabilities

ビット 説明
0 デバイス側(0: 左、1: 右)。
1 デバイスがスタンドアロンでモノラルデータを受信するか、デバイスがセットの一部であるか(0: モノラル、1: バイノーラル)を示します。
2 デバイスによる CSIS のサポート(0: サポートなし、1: サポートあり)
3-7 予約済み(0 に設定)

HiSyncID

このフィールドはすべてのバイノーラル デバイスで一意であることが必要ですが、左右のセットでは同じでなければなりません。

バイト 説明
0-1 メーカーの ID。BTSIG によって割り当てられた企業識別子です。
2-7 補聴器セットを識別する一意の ID。この ID は、左右のペリフェラルの両方で同じ値に設定する必要があります。

FeatureMap

ビット 説明
0 LE CoC オーディオ出力ストリーミングのサポート(対応 / 未対応)。
1-7 予約済み(0 に設定されています)。

コーデック ID

ビットが設定されている場合は、対応する特定のコーデックがサポートされます。

ID / ビット番号 コーデックとサンプルレート 必須のビットレート フレーム時間 セントラルで必須(C)またはペリフェラルで必須(P)
0 予約済み 予約済み 予約済み 予約済み
1 G.722(16 kHz) 64 kbit/s 変数 C および P
2~15 は予約済みです。
0 も予約済みです。

AudioControlPoint

LE CoC がクローズである場合、このコントロール ポイントは使用できません。手順の説明については、音声ストリームの開始と停止をご覧ください。

オペコード 引数 GATT sub-procedure 説明
1 «Start»
  • uint8_t codec
  • uint8_t audiotype
  • int8_t volume
  • int8_t otherstate
レスポンス付きで書き込み、AudioStatusPoint の特性による追加のステータス通知を待ちます。 コーデックをリセットしてフレーム 0 の再生を開始するようにペリフェラルに指示します。コーデック フィールドは、この再生に使用するコーデック ID を示します。たとえば、G.722(16 kHz)の場合、コーデック フィールドは「1」です。

音声タイプのビット フィールドは、ストリームに存在する音声タイプを示します。
  • 0 - 不明
  • 1 - 着信音
  • 2 - 通話
  • 3 - メディア
otherstate フィールドは、バイノーラル デバイスのもう一方の側が接続されているかどうかを示します。フィールド値は、もう一方のペリフェラル デバイスが接続されている場合は 1、接続されていない場合は 0 です。

ペリフェラルは、«Stop» オペコードが受信される前に接続更新をリクエストしないように設定する必要があります。
2 «Stop» なし レスポンス付きで書き込み、AudioStatusPoint の特性による追加のステータス通知を待ちます。 音声のレンダリングを停止するようにペリフェラルに指示します。音声を再度レンダリングするには、この停止後に新しい音声設定シーケンスを開始する必要があります。
3 «Status»
  • uint8_t connected
レスポンスなしの書き込み 接続されたペリフェラルに、他のペリフェラルでステータス更新があったことを通知します。connected フィールドは更新のタイプを示します。
  • 0 - 他のペリフェラルの接続が切断されている
  • 1 - 他のペリフェラルが接続されている
  • 2 - いずれかの接続で LE 接続パラメータの更新が発生した

AudioStatusPoint

音声コントロール ポイントのステータス レポート フィールド。

オペコード 説明
0 ステータス OK
-1 不明なコマンド
-2 不正なパラメータ

ASHA GATT サービスのアドバタイズメント

サービス UUID をアドバタイズメント パケットに含める必要があります。ペリフェラルは、アドバタイズメントまたはスキャン レスポンス フレームのいずれかで、以下のサービスデータを保持する必要があります。

バイト オフセット 名前 説明
0 AD の長さ >= 0x09
1 AD タイプ 0x16(サービスデータ - 16 ビット UUID)
2-3 サービス UUID 0xFDF0(リトル エンディアン)

注: これは一時的な ID です。
4 プロトコルのバージョン 0x01
5 Capability
  • 0 - 左側(0)または右側(1)。
  • 1 - 単一デバイス(0)またはデュアル デバイス(1)。
  • 2 - デバイスによる CSIS のサポート(<0: サポートなし、1: サポートあり)
  • 3-7 - 予約済み。これらのビットはゼロでなければなりません。
6-9 短縮型 HiSyncID HiSyncId の最上位 4 バイト。これらのバイトは ID の最もランダムな部分であるはずです。

ペリフェラルは、補聴器の名前を示す完全ローカルネーム データ型を持つ必要があります。この名前は、ユーザーが適切なデバイスを選択できるように、モバイル デバイスのユーザー インターフェースで使用されます。なお、この名前は左または右のチャンネルを示すものではありません。この情報は DeviceCapabilities で指定されます。

ペリフェラルが名前と ASHA サービスのデータ型を同じフレームタイプ(ADV または SCAN RESP)で指定した場合は、2 つのデータ型(「完全ローカルネーム」と「ASHA サービス用サービスデータ」)が同じフレーム内に表示されます。これにより、モバイル デバイスのスキャナが両方のデータを同じスキャン結果で取得できるようになります。

最初のペア設定では、モバイル デバイスが迅速にペリフェラルを検出して結合するうえで十分な速度でペリフェラルをアドバタイズすることが重要です。

左右のペリフェラル デバイスを同期する

Android モバイル デバイスで Bluetooth を利用するには、ペリフェラル デバイスの同期をペリフェラル デバイス側で確保する必要があります。左右のペリフェラル デバイスの再生のタイミングが同期できていなければなりません。両方のペリフェラル デバイスで、ソースから取得した音声サンプルを同時に再生する必要があります。

ペリフェラル デバイスは、音声ペイロードの各パケットの先頭に付加されたシーケンス番号を使用してタイミングを同期させることができます。セントラルでは、各ペリフェラル デバイスで同時に再生される音声パケットのシーケンス番号が同じであることを保証します。シーケンス番号は音声パケットごとに 1 ずつ増加します。各シーケンス番号の長さは 8 ビットであるため、シーケンス番号は音声パケット 256 個ごとに繰り返されます。各音声パケットのサイズとサンプルレートは接続ごとに固定されているため、2 つのペリフェラル デバイスで関連する再生時間を推測できます。音声パケットの詳細については、音声パケットの形式とタイミングをご覧ください。

セントラルは、同期が必要とされるときにトリガーをバイノーラル デバイスに提供することで同期をアシストします。これらのトリガーは、同期に影響する可能性があるオペレーションが存在するときにはいつでも、ペア設定されたペリフェラル デバイスのステータスを各ペリフェラルに通知します。トリガーは次のように機能します。

  • AudioControlPoint の «Start» コマンドの一部として、バイノーラル デバイスのもう一方の側の現在の接続状態を渡します。
  • 片方のペリフェラルで接続、接続の切断、または接続パラメータ更新のオペレーションが発生するたびに、AudioControlPoint の «Status» コマンドがバイノーラル デバイスのもう片方に送信されます。

音声パケットの形式とタイミング

音声フレーム(サンプルのブロック)をパケットにパックすると、補聴器はリンクレイヤのタイミング アンカーからタイミングを導出します。実装を簡素化するには、以下の要件を考慮してください。

  • 音声フレームのタイミングは、常に接続間隔と一致する必要があります。たとえば、接続間隔が 20 ms でサンプルレートが 16 kHz の場合、音声フレームには 320 個のサンプルが含まれます。
  • フレーム時間または接続間隔にかかわらずフレーム内のサンプル数が常に整数になるように、システムのサンプルレートは 8 kHz の倍数に制限されています。
  • 音声フレームの先頭にはシーケンス バイトを付加する必要があります。シーケンス バイトは、ラップアラウンドでカウントし、ペリフェラルがバッファの不一致またはアンダーフローを検出できるようにする必要があります。
  • 音声フレームが常に単一の LE パケットに収まるようにする必要があります。音声フレームは個別の L2CAP パケットとして送信する必要があります。LE LL PDU のサイズは次の式に従うものとします。
    音声ペイロード サイズ + 1(シーケンス カウンタ)+ 6(L2CAP ヘッダー用に 4、SDU 用に 2)
  • 接続イベントには、再送時の帯域幅を確保するために、常に 2 個の音声パケットと ACK 用の 2 個の空のパケットを含められるだけの大きさを用意する必要があります。音声パケットはセントラルの Bluetooth コントローラによって断片化される場合がある点に注意してください。ペリフェラルは、接続イベントごとに 3 つ以上の断片化された音声パケットを受信できる必要があります。

セントラルに柔軟性を持たせるため、G.722 のパケット長は規定されていません。G.722 パケット長は、セントラルが設定する接続間隔に応じて変化します。

G.722 出力オクテット形式は、ITU-T 勧告の G.722(09/2012)セクション 1.4.4 "Multiplexer" に沿って定められています。

ペリフェラルがサポートするすべてのコーデックに対して、以下の接続パラメータをペリフェラルでサポートする必要があります。これは、セントラルで実装可能な構成の一部であり、すべてを網羅したものではありません。

コーデック ビットレート 接続間隔 CE 長(1M/2M PHY) 音声ペイロード サイズ
G.722(16 kHz) 64 kbit/s 20 ミリ秒 5000/3750 マイクロ秒 160 バイト

音声ストリームの開始と停止

音声ストリームを開始する前に、セントラルはペリフェラルにクエリを発行して共通の基準コーデックを確立します。その後、ストリーム設定が次の順序で進行します。

  1. PSM(および必要に応じて RenderDelay)が読み込まれます。これらの値はセントラルでキャッシュに保存できます。
  2. CoC L2CAP チャンネルが開かれます。ペリフェラルは最初に 8 クレジットを付与する必要があります。
  3. 選択されたコーデックに必要なパラメータへのリンクを切り替えるため、接続の更新が実行されます。セントラルは、前のステップで CoC 接続を行う前に、この接続更新を行うことができます。
  4. セントラル ホストとペリフェラル ホストの両方が更新イベントが完了するまで待機します。
  5. 音声エンコーダを再起動し、パケット シーケンス数を 0 にリセットします。関連パラメータが指定された «Start» コマンドが AudioControlPoint で実行されます。ストリーミングを開始する前に、セントラルはペリフェラルから上記の «Start» コマンドの成功ステータスが通知されるまで待機します。この待機により、ペリフェラルは音声再生パイプラインの準備時間を得ることができます。音声ストリーミング中は、現在のレプリカのレイテンシがゼロでない場合でも、接続イベントごとにレプリカが使用可能であることが必要です。
  6. ペリフェラルは、その内部キューの最初の音声パケット(シーケンス番号 0)を取得して再生します。

セントラルは、«Stop» コマンドを実行して音声ストリームをクローズします。このコマンドの実行後は、接続イベントごとにペリフェラルが使用可能である必要はなくなります。音声ストリーミングを再開するには、上記の手順のステップ 5 以降を実施します。セントラルは、音声をストリーミングしていないときでも、GATT サービス用の LE 接続を維持する必要があります。

ペリフェラルでは、セントラルへの接続更新を行わないように設定する必要があります。電力を節約するため、セントラルがペリフェラルへの接続更新を実行できるのは、音声をストリーミングしていない場合です。