Partilhar via


Eventos de 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 do submix de sessão foi alterado.
  • A sessão foi desligada.
  • O estado da atividade da sessão foi alterado para ativo, inativo ou expirado.
  • A sessão recebeu um novo parâmetro de agrupamento.
  • Uma propriedade da 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 do interface IAudioSessionEvents. Ao contrário das outras interfaces em WASAPI, que são implementadas pelo módulo de sistema WASAPI, o cliente implementa IAudioSessionEvents. Os métodos nesta 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 IAudioSessionControl::RegisterAudioSessionNotification método para registrar seu IAudioSessionEvents interface. Quando o cliente não precisa mais de notificações, ele chama o IAudioSessionControl::UnregisterAudioSessionNotification método para excluir o registro.

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

A classe CAudioSessionEvents no exemplo de código anterior é uma implementação do IAudioSessionEvents interface. 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 IUnknownAddRef, Releasee QueryInterface. Os métodos públicos restantes na definição de classe são específicos para o IAudioSessionEvents interface.

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. Esta aplicação não monitoriza os volumes de canal porque não altera os volumes de canal (chamando os métodos na interfaceIChannelAudioVolume) e não partilha a sessão com outras aplicações que possam alterar os volumes de canal.

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

Para obter um exemplo de código que registra e cancela o registro da interfaceIAudioSessionEvents de umcliente, consulte Audio Events for Legacy Audio Applications.

Sessões de áudio