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
|
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.
|
* Returns the buffer of audio data associated with this sound.
|
||||||
*/
|
*/
|
||||||
@@ -109,7 +117,7 @@ public class Sound
|
|||||||
*/
|
*/
|
||||||
public boolean play (boolean allowDefer)
|
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)
|
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;
|
_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 we're not ready to go...
|
||||||
if (!_buffer.isPlayable()) {
|
if (!_buffer.isPlayable()) {
|
||||||
@@ -163,19 +183,29 @@ public class Sound
|
|||||||
// resolved
|
// resolved
|
||||||
_buffer.resolve(new ClipBuffer.Observer() {
|
_buffer.resolve(new ClipBuffer.Observer() {
|
||||||
public void clipLoaded (ClipBuffer buffer) {
|
public void clipLoaded (ClipBuffer buffer) {
|
||||||
play(false);
|
play(false, loop, obs);
|
||||||
}
|
}
|
||||||
public void clipFailed (ClipBuffer buffer) {
|
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 {
|
} else {
|
||||||
// sorry charlie...
|
// sorry charlie...
|
||||||
return false;
|
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 we do not already have a source, obtain one
|
||||||
if (_sourceId == -1) {
|
if (_sourceId == -1) {
|
||||||
_sourceId = _group.acquireSource(this);
|
_sourceId = _group.acquireSource(this);
|
||||||
|
|||||||
@@ -129,9 +129,12 @@ public class SoundManager
|
|||||||
}
|
}
|
||||||
|
|
||||||
// configure our LRU map with a removal observer
|
// configure our LRU map with a removal observer
|
||||||
_clips.setRemovalObserver(new LRUHashMap.RemovalObserver() {
|
_clips.setRemovalObserver(
|
||||||
public void removedFromMap (LRUHashMap map, Object item) {
|
new LRUHashMap.RemovalObserver<Comparable,ClipBuffer>() {
|
||||||
((ClipBuffer)item).dispose();
|
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)
|
protected ClipBuffer getClip (ClipProvider provider, String path)
|
||||||
{
|
{
|
||||||
Comparable ckey = ClipBuffer.makeKey(provider, path);
|
Comparable ckey = ClipBuffer.makeKey(provider, path);
|
||||||
ClipBuffer buffer = (ClipBuffer)_clips.get(ckey);
|
ClipBuffer buffer = _clips.get(ckey);
|
||||||
if (buffer == null) {
|
if (buffer == null) {
|
||||||
// check to see if this clip is currently loading
|
// check to see if this clip is currently loading
|
||||||
buffer = (ClipBuffer)_loading.get(ckey);
|
buffer = _loading.get(ckey);
|
||||||
if (buffer == null) {
|
if (buffer == null) {
|
||||||
buffer = new ClipBuffer(this, provider, path);
|
buffer = new ClipBuffer(this, provider, path);
|
||||||
_loading.put(ckey, buffer);
|
_loading.put(ckey, buffer);
|
||||||
@@ -197,10 +200,12 @@ public class SoundManager
|
|||||||
while (true) {
|
while (true) {
|
||||||
final ClipBuffer buffer = (ClipBuffer)_toLoad.get();
|
final ClipBuffer buffer = (ClipBuffer)_toLoad.get();
|
||||||
try {
|
try {
|
||||||
|
Log.debug("Loading " + buffer.getKey() + ".");
|
||||||
final Clip clip = buffer.load();
|
final Clip clip = buffer.load();
|
||||||
_rqueue.postRunnable(new Runnable() {
|
_rqueue.postRunnable(new Runnable() {
|
||||||
public void run () {
|
public void run () {
|
||||||
Comparable ckey = buffer.getKey();
|
Comparable ckey = buffer.getKey();
|
||||||
|
Log.debug("Loaded " + ckey + ".");
|
||||||
_loading.remove(ckey);
|
_loading.remove(ckey);
|
||||||
if (buffer.bind(clip)) {
|
if (buffer.bind(clip)) {
|
||||||
_clips.put(ckey, buffer);
|
_clips.put(ckey, buffer);
|
||||||
@@ -228,10 +233,12 @@ public class SoundManager
|
|||||||
protected RunQueue _rqueue;
|
protected RunQueue _rqueue;
|
||||||
|
|
||||||
/** Contains a mapping of all currently-loading clips. */
|
/** 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. */
|
/** 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. */
|
/** Contains a queue of clip buffers waiting to be loaded. */
|
||||||
protected Queue _toLoad;
|
protected Queue _toLoad;
|
||||||
@@ -241,12 +248,13 @@ public class SoundManager
|
|||||||
protected static SoundManager _soundmgr;
|
protected static SoundManager _soundmgr;
|
||||||
|
|
||||||
/** Used to compute the in-memory size of sound samples. */
|
/** Used to compute the in-memory size of sound samples. */
|
||||||
protected static LRUHashMap.ItemSizer _sizer = new LRUHashMap.ItemSizer() {
|
protected static LRUHashMap.ItemSizer<ClipBuffer> _sizer =
|
||||||
public int computeSize (Object item) {
|
new LRUHashMap.ItemSizer<ClipBuffer>() {
|
||||||
return ((ClipBuffer)item).getSize();
|
public int computeSize (ClipBuffer item) {
|
||||||
|
return item.getSize();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Default to a cache size of one megabyte. */
|
/** 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