Skip to main content
Neste tópico, vamos explicar o fluxo de código esperado sobre como usar o reverb de convolução por hardware em dispositivos XBOX Series X usando um dos exemplos incluídos no Microsoft Game Development Kit (GDK).

Conexão e inicialização do hardware

É necessário estabelecer uma conexão com a unidade de aceleração de hardware por meio de XDspConnect ou XDspConnectWithMaximumStreamLimit. O chamador define os requisitos da conexão usando os seguintes parâmetros:
  1. baseBuffer - Um ponteiro para a memória alocada pelo usuário, suficiente para armazenar os buffers de entrada, de saída, de envelope e/ou de multiplicador de bloco que serão passados ao hardware. Essa memória deve ser alocada por meio de XMemAlloc com estes atributos: XALLOC_MEMTYPE_PHYSICAL_CACHEABLE, XALLOC_PAGESIZE_64KB, XALLOC_ALIGNMENT_64K. Esses atributos devem ser definidos usando MAKE_XALLOC_ATTRIBUTES(), conforme mostrado no exemplo abaixo. Essa memória não deve ser liberada até que a chamada de XDspDisconnect seja bem-sucedida. Esse buffer deve ter pelo menos 64KB de tamanho.
  2. baseBufferLength - O comprimento do baseBuffer em bytes. Esse buffer deve ter pelo menos 64KB e no máximo 500 MB.
  3. aggregateImpulseResponseInSeconds - Representa a duração total de todas as respostas ao impulso individuais que serão ativadas simultaneamente usando XDspActivate com XDspProcessType::Convolution. Se esse valor for 0, nenhum fluxo com XDspProcessType::Convolution poderá ser ativado.
  4. handle - um ponteiro para o XDspClientHandle que armazenará o identificador retornado por esta chamada.
Se a chamada for bem-sucedida, o baseBuffer poderá ser usado pelo chamador para passar dados de entrada e recuperar os dados de saída dos fluxos por meio dos parâmetros de XDspCommand. Qualquer buffer passado no XDspCommand deve estar alinhado em 16 bytes. O exemplo a seguir de um gerenciador de buffers simples pode ser usado para gerenciar os buffers de entrada e saída.
Os buffers de envelope de cada fluxo devem fazer parte do baseBuffer passado para XDspConnect ou XDspConnectWithMaximumStreamLimit, assim como os buffers de entrada e saída. O comprimento de cada buffer de envelope pode ser calculado da seguinte forma.
Veja a seguir o exemplo de código da primeira etapa para alocar memória e estabelecer uma conexão. Observe que XDspConnectWithMaximumStreamLimit pode ser usado no lugar de XDspConnect para reduzir o uso de memória interna se o número de fluxos que podem estar ativos for inferior a 256.
Em que XMemAllocAttributes representa os atributos mencionados acima. O código a seguir define aggregateImpulseResponse como 32 segundos.

Ativação e desativação de fluxos

Depois que a conexão com o dispositivo for estabelecida, o chamador deverá enviar um comando de ativação de fluxo para iniciar uma convolução, FFT ou IFFT. O chamador deve especificar o XDspProcessType, a contagem de quadros do bloco, a contagem de canais, o comprimento da resposta ao impulso em floats e um ponteiro para os dados da resposta ao impulso no domínio da frequência em XDspActivationParameters. Somente fluxos mono ou estéreo são permitidos. Para XDspProcessType::ForwardFourierTransform e XDspProcessType::inverseFourierTransform, XDspActivationParameters::impulseResponse deve ser nullptr e XDspActivationParameters::impulseResponseLengthInFloats = 0. XDspActivationOptions deve ser definido adequadamente. Veja a seguir o código para ativar um fluxo para convolução.
XDspActivate retorna um buffer XDspStatus como um de seus parâmetros. Esse buffer XDspStatus deve ser usado para obter o status dos comandos processados pelo hardware para esse fluxo. Depois que o resultado da ativação for recebido, o chamador poderá começar a enviar dados para convolução/FFT/IFFT. Isso deve ser feito usando a API XDspSubmitCommand ou XDspSubmitCommandWithEnvelope. Em cada chamada, o chamador deve fazer o seguinte:
  1. Preencha o buffer de entrada com exatamente blockFrameCount de dados.
  2. Preencha o XDspCommand com os valores apropriados e com buffers de entrada e saída alinhados em 16 bytes.
  3. Chame XDspSubmitCommand para enviar o comando ao hardware. Essa função retorna um número de sequência de comando que pode ser usado para acompanhar o número de comandos enviados ao hardware.
  4. Para aplicar um envelope, preencha o buffer de envelope com valores de ganho para cada bloco do filtro de resposta ao impulso, chame XDspSubmitCommandWithEnvelope e continue fazendo essa chamada com o mesmo buffer de envelope até que o envelopamento não seja mais necessário ou o envelope precise ser alterado.
  5. Quando o envelopamento não for mais necessário, chame XDspSubmitCommand ou XDspSubmitCommandWithEnvelope com nullptr para envelopeBuffer. Observe que XDspSubmitCommandWithEnvelope com nullptr para envelopeBuffer é equivalente a XDspSubmitCommand.
  6. Ao trocar o envelope, o envelopeBuffer atual só poderá ser atualizado para o próximo envelope se o hardware tiver processado todos os comandos que usam esse envelope e os resultados tiverem sido coletados. Caso contrário, use um buffer de envelope diferente.
O trecho de código a seguir mostra um exemplo de preenchimento do buffer de envelope com valores de ganho para cada bloco do filtro de resposta ao impulso. Ele mostra como usar apenas a primeira metade do filtro de resposta ao impulso, com os valores de ganho da primeira metade dos blocos de resposta ao impulso começando em 1.0f e diminuindo linearmente, e a segunda metade preenchida com um valor de ganho de 0.0f. Para um filtro de resposta ao impulso estéreo, o filtro inteiro do canal esquerdo é seguido pelo do canal direito; o buffer de envelope do filtro de resposta ao impulso estéreo segue o mesmo padrão, com os valores de ganho de todo o canal esquerdo seguidos pelos valores de ganho de todo o canal direito. Consulte Visão geral do envelopamento usando a API XDSP para obter informações sobre como calcular o tamanho do buffer de envelope.
O trecho de código a seguir mostra a aplicação do envelope chamando XDspSubmitCommandWithEnvelope com um envelopeBuffer válido. Ele é igual ao trecho que mostra como enviar um comando usando XDspSubmitCommand, exceto pela passagem do parâmetro adicional envelopeBuffer. Isso deve ser repetido até que o envelope não seja mais necessário; nesse momento, deve-se chamar XDspSubmitCommand ou XDspSubmitCommandWithEnvelope com nullptr para envelopeBuffer.
Em seguida, XDspStatus pode ser verificado para obter o status dos comandos enviados ao hardware, da seguinte forma:
Quando os pacotes do fluxo forem processados ou o hardware retornar um erro no resultado de XDspStatus, XDspDeactivate deverá ser chamado.
XDspDeactivate retornará XDSP_E_PENDING_RESULTS se o hardware não tiver terminado de processar todos os comandos enviados para esse fluxo.

Encerramento

Depois que XDspDeactivate for bem-sucedido, o chamador deverá chamar XDspDisconnect para se desconectar da unidade de aceleração de hardware de áudio e liberar todos os recursos alocados. Se nem todos os fluxos forem desativados, XDspDisconnect retornará o erro XDSP_E_NOT_ALL_HANDLES_DEACTIVATED.

Documentação de referência da API

Confira também

Visão geral do XDSP Visão geral do envelopamento usando a API XDSP
Last modified on October 6, 2026