Описание Джека
В Windows Vista и более поздних версиях свойство KSPROPERTY_JACK_DESCRIPTION описывает аудиоразъем или другой физический соединитель на звуковом адаптере. Значение свойства описывает цвет разъема, физическое расположение разъема, тип соединителя и другие функции разъема. Эта информация предназначена для того, чтобы помочь пользователю найти правильный разъем для подключения к звуковому устройству конечной точки, например микрофону, наушникам или динамикам. Дополнительные сведения см. в разделе Аудиоустройства конечных точек.
Если фильтр KS на звуковом адаптере поддерживает свойство KSPROPERTY_JACK_DESCRIPTION, панель управления мультимедиа Windows Mmsys.cpl отображает сведения о разъеме для контактов моста на фильтре. Контакт моста представляет собой подключение (обычно это разъем) к устройству конечной точки аудио. Хотя значение свойства содержит сведения о контакте (или, скорее, о разъемах или разъемах, связанных с контактом), свойство является свойством фильтра, а не контакта. Дополнительные сведения о контактах моста см. в разделе Графы фильтра аудио. Дополнительные сведения о свойствах фильтра и закрепления см. в разделе Свойства фильтра, закрепления и узла.
Звуковое приложение может получить значение свойства KSPROPERTY_JACK_DESCRIPTION для устройства конечной точки аудио, вызвав метод IKsJackDescription::GetJackDescription в API DeviceTopology. Например, приложение может использовать сведения о разъеме, чтобы помочь пользователю отличить микрофон, подключенный к зеленому разъему XLR, от микрофона, подключенного к оранжевому разъему XLR. Дополнительные сведения об API DeviceTopology см. в разделе Топологии устройств.
Драйвер класса Microsoft HD Audio автоматически создает значения свойств KSPROPERTY_JACK_DESCRIPTION из данных, которые он считывает из регистров конфигурации пин-кода в кодеке HD Audio. Однако любой аудиодрайдер на основе KS может реализовать поддержку этого свойства в таблицах автоматизации фильтров. Дополнительные сведения о драйвере класса HD Audio см. в разделе HD Audio и 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 для чтения флага JackCapabilities структуры KSJACK_DESCRIPTION2 . Если для этого флага задан бит JACKDESC2_PRESENCE_DETECT_CAPABILITY, это означает, что конечная точка фактически поддерживает обнаружение присутствия разъема. В этом случае значение члена IsConnected можно интерпретировать как точное отражение состояния вставки разъема.
Макрос RGB, который отображается в предыдущих структурах, определен в файле заголовка Wingdi.h в windows SDK.
Кроме того, можно использовать массив описаний разъемов, чтобы показать, что два или более разъемов функционально эквивалентны друг другу. В следующем примере кода звуковой драйвер объединяет описания разъема для желтого разъема 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
}
};
В предыдущем примере кода значения членов ChannelMapping в двух KSJACK_DESCRIPTION структурах идентичны.
Пример драйвера "Simple" MSVAD в WDK (в каталоге примеров Src\Audio\Msvad\Simple) можно адаптировать для поддержки свойства KSPROPERTY_JACK_DESCRIPTION. Этот пример драйвера удобен для демонстрации использования свойства , так как для него не требуется фактическое оборудование. Таким образом, его можно установить на любой компьютер под управлением Windows. (Однако только Windows Vista и более поздние операционные системы обеспечивают полную поддержку свойства KSPROPERTY_JACK_DESCRIPTION.) Дополнительные сведения об этом примере см. в разделе Примеры комплекта драйверов Для Windows.
Фильтр топологии для примера Simple 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 .
Основное изменение примера Simple 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.
Для поддержки свойства KSPROPERTY_JACK_DESCRIPTION требуются два дополнительных изменения в примере Simple MSVAD. А именно:
Добавьте объявление метода PropertyHandlerJackDescription в предыдущем примере кода в определение класса CMiniportTopology в файле заголовка Mintopo.h.
Реализуйте таблицу автоматизации для фильтра топологии и загрузите адрес этой таблицы в элемент AutomationTableструктуры PCFILTER_DESCRIPTOR в файле заголовка Toptable.h. Эта структура называется 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);
В предыдущем примере кода элемент Handler структуры PCPROPERTY_ITEM содержит указатель функции на обработчик свойств, добавленный в Mintopo.cpp на предыдущем шаге. Чтобы сделать обработчик свойств доступным из файла заголовка, вставьте объявление функции extern для PropertyHandler_TopoFilter в начале файла заголовка.
Дополнительные сведения о свойстве описания разъема см. в разделе Описание джека для динамических аудиоподделений.