package com.robonobo.core.toolkit.audio;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.FloatControl;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.SourceDataLine;
import javax.sound.sampled.UnsupportedAudioFileException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.robonobo.common.concurrent.CatchingRunnable;
@Deprecated
public class GenericAudioPlayback extends CatchingRunnable {
Log log = LogFactory.getLog(getClass());
InputStream inputStream;
boolean isRunning = false;
SourceDataLine line;
AudioInputStream din = null;
public GenericAudioPlayback() {
}
public GenericAudioPlayback(InputStream in) {
this();
this.inputStream = new BufferedInputStream(in);
}
public synchronized void setVolume(float v) {
if(v < 0)
v = 0f;
if(v > 1)
v = 1f;
float gain = (float) (20d * Math.log(v) / Math.log(10));
if(getLine() != null) {
FloatControl volume = (FloatControl) getLine().getControl(FloatControl.Type.MASTER_GAIN);
if(volume != null)
volume.setValue(gain);
}
}
public synchronized float getVolume() {
if(getLine() != null) {
FloatControl volume = (FloatControl) getLine().getControl(FloatControl.Type.MASTER_GAIN);
if(volume != null) {
float gain = volume.getValue();
return (float) Math.pow(10, gain / 20);
}
}
return 0;
}
public SourceDataLine getLine() {
return line;
}
public void doRun() throws IOException, LineUnavailableException, UnsupportedAudioFileException {
isRunning = true;
AudioInputStream in = null;
while(in == null && isRunning) {
try {
in = AudioSystem.getAudioInputStream(inputStream);
} catch(UnsupportedAudioFileException e) {
log.info("Failed to read from stream, trying again", e);
try {
Thread.sleep(1000);
} catch(InterruptedException ex) {
Thread.currentThread().interrupt();
return;
}
}
}
AudioFormat baseFormat = in.getFormat();
AudioFormat decodedFormat = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, baseFormat.getSampleRate(), 16, baseFormat.getChannels(), baseFormat.getChannels() * 2, baseFormat.getSampleRate(), false);
din = AudioSystem.getAudioInputStream(decodedFormat, in);
byte[] data = new byte[2048];
line = getLine(decodedFormat);
if(line != null && isRunning) {
line.start();
int nBytesRead = 0, nBytesWritten = 0;
while(nBytesRead != -1 && isRunning) {
nBytesRead = din.read(data, 0, data.length);
if(nBytesRead != -1)
nBytesWritten = line.write(data, 0, nBytesRead);
}
line.drain();
line.stop();
line.close();
din.close();
}
in.close();
isRunning = false;
synchronized(this) {
notifyAll();
}
}
public boolean isRunning() {
return isRunning;
}
public void stop() {
isRunning = false;
try {
if(din != null)
din.close();
if(line != null)
line.close();
} catch(IOException e) {
}
}
private SourceDataLine getLine(AudioFormat audioFormat) throws LineUnavailableException {
SourceDataLine res = null;
DataLine.Info info = new DataLine.Info(SourceDataLine.class, audioFormat);
res = (SourceDataLine) AudioSystem.getLine(info);
res.open(audioFormat);
return res;
}
}