디바이스 토폴로지

DeviceTopology API클라이언트가 MMDevice API, WASAPI 또는 EndpointVolume API를 통해 액세스할 수 없는 오디오 어댑터의 다양한 내부 기능을 제어할 수 있도록 합니다.

앞서 설명한 것처럼 MMDevice API, WASAPIEndpointVolume API 는 마이크, 스피커, 헤드폰 및 기타 오디오 입력 및 출력 디바이스를 오디오 엔드포인트 디바이스로 클라이언트에 제공합니다. 엔드포인트 디바이스 모델은 클라이언트에게 오디오 디바이스의 볼륨 및 음소거 컨트롤에 편리하게 액세스할 수 있도록 합니다. 이러한 간단한 컨트롤만 필요한 클라이언트는 오디오 어댑터에서 하드웨어 디바이스의 내부 토폴로지 트래버스를 방지할 수 있습니다.

Windows Vista에서 오디오 엔진은 오디오 애플리케이션에서 사용할 오디오 디바이스의 토폴로지 를 자동으로 구성합니다. 따라서 애플리케이션은 이러한 용도로 DeviceTopology API를 사용해야 하는 경우가 거의 없습니다. 예를 들어 오디오 어댑터에 선 입력 또는 마이크에서 스트림을 캡처할 수 있지만 두 엔드포인트 디바이스의 스트림을 동시에 캡처할 수 없는 입력 멀티플렉서가 포함되어 있다고 가정합니다. 사용자가 단독 모드 스트림에 설명된 대로 공유 모드 애플리케이션에서 오디오 엔드포인트 디바이스의 사용을 선점하도록 단독 모드 애플리케이션을 사용하도록 설정했다고 가정합니다. 전용 모드 애플리케이션이 마이크에서 스트림 녹음을 시작할 때 공유 모드 애플리케이션이 라인 입력에서 스트림을 기록하는 경우 오디오 엔진은 자동으로 멀티플렉서가 라인 입력에서 마이크로 전환됩니다. 반면, Windows XP를 포함한 이전 버전의 Windows에서는 이 예제의 배타적 모드 애플리케이션이 Windows 멀티미디어 API의 mixerXxx 함수를 사용하여 어댑터 디바이스의 토폴로지를 트래버스하고, 멀티플렉서를 검색하고, 멀티플렉서가 마이크 입력을 선택하도록 구성합니다. Windows Vista에서는 이러한 단계가 더 이상 필요하지 않습니다.

그러나 일부 클라이언트는 MMDevice API, WASAPI 또는 EndpointVolume API를 통해 액세스할 수 없는 오디오 하드웨어 컨트롤 유형을 명시적으로 제어해야 할 수 있습니다. 이러한 클라이언트의 경우 DeviceTopology API는 어댑터 디바이스의 토폴로지를 트래버스하여 디바이스에서 오디오 컨트롤을 검색하고 관리하는 기능을 제공합니다. DeviceTopology API를 사용하는 애플리케이션은 Windows 오디오 정책을 방해하고 다른 애플리케이션과 공유되는 오디오 디바이스의 내부 구성을 방해하지 않도록 주의하여 설계해야 합니다. Windows 오디오 정책에 대한 자세한 내용은 사용자 모드 오디오 구성 요소를 참조하세요.

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는 커넥터 및 하위 단위의 특정 측면을 나타내기 위해 IConnectorISubunit 인터페이스를 구현합니다.

DeviceTopology API는 오디오 드라이버가 이러한 디바이스를 나타내기 위해 운영 체제에 노출하는 KS(커널 스트리밍) 필터에서 웨이브 캡처 디바이스 및 입력 멀티플렉서 디바이스의 토폴로지를 생성합니다. (오디오 어댑터 드라이버는 IMiniportWaveXxxIMiniportTopology 인터페이스를 구현하여 이러한 필터의 하드웨어 종속 부분을 나타냅니다. 이러한 인터페이스 및 KS 필터에 대한 자세한 내용은 Windows DDK 설명서를 참조하세요.)

DeviceTopology API는 이전 다이어그램에서 엔드포인트 디바이스 A 및 B를 나타내는 간단한 토폴로지를 생성합니다. 엔드포인트 디바이스의 디바이스 토폴로지 는 단일 커넥터로 구성됩니다. 이 토폴로지는 엔드포인트 디바이스의 자리 표시자일 뿐이며 오디오 데이터를 처리하기 위한 하위 단위를 포함하지 않습니다. 실제로 어댑터 디바이스에는 클라이언트 애플리케이션이 오디오 처리를 제어하는 데 사용하는 모든 하위 단위가 포함되어 있습니다. 엔드포인트 디바이스의 디바이스 토폴로지 는 주로 어댑터 디바이스의 디바이스 토폴로지를 탐색하기 위한 시작점으로 사용됩니다.

디바이스 토폴로지에서 두 부분 간의 내부 연결을 링크라고 합니다. DeviceTopology API는 디바이스 토폴로지에서 한 부분에서 다음 부분으로의 링크를 트래버스하는 메서드를 제공합니다. 또한 API는 디바이스 토폴로지 간의 연결을 트래버스하는 메서드를 제공합니다.

연결된 디바이스 토폴로지 집합의 탐색을 시작하기 위해 클라이언트 애플리케이션은 오디오 엔드포인트 디바이스의 IDeviceTopology 인터페이스를 활성화합니다. 엔드포인트 디바이스의 커넥터는 오디오 어댑터의 커넥터 또는 네트워크에 연결됩니다. 엔드포인트가 오디오 어댑터의 디바이스에 연결하는 경우 DeviceTopology API의 메서드를 사용하면 연결 반대편에 있는 어댑터 디바이스의 IDeviceTopology 인터페이스에 대한 참조를 가져와서 애플리케이션이 엔드포인트에서 어댑터로 연결을 단계별로 실행할 수 있습니다. 반면 네트워크에는 디바이스 토폴로지가 없습니다. 네트워크 연결은 원격으로 시스템에 액세스하는 클라이언트에 오디오 스트림을 파이프합니다.

DeviceTopology API는 오디오 어댑터에서 하드웨어 디바이스의 토폴로지만 액세스할 수 있도록 합니다. 다이어그램의 왼쪽 가장자리에 있는 외부 디바이스와 오른쪽 가장자리에 있는 소프트웨어 구성 요소는 API의 scope. 다이어그램의 양쪽에 있는 파선은 DeviceTopology API의 한계를 나타냅니다. 클라이언트는 API를 사용하여 입력 잭에서 시스템 버스까지 뻗어 있는 데이터 경로를 탐색할 수 있지만 API는 이러한 경계를 넘어 침투할 수 없습니다.

이전 다이어그램의 각 커넥터에는 커넥터가 만드는 연결 유형을 나타내는 연결된 연결 형식이 있습니다. 따라서 연결의 양쪽에 있는 커넥터는 항상 동일한 연결 형식을 갖습니다. 연결 형식은 ConnectorType 열거형 값(Physical_External, Physical_Internal, Software_Fixed, Software_IO 또는 네트워크)으로 표시됩니다. 입력 멀티플렉서 디바이스와 엔드포인트 디바이스 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 인터페이스를 가져옵니다.

  1. IMMDevice::Activate 메서드를 호출하여 엔드포인트 디바이스에 대한 IDeviceTopology 인터페이스를 가져옵니다.
  2. 이전 단계에서 가져온 IDeviceTopology 인터페이스를 사용하여 IDeviceTopology::GetConnector 메서드를 호출하여 엔드포인트 디바이스에서 단일 커넥터(커넥터 번호 0)의 IConnector 인터페이스를 가져옵니다.
  3. 이전 단계에서 가져온 IConnector 인터페이스를 사용하여 IConnector::GetConnectedTo 메서드를 호출하여 입력 멀티플렉서 디바이스에서 커넥터의 IConnector 인터페이스를 가져옵니다.
  4. 이전 단계에서 가져온 IConnector 인터페이스의 IPart 인터페이스를 쿼리합니다.
  5. 이전 단계에서 가져온 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개 이상의 하드웨어 컨트롤이 있을 수 있습니다. 하드웨어 컨트롤은 다음 인터페이스 쌍으로 표시됩니다.

  • 모든 하드웨어 컨트롤에 공통적인 메서드가 있는 제네릭 컨트롤 인터페이스인 IControlInterface입니다.
  • 특정 유형의 하드웨어 컨트롤(예: 볼륨 컨트롤)에 대한 컨트롤 매개 변수를 노출하는 함수별 인터페이스(예: IAudioVolumeLevel)입니다.

파트에 대한 하드웨어 컨트롤을 열거하기 위해 클라이언트는 먼저 IPart::GetControlInterfaceCount 메서드를 호출하여 파트와 연결된 하드웨어 컨트롤의 수를 확인합니다. 다음으로 클라이언트는 IPart::GetControlInterface 메서드를 일련의 호출하여 각 하드웨어 컨트롤에 대한 IControlInterface 인터페이스를 가져옵니다. 마지막으로 클라이언트는 IControlInterface::GetIID 메서드를 호출하여 인터페이스 ID를 가져와 각 하드웨어 컨트롤에 대한 함수별 인터페이스를 가져옵니다. 클라이언트는 이 ID를 사용하여 IPart::Activate 메서드를 호출하여 함수별 인터페이스를 가져옵니다.

커넥터인 파트는 다음 함수별 컨트롤 인터페이스 중 하나를 지원할 수 있습니다.

하위 단위인 부분은 다음 함수별 컨트롤 인터페이스 중 하나 이상을 지원할 수 있습니다.

파트는 기본 하드웨어 컨트롤에 디바이스별 컨트롤 값이 있고 컨트롤을 이전 목록의 다른 함수별 인터페이스로 적절하게 나타낼 수 없는 경우에만 IDeviceSpecificProperty 인터페이스를 지원합니다. 일반적으로 디바이스별 속성은 파트 형식, 파트 하위 형식 및 파트 이름과 같은 정보에서 속성 값의 의미를 유추할 수 있는 클라이언트에만 유용합니다. 클라이언트는 IPart::GetPartType, IPart::GetSubTypeIPart::GetName 메서드를 호출하여 이 정보를 가져올 수 있습니다.

프로그래밍 가이드