/*
* Copyright (c) 2008, 2009, 2010 Denis Tulskiy
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* version 3 along with this work. If not, see <http://www.gnu.org/licenses/>.
*/
package com.tulskiy.musique.audio.formats.ogg;
import com.jcraft.jorbis.Comment;
import com.jcraft.jorbis.Info;
import com.jcraft.jorbis.VorbisFile;
import com.tulskiy.musique.audio.Decoder;
import com.tulskiy.musique.playlist.Track;
import com.tulskiy.musique.playlist.TrackData;
import javax.sound.sampled.AudioFormat;
import org.jaudiotagger.tag.FieldKey;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLDecoder;
/**
* @Author: Denis Tulskiy
* @Date: 17.07.2009
*/
public class VorbisDecoder implements Decoder {
private VorbisFile vorbisFile;
private AudioFormat audioFormat;
private boolean streaming = false;
private Track track;
private int oldBitrate;
public boolean open(Track track) {
TrackData trackData = track.getTrackData();
try {
this.track = track;
if (trackData.isFile()) {
logger.fine("Opening file: " + trackData.getFile());
vorbisFile = new VorbisFile(trackData.getFile().getAbsolutePath());
streaming = false;
oldBitrate = trackData.getBitrate();
} else if (trackData.isStream()) {
URL url = trackData.getLocation().toURL();
logger.fine("Opening stream: " + URLDecoder.decode(url.toString(), "utf8"));
URLConnection urlConnection = url.openConnection();
String contentType = urlConnection.getContentType();
if (!contentType.equals("application/ogg")) {
logger.warning("Wrong content type: " + contentType);
return false;
}
InputStream is = urlConnection.getInputStream();
BufferedInputStream bis = new BufferedInputStream(is);
vorbisFile = new VorbisFile(bis, null, 0);
streaming = true;
reloadComments(track);
trackData.setCodec("OGG Vorbis Stream");
}
Info info = vorbisFile.getInfo()[0];
trackData.setSampleRate(info.rate);
trackData.setChannels(info.channels);
audioFormat = new AudioFormat(info.rate, 16, info.channels, true, false);
} catch (Exception e) {
e.printStackTrace();
return false;
}
return true;
}
private void reloadComments(Track track) {
try {
Comment[] comments = vorbisFile.getComment();
for (Comment c : comments) {
for (int i = 0; i < c.comments; i++) {
byte[] data = c.user_comments[i];
String comment = new String(data, 0, data.length - 1, "UTF-8");
String[] strings = comment.split("=");
String key = strings[0];
// String key = strings[0].toLowerCase();
String value = strings[1];
track.getTrackData().addTagFieldValues(FieldKey.valueOf(key), value);
}
}
} catch (Exception e) {
// e.printStackTrace();
}
}
public AudioFormat getAudioFormat() {
return audioFormat;
}
public void seekSample(long sample) {
vorbisFile.pcm_seek(sample);
}
public int decode(byte[] buf) {
int ret = vorbisFile.read(buf, buf.length);
track.getTrackData().setBitrate(vorbisFile.bitrate_instant() / 1000);
if (ret <= 0) {
//it's a stream, open it again
if (streaming) {
if (!open(track))
return -1;
else
return 0;
}
return -1;
}
return ret;
}
public void close() {
try {
if (vorbisFile != null) {
vorbisFile.close();
track.getTrackData().setBitrate(oldBitrate);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}