Udostępnij za pośrednictwem


Zdarzenia sesji audio

Aplikacja, która zarządza strumieniami audio w trybie udostępnionym, może rejestrować się w celu odbierania powiadomień po wystąpieniu zdarzeń sesji. Jak wyjaśniono wcześniej, każdy strumień należy do sesji audio . Zdarzenie sesji jest inicjowane przez zmianę stanu sesji audio.

Aplikacja kliencka może zarejestrować się w celu otrzymywania powiadomień o następujących typach zdarzeń sesji:

  • Poziom woluminu głównego lub stan wyciszenia podmiksu sesji uległ zmianie.
  • Poziom woluminu co najmniej jednego kanału podmiksu sesji uległ zmianie.
  • Sesja została rozłączona.
  • Stan działania sesji został zmieniony na aktywny, nieaktywny lub wygasł.
  • Sesja została przypisana do nowego parametru grupowania.
  • Zmieniono właściwość interfejsu użytkownika sesji (ikona lub nazwa wyświetlana).

Klient odbiera powiadomienia o tych zdarzeniach za pośrednictwem metod w implementacji interfejsu IAudioSessionEvents. W przeciwieństwie do innych interfejsów w interfejsie WASAPI, które są implementowane przez moduł systemu WASAPI, klient implementuje IAudioSessionEvents. Metody w tym interfejsie odbierają wywołania zwrotne z modułu systemu WASAPI po wystąpieniu zdarzeń sesji.

Aby rozpocząć odbieranie powiadomień, klient wywołuje metodę IAudioSessionControl::RegisterAudioSessionNotification metodę rejestrowania interfejsu IAudioSessionEvents. Gdy klient nie wymaga już powiadomień, wywołuje metodę IAudioSessionControl::UnregisterAudioSessionNotification metodę w celu usunięcia rejestracji.

Poniższy przykład kodu przedstawia możliwą implementację interfejsu 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;
    }
};

Klasa CAudioSessionEvents w poprzednim przykładzie kodu to implementacja interfejsu IAudioSessionEvents. Ta konkretna implementacja może być częścią aplikacji konsolowej, która wyświetla informacje o zdarzeniach sesji w oknie wiersza polecenia. Ponieważ IAudioSessionEvents dziedziczy z IUnknown, definicja klasy zawiera implementacje metod IUnknownAddRef, Releasei QueryInterface. Pozostałe metody publiczne w definicji klasy są specyficzne dla interfejsu IAudioSessionEvents.

Niektórzy klienci mogą nie być zainteresowani monitorowaniem wszystkich typów zdarzeń sesji. W poprzednim przykładzie kodu kilka metod powiadomień w klasie CAudioSessionEvents nic nie robi. Na przykład metoda OnChannelVolumeChanged nie zwraca kodu stanu S_OK. Ta aplikacja nie monitoruje woluminów kanałów, ponieważ nie zmienia woluminów kanału (wywołując metody w interfejsie IChannelAudioVolume) i nie udostępnia sesji innym aplikacjom, które mogą zmienić woluminy kanału.

Jedyne trzy metody w klasie CAudioSessionEvents, które powiadamiają użytkownika o zdarzeniach sesji, to OnSimpleVolumeChanged, OnStateChangedi OnSessionDisconnected. Jeśli na przykład użytkownik uruchamia systemowy program sterowania woluminami, Sndvol i używa kontrolki głośności w usłudze Sndvol do zmiany poziomu woluminu aplikacji, OnSimpleVolumeChanged natychmiast wyświetla nowy poziom woluminu.

Aby zapoznać się z przykładem kodu, który rejestruje i wyrejestrowuje interfejs IAudioSessionEvents, zobacz Audio Events for Legacy Audio Applications.

sesji audio