Jack Description 속성
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 Audio 클래스 드라이버에 대한 자세한 내용은 HD 오디오 및 UAA를 참조하세요. 핀 구성 레지스터에 대한 자세한 내용은 고화질 오디오 디바이스에 대한 핀 구성 지침 백서를 참조하세요.
오디오 엔드포인트 디바이스는 하나 이상의 잭을 통해 브리지 핀에 연결할 수 있습니다. 예를 들어(2 채널) 스테레오 스피커 집합에는 하나의 잭이 필요하지만 5.1 서라운드 사운드 스피커 집합에는 3개의 잭이 필요합니다(각 잭이 6개 채널 중 2개를 처리한다고 가정).
각 잭에 대한 설명은 KSJACK_DESCRIPTION 구조에 포함되어 있습니다. 예를 들어 하나의 잭이 있는 오디오 엔드포인트 디바이스의 KSPROPERTY_JACK_DESCRIPTION 속성 값에는 하나의 KSJACK_DESCRIPTION 구조가 포함되지만, 3개의 잭이 있는 엔드포인트 디바이스의 속성 값에는 세 개의 KSJACK_DESCRIPTION 구조가 포함됩니다. 두 경우 모두 속성 값의 KSJACK_DESCRIPTION 구조체 또는 구조체 앞에는 속성 값의 크기를 지정하는 KSMULTIPLE_ITEM 구조체가 있습니다. 자세한 내용은 KSPROPERTY_JACK_DESCRIPTION 참조하세요.
잭 정보는 사용자가 멀티채널 스피커 구성에 연결하는 잭을 구분하는 데 특히 유용합니다. 다음 코드 예제에서는 오디오 드라이버가 5.1 서라운드 스피커 집합에 대한 3개의 잭을 설명하는 데 사용하는 KSJACK_DESCRIPTION 구조의 배열을 보여 줍니다.
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 드라이버 키트 샘플을 참조하세요.
Simple MSVAD 샘플에 대한 토폴로지 필터는 세 개의 브리지 핀을 정의합니다. 이러한 핀은 다음 표에 나와 있습니다.
핀 ID | Description |
---|---|
KSPIN_TOPO_SYNTHIN_SOURCE |
MIDI 입력 잭 |
KSPIN_TOPO_MIC_SOURCE |
마이크 입력 잭 |
KSPIN_TOPO_LINEOUT_DEST |
스테레오 스피커 출력 잭 |
이 항목의 나머지 부분에서는 간단한 MSVAD 샘플 드라이버를 수정하여 3개의 브리지 핀에 대한 잭 정보를 제공하는 방법을 설명합니다.
먼저 이러한 핀에 대한 잭 정보를 다음과 같이 지정할 수 있습니다.
// 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으로 설정합니다. 아날로그 렌더링 핀만 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 구조체로 구성된 빈 잭 설명을 반환합니다. 클라이언트가 존재하지 않는 핀을 식별하는 잘못된 핀 ID를 지정하는 경우 처리기는 코드 STATUS_INVALID_PARAMETER 상태 반환합니다.
KSPROPERTY_JACK_DESCRIPTION 속성을 지원하려면 Simple MSVAD 샘플에 대한 두 가지 추가 수정이 필요합니다. 이러한 방법은 다음과 같습니다.
앞의 코드 예제에서 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 구조체의 처리기 멤버에는 이전 단계에서 Mintopo.cpp에 추가된 속성 처리기에 대한 함수 포인터가 포함되어 있습니다. 헤더 파일에서 속성 처리기에 액세스할 수 있도록 하려면 헤더 파일의 시작 부분에 PropertyHandler_TopoFilter 대한 extern 함수 선언을 삽입합니다.
잭 설명 속성에 대한 자세한 내용은 동적 오디오 하위 서비스에 대한 잭 설명을 참조하세요.