次の方法で共有


ストリーム ルーティングの実装に関する考慮事項

Windows 7 では、Media Foundation、DirectSound、Wave API などのコア オーディオ API を使用する高度なプラットフォーム API が、既存のデバイスから新しい既定のオーディオ エンドポイントへのストリーム切り替えを処理することで、ストリーム ルーティング機能を実装します。 これらの API を使用するメディア アプリケーションは、ソースに変更を加えることなくストリーム ルーティング動作を使用します。 直接 WASAPI クライアントは、コア オーディオ コンポーネントによって送信された通知を使用して、ストリーム ルーティング機能を実装できます。

ダイレクト WASAPI クライアント (WASAPI を直接使用するメディア アプリケーション) は、コア オーディオ コンポーネントによって送信された新しいデバイスとオーディオ セッションの通知を受け取ります。 ストリーム ルーティング機能の動作は、アプリケーションがこれらの通知を処理する方法によって定義されます。

デバイスの状態の変更とセッションの変更に関する通知は、MMDevice API とオーディオ セッションによってコールバックの形式で WASAPI クライアントに送信されます。 これらの通知を取得するには、クライアントが IMMNotificationClientIAudioSessionEvents の実装を登録する必要があります。 詳細については、「ストリーム ルーティングに関連する通知」を参照してください。

ストリーム ルーティング」で説明されている USB ヘッドセットのシナリオでは、アプリケーションがオーディオ ストリームを再生し、MMDeviceAPI と WASAPI を使用して、既定のレンダリング デバイスであるスピーカーにストリームをレンダリングします。 既定のデバイスが変更されると、アプリケーションは IMMNotificationClient 通知を受け取ります。 アプリケーションは、ユーザーがオーディオ エンドポイント デバイスを削除したか、オーディオ セッションが接続されているデバイスのストリーム形式が変更されたことを示す IAudioSessionEvents 通知も受け取ります。 通知を受信すると、アプリケーションはスピーカー エンドポイントへのストリーミングを停止し、現在の既定のエンドポイントであるヘッドセットでレンダリングするためにストリームを再度開きます。

diagram of data flow for device notifications.

このような通知に応答して、クライアントは、ユーザーによって選択された新しい形式で新しい既定のデバイス上のストリームを再度開く場合があります。

ストリームの管理

次の一覧は、ストリーム切り替え機能を提供するために WASAPI クライアントが実行する必要がある手順をまとめたものです。

  1. 関連する IMMNotificationClient の通知を待機します。 デバイスが既定のデバイスの場合は、IMMNotificationClient::OnDefaultDeviceChanged 通知が受信されます。

  2. 新しいデバイスが使用可能な場合は、新しいデバイスのエンドポイントへの参照を取得します。 新しい既定のデバイスに対して IMMDeviceEnumerator::GetDefaultAudioEndpoint を呼び出します。 新しいデバイスが既定のデバイスでない場合は、IMMDeviceEnumerator::GetDevice を呼び出してデバイスを取得できます。 詳細については、「ストリーム ルーティング用のデバイス エンドポイントの取得」を参照してください。

  3. 理由の値を含む IAudioSessionEvents::OnSessionDisconnected を待機します。

    Note

    これらの操作はすべて非同期であるため、アプリケーションでは、デバイス変更通知とセッション切断通知を受信する順序を予測することはできません。 アプリケーションは、任意の順序でこれらの通知を受信する通知処理を実装する必要があります。 ただし、通常アプリケーションは、既定のデバイス変更通知の前に AudioSessionDisconnect 値を受け取ります。

     

  4. 理由の値を評価して、ストリームを別のオーディオ エンドポイントに転送する必要があるか、ストリームを新しい形式で再初期化する必要があるかを判断します。

  5. ストリームを新しい既定のデバイスに再ルーティングする必要があることが理由に示されている場合は、古い既定のデバイスへのストリーミングを停止します。

  6. 位置マッピングの計算を実行します。

  7. 新しいデバイスでストリームを開き、すべての状態情報を転送します。

  8. 新しい既定のデバイスでストリーミングを再開します。

  9. 古い既定のデバイスの離脱の処理をします。

ストリーム切り替え操作をシームレスに表示するには、可能な限り迅速にこれを行う必要があります。 これは、新しいデバイスでのストリームの再開に関わるコンポーネントのパフォーマンスによって異なります。

位置マッピングに関する考慮事項

アプリケーションは、IMMNotificationClient 通知と IAudioSessionEvents 通知を取得すると、既存のストリームを新しい既定のデバイスにルーティングできるようになります。 既存のオーディオ ストリームが中断されて、新しいデバイスで開かれた場合、新しいデバイスでのレンダリングは、古いデバイスでストリームが停止した位置から開始する必要があります。 これを行うには、新しいデバイスの開始位置を計算するために、アプリケーションでは最後の既知のデバイス位置が必要となります。 たとえば、この位置は、後続の位置マッピングのデルタ オフセットとして使用できます。 ストリームがレンダリングを開始すると、新しいデバイスの位置をキャッシュされたデバイスの位置に再マッピングできます。

次の手順は、シームレスなストリーム遷移を行うプロセスをまとめたものです。

  1. 古いデバイス上のストリームの最後のデバイス位置をキャッシュします。
  2. 古いデバイスでストリームを停止します。
  3. 再マッピングの計算を実行して、新しい位置を取得します。
  4. 新しいデバイスでストリームのレンダリングを開始します。
  5. 古いストリームを解放します。

切り替え中にアプリケーションは、オーディオ ストリームとビデオ ストリームが同期されない状態にならないように、クロックが同期から外れないことを確実にする必要があります。 同期されていない状態は、オーディオ ストリームが新しいデバイスにルーティングされている間にビデオ サンプルがレンダリングを続ける場合に生じる可能性があります。 アプリケーションは、再マッピング計算のクロック位置をキャッシュし、オーディオ ストリームが新しいデバイスで再度開くまでビデオ サンプルがレンダリングされないようにする必要があります。これにより、クリップがレンダリングを再開したときに、オーディオ ストリームとビデオ ストリームが同期されます。 ビデオ フレームをレンダリングするためのプレゼンテーション時間がオーディオ クロックに基づいている場合は、ストリームの切り替えが完了し、オーディオ ビデオの同期のために実装が必要なビデオ ストリームのその他の位置マッピングがなくなるまで、オーディオ ストリームを停止するだけで十分な場合があります。

レンダリング中に、古いデバイスが失われることにより、IAudioRenderClient::GetBuffer がエラーを返した場合、ストリーミング操作は既に終了しているため、アプリケーションは古いストリームを停止する必要はありません。 このエラーの処理については、「無効なデバイス エラーからの回復」を参照してください。

MMDevice API について

WASAPI について

ストリーム ルーティング