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:
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user