Delen via


Audiosessie-gebeurtenissen

Een toepassing die audiostreams in de gedeelde modus beheert, kan zich registreren om meldingen te ontvangen wanneer er sessiegebeurtenissen plaatsvinden. Zoals eerder uitgelegd, behoort elke stream tot een audiosessie. Een sessie-gebeurtenis wordt gestart door een wijziging in de status van een audiosessie.

Een clienttoepassing kan zich registreren om meldingen te ontvangen van de volgende typen sessie-gebeurtenissen:

  • Het volumeniveau van de master of dempingsstatus van de sessiesubmix is gewijzigd.
  • Het volumeniveau van een of meer kanalen van de sessiesubmix is gewijzigd.
  • De verbinding met de sessie is verbroken.
  • De activiteitsstatus van de sessie is gewijzigd in actief, inactief of verlopen.
  • Aan de sessie is een nieuwe groeperingsparameter toegewezen.
  • Een eigenschap van de gebruikersinterface van de sessie (pictogram of weergavenaam) is gewijzigd.

De client ontvangt meldingen van deze gebeurtenissen via de methoden in de implementatie van de IAudioSessionEvents interface. In tegenstelling tot de andere interfaces in WASAPI, die worden geïmplementeerd door de WASAPI-systeemmodule, implementeert de client IAudioSessionEvents. De methoden in deze interface ontvangen callbacks van de WASAPI-systeemmodule wanneer sessiegebeurtenissen plaatsvinden.

Om meldingen te ontvangen, roept de client de methode IAudioSessionControl::RegisterAudioSessionNotification methode aan om de IAudioSessionEvents interface te registreren. Wanneer de client geen meldingen meer nodig heeft, wordt de methode IAudioSessionControl::UnregisterAudioSessionNotification methode aangeroepen om de registratie te verwijderen.

In het volgende codevoorbeeld ziet u een mogelijke implementatie van de IAudioSessionEvents interface:

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

De klasse CAudioSessionEvents in het voorgaande codevoorbeeld is een implementatie van de IAudioSessionEvents interface. Deze specifieke implementatie maakt mogelijk deel uit van een consoletoepassing waarmee informatie over sessie-gebeurtenissen wordt afgedrukt naar een opdrachtpromptvenster. Omdat IAudioSessionEvents overgenomen van IUnknown-, bevat de klassedefinitie implementaties van de IUnknown methoden AddRef, Releaseen QueryInterface. De resterende openbare methoden in de klassedefinitie zijn specifiek voor de IAudioSessionEvents interface.

Sommige clients zijn mogelijk niet geïnteresseerd in het bewaken van alle typen sessie-gebeurtenissen. In het voorgaande codevoorbeeld doen verschillende meldingsmethoden in de klasse CAudioSessionEvents niets. De methode OnChannelVolumeChanged doet bijvoorbeeld niets behalve het retourneren van statuscode S_OK. Deze toepassing bewaakt geen kanaalvolumes omdat het kanaalvolumes niet wijzigt (door de methoden aan te roepen in de interface IChannelAudioVolume) en de sessie niet deelt met andere toepassingen die de kanaalvolumes kunnen wijzigen.

De enige drie methoden in de klasse CAudioSessionEvents die de gebruiker op de hoogte stellen van sessiegebeurtenissen, worden OnSimpleVolumeChanged, OnStateChangeden OnSessionDisconnected. Als de gebruiker bijvoorbeeld het volumeregelingsprogramma van het systeem uitvoert, Sndvol en de volumeregeling in Sndvol gebruikt om het volumeniveau van de toepassing te wijzigen, OnSimpleVolumeChanged het nieuwe volumeniveau onmiddellijk afdrukken.

Zie voor een codevoorbeeld dat de IAudioSessionEvents interface van een client registreert en de registratie ervan ongedaan maakt, Audio-gebeurtenissen voor verouderde audiotoepassingen.

audiosessies