디바이스 토폴로지
DeviceTopology API 클라이언트는 MMDevice API, WASAPI또는 EndpointVolume API통해 액세스할 수 없는 오디오 어댑터의 다양한 내부 기능을 제어할 수 있습니다.
앞에서 설명한 것처럼 MMDevice API, WASAPI및 EndpointVolume API는 오디오 엔드포인트 디바이스가클라이언트에 마이크, 스피커, 헤드폰 및 기타 오디오 입력 및 출력 디바이스를 표시할 있습니다. 엔드포인트 디바이스 모델은 클라이언트에게 오디오 디바이스의 볼륨 및 음소거 컨트롤에 편리하게 액세스할 수 있도록 합니다. 이러한 간단한 컨트롤만 필요한 클라이언트는 오디오 어댑터에서 하드웨어 디바이스의 내부 토폴로지 트래버스를 방지할 수 있습니다.
Windows Vista에서 오디오 엔진은 오디오 애플리케이션에서 사용할 오디오 디바이스의 토폴로지 자동 구성 따라서 애플리케이션은 이러한 용도로 DeviceTopology API를 사용해야 하는 경우가 거의 없습니다. 예를 들어 오디오 어댑터에 줄 입력 또는 마이크에서 스트림을 캡처할 수 있지만 동시에 두 엔드포인트 디바이스에서 스트림을 캡처할 수 없는 입력 멀티플렉서가 포함되어 있다고 가정합니다. 사용자가 Exclusive-Mode Streams설명한 대로 공유 모드 애플리케이션에서 오디오 엔드포인트 디바이스 사용을 선점하도록 단독 모드 애플리케이션을 사용하도록 설정했다고 가정합니다. 전용 모드 애플리케이션이 마이크에서 스트림을 녹음하기 시작할 때 공유 모드 애플리케이션이 줄 입력에서 스트림을 기록하는 경우 오디오 엔진은 자동으로 멀티플렉서를 라인 입력에서 마이크로 전환합니다. 반면, Windows XP를 비롯한 이전 버전의 Windows에서 이 예제의 단독 모드 애플리케이션은 Windows 멀티미디어 API의 mixerXxx 함수를 사용하여 어댑터 디바이스의 토폴로지를 트래버스하고, 멀티플렉서를 검색하고, 멀티플렉서를 구성하여 마이크 입력을 선택합니다. Windows Vista에서는 이러한 단계가 더 이상 필요하지 않습니다.
그러나 일부 클라이언트는 MMDevice API, WASAPI 또는 EndpointVolume API를 통해 액세스할 수 없는 오디오 하드웨어 컨트롤 유형을 명시적으로 제어해야 할 수 있습니다. 이러한 클라이언트의 경우 DeviceTopology API는 어댑터 디바이스의 토폴로지 탐색을 통해 디바이스의 오디오 컨트롤을 검색하고 관리하는 기능을 제공합니다. DeviceTopology API를 사용하는 애플리케이션은 Windows 오디오 정책을 방해하고 다른 애플리케이션과 공유되는 오디오 디바이스의 내부 구성을 방해하지 않도록 주의하여 설계해야 합니다. Windows 오디오 정책에 대한 자세한 내용은 오디오 구성 요소 User-Mode 참조하세요.
DeviceTopology API는 디바이스 토폴로지에서 다음 유형의 오디오 컨트롤을 검색하고 관리하기 위한 인터페이스를 제공합니다.
- 자동 게인 제어
- 베이스 컨트롤
- 입력 선택기(멀티플렉서)
- 음의도 제어
- 미드레인지 컨트롤
- 음소거 컨트롤
- 출력 선택기(demultiplexer)
- 피크 미터
- 고음 제어
- 볼륨 제어
또한 DeviceTopology API를 사용하면 클라이언트가 지원하는 스트림 형식에 대한 정보를 어댑터 디바이스에 쿼리할 수 있습니다. 헤더 파일 Devicetopology.h는 DeviceTopology API의 인터페이스를 정의합니다.
다음 다이어그램에서는 마이크, 줄 입력 및 CD 플레이어에서 오디오를 캡처하는 PCI 어댑터 부분에 대해 연결된 여러 디바이스 토폴로지의 예를 보여 줍니다.
4개의 연결된 디바이스 토폴로지예
위의 다이어그램은 아날로그 입력에서 시스템 버스로 이어지는 데이터 경로를 보여 줍니다. 다음 각 디바이스는 IDeviceTopology 인터페이스를 사용하여 디바이스 토폴로지 개체로 표시됩니다.
- 웨이브 캡처 디바이스
- 입력 멀티플렉서 디바이스
- 엔드포인트 디바이스 A
- 엔드포인트 디바이스 B
토폴로지 다이어그램은 어댑터 디바이스(웨이브 캡처 및 입력 멀티플렉서 디바이스)를 엔드포인트 디바이스와 결합합니다. 디바이스 간의 연결을 통해 오디오 데이터는 한 디바이스에서 다음 디바이스로 전달됩니다. 연결의 각 측면에는 데이터가 디바이스에 들어오거나 나가는 커넥터(다이어그램의 레이블이 지정된 Con)가 있습니다.
다이어그램의 왼쪽 가장자리에서 라인 입력 및 마이크 잭의 신호가 엔드포인트 디바이스에 들어갑니다.
웨이브 캡처 디바이스 및 입력 멀티플렉서 디바이스 내부에는 DeviceTopology API의 용어에서 하위 단위라고 하는 스트림 처리 함수가 있습니다. 위의 다이어그램에는 다음과 같은 유형의 하위 단위가 표시됩니다.
- 볼륨 컨트롤(레이블이 지정된 Vol)
- 음소거 컨트롤(레이블이 지정된 음소거)
- 멀티플렉서(또는 입력 선택기, 레이블이 지정된 MUX)
- 아날로그-디지털 변환기(레이블이 지정된 ADC)
볼륨, 음소거 및 멀티플렉서 하위 단위의 설정은 클라이언트에서 제어할 수 있으며 DeviceTopology API는 제어를 위해 클라이언트에 제어 인터페이스를 제공합니다. 이 예제에서는 ADC 하위 단위에 컨트롤 설정이 없습니다. 따라서 DeviceTopology API는 ADC에 대한 제어 인터페이스를 제공하지 않습니다.
DeviceTopology API의 용어에서 커넥터 및 하위 단위는 동일한 일반 범주인 파트에 속합니다. 모든 파트는 커넥터인지 하위 단위인지에 관계없이 일반적인 함수 집합을 제공합니다. DeviceTopology API는 커넥터 및 하위 요소에 공통적인 제네릭 함수를 나타내는 IPart 인터페이스를 구현합니다. API는 IConnector 및 ISubunit 인터페이스를 구현하여 커넥터 및 하위 단위의 특정 측면을 나타냅니다.
DeviceTopology API는 오디오 드라이버가 이러한 디바이스를 나타내기 위해 운영 체제에 노출하는 KS(커널 스트리밍) 필터에서 웨이브 캡처 디바이스 및 입력 멀티플렉서 디바이스의 토폴로지를 생성합니다. (오디오 어댑터 드라이버는 이러한 필터의 하드웨어 종속 부분을 나타내기 위해 IMiniportWaveXxx 및 IMiniportTopology 인터페이스를 구현합니다. 이러한 인터페이스 및 KS 필터에 대한 자세한 내용은 Windows DDK 설명서를 참조하세요.)
DeviceTopology API는 이전 다이어그램에서 엔드포인트 디바이스 A 및 B를 나타내는 간단한 토폴로지를 생성합니다. 엔드포인트 디바이스의 디바이스 토폴로지 단일 커넥터로 구성됩니다. 이 토폴로지는 엔드포인트 디바이스에 대한 자리 표시자일 뿐이며 오디오 데이터를 처리하기 위한 하위 단위를 포함하지 않습니다. 실제로 어댑터 디바이스에는 클라이언트 애플리케이션이 오디오 처리를 제어하는 데 사용하는 모든 하위 단위가 포함되어 있습니다. 엔드포인트 디바이스의 디바이스 토폴로지에서는 주로 어댑터 디바이스의 디바이스 토폴로지 탐색을 위한 시작점으로 사용됩니다.
디바이스 토폴로지의 두 부분 간의 내부 연결을 링크라고 합니다. DeviceTopology API는 디바이스 토폴로지에서 한 부분에서 다음 부분으로의 링크를 트래버스하는 메서드를 제공합니다. 또한 API는 디바이스 토폴로지 간의 연결을 트래버스하는 메서드를 제공합니다.
연결된 디바이스 토폴로지 집합의 탐색을 시작하기 위해 클라이언트 애플리케이션은 오디오 엔드포인트 디바이스의 IDeviceTopology 인터페이스를 활성화합니다. 엔드포인트 디바이스의 커넥터는 오디오 어댑터의 커넥터 또는 네트워크에 연결됩니다. 엔드포인트가 오디오 어댑터의 디바이스에 연결하는 경우 DeviceTopology API의 메서드를 사용하면 애플리케이션이 연결의 반대편에 있는 어댑터 디바이스의 IDeviceTopology 인터페이스에 대한 참조를 가져와서 엔드포인트에서 어댑터로의 연결을 단계별로 실행할 수 있습니다. 반면 네트워크에는 디바이스 토폴로지가 없습니다. 네트워크 연결은 원격으로 시스템에 액세스하는 클라이언트에 오디오 스트림을 파이프합니다.
DeviceTopology API는 오디오 어댑터에서 하드웨어 디바이스의 토폴로지만 액세스할 수 있도록 합니다. 다이어그램의 왼쪽 가장자리에 있는 외부 디바이스와 오른쪽 가장자리에 있는 소프트웨어 구성 요소는 API 범위를 벗어날 수 있습니다. 다이어그램의 양쪽에 있는 파선은 DeviceTopology API의 제한을 나타냅니다. 클라이언트는 API를 사용하여 입력 잭에서 시스템 버스로 뻗어 있는 데이터 경로를 탐색할 수 있지만 API는 이러한 경계를 넘을 수 없습니다.
이전 다이어그램의 각 커넥터에는 연결선이 만드는 연결 유형을 나타내는 연결된 연결 형식이 있습니다. 따라서 연결의 양쪽에 있는 커넥터는 항상 동일한 연결 형식을 갖습니다. 연결 형식은 ConnectorType 열거형 값(Physical_External, Physical_Internal, Software_Fixed, Software_IO 또는 Network)으로 표시됩니다. 입력 멀티플렉서 디바이스와 엔드포인트 디바이스 A와 B 간의 연결은 Physical_External 형식입니다. 즉, 연결이 외부 디바이스에 대한 물리적 연결(즉, 사용자가 액세스할 수 있는 오디오 잭)을 나타냅니다. 내부 CD 플레이어에서 아날로그 신호에 대한 연결은 시스템 섀시 내에 설치된 보조 디바이스에 대한 물리적 연결을 나타내는 Physical_Internal 형식입니다. 웨이브 캡처 디바이스와 입력 멀티플렉서 디바이스 간의 연결은 Software_Fixed 형식이며, 이는 고정되고 소프트웨어 제어에서 구성할 수 없는 영구 연결을 나타냅니다. 마지막으로 다이어그램의 오른쪽에 있는 시스템 버스에 대한 연결은 Software_IO 형식이며, 이는 연결에 대한 데이터 I/O가 소프트웨어 제어 하에 있는 DMA 엔진에 의해 구현됨을 나타냅니다. (다이어그램에는 네트워크 연결 유형의 예가 포함되어 있지 않습니다.)
클라이언트는 엔드포인트 디바이스에서 데이터 경로를 트래버스하기 시작합니다. 먼저 클라이언트는 오디오 디바이스열거에 설명된 대로 엔드포인트 디바이스를 나타내는 IMMDevice 인터페이스를 가져옵니다. 엔드포인트 디바이스에 대한 IDeviceTopology 인터페이스를 가져오기 위해 클라이언트는 매개 변수 iid REFIID IID_IDeviceTopology 설정된 IMMDevice::Activate 메서드를 호출합니다.
이전 다이어그램의 예제에서 입력 멀티플렉서 디바이스에는 라인 입력 및 마이크 잭의 캡처 스트림에 대한 모든 하드웨어 컨트롤(볼륨, 음소거 및 멀티플렉서)이 포함됩니다. 다음 코드 예제에서는 줄 입력 또는 마이크에 대한 엔드포인트 디바이스의 IMMDevice 인터페이스에서 입력 멀티플렉서 디바이스에 대한 IDeviceTopology 인터페이스를 가져오는 방법을 보여 드립니다.
//-----------------------------------------------------------
// The input argument to this function is a pointer to the
// IMMDevice interface of an endpoint device. The function
// outputs a pointer (counted reference) to the
// IDeviceTopology interface of the adapter device that
// connects to the endpoint device.
//-----------------------------------------------------------
#define EXIT_ON_ERROR(hres) \
if (FAILED(hres)) { goto Exit; }
#define SAFE_RELEASE(punk) \
if ((punk) != NULL) \
{ (punk)->Release(); (punk) = NULL; }
const IID IID_IDeviceTopology = __uuidof(IDeviceTopology);
const IID IID_IPart = __uuidof(IPart);
HRESULT GetHardwareDeviceTopology(
IMMDevice *pEndptDev,
IDeviceTopology **ppDevTopo)
{
HRESULT hr = S_OK;
IDeviceTopology *pDevTopoEndpt = NULL;
IConnector *pConnEndpt = NULL;
IConnector *pConnHWDev = NULL;
IPart *pPartConn = NULL;
// Get the endpoint device's IDeviceTopology interface.
hr = pEndptDev->Activate(
IID_IDeviceTopology, CLSCTX_ALL,
NULL, (void**)&pDevTopoEndpt);
EXIT_ON_ERROR(hr)
// The device topology for an endpoint device always
// contains just one connector (connector number 0).
hr = pDevTopoEndpt->GetConnector(0, &pConnEndpt);
EXIT_ON_ERROR(hr)
// Use the connector in the endpoint device to get the
// connector in the adapter device.
hr = pConnEndpt->GetConnectedTo(&pConnHWDev);
EXIT_ON_ERROR(hr)
// Query the connector in the adapter device for
// its IPart interface.
hr = pConnHWDev->QueryInterface(
IID_IPart, (void**)&pPartConn);
EXIT_ON_ERROR(hr)
// Use the connector's IPart interface to get the
// IDeviceTopology interface for the adapter device.
hr = pPartConn->GetTopologyObject(ppDevTopo);
Exit:
SAFE_RELEASE(pDevTopoEndpt)
SAFE_RELEASE(pConnEndpt)
SAFE_RELEASE(pConnHWDev)
SAFE_RELEASE(pPartConn)
return hr;
}
이전 코드 예제의 GetHardwareDeviceTopology 함수는 다음 단계를 수행하여 입력 멀티플렉서 디바이스에 대한 IDeviceTopology 인터페이스를 가져옵니다.
- IMMDevice::Activate 메서드를 호출하여 엔드포인트 디바이스에 대한 IDeviceTopology 인터페이스를 가져옵니다.
- 이전 단계에서 가져온 IDeviceTopology 인터페이스를 사용하여 IDeviceTopology::GetConnector 메서드를 호출하여 엔드포인트 디바이스에서 단일 커넥터(커넥터 번호 0)의 IConnector 인터페이스를 가져옵니다.
- 이전 단계에서 가져온 IConnector 인터페이스를 사용하여 IConnector::GetConnectedTo 메서드를 호출하여 입력 멀티플렉서 디바이스에서 커넥터의 IConnector 인터페이스를 가져옵니다.
- 이전 단계에서 가져온 IConnector 인터페이스의 IPart 인터페이스를 쿼리합니다.
- 이전 단계에서 가져온 IPart 인터페이스를 사용하여 IPart::GetTopologyObject 메서드를 호출하여 입력 멀티플렉서 디바이스에 대한 IDeviceTopology 인터페이스를 가져옵니다.
사용자가 이전 다이어그램의 마이크에서 기록하기 전에 클라이언트 애플리케이션은 멀티플렉서가 마이크 입력을 선택해야 합니다. 다음 코드 예제에서는 클라이언트가 멀티플렉서가 발견될 때까지 마이크에서 데이터 경로를 트래버스하는 방법을 보여 줍니다. 그러면 마이크 입력을 선택하도록 프로그래밍됩니다.
//-----------------------------------------------------------
// The input argument to this function is a pointer to the
// IMMDevice interface for a capture endpoint device. The
// function traverses the data path that extends from the
// endpoint device to the system bus (for example, PCI)
// or external bus (USB). If the function discovers a MUX
// (input selector) in the path, it selects the MUX input
// that connects to the stream from the endpoint device.
//-----------------------------------------------------------
#define EXIT_ON_ERROR(hres) \
if (FAILED(hres)) { goto Exit; }
#define SAFE_RELEASE(punk) \
if ((punk) != NULL) \
{ (punk)->Release(); (punk) = NULL; }
const IID IID_IDeviceTopology = __uuidof(IDeviceTopology);
const IID IID_IPart = __uuidof(IPart);
const IID IID_IConnector = __uuidof(IConnector);
const IID IID_IAudioInputSelector = __uuidof(IAudioInputSelector);
HRESULT SelectCaptureDevice(IMMDevice *pEndptDev)
{
HRESULT hr = S_OK;
DataFlow flow;
IDeviceTopology *pDeviceTopology = NULL;
IConnector *pConnFrom = NULL;
IConnector *pConnTo = NULL;
IPart *pPartPrev = NULL;
IPart *pPartNext = NULL;
IAudioInputSelector *pSelector = NULL;
if (pEndptDev == NULL)
{
EXIT_ON_ERROR(hr = E_POINTER)
}
// Get the endpoint device's IDeviceTopology interface.
hr = pEndptDev->Activate(
IID_IDeviceTopology, CLSCTX_ALL, NULL,
(void**)&pDeviceTopology);
EXIT_ON_ERROR(hr)
// The device topology for an endpoint device always
// contains just one connector (connector number 0).
hr = pDeviceTopology->GetConnector(0, &pConnFrom);
SAFE_RELEASE(pDeviceTopology)
EXIT_ON_ERROR(hr)
// Make sure that this is a capture device.
hr = pConnFrom->GetDataFlow(&flow);
EXIT_ON_ERROR(hr)
if (flow != Out)
{
// Error -- this is a rendering device.
EXIT_ON_ERROR(hr = AUDCLNT_E_WRONG_ENDPOINT_TYPE)
}
// Outer loop: Each iteration traverses the data path
// through a device topology starting at the input
// connector and ending at the output connector.
while (TRUE)
{
BOOL bConnected;
hr = pConnFrom->IsConnected(&bConnected);
EXIT_ON_ERROR(hr)
// Does this connector connect to another device?
if (bConnected == FALSE)
{
// This is the end of the data path that
// stretches from the endpoint device to the
// system bus or external bus. Verify that
// the connection type is Software_IO.
ConnectorType connType;
hr = pConnFrom->GetType(&connType);
EXIT_ON_ERROR(hr)
if (connType == Software_IO)
{
break; // finished
}
EXIT_ON_ERROR(hr = E_FAIL)
}
// Get the connector in the next device topology,
// which lies on the other side of the connection.
hr = pConnFrom->GetConnectedTo(&pConnTo);
EXIT_ON_ERROR(hr)
SAFE_RELEASE(pConnFrom)
// Get the connector's IPart interface.
hr = pConnTo->QueryInterface(
IID_IPart, (void**)&pPartPrev);
EXIT_ON_ERROR(hr)
SAFE_RELEASE(pConnTo)
// Inner loop: Each iteration traverses one link in a
// device topology and looks for input multiplexers.
while (TRUE)
{
PartType parttype;
UINT localId;
IPartsList *pParts;
// Follow downstream link to next part.
hr = pPartPrev->EnumPartsOutgoing(&pParts);
EXIT_ON_ERROR(hr)
hr = pParts->GetPart(0, &pPartNext);
pParts->Release();
EXIT_ON_ERROR(hr)
hr = pPartNext->GetPartType(&parttype);
EXIT_ON_ERROR(hr)
if (parttype == Connector)
{
// We've reached the output connector that
// lies at the end of this device topology.
hr = pPartNext->QueryInterface(
IID_IConnector,
(void**)&pConnFrom);
EXIT_ON_ERROR(hr)
SAFE_RELEASE(pPartPrev)
SAFE_RELEASE(pPartNext)
break;
}
// Failure of the following call means only that
// the part is not a MUX (input selector).
hr = pPartNext->Activate(
CLSCTX_ALL,
IID_IAudioInputSelector,
(void**)&pSelector);
if (hr == S_OK)
{
// We found a MUX (input selector), so select
// the input from our endpoint device.
hr = pPartPrev->GetLocalId(&localId);
EXIT_ON_ERROR(hr)
hr = pSelector->SetSelection(localId, NULL);
EXIT_ON_ERROR(hr)
SAFE_RELEASE(pSelector)
}
SAFE_RELEASE(pPartPrev)
pPartPrev = pPartNext;
pPartNext = NULL;
}
}
Exit:
SAFE_RELEASE(pConnFrom)
SAFE_RELEASE(pConnTo)
SAFE_RELEASE(pPartPrev)
SAFE_RELEASE(pPartNext)
SAFE_RELEASE(pSelector)
return hr;
}
DeviceTopology API는 이전 다이어그램의 것과 같이 멀티플렉서가 캡슐화되는 IAudioInputSelector 인터페이스를 구현합니다. (IAudioOutputSelector 인터페이스는 demultiplexer를 캡슐화합니다.) 앞의 코드 예제에서 SelectCaptureDevice 함수의 내부 루프는 하위 단위가 멀티플렉서인지 여부를 검색하기 위해 찾은 각 하위 단위를 쿼리합니다. 하위 단위가 멀티플렉서인 경우 함수는 IAudioInputSelector::SetSelection 메서드를 호출하여 엔드포인트 디바이스에서 스트림에 연결하는 입력을 선택합니다.
앞의 코드 예제에서 외부 루프의 각 반복은 하나의 디바이스 토폴로지 통과합니다. 이전 다이어그램에서 디바이스 토폴로지 트래버스할 때 첫 번째 반복은 입력 멀티플렉서 디바이스를 트래버스하고 두 번째 반복은 웨이브 캡처 디바이스를 트래버스합니다. 함수는 다이어그램의 오른쪽 가장자리에 있는 커넥터에 도달하면 종료됩니다. 종료는 함수가 Software_IO 연결 형식의 커넥터를 검색할 때 발생합니다. 이 연결 유형은 어댑터 디바이스가 시스템 버스에 연결하는 지점을 식별합니다.
앞의 코드 예제에서 IPart::GetPartType 메서드를 호출하면 현재 부분이 커넥터인지 오디오 처리 하위 단위인지 여부를 나타내는 IPartType 열거형 값을 가져옵니다.
앞의 코드 예제의 내부 루프는 IPart::EnumPartsOutgoing 메서드를 호출하여 링크를 한 부분에서 다음 부분으로 이동합니다. (반대 방향으로 스테핑하기 위한 IPart::EnumPartsIncoming 메서드도 있습니다.) 이 메서드는 나가는 모든 부분의 목록을 포함하는 IPartsList 개체를 검색합니다. 그러나 SelectCaptureDevice 함수가 캡처 디바이스에서 발생할 것으로 예상되는 모든 부분에는 항상 정확히 하나의 나가는 부분이 있습니다. 따라서 IPartsList::GetPart 대한 후속 호출은 항상 목록의 첫 번째 부분인 0부를 요청합니다. 함수는 이것이 목록의 유일한 부분이라고 가정하기 때문입니다.
SelectCaptureDevice 함수에서 해당 가정이 유효하지 않은 토폴로지를 발견하면 함수가 디바이스를 올바르게 구성하지 못할 수 있습니다. 이러한 오류를 방지하기 위해 더 범용 버전의 함수는 다음을 수행할 수 있습니다.
- IPartsList::GetCount 메서드를 호출하여 나가는 부분의 수를 확인합니다.
- 나가는 각 파트에 대해 IPartsList::GetPart 호출하여 파트에서 이어지는 데이터 경로를 트래버스하기 시작합니다.
전부는 아니지만 일부 파트에는 클라이언트가 설정하거나 가져올 수 있는 연결된 하드웨어 컨트롤이 있습니다. 특정 부분에는 0개, 1개 이상의 하드웨어 컨트롤이 있을 수 있습니다. 하드웨어 컨트롤은 다음 인터페이스 쌍으로 표시됩니다.
- iControlInterface제네릭 컨트롤 인터페이스로, 모든 하드웨어 컨트롤에 공통적인 메서드가 있습니다.
- 특정 유형의 하드웨어 컨트롤(예: 볼륨 컨트롤)에 대한 컨트롤 매개 변수를 노출하는 함수별 인터페이스(예: IAudioVolumeLevel)입니다.
파트에 대한 하드웨어 컨트롤을 열거하기 위해 클라이언트는 먼저 IPart::GetControlInterfaceCount 메서드를 호출하여 파트와 연결된 하드웨어 컨트롤의 수를 확인합니다. 다음으로 클라이언트는 iPart::GetControlInterface메서드를일련의 호출을 수행하여 각 하드웨어 컨트롤에 대한 IControlInterface 인터페이스를 가져옵니다. 마지막으로 클라이언트는 IControlInterface::GetIID 메서드를 호출하여 각 하드웨어 컨트롤에 대한 함수별 인터페이스를 가져와서 인터페이스 ID를 가져옵니다. 클라이언트는 이 ID를 사용하여 IPart::Activate 메서드를 호출하여 함수별 인터페이스를 가져옵니다.
커넥터인 파트는 다음 함수별 컨트롤 인터페이스 중 하나를 지원할 수 있습니다.
- IKsFormatSupport
- IKsJackDescription
하위 단위인 파트는 다음 함수별 컨트롤 인터페이스 중 하나 이상을 지원할 수 있습니다.
- IAudioAutoGainControl
- IAudioBass
- IAudioChannelConfig
- IAudioInputSelector
- IAudioLoudness
- IAudioMidrange
- IAudioMute
- IAudioOutputSelector
- IAudioPeakMeter
- IAudioTreble
- IAudioVolumeLevel
- IDeviceSpecificProperty
파트는 기본 하드웨어 컨트롤에 디바이스별 컨트롤 값이 있고 컨트롤을 이전 목록의 다른 함수별 인터페이스로 적절하게 나타낼 수 없는 경우에만 IDeviceSpecificProperty 인터페이스를 지원합니다. 일반적으로 디바이스별 속성은 파트 형식, 파트 하위 형식 및 부품 이름과 같은 정보에서 속성 값의 의미를 유추할 수 있는 클라이언트에만 유용합니다. 클라이언트는 IPart::GetPartType, IPart::GetSubType및 IPart::GetName 메서드를 호출하여 이 정보를 가져올 수 있습니다.
관련 항목