> ## 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 ACP

> Guia de programação do Audio Control Processor (ACP) e da biblioteca acphal, que gerencia os flowgraphs de áudio do SHAPE em consoles XBOX One.

Este tópico fornece descrições e exemplos dos flowgraphs usados para direcionar o Audio Control Processor (ACP).

<a id="ID4EX" />

## Visão geral do ACP

Esta seção descreve a interface de programação do ACP.

A biblioteca `acphal` (*acphal.lib*) define o conjunto de APIs do Scalable Hardware Audio Processing Engine (SHAPE). O Microsoft Game Development Kit (GDK) também inclui uma coleção de utilitários de áudio e código-fonte para ajudar você a preparar dados de áudio para uso com o SHAPE. Os cabeçalhos dos utilitários definem o seguinte:

* As estruturas de contexto para cada formato de dados compatível

* Um conjunto completo de funções que podem ser usadas para ler e gravar nesses contextos

Defina pelo menos um flowgraph no seu aplicativo para rotear os dados de áudio *pelos* blocos do SHAPE. O ACP gerencia os blocos do SHAPE e garante a eficiência.

Para obter detalhes sobre o conjunto de APIs, incluindo as estruturas e enumerações declaradas nos arquivos de utilitários, confira a referência do [AcpHal](/pt-BR/reference/audio/acphal/acphal_members).

Para obter detalhes sobre a arquitetura do SHAPE, confira a [visão geral do SHAPE](/pt-BR/build/console-features/audio/overviews/shape-overview).

Nos arquivos de origem de um projeto de título, inclua o arquivo *ShapeContext.h*, e não os arquivos de cabeçalho de contexto individuais.

Neste tópico:

* [Flowgraphs](#ID4EVB)
* [Utilitários de DMA](#ID4EZH)
* [Utilitários do compressor de EQ](#ID4EIAAC)
* [Utilitários de volume de filtro](#ID4EWAAC)
* [Utilitários de PCM](#ID4EEBAC)
* [Utilitários de SRC](#ID4ESBAC)
* [Utilitários de XMA](#ID4EACAC)
* [Valores de destino](#ID4EXEAC)
* [Segurança de thread](#ID4E3NAC)
* [Diretrizes para usar o SRC com dados PCM e XMA](#ID4EUPAC)
* [Pausar e retomar um título](#ID4E5BAE)

<a id="ID4EVB" />

### Flowgraphs

Para usar o SHAPE, um título normalmente cria um flowgraph do SHAPE. Para obter a descrição de uma alternativa, confira a seção [Utilitários de XMA](#ID4EACAC). Um flowgraph do SHAPE é uma matriz de comandos (um por bloco do SHAPE) e dados de contexto associados que descrevem a ordem das operações dos blocos individuais e os dados sobre os quais eles operam. O ACP usa os dados do flowgraph para agendar corretamente as operações nos blocos do SHAPE.

O título é responsável por criar o flowgraph e enviá-lo ao ACP. Para criar um flowgraph, use [ShapeFlowGraph (métodos utilitários de flowgraph)](/pt-BR/reference/audio/shapeflowgraph/shapeflowgraph_members).

Nas figuras a seguir, os blocos verdes representam componentes do SHAPE, os blocos ciano são o material de origem e os círculos amarelos rotulados são os buffers de mixagem de hardware.

* [Sons 3D](#ID4EHC)
* [Front-end para um mecanismo de áudio de software](#ID4ETC)
* [Renderização de áudio](#ID4E6C)
* [Análise de flowgraphs](#ID4EHF)
* [Atualização de flowgraphs](#ID4EHG)
* [Vários flowgraphs](#ID4ELH)

<a id="ID4EHC" />

#### Sons 3D

**Figura 1. Duas vozes, cada uma com panorâmica entre duas saídas, com um envio para uma saída comum.**

<img src="https://mintcdn.com/microsoft-4404708b/CwRBzaXvHw9zaPoe/images/gdk/features/console/flowgraph_pan.png?fit=max&auto=format&n=CwRBzaXvHw9zaPoe&q=85&s=717d40735192142f7a194f6be5a27576" alt="Flowgraph de duas vozes" width="985" height="465" data-path="images/gdk/features/console/flowgraph_pan.png" />

No código, esse flowgraph pode ser representado da seguinte forma.

```cpp theme={null}
        typedef enum mixBuffers
        {
          noBuffer         =   0,
          mixBuffer_1      =   1,
          mixBuffer_2      =   2,
          mixBuffer_3      =   3,
          mixBuffer_4      =   4,
          mixBuffer_5      =   5,
          mixBuffer_6      =   6,
          mixBuffer_7      =   7,
          mixBuffer_8      =   8,
          mixBuffer_9      =   9,
          mixBuffer_10     =   10,
          mixBuffer_11     =   11
        };
        
        typedef enum DMAcontexts
        {
          DMAcontext_0    = 0,
          DMAcontext_1    = 1,
          DMAcontext_2    = 2,
          DMAcontext_3    = 3,
          DMAcontext_4    = 4,      
        };
        
        typedef enum FLTVOLcontexts
        {
          FLTVOLcontext_0    = 0,
          FLTVOLcontext_1    = 1,
          FLTVOLcontext_2    = 2,
          FLTVOLcontext_3    = 3,
          FLTVOLcontext_4    = 4,    
          FLTVOLcontext_5    = 5,
          FLTVOLcontext_6    = 6,
          FLTVOLcontext_7    = 7,  
        };
                
        typedef enum EQcontexts
        {
          EQcontext_0    = 0,
          EQcontext_1    = 1,      
        };
        
        typedef enum SRCcontexts
        {
          SRCcontext_0    = 0,
          SRCcontext_1    = 1,      
        };
        
        typedef enum XMAcontexts
        {
          XMAcontext_0    = 0,
          XMAcontext_1    = 1,      
        };
        
        //
        // Command structure to be initialized.
        //
        #define nSHAPE_3Dpan_commands       28
        //
        SHAPE_FLOWGRAPH_COMMAND cmd[nSHAPE_3Dpan_commands];
        
        //
        // Shared mix buffer.
        //

        // SetShapeAllocMixBufferCommand parameters:
        //                           command,    virtualID,      numIn, numOut,   attenuation
        SetShapeAllocMixBufferCommand(&cmd[0],   mixBuffer_1,     2,      1,      SHAPE_MIXBUFFER_ATTENUATION_0_DB);

        //
        // Mix buffers for voice A.
        //

        // SetShapeAllocMixBufferCommand parameters:
        //                           command,    virtualID,      numIn, numOut,   attenuation
        SetShapeAllocMixBufferCommand(&cmd[1],   mixBuffer_2,     1,      1,      SHAPE_MIXBUFFER_ATTENUATION_0_DB);
        SetShapeAllocMixBufferCommand(&cmd[2],   mixBuffer_3,     1,      1,      SHAPE_MIXBUFFER_ATTENUATION_0_DB);
        SetShapeAllocMixBufferCommand(&cmd[3],   mixBuffer_4,     1,      3,      SHAPE_MIXBUFFER_ATTENUATION_0_DB);
        SetShapeAllocMixBufferCommand(&cmd[4],   mixBuffer_5,     1,      1,      SHAPE_MIXBUFFER_ATTENUATION_0_DB);
        SetShapeAllocMixBufferCommand(&cmd[5],   mixBuffer_6,     1,      1,      SHAPE_MIXBUFFER_ATTENUATION_0_DB);

        //
        // Voice A.
        //

        // SetShapeSrcXmaCommand parameters:
        //                     command,      contextID,            XMAContextID,       leftorMonoMixBuffer, rightMixBuffer
        SetShapeSrcXmaCommand( &cmd[6],      SRCcontext_0,         XMAcontext_0,       mixBuffer_2,         noBuffer);

        // SetShapeFiltVolCommand parameters:
        //                     command,      contextID,          inputMixBuffer, outputMixBuffer
        SetShapeFiltVolCommand(&cmd[7],      FLTVOLcontext_0,    mixBuffer_2,    mixBuffer_3   );

        // SetShapeEqCompCommand parameters:
        //                  command,         contextID,     inputMixBuffer, sidechainMixBuffer, outputMixBuffer
        SetShapeEqCompCommand( &cmd[8],      EQcontext0,    mixBuffer_3,   noBuffer,           mixBuffer_4);

        // SetShapeFiltVolCommand parameters:
        //                  command,       contextID,            inputMixBuffer,   outputMixBuffer
        SetShapeFiltVolCommand(&cmd[9],    FLTVOLcontext_1,      mixBuffer_4,   mixBuffer_5   );
        SetShapeFiltVolCommand(&cmd[10],   FLTVOLcontext_2,      mixBuffer_4,   mixBuffer_6   );
        SetShapeFiltVolCommand(&cmd[11],   FLTVOLcontext_3,      mixBuffer_4,   mixBuffer_1   );

        //
        // Mix buffers for voice B.
        //

        // SetShapeAllocMixBufferCommand parameters:
        //                           command,     virtualID,      numIn, nmmOut,   attenuation
        SetShapeAllocMixBufferCommand(&cmd[12],   mixBuffer_7,      1,      1,      SHAPE_MIXBUFFER_ATTENUATION_0_DB);
        SetShapeAllocMixBufferCommand(&cmd[13],   mixBuffer_8,      1,      1,      SHAPE_MIXBUFFER_ATTENUATION_0_DB);
        SetShapeAllocMixBufferCommand(&cmd[14],   mixBuffer_9,      1,      3,      SHAPE_MIXBUFFER_ATTENUATION_0_DB);
        SetShapeAllocMixBufferCommand(&cmd[15],   mixBuffer_10,     1,      1,      SHAPE_MIXBUFFER_ATTENUATION_0_DB);
        SetShapeAllocMixBufferCommand(&cmd[16],   mixBuffer_11,     1,      1,      SHAPE_MIXBUFFER_ATTENUATION_0_DB);

        //
        // Voice B.
        //

        // SetShapeSrcXmaCommand parameters:
        //                     command,    contextID,            XMAContextID,         leftorMonoMixBuffer, rightMixBuffer
        SetShapeSrcXmaCommand( &cmd[17],   SRCcontext_1,         XMAcontext_1,         mixBuffer_7,         noBuffer);

        // SetShapeFiltVolCommand parameters:
        //                     command,    contextID,            inputMixBuffer, outputMixBuffer
        SetShapeFiltVolCommand(&cmd[18],   FLTVOLcontext_4,      mixBuffer_7,    mixBuffer_8   );

        // SetShapeEqCompCommand parameters:
        //                     command,    contextID,       inputMixBuffer, sidechainMixBuffer, outputMixBuffer
        SetShapeEqCompCommand( &cmd[19],   EQcontext1,      mixBuffer_8,    noBuffer,           mixBuffer_9);

        // SetShapeFiltVolCommand parameters:
        //                     command,    contextID,            inputMixBuffer, outputMixBuffer
        SetShapeFiltVolCommand(&cmd[20],   FLTVOLcontext_5,      mixBuffer_9,    mixBuffer_10   );
        SetShapeFiltVolCommand(&cmd[21],   FLTVOLcontext_6,      mixBuffer_9,    mixBuffer_11   );
        SetShapeFiltVolCommand(&cmd[22],   FLTVOLcontext_7,      mixBuffer_9,    mixBuffer_1   );

        //
        // DMA all outputs.
        //

        // SetShapeDmaCommand parameters:
        //                     command,       contextID,         mixBuffer,      write
        SetShapeDmaCommand(    &cmd[23],      DMAcontext_0,      mixBuffer_1,    true);
        SetShapeDmaCommand(    &cmd[24],      DMAcontext_1,      mixBuffer_5,    true);
        SetShapeDmaCommand(    &cmd[25],      DMAcontext_2,      mixBuffer_6,    true);
        SetShapeDmaCommand(    &cmd[26],      DMAcontext_3,      mixBuffer_10,   true);
        SetShapeDmaCommand(    &cmd[27],      DMAcontext_4,      mixBuffer_11,   true);  
```

<a id="ID4ETC" />

#### Front-end para um mecanismo de áudio de software

**Figura 2.  Um front-end básico para um mecanismo de software. Potencialmente, todas as vozes que usam esse modelo usariam a mesma estrutura.**

<img src="https://mintcdn.com/microsoft-4404708b/CwRBzaXvHw9zaPoe/images/gdk/features/console/flowgraph_frontend.png?fit=max&auto=format&n=CwRBzaXvHw9zaPoe&q=85&s=d91f5904751f33337ccc9673e6206825" alt="Um front-end básico para um mecanismo de áudio de software" width="648" height="105" data-path="images/gdk/features/console/flowgraph_frontend.png" />

No código, esse flowgraph pode ser representado da seguinte forma.

```cpp theme={null}
        typedef enum mixBuffers
        {
          noBuffer      =   0,
          mixBuffer_1   =   1,
          mixBuffer_2   =   2,
          mixBuffer_3   =   3
        };
        
        typedef enum DMAcontexts
        {
          DMAcontext_0    = 0,  
        };
        
        typedef enum FLTVOLcontexts
        {
          FLTVOLcontext_0   = 0,
        };
                
        typedef enum EQcontexts
        {
          EQcontext_0    = 0,     
        };
        
        typedef enum SRCcontexts
        {
          SRCcontext_0    = 0,  
        };
        
        typedef enum XMAcontexts
        {
          XMAcontext_0    = 0,   
        };
        
        //
        // Command structure to be initialized.
        //
        #define nSHAPE_frontend_commands        7
        //
        SHAPE_FLOWGRAPH_COMMAND cmd[nSHAPE_frontend_commands];
        
        //
        // Mix buffer allocation for the voice.
        //

        // SetShapeAllocMixBufferCommand parameters:
        //                            command,   virtualID,      numIn,  numOut,   attenuation
        SetShapeAllocMixBufferCommand(&cmd[0],   mixBuffer_1,    1,        1,      SHAPE_MIXBUFFER_ATTENUATION_0_DB);
        SetShapeAllocMixBufferCommand(&cmd[1],   mixBuffer_2,    1,        1,      SHAPE_MIXBUFFER_ATTENUATION_0_DB);
        SetShapeAllocMixBufferCommand(&cmd[2],   mixBuffer_3,    1,        1,      SHAPE_MIXBUFFER_ATTENUATION_0_DB);

        //
        // SHAPE blocks.
        //

        // SetShapeSrcXmaCommand parameters:
        //                     command,      contextID,            XMAContextID,          leftorMonoMixBuffer, rightMixBuffer
        SetShapeSrcXmaCommand( &cmd[3],      SRCcontext_0,         XMAcontext_0,          mixBuffer_1,         noBuffer);

        // SetShapeEqCompCommand parameters:
        //                     command,      contextID,       inputMixBuffer, sidechainMixBuffer,   outputMixBuffer
        SetShapeEqCompCommand( &cmd[4],      EQcontext_0,     mixBuffer_1,   noBuffer,             mixBuffer_2);

        // SetShapeFiltVolCommand parameters:
        //                     command,      contextID,           inputMixBuffer, outputMixBuffer
        SetShapeFiltVolCommand(&cmd[5],      FLTVOLcontext_0,     mixBuffer_2,   mixBuffer_3   );

        // SetShapeDmaCommand parameters:
        //                     command,   contextID,         mixBuffer,    write
        SetShapeDmaCommand(    &cmd[6],   DMAcontext_0,      mixBuffer_3,   true   );  
```

<a id="ID4E6C" />

#### Renderização de áudio

Para renderizar áudio

1. Crie um flowgraph como os mostrados nos exemplos anteriores, que defina o grafo de áudio a ser processado.

2. Crie estruturas de contexto que definam como e o que o flowgraph processará.

3. Use o método [SubmitCommand](/pt-BR/reference/audio/acphal/interfaces/IAcpHal/methods/iacphal_submitcommand) para enviar o flowgraph ao ACP. Com base nos parâmetros de `SubmitCommand`, o flowgraph é processado uma vez e depois descartado, ou é processado a cada quadro de áudio.

4. O título é responsável por atualizar os dados de contexto de cada quadro de áudio usando os comandos `ACP_COMMAND_UPDATE_*_CONTEXT` ou sincronizando corretamente as atualizações com o processamento do flowgraph e atualizando os contextos manualmente.

   * [ACP\_COMMAND\_UPDATE\_DMA\_CONTEXT](/pt-BR/reference/audio/acphal/structs/acp_command_update_dma_context)
   * [ACP\_COMMAND\_UPDATE\_EQCOMP\_CONTEXT](/pt-BR/reference/audio/acphal/structs/acp_command_update_eqcomp_context)
   * [ACP\_COMMAND\_UPDATE\_FILTVOL\_CONTEXT](/pt-BR/reference/audio/acphal/structs/acp_command_update_filtvol_context)
   * [ACP\_COMMAND\_UPDATE\_PCM\_CONTEXT](/pt-BR/reference/audio/acphal/structs/acp_command_update_pcm_context)
   * [ACP\_COMMAND\_UPDATE\_SRC\_CONTEXT](/pt-BR/reference/audio/acphal/structs/acp_command_update_src_context)
   * [ACP\_COMMAND\_UPDATE\_XMA\_CONTEXT](/pt-BR/reference/audio/acphal/structs/acp_command_update_xma_context)

   Ao atualizar contextos, observe que um parâmetro de sinalizador de [SubmitCommand](/pt-BR/reference/audio/acphal/interfaces/IAcpHal/methods/iacphal_submitcommand) determina se a atualização ocorre o mais rápido possível ou no próximo quadro de áudio.

Para obter detalhes sobre o método para sincronizar manualmente a atualização de contextos, consulte o comando [ACP\_COMMAND\_LOAD\_SHAPE\_FLOWGRAPH](/pt-BR/reference/audio/acphal/structs/acp_command_load_shape_flowgraph). Em geral, use os comandos `ACP_COMMAND_TYPE_UPDATE_*_CONTEXT` para atualizar um pequeno número de contextos por quadro de áudio. Usar esses comandos para atualizar um grande número de contextos não é eficiente, porque uma grande quantidade de dados de contexto precisa ser copiada e transmitida ao ACP, além do processamento dos comandos. Se quiser atualizar um grande número de contextos, o título deve modificar os dados de contexto e depois enviar flowgraphs não persistentes ao ACP ou fazer bom uso do comando `ACP_COMMAND_TYPE_START_FLOWGRAPH` e do parâmetro `waitForStart` do comando [ACP\_COMMAND\_LOAD\_SHAPE\_FLOWGRAPH](/pt-BR/reference/audio/acphal/structs/acp_command_load_shape_flowgraph) para suspender o processamento até que o contexto seja atualizado. Quando o flowgraph conclui o processamento, os contextos ficam livres para serem atualizados novamente.

Uma terceira alternativa para atualizar contextos é usar um processo de buffer duplo. O título pode atualizar a segunda cópia dos contextos enquanto o flowgraph está sendo processado e trocar os contextos no início de um quadro de áudio.

<a id="ID4EHF" />

#### Análise de flowgraphs

O ACP encerra a análise de flowgraphs persistentes no final do quadro de áudio, que é um quadro de áudio do ACP com limite de 2,667 ms. Se um título tiver um flowgraph que leva 75% de um quadro de áudio para ser processado, mas o título só permitir que o processamento comece quando 30% do quadro de áudio já tiver decorrido, as partes do flowgraph que não foram analisadas serão descartadas. O flowgraph em si não é alterado. Quando isso ocorre, o ACP envia a mensagem `ACP_MESSAGE_TYPE_FLOWGRAPH_TERMINATED` se o título tiver se registrado para receber mensagens. Para determinar quais comandos não foram inseridos nas filas internas do SHAPE, o título deve examinar o sinalizador `queued` do comando do flowgraph.

Flowgraphs não persistentes geralmente são processados até a conclusão, independentemente do momento em que são enviados. Uma das exceções é o bloqueio de um ou mais comandos devido à indisponibilidade dos dados de origem ou ao uso inadequado do sinalizador `disabled`. Um título pode enviar um flowgraph não persistente em qualquer ponto de um quadro de áudio do ACP e ter certeza (exceto em alguns casos-limite) de que ele será concluído. O benefício é que o título não precisa estar perfeitamente sincronizado com o relógio de áudio, desde que continue atendendo aos flowgraphs dentro do intervalo de quadro de áudio do ACP de 2,667 ms. O risco é que o título pode causar interrupções de áudio se não enviar seus flowgraphs de forma consistente ou se os flowgraphs exigirem mais de 2,667 ms.

Veja a seguir um resumo do tempo de vida dos flowgraphs.

* Um flowgraph persistente permanece ativo no ACP até ser substituído pelo envio de um novo flowgraph ou de um flowgraph nulo, o que efetivamente o remove.

* O ACP começa a processar um flowgraph persistente no início de um quadro de áudio, a menos que o cliente instrua o ACP a aguardar um comando de início.

* O ACP para de processar um flowgraph persistente pouco antes do final do quadro de áudio, mesmo que ele não tenha sido totalmente processado.

* Um flowgraph não persistente fica ativo somente até ser concluído e, em seguida, é removido.

* Um flowgraph não persistente permanece ativo entre quadros de áudio. Ele só é removido depois de concluído.

<Note>O processamento de comandos não está vinculado à análise de flowgraphs. O ACP verifica constantemente se há novos comandos e os processa o mais rápido possível enquanto analisa um flowgraph ou realiza outro trabalho.</Note>

<a id="ID4EHG" />

#### Atualização de flowgraphs

As opções para atualizar flowgraphs são semelhantes às opções para atualizar contextos descritas anteriormente. A regra básica é a mesma: não atualize flowgraphs enquanto eles estiverem sendo processados.

Você pode usar três estratégias para atualizar flowgraphs.

1. Use flowgraphs não persistentes, recrie-os conforme necessário e envie-os no início do quadro de áudio. Um título pode reutilizar o mesmo flowgraph quantas vezes forem necessárias. Se o flowgraph não mudar, o título não precisará recriá-lo. Você também pode usar buffer duplo nessa abordagem, construindo um novo flowgraph enquanto o antigo está sendo processado. Ao serem recriados, os flowgraphs não só podem ser construídos do zero, mas também ter suas seções armazenadas e vinculadas conforme necessário, definindo adequadamente as IDs dos buffers de mixagem.

2. Use flowgraphs persistentes e recrie-os e substitua-os somente quando forem necessárias alterações. O buffer duplo também funciona aqui. O ACP pode ser executado livremente se você não usar o parâmetro `waitForStart` de [ACP\_COMMAND\_LOAD\_SHAPE\_FLOWGRAPH](/pt-BR/reference/audio/acphal/structs/acp_command_load_shape_flowgraph). O ACP começa a processar o flowgraph assim que o quadro de áudio começa e logo após o processamento dos comandos marcados para esse quadro de áudio. Como alternativa, o parâmetro `waitForStart` pode ser definido para impedir que o flowgraph seja processado até que o comando `ACP_COMMAND_TYPE_START_FLOWGRAPH` seja enviado. Isso não afeta diretamente as atualizações do flowgraph, mas permite uma pequena melhoria na sincronização.

3. Use o sinalizador `disabled` nos comandos do flowgraph para desabilitar partes de um flowgraph. Por exemplo, um flowgraph mestre pode ser criado, mas apenas as seções necessárias são habilitadas em cada execução. Isso deve ser combinado com a opção 1 ou 2 para que o novo flowgraph chegue ao ACP. Observe que atualmente o ACP não percorre o flowgraph em busca de blocos órfãos. O título deve desabilitar caminhos completos pelo flowgraph (não apenas os primeiros nós). Caso contrário, os comandos do SHAPE travam temporariamente o hardware. Esses travamentos podem ser simples, como um único bloco que não pode ser processado e é removido a um custo pequeno. Também podem ser graves o suficiente para travar uma voz inteira.

Use a técnica de buffer duplo em títulos que tenham grandes quantidades de vozes ou que façam muitas atualizações por quadro de áudio.

Se um título estiver usando `ACP_MESSAGE_TYPE_FLOWGRAPH_COMPLETED` para gerenciar atualizações, o ACP pode ficar ocioso por um longo período entre o momento em que o ACP adiciona a mensagem à fila de mensagens e o momento em que o título chama `PopMessage`. Não use essa abordagem para gerenciar atualizações — mantenha o ACP ativo.

<a id="ID4ELH" />

#### Vários flowgraphs

Um título pode processar vários flowgraphs por quadro de áudio se os requisitos combinados não excederem os recursos do hardware. O benefício é que o título pode executar vários mecanismos de áudio, tanto middleware quanto personalizados, ou dividir a análise em partes mais gerenciáveis. A desvantagem é que o hardware do SHAPE não funcionará com a mesma eficiência nesse modo. Para alcançar a taxa de transferência máxima do SHAPE, cada bloco do SHAPE deve ser mantido 100% ocupado, o que é impossível quando vários flowgraphs estão sendo processados.

Apenas um flowgraph pode ser carregado por cliente do ACP. Se um novo flowgraph for enviado por um cliente, ele substituirá o existente. Um título que exija suporte a vários flowgraphs precisa ter clientes separados para cada tipo de flowgraph (cada cliente com suas próprias filas de comandos e de mensagens) ou precisa aguardar a conclusão de um flowgraph antes de enviar um novo.

O suporte a vários flowgraphs foi projetado para ser usado por vários clientes, e não por um único cliente. Isso permite que um mecanismo de middleware envie seu flowgraph e que o título envie um flowgraph separado para processamento personalizado adicional. Para cada cliente do ACP exigido pelo título, crie uma instância da interface `IACPHAL`.

Como todos os recursos do ACP e do SHAPE são compartilhados entre todos os clientes (em especial as matrizes de contexto), os clientes devem coordenar a alocação e o compartilhamento desses recursos.

<a id="ID4EZH" />

### Utilitários de DMA

Inclua os utilitários de Direct Memory Access (DMA) do arquivo *ShapeDMAContext.h*. Os utilitários a seguir operam em uma estrutura [SHAPE\_DMA\_CONTEXT](/pt-BR/reference/audio/shapedmacontext/structs/shape_dma_context). Para obter mais informações, confira [ShapeDmaContext (métodos utilitários de DMA)](/pt-BR/reference/audio/shapedmacontext/shapedmacontext_members).

<a id="ID4EIAAC" />

### Utilitários do compressor de EQ

Inclua os utilitários de EQCOMP do arquivo *ShapeEqCompContext.h*. Esses utilitários operam em uma estrutura [SHAPE\_EQCOMP\_CONTEXT](/pt-BR/reference/audio/shapeeqcompcontext/structs/shape_eqcomp_context).

Para obter mais informações, confira [ShapeEqCompContext (métodos utilitários de EQCOMP)](/pt-BR/reference/audio/shapeeqcompcontext/shapeeqcompcontext_members).

<a id="ID4EWAAC" />

### Utilitários de volume de filtro

Inclua os utilitários de volume de filtro do arquivo *ShapeFiltVolContext.h*. Esses utilitários operam em uma estrutura [SHAPE\_FILTVOL\_CONTEXT](/pt-BR/reference/audio/shapefiltvolcontext/structs/shape_filtvol_context).

Para obter mais informações, confira [ShapeFiltVolContext (métodos utilitários de FLTVOL)](/pt-BR/reference/audio/shapefiltvolcontext/shapefiltvolcontext_members).

<a id="ID4EEBAC" />

### Utilitários de PCM

Inclua os utilitários de Pulse Code Modulation (PCM) do arquivo *ShapePCMContext.h*. Esses utilitários operam em uma estrutura [SHAPE\_PCM\_CONTEXT](/pt-BR/reference/audio/shapepcmcontext/structs/shape_pcm_context).

Para obter mais informações, confira [ShapePcmContext (métodos utilitários de PCM)](/pt-BR/reference/audio/shapepcmcontext/shapepcmcontext_members).

<a id="ID4ESBAC" />

### Utilitários de SRC

Inclua os utilitários de Sample Rate Convertor (SRC) do arquivo *ShapeSRCContext.h*. Esses utilitários operam em uma estrutura [SHAPE\_SRC\_CONTEXT](/pt-BR/reference/audio/shapesrccontext/structs/shape_src_context).

Para obter mais informações, confira [ShapeSrcContext (métodos utilitários de SRC)](/pt-BR/reference/audio/shapesrccontext/shapesrccontext_members).

<a id="ID4EACAC" />

### Utilitários de XMA

Inclua os utilitários de XMA do arquivo *ShapeXMAContext.h*. Esses utilitários operam em uma estrutura [SHAPE\_XMA\_CONTEXT](/pt-BR/reference/audio/shapexmacontext/structs/shape_xma_context).

Para obter mais informações, confira [ShapeXmaContext (métodos utilitários de XMA)](/pt-BR/reference/audio/shapexmacontext/shapexmacontext_members).

Os recursos de decodificação de XMA da emulação de hardware são limitados. Para obter detalhes, confira o tópico da estrutura [SHAPE\_XMA\_CONTEXT](/pt-BR/reference/audio/shapexmacontext/structs/shape_xma_context).

Um título pode usar dados XMA sem usar flowgraphs, mas os dados ainda precisam passar pelo ACP usando os comandos [ACP\_COMMAND\_TYPE](/pt-BR/reference/audio/acphal/enums/acp_command_type), conforme mostrado na tabela a seguir.

| Comando | Descrição |
| - | - |
| `ACP_COMMAND_TYPE_ENABLE_XMA_CONTEXT` | Habilita um único contexto XMA, e o ACP começa a decodificar o buffer especificado no contexto. |
| `ACP_COMMAND_TYPE_ENABLE_XMA_CONTEXTS` | Habilita um bloco de contextos XMA, e o ACP começa a decodificar os buffers definidos nos contextos. |
| `ACP_COMMAND_TYPE_DISABLE_XMA_CONTEXT` | Desabilita um único contexto XMA, e o ACP para de decodificar o buffer especificado no contexto. |
| `ACP_COMMAND_TYPE_DISABLE_XMA_CONTEXTS` | Desabilita um bloco de contextos XMA, e o ACP para de decodificar os buffers definidos nos contextos. |
| `ACP_COMMAND_TYPE_UPDATE_XMA_CONTEXT` | Atualiza um ou mais campos do contexto XMA. Isso pode ser feito de forma síncrona, no ACP, ou de forma assíncrona. |

Usando esses comandos, um título pode usar o ACP HAL do XBOX One de forma quase idêntica à forma como usa o XMA HAL do XBOX 360, com a seguinte ordem de operação.

1. Preencha o contexto ou os contextos com os dados relevantes: buffers, deslocamentos e muito mais.

2. Habilite os contextos.

3. Atualize os contextos. Se o contexto estiver desabilitado, o título poderá modificar o conteúdo diretamente. Se o contexto estiver habilitado, o título poderá desabilitá-lo primeiro ou usar o comando `ACP_COMMAND_TYPE_UPDATE_XMA_CONTEXT`, o que pode ser mais eficiente, pois o ACP cuida da desabilitação, da espera e da atualização.

Em geral, um título não deve usar apenas o componente XMA do SHAPE. É quase trivial criar um flowgraph de "front-end" que precisa apenas de manutenção mínima e que oferece ao título um SRC gratuito e de alta qualidade, além de outros recursos. Flowgraphs são fáceis de criar e gerenciar, e eles descarregarão o SRC da CPU principal e melhorarão a qualidade.

<a id="ID4EXEAC" />

### Valores de destino

Os valores de destino que podem ser definidos nas funções utilitárias representam os valores finais do parâmetro no final do quadro de áudio. Por exemplo, a estrutura [SHAPE\_FILTVOL\_CONTEXT](/pt-BR/reference/audio/shapefiltvolcontext/structs/shape_filtvol_context) contém valores para `gain` e `gainTarget`. Enquanto o quadro está sendo processado, `gain` é calculado usando interpolação linear e a equação a seguir.

```cpp theme={null}
gain = ((gainTarget - gain) / 127) * i + gain  
```

Em que i vai de 0 a 127.

No final do quadro, `gain` será igual a `gainTarget`.

Os parâmetros de destino podem ser definidos para o ACP conforme mostrado na tabela a seguir.

| Componente | Destino | Descrição |
| - | - | - |
| EQCOMP | `eqAB0Target` | Destino do coeficiente b0 do EQ A |
| EQCOMP | `eqAB1Target_L` | Destino do coeficiente b1 do EQ A, 8 bits inferiores |
| EQCOMP | `eqAB1Target_H` | Destino do coeficiente b1 do EQ A, 16 bits superiores |
| EQCOMP | `eqAB2Target_L` | Destino do coeficiente b2 do EQ A, 16 bits inferiores |
| EQCOMP | `eqAB2Target_H` | Destino do coeficiente b2 do EQ A, 8 bits superiores |
| EQCOMP | `eqAA1Target` | Destino do coeficiente a1 do EQ A |
| EQCOMP | `eqAA2Target` | Destino do coeficiente a2 do EQ A |
| EQCOMP | `eqBB0Target_L` | Destino do coeficiente b0 do EQ B, 8 bits inferiores |
| EQCOMP | `eqBB0Target_H` | Destino do coeficiente b0 do EQ B, 16 bits superiores |
| EQCOMP | `eqBB1Target_L` | Destino do coeficiente b1 do EQ B, 16 bits inferiores |
| EQCOMP | `eqBB1Target_H` | Destino do coeficiente b1 do EQ B, 8 bits superiores |
| EQCOMP | `eqBB2Target` | Destino do coeficiente b2 do EQ B |
| EQCOMP | `eqBA1Target` | Destino do coeficiente a1 do EQ B |
| EQCOMP | `eqBA2Target_L` | Destino do coeficiente a2 do EQ B, 8 bits inferiores |
| EQCOMP | `eqBA2Target_H` | Destino do coeficiente a2 do EQ B, 16 bits superiores |
| EQCOMP | `eqCB0Target_L` | Destino do coeficiente b0 do EQ C, 16 bits inferiores |
| EQCOMP | `eqCB0Target_H` | Destino do coeficiente b0 do EQ C, 8 bits superiores |
| EQCOMP | `eqCB1Target` | Destino do coeficiente b1 do EQ C |
| EQCOMP | `eqCB2Target` | Destino do coeficiente b2 do EQ C |
| EQCOMP | `eqCA1Target_L` | Destino do coeficiente a1 do EQ C, 8 bits inferiores |
| EQCOMP | `eqCA1Target_H` | Destino do coeficiente a1 do EQ C, 16 bits superiores |
| EQCOMP | `eqCA2Target_L` | Destino do coeficiente a2 do EQ C, 16 bits inferiores |
| EQCOMP | `eqCA2Target_H` | Destino do coeficiente a2 do EQ C, 8 bits superiores |
| EQCOMP | `compGainTarget` | Destino do ganho de saída configurável pelo usuário |
| FILTVOL | `gainTarget` | Nível de destino do volume |
| FILTVOL | `qRecipTarget` | Valor de destino de 1 sobre Q |
| FILTVOL | `fcTarget` | Valor de destino da frequência |
| SRC | `samplingIncrementTarget` | Valor final do incremento de amostragem |

<a id="ID4E3NAC" />

### Segurança de thread

Os [métodos da interface IACPHAL](/pt-BR/reference/audio/acphal/interfaces/IAcpHal/iacphal) e os [métodos do ACPHAL](/pt-BR/reference/audio/acphal/acphal_members) são thread-safe. Se a chamada [ApuCreateHeap](/pt-BR/reference/audio/apu/functions/apucreateheap) for feita, o heap será usado por todos os threads.

As funções utilitárias a seguir *não* são thread-safe. No entanto, o código-fonte delas é fornecido. Se necessário, você pode torná-las thread-safe. A maneira típica de fazer isso é usar [Objetos de Seção Crítica](https://msdn.microsoft.com/library/windows/desktop/ms682530\(v=vs.85\).aspx).

* [ShapeFlowGraph (flowgraph)](/pt-BR/reference/audio/shapeflowgraph/shapeflowgraph_members)
* [ShapeDmaContext (DMA)](/pt-BR/reference/audio/shapedmacontext/shapedmacontext_members)
* [ShapeEqCompContext (EQCOMP)](/pt-BR/reference/audio/shapeeqcompcontext/shapeeqcompcontext_members)
* [ShapeFiltVolContext (FLTVOL)](/pt-BR/reference/audio/shapefiltvolcontext/shapefiltvolcontext_members)
* [ShapePcmContext (PCM)](/pt-BR/reference/audio/shapepcmcontext/shapepcmcontext_members)
* [ShapeSrcContext (SRC)](/pt-BR/reference/audio/shapesrccontext/shapesrccontext_members)
* [ShapeXmaContext (XMA)](/pt-BR/reference/audio/shapexmacontext/shapexmacontext_members)

<a id="ID4EUPAC" />

### Diretrizes para usar o SRC com dados PCM e XMA

A tabela a seguir mostra as diretrizes para usar o bloco SRC com dados PCM e XMA.

| Destino | Implementação |
| - | - |
| PCM linear sem loop | Inicie a voz usando `SHAPE_SRC_COMMAND_TYPE_START` para o SRC. Deixe a voz ser reproduzida até o fim. Opcionalmente, interrompa-a antes do fim usando `SHAPE_SRC_COMMAND_TYPE_STOP_IMMEDIATE`. |
| PCM linear com loop infinito | Defina a contagem de loops do contexto PCM (`loopCount`) como `SHAPE_PCM_INFINITE_LOOP_COUNT`. Inicie a voz usando `SHAPE_SRC_COMMAND_TYPE_START` para o SRC. Zero. Deixe a voz ser reproduzida até que você queira interrompê-la no final de um loop emitindo `SHAPE_SRC_COMMAND_TYPE_STOP_END` e deixe a voz terminar de tocar. Opcionalmente, interrompa-a imediatamente emitindo `SHAPE_SRC_COMMAND_TYPE_STOP_IMMEDIATE`. |
| PCM linear com loop finito | Defina a contagem de loops do contexto PCM (`loopCount`) como \[0, 254]. Inicie a voz usando `SHAPE_SRC_COMMAND_TYPE_START` para o SRC. Deixe a voz ser reproduzida até o fim. Opcionalmente, interrompa-a no final de um loop usando `SHAPE_SRC_COMMAND_TYPE_STOP_END` e deixe a voz terminar de tocar. Opcionalmente, interrompa-a imediatamente emitindo `SHAPE_SRC_COMMAND_TYPE_STOP_IMMEDIATE`. |
| PCM circular | Inicie a voz usando `SHAPE_SRC_COMMAND_TYPE_START` para o SRC. Continue transmitindo dados e atualizando o ponteiro de gravação do contexto PCM até querer parar. Emita `SHAPE_SRC_COMMAND_TYPE_STOP_END` para deixar o SRC reproduzir até o ponteiro de gravação PCM atual (`loopStartWritePointer`). Opcionalmente, emita `SHAPE_SRC_COMMAND_TYPE_STOP_IMMEDIATE` para parar imediatamente. |
| XMA de streaming (sem loop de HW) | Inicie a voz usando `SHAPE_SRC_COMMAND_TYPE_START` para o SRC. Quando o último buffer de entrada XMA for consumido, emita `SHAPE_SRC_COMMAND_TYPE_STOP_END` para reproduzir até o fim do buffer decodificado (confira a OBSERVAÇÃO a seguir). Opcionalmente, emita `SHAPE_SRC_COMMAND_TYPE_STOP_IMMEDIATE` para parar imediatamente. |
| XMA com loop de HW infinito | Defina a contagem de loops do contexto XMA (`numLoops`) como `SHAPE_XMA_INFINITE_LOOP_COUNT`. Inicie a voz usando `SHAPE_SRC_COMMAND_TYPE_START` para o SRC. Deixe a voz ser reproduzida até que você queira interrompê-la no final de um loop definindo a contagem de loops do XMA como zero, emitindo `SHAPE_SRC_COMMAND_TYPE_STOP_END` e, em seguida, deixando a voz terminar de tocar. Opcionalmente, interrompa imediatamente emitindo `SHAPE_SRC_COMMAND_TYPE_STOP_IMMEDIATE`. |
| XMA com loop de HW finito | Defina a contagem de loops do contexto XMA (`numLoops`) como \[0, 254]. Inicie a voz usando `SHAPE_SRC_COMMAND_TYPE_START` para o SRC. Deixe a voz ser reproduzida até que você queira interrompê-la no final dos loops, acompanhando a contagem de loops. Quando ela chegar a zero, emita `SHAPE_SRC_COMMAND_TYPE_STOP_END` e deixe a voz terminar de tocar. Opcionalmente, para parar no final do próximo loop, defina a contagem de loops como zero. Quando o último buffer de entrada XMA for consumido, defina o comando do SRC como `SHAPE_SRC_COMMAND_TYPE_STOP_END` e deixe a voz terminar de tocar (confira a OBSERVAÇÃO a seguir). Para parar imediatamente, emita `SHAPE_SRC_COMMAND_TYPE_STOP_IMMEDIATE`. |

<Note>Quando qualquer um desses cenários for concluído, o comando do SRC será `SHAPE_SRC_COMMAND_TYPE_STOP_IMMEDIATE`.</Note>

Verifique os bits válidos do buffer de entrada XMA na mesma frequência usada para processar os flowgraphs do SHAPE. Se você fizer essa verificação como parte da lógica de streaming, que ocorre em intervalos muito mais longos, é possível que o buffer de saída XMA se esvazie antes que você instrua o SRC a parar no final. Isso pode fazer com que o flowgraph trave.

<a id="ID4E5BAE" />

### Pausar e retomar um título

Um título deve ser capaz de pausar e retomar, por exemplo, quando o usuário o coloca no modo restrito. Para pausar e retomar ao programar diretamente para o hardware do SHAPE usando `IAcpHal`, basta fazer com que o título pare de enviar comandos. Os comandos que já foram enviados serão concluídos normalmente e poderão encher a fila de mensagens.

Se um título estiver usando flowgraphs persistentes, ele deverá carregar um flowgraph nulo para interromper o processamento. Isso difere do processo de pausa e retomada quando você programa usando o `XAudio2`. Para obter mais informações, confira a [visão geral do XAudio2](/pt-BR/build/console-features/audio/overviews/xaudio2-overview).

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

* [Acphal (conteúdo da API)](/pt-BR/reference/audio/acphal/acphal_members)
  * Estruturas
    * [ACP\_COMMAND\_UPDATE\_DMA\_CONTEXT](/pt-BR/reference/audio/acphal/structs/acp_command_update_dma_context)
    * [ACP\_COMMAND\_UPDATE\_EQCOMP\_CONTEXT](/pt-BR/reference/audio/acphal/structs/acp_command_update_eqcomp_context)
    * [ACP\_COMMAND\_UPDATE\_FILTVOL\_CONTEXT](/pt-BR/reference/audio/acphal/structs/acp_command_update_filtvol_context)
    * [ACP\_COMMAND\_UPDATE\_PCM\_CONTEXT](/pt-BR/reference/audio/acphal/structs/acp_command_update_pcm_context)
    * [ACP\_COMMAND\_UPDATE\_SRC\_CONTEXT](/pt-BR/reference/audio/acphal/structs/acp_command_update_src_context)
    * [ACP\_COMMAND\_UPDATE\_XMA\_CONTEXT](/pt-BR/reference/audio/acphal/structs/acp_command_update_xma_context)
    * [ACP\_COMMAND\_LOAD\_SHAPE\_FLOWGRAPH](/pt-BR/reference/audio/acphal/structs/acp_command_load_shape_flowgraph)
* [Shapedmacontext (conteúdo da API)](/pt-BR/reference/audio/shapedmacontext/shapedmacontext_members)
  * Estruturas
    * [SHAPE\_DMA\_CONTEXT](/pt-BR/reference/audio/shapedmacontext/structs/shape_dma_context)
* [Shapeeqcompcontext (conteúdo da API)](/pt-BR/reference/audio/shapeeqcompcontext/shapeeqcompcontext_members)
  * Estruturas
    * [SHAPE\_EQCOMP\_CONTEXT](/pt-BR/reference/audio/shapeeqcompcontext/structs/shape_eqcomp_context)
* [Shapefiltvolcontext (conteúdo da API)](/pt-BR/reference/audio/shapefiltvolcontext/shapefiltvolcontext_members)
  * Estruturas
    * [SHAPE\_FILTVOL\_CONTEXT](/pt-BR/reference/audio/shapefiltvolcontext/structs/shape_filtvol_context)
* [Shapeflowgraph (conteúdo da API)](/pt-BR/reference/audio/shapeflowgraph/shapeflowgraph_members)
* [Shapepcmcontext (conteúdo da API)](/pt-BR/reference/audio/shapepcmcontext/shapepcmcontext_members)
  * Estruturas
    * [SHAPE\_PCM\_CONTEXT](/pt-BR/reference/audio/shapepcmcontext/structs/shape_pcm_context)
* [Shapesrccontext (conteúdo da API)](/pt-BR/reference/audio/shapesrccontext/shapesrccontext_members)
  * Estruturas
    * [SHAPE\_SRC\_CONTEXT](/pt-BR/reference/audio/shapesrccontext/structs/shape_src_context)
* [Shapexmacontext (conteúdo da API)](/pt-BR/reference/audio/shapexmacontext/shapexmacontext_members)
  * Estruturas
    * [SHAPE\_XMA\_CONTEXT](/pt-BR/reference/audio/shapexmacontext/structs/shape_xma_context)
* [apu (conteúdo da API)](/pt-BR/reference/audio/apu/apu_members)
  * Funções
    * [ApuCreateHeap](/pt-BR/reference/audio/apu/functions/apucreateheap)


## Related topics

- [Visão geral do SHAPE](/pt-BR/build/console-features/audio/overviews/shape-overview.md)
- [ACP_COMMAND_TYPE](/pt-BR/reference/audio/acphal/enums/acp_command_type.md)
- [ACP_COMMAND_LOAD_SHAPE_FLOWGRAPH](/pt-BR/reference/audio/acphal/structs/acp_command_load_shape_flowgraph.md)
- [ACP_COMMAND_UPDATE_XMA_CONTEXT](/pt-BR/reference/audio/acphal/structs/acp_command_update_xma_context.md)
- [ACP_COMMAND_UPDATE_DMA_CONTEXT](/pt-BR/reference/audio/acphal/structs/acp_command_update_dma_context.md)
