Considerazioni sull'implementazione per le notifiche di ducking
L'esperienza predefinita ducking fornita dal sistema anatra tutti i flussi non di comunicazione disponibili nel sistema quando si apre un flusso di comunicazione. Un'applicazione multimediale può eseguire l'override della gestione predefinita se sa quando viene avviata e terminata la sessione di comunicazione.
Si consideri lo scenario implementato dall'applicazione multimediale nell'esempio DuckingMediaPlayer . L'applicazione sospende il flusso audio che viene riprodotto quando riceve una notifica di anatra e continua la riproduzione quando riceve una notifica senza dollari. Gli eventi di sospensione e continuazione si riflettono nell'interfaccia utente dell'applicazione multimediale. Questa operazione è supportata tramite due messaggi di finestra definiti dall'applicazione, WM_APP_edizione StandardSSION_DUCKED e WM_APP_edizione StandardSSION_UNDUCKED. Le notifiche di anatraggio vengono ricevute in modo asincrono in background e l'applicazione multimediale non deve bloccare il thread di notifica per elaborare i messaggi della finestra. I messaggi della finestra devono essere elaborati nel thread dell'interfaccia utente.
Il comportamento di anatraggio funziona tramite un meccanismo di notifica. Per offrire un'esperienza personalizzata, l'applicazione multimediale deve implementare l'interfaccia IAudioVolumeDuckNotification e registrare l'implementazione con il sistema audio. Al termine della registrazione, l'applicazione multimediale riceve notifiche degli eventi sotto forma di callback tramite i metodi nell'interfaccia. Il gestore di sessioni che gestisce la sessione di comunicazione chiama IAudioVolumeDuckNotification::OnVolumeDuckNotification all'apertura del flusso di comunicazione e quindi chiama IAudioVolumeDuckNotification::OnVolumeUnduckNotification quando il flusso viene chiuso nel dispositivo di comunicazione.
Il codice seguente illustra un'implementazione di esempio dell'interfaccia IAudioVolumeDuckNotification . Per la definizione di CMediaPlayer::D uckingOptOut, vedi Recupero di eventi di anatraggio da un dispositivo di comunicazione.
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;
}
Argomenti correlati