Eventos de sessão de áudio
Um aplicativo que gerencia fluxos de áudio de modo compartilhado pode se registrar para receber notificações quando ocorrem eventos de sessão. Conforme 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 mudo do submixo 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 desconectada.
- 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 de interface do usuário da sessão (ícone ou nome de exibição) foi alterada.
O cliente recebe notificações desses eventos por meio dos métodos em sua implementação da interfaceIAudioSessionEvents. 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 método para excluir o registro.
O exemplo de código a seguir mostra uma possível implementação da interfaceIAudioSessionEvents:
//-----------------------------------------------------------
// 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 em particular 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 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étodoOnChannelVolumeChanged não faz nada além de retornar o código de status S_OK. Esse aplicativo não monitora volumes de canal porque não altera os volumes de canal (chamando os métodos na interfaceIChannelAudioVolume) 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, OnStateChangede OnSessionDisconnected. Por exemplo, se o usuário executar o programa de controle de volume do sistema, o 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 interfaceIAudioSessionEvents de um cliente, consulte Eventos de Áudio para Aplicativos de Áudio Herdados.
Tópicos relacionados