Peristiwa Sesi Audio
Aplikasi yang mengelola aliran audio mode bersama dapat mendaftar untuk menerima pemberitahuan saat peristiwa sesi terjadi. Seperti yang dijelaskan sebelumnya, setiap aliran termasuk dalam sesi audio. Peristiwa sesi dimulai oleh perubahan status sesi audio.
Aplikasi klien dapat mendaftar untuk menerima pemberitahuan tentang jenis peristiwa sesi berikut:
- Tingkat volume master atau status membisukan submix sesi telah berubah.
- Tingkat volume satu atau beberapa saluran submix sesi telah berubah.
- Sesi telah terputus.
- Status aktivitas sesi telah berubah menjadi aktif, tidak aktif, atau kedaluwarsa.
- Sesi telah diberi parameter pengelompokan baru.
- Properti antarmuka pengguna sesi (ikon atau nama tampilan) telah berubah.
Klien menerima pemberitahuan tentang peristiwa ini melalui metode dalam implementasi antarmuka IAudioSessionEvents . Tidak seperti antarmuka lain di WASAPI, yang diimplementasikan oleh modul sistem WASAPI, klien mengimplementasikan IAudioSessionEvents. Metode dalam antarmuka ini menerima panggilan balik dari modul sistem WASAPI ketika peristiwa sesi terjadi.
Untuk mulai menerima pemberitahuan, klien memanggil metode IAudioSessionControl::RegisterAudioSessionNotification untuk mendaftarkan antarmuka IAudioSessionEvents-nya. Ketika klien tidak lagi memerlukan pemberitahuan, klien memanggil metode IAudioSessionControl::UnregisterAudioSessionNotification untuk menghapus pendaftaran.
Contoh kode berikut menunjukkan kemungkinan implementasi antarmuka 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;
}
};
Kelas CAudioSessionEvents dalam contoh kode sebelumnya adalah implementasi antarmuka IAudioSessionEvents. Implementasi khusus ini mungkin bagian dari aplikasi konsol yang mencetak informasi tentang peristiwa sesi ke jendela Prompt Perintah. Karena IAudioSessionEvents mewarisi dari IUnknown, definisi kelas berisi implementasi metode IUnknown AddRef, Release, dan QueryInterface. Metode publik yang tersisa dalam definisi kelas khusus untuk antarmuka IAudioSessionEvents .
Beberapa klien mungkin tidak tertarik untuk memantau semua jenis peristiwa sesi. Dalam contoh kode sebelumnya, beberapa metode pemberitahuan di kelas CAudioSessionEvents tidak melakukan apa pun. Misalnya, metode OnChannelVolumeChanged tidak melakukan apa pun kecuali mengembalikan kode status S_OK. Aplikasi ini tidak memantau volume saluran karena tidak mengubah volume saluran (dengan memanggil metode di antarmuka IChannelAudioVolume ), dan tidak berbagi sesi dengan aplikasi lain yang mungkin mengubah volume saluran.
Satu-satunya tiga metode di kelas CAudioSessionEvents yang memberi tahu pengguna tentang peristiwa sesi adalah OnSimpleVolumeChanged, OnStateChanged, dan OnSessionDisconnected. Misalnya, jika pengguna menjalankan program kontrol volume sistem, Sndvol, dan menggunakan kontrol volume di Sndvol untuk mengubah tingkat volume aplikasi, OnSimpleVolumeChanged
segera mencetak tingkat volume baru.
Untuk contoh kode yang mendaftarkan dan membatalkan pendaftaran antarmuka IAudioSessionEvents klien, lihat Peristiwa Audio untuk Aplikasi Audio Warisan.
Topik terkait