2012-06-12 6 views
9

Ich hatte in den letzten paar Tagen ein bisschen Ärger, als ich versuchte, das zum Laufen zu bringen. Aber was ich will, ist eine Anwendung, die Rohdaten über das Netzwerk sendet. Ich lese diese Binärdaten dann ein und möchte sie in einer WAV-Datei (jeder Audio-Datei) speichern. Könnte später auf Kompression schauen.Speichern von Audio-Byte [] in eine WAV-Datei

So ist die problematische Code:

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);     

Haben Sie versucht auch die obige Aussage zu verwenden, aber ich bekomme die Ausnahme: javax.sound.sampled.UnsupportedAudioFileException: could not get audio input stream from stream. Was ich denke ist, dass mein Stream rohe Audiodaten ist und keinen Wave-Header hat, was eine Ausnahme darstellt?

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); 

Die Datei schreiben nicht erfolgreich, aber es ist alles andere als statisch, Benötige ich eine Wave-Header auf den Ausgang wie this mit dem etwas zu schaffen. Wenn ich mir die ausgegebene wav-Datei in Notepad anschaue, scheint sie eine Kopfzeile zu haben, da sie mit 'RIFF' beginnt.

Muss ich einen falschen Header in meinen Eingabestream einfügen? Sollte ich nur meinen eigenen Ausgabe-Header erstellen und ihn einfach mit einem Binär-Writer speichern?

+0

Etwas stimmt nicht mit Ihrer Post. Ihnen fehlen Daten/Formatierung. – user845279

+1

Wie wäre es mit anderen gültigen WAVE-Dateien zu vergleichen? Wenn Sie eines von ihnen auswählen, kopieren Sie die Daten nach dem Header und legen Sie dann die Rohdaten auf Code in Ihr Array allBytes. Nachdem Sie Ihren Code ausgeführt haben, können Sie einfach die 2 Wave-Dateien vergleichen. Wenn es nicht das gleiche ist, dann ist entweder Code schlecht oder du musst das Wave Format besser verstehen. –

+0

Das 'length'-Argument im Konstruktor von' AudioInputStream' sollte anstelle der Datenlänge ein Framelängenwert sein. 'frame-length = Datenlänge/channel/sample-size-in-byte' –

Antwort

2

So landete ich immer daran zu arbeiten, nicht wirklich sicher, warum, aber dies ist der Code, der funktioniert:

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) 

So muss es meine signed/unsigned/Little Endian Einstellungen gewesen sein. Am Ende habe ich die Daten in einer Binärdatei gespeichert. Dann importieren Sie diese Datei als Rohdaten in Dreistigkeit. Das hat mir alles außer der Rate erzählt, die ich bereits neu bin. Das einzige Problem, das ich jetzt habe, ist mit der Header-Berechnung zu tun. Ich speichere die binären Daten, die eine 4 Sekunden wav erzeugen, aber es hat immer nur 2 Sekunden Sound. Es ist, als würde es meine Kopfzeile falsch berechnen. Ich bin mir nicht sicher, ob es mit der Rahmenlänge zu tun hat, die LiuYan erwähnt hat.

Wenn ich eine Array-Länge von 160 habe. Bedeutet dies, dass ich eine Rahmenlänge von 10 habe? 160/1/16. Wenn ich dies mache, dann speichere ich nur 10 Bytes Daten in meine Binärdatei.

+0

Ok, wenn jemand sonst bekomme ich das problem mit dem audio ich nahm an das die framelänge 16 war .... Aber als ich format.getFrameSize() überprüfte war der wert 2 Also muss man folgendes haben AudioInputStream stream = neuer AudioInputStream (b_in, Format, \t \t \t \t \t ErgebnisArray.Length/1/format.getFrameSize()); – user1434177

1

Es ist schwer von Ihrer Beschreibung zu wissen, wo der Fehler ist, aber um Ihre Fragen zu beantworten, wenn Sie "RIFF" sehen, wenn Sie die Datei öffnen, die bedeutet, dass es eine Kopfzeile hat. Der Versuch, einen eigenen Header zu erstellen, ist möglich, aber ein wenig zeitaufwendig (und unnötig, da Sie einen haben).

Jetzt, beim Lesen, ist es am sichersten, das Format von der Datei selbst zu bekommen, anstatt es manuell zu spezifizieren - das wird weniger fehleranfällig sein. Es gibt Beispielcode für das hier:

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

Beim Schreiben, sagen Sie „Die Datei schreiben nicht erfolgreich, aber es ist alles andere als statisch“ - haben Sie bestätigt, dass mit etwas anderes als Ihre eigenen Java-Code? Vielleicht verstehe ich das nicht richtig, aber es hört sich so an, als würden Sie versuchen, WAV-Dateien mit frischem Java-Code aufzunehmen und wiederzugeben, und wenn das der Fall ist, ist es schwer zu sagen, ob etwas mit der Aufnahme oder der Wiedergabe schief geht.

Sie sollten mit einem Vanilla-Format (16 Bit, Stereo, unkomprimiert, 44.100 kHz) beginnen, so dass Sie die Datei im Media Player oder Quicktime oder etwas öffnen und überprüfen können, ob die Aufnahme funktioniert hat. Sobald das funktioniert, können Sie versuchen, die SR usw. zu ändern. Hier ist ein Beispielcode für die Aufnahme. Beginnen Sie damit, sicherzustellen, dass es funktioniert, und fahren Sie dann mit etwas komplexer:

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

0

Versuchen Sie, die Codierung und Bildgröße und Bildrate von AudioFormat einzustellen.

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