Condividi tramite


Eventi di sessione audio

Un'applicazione che gestisce flussi audio in modalità condivisa può registrarsi per ricevere notifiche quando si verificano eventi di sessione. Come spiegato in precedenza, ogni flusso appartiene a una sessione audio. Un evento di sessione viene avviato da una modifica dello stato di una sessione audio.

Un'applicazione client può registrarsi per ricevere notifiche dei tipi di eventi di sessione seguenti:

  • Il livello del volume master o lo stato di disattivazione della sottomix sessione è cambiato.
  • Il livello di volume di uno o più canali del submix della sessione è cambiato.
  • La sessione è stata disconnessa.
  • Lo stato dell'attività della sessione è stato modificato in attivo, inattivo o scaduto.
  • Alla sessione è stato assegnato un nuovo parametro di raggruppamento.
  • È stata modificata una proprietà dell'interfaccia utente della sessione (icona o nome visualizzato).

Il client riceve notifiche di questi eventi tramite i metodi nell'implementazione dell'interfaccia IAudioSessionEvents . A differenza delle altre interfacce in WASAPI, implementate dal modulo di sistema WASAPI, il client implementa IAudioSessionEvents. I metodi in questa interfaccia ricevono callback dal modulo di sistema WASAPI quando si verificano eventi di sessione.

Per iniziare a ricevere notifiche, il client chiama il metodo IAudioSessionControl::RegisterAudioSessionNotification per registrare l'interfaccia IAudioSessionEvents. Quando il client non richiede più notifiche, chiama il metodo IAudioSessionControl::UnregisterAudioSessionNotification per eliminare la registrazione.

L'esempio di codice seguente illustra una possibile implementazione dell'interfaccia 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;
    }
};

La classe CAudioSessionEvents nell'esempio di codice precedente è un'implementazione dell'interfaccia IAudioSessionEvents . Questa particolare implementazione potrebbe far parte di un'applicazione console che stampa informazioni sugli eventi di sessione in una finestra del prompt dei comandi. Poiché IAudioSessionEvents eredita da IUnknown, la definizione della classe contiene implementazioni dei metodi IUnknown AddRef, Release e QueryInterface. I metodi pubblici rimanenti nella definizione della classe sono specifici dell'interfaccia IAudioSessionEvents .

Alcuni client potrebbero non essere interessati al monitoraggio di tutti i tipi di eventi di sessione. Nell'esempio di codice precedente diversi metodi di notifica nella classe CAudioSessionEvents non eseguono alcuna operazione. Ad esempio, il metodo OnChannelVolumeChanged non esegue alcuna operazione tranne che per restituire il codice di stato S_OK. Questa applicazione non monitora i volumi dei canali perché non modifica i volumi di canale (chiamando i metodi nell'interfaccia IChannelAudioVolume ) e non condivide la sessione con altre applicazioni che potrebbero modificare i volumi del canale.

Gli unici tre metodi nella classe CAudioSessionEvents che informano l'utente degli eventi di sessione sono OnSimpleVolumeChanged, OnStateChanged e OnSessionDisconnected. Ad esempio, se l'utente esegue il programma di controllo del volume di sistema, Sndvol e usa il controllo volume in Sndvol per modificare il livello del volume dell'applicazione, OnSimpleVolumeChanged stampa immediatamente il nuovo livello di volume.

Per un esempio di codice che registra e annulla la registrazione dell'interfaccia IAudioSessionEvents di un client, vedi Eventi audio per applicazioni audio legacy.

Sessioni audio