Compartilhar via


Propriedade Jack Description

No Windows Vista e posteriores, a propriedade KSPROPERTY_JACK_DESCRIPTION descreve uma tomada de áudio ou outro conector físico em um adaptador de áudio. O valor da propriedade descreve a cor da tomada, o local físico da tomada, o tipo de conector e outros recursos de tomada. A finalidade dessas informações é ajudar o usuário a encontrar a tomada correta para conectar um dispositivo de ponto de extremidade de áudio, como microfone, fones de ouvido ou alto-falantes. Para obter mais informações, consulte Dispositivos de ponto de extremidade de áudio.

Se um filtro KS em um adaptador de áudio der suporte à propriedade KSPROPERTY_JACK_DESCRIPTION, o painel de controle multimídia do Windows, Mmsys.cpl, exibirá as informações de tomada para os pinos de ponte no filtro. Um pino de ponte representa uma conexão (normalmente, uma tomada) com um dispositivo de ponto de extremidade de áudio. Embora o valor da propriedade contenha informações sobre um pino (ou melhor, a tomada ou as tomadas associadas ao pino), a propriedade é uma propriedade do filtro, não do pino. Para obter mais informações sobre pinos de ponte, consulte Grafos de filtro de áudio. Para obter mais informações sobre propriedades de filtro e propriedades de fixação, consulte Filtrar, Fixar e Propriedades do Nó.

Um aplicativo de áudio pode obter o valor da propriedade KSPROPERTY_JACK_DESCRIPTION para um dispositivo de ponto de extremidade de áudio chamando o método IKsJackDescription::GetJackDescription na API DeviceTopology. Por exemplo, um aplicativo pode usar as informações de tomada para ajudar o usuário a distinguir um microfone conectado a uma tomada XLR verde de um microfone conectado a uma tomada XLR laranja. Para obter mais informações sobre a API DeviceTopology, consulte Topologias de dispositivo.

O driver de classe de Áudio HD da Microsoft constrói automaticamente os valores da propriedade KSPROPERTY_JACK_DESCRIPTION a partir dos dados que ele lê dos registros de configuração de pin em um codec de áudio HD. No entanto, qualquer driver de áudio baseado em KS pode implementar suporte para essa propriedade em suas tabelas de automação de filtro. Para obter mais informações sobre o driver de classe de áudio HD, consulte Áudio HD e UAA. Para obter mais informações sobre registros de configuração de pin, consulte o white paper Diretrizes de configuração de pin para dispositivos de áudio de alta definição .

Um dispositivo de ponto de extremidade de áudio pode se conectar a um pino de ponte por meio de uma ou mais tomadas. Por exemplo, um conjunto de alto-falantes estéreo (de dois canais) requer uma tomada, mas um conjunto de alto-falantes de som surround 5.1 requer três tomadas (supondo que cada tomada manipule dois dos seis canais).

A descrição de cada tomada está contida em uma estrutura KSJACK_DESCRIPTION . Por exemplo, o valor da propriedade KSPROPERTY_JACK_DESCRIPTION para um dispositivo de ponto de extremidade de áudio com uma tomada contém uma estrutura KSJACK_DESCRIPTION, mas o valor da propriedade de um dispositivo de ponto de extremidade com três tomadas contém três estruturas KSJACK_DESCRIPTION. Em ambos os casos, a estrutura KSJACK_DESCRIPTION ou estruturas no valor da propriedade são precedidas por uma estrutura KSMULTIPLE_ITEM que especifica o tamanho do valor da propriedade. Para obter mais informações, consulte KSPROPERTY_JACK_DESCRIPTION.

As informações de jack são particularmente úteis para ajudar os usuários a distinguir entre as tomadas que se conectam a uma configuração de alto-falante multicanal. O exemplo de código a seguir mostra uma matriz de estruturas de KSJACK_DESCRIPTION que um driver de áudio usa para descrever as três tomadas para um conjunto de alto-falantes surround 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
    }
};

Se o hardware de áudio puder detectar se o dispositivo está conectado, o driver atualizará dinamicamente o valor desse membro para indicar se o dispositivo está conectado atualmente (TRUE) ou desconectado (FALSE)

No exemplo de código anterior, o membro IsConnected em cada elemento de matriz é definido como TRUE para indicar que o dispositivo de ponto de extremidade está conectado à tomada. No entanto, se o hardware não tiver detecção de presença de tomada, IsConnected sempre deverá ser definido como TRUE, independentemente de haver um dispositivo conectado à tomada. Para remover a ambiguidade resultante desse duplo significado do valor retornado TRUE , um aplicativo cliente pode chamar IKsJackDescription2::GetJackDescription2 para ler o sinalizador JackCapabilities da estrutura KSJACK_DESCRIPTION2 . Se esse sinalizador tiver o JACKDESC2_PRESENCE_DETECT_CAPABILITY bit definido, ele indicará que o ponto de extremidade de fato dá suporte à detecção de presença de jack. Nesse caso, o valor do membro IsConnected pode ser interpretado como um reflexo preciso da inserção status da tomada.

A macro RGB que aparece nas estruturas anteriores é definida no arquivo de cabeçalho Wingdi.h no SDK do Windows.

Além disso, uma matriz de descrições de jack pode ser usada para mostrar que duas ou mais tomadas são funcionalmente equivalentes umas às outras. No exemplo de código a seguir, o driver de áudio combina as descrições de tomada para uma tomada RCA amarela e para uma tomada digital-óptica preta em uma matriz para indicar ao usuário que as duas tomadas carregam o mesmo sinal:

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

No exemplo de código anterior, os valores dos membros ChannelMapping nas duas estruturas KSJACK_DESCRIPTION são idênticos.

O driver de exemplo "Simples" do MSVAD no WDK (no diretório de exemplo Src\Audio\Msvad\Simple) pode ser adaptado para dar suporte à propriedade KSPROPERTY_JACK_DESCRIPTION. Este driver de exemplo é conveniente para demonstrar o uso da propriedade porque ela não requer hardware real. Assim, ele pode ser instalado em qualquer computador que execute o Windows. (No entanto, somente o Windows Vista e sistemas operacionais posteriores fornecem suporte total para a propriedade KSPROPERTY_JACK_DESCRIPTION.) Para obter mais informações sobre este exemplo, consulte Exemplos do Kit de Driver do Windows.

O filtro de topologia para o exemplo msvad simples define três pinos de ponte. Esses pinos são listados na tabela a seguir.

ID do pino Descrição

KSPIN_TOPO_SYNTHIN_SOURCE

Entrada MIDI

KSPIN_TOPO_MIC_SOURCE

Tomada de entrada do microfone

KSPIN_TOPO_LINEOUT_DEST

Tomada de saída do alto-falante estéreo

O restante deste tópico explica como modificar o driver de exemplo msvad simples para fornecer as informações de tomada para os três pinos de ponte.

Primeiro, as informações de tomada para esses pinos podem ser especificadas da seguinte maneira:

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

O exemplo de código anterior define os membros ChannelMapping para os dois pinos de captura como 0. Somente os pinos de renderização analógicos devem ter valores ChannelMapping diferentes de zero.

A principal modificação no exemplo msvad simples é adicionar o seguinte manipulador de propriedades à implementação do miniporto de topologia no arquivo de exemplo 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;
}

O exemplo de código anterior refere-se às três variáveis de KSJACK_DESCRIPTION - SynthIn_Jack, MicIn_Jack e LineOut_Jack - que foram definidas anteriormente. Se o cliente consultar o filtro para a descrição da tomada de um pino válido, mas um que não seja um pino de ponte (e, portanto, não tiver nenhuma descrição de tomada), a consulta terá êxito (com status código STATUS_SUCCESS), mas o manipulador de propriedades retornará uma descrição de tomada vazia que consiste em uma estrutura KSMULTIPLE_ITEM e nada mais. Se o cliente especificar uma ID de pin inválida (que identifica um pino inexistente), o manipulador retornará status código STATUS_INVALID_PARAMETER.

Duas modificações adicionais no exemplo MSVAD Simples são necessárias para dar suporte à propriedade KSPROPERTY_JACK_DESCRIPTION. Eles são:

  • Adicione a declaração do método PropertyHandlerJackDescription no exemplo de código anterior à definição da classe CMiniportTopology no arquivo de cabeçalho Mintopo.h.

  • Implemente uma tabela de automação para o filtro de topologia e carregue o endereço dessa tabela no membro AutomationTable da estrutura PCFILTER_DESCRIPTOR no arquivo de cabeçalho Toptable.h. Essa estrutura se chama MiniportFilterDescriptor.

Para implementar a tabela de automação para o filtro, insira o seguinte código no arquivo de cabeçalho Toptable.h (antes da definição de MiniportFilterDescriptor):

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

DEFINE_PCAUTOMATION_TABLE_PROP(AutomationTopoFilter, PropertiesTopoFilter);

No exemplo de código anterior, o membro Handler da estrutura PCPROPERTY_ITEM contém um ponteiro de função para o manipulador de propriedades que foi adicionado a Mintopo.cpp em uma etapa anterior. Para tornar o manipulador de propriedades acessível a partir do arquivo de cabeçalho, insira uma declaração de função extern para PropertyHandler_TopoFilter no início do arquivo de cabeçalho.

Para obter mais informações sobre a propriedade jack description, consulte Jack Descriptions for Dynamic Audio Subdevices.