2012-06-12 41 views
9

He estado teniendo problemas durante los últimos días tratando de hacer que esto funcione. Pero lo que quiero es que tengamos una aplicación que envíe datos en bruto a través de la red. Luego leo estos datos binarios y quiero guardarlos en un archivo wav (cualquier audio). Podría ver la compresión más tarde.Guardando el byte de audio [] en un archivo wav

Así que el código problemático:

byte[] allBytes = ... 
InputStream b_in = new ByteArrayInputStream(allBytes); 

try 
{ 
    AudioFormat format = new AudioFormat(8000f, 16, 1, true, true); 
    AudioInputStream stream = new AudioInputStream(b_in, format, allBytes.length); 
    //AudioInputStream stream = AudioSystem.getAudioInputStream(b_in);     

han tratado de utilizar la declaración anterior también, pero me da la excepción: javax.sound.sampled.UnsupportedAudioFileException: could not get audio input stream from stream. Entonces, lo que creo que está sucediendo es que debido a que mi flujo de datos de audio en bruto y no tiene un encabezado de onda, ¿está lanzando una excepción?

File newPath = new File(SystemConfiguration.getLatest().voiceNetworkPathDirectory + currentPhoneCall.fileName); 
if (!AudioSystem.isFileTypeSupported(Type.WAVE, stream)) 
{ 
    Logger.error("Audio System file type not supported"); 
} 

AudioSystem.write(stream, Type.WAVE, newPath); 

El archivo escribir con éxito pero todo es estático, ¿Es necesario crear un encabezado de onda en la salida utilizando el algo así como this. Cuando miro el archivo wav de salida en el bloc de notas y parece tener un encabezado, ya que comienza con 'RIFF'.

¿Debo agregar un encabezado falso en mi flujo de entrada? ¿Debo simplemente crear mi propio encabezado de salida y simplemente guardarlo con un escritor binario?

+0

Algo está mal con su publicación. Te faltan datos/formateo. – user845279

+1

¿Qué le parece comparar con otros archivos WAVE válidos? Cuando selecciona uno de ellos, copie los datos después del encabezado y luego coloque los datos brutos en el código de su matriz allBytes. Después de ejecutar su código, simplemente puede comparar los 2 archivos de onda. Si no es lo mismo, el código es incorrecto o necesita comprender el formato de onda. –

+0

el argumento 'length' en el constructor de' AudioInputStream' debe ser un valor de longitud de cuadro en lugar de longitud de datos. 'frame-length = data-length/channel/sample-size-in-byte' –

Respuesta

2

así que terminé conseguir que funcione, no entendemos para qué, pero este es el código que está trabajando:

InputStream b_in = new ByteArrayInputStream(resultArray); 
try { 
     DataOutputStream dos = new DataOutputStream(new FileOutputStream(
       "C:\\filename.bin")); 
     dos.write(resultArray); 
     AudioFormat format = new AudioFormat(8000f, 16, 1, true, false); 
     AudioInputStream stream = new AudioInputStream(b_in, format, 
       resultArray.length); 
     File file = new File("C:\\file.wav"); 
     AudioSystem.write(stream, Type.WAVE, file); 
     Logger.info("File saved: " + file.getName() + ", bytes: " 
       + resultArray.length) 

Así que debe haber sido mi configuración firm/unsigned/little endian. Lo que terminé haciendo fue guardar los datos en un archivo binario. Luego, importar ese archivo como datos sin procesar en audacia. Esto me dijo todo excepto la tarifa que ya soy nueva. El único problema que tengo ahora es hacer con el cálculo del encabezado. Guardo los datos binarios que generan un wav de 4 segundos pero solo tienen 2 segundos de sonido. Es como si estuviera calculando mal mi encabezado. No estoy seguro de si tiene que ver con la longitud de fotograma que mencionó LiuYan.

Si tengo una longitud de matriz de 160. ¿Esto significa que tengo una longitud de trama de 10? 160/1/16. Si hago esto, entonces solo almaceno 10 bytes de datos en mi archivo binario.

+0

Ok si alguien else obtiene el problema con el audio suponía que la longitud del fotograma era 16 .... Pero cuando revisé format.getFrameSize() el valor era 2 Por lo tanto, necesita tener el siguiente AudioInputStream stream = new AudioInputStream (b_in, formato, \t \t \t \t \t resultArray.length/1/format.getFrameSize()); – user1434177

1

Es difícil saber por su descripción dónde está el error, pero para responder a sus preguntas, cuando ve 'RIFF' cuando abre el archivo significa que tiene un encabezado. Tratar de construir su propio encabezado es posible, pero requiere mucho tiempo (e innecesario ya que tiene uno).

Ahora, al leer, es más seguro obtener el formato del archivo en sí, en lugar de tratar de especificarlo manualmente, que será menos propenso a errores. No hay código de ejemplo para que aquí:

http://www.jsresources.org/examples/SimpleAudioPlayer.java.html

Al escribir, se dice "El archivo no escribir con éxito pero todo es estático" - ¿ha confirmado que con algo que no sea su propio código java? Tal vez no entiendo bien, pero parece que estás intentando grabar y reproducir archivos WAV con código Java nuevo, y si ese es el caso, es difícil saber si algo anda mal con la grabación o la reproducción.

Debe comenzar con un formato vanilla (16 bits, estéreo, sin comprimir, 44,100 kHz) para que pueda abrir el archivo en el reproductor multimedia o quicktime o algo así y verificar que la grabación funcionó. Una vez que eso funcione, puedes intentar cambiar el SR, y así sucesivamente. Aquí hay un código de muestra para grabar. Empezar con eso, verifique que funciona, y luego pasar a algo más complejo:

http://www.jsresources.org/examples/SimpleAudioRecorder.java.html

0

Intente configurar la Codificación y el tamaño del cuadro y la velocidad de cuadro de AudioFormato.

new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, 
        8000f, 
        16, 
        1, 
        2, // frameSize 
        8000f,// frameRate 
        false); 
Cuestiones relacionadas