Diseña para reducir la latencia

La versión de Android 4.1 introdujo cambios en el framework interno para lograr una ruta de salida de audio con menor latencia. Se realizaron cambios mínimos en la API de cliente público o en la API de HAL. En este documento, se describe el diseño inicial, que ha seguido evolucionando con el tiempo. Comprender bien este diseño debería ayudar a los OEM de dispositivos y a los proveedores de SoC a implementar el diseño correctamente en sus dispositivos y conjuntos de chips específicos. Este artículo no está destinado a desarrolladores de aplicaciones.

Creación de segmentos

De manera opcional, el cliente puede establecer el bit AUDIO_OUTPUT_FLAG_FAST en el parámetro audio_output_flags_t del constructor de AudioTrack en C++ o en AudioTrack::set(). Actualmente, los únicos clientes que lo hacen son los siguientes:

La implementación de AudioTrack en C++ revisa la solicitud AUDIO_OUTPUT_FLAG_FAST y, de manera opcional, puede rechazarla a nivel del cliente. Si decide pasar la solicitud, lo hace con el bit TRACK_FAST del parámetro track_flags_t del método de fábrica IAudioTrack IAudioFlinger::createTrack().

El servidor de audio AudioFlinger revisa la solicitud TRACK_FAST y, de manera opcional, puede rechazarla a nivel del servidor. Le informa al cliente si se aceptó o no la solicitud a través del bit CBLK_FAST del bloque de control de memoria compartida.

Entre los factores que influyen en la decisión, se incluyen los siguientes:

  • Presencia de un subproceso de mezclador rápido para este resultado (consulta a continuación)
  • Tasa de muestreo de la pista
  • Presencia de un subproceso de cliente para ejecutar controladores de devolución de llamada para esta pista
  • Tamaño del búfer de la pista
  • Los horarios disponibles para el carril rápido (consulta a continuación)

Si se aceptó la solicitud del cliente, se denomina “vía rápida”. De lo contrario, se denomina "pista normal".

Subprocesos de Mixer

En el momento en que AudioFlinger crea un subproceso de mezclador normal, decide si también creará un subproceso de mezclador rápido. Tanto el mezclador normal como el rápido no están asociados con una pista en particular, sino con un conjunto de pistas. Siempre hay un subproceso de mezclador normal. El subproceso de mezclador rápido, si existe, está subordinado al subproceso de mezclador normal y actúa bajo su control.

Batidora rápida

Funciones

El subproceso del mezclador rápido proporciona las siguientes funciones:

  • Mezcla de la submezcla del mezclador normal y hasta 7 pistas rápidas del cliente
  • Atenuación por pista

Funciones omitidas:

  • Conversión de la tasa de muestreo por pista
  • Efectos por pista
  • Efectos por mezcla

Período

El mezclador rápido se ejecuta de forma periódica, con un período recomendado de dos a tres milisegundos (ms) o un período ligeramente superior de cinco ms si es necesario para programar la estabilidad. Se eligió este número para que, teniendo en cuenta la canalización de búfer completa, la latencia total sea del orden de 10 ms. Es posible usar valores más pequeños, pero es posible que aumente el consumo de energía y la posibilidad de fallas, según la previsibilidad de programación de la CPU. Se pueden usar valores más grandes, de hasta 20 ms, pero se degrada la latencia total, por lo que se deben evitar.

Programación

El mezclador rápido se ejecuta con prioridad SCHED_FIFO elevada. Necesita muy poco tiempo de CPU, pero debe ejecutarse con frecuencia y con un jitter de programación bajo. El jitter expresa la variación en el tiempo de ciclo: es la diferencia entre el tiempo de ciclo real y el esperado. Si se ejecuta demasiado tarde, se producirán fallas debido al subdesbordamiento. Si se ejecuta demasiado pronto, se producirán fallas debido a que se extrae de un segmento rápido antes de que este proporcione datos.

Bloqueo

Idealmente, el subproceso del mezclador rápido nunca se bloquea, excepto en HAL write(). Otros casos de bloqueo dentro del mezclador rápido se consideran errores. En particular, se evitan los mutex. En su lugar, se usan algoritmos sin bloqueo (también conocidos como algoritmos sin bloqueo). Consulta Cómo evitar la inversión de prioridad para obtener más información sobre este tema.

Relación con otros componentes

El mezclador rápido tiene poca interacción directa con los clientes. En particular, no ve las operaciones a nivel del Binder, pero sí accede al bloque de control de memoria compartida del cliente.

El mezclador rápido recibe comandos del mezclador normal a través de una cola de estado.

Además de extraer datos de pistas, la interacción con los clientes se realiza a través del mezclador normal.

El receptor principal del mezclador rápido es el HAL de audio.

Batidora normal

Funciones

Todas las funciones están habilitadas:

  • Hasta 32 pistas
  • Atenuación por pista
  • Conversión de la tasa de muestreo por pista
  • Procesamiento de efectos

Período

El período se calcula para ser el primer múltiplo integral del período del mezclador rápido que sea superior o igual a 20 ms.

Programación

El mezclador normal se ejecuta con prioridad SCHED_OTHER elevada.

Bloqueo

El mezclador normal puede bloquearse y, a menudo, lo hace en varios mutexes, así como en un canal de bloqueo para escribir su submezcla.

Relación con otros componentes

El mezclador normal interactúa de forma extensa con el entorno externo, incluidos los subprocesos de Binder, el administrador de políticas de audio, el subproceso de mezclador rápido y las pistas de cliente.

El sumidero del mezclador normal es un tubo de bloqueo para la pista 0 del mezclador rápido.

Marcas

El bit AUDIO_OUTPUT_FLAG_FAST es una sugerencia. No hay garantía de que se complete la solicitud.

AUDIO_OUTPUT_FLAG_FAST es un concepto a nivel del cliente. No aparece en el servidor.

TRACK_FAST es un concepto de cliente a servidor.