Freigeben über


Jack Description-Eigenschaft

In Windows Vista und höher beschreibt die eigenschaft KSPROPERTY_JACK_DESCRIPTION eine Audiobuchse oder einen anderen physischen Anschluss an einem Audioadapter. Der -Eigenschaftswert beschreibt die Farbe der Buchse, die physische Position der Buchse, den Anschlusstyp und andere Klinkenfeatures. Der Zweck dieser Informationen besteht darin, dem Benutzer zu helfen, die richtige Buchse für das Anschließen eines Audioendpunktgeräts wie mikrofon, Kopfhörer oder Lautsprecher zu finden. Weitere Informationen finden Sie unter Audioendpunktgeräte.

Wenn ein KS-Filter auf einem Audioadapter die eigenschaft KSPROPERTY_JACK_DESCRIPTION unterstützt, zeigt die Windows-Multimedia-Systemsteuerung Mmsys.cpl die Klinkeninformationen für die Bridge-Pins im Filter an. Ein Bridge-Pin stellt eine Verbindung (in der Regel eine Buchse) mit einem Audioendpunktgerät dar. Obwohl der -Eigenschaftswert Informationen über einen Stift (oder besser gesagt, die Buchse oder Buchsen enthält, die dem Stift zugeordnet sind), ist die Eigenschaft eine Eigenschaft des Filters, nicht des Stifts. Weitere Informationen zu Bridge-Pins finden Sie unter Audiofiltergraphen. Weitere Informationen zu Filtereigenschaften und Anhefteigenschaften finden Sie unter Filter-, Pin- und Node-Eigenschaften.

Eine Audioanwendung kann den KSPROPERTY_JACK_DESCRIPTION-Eigenschaftswert für ein Audioendpunktgerät abrufen, indem sie die IKsJackDescription::GetJackDescription-Methode in der DeviceTopology-API aufruft. Beispielsweise kann eine Anwendung die Klinkeninformationen verwenden, um dem Benutzer zu helfen, ein Mikrofon zu unterscheiden, das an eine grüne XLR-Buchse angeschlossen ist, von einem Mikrofon, das an eine orangefarbene XLR-Buchse angeschlossen ist. Weitere Informationen zur DeviceTopology-API finden Sie unter Gerätetopologien.

Der Microsoft HD Audio-Klassentreiber erstellt automatisch die KSPROPERTY_JACK_DESCRIPTION-Eigenschaftswerte aus den Daten, die er aus den Pinkonfigurationsregistern in einem HD-Audiocodec liest. Allerdings kann jeder KS-basierte Audiotreiber unterstützung für diese Eigenschaft in seinen Filterautomatisierungstabellen implementieren. Weitere Informationen zum HD Audio-Klassentreiber finden Sie unter HD Audio und UAA. Weitere Informationen zu Pinkonfigurationsregistern finden Sie im Whitepaper Pin Configuration Guidelines for High Definition Audio Devices ( Pin Configuration Guidelines for High Definition Audio Devices ).

Ein Audioendpunktgerät kann über eine oder mehrere Buchsen eine Verbindung mit einem Bridge-Pin herstellen. Beispielsweise erfordert ein Satz von Stereolautsprechern (zwei Kanäle) eine Buchse, aber ein Satz von 5.1-Surround-Sound-Lautsprechern erfordert drei Buchsen (vorausgesetzt, dass jede Buchse zwei der sechs Kanäle übernimmt).

Die Beschreibung für jede Buchse ist in einer KSJACK_DESCRIPTION-Struktur enthalten. Beispielsweise enthält der KSPROPERTY_JACK_DESCRIPTION-Eigenschaftswert für ein Audioendpunktgerät mit einer Buchse eine KSJACK_DESCRIPTION-Struktur, aber der Eigenschaftswert für ein Endpunktgerät mit drei Buchsen enthält drei KSJACK_DESCRIPTION-Strukturen. In beiden Fällen wird den KSJACK_DESCRIPTION Strukturen im Eigenschaftswert eine KSMULTIPLE_ITEM-Struktur vorangestellt, die die Größe des Eigenschaftswerts angibt. Weitere Informationen finden Sie unter KSPROPERTY_JACK_DESCRIPTION.

Jack-Informationen sind besonders nützlich, um Benutzern zu helfen, zwischen den Buchsen zu unterscheiden, die eine Verbindung mit einer Multichannel-Lautsprecherkonfiguration herstellen. Das folgende Codebeispiel zeigt ein Array von KSJACK_DESCRIPTION Strukturen, die ein Audiotreiber verwendet, um die drei Buchsen für einen Satz von 5.1-Surround-Lautsprechern zu beschreiben:

KSJACK_DESCRIPTION ar_5dot1_Jacks[] =
{
    // Jack 1
    {
        (SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT), // ChannelMapping (L,R)
        RGB(0,255,0),       // Color (green)
        eConnType3Point5mm, // ConnectionType
        eGeoLocRear,        // GeoLocation
        eGenLocPrimaryBox,  // GenLocation
        ePortConnJack,      // PortConnection
        TRUE                // IsConnected
    },
    // Jack 2
    {
        (SPEAKER_FRONT_CENTER | SPEAKER_LOW_FREQUENCY), // (C,Sub)
        RGB(0,0,255),       // (red)
        eConnType3Point5mm,
        eGeoLocRear,
        eGenLocPrimaryBox,
        ePortConnJack,
        TRUE
    },
    // Jack 3
    {
        (SPEAKER_SIDE_LEFT | SPEAKER_SIDE_RIGHT),  // (SL,SR)
        RGB(0,255,255),     // (yellow)
        eConnType3Point5mm,
        eGeoLocRear,
        eGenLocPrimaryBox,
        ePortConnJack,
        TRUE
    }
};

Wenn die Audiohardware erkennen kann, ob das Gerät angeschlossen ist, aktualisiert der Treiber dynamisch den Wert dieses Members, um anzugeben, ob das Gerät derzeit eingesteckt (TRUE) oder unplugged (FALSE) ist.

Im vorherigen Codebeispiel ist der IsConnected-Member in jedem Arrayelement auf TRUE festgelegt, um anzugeben, dass das Endpunktgerät an die Buchse angeschlossen ist. Wenn die Hardware jedoch keine Buchse-Anwesenheitserkennung aufweist, muss IsConnected immer auf TRUE festgelegt werden, unabhängig davon, ob ein Gerät an die Buchse angeschlossen ist. Um die Mehrdeutigkeit zu entfernen, die sich aus dieser doppelten Bedeutung des TRUE-Rückgabewerts ergibt, kann eine Clientanwendung IKsJackDescription2::GetJackDescription2 aufrufen, um das JackCapabilities-Flag der KSJACK_DESCRIPTION2-Struktur zu lesen. Wenn für dieses Flag das JACKDESC2_PRESENCE_DETECT_CAPABILITY Bit festgelegt ist, gibt dies an, dass der Endpunkt tatsächlich die Erkennung der Jack-Anwesenheit unterstützt. In diesem Fall kann der Wert des IsConnected-Elements als genaue Spiegelung der einfüge status der Buchse interpretiert werden.

Das RGB-Makro, das in den vorherigen Strukturen angezeigt wird, ist in der Headerdatei Wingdi.h im Windows SDK definiert.

Darüber hinaus kann ein Array von Jack-Beschreibungen verwendet werden, um zu zeigen, dass zwei oder mehr Buchsen funktional gleichwertig sind. Im folgenden Codebeispiel kombiniert der Audiotreiber die Beschreibungen der Buchse für eine gelbe Rca-Buchse und eine schwarze digital-optische Buchse in einem Array, um dem Benutzer anzuzeigen, dass die beiden Buchsen das gleiche Signal aufweisen:

KSJACK_DESCRIPTION ar_SPDIF_Jacks[] =
{
    // Jack 1
    {
        (SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT), // ChannelMapping (L,R)
        RGB(0,255,255),         // Color (yellow)
        eConnTypeRCA,           // ConnectionType (RCA)
        eGeoLocRear,            // GeoLocation
 eGenLocPrimaryBox,   // GenLocation
        ePortConnJack,       // PortConnection
        TRUE                    // IsConnected
    },
    // Jack 2
    {
        (SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT), // (L,R)
        RGB(0,0,0),             // (black)
        eConnTypeOptical,       // (optical)
        eGeoLocRear,
 eGenLocPrimaryBox,
        ePortConnJack,
        TRUE
    }
};

Im vorherigen Codebeispiel sind die Werte der ChannelMapping-Member in den beiden KSJACK_DESCRIPTION-Strukturen identisch.

Der MSVAD-Beispieltreiber "Simple" im WDK (im Beispielverzeichnis Src\Audio\Msvad\Simple) kann angepasst werden, um die eigenschaft KSPROPERTY_JACK_DESCRIPTION zu unterstützen. Dieser Beispieltreiber eignet sich für die Veranschaulichung der Verwendung der -Eigenschaft, da er keine tatsächliche Hardware erfordert. Daher kann es auf jedem Computer installiert werden, auf dem Windows ausgeführt wird. (Allerdings bieten nur Windows Vista und höhere Betriebssysteme vollständige Unterstützung für die KSPROPERTY_JACK_DESCRIPTION-Eigenschaft.) Weitere Informationen zu diesem Beispiel finden Sie unter Beispiele für das Windows Driver Kit.

Der Topologiefilter für das Einfache MSVAD-Beispiel definiert drei Brückenstifte. Diese Pins sind in der folgenden Tabelle aufgeführt.

Pin-ID BESCHREIBUNG

KSPIN_TOPO_SYNTHIN_SOURCE

MIDI-Eingangsbuchse

KSPIN_TOPO_MIC_SOURCE

Mikrofoneingangsbuchse

KSPIN_TOPO_LINEOUT_DEST

Stereolautsprecherausgangsbuchse

Im weiteren Verlauf dieses Themas wird erläutert, wie Sie den Einfachen MSVAD-Beispieltreiber so ändern, dass er die Klinkeninformationen für die drei Brückenstifte bereitstellt.

Zunächst können die Klinkeninformationen für diese Pins wie folgt angegeben werden:

// Describe MIDI input jack (pin ID = KSPIN_TOPO_SYNTHIN_SOURCE).
static KSJACK_DESCRIPTION SynthIn_Jack[] =
{
    {
        0,                  // ChannelMapping
        RGB(255,255,0),    // Color (cyan)
 eConnType3Point5mm, // ConnectionType
        eGeoLocRear,        // GeoLocation
        eGenLocPrimaryBox,  // GenLocation
        ePortConnJack,      // PortConnection
        TRUE                // IsConnected
    }
};

// Describe microphone jack (pin ID = KSPIN_TOPO_MIC_SOURCE).
static KSJACK_DESCRIPTION MicIn_Jack[] =
{
    {
        0,
        RGB(0,128,255),   // (orange)
 eConnType3Point5mm,
        eGeoLocFront,
        eGenLocPrimaryBox,
        ePortConnJack,
        TRUE
    }
};

// Describe stereo speaker jack (pin ID = KSPIN_TOPO_LINEOUT_DEST).
static KSJACK_DESCRIPTION LineOut_Jack[] =
{
    {
        (SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT), // ChannelMapping (L,R)
        RGB(0,255,0),       // (green)
 eConnType3Point5mm,
        eGeoLocRear,
        eGenLocPrimaryBox,
        ePortConnJack,
        TRUE
    }
};

Im vorherigen Codebeispiel werden die ChannelMapping-Member für die beiden Aufnahmepins auf 0 festgelegt. Nur analoge Renderingpins sollten ChannelMapping-Werte ungleich null aufweisen.

Die primäre Änderung am Simple MSVAD-Beispiel besteht darin, der Implementierung des Topologieminiports in der Beispieldatei Mintopo.cpp den folgenden Eigenschaftenhandler hinzuzufügen:

#define ARRAY_LEN(a)  sizeof(a)/sizeof(a[0]);
#define MAXIMUM_VALID_PIN_ID  KSPIN_TOPO_WAVEIN_DEST

NTSTATUS
CMiniportTopology::PropertyHandlerJackDescription(
               IN PPCPROPERTY_REQUEST PropertyRequest)
{
    PAGED_CODE();

    ASSERT(PropertyRequest);

    DPF_ENTER(("[PropertyHandlerJackDescription]"));

    NTSTATUS ntStatus = STATUS_INVALID_DEVICE_REQUEST;
    ULONG nPinId = (ULONG)-1;

    if (PropertyRequest->InstanceSize >= sizeof(ULONG))
    {
        nPinId = *((PULONG)(PropertyRequest->Instance));

        if (nPinId > MAXIMUM_VALID_PIN_ID)
        {
            ntStatus = STATUS_INVALID_PARAMETER;
        }
        else if (PropertyRequest->Verb & KSPROPERTY_TYPE_BASICSUPPORT)
        {
            ntStatus = PropertyHandler_BasicSupport(
                            PropertyRequest,
                            KSPROPERTY_TYPE_BASICSUPPORT | KSPROPERTY_TYPE_GET,
                            VT_ILLEGAL);
        }
        else
        {
            PKSJACK_DESCRIPTION pJack = NULL;
            ULONG cJacks = 0;

            switch (nPinId)
            {
            case KSPIN_TOPO_SYNTHIN_SOURCE:
                pJack = SynthIn_Jack;
                cJacks = ARRAY_LEN(SynthIn_Jack);
                break;
            case KSPIN_TOPO_MIC_SOURCE:
                pJack = MicIn_Jack;
                cJacks = ARRAY_LEN(MicIn_Jack);
                break;
            case KSPIN_TOPO_LINEOUT_DEST:
                pJack = LineOut_Jack;
                cJacks = ARRAY_LEN(LineOut_Jack);
                break;
            default:
                break;
            }

            ULONG cbNeeded = sizeof(KSMULTIPLE_ITEM) +
                             sizeof(KSJACK_DESCRIPTION) * cJacks;

            if (PropertyRequest->ValueSize == 0)
            {
                PropertyRequest->ValueSize = cbNeeded;
                ntStatus = STATUS_BUFFER_OVERFLOW;
            }
            else if (PropertyRequest->ValueSize < cbNeeded)
            {
                ntStatus = STATUS_BUFFER_TOO_SMALL;
            }
            else if (PropertyRequest->Verb & KSPROPERTY_TYPE_GET)
            {
                PKSMULTIPLE_ITEM pMI = (PKSMULTIPLE_ITEM)PropertyRequest->Value;

                pMI->Size = cbNeeded;
                pMI->Count = cJacks;

                // Copy jack description structure into Value buffer.
                // RtlCopyMemory correctly handles the case Length=0.
                PKSJACK_DESCRIPTION pDesc = (PKSJACK_DESCRIPTION)(pMI + 1);

                RtlCopyMemory(pDesc, pJack, pMI->Size * pMI->Count);

                ntStatus = STATUS_SUCCESS;
            }
        }
    }

    return ntStatus;
}

NTSTATUS
PropertyHandler_TopoFilter(IN PPCPROPERTY_REQUEST PropertyRequest)
{
    PAGED_CODE();

    ASSERT(PropertyRequest);

    DPF_ENTER(("[PropertyHandler_TopoFilter]"));

    // PropertyRequest structure is filled by PortCls.
    // MajorTarget is a pointer to miniport object for miniports.
    //
    NTSTATUS ntStatus = STATUS_INVALID_DEVICE_REQUEST;
    PCMiniportTopology pMiniport = (PCMiniportTopology)PropertyRequest->MajorTarget;

    if (IsEqualGUIDAligned(*PropertyRequest->PropertyItem->Set, KSPROPSETID_Jack) &&
        (PropertyRequest->PropertyItem->Id == KSPROPERTY_JACK_DESCRIPTION))
    {
        ntStatus = pMiniport->PropertyHandlerJackDescription(PropertyRequest);
    }

    return ntStatus;
}

Das vorangehende Codebeispiel bezieht sich auf die drei zuvor definierten KSJACK_DESCRIPTION Variablen SynthIn_Jack, MicIn_Jack und LineOut_Jack. Wenn der Client den Filter für die Buchsenbeschreibung eines gültigen Pins abfragt, der jedoch kein Bridge-Pin ist (und daher keine Buchsenbeschreibung aufweist), ist die Abfrage erfolgreich (mit status Code STATUS_SUCCESS), aber der Eigenschaftenhandler gibt eine leere Jack-Beschreibung zurück, die aus einer KSMULTIPLE_ITEM-Struktur und nichts anderem besteht. Wenn der Client eine ungültige Pin-ID angibt (die eine nicht vorhandene Pin identifiziert), gibt der Handler status Code STATUS_INVALID_PARAMETER zurück.

Zwei zusätzliche Änderungen am Simple MSVAD-Beispiel sind erforderlich, um die KSPROPERTY_JACK_DESCRIPTION-Eigenschaft zu unterstützen. Diese lauten wie folgt:

  • Fügen Sie die Deklaration der PropertyHandlerJackDescription-Methode im vorherigen Codebeispiel der CMiniportTopology-Klassendefinition in der Headerdatei Mintopo.h hinzu.

  • Implementieren Sie eine Automatisierungstabelle für den Topologiefilter, und laden Sie die Adresse dieser Tabelle in das AutomationTable-Element der PCFILTER_DESCRIPTOR-Struktur in der Headerdatei Toptable.h. Diese Struktur heißt MiniportFilterDescriptor.

Um die Automatisierungstabelle für den Filter zu implementieren, fügen Sie den folgenden Code in die Headerdatei Toptable.h ein (vor der Definition von MiniportFilterDescriptor):

static PCPROPERTY_ITEM PropertiesTopoFilter[] =
{
    {
        &KSPROPSETID_Jack,
        KSPROPERTY_JACK_DESCRIPTION,
        KSPROPERTY_TYPE_GET | KSPROPERTY_TYPE_BASICSUPPORT,
        PropertyHandler_TopoFilter
    }
};

DEFINE_PCAUTOMATION_TABLE_PROP(AutomationTopoFilter, PropertiesTopoFilter);

Im vorherigen Codebeispiel enthält der Handler-Member der PCPROPERTY_ITEM-Struktur einen Funktionszeiger auf den Eigenschaftenhandler, der mintopo.cpp in einem vorherigen Schritt hinzugefügt wurde. Um den Zugriff auf den Eigenschaftenhandler über die Headerdatei zu ermöglichen, fügen Sie am Anfang der Headerdatei eine externe Funktionsdeklaration für PropertyHandler_TopoFilter ein.

Weitere Informationen zur Jack description-Eigenschaft finden Sie unter Jack Descriptions for Dynamic Audio Subdevices.For more information about the jack descriptions property, see Jack Descriptions for Dynamic Audio Subdevices.