次の方法で共有


マルチ チャネル ノードの公開

Windows XP より前のバージョンの Microsoft Windows では、WDM オーディオ ドライバーに、以下の種類のマルチチャネル ノードを公開する合理化された方法はありません。

KSNODETYPE_VOLUME

KSNODETYPE_MUTE

KSNODETYPE_TONE

特に、サポートされているチャネルの数について、ノードに対して明示的にクエリを実行するためのメカニズムは存在しません。 この問題の回避策は存在しますが、欠点があります。 たとえば、クライアントは KSPROPERTY_AUDIO_VOLUMELEVEL プロパティを使用して、各チャネルのボリューム レベル (0、1 など) のボリューム ノード (KSNODETYPE_VOLUME) に対して、チャネルが存在しないことを示すエラーが要求から返されるまで反復的にクエリを実行できます。 ただし、この手法には複数のクエリが必要であり、新しいマルチチャネル オーディオ デバイスを処理するには非効率的すぎます。 Windows XP 以降のオペレーティング システムでは、この制限は、基本サポート クエリに応答してプロパティ ハンドラーによって出力される、KSPROPERTY_MEMBERSHEADER 構造の Flags メンバーに 2 つの追加フラグ ビットを定義することによって解決されます。

  • KSPROPERTY_MEMBER_FLAG_BASICSUPPORT_MULTICHANNEL

    ノードの基本サポート プロパティ要求時、ハンドラーは、KSPROPERTY_MEMBERSHEADER の MembersCount メンバーに、ノードによってサポートされるチャネル数が含まれていることを示すよう、このフラグ ビットを設定します。 Windows Vista 以降の Windows オペレーティング システムでは、すべてのチャネル プロパティに対してこのフラグを設定する必要があります。

  • KSPROPERTY_MEMBER_FLAG_BASICSUPPORT_UNIFORM

    ハンドラーは、このフラグ ビットと KSPROPERTY_MEMBER_FLAG_BASICSUPPORT_MULTICHANNEL フラグ ビットの間でビットごとの OR を実行し、ノード内のすべてのチャネルに 1 つのプロパティ値が均一に適用されることを示します。 たとえば、ハードウェアがすべてのチャネルに対して単一のボリューム レベル制御のみ提供する場合、ボリューム ノードの基本サポート ハンドラーは、この制限を示す KSPROPERTY_MEMBER_FLAG_BASICSUPPORT_UNIFORM フラグを設定します。 このフラグが設定されていない場合、各チャネルのボリューム レベルは、他のチャネルのボリューム レベルとは別個に制御できます。

    KSPROPERTY_MEMBER_FLAG_BASICSUPPORT_UNIFORM フラグは、Windows Vista オペレーティング システムでは使用されません。

Windows XP 以降のミニポート ドライバーでは、マルチチャネル ボリューム ノードのプロパティ ハンドラーは、KSPROPERTY_AUDIO_VOLUMELEVEL 基本サポート クエリに応答して KSPROPERTY_MEMBER_FLAG_BASICSUPPORT_MULTICHANNEL ビットを設定する必要があります。 ハンドラーは、KSPROPERTY_STEPPING_LONG 構造の配列 (ノードによって公開されるチャネルごとに 1 つ) を返し、MembersSizesizeof (KSPROPERTY_STEPPING_LONG) に設定します。 各配列要素は、チャネルの最小および最大ボリューム レベルと、範囲内の連続する値間の差分を記述します。 均一ではない範囲のチャネルを正しく公開できるよう、個々のチャネルごとに異なる範囲を指定できます。 たとえば、サブウーファー チャネルの範囲は他のチャネルとは異なる場合があります。

次のコード例は、均一ではないプロパティ値を 持つオーディオ プロパティ の基本サポート クエリを処理する方法を示しています。 以下のコードの最初の行にある変数 pDescription は、ハンドラーが基本的なサポート情報を書き込むデータ バッファーの先頭にある KSPROPERTY_DESCRIPTION 構造をポイントしています。

  //
  // Fill in the members header.
  //
  PKSPROPERTY_MEMBERSHEADER pMembers = PKSPROPERTY_MEMBERSHEADER(pDescription + 1);

  pMembers->MembersFlags = KSPROPERTY_MEMBER_STEPPEDRANGES;
  pMembers->MembersSize = sizeof(KSPROPERTY_STEPPING_LONG);
  pMembers->MembersCount = ulNumChannels;
  pMembers->Flags = KSPROPERTY_MEMBER_FLAG_BASICSUPPORT_MULTICHANNEL;

  //
  // Fill in the stepped range with the driver default.
  //
  PKSPROPERTY_STEPPING_LONG pRange = PKSPROPERTY_STEPPING_LONG(pMembers + 1);
  pRange->Reserved = 0;

  for (ULONG i=0; i<ulNumChannels; i++)
  {
      pRange[i].Bounds.SignedMinimum = ulChannelMin[i];
      pRange[i].Bounds.SignedMaximum = ulChannelMax[i];
      pRange[i].SteppingDelta = ChannelStepping[i];
  }

  pPropertyRequest->ValueSize = sizeof(KSPROPERTY_DESCRIPTION) +
                                sizeof(KSPROPERTY_MEMBERSHEADER) + 
                                ulNumChannels * sizeof(KSPROPERTY_STEPPING_LONG);

次の図は、この例のデータ バッファーのレイアウトを示しています。 pDescription、pMembers、および pRange ポインターは、バッファー内のそれぞれのオフセットをポイントして表示されます。

Diagram illustrating the layout of a data buffer for a basic-support query with pDescription, pMembers, and pRange pointers.

この例では、ハンドラーは MembersCountulNumChannels (チャネルの数) に設定します。 範囲配列のサイズ (バイト)

MembersSize * MembersCount

この例で KSPROPERTY_MEMBER_FLAG_BASICSUPPORT_UNIFORM フラグが設定されている場合、ハンドラーは配列内のすべての KSPROPERTY_STEPPING_LONG 構造を同じ範囲に設定する点に注意してください。

トーン ノードの KSPROPERTY_AUDIO_BASSKSPROPERTY_AUDIO_TREBLE、または KSPROPERTY_AUDIO_MID プロパティの基本サポート ハンドラーも同様に動作します。

マルチチャネル ノードに BOOL 型のチャネル単位プロパティ値を持つプロパティがある場合、基本サポート ハンドラーはステップ範囲配列の値を入力する必要があります。 この場合、ハンドラーはメンバーを次のコード例に示す値に設定します。 この種類のプロパティの 2 つの例として、ミュート ノードの KSPROPERTY_AUDIO_MUTE プロパティとトーン ノードの KSPROPERTY_AUDIO_BASS_BOOST プロパティがあります。

次のコード例は、BOOL 型のチャネル単位プロパティ値を持つプロパティの場合に、マルチチャネル ノードの基本サポート要求を処理する方法を示しています。

  //
  // Fill in the members header.
  //
  PKSPROPERTY_MEMBERSHEADER pMembers = PKSPROPERTY_MEMBERSHEADER(pDescription + 1);

  pMembers->MembersFlags = KSPROPERTY_MEMBER_STEPPEDRANGES;
  pMembers->MembersSize = sizeof (KSPROPERTY_STEPPING_LONG);
  pMembers->MembersCount = ulNumChannels;
  pMembers->Flags = KSPROPERTY_MEMBER_FLAG_BASICSUPPORT_MULTICHANNEL;

  pPropertyRequest->ValueSize = sizeof(KSPROPERTY_DESCRIPTION) +
                                sizeof(KSPROPERTY_MEMBERSHEADER) + 
                                ulNumChannels * sizeof(KSPROPERTY_STEPPING_LONG);

  //
  // Fill in the stepped range with values in FOR loop.
  //
  PKSPROPERTY_STEPPING_LONG pRange = PKSPROPERTY_STEPPING_LONG(pMembers + 1);
  pRange->Reserved = 0;

  for (ULONG i=0; i<ulNumChannels; i++)
  {
      pRange[i].Bounds.SignedMinimum = 0;
      pRange[i].Bounds.SignedMaximum = 1;
      pRange[i].SteppingDelta = 1;
  }

前のコード例では、FOR ループでゼロ (0) と 1 を使用して、チャネル単位の範囲の最小値と最大値を設定していることに注意してください。 これは、BOOL 型のチャネル単位プロパティ値を使用してマルチチャネル ノードを構成しているためです。

チャネル プロパティが均一な場合、KSPROPERTY_MEMBER_FLAG_BASICSUPPORT_UNIFORM フラグと、KSPROPERTY_MEMBER_FLAG_BASICSUPPORT_MULTICHANNEL フラグおよび pMembers->Flags メンバーに割り当てられた結果の間でビットごとの OR 操作を実行できます。 この値は、ハードウェアがノード内のすべてのチャネルで同じプロパティ値を均一に適用することを示すために使用されます。

KSPROPERTY_MEMBER_FLAG_UNIFORM フラグと KSPROPERTY_MEMBER_FLAG_MULTICHANNEL フラグを使用すると、Windows Driver Kit (WDK) の Ac97 サンプル ドライバーで行われるように、チャネルをペアにグループ化し、チャネルのペアごとに個別のステレオ ボリューム ノードを公開する必要がなくなります。 Windows XP より前のバージョンの Windows ではこれらのフラグがサポートされていないため、ドライバーの基本サポート ハンドラーは、これらのフラグを使用するかどうかを判断するため、IPortClsVersion インターフェイスを使用して Portcls.sys バージョンのクエリを実行する必要があります。

トポロジ パーサー (カーネル モード WDMAud システム ドライバーでは Wdmaud.sys) は、WDM オーディオ ドライバーからオーディオ デバイスのトポロジを取得します。 パーサーは、従来の Windows マルチメディア ミキサー API を通じてそのデバイスを従来のミキサー デバイスとして公開します。 Windows XP 以降では、WDMAud は KSPROPERTY_MEMBER_FLAG_BASICSUPPORT_MULTICHANNEL フラグを使用し、MIXERLINE 構造の cChannels メンバーで報告するチャネルの数を決定します。 加えて、ノードの基本サポート ハンドラーが KSPROPERTY_MEMBER_FLAG_BASICSUPPORT_UNIFORM フラグを指定する場合、WDMAud 対応する MIXERCONTROL 構造で MIXERCONTROL_CONTROLF_UNIFORM フラグを設定します。 このフラグを通じて、アプリケーションはマスター コントロールを使用して各チャネルを個別に調整できるか、すべてのチャネルを均一に調整できるかを決定できます。 MIXERCONTROL、MIXERLINE、ミキサー API について詳しくは、Microsoft Windows SDK のドキュメントをご覧ください。

Windows XP 以降では、次の図に示すように、SndVol32 ボリューム制御プログラム (「SysTray と SndVol32」を参照) にマルチチャネル デバイスのコントロールが表示されます。

Screenshot of the SndVol32 volume-control dialog box displaying controls for multichannel devices.

SndVol32 は、2 つ以上のチャネルを持つ行を検出した場合、通常のパン コントロールを、前の図のメイン ボリューム スライダーの上に表示される「スピーカーの音量」というラベルのボタンに置き換えます。 次の図に示すように、[スピーカーの音量] ボタンをクリックすると、特定の行のすべてのチャネルのコントロールを表示するダイアログが表示されます。

Screenshot of the speaker-volume dialog box displaying controls for all channels and advanced audio properties.

ミキサー API はチャネルを番号ごとに公開するため、Windows マルチメディア コントロール パネル (Mmsys.cpl) の [オーディオの 詳細プロパティ] ダイアログで現在選択されているスピーカー構成からチャネル名を推測します。

たとえば、デバイスが 1 行に 4 つのチャネルを公開し、ユーザーが "4 チャネル スピーカー" を選択した場合、前の図に示すように、チャネル名は "左" (チャネル 0)、"右" (チャネル 1)、"背面左" (チャネル 2)、"背面右" (チャネル 3) になります。 スピーカー構成を "サラウンド サウンド スピーカー" に変更すると、チャネル マッピングが "左" (チャネル 0)、"右" (チャネル 1)、"前面中央" (チャネル 2)、"背面中央" (チャネル 3) になります。

ドライバー レベルでは、KSPROPERTY_AUDIO_CHANNEL_CONFIG プロパティは、KSAUDIO_SPEAKER_QUAD または KSAUDIO_SPEAKER_SURROUND のマスク値を使用して、それぞれ 4 チャネルまたはサラウンド スピーカーの構成を表します。 ヘッダー ファイル Ksmedia.h は、以下のようにこれらの値を定義します。

  #define KSAUDIO_SPEAKER_QUAD      (SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | \
                                     SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT)

  #define KSAUDIO_SPEAKER_SURROUND  (SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | \
                                     SPEAKER_FRONT_CENTER | SPEAKER_BACK_CENTER)

どちらのマスクにも、4 つのチャネルのスピーカー位置を指定する 4 ビットが含まれています。 どちらの場合も、KSPROPERTY_AUDIO_VOLUMELEVEL プロパティは、それぞれチャネル 0、1、2、3 と同じ 4 つのチャネルを識別します。

ノードの基本サポート ハンドラーにより KSPROPERTY_MEMBER_FLAG_BASICSUPPORT_UNIFORM フラグ ビットが設定されている場合、[スピーカーの音量] ダイアログに表示されるスライダーは、単一のスライダーに加えられた変更と同時に移動します。