Freigeben über


Audiositzungsereignisse

Eine Anwendung, die Audiostreams im freigegebenen Modus verwaltet, kann sich registrieren, um Benachrichtigungen zu empfangen, wenn Sitzungsereignisse auftreten. Wie bereits erläutert, gehört jeder Datenstrom zu einer Audiositzung. Ein Sitzungsereignis wird durch eine Änderung des Status einer Audiositzung initiiert.

Eine Clientanwendung kann sich registrieren, um Benachrichtigungen über die folgenden Arten von Sitzungsereignissen zu erhalten:

  • Die Masterlautstärke oder der Stummschaltungszustand des Sitzungs-Submixes wurde geändert.
  • Die Lautstärke eines oder mehrerer Kanäle des Sitzungs-Submixes wurde geändert.
  • Die Sitzung wurde getrennt.
  • Der Aktivitätsstatus der Sitzung wurde in "aktiv", "inaktiv" oder "abgelaufen" geändert.
  • Der Sitzung wurde ein neuer Gruppierungsparameter zugewiesen.
  • Eine Benutzeroberfläche-Eigenschaft der Sitzung (Symbol oder Anzeigename) wurde geändert.

Der Client empfängt Benachrichtigungen über diese Ereignisse über die Methoden in der Implementierung der IAudioSessionEvents Schnittstelle. Im Gegensatz zu den anderen Schnittstellen in WASAPI, die vom WASAPI-Systemmodul implementiert werden, implementiert der Client IAudioSessionEvents. Die Methoden in dieser Schnittstelle empfangen Rückrufe vom WASAPI-Systemmodul, wenn Sitzungsereignisse auftreten.

Um mit dem Empfangen von Benachrichtigungen zu beginnen, ruft der Client die IAudioSessionControl::RegisterAudioSessionNotification Methode auf, um seine IAudioSessionEvents- Schnittstelle zu registrieren. Wenn der Client keine Benachrichtigungen mehr benötigt, ruft er die IAudioSessionControl::UnregisterAudioSessionNotification Methode auf, um die Registrierung zu löschen.

Das folgende Codebeispiel zeigt eine mögliche Implementierung der IAudioSessionEvents Schnittstelle:

//-----------------------------------------------------------
// 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;
    }
};

Die CAudioSessionEvents-Klasse im vorherigen Codebeispiel ist eine Implementierung der IAudioSessionEvents Schnittstelle. Diese spezielle Implementierung kann Teil einer Konsolenanwendung sein, die Informationen zu Sitzungsereignissen in ein Eingabeaufforderungsfenster druckt. Da IAudioSessionEvents von IUnknownerbt, enthält die Klassendefinition Implementierungen der IUnknown Methoden AddRef, Releaseund QueryInterface. Die verbleibenden öffentlichen Methoden in der Klassendefinition sind spezifisch für die IAudioSessionEvents- Schnittstelle.

Einige Clients sind möglicherweise nicht daran interessiert, alle Arten von Sitzungsereignissen zu überwachen. Im vorherigen Codebeispiel führen mehrere Benachrichtigungsmethoden in der CAudioSessionEvents-Klasse nichts aus. Die OnChannelVolumeChanged--Methode führt z. B. nichts aus, als Statuscode S_OK zurückzugeben. Diese Anwendung überwacht keine Kanalvolumes, da sie die Kanalvolumes nicht ändert (durch Aufrufen der Methoden im IChannelAudioVolume Schnittstelle), und sie gibt die Sitzung nicht für andere Anwendungen frei, die die Kanalvolumes ändern können.

Die einzigen drei Methoden in der CAudioSessionEvents-Klasse, die den Benutzer über Sitzungsereignisse benachrichtigen, sind OnSimpleVolumeChanged, OnStateChangedund OnSessionDisconnected. Wenn der Benutzer z. B. das Systemlautstärkeprogramm Sndvol ausführt und die Lautstärkeregelung in Sndvol verwendet, um die Lautstärke der Anwendung zu ändern, OnSimpleVolumeChanged sofort die neue Volumeebene druckt.

Ein Codebeispiel zum Registrieren und Aufheben der Registrierung des IAudioSessionEvents--Schnittstelle eines Clients finden Sie unter Audioereignisse für Legacyaudioanwendungen.

Audiositzungen