共用方式為


Jack 描述屬性

在 Windows Vista 和更新版本中, KSPROPERTY_JACK_DESCRIPTION 屬性描述音訊配接器上的音訊插孔或其他實體連接器。 屬性值描述插孔的色彩、插孔的實體位置、連接器類型和其他插孔功能。 此資訊的目的是要協助使用者尋找正確的插孔,以插入音訊端點裝置,例如麥克風、耳機或喇叭。 如需詳細資訊,請參閱 音訊端點裝置

如果音訊適配卡上的 KS 過濾器支援 KSPROPERTY_JACK_DESCRIPTION 屬性,Windows 多媒體控制面板 Mmsys.cpl會顯示過濾器上橋接針的插孔資訊。 橋接針腳代表音訊端點裝置的連接(通常是插孔)。 雖然此屬性值包含針腳的資訊(或者更準確地說,是與針腳相關聯的插孔的資訊),但這個屬性是篩選器的屬性,而不是針腳的屬性。 如需網橋接點的詳細資訊,請參閱 音訊篩選圖形。 如需篩選屬性和釘選屬性的詳細資訊,請參閱 篩選、釘選和節點屬性

音訊應用程式可以在 DeviceTopology API 中呼叫 IKsJackDescription::GetJackDescription 方法來取得音訊端點裝置的 KSPROPERTY_JACK_DESCRIPTION 屬性值。 例如,應用程式可以使用插孔資訊來協助用戶區分插入綠色 XLR 插孔的麥克風與插入橙色 XLR 插孔的麥克風。 如需DeviceTopology API的詳細資訊,請參閱 裝置拓撲

Microsoft HD Audio 類別驅動程式會自動從 HD 音訊編解碼器中針腳組態緩存器讀取的數據建構KSPROPERTY_JACK_DESCRIPTION屬性值。 不過,任何以 KS 為基礎的音訊驅動程式都可以在其篩選自動化數據表中實作此屬性的支援。 如需 HD 音訊類別驅動程式的詳細資訊,請參閱 HD 音訊和 UAA。 如需針腳設定緩存器的詳細資訊,請參閱 高畫質音訊裝置的針腳設定指導方針 白皮書。

音訊端點裝置可以透過一個或多個插孔連接到橋接點。 例如,一組(雙通道)立體聲喇叭需要一個插孔,但一組 5.1 環繞音效喇叭需要三個插孔(假設每個插孔處理六個通道的兩個)。

每個插孔的描述都包含在 KSJACK_DESCRIPTION 結構中。 例如,具有一個插孔的音訊端點裝置KSPROPERTY_JACK_DESCRIPTION屬性值包含一個KSJACK_DESCRIPTION結構,但具有三個插孔的端點裝置的屬性值包含三個KSJACK_DESCRIPTION結構。 不論是哪一種情況,屬性值中的KSJACK_DESCRIPTION結構或結構前面都有指定屬性值大小的 KSMULTIPLE_ITEM 結構。 如需詳細資訊,請參閱 KSPROPERTY_JACK_DESCRIPTION

插孔資訊特別適用於協助用戶區分連線到多通道喇叭組態的插孔。 下列程式碼範例顯示一個 KSJACK_DESCRIPTION 結構陣列,音訊驅動程式用來描述一組 5.1 環繞喇叭的三個插孔:

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

如果音訊硬體可以偵測裝置是否已插入,驅動程式會動態更新此成員的值,以指出裝置目前是否插入 (TRUE) 或未插入 (FALSE

在上述程式代碼範例中,每個數位元素中的 IsConnected 成員會設定為 TRUE ,表示端點裝置已插入插孔。 不過,如果硬體缺少插孔存在偵測, IsConnected 必須一律設定為 TRUE,是否有裝置插入插孔。 為了消除由 TRUE 傳回值的雙重意義引起的混淆,用戶端應用程式可以呼叫 IKsJackDescription2::GetJackDescription2 來讀取 KSJACK_DESCRIPTION2 結構的 JackCapabilities 標誌。 如果此旗標已設定JACKDESC2_PRESENCE_DETECT_CAPABILITY位,表示端點實際上支援插孔存在偵測。 在此情況下, IsConnected 成員的值可以解譯為精確反映插孔的插入狀態。

出現在上述結構的 RGB 巨集定義於 Windows SDK 的頭檔 Wingdi.h 中。

此外,插孔描述的陣列可用來顯示兩個以上的插孔在功能上彼此相等。 在下列程式碼範例中,音效驅動程式將黃色 RCA 插孔和黑色數位光學插孔的描述合併成一個陣列,以告知使用者這兩個插孔傳輸相同的訊號:

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

在上述程式代碼範例中,兩個KSJACK_DESCRIPTION結構中的 ChannelMapping 成員值完全相同。

WDK 中的 “Simple” MSVAD 範例驅動程式(在範例目錄 Src\Audio\Msvad\Simple 中)可以調整以支援 KSPROPERTY_JACK_DESCRIPTION 屬性。 此範例驅動程式很方便示範屬性的使用,因為它不需要實際的硬體。 因此,它可以安裝在任何執行 Windows 的電腦上。 (不過,只有 Windows Vista 和更新版本的作系統提供KSPROPERTY_JACK_DESCRIPTION屬性的完整支援。如需此範例的詳細資訊,請參閱 Windows 驅動程式套件範例

簡單 MSVAD 範例的拓撲篩選器會定義三個橋接針腳。 下表列出這些針腳。

固定標識碼 說明

KSPIN_TOPO_SYNTHIN_SOURCE

MIDI 輸入插孔

KSPIN_TOPO_MIC_SOURCE

麥克風輸入插孔

KSPIN_TOPO_LINEOUT_DEST

立體聲喇叭輸出插孔

本主題的其餘部分說明如何修改 Simple MSVAD 範例驅動程式,以提供三個網橋接腳的插孔資訊。

首先,您可以指定這些針腳的插孔資訊,如下所示:

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

上述程式碼範例會將兩個擷取端子的 ChannelMapping 成員設定為 0。 只有類比轉譯針腳應該有非零 ChannelMapping 值。

簡單 MSVAD 範例的主要修改是將下列屬性處理程式新增至範例檔案中的拓撲迷你埠實作Mintopo.cpp:

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

上述程式代碼範例是指先前定義的三個KSJACK_DESCRIPTION變數-SynthIn_Jack、MicIn_Jack和LineOut_Jack。 如果客戶端查詢有效針腳的插孔描述過濾器,但該針腳不是橋接針腳(因此沒有插孔描述),查詢會成功(狀態代碼為STATUS_SUCCESS),但屬性處理程式會返回一個只包含KSMULTIPLE_ITEM結構的空插孔描述,不含其他內容。 如果用戶端指定錯誤的引腳識別碼(識別不存在的引腳),處理程式會傳回狀態代碼STATUS_INVALID_PARAMETER。

需要對簡單 MSVAD 範例進行兩項額外的修改,才能支援 KSPROPERTY_JACK_DESCRIPTION 屬性。 這些包括:

  • 將上述程式代碼範例中的 PropertyHandlerJackDescription 方法宣告新增至頭檔 Mintopo.h 中的 CMiniportTopology 類別定義。

  • 實作拓撲篩選的自動化數據表,並將此數據表的位址載入頭檔 Toptable.h 中PCFILTER_DESCRIPTOR結構的 AutomationTable 成員。 此結構名為 MiniportFilterDescriptor

若要實作篩選的自動化數據表,請將下列程序代碼插入頭檔 Toptable.h 中( 在 MiniportFilterDescriptor 定義之前):

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

DEFINE_PCAUTOMATION_TABLE_PROP(AutomationTopoFilter, PropertiesTopoFilter);

在上述程式代碼範例中,PCPROPERTY_ITEM 結構的 Handler 成員包含上一個步驟中新增至Mintopo.cpp之屬性處理程式的函式指標。 若要讓屬性處理程式可從頭檔存取,請在頭檔開頭插入PropertyHandler_TopoFilter的 extern 函式宣告。

如需有關 jack description 屬性的詳細資訊,請參閱 Dynamic Audio Subdevices 的 Jack Descriptions