Pregunta

¿Es Java una alternativa adecuada a C / C ++ para el procesamiento de audio en tiempo real?

Estoy considerando una aplicación con ~ 100 (como máximo) pistas de audio con líneas de retardo (30s @ 48khz), filtrado (512 puntos ¿FIR?), y otras operaciones de tipo DSP que ocurren en cada pista simultáneamente.

Las operaciones se convertirían y realizarían en punto flotante.

El sistema probablemente sería un 3GHz de cuatro núcleos con 4GB de RAM, ejecutando Ubuntu.

He visto artículos sobre Java que son mucho más rápidos de lo que solía ser, que se acercan a C / C ++ y que ahora también tienen extensiones en tiempo real. ¿Es esta realidad? ¿Requiere codificación de núcleo duro y ajuste para lograr el rendimiento de% 50-% 100 de C que algunos están especificando?

Realmente estoy buscando un sentido si esto es posible y un aviso para cualquier error.

¿Fue útil?

Solución

Para una aplicación de audio, a menudo solo tiene partes muy pequeñas de código donde se pasa la mayor parte del tiempo.

En Java, siempre puedes usar el JNI (interfaz Java Native) y mover tu código pesado de cómputo a un módulo C (o ensamblaje usando SSE si realmente necesitas la energía). Así que yo diría que use Java y haga que su código funcione. Si resulta que no cumple con su objetivo de rendimiento, utilice JNI.

El 90% del código probablemente será código de pegamento y cosas de la aplicación de todos modos. Pero ten en cuenta que pierdes algunas de las funciones de plataforma cruzada de esa manera. Si puedes vivir con eso, JNI siempre te dejará la puerta abierta para el rendimiento del código nativo.

Otros consejos

Java está bien para muchas aplicaciones de audio. Contrariamente a algunos de los otros carteles, me parece un placer trabajar con el audio de Java. Compare la API y los recursos disponibles para usted con la mente horrible, apenas documentada que es CoreAudio y usted será un creyente. El audio de Java sufre de algunos problemas de latencia, aunque para muchas aplicaciones esto es irrelevante y la falta de códecs. También hay muchas personas que nunca se han molestado en tomarse el tiempo para escribir buenos motores de reproducción de audio (sugerencia, nunca cerrar una SourceDataLine, en lugar de escribirle ceros) y, posteriormente, culpar a Java por sus problemas. Desde el punto de vista de la API, el audio de Java es muy sencillo, muy fácil de usar, y hay mucha orientación sobre jsresources .org .

Claro, ¿por qué no?

Las preguntas cruciales (independientemente del lenguaje, esto es de la teoría de colas) son:

  • ¿cuál es el rendimiento máximo que necesita manejar (ha especificado 100 x 48kHz, es mono o estéreo, cuántos bits equivalen a esa frecuencia?)
  • ¿Sus rutinas Java pueden mantenerse al día con esta tasa en promedio?
  • ¿Cuál es la latencia máxima permitida?

Si su programa puede mantenerse al día con el rendimiento promedio, y tiene suficiente espacio para la latencia, entonces debería poder usar colas para entradas y salidas, y las únicas partes del programa que son críticas para la temporización son las piezas que ponen los datos en la cola de entrada y los sacan de la cola de salida y los envían a un DAC / altavoz / lo que sea.

Las líneas de retardo tienen una carga computacional baja, solo necesita suficiente memoria (+ ancho de banda de memoria) ... de hecho, probablemente debería usar las colas de entrada / salida para eso, es decir, comenzar a poner los datos en la cola de entrada inmediatamente, y comenzar sacar los datos de la cola de salida 30 s más tarde. Si no está allí, su programa es demasiado lento ...).

Los FIR son más caros, probablemente será el cuello de botella (y lo que querría optimizar) a menos que tenga en mente alguna otra operación desagradable.

Creo que la latencia será su principal problema: es bastante difícil mantener la latencia en C / C ++ en los sistemas operativos modernos, y Java seguramente se suma al problema (recolector de basura). El diseño general para " tiempo real " el procesamiento de audio es hacer que sus subprocesos de procesamiento se ejecuten en la programación en tiempo real (SCHED_FIFO en los kernels de Linux, equivalente en otros sistemas operativos), y esos subprocesos nunca deben bloquearse. Esto significa que no hay llamadas al sistema, ni malloc, IO, por supuesto, etc ... Incluso la paginación es un problema (obtener una página del disco a la memoria puede demorar varios ms), por lo que debe bloquear algunas páginas para asegurarse de que nunca se intercambiado.

Es posible que puedas hacer esas cosas en Java, pero Java lo hace más complicado, no más fácil. Me gustaría ver un diseño mixto, donde el núcleo estaría en C, y el resto (GUI, etc.) estaría en Java si lo desea.

Una cosa que no vi en su pregunta es si necesita reproducir estas muestras procesadas o si está haciendo otra cosa con ellas (codificarlas en un archivo, por ejemplo). Estaría más preocupado por el estado del motor de sonido de Java que por la rapidez con que la JVM puede procesar muestras.

Presioné bastante fuerte en javax.sound.sampled hace unos años y salí profundamente impresionado: no se compara con marcos equivalentes como OpenAL o Core / Mac / iPhone (ambos de los cuales he usado a una nivel de intensidad similar). javax.sound.sampled requiere que inserte sus muestras en un búfer opaco de duración desconocida, lo que hace que la sincronización sea casi imposible. También está mal documentado (es muy difícil encontrar ejemplos de transmisión de audio de longitud indeterminada a través de una línea en lugar de los ejemplos triviales de clips en memoria), tiene métodos no implementados (DataLine.getLevel () ... cuya no implementación no es Incluso documentado), y para colmo, creo que Sun despidió al último ingeniero de JavaSound hace años.

Si tuviera utilizar un motor Java para la mezcla y salida de sonido, probablemente intentaría usar los enlaces JOAL para OpenAL como primera opción, ya que al menos sabría el motor Actualmente es compatible y capaz de muy baja latencia. Aunque a la larga sospecho que Nils es correcto y que terminarás usando JNI para llamar a la API de sonido nativo.

Sí, Java es ideal para aplicaciones de audio. Puede usar Java y acceder a las capas de audio a través de Asio y tener una latencia muy baja (64 latencias de muestra, que es casi nada) en la plataforma Windows. Significa que tendrás sincronización de labios en video / película. Más latencia en Mac, ya que no hay Asio para " acceso directo " la combinación de OS X y "Java en la parte superior", pero aún así está bien. Linux también, pero soy más ignorante. Vea en soundpimp.com un ejemplo práctico (y el primero en el mundo) de Java y Asio trabajando en perfecta armonía. También vea la aplicación de Android NRK Radio & amp; tv que contiene un decodificador sw mp3 (de Java). Puede hacer la mayoría de las cosas de audio con Java, y luego usar una capa nativa si tiene tiempo adicional.

Echa un vistazo a una biblioteca llamada Jsyn.

http://www.softsynth.com/jsyn/

¿Por qué no pasar un día y escribir una aplicación java simple que realiza un procesamiento mínimo y valida si el rendimiento es adecuado?

De http://www.jsresources.org/faq_performance.html#java_slow

  

Recolectemos algo de sabiduría eterna:

     
      
  • La tierra es plana.

  •   
  • y, para no olvidar: Java es lento.

  •   
     

Como lo demuestran varias aplicaciones (ver la sección de enlaces), Java es suficiente   para construir editores de audio, sistemas de grabación multipista y MIDI   software de procesamiento. Pruébalo!

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top