音訊會話事件
管理共用模式音訊數據流的應用程式可以註冊,以在會話事件發生時接收通知。 如先前所述,每個數據流都屬於 音訊會話。 會話事件是由音訊會話狀態的變更所起始。
用戶端應用程式可以註冊以接收下列會話事件的通知:
- 會話子混音的主要磁碟區層級或靜音狀態已變更。
- 會話子混音的一或多個通道的音量層級已變更。
- 會話已中斷連線。
- 會話的活動狀態已變更為作用中、非使用中或已過期。
- 會話已指派新的群組參數。
- 工作階段的使用者介面屬性已變更(圖示或顯示名稱)。
用戶端會透過其 IAudioSessionEvents 介面實作中的方法接收這些事件的通知。 不同於 WASAPI 系統模組實作的 WASAPI 中的其他介面,用戶端會實作 IAudioSessionEvents。 當會話事件發生時,這個介面中的方法會從 WASAPI 系統模組接收回呼。
為了開始接收通知,用戶端會呼叫 IAudioSessionControl::RegisterAudioSessionNotification 方法來註冊其 IAudioSessionEvents 介面。 當用戶端不再需要通知時,它會呼叫 IAudioSessionControl::UnregisterAudioSessionNotification 方法來刪除註冊。
下列程式代碼範例示範 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;
}
};
上述程式代碼範例中的 CAudioSessionEvents 類別是 IAudioSessionEvents 介面的實作。 這個特定實作可能是主控台應用程式的一部分,它會將會話事件的相關信息列印到命令提示字元視窗。 由於 IAudioSessionEvents 繼承自 IUnknown,因此類別定義包含 IUnknown 方法 AddRef、Release 和 QueryInterface 的實作。 類別定義中的其餘公用方法是 IAudioSessionEvents 介面特有的。
某些用戶端可能不想要監視所有類型的會話事件。 在上述程式代碼範例中,CAudioSessionEvents 類別中的數個通知方法不會執行任何動作。 例如, OnChannelVolumeChanged 方法除了傳回狀態代碼S_OK以外,不會執行任何動作。 此應用程式不會監視通道磁碟區,因為它不會變更通道磁碟區(藉由在 IChannelAudioVolume 介面中呼叫 方法),也不會與其他可能變更通道磁碟區的應用程式共享會話。
CAudioSessionEvents 類別中唯一通知用戶會話事件的三種方法是 OnSimpleVolumeChanged、OnStateChanged 和 OnSessionDisconnected。 例如,如果使用者執行系統磁碟區控制程式 Sndvol,並使用 Sndvol 中的磁碟區控制來變更應用程式的磁碟區層級, OnSimpleVolumeChanged
請立即列印新的磁碟區層級。
如需註冊和取消註冊用戶端 IAudioSessionEvents 介面的程式代碼範例,請參閱舊版音訊應用程式的音訊事件。
相關主題