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

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. Para obtener más información sobre la arquitectura de SHAPE, consulta la información general sobre SHAPE. 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

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

Figura 1. Dos voces, cada una panoramizada entre dos salidas, con un envío a una salida común. En código, este grafo de flujo puede representarse de la siguiente manera.

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. En código, este grafo de flujo puede representarse de la siguiente manera.

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 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. Al actualizar los contextos, ten en cuenta que un parámetro de marca de 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. 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 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.

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

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

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.

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. Para obtener más información, consulta ShapeDmaContext (métodos de utilidad de DMA).

Utilidades del compresor de EQ

Incluye las utilidades de EQCOMP en el archivo ShapeEqCompContext.h. Estas utilidades operan sobre una estructura SHAPE_EQCOMP_CONTEXT. Para obtener más información, consulta ShapeEqCompContext (métodos de utilidad de EQCOMP).

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. Para obtener más información, consulta ShapeFiltVolContext (métodos de utilidad de FLTVOL).

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. Para obtener más información, consulta ShapePcmContext (métodos de utilidad de PCM).

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. Para obtener más información, consulta ShapeSrcContext (métodos de utilidad de SRC).

Utilidades de XMA

Incluye las utilidades de XMA en el archivo ShapeXMAContext.h. Estas utilidades operan sobre una estructura SHAPE_XMA_CONTEXT. Para obtener más información, consulta ShapeXmaContext (métodos de utilidad de XMA). 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. 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, como se muestra en la tabla siguiente. 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.

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 contiene valores para gain y gainTarget. Mientras se procesa el fotograma, gain se calcula mediante interpolación lineal y la siguiente ecuación.
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.

Seguridad para subprocesos

Los métodos de la interfaz IACPHAL y los métodos de ACPHAL son seguros para subprocesos. Si se realiza la llamada 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.

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.
Cuando se completa cualquiera de estos escenarios, el comando del SRC es SHAPE_SRC_COMMAND_TYPE_STOP_IMMEDIATE.
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.

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.

Documentación de referencia de la API

Última modificación el 28 de agosto de 2026