Compartilhar via


Eventos da sessão de áudio

Um aplicativo que gerencia fluxos de áudio de modo compartilhado pode se registrar para receber notificações quando ocorrerem eventos de sessão. Como explicado anteriormente, cada fluxo pertence a uma sessão de áudio. Um evento de sessão é iniciado por uma alteração no status de uma sessão de áudio.

Um aplicativo cliente pode se registrar para receber notificações dos seguintes tipos de eventos de sessão:

  • O nível de volume mestre ou o estado de silenciamento da submistura de sessão foi alterado.
  • O nível de volume de um ou mais canais da submistura de sessão foi alterado.
  • A sessão foi desconectada.
  • O estado de atividade da sessão foi alterado para ativo, inativo ou expirado.
  • A sessão recebeu um novo parâmetro de agrupamento.
  • Uma propriedade de interface do usuário da sessão (ícone ou nome para exibição) foi alterada.

O cliente recebe notificações desses eventos através dos métodos em sua implementação da interface IAudioSessionEvents. Ao contrário das outras interfaces no WASAPI, que são implementadas pelo módulo do sistema WASAPI, o cliente implementa IAudioSessionEvents. Os métodos nessa interface recebem retornos de chamada do módulo do sistema WASAPI quando ocorrem eventos de sessão.

Para começar a receber notificações, o cliente chama o método IAudioSessionControl::RegisterAudioSessionNotification para registrar sua interface IAudioSessionEvents. Quando o cliente não requer mais notificações, ele chama o método IAudioSessionControl::UnregisterAudioSessionNotification para excluir o registro.

O exemplo de código a seguir mostra uma possível implementação da interface 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;
    }
};

A classe CAudioSessionEvents no exemplo de código anterior é uma implementação da interface IAudioSessionEvents. Essa implementação específica pode fazer parte de um aplicativo de console que imprime informações sobre eventos de sessão em uma janela do Prompt de Comando. Como IAudioSessionEvents herda de IUnknown, a definição de classe contém implementações dos métodos IUnknown AddRef, Release e QueryInterface. Os métodos públicos restantes na definição de classe são específicos para a interface IAudioSessionEvents .

Alguns clientes podem não estar interessados em monitorar todos os tipos de eventos de sessão. No exemplo de código anterior, vários métodos de notificação na classe CAudioSessionEvents não fazem nada. Por exemplo, o método OnChannelVolumeChanged não faz nada além de retornar o código de status S_OK. Este aplicativo não monitora volumes de canal porque ele não altera os volumes de canal (chamando os métodos na interface IChannelAudioVolume ) e não compartilha a sessão com outros aplicativos que podem alterar os volumes de canal.

Os únicos três métodos na classe CAudioSessionEvents que notificam o usuário de eventos de sessão são OnSimpleVolumeChanged, OnStateChanged e OnSessionDisconnected. Por exemplo, se o usuário executar o programa de controle de volume do sistema, Sndvol, e usar o controle de volume no Sndvol para alterar o nível de volume do aplicativo, OnSimpleVolumeChanged imprimirá imediatamente o novo nível de volume.

Para obter um exemplo de código que registra e cancela o registro da interface IAudioSessionEvents de um cliente, consulte Eventos de áudio para aplicativos de áudio herdados.

Sessões de Áudio