You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

183 lines
3.8 KiB
Java

Audio channel
import java.io.InputStream;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.LineListener;
import javax.sound.sampled.LineEvent;
import javax.sound.sampled.Mixer;
import javax.sound.sampled.SourceDataLine;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.FloatControl;
import javax.sound.sampled.BooleanControl;
// IDEA: can this class be derived from AudioStream??
public class AudioChannel
extends Thread
{
private static final boolean DEBUG = true;
private static final int BUFFER_SIZE = 16384;
private List m_audioStreamQueue;
private SourceDataLine m_line;
private byte[] m_dataArray;
/*
* Uses the passed Mixer.
*/
public AudioChannel(SourceDataLine line)
{
super("AudioChannel");
/* Setting this thread to daemon means that this thread
doesn't prevent the VM from exiting even if it is
still running.
*/
setDaemon(true);
// TODO: check if priority makes sense
setPriority(9);
m_line = line;
m_audioStreamQueue = new ArrayList();
// TODO: make size configurable
int nBufSizeInFrames = 0;
if (m_line.getBufferSize() > 0)
{
nBufSizeInFrames = m_line.getBufferSize() / 2;
}
else
{
nBufSizeInFrames = 4096;
}
m_dataArray = new byte[nBufSizeInFrames];
}
public AudioFormat getFormat()
{
return m_line.getFormat();
}
public boolean addAudioInputStream(AudioInputStream audioStream)
{
if (DEBUG) { out("AudioChannel.addAudioInputStream(): called."); }
if (!getFormat().matches(audioStream.getFormat()))
{
if (DEBUG) { out("AudioChannel.addAudioInputStream(): audio formats do not match, trying to convert."); }
AudioInputStream asold = audioStream;
audioStream = AudioSystem.getAudioInputStream(getFormat(), asold);
if (audioStream == null)
{
out("### AudioChannel.addAudioInputStream(): could not convert.");
return false;
}
if (DEBUG) { out(" converted"); }
}
synchronized (m_audioStreamQueue)
{
m_audioStreamQueue.add(audioStream);
m_audioStreamQueue.notifyAll();
}
if (DEBUG) { out("AudioChannel.addAudioInputStream(): enqueued " + audioStream); }
return true;
}
// TODO: termination of loop
public void run()
{
if (DEBUG)
{
out("AudioChannel.run(): starting");
}
while (true)
{
AudioInputStream audioStream = null;
synchronized (m_audioStreamQueue)
{
while (m_audioStreamQueue.size() == 0)
{
try
{
m_audioStreamQueue.wait();
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
audioStream = (AudioInputStream) m_audioStreamQueue.remove(0);
}
if (DEBUG)
{
out("AudioChannel.run(): playing " + audioStream);
}
int nBytesRead;
while (true)
{
try
{
nBytesRead = audioStream.read(m_dataArray);
if (nBytesRead == -1)
{
// m_line.write(null, 0, 0);
break;
}
int nBytesWritten = m_line.write(m_dataArray, 0, nBytesRead);
// Contract.check(nBytesWritten == nBytesRead);
}
catch (IOException e)
{
e.printStackTrace();
break;
}
}
}
}
public void closeChannel()
{
// TODO:
}
public void startChannel()
{
// TODO:
m_line.start();
super.start();
}
// should not block, but trigger the termination
public void stopChannel()
{
// TODO: do some mystery to
// a) stop the line (without interupting current plays)
// b) stop the Thread
}
private static void out(String strMessage)
{
System.out.println(strMessage);
}
}
/*** AudioChannel.java ***/
Built by Text2Html