Zdarzenia sesji audio
Aplikacja, która zarządza strumieniami audio w trybie udostępnionym, może rejestrować się w celu odbierania powiadomień po wystąpieniu zdarzeń sesji. Jak wyjaśniono wcześniej, każdy strumień należy do sesji audio . Zdarzenie sesji jest inicjowane przez zmianę stanu sesji audio.
Aplikacja kliencka może zarejestrować się w celu otrzymywania powiadomień o następujących typach zdarzeń sesji:
- Poziom woluminu głównego lub stan wyciszenia podmiksu sesji uległ zmianie.
- Poziom woluminu co najmniej jednego kanału podmiksu sesji uległ zmianie.
- Sesja została rozłączona.
- Stan działania sesji został zmieniony na aktywny, nieaktywny lub wygasł.
- Sesja została przypisana do nowego parametru grupowania.
- Zmieniono właściwość interfejsu użytkownika sesji (ikona lub nazwa wyświetlana).
Klient odbiera powiadomienia o tych zdarzeniach za pośrednictwem metod w implementacji interfejsu IAudioSessionEvents. W przeciwieństwie do innych interfejsów w interfejsie WASAPI, które są implementowane przez moduł systemu WASAPI, klient implementuje IAudioSessionEvents. Metody w tym interfejsie odbierają wywołania zwrotne z modułu systemu WASAPI po wystąpieniu zdarzeń sesji.
Aby rozpocząć odbieranie powiadomień, klient wywołuje metodę IAudioSessionControl::RegisterAudioSessionNotification metodę rejestrowania interfejsu IAudioSessionEvents. Gdy klient nie wymaga już powiadomień, wywołuje metodę IAudioSessionControl::UnregisterAudioSessionNotification metodę w celu usunięcia rejestracji.
Poniższy przykład kodu przedstawia możliwą implementację interfejsu IAudioSessionEvents:
//-----------------------------------------------------------
// Client implementation of IAudioSessionEvents interface.
// WASAPI calls these methods to notify the application when
// a parameter or property of the audio session changes.
//-----------------------------------------------------------
class CAudioSessionEvents : public IAudioSessionEvents
{
LONG _cRef;
public:
CAudioSessionEvents() :
_cRef(1)
{
}
~CAudioSessionEvents()
{
}
// IUnknown methods -- AddRef, Release, and QueryInterface
ULONG STDMETHODCALLTYPE AddRef()
{
return InterlockedIncrement(&_cRef);
}
ULONG STDMETHODCALLTYPE Release()
{
ULONG ulRef = InterlockedDecrement(&_cRef);
if (0 == ulRef)
{
delete this;
}
return ulRef;
}
HRESULT STDMETHODCALLTYPE QueryInterface(
REFIID riid,
VOID **ppvInterface)
{
if (IID_IUnknown == riid)
{
AddRef();
*ppvInterface = (IUnknown*)this;
}
else if (__uuidof(IAudioSessionEvents) == riid)
{
AddRef();
*ppvInterface = (IAudioSessionEvents*)this;
}
else
{
*ppvInterface = NULL;
return E_NOINTERFACE;
}
return S_OK;
}
// Notification methods for audio session events
HRESULT STDMETHODCALLTYPE OnDisplayNameChanged(
LPCWSTR NewDisplayName,
LPCGUID EventContext)
{
return S_OK;
}
HRESULT STDMETHODCALLTYPE OnIconPathChanged(
LPCWSTR NewIconPath,
LPCGUID EventContext)
{
return S_OK;
}
HRESULT STDMETHODCALLTYPE OnSimpleVolumeChanged(
float NewVolume,
BOOL NewMute,
LPCGUID EventContext)
{
if (NewMute)
{
printf("MUTE\n");
}
else
{
printf("Volume = %d percent\n",
(UINT32)(100*NewVolume + 0.5));
}
return S_OK;
}
HRESULT STDMETHODCALLTYPE OnChannelVolumeChanged(
DWORD ChannelCount,
float NewChannelVolumeArray[],
DWORD ChangedChannel,
LPCGUID EventContext)
{
return S_OK;
}
HRESULT STDMETHODCALLTYPE OnGroupingParamChanged(
LPCGUID NewGroupingParam,
LPCGUID EventContext)
{
return S_OK;
}
HRESULT STDMETHODCALLTYPE OnStateChanged(
AudioSessionState NewState)
{
char *pszState = "?????";
switch (NewState)
{
case AudioSessionStateActive:
pszState = "active";
break;
case AudioSessionStateInactive:
pszState = "inactive";
break;
}
printf("New session state = %s\n", pszState);
return S_OK;
}
HRESULT STDMETHODCALLTYPE OnSessionDisconnected(
AudioSessionDisconnectReason DisconnectReason)
{
char *pszReason = "?????";
switch (DisconnectReason)
{
case DisconnectReasonDeviceRemoval:
pszReason = "device removed";
break;
case DisconnectReasonServerShutdown:
pszReason = "server shut down";
break;
case DisconnectReasonFormatChanged:
pszReason = "format changed";
break;
case DisconnectReasonSessionLogoff:
pszReason = "user logged off";
break;
case DisconnectReasonSessionDisconnected:
pszReason = "session disconnected";
break;
case DisconnectReasonExclusiveModeOverride:
pszReason = "exclusive-mode override";
break;
}
printf("Audio session disconnected (reason: %s)\n",
pszReason);
return S_OK;
}
};
Klasa CAudioSessionEvents w poprzednim przykładzie kodu to implementacja interfejsu IAudioSessionEvents. Ta konkretna implementacja może być częścią aplikacji konsolowej, która wyświetla informacje o zdarzeniach sesji w oknie wiersza polecenia. Ponieważ IAudioSessionEvents dziedziczy z IUnknown, definicja klasy zawiera implementacje metod IUnknownAddRef, Releasei QueryInterface. Pozostałe metody publiczne w definicji klasy są specyficzne dla interfejsu IAudioSessionEvents.
Niektórzy klienci mogą nie być zainteresowani monitorowaniem wszystkich typów zdarzeń sesji. W poprzednim przykładzie kodu kilka metod powiadomień w klasie CAudioSessionEvents nic nie robi. Na przykład metoda OnChannelVolumeChanged nie zwraca kodu stanu S_OK. Ta aplikacja nie monitoruje woluminów kanałów, ponieważ nie zmienia woluminów kanału (wywołując metody w interfejsie IChannelAudioVolume) i nie udostępnia sesji innym aplikacjom, które mogą zmienić woluminy kanału.
Jedyne trzy metody w klasie CAudioSessionEvents, które powiadamiają użytkownika o zdarzeniach sesji, to OnSimpleVolumeChanged, OnStateChangedi OnSessionDisconnected. Jeśli na przykład użytkownik uruchamia systemowy program sterowania woluminami, Sndvol i używa kontrolki głośności w usłudze Sndvol do zmiany poziomu woluminu aplikacji, OnSimpleVolumeChanged
natychmiast wyświetla nowy poziom woluminu.
Aby zapoznać się z przykładem kodu, który rejestruje i wyrejestrowuje interfejs IAudioSessionEvents, zobacz Audio Events for Legacy Audio Applications.
Tematy pokrewne