Método IAudioClient::Initialize (audioclient.h)

O método Initialize inicializa o fluxo de áudio.

Sintaxe

HRESULT Initialize(
  [in] AUDCLNT_SHAREMODE  ShareMode,
  [in] DWORD              StreamFlags,
  [in] REFERENCE_TIME     hnsBufferDuration,
  [in] REFERENCE_TIME     hnsPeriodicity,
  [in] const WAVEFORMATEX *pFormat,
  [in] LPCGUID            AudioSessionGuid
);

Parâmetros

[in] ShareMode

O modo de compartilhamento para a conexão. Por meio desse parâmetro, o cliente informa ao mecanismo de áudio se deseja compartilhar o dispositivo de ponto de extremidade de áudio com outros clientes. O cliente deve definir esse parâmetro como um dos seguintes valores de enumeração AUDCLNT_SHAREMODE :

AUDCLNT_SHAREMODE_EXCLUSIVE

AUDCLNT_SHAREMODE_SHARED

[in] StreamFlags

Sinalizadores para controlar a criação do fluxo. O cliente deve definir esse parâmetro como 0 ou para o OR bit a bit de uma ou mais constantes AUDCLNT_STREAMFLAGS_XXX ou as constantes AUDCLNT_SESSIONFLAGS_XXX.

[in] hnsBufferDuration

A capacidade do buffer como um valor de tempo. Esse parâmetro é do tipo REFERENCE_TIME e é expresso em unidades de 100 nanossegundos. Esse parâmetro contém o tamanho do buffer que o chamador solicita para o buffer que o aplicativo de áudio compartilhará com o mecanismo de áudio (no modo compartilhado) ou com o dispositivo de ponto de extremidade (no modo exclusivo). Se a chamada for bem-sucedida, o método alocará um buffer que seja pelo menos tão grande. Para obter mais informações sobre REFERENCE_TIME, consulte a documentação do SDK do Windows. Para obter mais informações sobre os requisitos de buffer, consulte Comentários.

[in] hnsPeriodicity

O período do dispositivo. Esse parâmetro pode ser diferente de zero somente no modo exclusivo. No modo compartilhado, sempre defina esse parâmetro como 0. No modo exclusivo, esse parâmetro especifica o período de agendamento solicitado para acessos sucessivos de buffer pelo dispositivo de ponto de extremidade de áudio. Se o período de dispositivo solicitado estiver fora do intervalo definido pelo período mínimo do dispositivo e pelo período máximo do sistema, o método fixa o período nesse intervalo. Se esse parâmetro for 0, o método definirá o período do dispositivo como seu valor padrão. Para obter o período padrão do dispositivo, chame o método IAudioClient::GetDevicePeriod . Se o sinalizador de fluxo AUDCLNT_STREAMFLAGS_EVENTCALLBACK estiver definido e AUDCLNT_SHAREMODE_EXCLUSIVE for definido como ShareMode, hnsPeriodicity deverá ser diferente de zero e igual a hnsBufferDuration.

[in] pFormat

Ponteiro para um descritor de formato. Esse parâmetro deve apontar para um descritor de formato válido do tipo WAVEFORMATEX (ou WAVEFORMATEXTENSIBLE). Para obter mais informações, consulte Comentários.

[in] AudioSessionGuid

Ponteiro para um GUID de sessão. Esse parâmetro aponta para um valor GUID que identifica a sessão de áudio à qual o fluxo pertence. Se o GUID identificar uma sessão que foi aberta anteriormente, o método adicionará o fluxo a essa sessão. Se o GUID não identificar uma sessão existente, o método abrirá uma nova sessão e adicionará o fluxo a essa sessão. O fluxo permanece um membro da mesma sessão durante seu tempo de vida. Definir esse parâmetro como NULL é equivalente a passar um ponteiro para um valor GUID_NULL.

Valor retornado

Se o método for bem-sucedido, retornará S_OK. Se falhar, os códigos de retorno possíveis incluem, mas não se limitam a, os valores mostrados na tabela a seguir.

Código de retorno Descrição
AUDCLNT_E_ALREADY_INITIALIZED
O objeto IAudioClient já está inicializado.
AUDCLNT_E_WRONG_ENDPOINT_TYPE
O sinalizador AUDCLNT_STREAMFLAGS_LOOPBACK está definido, mas o dispositivo de ponto de extremidade é um dispositivo de captura, não um dispositivo de renderização.
AUDCLNT_E_BUFFER_SIZE_NOT_ALIGNED
Nota Aplica-se ao Windows 7 e posterior.
 
O tamanho do buffer solicitado não está alinhado. Esse código poderá ser retornado para um dispositivo de renderização ou de captura se o chamador especificar AUDCLNT_SHAREMODE_EXCLUSIVE e os sinalizadores de AUDCLNT_STREAMFLAGS_EVENTCALLBACK. O chamador deve chamar Initialize novamente com o tamanho do buffer alinhado. Para obter mais informações, consulte Comentários.
AUDCLNT_E_BUFFER_SIZE_ERROR
Nota Aplica-se ao Windows 7 e posterior.
 
Indica que o valor de duração do buffer solicitado por um cliente de modo exclusivo está fora do intervalo. O valor de duração solicitado para o modo de pull não deve ser maior que 5000 milissegundos; para o modo push, o valor de duração não deve ser maior que 2 segundos.
AUDCLNT_E_CPUUSAGE_EXCEEDED
Indica que a duração de passagem de processo excedeu o uso máximo da CPU. O mecanismo de áudio controla o uso da CPU mantendo o número de vezes que a duração de passagem de processo excede o uso máximo da CPU. O uso máximo da CPU é calculado como uma porcentagem da periodicidade do mecanismo. O valor percentual é o valor de limitação da CPU do sistema (dentro do intervalo de 10% e 90%). Se esse valor não for encontrado, o valor padrão de 40% será usado para calcular o uso máximo da CPU.
AUDCLNT_E_DEVICE_INVALIDATED
O dispositivo de ponto de extremidade de áudio foi desconectado ou o hardware de áudio ou os recursos de hardware associados foram reconfigurados, desabilitados, removidos ou não estão disponíveis para uso.
AUDCLNT_E_DEVICE_IN_USE
O dispositivo de ponto de extremidade já está em uso. O dispositivo está sendo usado no modo exclusivo ou o dispositivo está sendo usado no modo compartilhado e o chamador pediu para usar o dispositivo no modo exclusivo.
AUDCLNT_E_ENDPOINT_CREATE_FAILED
O método falhou ao criar o ponto de extremidade de áudio para a renderização ou o dispositivo de captura. Isso pode ocorrer se o dispositivo de ponto de extremidade de áudio tiver sido desconectado ou se o hardware de áudio ou os recursos de hardware associados tiverem sido reconfigurados, desabilitados, removidos ou não estiverem disponíveis para uso.
AUDCLNT_E_INVALID_DEVICE_PERIOD
Nota Aplica-se ao Windows 7 e posterior.
 
Indica que o período de dispositivo solicitado por um cliente de modo exclusivo é maior que 5000 milissegundos.
AUDCLNT_E_UNSUPPORTED_FORMAT
O mecanismo de áudio (modo compartilhado) ou dispositivo de ponto de extremidade de áudio (modo exclusivo) não dá suporte ao formato especificado.
AUDCLNT_E_EXCLUSIVE_MODE_NOT_ALLOWED
O chamador está solicitando o uso do modo exclusivo do dispositivo de ponto de extremidade, mas o usuário desabilitou o uso do modo exclusivo do dispositivo.
AUDCLNT_E_BUFDURATION_PERIOD_NOT_EQUAL
O sinalizador AUDCLNT_STREAMFLAGS_EVENTCALLBACK é definido, mas os parâmetros hnsBufferDuration e hnsPeriodicity não são iguais.
AUDCLNT_E_SERVICE_NOT_RUNNING
O serviço de áudio do Windows não está em execução.
E_POINTER
O parâmetro pFormat é NULL.
E_INVALIDARG
O parâmetro pFormat aponta para uma descrição de formato inválida; ou o sinalizador AUDCLNT_STREAMFLAGS_LOOPBACK está definido, mas ShareMode não é igual a AUDCLNT_SHAREMODE_SHARED; ou o sinalizador AUDCLNT_STREAMFLAGS_CROSSPROCESS está definido, mas ShareMode é igual a AUDCLNT_SHAREMODE_EXCLUSIVE.

Uma chamada anterior a SetClientProperties foi feita com uma categoria inválida para fluxos de áudio/renderização.

E_OUTOFMEMORY
Sem memória.

Comentários

Depois de ativar uma interface IAudioClient em um dispositivo de ponto de extremidade de áudio, o cliente deve chamar Initialize com êxito uma vez e apenas uma vez para inicializar o fluxo de áudio entre o cliente e o dispositivo. O cliente pode se conectar diretamente ao hardware de áudio (modo exclusivo) ou indiretamente por meio do mecanismo de áudio (modo compartilhado). Na chamada Inicializar , o cliente especifica o formato de dados de áudio, o tamanho do buffer e a sessão de áudio do fluxo.

Nota No Windows 8, o primeiro uso de IAudioClient para acessar o dispositivo de áudio deve estar no thread STA. Chamadas de um thread MTA podem resultar em um comportamento indefinido.
 
Uma tentativa de criar um fluxo de modo compartilhado só poderá ser bem-sucedida se o dispositivo de áudio já estiver operando no modo compartilhado ou se o dispositivo não estiver utilizado no momento. Uma tentativa de criar um fluxo de modo compartilhado falhará se o dispositivo já estiver operando no modo exclusivo.

Se um fluxo for inicializado para ser controlado por eventos e no modo compartilhado, o ShareMode será definido como AUDCLNT_SHAREMODE_SHARED e um dos sinalizadores de fluxo definidos inclui AUDCLNT_STREAMFLAGS_EVENTCALLBACK. Para esse fluxo, o aplicativo associado também deve obter um identificador fazendo uma chamada para IAudioClient::SetEventHandle. Quando for hora de desativar o fluxo, o mecanismo de áudio poderá usar o identificador para liberar os objetos de fluxo. A falha ao chamar IAudioClient::SetEventHandle antes de liberar os objetos de fluxo pode causar um atraso de vários segundos (um período de tempo limite) enquanto o mecanismo de áudio aguarda um identificador disponível. Depois que o período de tempo limite expirar, o mecanismo de áudio liberará os objetos de fluxo.

Se uma tentativa de criar um fluxo de modo exclusivo é bem-sucedida depende de vários fatores, incluindo a disponibilidade do dispositivo e as configurações controladas pelo usuário que regem a operação de modo exclusivo do dispositivo. Para obter mais informações, consulte Fluxos de modo exclusivo.

Um objeto IAudioClient dá suporte a exatamente uma conexão com o mecanismo de áudio ou hardware de áudio. Essa conexão dura o tempo de vida do objeto IAudioClient .

O cliente deve chamar os seguintes métodos somente depois de chamar Initialize:

Os seguintes métodos não exigem que Initialize seja chamado primeiro: Esses métodos podem ser chamados a qualquer momento após a ativação da interface IAudioClient .

Antes de chamar Initialize para configurar uma conexão de modo compartilhado ou de modo exclusivo, o cliente pode chamar o método IAudioClient::IsFormatSupported para descobrir se o mecanismo de áudio ou o dispositivo de ponto de extremidade de áudio dá suporte a um formato específico nesse modo. Antes de abrir uma conexão de modo compartilhado, o cliente pode obter o formato de combinação do mecanismo de áudio chamando o método IAudioClient::GetMixFormat .

O buffer de ponto de extremidade compartilhado entre o cliente e o mecanismo de áudio deve ser grande o suficiente para evitar que falhas ocorram no fluxo de áudio entre as passagens de processamento pelo cliente e pelo mecanismo de áudio. Para um ponto de extremidade de renderização, o thread do cliente grava periodicamente dados no buffer e o thread do mecanismo de áudio lê periodicamente os dados do buffer. Para um ponto de extremidade de captura, o thread do mecanismo grava periodicamente no buffer e o thread do cliente lê periodicamente do buffer. Em ambos os casos, se os períodos do thread do cliente e do thread do mecanismo não forem iguais, o buffer deverá ser grande o suficiente para acomodar o período mais longo dos dois períodos sem permitir que falhas ocorram.

O cliente especifica um tamanho de buffer por meio do parâmetro hnsBufferDuration . O cliente é responsável por solicitar um buffer grande o suficiente para garantir que falhas não possam ocorrer entre as passagens periódicas de processamento que ele executa no buffer. Da mesma forma, o método Initialize garante que o buffer nunca seja menor do que o tamanho mínimo do buffer necessário para garantir que falhas não ocorram entre as passagens periódicas de processamento que o thread do mecanismo executa no buffer. Se o cliente solicitar um tamanho de buffer menor que o tamanho mínimo necessário do buffer do mecanismo de áudio, o método definirá o tamanho do buffer como esse tamanho mínimo de buffer em vez do tamanho do buffer solicitado pelo cliente.

Se o cliente solicitar um tamanho de buffer (por meio do parâmetro hnsBufferDuration ) que não seja um número integral de quadros de áudio, o método arredondará o tamanho do buffer solicitado para o próximo número integral de quadros.

Após a chamada Inicializar , o cliente deve chamar o método IAudioClient::GetBufferSize para obter o tamanho preciso do buffer do ponto de extremidade. Durante cada passagem de processamento, o cliente precisará do tamanho real do buffer para calcular a quantidade de dados a serem transferidos de ou para o buffer. O cliente chama o método IAudioClient::GetCurrentPadding para determinar quanto dos dados no buffer estão disponíveis no momento para processamento.

Para obter a latência mínima de fluxo entre o aplicativo cliente e o dispositivo de ponto de extremidade de áudio, o thread do cliente deve ser executado no mesmo período que o thread do mecanismo de áudio. O período do thread do mecanismo é corrigido e não pode ser controlado pelo cliente. Tornar o período do cliente menor que o período do mecanismo aumenta desnecessariamente a carga do thread do cliente no processador sem melhorar a latência ou diminuir o tamanho do buffer. Para determinar o período do thread do mecanismo, o cliente pode chamar o método IAudioClient::GetDevicePeriod . Para definir o buffer para o tamanho mínimo exigido pelo thread do mecanismo, o cliente deve chamar Initialize com o parâmetro hnsBufferDuration definido como 0. Após a chamada Inicializar , o cliente pode obter o tamanho do buffer resultante chamando IAudioClient::GetBufferSize.

Um cliente tem a opção de solicitar um tamanho de buffer maior do que o que é estritamente necessário para tornar falhas de tempo raras ou inexistentes. Aumentar o tamanho do buffer não necessariamente aumenta a latência do fluxo. Para um fluxo de renderização, a latência por meio do buffer é determinada apenas pela separação entre o ponteiro de gravação do cliente e o ponteiro de leitura do mecanismo. Para um fluxo de captura, a latência por meio do buffer é determinada apenas pela separação entre o ponteiro de gravação do mecanismo e o ponteiro de leitura do cliente.

O sinalizador de loopback (AUDCLNT_STREAMFLAGS_LOOPBACK) habilita o loopback de áudio. Um cliente pode habilitar o loopback de áudio somente em um ponto de extremidade de renderização com um fluxo de modo compartilhado. O loopback de áudio é fornecido principalmente para dar suporte ao cancelamento de eco acústico (AEC).

Um cliente AEC requer um ponto de extremidade de renderização e a capacidade de capturar o fluxo de saída do mecanismo de áudio. O fluxo de saída do mecanismo é a combinação global que o dispositivo de áudio reproduz por meio dos alto-falantes. Se o loopback de áudio estiver habilitado, um cliente poderá abrir um buffer de captura para a combinação de áudio global chamando o método IAudioClient::GetService para obter uma interface IAudioCaptureClient no objeto de fluxo de renderização. Se o loopback de áudio não estiver habilitado, uma tentativa de abrir um buffer de captura em um fluxo de renderização falhará. Os dados de loopback no buffer de captura estão no formato do dispositivo, que o cliente pode obter consultando a propriedade PKEY_AudioEngine_DeviceFormat do dispositivo.

Em versões do Windows anteriores ao Windows 10, um cliente de captura de modo pull não receberá eventos quando um fluxo for inicializado com buffer controlado por eventos (AUDCLNT_STREAMFLAGS_EVENTCALLBACK) e estiver habilitado para loopback (AUDCLNT_STREAMFLAGS_LOOPBACK). Se o fluxo for aberto com essa configuração, a chamada Inicializar será bem-sucedida, mas eventos relevantes não serão gerados para notificar o cliente de captura sempre que um buffer estiver pronto para processamento. Para contornar isso, inicialize um fluxo de renderização no modo controlado por eventos. Sempre que o cliente recebe um evento para o fluxo de renderização, ele deve sinalizar o cliente de captura para executar o thread de captura que lê o próximo conjunto de exemplos do buffer do ponto de extremidade de captura. A partir do Windows 10, os identificadores de eventos relevantes agora estão definidos para fluxos habilitados para loopback que estão ativos.

Observe que todos os fluxos devem ser abertos no modo de compartilhamento porque os fluxos de modo exclusivo não podem operar no modo de loopback. Para obter mais informações sobre o loopback de áudio, consulte Gravação de loopback.

O sinalizador AUDCLNT_STREAMFLAGS_EVENTCALLBACK indica que o processamento do buffer de áudio pelo cliente será controlado por eventos. O WASAPI dá suporte ao buffer controlado por eventos para habilitar o processamento de baixa latência de fluxos de modo compartilhado e de modo exclusivo.

A versão inicial do Windows Vista dá suporte ao buffer controlado por eventos (ou seja, o uso do sinalizador AUDCLNT_STREAMFLAGS_EVENTCALLBACK) somente para renderizar fluxos.

Na versão inicial do Windows Vista, para fluxos de captura, o sinalizador AUDCLNT_STREAMFLAGS_EVENTCALLBACK tem suporte apenas no modo compartilhado. Definir esse sinalizador não tem efeito para fluxos de captura de modo exclusivo. Ou seja, embora o aplicativo especifique esse sinalizador no modo exclusivo por meio da chamada Inicializar , o aplicativo não receberá eventos que geralmente são necessários para capturar o fluxo de áudio. Na versão do Windows Vista Service Pack 1, esse sinalizador é funcional no modo compartilhado e no modo exclusivo; um aplicativo pode definir esse sinalizador para habilitar o buffer de eventos para fluxos de captura. Para obter mais informações sobre como capturar um fluxo de áudio, consulte Capturando um fluxo.

Para habilitar o buffer controlado por eventos, o cliente deve fornecer um identificador de evento para o sistema. Após a chamada Inicializar e antes de chamar o método IAudioClient::Start para iniciar o fluxo, o cliente deve chamar o método IAudioClient::SetEventHandle para definir o identificador de evento. Enquanto o fluxo está em execução, o sistema sinaliza periodicamente o evento para indicar ao cliente que os dados de áudio estão disponíveis para processamento. Entre as passagens de processamento, o thread do cliente aguarda no identificador de evento chamando uma função de sincronização, como WaitForSingleObject. Para obter mais informações sobre funções de sincronização, consulte a documentação do SDK do Windows.

Para um fluxo de modo compartilhado que usa buffer controlado por eventos, o chamador deve definir hnsPeriodicity e hnsBufferDuration como 0. O método Initialize determina o tamanho de um buffer a ser alocado com base no período de agendamento do mecanismo de áudio. Embora o thread de processamento de buffer do cliente seja controlado por eventos, o processo básico de gerenciamento de buffers, conforme descrito anteriormente, é sem alterações. Sempre que o thread despertar, ele deve chamar IAudioClient::GetCurrentPadding para determinar quantos dados gravar em um buffer de renderização ou ler de um buffer de captura. Ao contrário dos dois buffers que o método Initialize aloca para um fluxo de modo exclusivo que usa buffer controlado por eventos, um fluxo de modo compartilhado requer um único buffer.

Para um fluxo de modo exclusivo que usa buffer controlado por eventos, o chamador deve especificar valores não zero para hnsPeriodicity e hnsBufferDuration, e os valores desses dois parâmetros devem ser iguais. O método Initialize aloca dois buffers para o fluxo. Cada buffer é igual em duração ao valor do parâmetro hnsBufferDuration . Após a chamada Inicializar para um fluxo de renderização, o chamador deve preencher o primeiro dos dois buffers antes de iniciar o fluxo. Para um fluxo de captura, os buffers estão inicialmente vazios e o chamador deve assumir que cada buffer permanece vazio até que o evento desse buffer seja sinalizado. Enquanto o fluxo estiver em execução, o sistema alternadamente envia um buffer ou outro para o cliente— essa forma de buffer duplo é chamada de "ping-ponging". Sempre que o cliente recebe um buffer do sistema (que o sistema indica sinalizando o evento), o cliente deve processar todo o buffer. Por exemplo, se o cliente solicitar um tamanho de pacote do método IAudioRenderClient::GetBuffer que não corresponde ao tamanho do buffer, o método falhará. As chamadas para o método IAudioClient::GetCurrentPadding são desnecessárias porque o tamanho do pacote deve sempre ser igual ao tamanho do buffer. Ao contrário dos modos de buffer discutidos anteriormente, a latência de um fluxo de modo exclusivo controlado por eventos depende diretamente do tamanho do buffer.

Conforme explicado em Sessões de Áudio, o comportamento padrão de uma sessão que contém fluxos de renderização é que suas configurações de volume e mudo persistem entre as reinicializações do aplicativo. O sinalizador AUDCLNT_STREAMFLAGS_NOPERSIST substitui o comportamento padrão e torna as configurações nãopersistentes. Esse sinalizador não tem efeito nas sessões que contêm fluxos de captura— as configurações dessas sessões nunca são persistentes. Além disso, as configurações de uma sessão que contém um fluxo de loopback (um fluxo inicializado com o sinalizador AUDCLNT_STREAMFLAGS_LOOPBACK) não são persistentes.

Somente uma sessão que se conecta a um dispositivo de ponto de extremidade de renderização pode ter configurações persistentes de volume e mudo. O primeiro fluxo a ser adicionado à sessão determina se as configurações da sessão são persistentes. Portanto, se o sinalizador AUDCLNT_STREAMFLAGS_NOPERSIST ou AUDCLNT_STREAMFLAGS_LOOPBACK for definido durante a inicialização do primeiro fluxo, as configurações da sessão não serão persistentes. Caso contrário, eles são persistentes. Sua persistência não é afetada por fluxos adicionais que podem ser adicionados ou removidos posteriormente durante o tempo de vida do objeto de sessão.

Depois que uma chamada para Initialize tiver inicializado com êxito uma instância de interface IAudioClient , uma chamada inicializar subsequente para inicializar a mesma instância de interface falhará e retornará o código de erro E_ALREADY_INITIALIZED.

Se a chamada inicial para Inicializar falhar, as chamadas inicializar subsequentes poderão falhar e retornar o código de erro E_ALREADY_INITIALIZED, mesmo que a interface não tenha sido inicializada. Se isso ocorrer, libere a interface IAudioClient e obtenha uma nova interface IAudioClient da API MMDevice antes de chamar Initialize novamente.

Para obter exemplos de código que chamam o método Initialize , consulte os seguintes tópicos:

A partir do Windows 7, Initialize pode retornar AUDCLNT_E_BUFFER_SIZE_NOT_ALIGNED para uma renderização ou um dispositivo de captura. Isso indica que o tamanho do buffer, especificado pelo chamador no parâmetro hnsBufferDuration , não está alinhado. Esse código de erro será retornado somente se o chamador solicitou um fluxo de modo exclusivo (AUDCLNT_SHAREMODE_EXCLUSIVE) e um buffer controlado por eventos (AUDCLNT_STREAMFLAGS_EVENTCALLBACK).

Se Initialize retornar AUDCLNT_E_BUFFER_SIZE_NOT_ALIGNED, o chamador deverá chamar Initialize novamente e especificar o tamanho do buffer alinhado. Use as seguintes etapas:

  1. Chame IAudioClient::GetBufferSize e receba o próximo tamanho de buffer alinhado mais alto (em quadros).
  2. Chame IAudioClient::Release para liberar o cliente de áudio usado na chamada anterior que retornou AUDCLNT_E_BUFFER_SIZE_NOT_ALIGNED.
  3. Calcule o tamanho do buffer alinhado em unidades de 100 nanossegundos (hns). O tamanho do buffer é (REFERENCE_TIME)((10000.0 * 1000 / WAVEFORMATEX.nSamplesPerSecond * nFrames) + 0.5). Nesta fórmula, nFrames é o tamanho do buffer recuperado por GetBufferSize.
  4. Chame o método IMMDevice::Activate com iid de parâmetro definido como REFIID IID_IAudioClient para criar um novo cliente de áudio.
  5. Chame Inicializar novamente no cliente de áudio criado e especifique o novo tamanho do buffer e a periodicidade.

A partir do Windows 10, os fluxos de áudio descarregados por hardware devem ser controlados por eventos. Isso significa que, se você chamar IAudioClient2::SetClientProperties e definir o parâmetro bIsOffload do AudioClientProperties como TRUE, deverá especificar o sinalizador AUDCLNT_STREAMFLAGS_EVENTCALLBACK no parâmetro StreamFlags como IAudioClient::Initialize.

Exemplos

O código de exemplo a seguir mostra como responder ao código de retorno AUDCLNT_E_BUFFER_SIZE_NOT_ALIGNED .

#define REFTIMES_PER_SEC  10000000

HRESULT CreateAudioClient(IMMDevice* pDevice, IAudioClient** ppAudioClient)
{
    if (!pDevice)
    {
        return E_INVALIDARG;
    }

    if (!ppAudioClient)
    {
        return E_POINTER;
    }

    HRESULT hr = S_OK;
    
    WAVEFORMATEX *pwfx = NULL;

    REFERENCE_TIME hnsRequestedDuration = REFTIMES_PER_SEC;

    UINT32 nFrames = 0;

    IAudioClient *pAudioClient = NULL;

    // Get the audio client.
    CHECK_HR( hr = pDevice->Activate(
        __uuidof(IAudioClient), 
        CLSCTX_ALL,
        NULL, 
        (void**)&pAudioClient));

    // Get the device format.
    CHECK_HR( hr = pAudioClient->GetMixFormat(&pwfx));

    // Open the stream and associate it with an audio session.
    hr = pAudioClient->Initialize( 
        AUDCLNT_SHAREMODE_EXCLUSIVE,
        AUDCLNT_STREAMFLAGS_EVENTCALLBACK, 
        hnsRequestedDuration, 
        hnsRequestedDuration, 
        pwfx, 
        NULL);

    // If the requested buffer size is not aligned...
    if (hr == AUDCLNT_E_BUFFER_SIZE_NOT_ALIGNED)
    {	
        // Get the next aligned frame.
        CHECK_HR( hr = pAudioClient->GetBufferSize(&nFrames));
        
        hnsRequestedDuration = (REFERENCE_TIME)
        ((10000.0 * 1000 / pwfx->nSamplesPerSec * nFrames) + 0.5);

        // Release the previous allocations.
        SAFE_RELEASE(pAudioClient);
        CoTaskMemFree(pwfx);
        
        // Create a new audio client.
        CHECK_HR( hr = pDevice->Activate(
            __uuidof(IAudioClient), 
            CLSCTX_ALL,
            NULL, 
            (void**)&pAudioClient));
    
        // Get the device format.
        CHECK_HR( hr = pAudioClient->GetMixFormat(&pwfx));
        
        // Open the stream and associate it with an audio session.
        CHECK_HR( hr = pAudioClient->Initialize( 
            AUDCLNT_SHAREMODE_EXCLUSIVE,
            AUDCLNT_STREAMFLAGS_EVENTCALLBACK, 
            hnsRequestedDuration, 
            hnsRequestedDuration, 
            pwfx, 
            NULL));
    }
    else
    {
        CHECK_HR (hr);
    }
    
    // Return to the caller.
    *(ppAudioClient) = pAudioClient;
    (*ppAudioClient)->AddRef();

done:

    // Clean up.
    CoTaskMemFree(pwfx);
    SAFE_RELEASE(pAudioClient);
    return hr;
}

Requisitos

   
Plataforma de Destino Windows
Cabeçalho audioclient.h

Confira também

IAudioCaptureClient Interface

IAudioClient Interface

IAudioClient::GetBufferSize

IAudioClient::GetCurrentPadding

IAudioClient::GetDevicePeriod

IAudioClient::GetMixFormat

IAudioClient::GetService

IAudioClient::SetEventHandle

IAudioClient::Start

IAudioRenderClient::GetBuffer