|
||||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
java.lang.Objectbb.gui.SoundUtil.Player
private static class SoundUtil.Player
Generates a Clip from a URL
and can play
it,
but most importantly it robustly ensures that the clip is eventually closed
and that this close event gets propagated.
There seems to be a common code idiom for working with Java Sound that is not robust against known bugs and defects. This approach has a LineListener alone listen for the Clip's STOP event and either closes the Clip at that point and/or notifies the calling thread (which is waiting on the Clip instance, if synchronous sound playback is desired). Examples of this code idiom include:
Unfortunately, as the bug reports cited above illustrate, there are many problems with Java Sound:
This class avoids all these problems.
First, it uses the Player instance itself as the wait/notify object.
Second, it does not solely rely on the event mechanism to close the Clip.
Instead, a task that executes in a dedicated background daemon thread is used to guarantee that close
is called after the expected amount of playing time has elapsed, which guards against dropped events.
This class is multithread safe.
Nested Class Summary | |
---|---|
private class |
SoundUtil.Player.Closer
Sleeps for the duration of the sound playback, and then calls StreamUtil.close ( Player.this ). |
Field Summary | |
---|---|
private Clip |
clip
|
private boolean |
closeExecuted
Condition predicate for this instance's condition queue (i.e. the wait/notifyAll calls below; see "Java Concurrency in Practice" by Goetz et al p. 296ff, especially p. 299). |
private int |
numberLoops
|
private URL |
url
|
Constructor Summary | |
---|---|
private |
SoundUtil.Player(URL url,
int numberLoops)
|
Method Summary | |
---|---|
void |
close()
Calls clip.close, and then calls this instance's notifyAll. |
private long |
getDuration()
|
private void |
play()
Initiates the playing of clip in a loop that will execute numberLoops times. |
void |
update(LineEvent event)
|
private void |
waitTillClosed()
Waits until this instance is notified. |
Methods inherited from class java.lang.Object |
---|
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait |
Field Detail |
---|
private final URL url
private final int numberLoops
private final Clip clip
private boolean closeExecuted
Constructor Detail |
---|
private SoundUtil.Player(URL url, int numberLoops) throws UnsupportedAudioFileException, IOException, LineUnavailableException, IllegalArgumentException, IllegalStateException, SecurityException
UnsupportedAudioFileException
IOException
LineUnavailableException
IllegalArgumentException
IllegalStateException
SecurityException
Method Detail |
---|
private void play() throws IllegalStateException
Schedules a background task which will call close
after a delay of getDuration
.
IllegalStateException
- if clip is currently runningprivate long getDuration()
private void waitTillClosed() throws InterruptedException
InterruptedException
public void close()
close
in interface Closeable
public void update(LineEvent event)
update
in interface LineListener
|
||||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |