Renderizador de Áudio de Streaming

O SAR (renderizador de áudio de streaming) é um coletor de mídia que renderiza áudio. Cada instância do SAR renderiza um único fluxo de áudio. Para renderizar vários fluxos, use várias instâncias do SAR.

Para criar o SAR, chame uma das seguintes funções:

A segunda função, que retorna um objeto de ativação, será necessária se você estiver reproduzindo conteúdo protegido, pois o objeto de ativação deve ser serializado para o processo protegido. Para obter conteúdo claro, você pode usar qualquer função.

O SAR pode receber áudio não compactado no formato de ponto flutuante PCM ou IEEE. Se a taxa de reprodução for mais rápida ou mais lenta que 1×, o SAR ajustará automaticamente o tom.

Configurando o Renderizador de Áudio

O SAR dá suporte a vários atributos de configuração. O mecanismo para definir esses atributos depende de qual função você chama para criar o SAR. Se você usar a função MFCreateAudioRenderer , faça o seguinte:

  1. Crie um novo repositório de atributos chamando MFCreateAttributes.
  2. Adicione os atributos ao repositório de atributos.
  3. Passe o repositório de atributos para a função MFCreateAudioRenderer no parâmetro pAudioAttributes .

Se você usar a função MFCreateAudioRendererActivate , a função retornará um ponteiro para a interface IMFAttributes no parâmetro ppActivate . Use esse ponteiro para adicionar os atributos.

Para obter uma lista de atributos de configuração, consulte Atributos do Renderizador de Áudio.

Selecionando o dispositivo de ponto de extremidade de áudio

Um dispositivo de ponto de extremidade de áudio é um dispositivo de hardware que renderiza ou captura áudio. Exemplos incluem alto-falantes, fones de ouvido, microfones e cd players. O SAR sempre usa um dispositivo de renderização de áudio. Há duas maneiras de selecionar o dispositivo.

A primeira abordagem é enumerar os dispositivos de renderização de áudio no sistema, usando a interface IMMDeviceEnumerator . Essa interface está documentada na documentação principal da API de áudio.

  1. Crie o objeto enumerador de dispositivo.
  2. Use o enumerador de dispositivo para enumerar dispositivos de renderização de áudio. Cada dispositivo é representado por um ponteiro para a interface IMMDevice .
  3. Selecione um dispositivo, com base nas propriedades do dispositivo ou na seleção do usuário.
  4. Chame IMMDevice::GetId para obter o identificador do dispositivo.
  5. Defina o identificador do dispositivo como o valor do atributo MF_AUDIO_RENDERER_ATTRIBUTE_ENDPOINT_ID .

Em vez de enumerar dispositivos, você pode especificar o dispositivo de áudio por sua função. Uma função de áudio identifica uma categoria geral de uso. Por exemplo, a função de console é definida para jogos e notificações do sistema, enquanto a função multimídia é definida para músicas e filmes. Cada função tem um dispositivo de renderização de áudio atribuído a ele e o usuário pode alterar essas atribuições. Se você especificar uma função de dispositivo, o SAR usará qualquer dispositivo de áudio atribuído para essa função. Para especificar a função de dispositivo, defina o atributo MF_AUDIO_RENDERER_ATTRIBUTE_ENDPOINT_ROLE .

Os dois atributos listados nesta seção são mutuamente exclusivos. Se você não definir nenhum deles, o SAR usará o dispositivo de áudio atribuído à função eConsole .

O código a seguir enumera os dispositivos de renderização de áudio e atribui o primeiro dispositivo na lista ao SAR. Este exemplo usa a função MFCreateAudioRenderer para criar o SAR.

#include <mmdeviceapi.h>

HRESULT hr = S_OK;

IMMDeviceEnumerator *pEnum = NULL;      // Audio device enumerator.
IMMDeviceCollection *pDevices = NULL;   // Audio device collection.
IMMDevice *pDevice = NULL;              // An audio device.
IMFAttributes *pAttributes = NULL;      // Attribute store.
IMFMediaSink *pSink = NULL;             // Streaming audio renderer (SAR)

LPWSTR wstrID = NULL;                   // Device ID.

// Create the device enumerator.
hr = CoCreateInstance(
    __uuidof(MMDeviceEnumerator), 
    NULL,
    CLSCTX_ALL, 
    __uuidof(IMMDeviceEnumerator), 
    (void**)&pEnum
    );

// Enumerate the rendering devices.
if (SUCCEEDED(hr))
{
    hr = pEnum->EnumAudioEndpoints(eRender, DEVICE_STATE_ACTIVE, &pDevices);
}

// Get ID of the first device in the list.
if (SUCCEEDED(hr))
{
    hr = pDevices->Item(0, &pDevice);
}

if (SUCCEEDED(hr))
{
    hr = pDevice->GetId(&wstrID);
}

// Create an attribute store and set the device ID attribute.
if (SUCCEEDED(hr))
{
    hr = MFCreateAttributes(&pAttributes, 2);
}

if (SUCCEEDED(hr))
{
    hr = pAttributes->SetString(
        MF_AUDIO_RENDERER_ATTRIBUTE_ENDPOINT_ID, 
        wstrID
        );
}

// Create the audio renderer.
if (SUCCEEDED(hr))
{
    hr = MFCreateAudioRenderer(pAttributes, &pSink);    
}

SAFE_RELEASE(pEnum);
SAFE_RELEASE(pDevices);
SAFE_RELEASE(pDevice); 
SAFE_RELEASE(pAttributes);
CoTaskMemFree(wstrID);

Para criar o objeto de ativação para o SAR, altere o código que aparece após a chamada para IMMDevice::GetId para o seguinte:

IMFActivate *pActivate = NULL;          // Activation object.

if (SUCCEEDED(hr))
{
    hr = MFCreateAudioRendererActivate(&pActivate);    
}

if (SUCCEEDED(hr))
{
    hr = pActivate->SetString(
        MF_AUDIO_RENDERER_ATTRIBUTE_ENDPOINT_ID, 
        wstrID
        );
}

SAFE_RELEASE(pActivate);

Selecionando a Sessão de Áudio

Uma sessão de áudio é um grupo de fluxos de áudio relacionados que um aplicativo pode gerenciar coletivamente. O aplicativo pode controlar o nível de volume e silenciar o estado de cada sessão. As sessões são identificadas pelo GUID. Para especificar a sessão de áudio para o SAR, use o atributo MF_AUDIO_RENDERER_ATTRIBUTE_SESSION_ID . Se você não definir esse atributo, o SAR unirá a sessão padrão para esse processo, identificada por GUID_NULL.

Por padrão, uma sessão de áudio é específica do processo, o que significa que ela contém apenas fluxos do processo de chamada. Para ingressar em uma sessão entre processos, defina o atributo MF_AUDIO_RENDERER_ATTRIBUTE_FLAGS com o valor MF_AUDIO_RENDERER_ATTRIBUTE_FLAGS_CROSSPROCESS.

Depois de criar o SAR, você usa a interface IMFAudioPolicy para ingressar a sessão em um grupo de sessões, todas controladas pelo mesmo controle de volume no painel de controle. Você também pode usar essa interface para definir o nome de exibição e o ícone que aparecem no controle de volume.

Controlando níveis de volume

Para controlar o nível de volume master de todos os fluxos na sessão de áudio do SAR, use a interface IMFSimpleAudioVolume. Para controlar o volume de um fluxo individual ou controlar o volume de canais individuais em um fluxo, use a interface IMFAudioStreamVolume . Ambas as interfaces são obtidas chamando IMFGetService::GetService. Você pode chamar GetService diretamente no SAR ou chamá-lo na Sessão de Mídia. Os níveis de volume são expressos como valores de atenuação. Para cada canal, o nível de atenuação é o produto do volume master e do volume do canal.

Reprodução de áudio/vídeo