G
Gergely Buday
Hi Folks,
I'm having a problem. My SourceDataLine does not send a STOP event when it
finishes. My ugly hack is the following (see the while(true) cycle in
Player.run()):
public class SourceDatalineSoundPlayer implements LineListener,
SoundFilePlayerInterface {
private Player player = null;
private AudioInputStream ais = null;
private AudioFormat audioFormat = null;
private DataLine.Info info = null;
private SourceDataLine line = null;
private String filename;
private NavigationControl navCtrl = null;
private class Player implements Runnable {
Thread thread = null;
public void start() {
thread = new Thread(this);
thread.setName("Playback");
thread.start();
}
public void stop() {
thread = null;
}
public void run() {
int bufferLengthInBytes = line.getBufferSize();
byte[] data = new byte[bufferLengthInBytes];
int numBytesRead = 0;
line.start();
while (thread != null) {
try {
if ((numBytesRead = ais.read(data)) == -1) {
if (Constants.getDebug()) {
System.out.println("vége");
}
break;
}
int numBytesRemaining = numBytesRead;
while (numBytesRemaining > 0 ) {
numBytesRemaining -= line.write(data, 0, numBytesRemaining);
if (Constants.getDebug()) {
System.err.println("numBytesRemaining=" + numBytesRemaining);
}
}
} catch (Exception e) {
break;
} // try - catch
} // while (thread != null)
while (true) {
if (Constants.getDebug()) {
System.out.println("line.isActive()=" + line.isActive());
}
if (!line.isActive()) {
break;
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
break;
}
} // while (true)
line.stop();
} // public void run()
public boolean loadAudioInputStream(AudioInputStream stream) {
AudioFormat tempAudioFormat = stream.getFormat();
SourceDataLine tempLine = null;
DataLine.Info tempInfo =
new DataLine.Info(SourceDataLine.class, tempAudioFormat);
try {
tempLine = (SourceDataLine) AudioSystem.getLine(tempInfo);
tempLine.open(tempAudioFormat);
} catch (LineUnavailableException e) {
e.printStackTrace();
System.err.println("Line is not available in loadAudioInputStream");
return false;
}
ais = stream;
ais.mark(20000000);
audioFormat = tempAudioFormat;
info = tempInfo;
line = tempLine;
line.addLineListener(this);
return true;
}
public void update(LineEvent event) {
if (Constants.getDebug()) {
System.out.println("event = " + event.toString());
}
}
If I remove line.stop(), the output is the following:
event = Start event from line com.sun.media.sound.MixerSourceLine@9a9b65
numBytesRemaining=0
numBytesRemaining=0
vége ["the end"]
line.isActive()=true
line.isActive()=false
so it does not generate a STOP event (the above update method do receive the
START event, as you can see from the output).
I get "STOP" event only if I use line.stop(), which is in contradiction with
DataLine documentation, what says
"A data line produces START and STOP events whenever it begins or ceases
active presentation or capture of data."
To my understanding, line should generate a STOP event on having no more
data input, shouldn't it?
Do I misunderstand the docs?
- Gergely
I'm having a problem. My SourceDataLine does not send a STOP event when it
finishes. My ugly hack is the following (see the while(true) cycle in
Player.run()):
public class SourceDatalineSoundPlayer implements LineListener,
SoundFilePlayerInterface {
private Player player = null;
private AudioInputStream ais = null;
private AudioFormat audioFormat = null;
private DataLine.Info info = null;
private SourceDataLine line = null;
private String filename;
private NavigationControl navCtrl = null;
private class Player implements Runnable {
Thread thread = null;
public void start() {
thread = new Thread(this);
thread.setName("Playback");
thread.start();
}
public void stop() {
thread = null;
}
public void run() {
int bufferLengthInBytes = line.getBufferSize();
byte[] data = new byte[bufferLengthInBytes];
int numBytesRead = 0;
line.start();
while (thread != null) {
try {
if ((numBytesRead = ais.read(data)) == -1) {
if (Constants.getDebug()) {
System.out.println("vége");
}
break;
}
int numBytesRemaining = numBytesRead;
while (numBytesRemaining > 0 ) {
numBytesRemaining -= line.write(data, 0, numBytesRemaining);
if (Constants.getDebug()) {
System.err.println("numBytesRemaining=" + numBytesRemaining);
}
}
} catch (Exception e) {
break;
} // try - catch
} // while (thread != null)
while (true) {
if (Constants.getDebug()) {
System.out.println("line.isActive()=" + line.isActive());
}
if (!line.isActive()) {
break;
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
break;
}
} // while (true)
line.stop();
} // public void run()
public boolean loadAudioInputStream(AudioInputStream stream) {
AudioFormat tempAudioFormat = stream.getFormat();
SourceDataLine tempLine = null;
DataLine.Info tempInfo =
new DataLine.Info(SourceDataLine.class, tempAudioFormat);
try {
tempLine = (SourceDataLine) AudioSystem.getLine(tempInfo);
tempLine.open(tempAudioFormat);
} catch (LineUnavailableException e) {
e.printStackTrace();
System.err.println("Line is not available in loadAudioInputStream");
return false;
}
ais = stream;
ais.mark(20000000);
audioFormat = tempAudioFormat;
info = tempInfo;
line = tempLine;
line.addLineListener(this);
return true;
}
public void update(LineEvent event) {
if (Constants.getDebug()) {
System.out.println("event = " + event.toString());
}
}
If I remove line.stop(), the output is the following:
event = Start event from line com.sun.media.sound.MixerSourceLine@9a9b65
numBytesRemaining=0
numBytesRemaining=0
vége ["the end"]
line.isActive()=true
line.isActive()=false
so it does not generate a STOP event (the above update method do receive the
START event, as you can see from the output).
I get "STOP" event only if I use line.stop(), which is in contradiction with
DataLine documentation, what says
"A data line produces START and STOP events whenever it begins or ceases
active presentation or capture of data."
To my understanding, line should generate a STOP event on having no more
data input, shouldn't it?
Do I misunderstand the docs?
- Gergely