PCM als WAV schreiben bzw ogg-Vorbis zu WAV

kirchrath

Mitglied
Hallo Leute,
Ich habs jetzt schon recht lange versucht und ich bekomme es einfach nicht hin.
Ich möchte eine .ogg Datei (Vorbis) in eine .wav Datei umwandeln. Um die Datei lesen zu können habe ich von javazoom die Vorbis SPI geladen. Abspielen klappt - daher weiß ich, dass zumindest dort der Fehler nicht liegt.
Meine Schritte sehen wie folgt aus:
  1. ogg-Datei als AudioInputStream lesen
  2. AudioInputStream aus vorherigem Stream mit PCM-Format erstellen
  3. AudioInputStream in .wav-Datei speichern

Der Code sollte eigentlich dann so aussehen...
Java:
AudioInputStream oggAIS = AudioSystem.getAudioInputStream(new File("input.ogg"));
AudioInputStream pcmAIS = AudioSystem.getAudioInputStream(Encoding.PCM_SIGNED, oggAIS);
AudioSystem.write(pcmAIS, Type.WAVE, new File("output.wav"));

Klappt aber nicht - datei ist (fast -bis auf einen wav-Header) leer. Mir scheint es, als wäre der oggAIS nicht eingelesen worden. Wenn ich den pcmAIS über read(byte[]) einlese, dann bekomme ich eine Datenmenge die der .wav-Datei entspricht - halt ohne Header.

Würde mich freuen, wenn mir jemand dabei helfen kann. Ich versteh es derzeit einfach nicht :-(

Gruß
Kirchrath
 
Java:
AudioSystem.write(pcmAIS, Type.WAVE, new File("output.wav"));
Mich wundert, dass das bei Dir keine IOException wirft.

Das Problem ist aber grundsätzlich der Header: Die meisten AudioFileWriter benötigen die Länge des AudioInputstreams in Frames, der z. B. aus dem Konstruktor kommt; die scheint hier 0 zu sein. Beim Herum-Google-n habe ich keine Möglichkeit gefunden, mit der SUN-Implementierung eine Konvertierung ohne temporäres File zu machen.

Ich habe die VorbisSPI mal installiert, etwas gehackt, auf Verdacht ein paar Frames kodiert und das klappt auch. Man muss eben noch die Anzahl der Frames ermitteln.
Java:
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

import javax.sound.sampled.AudioFileFormat;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.UnsupportedAudioFileException;

public class OggConvert {

	public static void main(String[] args) throws FileNotFoundException, IOException, UnsupportedAudioFileException {
		
		final File file = new File("/home/kay/Downloads/Kid_Mingus_Crash_Site_Tune.ogg");
		final AudioInputStream in = AudioSystem.getAudioInputStream(file);			
		final AudioFormat baseFormat = in.getFormat();
		final AudioFormat decodedFormat = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, baseFormat.getSampleRate(), 16, baseFormat.getChannels(), baseFormat.getChannels() * 2, baseFormat.getSampleRate(), false);		
		final AudioInputStream din = AudioSystem.getAudioInputStream(decodedFormat, in);
		
		final byte [] buffer = new byte [4096];
		int n;
		
		final FileOutputStream fos = new FileOutputStream("test.pcm");		
		while(-1 != (n = din.read(buffer))) {
			fos.write(buffer, 0, n);
		}		
		fos.close();
		
		final AudioInputStream pcmIn = new AudioInputStream(new FileInputStream("test.pcm"), decodedFormat, 50000);
		AudioSystem.write(pcmIn, AudioFileFormat.Type.WAVE, new FileOutputStream("test.wav"));
	}
}
Es gibt auch einen AudioOutputStream in der tritonus-Implementierung, der ohne Länge auskommt. Das habe ich aber nicht probiert.
 
Zuletzt bearbeitet:

Zurück
Oben