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

# Información general sobre ACP

> Guía de programación del Audio Control Processor (ACP) y la biblioteca acphal que administra los grafos de flujo de audio de SHAPE en las consolas XBOX One.

Este tema proporciona descripciones y ejemplos de los grafos de flujo que se usan para dirigir el Audio Control Processor (ACP).

<a id="ID4EX" />

## Información general sobre ACP

En esta sección se describe la interfaz de programación del ACP.

La biblioteca `acphal` (*acphal.lib*) define el conjunto de API del Scalable Hardware Audio Processing Engine (SHAPE). El Microsoft Game Development Kit (GDK) también incluye una colección de utilidades de audio y código fuente que te ayudan a preparar los datos de audio para su uso con SHAPE. Los encabezados de utilidades definen lo siguiente:

* Las estructuras de contexto para cada formato de datos admitido

* Un conjunto completo de funciones que pueden usarse para leer y escribir en estos contextos

Define al menos un grafo de flujo en tu aplicación para enrutar los datos de audio *a través* de los bloques de SHAPE. El ACP administra los bloques de SHAPE y garantiza la eficiencia.

Para obtener más información sobre el conjunto de API, incluidas las estructuras y enumeraciones declaradas en los archivos de utilidades, consulta la referencia de [AcpHal](/reference/audio/acphal/acphal_members).

Para obtener más información sobre la arquitectura de SHAPE, consulta la [información general sobre SHAPE](/build/console-features/audio/overviews/shape-overview).

En los archivos de código fuente de un proyecto de título, asegúrate de incluir el archivo *ShapeContext.h*, no los archivos de encabezado de contexto individuales.

En este tema:

* [Grafos de flujo](#ID4EVB)
* [Utilidades de DMA](#ID4EZH)
* [Utilidades del compresor de EQ](#ID4EIAAC)
* [Utilidades de volumen de filtro](#ID4EWAAC)
* [Utilidades de PCM](#ID4EEBAC)
* [Utilidades de SRC](#ID4ESBAC)
* [Utilidades de XMA](#ID4EACAC)
* [Valores objetivo](#ID4EXEAC)
* [Seguridad para subprocesos](#ID4E3NAC)
* [Directrices para usar SRC con datos PCM y XMA](#ID4EUPAC)
* [Pausa y reanudación de un título](#ID4E5BAE)

<a id="ID4EVB" />

### Grafos de flujo

Para usar SHAPE, un título normalmente crearía un grafo de flujo de SHAPE. Para ver la descripción de una alternativa, consulta la sección [Utilidades de XMA](#ID4EACAC). Un grafo de flujo de SHAPE es una matriz de comandos (uno por bloque de SHAPE) acompañada de datos de contexto que describe el orden de las operaciones de los bloques individuales y los datos sobre los que operan. El ACP usa los datos del grafo de flujo para programar correctamente las operaciones dentro de los bloques de SHAPE.

El título es responsable de compilar el grafo de flujo y enviarlo al ACP. Para compilar un grafo de flujo, usa [ShapeFlowGraph (métodos de utilidad de grafos de flujo)](/reference/audio/shapeflowgraph/shapeflowgraph_members).

En las figuras siguientes, los bloques verdes representan componentes de SHAPE, los bloques cian son el material de origen y los círculos amarillos etiquetados son los búferes de mezcla de hardware.

* [Sonidos 3D](#ID4EHC)
* [Front end para un motor de audio por software](#ID4ETC)
* [Representación de audio](#ID4E6C)
* [Análisis de grafos de flujo](#ID4EHF)
* [Actualización de grafos de flujo](#ID4EHG)
* [Varios grafos de flujo](#ID4ELH)

<a id="ID4EHC" />

#### Sonidos 3D

**Figura 1. Dos voces, cada una panoramizada entre dos salidas, con un envío a una salida común.**

<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="Grafo de flujo de dos voces" width="985" height="465" data-path="images/gdk/features/console/flowgraph_pan.png" />

En código, este grafo de flujo puede representarse de la siguiente manera.

```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 un motor de audio por software

**Figura 2.  Un front end básico para un motor por software. Potencialmente, todas las voces que usen este modelo usarían la misma estructura.**

<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="Un front end básico para un motor de audio por software" width="648" height="105" data-path="images/gdk/features/console/flowgraph_frontend.png" />

En código, este grafo de flujo puede representarse de la siguiente manera.

```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" />

#### Representación de audio

Para representar audio

1. Crea un grafo de flujo como los que se muestran en los ejemplos anteriores y que defina el grafo de audio que se va a procesar.

2. Crea las estructuras de contexto que definen cómo y qué procesará el grafo de flujo.

3. Usa el método [SubmitCommand](/reference/audio/acphal/interfaces/IAcpHal/methods/iacphal_submitcommand) para enviar el grafo de flujo al ACP. Según los parámetros de `SubmitCommand`, el grafo de flujo se procesa una vez y luego se descarta, o se procesa en cada fotograma de audio.

4. El título es responsable de actualizar los datos de contexto en cada fotograma de audio mediante los comandos `ACP_COMMAND_UPDATE_*_CONTEXT` o sincronizando correctamente las actualizaciones con el procesamiento del grafo de flujo y actualizando los contextos manualmente.

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

   Al actualizar los contextos, ten en cuenta que un parámetro de marca de [SubmitCommand](/reference/audio/acphal/interfaces/IAcpHal/methods/iacphal_submitcommand) determina si la actualización se realiza lo antes posible o en el siguiente fotograma de audio.

Para obtener más información sobre el método de sincronización manual de la actualización de contextos, consulta el comando [ACP\_COMMAND\_LOAD\_SHAPE\_FLOWGRAPH](/reference/audio/acphal/structs/acp_command_load_shape_flowgraph). En general, usa los comandos `ACP_COMMAND_TYPE_UPDATE_*_CONTEXT` para actualizar un número reducido de contextos por fotograma de audio. Usar estos comandos para actualizar un gran número de contextos no es eficiente porque, además del procesamiento de los comandos, es necesario copiar y transmitir al ACP una gran cantidad de datos de contexto. Si quieres actualizar un gran número de contextos, el título debería modificar los datos de contexto y luego enviar grafos de flujo no persistentes al ACP, o bien hacer un buen uso del comando `ACP_COMMAND_TYPE_START_FLOWGRAPH` y del parámetro `waitForStart` del comando [ACP\_COMMAND\_LOAD\_SHAPE\_FLOWGRAPH](/reference/audio/acphal/structs/acp_command_load_shape_flowgraph) para retener el procesamiento hasta que el contexto se haya actualizado. Cuando el grafo de flujo termina de procesarse, los contextos quedan libres para actualizarse de nuevo.

Una tercera alternativa para actualizar los contextos es usar un proceso de doble búfer. El título puede actualizar la segunda copia de los contextos mientras se procesa el grafo de flujo e intercambiar los contextos al inicio de un fotograma de audio.

<a id="ID4EHF" />

#### Análisis de grafos de flujo

El ACP termina el análisis de los grafos de flujo persistentes al final del fotograma de audio, que es un fotograma de audio del ACP con un límite de 2,667 ms. Si un título tiene un grafo de flujo que tarda el 75 por ciento de un fotograma de audio en procesarse pero el título no deja que el procesamiento comience hasta que ha transcurrido el 30 por ciento del fotograma de audio, las partes del grafo de flujo que no se analizaron se purgan. El grafo de flujo en sí no se altera. Cuando esto ocurre, el ACP envía el mensaje `ACP_MESSAGE_TYPE_FLOWGRAPH_TERMINATED` si el título se ha registrado para recibir mensajes. Para determinar qué comandos no se insertaron en las colas internas de SHAPE, el título examinaría la marca `queued` del comando del grafo de flujo.

Los grafos de flujo no persistentes normalmente se procesan hasta completarse, independientemente del momento de su envío. Una de las excepciones es el bloqueo de uno o varios comandos debido a la no disponibilidad de los datos de origen o a un mal uso de la marca `disabled`. Un título puede enviar un grafo de flujo no persistente en cualquier momento de un fotograma de audio del ACP y tener la certeza (salvo unos pocos casos límite) de que se completará. La ventaja es que el título no tiene que estar perfectamente sincronizado con el reloj de audio, siempre que siga atendiendo los grafos de flujo dentro del intervalo de fotograma de audio del ACP de 2,667 ms. El riesgo es que un título puede provocar cortes de audio si no envía sus grafos de flujo de forma coherente o si los grafos de flujo requieren más de 2,667 ms.

A continuación se resume el ciclo de vida de los grafos de flujo.

* Un grafo de flujo persistente permanece activo en el ACP hasta que se reemplaza enviando un nuevo grafo de flujo o un grafo de flujo nulo, lo que en la práctica lo elimina.

* El ACP comienza a procesar un grafo de flujo persistente al principio de un fotograma de audio, a menos que el cliente indique al ACP que espere un comando de inicio.

* El ACP deja de procesar un grafo de flujo persistente poco antes del final del fotograma de audio, incluso si no se ha procesado por completo.

* Un grafo de flujo no persistente solo está activo hasta que se completa, y luego se elimina.

* Un grafo de flujo no persistente permanece activo entre fotogramas de audio. Solo se elimina después de haberse completado.

<Note>El procesamiento de comandos no está ligado al análisis de grafos de flujo. El ACP busca constantemente comandos nuevos y los procesa lo más rápido posible mientras analiza un grafo de flujo o realiza otro trabajo.</Note>

<a id="ID4EHG" />

#### Actualización de grafos de flujo

Las opciones para actualizar grafos de flujo son similares a las de la actualización de contextos descrita anteriormente. La regla básica es la misma: no actualices los grafos de flujo mientras se están procesando.

Puedes usar tres estrategias para actualizar los grafos de flujo.

1. Usa grafos de flujo no persistentes, recompílalos según sea necesario y envíalos al principio del fotograma de audio. Un título puede reutilizar el mismo grafo de flujo tantas veces como sea necesario. Si el grafo de flujo no cambia, el título no necesita recompilarlo. También puedes aplicar doble búfer a este enfoque construyendo un nuevo grafo de flujo mientras se procesa el anterior. Al recompilarlos, los grafos de flujo no solo pueden construirse desde cero, sino que sus secciones también pueden almacenarse y enlazarse según sea necesario estableciendo adecuadamente los identificadores de los búferes de mezcla.

2. Usa grafos de flujo persistentes y recompílalos y reemplázalos solo cuando se necesiten cambios. El doble búfer también funciona aquí. Se puede dejar que el ACP funcione libremente no usando el parámetro `waitForStart` de [ACP\_COMMAND\_LOAD\_SHAPE\_FLOWGRAPH](/reference/audio/acphal/structs/acp_command_load_shape_flowgraph). El ACP comienza a procesar el grafo de flujo en cuanto empieza el fotograma de audio y justo después de que se procesen los comandos etiquetados para ese fotograma de audio. Como alternativa, se puede establecer el parámetro `waitForStart` para impedir que el grafo de flujo se procese hasta que se envíe el comando `ACP_COMMAND_TYPE_START_FLOWGRAPH`. Esto no afecta directamente a las actualizaciones de los grafos de flujo, pero permite una ligera mejora en la sincronización.

3. Usa la marca `disabled` en los comandos del grafo de flujo para deshabilitar partes de un grafo de flujo. Por ejemplo, se puede compilar un grafo de flujo maestro, pero habilitando solo las secciones necesarias en cada ejecución. Esto debe combinarse con la opción 1 o 2 para hacer llegar el nuevo grafo de flujo al ACP. Ten en cuenta que el ACP actualmente no recorre el grafo de flujo en busca de bloques huérfanos. El título debe deshabilitar rutas completas a través del grafo de flujo (no solo los primeros nodos). Si no se hace así, los comandos de SHAPE bloquean temporalmente el hardware. Estos bloqueos pueden ser simples, como un único bloque que no puede procesarse y se elimina con un coste pequeño. También pueden ser lo bastante graves como para bloquear una voz completa.

Usa la técnica de doble búfer en los títulos que tienen un gran número de voces o que realizan muchas actualizaciones por fotograma de audio.

Si un título usa `ACP_MESSAGE_TYPE_FLOWGRAPH_COMPLETED` para administrar las actualizaciones, el ACP puede quedar inactivo durante un periodo prolongado entre el momento en que el ACP agrega el mensaje a la cola de mensajes y el momento en que el título llama a `PopMessage`. No uses este enfoque para administrar las actualizaciones: mantén el ACP activo.

<a id="ID4ELH" />

#### Varios grafos de flujo

Un título puede procesar varios grafos de flujo por fotograma de audio si sus requisitos combinados no superan las capacidades del hardware. La ventaja es que el título puede ejecutar varios motores de audio, tanto middleware como personalizados, o dividir su análisis en fragmentos más manejables. El inconveniente es que el hardware de SHAPE no funcionará con la misma eficiencia en este modo. Para alcanzar el rendimiento máximo de SHAPE, cada bloque de SHAPE debe mantenerse ocupado al 100 por cien, lo que es imposible cuando se procesan varios grafos de flujo.

Solo se puede cargar un grafo de flujo por cliente del ACP. Si un cliente envía un nuevo grafo de flujo, este reemplaza al existente. Un título que requiera compatibilidad con varios grafos de flujo necesita tener clientes independientes para cada tipo de grafo de flujo (cada cliente con sus propias colas de comandos y mensajes) o debe esperar a que un grafo de flujo se complete antes de enviar uno nuevo.

La compatibilidad con varios grafos de flujo está diseñada para su uso por varios clientes, no por un único cliente. Esto permite que un motor de middleware envíe su grafo de flujo y que el título envíe un grafo de flujo independiente para procesamiento personalizado adicional. Para cada cliente del ACP que requiera el título, crea una instancia de la interfaz `IACPHAL`.

Dado que todos los recursos del ACP y de SHAPE se comparten entre todos los clientes (en particular las matrices de contexto), los clientes deben coordinar la asignación y el uso compartido de esos recursos.

<a id="ID4EZH" />

### Utilidades de DMA

Incluye las utilidades de acceso directo a memoria (DMA) en el archivo *ShapeDMAContext.h*. Las siguientes utilidades operan sobre una estructura [SHAPE\_DMA\_CONTEXT](/reference/audio/shapedmacontext/structs/shape_dma_context). Para obtener más información, consulta [ShapeDmaContext (métodos de utilidad de DMA)](/reference/audio/shapedmacontext/shapedmacontext_members).

<a id="ID4EIAAC" />

### Utilidades del compresor de EQ

Incluye las utilidades de EQCOMP en el archivo *ShapeEqCompContext.h*. Estas utilidades operan sobre una estructura [SHAPE\_EQCOMP\_CONTEXT](/reference/audio/shapeeqcompcontext/structs/shape_eqcomp_context).

Para obtener más información, consulta [ShapeEqCompContext (métodos de utilidad de EQCOMP)](/reference/audio/shapeeqcompcontext/shapeeqcompcontext_members).

<a id="ID4EWAAC" />

### Utilidades de volumen de filtro

Incluye las utilidades de volumen de filtro en el archivo *ShapeFiltVolContext.h*. Estas utilidades operan sobre una estructura [SHAPE\_FILTVOL\_CONTEXT](/reference/audio/shapefiltvolcontext/structs/shape_filtvol_context).

Para obtener más información, consulta [ShapeFiltVolContext (métodos de utilidad de FLTVOL)](/reference/audio/shapefiltvolcontext/shapefiltvolcontext_members).

<a id="ID4EEBAC" />

### Utilidades de PCM

Incluye las utilidades de modulación por impulsos codificados (PCM) en el archivo *ShapePCMContext.h*. Estas utilidades operan sobre una estructura [SHAPE\_PCM\_CONTEXT](/reference/audio/shapepcmcontext/structs/shape_pcm_context).

Para obtener más información, consulta [ShapePcmContext (métodos de utilidad de PCM)](/reference/audio/shapepcmcontext/shapepcmcontext_members).

<a id="ID4ESBAC" />

### Utilidades de SRC

Incluye las utilidades del convertidor de frecuencia de muestreo (SRC) en el archivo *ShapeSRCContext.h*. Estas utilidades operan sobre una estructura [SHAPE\_SRC\_CONTEXT](/reference/audio/shapesrccontext/structs/shape_src_context).

Para obtener más información, consulta [ShapeSrcContext (métodos de utilidad de SRC)](/reference/audio/shapesrccontext/shapesrccontext_members).

<a id="ID4EACAC" />

### Utilidades de XMA

Incluye las utilidades de XMA en el archivo *ShapeXMAContext.h*. Estas utilidades operan sobre una estructura [SHAPE\_XMA\_CONTEXT](/reference/audio/shapexmacontext/structs/shape_xma_context).

Para obtener más información, consulta [ShapeXmaContext (métodos de utilidad de XMA)](/reference/audio/shapexmacontext/shapexmacontext_members).

Las capacidades de descodificación de XMA de la emulación de hardware son limitadas. Para obtener más información, consulta el tema de la estructura [SHAPE\_XMA\_CONTEXT](/reference/audio/shapexmacontext/structs/shape_xma_context).

Un título puede usar datos XMA sin usar grafos de flujo, pero los datos aún tienen que pasar por el ACP mediante los comandos [ACP\_COMMAND\_TYPE](/reference/audio/acphal/enums/acp_command_type), como se muestra en la tabla siguiente.

| Comando                                 | Descripción                                                                                                                |
| --------------------------------------- | -------------------------------------------------------------------------------------------------------------------------- |
| `ACP_COMMAND_TYPE_ENABLE_XMA_CONTEXT`   | Habilita un único contexto XMA, y el ACP comienza a descodificar el búfer especificado en el contexto.                     |
| `ACP_COMMAND_TYPE_ENABLE_XMA_CONTEXTS`  | Habilita un bloque de contextos XMA, y el ACP comienza a descodificar los búferes definidos en los contextos.              |
| `ACP_COMMAND_TYPE_DISABLE_XMA_CONTEXT`  | Deshabilita un único contexto XMA, y el ACP deja de descodificar el búfer especificado en el contexto.                     |
| `ACP_COMMAND_TYPE_DISABLE_XMA_CONTEXTS` | Deshabilita un bloque de contextos XMA, y el ACP deja de descodificar los búferes definidos en los contextos.              |
| `ACP_COMMAND_TYPE_UPDATE_XMA_CONTEXT`   | Actualiza uno o varios campos del contexto XMA. Esto puede hacerse de forma sincrónica, en el ACP, o de forma asincrónica. |

Con estos comandos, un título puede usar la HAL del ACP de XBOX One de forma casi idéntica a como usa la HAL de XMA de XBOX 360, con el siguiente orden de operación.

1. Rellena el contexto o los contextos con los datos pertinentes: búferes, desplazamientos y más.

2. Habilita los contextos.

3. Actualiza los contextos. Si el contexto está deshabilitado, el título puede modificar directamente el contenido. Si el contexto está habilitado, el título puede deshabilitarlo primero o usar el comando `ACP_COMMAND_TYPE_UPDATE_XMA_CONTEXT`, que puede ser más eficiente porque el ACP se encarga de deshabilitar, esperar y actualizar.

En general, un título no debería usar solo el componente XMA de SHAPE. Es casi trivial crear un grafo de flujo de "front-end" que solo necesita un mantenimiento menor y que proporciona al título un SRC gratuito de alta calidad y otras características. Los grafos de flujo son fáciles de crear y administrar, y descargarán el SRC de la CPU principal y mejorarán la calidad.

<a id="ID4EXEAC" />

### Valores objetivo

Los valores objetivo que pueden establecerse en las funciones de utilidad representan los valores finales del parámetro al final del fotograma de audio. Por ejemplo, la estructura [SHAPE\_FILTVOL\_CONTEXT](/reference/audio/shapefiltvolcontext/structs/shape_filtvol_context) contiene valores para `gain` y `gainTarget`. Mientras se procesa el fotograma, `gain` se calcula mediante interpolación lineal y la siguiente ecuación.

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

Donde i va de 0 a 127.

Al final del fotograma, `gain` será igual a `gainTarget`.

Los parámetros objetivo pueden establecerse para el ACP como se muestra en la tabla siguiente.

| Componente | Objetivo                  | Descripción                                                     |
| ---------- | ------------------------- | --------------------------------------------------------------- |
| EQCOMP     | `eqAB0Target`             | Objetivo del coeficiente b0 del EQ A                            |
| EQCOMP     | `eqAB1Target_L`           | Objetivo del coeficiente b1 del EQ A, 8 bits inferiores         |
| EQCOMP     | `eqAB1Target_H`           | Objetivo del coeficiente b1 del EQ A, 16 bits superiores        |
| EQCOMP     | `eqAB2Target_L`           | Objetivo del coeficiente b2 del EQ A, 16 bits inferiores        |
| EQCOMP     | `eqAB2Target_H`           | Objetivo del coeficiente b2 del EQ A, 8 bits superiores         |
| EQCOMP     | `eqAA1Target`             | Objetivo del coeficiente a1 del EQ A                            |
| EQCOMP     | `eqAA2Target`             | Objetivo del coeficiente a2 del EQ A                            |
| EQCOMP     | `eqBB0Target_L`           | Objetivo del coeficiente b0 del EQ B, 8 bits inferiores         |
| EQCOMP     | `eqBB0Target_H`           | Objetivo del coeficiente b0 del EQ B, 16 bits superiores        |
| EQCOMP     | `eqBB1Target_L`           | Objetivo del coeficiente b1 del EQ B, 16 bits inferiores        |
| EQCOMP     | `eqBB1Target_H`           | Objetivo del coeficiente b1 del EQ B, 8 bits superiores         |
| EQCOMP     | `eqBB2Target`             | Objetivo del coeficiente b2 del EQ B                            |
| EQCOMP     | `eqBA1Target`             | Objetivo del coeficiente a1 del EQ B                            |
| EQCOMP     | `eqBA2Target_L`           | Objetivo del coeficiente a2 del EQ B, 8 bits inferiores         |
| EQCOMP     | `eqBA2Target_H`           | Objetivo del coeficiente a2 del EQ B, 16 bits superiores        |
| EQCOMP     | `eqCB0Target_L`           | Objetivo del coeficiente b0 del EQ C, 16 bits inferiores        |
| EQCOMP     | `eqCB0Target_H`           | Objetivo del coeficiente b0 del EQ C, 8 bits superiores         |
| EQCOMP     | `eqCB1Target`             | Objetivo del coeficiente b1 del EQ C                            |
| EQCOMP     | `eqCB2Target`             | Objetivo del coeficiente b2 del EQ C                            |
| EQCOMP     | `eqCA1Target_L`           | Objetivo del coeficiente a1 del EQ C, 8 bits inferiores         |
| EQCOMP     | `eqCA1Target_H`           | Objetivo del coeficiente a1 del EQ C, 16 bits superiores        |
| EQCOMP     | `eqCA2Target_L`           | Objetivo del coeficiente a2 del EQ C, 16 bits inferiores        |
| EQCOMP     | `eqCA2Target_H`           | Objetivo del coeficiente a2 del EQ C, 8 bits superiores         |
| EQCOMP     | `compGainTarget`          | Objetivo configurable por el usuario para la ganancia de salida |
| FILTVOL    | `gainTarget`              | Nivel objetivo de volumen                                       |
| FILTVOL    | `qRecipTarget`            | Valor objetivo de 1 entre Q                                     |
| FILTVOL    | `fcTarget`                | Valor objetivo de frecuencia                                    |
| SRC        | `samplingIncrementTarget` | Valor final del incremento de muestreo                          |

<a id="ID4E3NAC" />

### Seguridad para subprocesos

Los [métodos de la interfaz IACPHAL](/reference/audio/acphal/interfaces/IAcpHal/iacphal) y los [métodos de ACPHAL](/reference/audio/acphal/acphal_members) son seguros para subprocesos. Si se realiza la llamada [ApuCreateHeap](/reference/audio/apu/functions/apucreateheap), el montón lo usan todos los subprocesos.

Las siguientes funciones de utilidad *no* son seguras para subprocesos. Sin embargo, se proporciona su código fuente. Si es necesario, puedes hacerlas seguras para subprocesos. La forma habitual de hacerlo es usar [objetos de sección crítica](https://msdn.microsoft.com/library/windows/desktop/ms682530\(v=vs.85\).aspx).

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

<a id="ID4EUPAC" />

### Directrices para usar SRC con datos PCM y XMA

En la tabla siguiente se muestran las directrices para usar el bloque SRC con datos PCM y XMA.

| Objetivo                                  | Implementación                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| ----------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| PCM lineal sin bucle                      | Inicia la voz mediante `SHAPE_SRC_COMMAND_TYPE_START` para el SRC. Deja que la voz se reproduzca hasta el final. Opcionalmente, deténla antes del final mediante `SHAPE_SRC_COMMAND_TYPE_STOP_IMMEDIATE`.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| PCM lineal con bucle infinito             | Establece el número de bucles del contexto PCM (`loopCount`) en `SHAPE_PCM_INFINITE_LOOP_COUNT`. Inicia la voz mediante `SHAPE_SRC_COMMAND_TYPE_START` para el SRC. Cero. Deja que la voz se reproduzca hasta que quieras detenerla al final de un bucle emitiendo `SHAPE_SRC_COMMAND_TYPE_STOP_END`, y deja que la voz termine de sonar. Opcionalmente, deténla inmediatamente emitiendo `SHAPE_SRC_COMMAND_TYPE_STOP_IMMEDIATE`.                                                                                                                                                                                                                                                                                               |
| PCM lineal con bucle finito               | Establece el número de bucles del contexto PCM (`loopCount`) en \[0, 254]. Inicia la voz mediante `SHAPE_SRC_COMMAND_TYPE_START` para el SRC. Deja que la voz se reproduzca hasta el final. Opcionalmente, deténla al final de un bucle mediante `SHAPE_SRC_COMMAND_TYPE_STOP_END` y deja que la voz termine de sonar. Opcionalmente, deténla inmediatamente emitiendo `SHAPE_SRC_COMMAND_TYPE_STOP_IMMEDIATE`.                                                                                                                                                                                                                                                                                                                  |
| PCM circular                              | Inicia la voz mediante `SHAPE_SRC_COMMAND_TYPE_START` para el SRC. Sigue transmitiendo datos y actualizando el puntero de escritura del contexto PCM hasta que quieras detenerla. Emite `SHAPE_SRC_COMMAND_TYPE_STOP_END` para dejar que el SRC reproduzca hasta el puntero de escritura PCM actual (`loopStartWritePointer`). Opcionalmente, emite `SHAPE_SRC_COMMAND_TYPE_STOP_IMMEDIATE` para detenerla inmediatamente.                                                                                                                                                                                                                                                                                                       |
| XMA de streaming (sin bucle por hardware) | Inicia la voz mediante `SHAPE_SRC_COMMAND_TYPE_START` para el SRC. Cuando se consuma el último búfer de entrada XMA, emite `SHAPE_SRC_COMMAND_TYPE_STOP_END` para reproducir hasta el final del búfer descodificado (consulta la NOTA que sigue). Opcionalmente, emite `SHAPE_SRC_COMMAND_TYPE_STOP_IMMEDIATE` para detenerla inmediatamente.                                                                                                                                                                                                                                                                                                                                                                                    |
| XMA con bucle infinito por hardware       | Establece el número de bucles del contexto XMA (`numLoops`) en `SHAPE_XMA_INFINITE_LOOP_COUNT`. Inicia la voz mediante `SHAPE_SRC_COMMAND_TYPE_START` para el SRC. Deja que la voz se reproduzca hasta que quieras detenerla al final de un bucle estableciendo el número de bucles de XMA en cero, emitiendo `SHAPE_SRC_COMMAND_TYPE_STOP_END` y dejando después que la voz termine de sonar. Opcionalmente, deténla inmediatamente emitiendo `SHAPE_SRC_COMMAND_TYPE_STOP_IMMEDIATE`.                                                                                                                                                                                                                                          |
| XMA con bucle finito por hardware         | Establece el número de bucles del contexto XMA (`numLoops`) en \[0, 254]. Inicia la voz mediante `SHAPE_SRC_COMMAND_TYPE_START` para el SRC. Deja que la voz se reproduzca hasta que quieras detenerla al final de los bucles observando el número de bucles. Cuando sea cero, emite `SHAPE_SRC_COMMAND_TYPE_STOP_END` y deja que la voz termine de sonar. Opcionalmente, para detenerla al final del siguiente bucle, establece el número de bucles en cero. Cuando se consuma el último búfer de entrada XMA, establece el comando del SRC en `SHAPE_SRC_COMMAND_TYPE_STOP_END` y deja que la voz termine de sonar (consulta la NOTA que sigue). Para detenerla inmediatamente, emite `SHAPE_SRC_COMMAND_TYPE_STOP_IMMEDIATE`. |

<Note>Cuando se completa cualquiera de estos escenarios, el comando del SRC es `SHAPE_SRC_COMMAND_TYPE_STOP_IMMEDIATE`.</Note>

Comprueba los bits válidos del búfer de entrada XMA con la misma frecuencia con la que procesas los grafos de flujo de SHAPE. Si realizas esta comprobación como parte de tu lógica de streaming, que se ejecuta a intervalos mucho más largos, es posible que el búfer de salida XMA se vacíe antes de que indiques al SRC que se detenga al final. Esto puede provocar que el grafo de flujo se bloquee.

<a id="ID4E5BAE" />

### Pausa y reanudación de un título

Un título debe poder pausarse y reanudarse, por ejemplo, cuando el usuario lo pone en modo restringido. Para pausar y reanudar cuando se programa directamente contra el hardware de SHAPE mediante `IAcpHal`, basta con que el título deje de enviar comandos. Los comandos que ya se enviaron se completarán con normalidad y podrían llenar la cola de mensajes.

Si un título usa grafos de flujo persistentes, debería cargar un grafo de flujo nulo para detener el procesamiento. Esto difiere del proceso de pausa y reanudación cuando se programa con `XAudio2`. Para obtener más información, consulta la [información general sobre XAudio2](/build/console-features/audio/overviews/xaudio2-overview).

## Documentación de referencia de la API

* [Acphal (contenido de la API)](/reference/audio/acphal/acphal_members)
  * Estructuras
    * [ACP\_COMMAND\_UPDATE\_DMA\_CONTEXT](/reference/audio/acphal/structs/acp_command_update_dma_context)
    * [ACP\_COMMAND\_UPDATE\_EQCOMP\_CONTEXT](/reference/audio/acphal/structs/acp_command_update_eqcomp_context)
    * [ACP\_COMMAND\_UPDATE\_FILTVOL\_CONTEXT](/reference/audio/acphal/structs/acp_command_update_filtvol_context)
    * [ACP\_COMMAND\_UPDATE\_PCM\_CONTEXT](/reference/audio/acphal/structs/acp_command_update_pcm_context)
    * [ACP\_COMMAND\_UPDATE\_SRC\_CONTEXT](/reference/audio/acphal/structs/acp_command_update_src_context)
    * [ACP\_COMMAND\_UPDATE\_XMA\_CONTEXT](/reference/audio/acphal/structs/acp_command_update_xma_context)
    * [ACP\_COMMAND\_LOAD\_SHAPE\_FLOWGRAPH](/reference/audio/acphal/structs/acp_command_load_shape_flowgraph)
* [Shapedmacontext (contenido de la API)](/reference/audio/shapedmacontext/shapedmacontext_members)
  * Estructuras
    * [SHAPE\_DMA\_CONTEXT](/reference/audio/shapedmacontext/structs/shape_dma_context)
* [Shapeeqcompcontext (contenido de la API)](/reference/audio/shapeeqcompcontext/shapeeqcompcontext_members)
  * Estructuras
    * [SHAPE\_EQCOMP\_CONTEXT](/reference/audio/shapeeqcompcontext/structs/shape_eqcomp_context)
* [Shapefiltvolcontext (contenido de la API)](/reference/audio/shapefiltvolcontext/shapefiltvolcontext_members)
  * Estructuras
    * [SHAPE\_FILTVOL\_CONTEXT](/reference/audio/shapefiltvolcontext/structs/shape_filtvol_context)
* [Shapeflowgraph (contenido de la API)](/reference/audio/shapeflowgraph/shapeflowgraph_members)
* [Shapepcmcontext (contenido de la API)](/reference/audio/shapepcmcontext/shapepcmcontext_members)
  * Estructuras
    * [SHAPE\_PCM\_CONTEXT](/reference/audio/shapepcmcontext/structs/shape_pcm_context)
* [Shapesrccontext (contenido de la API)](/reference/audio/shapesrccontext/shapesrccontext_members)
  * Estructuras
    * [SHAPE\_SRC\_CONTEXT](/reference/audio/shapesrccontext/structs/shape_src_context)
* [Shapexmacontext (contenido de la API)](/reference/audio/shapexmacontext/shapexmacontext_members)
  * Estructuras
    * [SHAPE\_XMA\_CONTEXT](/reference/audio/shapexmacontext/structs/shape_xma_context)
* [apu (contenido de la API)](/reference/audio/apu/apu_members)
  * Funciones
    * [ApuCreateHeap](/reference/audio/apu/functions/apucreateheap)


## Related topics

- [Información general sobre SHAPE](/es/build/console-features/audio/overviews/shape-overview.md)
- [ACP_COMMAND_UPDATE_EQCOMP_CONTEXT](/es/reference/audio/acphal/structs/acp_command_update_eqcomp_context.md)
- [ACP_COMMAND_UPDATE_FILTVOL_CONTEXT](/es/reference/audio/acphal/structs/acp_command_update_filtvol_context.md)
- [ACP_COMMAND_UPDATE_PCM_CONTEXT](/es/reference/audio/acphal/structs/acp_command_update_pcm_context.md)
- [ACP_COMMAND_UPDATE_SRC_CONTEXT](/es/reference/audio/acphal/structs/acp_command_update_src_context.md)
