Compartir a través de


Eventos de sesión de audio

Una aplicación que administra secuencias de audio en modo compartido puede registrarse para recibir notificaciones cuando se producen eventos de sesión. Como se explicó anteriormente, cada secuencia pertenece a una sesión de audio. Un evento de sesión se inicia mediante un cambio en el estado de una sesión de audio.

Una aplicación cliente puede registrarse para recibir notificaciones de los siguientes tipos de eventos de sesión:

  • El nivel de volumen maestro o el estado de silenciamiento de la submezcla de sesión ha cambiado.
  • El nivel de volumen de uno o varios canales de la submezcla de sesión ha cambiado.
  • La sesión se ha desconectado.
  • El estado de actividad de la sesión ha cambiado a activo, inactivo o expirado.
  • A la sesión se le ha asignado un nuevo parámetro de agrupación.
  • Ha cambiado una propiedad de interfaz de usuario de la sesión (icono o nombre para mostrar).

El cliente recibe notificaciones de estos eventos a través de los métodos en su implementación de la interfaz IAudioSessionEvents . A diferencia de las otras interfaces de WASAPI, que implementa el módulo del sistema WASAPI, el cliente implementa IAudioSessionEvents. Los métodos de esta interfaz reciben devoluciones de llamada del módulo del sistema WASAPI cuando se producen eventos de sesión.

Para empezar a recibir notificaciones, el cliente llama al método IAudioSessionControl::RegisterAudioSessionNotification para registrar su interfaz IAudioSessionEvents . Cuando el cliente ya no requiere notificaciones, llama al método IAudioSessionControl::UnregisterAudioSessionNotification para eliminar el registro.

En el ejemplo de código siguiente se muestra una posible implementación de la interfaz 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 clase CAudioSessionEvents del ejemplo de código anterior es una implementación de la interfaz IAudioSessionEvents . Esta implementación determinada puede formar parte de una aplicación de consola que imprime información sobre los eventos de sesión en una ventana del símbolo del sistema. Dado que IAudioSessionEvents hereda de IUnknown, la definición de clase contiene implementaciones de los métodos IUnknownAddRef, Release y QueryInterface. Los métodos públicos restantes de la definición de clase son específicos de la interfaz IAudioSessionEvents .

Es posible que algunos clientes no estén interesados en supervisar todos los tipos de eventos de sesión. En el ejemplo de código anterior, varios métodos de notificación de la clase CAudioSessionEvents no hacen nada. Por ejemplo, el método OnChannelVolumeChanged no hace nada excepto devolver el código de estado S_OK. Esta aplicación no supervisa los volúmenes de canal porque no cambia los volúmenes de canal (llamando a los métodos de la interfaz IChannelAudioVolume ) y no comparte la sesión con otras aplicaciones que podrían cambiar los volúmenes del canal.

Los únicos tres métodos de la clase CAudioSessionEvents que notifican al usuario los eventos de sesión son OnSimpleVolumeChanged, OnStateChanged y OnSessionDisconnected. Por ejemplo, si el usuario ejecuta el programa de control de volumen del sistema, Sndvol y usa el control de volumen en Sndvol para cambiar el nivel de volumen de la aplicación, OnSimpleVolumeChanged imprime inmediatamente el nuevo nivel de volumen.

Para obtener un ejemplo de código que registra y anula el registro de la interfaz IAudioSessionEvents de un cliente, vea Eventos de audio para aplicaciones de audio heredadas.

Sesiones de audio