Added support for observing sound resolution; type-safetified.

git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@4021 542714f4-19e9-0310-aa3c-eee0fc999fb1
This commit is contained in:
Michael Bayne
2006-04-14 18:34:08 +00:00
parent 3c6ac7ac67
commit 79be7ebd1b
2 changed files with 55 additions and 17 deletions
+36 -6
View File
@@ -32,6 +32,14 @@ import org.lwjgl.openal.AL10;
*/
public class Sound
{
/** Used to await notification of the starting of a sound which may be
* delayed in loading. */
public interface StartObserver
{
/** Called when the specified sound has started playing. */
public void soundStarted (Sound sound);
}
/**
* Returns the buffer of audio data associated with this sound.
*/
@@ -109,7 +117,7 @@ public class Sound
*/
public boolean play (boolean allowDefer)
{
return play(allowDefer, false);
return play(allowDefer, false, null);
}
/**
@@ -122,7 +130,18 @@ public class Sound
*/
public boolean loop (boolean allowDefer)
{
return play(allowDefer, true);
return play(allowDefer, true, null);
}
/**
* Plays this sound from the beginning, notifying the supplied observer
* when the audio starts.
*
* @param loop whether or not to loop the sampe until {@link #stop}ped.
*/
public void play (StartObserver obs, boolean loop)
{
play(true, loop, obs);
}
/**
@@ -154,7 +173,8 @@ public class Sound
_buffer = buffer;
}
protected boolean play (boolean allowDefer, boolean loop)
protected boolean play (
boolean allowDefer, final boolean loop, final StartObserver obs)
{
// if we're not ready to go...
if (!_buffer.isPlayable()) {
@@ -163,19 +183,29 @@ public class Sound
// resolved
_buffer.resolve(new ClipBuffer.Observer() {
public void clipLoaded (ClipBuffer buffer) {
play(false);
play(false, loop, obs);
}
public void clipFailed (ClipBuffer buffer) {
// ugh. nothing to do here but be sad
// well, let's pretend like the sound started so that
// the observer isn't left hanging
if (obs != null) {
obs.soundStarted(Sound.this);
}
}
});
return true;
} else {
// sorry charlie...
return false;
}
}
// let the observer know that (as far as they're concerned), we're
// started
if (obs != null) {
obs.soundStarted(this);
}
// if we do not already have a source, obtain one
if (_sourceId == -1) {
_sourceId = _group.acquireSource(this);
@@ -129,9 +129,12 @@ public class SoundManager
}
// configure our LRU map with a removal observer
_clips.setRemovalObserver(new LRUHashMap.RemovalObserver() {
public void removedFromMap (LRUHashMap map, Object item) {
((ClipBuffer)item).dispose();
_clips.setRemovalObserver(
new LRUHashMap.RemovalObserver<Comparable,ClipBuffer>() {
public void removedFromMap (LRUHashMap<Comparable,ClipBuffer> map,
ClipBuffer item) {
Log.debug("Flushing " + item.getKey());
item.dispose();
}
});
@@ -152,10 +155,10 @@ public class SoundManager
protected ClipBuffer getClip (ClipProvider provider, String path)
{
Comparable ckey = ClipBuffer.makeKey(provider, path);
ClipBuffer buffer = (ClipBuffer)_clips.get(ckey);
ClipBuffer buffer = _clips.get(ckey);
if (buffer == null) {
// check to see if this clip is currently loading
buffer = (ClipBuffer)_loading.get(ckey);
buffer = _loading.get(ckey);
if (buffer == null) {
buffer = new ClipBuffer(this, provider, path);
_loading.put(ckey, buffer);
@@ -197,10 +200,12 @@ public class SoundManager
while (true) {
final ClipBuffer buffer = (ClipBuffer)_toLoad.get();
try {
Log.debug("Loading " + buffer.getKey() + ".");
final Clip clip = buffer.load();
_rqueue.postRunnable(new Runnable() {
public void run () {
Comparable ckey = buffer.getKey();
Log.debug("Loaded " + ckey + ".");
_loading.remove(ckey);
if (buffer.bind(clip)) {
_clips.put(ckey, buffer);
@@ -228,10 +233,12 @@ public class SoundManager
protected RunQueue _rqueue;
/** Contains a mapping of all currently-loading clips. */
protected HashMap _loading = new HashMap();
protected HashMap<Comparable,ClipBuffer> _loading =
new HashMap<Comparable,ClipBuffer>();
/** Contains a mapping of all loaded clips. */
protected LRUHashMap _clips = new LRUHashMap(DEFAULT_CACHE_SIZE, _sizer);
protected LRUHashMap<Comparable,ClipBuffer> _clips =
new LRUHashMap<Comparable,ClipBuffer>(DEFAULT_CACHE_SIZE, _sizer);
/** Contains a queue of clip buffers waiting to be loaded. */
protected Queue _toLoad;
@@ -241,12 +248,13 @@ public class SoundManager
protected static SoundManager _soundmgr;
/** Used to compute the in-memory size of sound samples. */
protected static LRUHashMap.ItemSizer _sizer = new LRUHashMap.ItemSizer() {
public int computeSize (Object item) {
return ((ClipBuffer)item).getSize();
protected static LRUHashMap.ItemSizer<ClipBuffer> _sizer =
new LRUHashMap.ItemSizer<ClipBuffer>() {
public int computeSize (ClipBuffer item) {
return item.getSize();
}
};
/** Default to a cache size of one megabyte. */
protected static final int DEFAULT_CACHE_SIZE = 1024 * 1024;
protected static final int DEFAULT_CACHE_SIZE = 8 * 1024 * 1024;
}