> ## Documentation Index
> Fetch the complete documentation index at: https://devdocs.xbox.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Visão geral do envelopamento do XDSP

> Visão geral do envelopamento do XDSP

Neste tópico, vamos explicar o uso do envelopamento como parte da execução de convolução em dispositivos XBOX Series X|S usando o XDSP. Esse mecanismo foi desenvolvido como um método flexível para que os desenvolvedores alterem dinamicamente uma parte do filtro de resposta ao impulso no fluxo existente sem reativar um novo fluxo. É fornecida a API [XDspSubmitCommandWithEnvelope](/pt-BR/reference/audio/xdspaudio/functions/xdspsubmitcommandwithenvelope), que recebe um *envelopeBuffer* contendo valores de ganho para cada bloco do filtro de resposta ao impulso, além dos parâmetros fornecidos à API [XDspSubmitCommand](/pt-BR/reference/audio/xdspaudio/functions/xdspsubmitcommand). Os valores de ganho são multiplicados pelos blocos correspondentes no filtro de resposta ao impulso durante o processo de convolução para fornecer o efeito desejado. O filtro de resposta ao impulso original não é modificado durante esse processo.

Para entender melhor o mecanismo de envelopamento, vamos definir as seguintes variáveis no domínio da frequência:

* Seja o sinal do filtro de resposta ao impulso para o bin de frequência ***n*** do bloco ***m*** igual a ***f\[n,m] = f\_Real\[n,m] + if\_Imag\[n,m]***.
* Seja o sinal de entrada para o bin de frequência ***n*** do bloco ***m*** igual a ***s\[n,m] = s\_Real\[n,m] + is\_Imag\[n,m]***.
* Seja o valor de ganho para um bloco de filtro ***m*** representado como ***K\[m]*** (o ganho de envelope para o bloco ***m***).

Então, a representação matemática do envelopamento é a seguinte:

***r\[n,m] = K\[m] \* f\[n,m] \* s\[n,m]***
***r\[n,m] = K\[m] \* (f\_Real\[n,m] + if\_Imag\[n,m]) \* (s\_Real\[n,m] + is\_Imag\[n,m])***

Em que ***r\[n,m]*** é a saída convolucional depois que cada bin de frequência e bloco foi dimensionado pelo ganho de envelope associado. Se nenhum ganho de envelope for especificado, então ***K\[m] = 1.0f*** para todos os blocos ***m***.

## Buffer de envelope

O buffer de envelope contém valores de ganho em float para cada bloco do filtro de resposta ao impulso a serem aplicados durante a convolução.  O tamanho mínimo desse buffer deve ser de 8 valores float no caso de um filtro de resposta ao impulso mono e de 16 valores float para um filtro de resposta ao impulso estéreo. No caso de uma resposta ao impulso estéreo, o buffer de envelope contém valores de ganho para ambos os canais, com os valores de ganho de todo o canal esquerdo seguidos pelos valores de ganho de todo o canal direito. O comprimento do envelope para cada canal deve ser um múltiplo de 16 bytes; caso contrário, a saída poderá não estar correta. Quaisquer valores adicionais resultantes do arredondamento para o múltiplo de 16 bytes mais próximo serão ignorados. Todos os ponteiros de buffer devem estar alinhados em 16 bytes.
Esse buffer deve fazer parte da memória registrada por [XDspConnect](/pt-BR/reference/audio/xdspaudio/functions/xdspconnect) ou [XDspConnectWithMaximumStreamLimit](/pt-BR/reference/audio/xdspaudio/functions/xdspconnectwithmaximumstreamlimit) e deve estar alinhado em 16 bytes. Esse buffer é usado pelo hardware e não pode ser modificado nem liberado até que todos os comandos que o utilizam sejam concluídos e as respostas tenham sido coletadas.
A contagem de valores de ganho no buffer de envelope deve ser o número de blocos no filtro de resposta ao impulso arredondado para o múltiplo de 16 bytes mais próximo e é calculada da seguinte forma.

```cpp theme={null}
#define ROUND_UP_TO_16BYTE_ALIGNED(x) (((x) + (15)) & ~(0xF))

// XDspActivationParameters::impulseResponseLengthInFloats is the impulse response length of each channel in case of stereo IR
uint32_t irLengthInComplexes = XDspActivationParameters::impulseResponseLengthInFloats/2;  
uint32_t numFilterBlocks = irLengthInComplexes/XDspActivationParameters::blockFrameCount;

// Round up the envelope size to the nearest multiple of 16 bytes. Additional values resulting from the rounding will be ignored.
// envelopeGainCount represents the number of gain values an envelope buffer holds. In case of a stereo impulse response filter,
// this is the number of gain values per channel.
uint32_t envelopeLengthInBytes = ROUND_UP_TO_16BYTE_ALIGNED(numFilterBlocks * sizeof(float));
uint32_t envelopeGainCount = envelopeSize / sizeof(float)  

// Account for left and right channel envelopes in case of stereo impulse response
if (stereoImpulseRespone)
{
    envelopeLengthInBytes = envelopeLengthInBytes * 2;
}
```

Esse buffer segue a natureza do filtro de resposta ao impulso. Para a resposta ao impulso estéreo, os valores de ganho de todo o canal esquerdo são seguidos pelos valores de ganho de todo o canal direito, da mesma forma que a resposta ao impulso do canal esquerdo é seguida pela resposta ao impulso do canal direito.
Para uma resposta ao impulso mono, os mesmos valores de ganho são aplicados aos canais esquerdo e direito de um sinal de entrada estéreo.

## Uso da API

Veja a seguir um exemplo de padrão de uso da API. Consulte as observações abaixo para obter detalhes adicionais.

```cpp theme={null}
XDspSubmitCommand(...)/XDspSubmitCommandWithEnvelope(.., nullptr, ...);  // _envelopeState = Off;  
XDspSubmitCommand(...)/XDspSubmitCommandWithEnvelope(.., nullptr, ...);  // _envelopeState = Off;  
:::::::::::::::::::::::     
XDspSubmitCommandWithEnvelope(..., envelopeBuffer1, ...); // _envelopeState = Engaged with envelopeBuffer1  
XDspSubmitCommandWithEnvelope(..., envelopeBuffer1, ...); // _envelopeState = Engaged with envelopeBuffer1  
:::::::::::::::::::::: 
XDspSubmitCommandWithEnvelope(..., envelopeBuffer2, ...); // _envelopeState = Engaged with envelopeBuffer2  
XDspSubmitCommandWithEnvelope(..., envelopeBuffer2, ...); // _envelopeState = Engaged with envelopeBuffer2  
::::::::::::::::::::::  
XDspSubmitCommand(...)/XDspSubmitCommandWithEnvelope(.., nullptr, ...);  // _envelopeState = Off;  
XDspSubmitCommand(...)/XDspSubmitCommandWithEnvelope(.., nullptr, ...);  // _envelopeState = Off;  
:::::::::::::::::::::::
```

## Observações

A convolução é implementada como um processo de vários estágios, e cada pacote de entrada passa por um desses estágios. Para manter a saída suave, o envelopamento pode ser ativado ou desativado somente no primeiro estágio. Isso significa que o efeito de envelopamento pode não ser desativado/ativado imediatamente quando o comando é enviado. Pode levar algumas chamadas para que ele entre em vigor.

## Documentação de referência da API

* [XDspAudio (conteúdo da API)](/pt-BR/reference/audio/xdspaudio/xdspaudio_members)
  * Funções
    * [XDspSubmitCommandWithEnvelope](/pt-BR/reference/audio/xdspaudio/functions/xdspsubmitcommandwithenvelope)
    * [XDspSubmitCommand](/pt-BR/reference/audio/xdspaudio/functions/xdspsubmitcommand)
    * [XDspConnect](/pt-BR/reference/audio/xdspaudio/functions/xdspconnect)
    * [XDspConnectWithMaximumStreamLimit](/pt-BR/reference/audio/xdspaudio/functions/xdspconnectwithmaximumstreamlimit)

## Confira também

[Visão geral do XDSP](/pt-BR/build/console-features/audio/overviews/xdsp-overview)
[XDspSubmitCommandWithEnvelope](/pt-BR/reference/audio/xdspaudio/functions/xdspsubmitcommandwithenvelope)
[Visão geral de uma convolução de fluxo único com envelope usando a API XDSP](/pt-BR/build/console-features/audio/overviews/xdsp-overview-single-stream-convolution-with-envelope)


## Related topics

- [Visão geral do Unity](/pt-BR/paths/unity/overview.md)
- [Visão geral do Unreal Engine](/pt-BR/paths/unreal/overview.md)
- [Visão geral do XBOX Series X|S](/pt-BR/paths/series-xs/overview.md)
- [Visão geral do Windows & ROG XBOX Ally](/pt-BR/paths/windows/overview.md)
- [Visão geral do Play Anywhere (Console + PC)](/pt-BR/paths/play-anywhere/overview.md)
