Pregunta

Estoy usando la API Javax Sound para implementar un programa de reproducción de consola simple basado en http://www.jsresources.org/examples/audioplayer.html.

Después de haberlo probado usando un archivo de rampa de 24 bits (cada muestra es la última muestra más 1 en el rango completo de 24 bits), es evidente que algo impar está sucediendo durante la reproducción. La salida grabada no es el contenido del archivo (tengo un bucle de bucle digital para verificar esto).

Parece estar malinterpretando las muestras de alguna manera que hace que el canal izquierdo parezca que se le aplica una ganancia y parece que el canal correcto está siendo atenuado.

He examinado si los controles de sartén y equilibrio necesitan configuración, pero estos no están disponibles y he revisado la configuración del sistema de sonido Windows XP. Cualquier otra forma de reproducción de este archivo de rampa está bien.

Si hago la misma prueba con un archivo de 16 bits, realiza correctamente sin corrupción de la transmisión.

Entonces, ¿alguien tiene alguna idea de por qué la API Java Sound está modificando mi transmisión de audio?

¿Fue útil?

Solución

El problema con la reproducción de Java de audio de 24 bits es en realidad con Microsoft DirectSound y/o la implementación de Windows Java Sound. Usando Linux con Java Sound y ALSA, el audio de 24 bits se reproduce perfectamente (la grabación de la salida muestra una coincidencia perfecta con el archivo de entrada).

Para ver por qué no funciona en Windows, puede consultar los formatos de audio compatibles de la línea de salida que desea reproducir en Java usando (donde lineInfo es el Line.Info de la línea de salida):

DataLine.Info dataLineInfo = (DataLine.Info) lineInfo;

y luego recorriendo los formatos compatibles:

for (AudioFormat lineFormat : dataLineInfo.getFormats())

Para Windows obtengo algo como:

Format #1: PCM_UNSIGNED unknown sample rate, 8 bit, mono, 1 bytes/frame,
Format #2: PCM_SIGNED unknown sample rate, 8 bit, mono, 1 bytes/frame,
Format #3: PCM_SIGNED unknown sample rate, 16 bit, mono, 2 bytes/frame, little-endian
Format #4: PCM_SIGNED unknown sample rate, 16 bit, mono, 2 bytes/frame, big-endian
Format #5: PCM_UNSIGNED unknown sample rate, 8 bit, stereo, 2 bytes/frame,
Format #6: PCM_SIGNED unknown sample rate, 8 bit, stereo, 2 bytes/frame,
Format #7: PCM_SIGNED unknown sample rate, 16 bit, stereo, 4 bytes/frame, little-endian
Format #8: PCM_SIGNED unknown sample rate, 16 bit, stereo, 4 bytes/frame, big-endian

Que no tiene 24 bits como formato compatible. Pero en Windows XP todavía me permitió reproducir audio de 24 bits, pero presumiblemente procesado a 16 bits por Java / DirectSound y luego regresar a 24 bit por la tarjeta de sonido. Por lo tanto, por qué la salida de datos es incorrecta. En Windows 7, encontré que se negaba a reproducir audio de 24 bits (probablemente más sensato si todo lo que va a hacer es de 16 bits de todos modos).

Para Linux (Fedora 17) obtengo algo como (con exactamente la misma tarjeta de sonido, una esi juli@, en la misma PC):

Format #1: PCM_SIGNED unknown sample rate, 32 bit, mono, 4 bytes/frame, little-endian
Format #2: PCM_SIGNED unknown sample rate, 32 bit, mono, 4 bytes/frame, big-endian
Format #3: PCM_SIGNED unknown sample rate, 32 bit, stereo, 8 bytes/frame, little-endian
Format #4: PCM_SIGNED unknown sample rate, 32 bit, stereo, 8 bytes/frame, big-endian
Format #5: PCM_SIGNED unknown sample rate, 24 bit, mono, 4 bytes/frame, little-endian
Format #6: PCM_SIGNED unknown sample rate, 24 bit, mono, 4 bytes/frame, big-endian
Format #7: PCM_SIGNED unknown sample rate, 24 bit, stereo, 8 bytes/frame, little-endian
Format #8: PCM_SIGNED unknown sample rate, 24 bit, stereo, 8 bytes/frame, big-endian
Format #9: PCM_SIGNED unknown sample rate, 24 bit, mono, 3 bytes/frame, little-endian
Format #10: PCM_SIGNED unknown sample rate, 24 bit, mono, 3 bytes/frame, big-endian
Format #11: PCM_SIGNED unknown sample rate, 24 bit, stereo, 6 bytes/frame, little-endian
Format #12: PCM_SIGNED unknown sample rate, 24 bit, stereo, 6 bytes/frame, big-endian
Format #13: PCM_SIGNED unknown sample rate, 20 bit, mono, 3 bytes/frame, little-endian
Format #14: PCM_SIGNED unknown sample rate, 20 bit, mono, 3 bytes/frame, big-endian
Format #15: PCM_SIGNED unknown sample rate, 20 bit, stereo, 6 bytes/frame, little-endian
Format #16: PCM_SIGNED unknown sample rate, 20 bit, stereo, 6 bytes/frame, big-endian
Format #17: PCM_SIGNED unknown sample rate, 16 bit, mono, 2 bytes/frame, little-endian
Format #18: PCM_SIGNED unknown sample rate, 16 bit, mono, 2 bytes/frame, big-endian
Format #19: PCM_SIGNED unknown sample rate, 16 bit, stereo, 4 bytes/frame, little-endian
Format #20: PCM_SIGNED unknown sample rate, 16 bit, stereo, 4 bytes/frame, big-endian
Format #21: PCM_SIGNED unknown sample rate, 8 bit, mono, 1 bytes/frame,
Format #22: PCM_UNSIGNED unknown sample rate, 8 bit, mono, 1 bytes/frame,
Format #23: PCM_SIGNED unknown sample rate, 8 bit, stereo, 2 bytes/frame,
Format #24: PCM_UNSIGNED unknown sample rate, 8 bit, stereo, 2 bytes/frame, 

Que tiene 24 bits como formato compatible. Y como tal esto funciona como se esperaba y sin el procesamiento adicional no deseado.

Por lo tanto, parece que la reproducción de 24 bits funciona con Java Sound, siempre que la implementación de TI lo enumere como la implementación específica (y tal vez específica del dispositivo, pero no he encontrado ninguna variación entre los dispositivos que he probado) Un formato de audio compatible. Mis pruebas sugieren que Linux (ALSA) lo admite, mientras que Windows (DirectSound) no.

Espero que esto sea útil para alguien; No pude encontrar nada más sobre esto en línea, por eso he publicado en una pregunta tan antigua.

La siguiente fue mi pregunta inicial, que acabo de responder (la he dejado como referencia):


No estoy seguro de si este es el procedimiento correcto para aumentar las preguntas antiguas, pero al leer las preguntas frecuentes parece que esto se prefiere publicar una nueva. Ya he publicado este problema en un par de otros lugares (incluido el Foro de sonido de Oracle Java) pero sin respuestas hasta ahora y esta pregunta suena exactamente igual que el problema que tengo:

Estoy usando Java Sound para reproducir archivos de audio (en formato PCM estándar), pero he notado que no reproduce correctamente los datos de 24 bits, ya que la salida de datos de la tarjeta de sonido no coincide con la entrada del archivo. Funciona bien para datos de audio de 16 bits (e incluso 8 bits), pero no para 24 bits (y presumiblemente 32 bits, pero no tengo archivos de audio reales de 32 bits para probar) archivos. Desde la salida parece que Java Sound está haciendo un procesamiento adicional (y no deseado) a los datos de audio antes de pasarlo a la tarjeta de sonido. Puedo decir con certeza que es Java Sound haciendo esto porque si ejecuto la misma prueba usando ASIO para reproducir el archivo, entonces no hay problema y los datos coinciden como se esperaba.

Un poco más de información sobre la configuración: - Java JRE Última versión (7U7 Creo), que se ejecuta en Windows XP SP3. - El sonido se reproduce usando el ejemplo de AudioPlayer (como se menciona en la pregunta principal) en jsresources.org (primero intenté usar mi propio código, pero cambié a esto en caso de que hubiera cometido un error, los resultados son los mismos en ambos). - El audio se reproduce está en una tarjeta de sonido M-Audio a través de la salida digital (S/PDIF), que está directamente conectada (a través de un cable externo) a una tarjeta de sonido Lynx (en la misma PC), donde está grabado (usando Sony Sound Forge). - El archivo grabado se compara con el archivo de onda de entrada.

Para la prueba, se utilizan cuatro archivos de onda de entrada diferentes (se generan a partir del mismo archivo de origen): - 16 bits, 44.1 kHz; - 16 bit, 48 kHz; - 24 bits, 44.1 kHz; - 24 bit, 48 kHz.

Usando ASIO para reproducir los archivos de prueba, los cuatro archivos produjeron la salida correcta (los datos grabados coinciden con el byte de datos de archivo de onda de entrada para byte, después de alinear las posiciones iniciales para el tiempo entre el registro presionado y la reproducción presionada).

Usando Java para reproducir los archivos de prueba, los de 16 bits (tanto 44.1 kHz como 48 kHz) producen la salida correcta, mientras que los de 24 bits (los 44.1 kHz y 48 kHz) no lo hacen. No solo eso, sino que la forma en que la salida es incorrecta es inconsistente (si ejecuto la prueba dos veces, produce una salida diferente cada vez, ninguno de los cuales se acerca a coincidir con el archivo de entrada). Entonces, Java Sound no solo está reproduciendo los archivos de 24 bits incorrectamente, sino que lo está haciendo erróneamente de una manera diferente cada vez. Si ayuda, puedo tomar capturas de pantalla de la salida de sonido Java en comparación con el archivo de entrada (salida esperada).

La forma más fácil de reproducir esto sería usar el ejemplo de AudioPlayer mencionado anteriormente, reproducir un archivo de 24 bits y grabar la salida (si solo tiene una tarjeta de sonido, es posible usar su mezclador para enrutar los datos adecuadamente para permitir que sea capturado). Si bien no está lo suficientemente incorrecto como para que pueda escuchar ninguna diferencia, derrota el propósito del audio de alta resolución si los datos se alteran de una manera inesperada (corre el riesgo de perder cualquier ganancia de usar 24 bits durante 16 bits, aunque yo Realmente no quiero entrar en ese argumento aquí).

Entonces, para expresar esto como una pregunta: ¿cómo puedo hacer que Java Sound repita el audio de 24 bits correctamente?

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