Ducking 알림에 대한 구현 고려 사항

시스템에서 제공하는 기본 더킹 환경 은 통신 스트림이 열릴 때 시스템에서 사용할 수 있는 모든 비커뮤니케이션 스트림을 검색합니다. 미디어 애플리케이션은 통신 세션이 시작되고 종료되는 시기를 알고 있는 경우 기본 처리를 재정의할 수 있습니다.

DuckingMediaPlayer 샘플에서 미디어 애플리케이션에서 구현한 시나리오를 고려합니다. 애플리케이션은 오리 알림을 받을 때 재생 중인 오디오 스트림을 일시 중지하고, 잘못된 알림을 받으면 재생을 계속합니다. 일시 중지 및 계속 이벤트는 미디어 애플리케이션의 사용자 인터페이스에 반영됩니다. WM_APP_SESSION_DUCKED 및 WM_APP_SESSION_UNDUCKED 두 개의 애플리케이션 정의 창 메시지를 통해 지원됩니다. 더킹 알림은 백그라운드에서 비동기적으로 수신되며 미디어 애플리케이션은 창 메시지를 처리하기 위해 알림 스레드를 차단해서는 안 됩니다. 창 메시지는 사용자 인터페이스 스레드에서 처리되어야 합니다.

더킹 동작은 알림 메커니즘을 통해 작동합니다. 사용자 지정된 환경을 제공하려면 미디어 애플리케이션이 IAudioVolumeDuckNotification 인터페이스를 구현하고 구현을 오디오 시스템에 등록해야 합니다. 등록에 성공하면 미디어 애플리케이션은 인터페이스의 메서드를 통해 콜백 형식으로 이벤트 알림을 받습니다. 통신 세션을 처리하는 세션 관리자는 통신 스트림이 열릴 때 IAudioVolumeDuckNotification::OnVolumeDuckNotification 을 호출한 다음, 통신 디바이스에서 스트림이 닫혀 있을 때 IAudioVolumeDuckNotification::OnVolumeUnduckNotification 을 호출합니다.

다음 코드는 IAudioVolumeDuckNotification 인터페이스의 샘플 구현을 보여줍니다. CMediaPlayer::D uckingOptOut의 정의는 통신 디바이스에서 더킹 이벤트 가져오기를 참조하세요.

class CMediaPlayer : public IAudioVolumeDuckNotification
{
    LONG _refCount;

    HWND _AppWindow;

    ~CMediaPlayer();

    STDMETHOD(OnVolumeDuckNotification) (LPCWSTR sessionID, 
                  UINT32 countCommunicationSessions);
    STDMETHOD(OnVolumeUnduckNotification) (LPCWSTR sessionID);

public:
    CDuckingImpl(HWND hWnd);
    HRESULT DuckingOptOut(bool GetDuckEvents);

    // IUnknown
    IFACEMETHODIMP QueryInterface(__in REFIID riid, __deref_out void **ppv);
    IFACEMETHODIMP_(ULONG) AddRef();
    IFACEMETHODIMP_(ULONG) Release();
};

CMediaPlayer::CMediaPlayer(HWND AppWindow) :
        _AppWindow(AppWindow),
        _refCount(1)
{
}
CMediaPlayer::~CMediaPlayer()
{
}

// When we receive a duck notification, 
// post a "Session Ducked" message to the application window.

STDMETHODIMP CMediaPlayer::OnVolumeDuckNotification(LPCWSTR SessionID, 
                                                    UINT32 CountCommunicationsSessions)
{
    PostMessage(_AppWindow, WM_APP_SESSION_DUCKED, 0, 0);
    return 0;
}


// When we receive an unduck notification, 
// post a "Session Unducked" message to the application window.

STDMETHODIMP CMediaPlayer::OnVolumeUnduckNotification(LPCWSTR SessionID)
{
    PostMessage(_AppWindow, WM_APP_SESSION_UNDUCKED, 0, 0);
    return 0;
}

IFACEMETHODIMP CMediaPlayer::QueryInterface(REFIID iid, void **pvObject)
{
    if (pvObject == NULL)
    {
        return E_POINTER;
    }
    *pvObject = NULL;
    if (iid == IID_IUnknown)
    {
        *pvObject = static_cast<IUnknown *>(static_cast<IAudioVolumeDuckNotification *>
                                                                              (this));
        AddRef();
    }
    else if (iid == __uuidof(IAudioVolumeDuckNotification))
    {
        *pvObject = static_cast<IAudioVolumeDuckNotification *>(this);
        AddRef();
    }
    else
    {
        return E_NOINTERFACE;
    }
    return S_OK;
}

IFACEMETHODIMP_(ULONG) CMediaPlayer::AddRef()
{
    return InterlockedIncrement(&_refCount);
}

IFACEMETHODIMP_(ULONG) CMediaPlayer::Release()
{
    LONG refs = InterlockedDecrement(&_refCount);

    if (refs == 0)
    {
        delete this; 
    }

    return refs;   
}

통신 디바이스 사용

기본 더킹 환경

기본 더킹 환경 비활성화

사용자 지정 더킹 동작 제공

더킹 이벤트 가져오기