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 Stream zu einer Audiositzung. Ein Sitzungsereignis wird durch eine Änderung im status einer Audiositzung initiiert.

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

  • Der master Lautstärkeebene oder des Stummschaltzustands des Sitzungsuntermixes wurde geändert.
  • Die Lautstärkeebene eines oder mehrerer Kanäle des Sitzungsuntermix 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ächeneigenschaft der Sitzung (Symbol oder Anzeigename) wurde geändert.

Der Client empfängt Benachrichtigungen zu diesen Ereignissen über die Methoden in seiner 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 erhalten Rückrufe aus dem WASAPI-Systemmodul, wenn Sitzungsereignisse auftreten.

Um Benachrichtigungen zu erhalten, ruft der Client die IAudioSessionControl::RegisterAudioSessionNotification-Methode auf, um die 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 einem Eingabeaufforderungsfenster ausgibt. Da IAudioSessionEvents von IUnknown erbt, enthält die Klassendefinition Implementierungen der IUnknown-MethodenAddRef, Release und QueryInterface. Die restlichen ö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 beispielsweise nichts anderes aus, als status Code S_OK zurückzugeben. Diese Anwendung überwacht keine Kanalvolumes, da sie die Kanalvolumes nicht ändert (indem sie die Methoden in der IChannelAudioVolume-Schnittstelle aufruft ) und die Sitzung nicht für andere Anwendungen freigibt, die die Kanalvolumes möglicherweise ändern.

Die einzigen drei Methoden in der CAudioSessionEvents-Klasse, die den Benutzer über Sitzungsereignisse benachrichtigen, sind OnSimpleVolumeChanged, OnStateChanged und OnSessionDisconnected. Wenn der Benutzer beispielsweise das Systemvolumesteuerungsprogramm Sndvol ausführt und die Lautstärkeregelung in Sndvol verwendet, um die Lautstärkeebene der Anwendung zu ändern, OnSimpleVolumeChanged druckt sofort die neue Volumeebene.

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

Audiositzungen