Android: API de sonido (determinista, baja latencia)


Estoy revisando todo tipo de Android sound API y me gustaría saber cuál debo usar. Mi objetivo es obtener audio de baja latencia o, al menos, un comportamiento determinista con respecto al retraso de la reproducción.

Hemos tenido un montón de problemas y parece que Android sound API es una mierda, así que estoy explorando posibilidades.

El problema que tenemos es que hay un retraso significativo entre sound_out.write(sound_samples); y el sonido real reproducido desde los altavoces. Por lo general, es de alrededor de 300 ms. El problema es que en todos dispositivos es diferente; algunos no tienen ese problema, pero la mayoría están paralizados (sin embargo, CS call tiene cero latencia). El mayor problema con este retardo ridículo es que en algunos dispositivos este retardo parece ser algún valor aleatorio (es decir, no siempre es 300ms).

Estoy leyendo sobre OpenSL ES y me gustaría saber si alguien tuvo experiencia con él, o es la misma mierda pero envuelto en un paquete diferente?

Prefiero tener acceso nativo, pero no me importa la indirección de la capa de Java mientras como puedo obtener un comportamiento determinista: o el retardo tiene que ser constante (para un dispositivo dado), o me gustaría obtener acceso a la posición de reproducción actual en lugar de adivinarlo con un rango de error de ±300 ms...

EDITAR:
1.5 años más tarde probé varios teléfonos Android para ver cómo puedo obtener la mejor latencia posible para una comunicación de voz en tiempo real. Usando herramientas especializadas medí el retraso de la ruta de waveout. Los mejores resultados fueron de más de 100 ms, la mayoría de los teléfonos estaban en el rango de 180 ms. Alguien tiene ideas?

Author: Pavel, 2011-09-01

4 answers

SoundPool es la interfaz de menor latencia en la mayoría de los dispositivos, porque el grupo se almacena en el proceso de audio. Todas las otras rutas de audio requieren comunicación entre procesos. OpenSL es la mejor opción si SoundPool no satisface tus necesidades.

¿Por qué OpenSL? AudioTrack y OpenSL tienen latencias similares, con una diferencia importante: los callbacks de búfer AudioTrack se mantienen en Dalvik, mientras que los callbacks de OpenSL se mantienen en hilos nativos. La implementación actual de Dalvik no es capaz de dar servicio a las devoluciones de llamada a latencias extremadamente bajas, porque no hay forma de suspender la recolección de basura durante las devoluciones de llamada de audio. Esto significa que el tamaño mínimo de los búferes AudioTrack tiene que ser mayor que el tamaño mínimo de los búferes OpenSL para mantener la reproducción sin fallos.

En la mayoría de los lanzamientos de Android esta diferencia entre AudioTrack y OpenSL no hizo ninguna diferencia en absoluto. Pero con Jellybean, Android ahora tiene una ruta de audio de baja latencia. La latencia real sigue siendo el dispositivo dependiente, pero puede ser considerablemente menor que antes. Por ejemplo, http://code.google.com/p/music-synthesizer-for-android / utiliza búferes de 384 fotogramas en el Galaxy Nexus para una latencia de salida total de menos de 30 ms. Esto requiere el hilo de audio para mantener búferes aproximadamente una vez cada 8 ms, lo que no era factible en versiones anteriores de Android. Todavía no es factible en un hilo Dalvik.

Esta explicación asume dos cosas: primero, que usted está solicitando el más pequeño posibles buffers de OpenSL y haciendo su procesamiento en el buffer callback en lugar de con una cola de buffer. En segundo lugar, que el dispositivo sea compatible con la ruta de baja latencia. En la mayoría de los dispositivos actuales no verá mucha diferencia entre AudioTrack y OpenSL ES. Pero en los dispositivos que admiten Jellybean+ y audio de baja latencia, OpenSL ES le dará la ruta de menor latencia.

 26
Author: Ian Ni-Lewis,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-04-25 18:38:08

IIRC, OpenSL se pasa a través de la misma interfaz que AudioTrack, por lo que en el mejor de los casos coincidirá con AudioTrack. (FWIW, actualmente estoy usando OpenSL para la salida de "baja latencia")

La triste verdad es que no existe el audio de baja latencia en Android. Ni siquiera hay una forma adecuada de marcar y/o filtrar dispositivos basados en la latencia de audio.

La interfaz que querrá usar para minimizar la latencia dependerá de lo que esté tratando de hacer. Si quieres tener un flujo de audio serás mirando OpenSL o AudioTrack.

Si desea activar algunos oneshots estáticos, puede usar SoundPool. Para oneshots estáticos SoundPool tendrá baja latencia ya que las muestras están precargadas en el hardware. Creo que es posible precargar oneshots usando OpenSL también, pero no lo he intentado.

 2
Author: Drakonite,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-06-11 08:31:15

La latencia más baja que puede obtener es de SoundPool. Hay un límite en el tamaño de un sonido que se puede reproducir de esa manera, pero si estás por debajo del límite (1Mb, IIRC) es bastante baja latencia. Aunque probablemente no sean 40ms.

Pero es más rápido de lo que se puede obtener por streaming, al menos en mi experiencia.

Advertencia: Es posible que vea bloqueos ocasionales en SoundPool en dispositivos Samsung. Tengo una teoría de que solo sucede cuando accedes al SoundPool desde múltiples hilos, pero no he verificado esto.

EDIT: OpenSL ES aparentemente tiene una latencia extremadamente ALTA en Kindle Fire, mientras que SoundPool es mucho mejor, pero lo contrario puede ser cierto en otras plataformas.

 1
Author: SomeCallMeTim,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-07-12 21:12:28

Sobre el problema de una latencia determinista/constante, aquí puede encontrar un artículo interesante:

ENFOQUES PARA LA LATENCIA DE AUDIO CONSTANTE EN ANDROID

El núcleo de sus investigaciones es: Debido a que el HAL de Audio, que es uno de los niveles más profundos de la audiópata y responsable de la sincronización de los eventos de devolución de llamada de audio, está implementado por el proveedor, las latencias relativas pueden variar, especialmente en hardware barato. Así que sugieren dos enfoques para reducir la varianza de la latencia. Uno es cuidar el tiempo de devolución de llamada insertando audio en intervalos fijos, el otro es filtrar los tiempos de devolución de llamada para estimar el tiempo en el que una devolución de llamada de latencia constante debería haber ocurrido mediante la aplicación de un filtro de suavizado. Con estos dos enfoques el podría reducir significativamente la varianza de la latencia.

También debe mencionarse, que hay una nueva Android-Audio-API nativa, AAudio.

AAudio API

Está disponible / estable desde Android Oreo 8.1 (Nivel de API 27). También hay un wrapper, que elige dinámicamente entre OpenSL ES y AAudio y es mucho más fácil codificar el OpenSL ES. Todavía está en vista previa del desarrollador.

Oboe Audio Library

 0
Author: Niklas D,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-07-17 07:02:41