Share via


Verfügbarmachen von Mehrkanalknoten

In Versionen von Microsoft Windows vor Windows XP verfügen WDM-Audiotreiber nicht über eine optimierte Möglichkeit, Mehrkanalknoten der folgenden Typen verfügbar zu machen:

KSNODETYPE_VOLUME

KSNODETYPE_MUTE

KSNODETYPE_TONE

Insbesondere ist kein Mechanismus zum expliziten Abfragen eines Knotens nach der Anzahl der unterstützten Kanäle vorhanden. Obwohl für dieses Problem Problem Problemumgehungen vorhanden sind, haben sie Nachteile. Beispielsweise kann ein Client die eigenschaft KSPROPERTY_AUDIO_VOLUMELEVEL verwenden, um iterativ einen Volumeknoten (KSNODETYPE_VOLUME) für die Volumeebene jedes Kanals (0, 1 usw.) abzufragen, bis die Anforderung einen Fehler zurückgibt, der angibt, dass keine weiteren Kanäle vorhanden sind. Dieses Verfahren erfordert jedoch mehrere Abfragen und ist zu ineffizient, um neuere Multichannel-Audiogeräte zu verarbeiten. In Windows XP und höheren Betriebssystemen wird diese Einschränkung behoben, indem zwei zusätzliche Flagbits im Flags-Member der KSPROPERTY_MEMBERSHEADER-Struktur definiert werden, die der Eigenschaftenhandler als Antwort auf eine Abfrage mit grundlegender Unterstützung ausgibt:

  • KSPROPERTY_MEMBER_FLAG_BASICSUPPORT_MULTICHANNEL

    Während einer Anforderung der Basic-Support-Eigenschaft für einen Knoten legt der Handler dieses Flagbit fest, um anzugeben, dass das MemberCount-Element von KSPROPERTY_MEMBERSHEADER die Anzahl von Kanälen enthält, die der Knoten unterstützt. Für Windows Vista und höhere Windows-Betriebssysteme muss dieses Flag für jede Kanaleigenschaft festgelegt werden.

  • KSPROPERTY_MEMBER_FLAG_BASICSUPPORT_UNIFORM

    Der Handler führt einen bitweisen OR zwischen diesem Flagbit und dem KSPROPERTY_MEMBER_FLAG_BASICSUPPORT_MULTICHANNEL Flagbit aus, um anzugeben, dass ein einzelner Eigenschaftswert gleichmäßig auf alle Kanäle in einem Knoten angewendet wird. Wenn die Hardware beispielsweise nur ein einzelnes Steuerelement auf Volumeebene für alle Kanäle bereitstellt, legt der Basic-Support-Handler für den Volumeknoten das flag KSPROPERTY_MEMBER_FLAG_BASICSUPPORT_UNIFORM fest, um diese Einschränkung anzugeben. Wenn dieses Flag nicht festgelegt ist, kann die Lautstärke für jeden Kanal unabhängig von den Lautstärkepegeln für die anderen Kanäle gesteuert werden.

    Hinweis Das KSPROPERTY_MEMBER_FLAG_BASICSUPPORT_UNIFORM-Flag wird vom Windows Vista-Betriebssystem nicht verwendet.

In Miniporttreibern für Windows XP und höher sollte der Eigenschaftenhandler für einen Mehrkanalvolumeknoten das KSPROPERTY_MEMBER_FLAG_BASICSUPPORT_MULTICHANNEL Bit als Antwort auf eine KSPROPERTY_AUDIO_VOLUMELEVEL Basic-Support-Abfrage festlegen. Der Handler gibt ein Array von KSPROPERTY_STEPPING_LONG Strukturen zurück - eine für jeden kanal, der vom knoten verfügbar gemacht wird - und legt MembersSize auf sizeof(KSPROPERTY_STEPPING_LONG) fest. Jedes Arrayelement beschreibt die minimale und maximale Lautstärke eines Kanals sowie das Delta zwischen aufeinanderfolgenden Werten im Bereich. Für jeden einzelnen Kanal kann ein anderer Bereich angegeben werden, damit Kanäle mit nicht gleichmäßigen Bereichen korrekt verfügbar gemacht werden können. Beispielsweise kann ein Subwooferkanal einen Bereich aufweisen, der sich von dem der anderen Kanäle unterscheidet.

Im folgenden Codebeispiel wird gezeigt, wie sie eine Grundlegende Unterstützungsabfrage für eine Audioeigenschaft mit nicht uniformen Eigenschaftenwerten behandeln. Variable pDescription in der ersten Codezeile unten verweist auf die KSPROPERTY_DESCRIPTION-Struktur am Anfang des Datenpuffers, in die der Handler die Grundlegenden Unterstützungsinformationen schreibt:

  //
  // 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);

Die folgende Abbildung zeigt das Layout des Datenpuffers für dieses Beispiel. Die pDescription-, pMembers- und pRange-Zeiger werden angezeigt, die auf ihre jeweiligen Offsets innerhalb des Puffers zeigen.

Diagramm, das das Layout eines Datenpuffers für eine Abfrage mit basisbasierter Unterstützung mit pDescription-, pMembers- und pRange-Zeigern veranschaulicht.

In diesem Beispiel legt der Handler MembersCount auf ulNumChannels, die Anzahl der Kanäle, fest. Die Größe des Bereichsarrays in Bytes ist

MemberSize * MembersCount

Beachten Sie, dass der Handler, wenn in diesem Beispiel das flag KSPROPERTY_MEMBER_FLAG_BASICSUPPORT_UNIFORM festgelegt würde, alle KSPROPERTY_STEPPING_LONG Strukturen im Array auf denselben Bereich festlegen würde.

Der Grundlegende Unterstützungshandler für die KSPROPERTY_AUDIO_BASS, KSPROPERTY_AUDIO_TREBLE oder KSPROPERTY_AUDIO_MID Eigenschaft eines Toneknotens funktioniert auf ähnliche Weise.

Wenn ein Mehrkanalknoten über eine Eigenschaft mit einem Kanaleigenschaftswert vom Typ BOOL verfügt, muss der Basic-Support-Handler Werte für ein Schrittbereichsarray ausfüllen. In diesem Fall legt der Handler die Member auf die Werte fest, die im folgenden Codebeispiel gezeigt werden. Zwei Beispiele für diesen Eigenschaftstyp sind die KSPROPERTY_AUDIO_MUTE-Eigenschaft eines stummgeschalteten Knotens und die KSPROPERTY_AUDIO_BASS_BOOST-Eigenschaft eines Tonknotens.

Im folgenden Codebeispiel wird gezeigt, wie die Basic-Support-Anforderung für einen Mehrkanalknoten im Fall einer Eigenschaft mit einem Kanaleigenschaftswert vom Typ BOOL behandelt wird:

  //
  // 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;
  }

Beachten Sie, dass im vorherigen Codebeispiel die FOR-Schleife eine Null (0) und eins (1) verwendet, um die Mindest- und Höchstwerte für die Kanalbereiche festzulegen. Dies liegt daran, dass wir einen Mehrkanalknoten mit einem Kanaleigenschaftswert vom Typ BOOL konfigurieren.

Wenn die Kanaleigenschaft einheitlich ist, kann ein bitweiser OR-Vorgang zwischen dem KSPROPERTY_MEMBER_FLAG_BASICSUPPORT_UNIFORM-Flag und dem KSPROPERTY_MEMBER_FLAG_BASICSUPPORT_MULTICHANNEL-Flag und dem Ergebnis ausgeführt werden, das dem pMembers-Flags-Member> zugewiesen ist. Dieser Wert wird verwendet, um anzugeben, dass die Hardware denselben Eigenschaftswert gleichmäßig auf alle Kanäle in einem Knoten anwendet.

Die Verwendung der KSPROPERTY_MEMBER_FLAG_UNIFORM- und KSPROPERTY_MEMBER_FLAG_MULTICHANNEL-Flags entfällt die Notwendigkeit, die Kanäle in Paare zu gruppieren und einen separaten Stereovolumeknoten für jedes Kanalpaar verfügbar zu machen, wie dies im Ac97-Beispieltreiber im Windows Driver Kit (WDK) geschieht. Da Windows-Versionen vor Windows XP diese Flags nicht unterstützen, muss der Basic-Support-Handler für Ihren Treiber die IPortClsVersion-Schnittstelle verwenden, um die Portcls.sys Version abzufragen, um zu bestimmen, ob diese Flags verwendet werden sollen.

Der Topologieparser (im Kernelmodus WDMAud-Systemtreiber, Wdmaud.sys) ruft die Topologie eines Audiogeräts vom WDM-Audiotreiber ab. Der Parser macht dieses Gerät als herkömmliches Mixergerät über die Legacy-Windows Multimedia-Mixer-API verfügbar. In Windows XP und höher verwendet WDMAud das flag KSPROPERTY_MEMBER_FLAG_BASICSUPPORT_MULTICHANNEL, um die Anzahl der Kanäle zu bestimmen, die im cChannels-Member der MIXERLINE-Struktur gemeldet werden sollen. Wenn der Basic-Support-Handler des Knotens das KSPROPERTY_MEMBER_FLAG_BASICSUPPORT_UNIFORM-Flag angibt, legt WDMAud außerdem das flag MIXERCONTROL_CONTROLF_UNIFORM in der entsprechenden MIXERCONTROL-Struktur fest. Mithilfe dieses Flags können Anwendungen bestimmen, ob sie jeden Kanal einzeln oder alle Kanäle einheitlich über ein master-Steuerelement anpassen können. Weitere Informationen zu MIXERCONTROL, MIXERLINE und der Mixer-API finden Sie in der Microsoft Windows SDK-Dokumentation.

In Windows XP und höher zeigt das SndVol32-Volume-Control-Programm (siehe SysTray und SndVol32) Steuerelemente für Mehrkanalgeräte an, wie in der folgenden Abbildung dargestellt.

Screenshot des Dialogfelds

Wenn SndVol32 eine Linie mit mehr als zwei Kanälen erkennt, ersetzt es das normale Schwenksteuerelement durch eine Schaltfläche mit der Bezeichnung Lautsprecherlautstärke, die über dem Standard Lautstärkeregler in der vorherigen Abbildung angezeigt wird. Wenn Sie auf die Schaltfläche Lautsprecherlautstärke klicken, wird ein Dialogfeld geöffnet, in dem Steuerelemente für alle Kanäle für eine bestimmte Zeile angezeigt werden, wie in der folgenden Abbildung dargestellt.

Screenshot des Dialogfelds

Da die Mixer-API Kanäle nach Nummer verfügbar macht, leitet sie die Kanalnamen aus der Lautsprecherkonfiguration ab, die derzeit im Dialogfeld Erweiterte Audioeigenschaften in der Windows-Multimedia-Systemsteuerung (Mmsys.cpl) ausgewählt ist.

Wenn ein Gerät beispielsweise vier Kanäle in einer Zeile verfügbar macht und der Benutzer "Quadraphonic speakers" ausgewählt hat, sind die Kanalnamen "Left" (Kanal 0), "Right" (Kanal 1), "Back Left" (Kanal 2) und "Back Right" (Kanal 3), wie in der vorherigen Abbildung dargestellt. Wenn Sie die Lautsprecherkonfiguration in "Surround-Soundlautsprecher" ändern, wird eine Kanalzuordnung von "Left" (Kanal 0), "Right" (Kanal 1), "Front Center" (Kanal 2) und "Back Center" (Kanal 3) erstellt.

Auf Treiberebene verwendet die KSPROPERTY_AUDIO_CHANNEL_CONFIG-Eigenschaft einen Maskenwert von KSAUDIO_SPEAKER_QUAD oder KSAUDIO_SPEAKER_SURROUND, um eine quadraphonische oder Surround-Lautsprecherkonfiguration darzustellen. Die Headerdatei Ksmedia.h definiert diese Werte wie folgt:

  #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)

Jede Maske enthält vier Bits, die die Sprecherpositionen der vier Kanäle angeben. In beiden Fällen identifiziert die eigenschaft KSPROPERTY_AUDIO_VOLUMELEVEL dieselben vier Kanäle als Kanäle 0, 1, 2 und 3.

Wenn der Basic-Support-Handler des Knotens das KSPROPERTY_MEMBER_FLAG_BASICSUPPORT_UNIFORM-Flag-Bit festlegt, werden die im Dialogfeld Lautsprecherlautstärke angezeigten Schieberegler im Einklang mit Änderungen an einem einzelnen Schieberegler verschoben.