a timorous transition from listening to stop events to just calculating

the time at which the sound will stop. Stop events are flawed.


git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@1886 542714f4-19e9-0310-aa3c-eee0fc999fb1
This commit is contained in:
Ray Greenwell
2002-11-02 01:49:20 +00:00
parent c81cf22659
commit 271d0ffb85
@@ -1,5 +1,5 @@
//
// $Id: SoundManager.java,v 1.7 2002/11/02 00:26:55 ray Exp $
// $Id: SoundManager.java,v 1.8 2002/11/02 01:49:20 ray Exp $
package com.threerings.media;
@@ -288,7 +288,36 @@ public class SoundManager
{
_clip = clip;
_clip.addLineListener(this);
// The mess:
// If we restart a sample, we get two stop events, one immediately
// and one later on.
// We can't just ignore the first in that case, because once
// a sample is restarted it seems to not return true
// for isRunning() (maybe because it's already been reset?)
// but will continue to generate stop events each time it
// is started.
//
// So- we can't depend on capturing stop events to know
// when a sound is done playing. Instead we just add the length
// of the sound to the current time. We fall back on the
// LineListener method if the clip length is unavailable.
//
// The good news is that just adding the length is in many
// ways a better system. I don't feel confident in doing
// that right now because I don't know if any sounds
// will ever return NOT_SPECIFIED.
long length = _clip.getMicrosecondLength();
if (length == AudioSystem.NOT_SPECIFIED) {
Log.info("Length of AudioClip not specified, falling back " +
"to listening for stop events.");
_clip.addLineListener(this);
_length = AudioSystem.NOT_SPECIFIED;
} else {
// convert microseconds to milliseconds, round up.
_length = (length / 1000L) + 1;
}
}
/**
@@ -305,12 +334,13 @@ public class SoundManager
*/
public void restart ()
{
if (_clip.isRunning()) {
_clip.stop();
}
// this seems to be unneeded
// if (_clip.isRunning()) {
// Log.info("Restarted a sound and sent it a stop..");
// _clip.stop();
// }
_clip.setFramePosition(0);
_clip.start();
didStart();
start();
}
/**
@@ -328,11 +358,16 @@ public class SoundManager
*/
public void close ()
{
_clip.removeLineListener(this);
if (areListening()) {
_clip.removeLineListener(this);
}
if (_clip.isRunning()) {
_clip.stop();
}
_clip.close();
// make sure nobody uses this SoundRecord again
_clip = null;
}
/**
@@ -340,7 +375,14 @@ public class SoundManager
*/
protected void didStart ()
{
_stamp = Long.MAX_VALUE;
if (areListening()) {
// clear out the stamp so that we can't possibly be reaped
// and since we're listening, we'll eventually call didStop()
_stamp = Long.MAX_VALUE;
} else {
_stamp = System.currentTimeMillis() + _length;
}
}
/**
@@ -348,6 +390,7 @@ public class SoundManager
*/
protected void didStop ()
{
// no matter what, when we stop, we stop
_stamp = System.currentTimeMillis();
}
@@ -362,14 +405,28 @@ public class SoundManager
// documentation inherited from interface LineListener
public void update (LineEvent event)
{
// this only gets run if we actually need to listen for the
// stop events.
if (event.getType() == LineEvent.Type.STOP) {
didStop();
}
}
/**
* Are we registered as a LineListener on our clip?
*/
private final boolean areListening ()
{
return _length == AudioSystem.NOT_SPECIFIED;
}
/** The timestamp of the moment this clip last stopped playing. */
protected long _stamp;
/** The length of the clip, in milliseconds, or
* AudioSystem.NOT_SPECIFIED if unknown. */
protected long _length;
/** The clip we're wrapping. */
protected Clip _clip;
}