共用方式為


音訊會話事件

管理共用模式音訊數據流的應用程式可以註冊,以在會話事件發生時接收通知。 如先前所述,每個數據流都屬於 音訊會話。 會話事件是由音訊會話狀態的變更所起始。

用戶端應用程式可以註冊以接收下列會話事件的通知:

  • 會話子混音的主要磁碟區層級或靜音狀態已變更。
  • 會話子混音的一或多個通道的音量層級已變更。
  • 會話已中斷連線。
  • 會話的活動狀態已變更為作用中、非使用中或已過期。
  • 會話已指派新的群組參數。
  • 工作階段的使用者介面屬性已變更(圖示或顯示名稱)。

用戶端會透過其 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 方法 AddRefReleaseQueryInterface實作。 類別定義中的其餘公用方法是 IAudioSessionEvents 介面特有的

某些用戶端可能不想要監視所有類型的會話事件。 在上述程式代碼範例中,CAudioSessionEvents 類別中的數個通知方法不會執行任何動作。 例如, OnChannelVolumeChanged 方法除了傳回狀態代碼S_OK以外,不會執行任何動作。 此應用程式不會監視通道磁碟區,因為它不會變更通道磁碟區(藉由在 IChannelAudioVolume 介面中呼叫 方法),也不會與其他可能變更通道磁碟區的應用程式共享會話。

CAudioSessionEvents 類別中唯一通知用戶會話事件的三種方法是 OnSimpleVolumeChanged、OnStateChanged OnSessionDisconnected。 例如,如果使用者執行系統磁碟區控制程式 Sndvol,並使用 Sndvol 中的磁碟區控制來變更應用程式的磁碟區層級, OnSimpleVolumeChanged 請立即列印新的磁碟區層級。

如需註冊和取消註冊用戶端 IAudioSessionEvents 介面的程式代碼範例,請參閱舊版音訊應用程式的音訊事件。

音訊會話