Rename all the media.SoundManager stuff to variants on SoundPlayer to conflict
less with openal.SoundManager. git-svn-id: svn+ssh://src.earth.threerings.net/nenya/trunk@625 ed5b42cb-e716-0410-a449-f6a68f950b19
This commit is contained in:
@@ -0,0 +1,273 @@
|
||||
package com.threerings.media.sound;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import com.google.common.collect.Sets;
|
||||
|
||||
import com.samskivert.util.Interval;
|
||||
import com.samskivert.util.RunQueue;
|
||||
|
||||
/**
|
||||
* Loads, plays and loops sounds.
|
||||
*/
|
||||
public abstract class SoundPlayer
|
||||
{
|
||||
/** A pan value indicating that a sound should play from the left only. */
|
||||
public static final float PAN_LEFT = -1f;
|
||||
|
||||
/** A pan value indicating that a sound should play from the right only. */
|
||||
public static final float PAN_RIGHT = 1f;
|
||||
|
||||
/** A pan value indicating that a sound should play from center. */
|
||||
public static final float PAN_CENTER = 0f;
|
||||
|
||||
/**
|
||||
* Create instances of this for your application to differentiate
|
||||
* between different types of sounds.
|
||||
*/
|
||||
public static class SoundType
|
||||
{
|
||||
/**
|
||||
* Construct a new SoundType.
|
||||
* Which should be a static variable stashed somewhere for the entire application to share.
|
||||
*
|
||||
* @param strname a short string identifier, preferably without spaces.
|
||||
*/
|
||||
public SoundType (String strname)
|
||||
{
|
||||
_strname = strname;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString ()
|
||||
{
|
||||
return _strname;
|
||||
}
|
||||
|
||||
protected String _strname;
|
||||
}
|
||||
|
||||
/**
|
||||
* A control for sounds.
|
||||
*/
|
||||
public static interface Frob
|
||||
{
|
||||
/**
|
||||
* Stop playing or looping the sound.
|
||||
* At present, the granularity of this command is limited to the buffer size of the
|
||||
* line spooler, or about 8k of data. Thus, if playing an 11khz sample, it could take
|
||||
* 8/11ths of a second for the sound to actually stop playing.
|
||||
*/
|
||||
public void stop ();
|
||||
|
||||
/**
|
||||
* Set the volume of the sound.
|
||||
*/
|
||||
public void setVolume (float vol);
|
||||
|
||||
/**
|
||||
* Get the volume of this sound.
|
||||
*/
|
||||
public float getVolume ();
|
||||
|
||||
/**
|
||||
* Set the pan value for the sound. Valid values are
|
||||
* -1 for left-only, 0 is centered, all the way to +1 for right-only.
|
||||
*/
|
||||
public void setPan (float pan);
|
||||
|
||||
/**
|
||||
* Get the pan value of this sound.
|
||||
*/
|
||||
public float getPan ();
|
||||
}
|
||||
|
||||
/** The default sound type. */
|
||||
public static final SoundType DEFAULT = new SoundType("default");
|
||||
/**
|
||||
* Shut the damn thing off.
|
||||
*/
|
||||
public abstract void shutdown ();
|
||||
|
||||
/**
|
||||
* Returns a string summarizing our volume settings and disabled sound types.
|
||||
*/
|
||||
public String summarizeState ()
|
||||
{
|
||||
StringBuilder buf = new StringBuilder();
|
||||
buf.append("clipVol=").append(_clipVol);
|
||||
buf.append(", disabled=[");
|
||||
int ii = 0;
|
||||
for (SoundType soundType : _disabledTypes) {
|
||||
if (ii++ > 0) {
|
||||
buf.append(", ");
|
||||
}
|
||||
buf.append(soundType);
|
||||
}
|
||||
return buf.append("]").toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Is the specified soundtype enabled?
|
||||
*/
|
||||
public boolean isEnabled (SoundType type)
|
||||
{
|
||||
// by default, types are enabled..
|
||||
return (!_disabledTypes.contains(type));
|
||||
}
|
||||
|
||||
/**
|
||||
* Turns on or off the specified sound type.
|
||||
*/
|
||||
public void setEnabled (SoundType type, boolean enabled)
|
||||
{
|
||||
if (enabled) {
|
||||
_disabledTypes.remove(type);
|
||||
} else {
|
||||
_disabledTypes.add(type);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the volume for all sound clips.
|
||||
*
|
||||
* @param vol a volume parameter between 0f and 1f, inclusive.
|
||||
*/
|
||||
public void setClipVolume (float vol)
|
||||
{
|
||||
_clipVol = Math.max(0f, Math.min(1f, vol));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the volume for all sound clips.
|
||||
*/
|
||||
public float getClipVolume ()
|
||||
{
|
||||
return _clipVol;
|
||||
}
|
||||
|
||||
/**
|
||||
* Optionally lock each of these keys prior to playing, to guarantee that it will be quickly
|
||||
* available for playing.
|
||||
*/
|
||||
public abstract void lock (String pkgPath, String... keys);
|
||||
|
||||
/**
|
||||
*Unlock the specified sounds so that its resources can be freed.
|
||||
*/
|
||||
public abstract void unlock (String pkgPath, String... keys);
|
||||
|
||||
/**
|
||||
* Play the specified sound as the specified type of sound, immediately. Note that a sound
|
||||
* need not be locked prior to playing.
|
||||
*
|
||||
* @return true if the sound actually played, or false if its sound type was disabled or if
|
||||
* sound is off altogether.
|
||||
*/
|
||||
public boolean play (SoundType type, String pkgPath, String key)
|
||||
{
|
||||
return play(type, pkgPath, key, 0, PAN_CENTER);
|
||||
}
|
||||
|
||||
/**
|
||||
* Play the specified sound as the specified type of sound, immediately, with the specified
|
||||
* pan value. Note that a sound need not be locked prior to playing.
|
||||
*
|
||||
* @param pan a value from -1f (all left) to +1f (all right).
|
||||
* @return true if the sound actually played, or false if its sound type was disabled or if
|
||||
* sound is off altogether.
|
||||
*/
|
||||
public boolean play (SoundType type, String pkgPath, String key, float pan)
|
||||
{
|
||||
return play(type, pkgPath, key, 0, pan);
|
||||
}
|
||||
|
||||
/**
|
||||
* Play the specified sound after the specified delay.
|
||||
* @param delay the delay in milliseconds.
|
||||
* @return true if the sound actually played, or false if its sound type was disabled or if
|
||||
* sound is off altogether.
|
||||
*/
|
||||
public boolean play (SoundType type, String pkgPath, String key, int delay)
|
||||
{
|
||||
return play(type, pkgPath, key, delay, PAN_CENTER);
|
||||
}
|
||||
|
||||
/**
|
||||
* Play the specified sound after the specified delay.
|
||||
* @param delay the delay in milliseconds.
|
||||
* @param pan a value from -1f (all left) to +1f (all right).
|
||||
* @return true if the sound actually played, or false if its sound type was disabled or if
|
||||
* sound is off altogether.
|
||||
*/
|
||||
public boolean play (SoundType type, final String pkgPath, final String key, int delay,
|
||||
final float pan)
|
||||
{
|
||||
if (!shouldPlay(type)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (delay > 0) {
|
||||
new Interval(getSoundQueue()) {
|
||||
@Override
|
||||
public void expired () {
|
||||
play(pkgPath, key, pan);
|
||||
}
|
||||
}.schedule(delay);
|
||||
} else {
|
||||
play(pkgPath, key, pan);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Play the specified sound after the specified delay.
|
||||
* @param pan a value from -1f (all left) to +1f (all right).
|
||||
*/
|
||||
protected abstract void play (String pkgPath, String key, float pan);
|
||||
|
||||
/**
|
||||
* Loop the specified sound, stopping as quickly as possible when stop is called.
|
||||
*/
|
||||
public Frob loop (SoundType type, String pkgPath, String key)
|
||||
{
|
||||
return loop(type, pkgPath, key, PAN_CENTER);
|
||||
}
|
||||
|
||||
/**
|
||||
* Loop the specified sound, stopping as quickly as possible when stop is called.
|
||||
*/
|
||||
public Frob loop (SoundType type, String pkgPath, String key, float pan)
|
||||
{
|
||||
if (!shouldPlay(type)) {
|
||||
return null;
|
||||
}
|
||||
return loop(pkgPath, key, pan);
|
||||
}
|
||||
|
||||
/**
|
||||
* Loop the specified sound, stopping as quickly as possible when stop is called.
|
||||
*/
|
||||
protected abstract Frob loop (String pkgPath, String key, float pan);
|
||||
|
||||
protected boolean shouldPlay (SoundType type)
|
||||
{
|
||||
if (type == null) {
|
||||
type = DEFAULT; // let the lazy kids play too
|
||||
}
|
||||
|
||||
return _clipVol != 0f && isEnabled(type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the run queue on which sound should be played. It defaults to {@link RunQueue#AWT}.
|
||||
*/
|
||||
protected abstract RunQueue getSoundQueue ();
|
||||
|
||||
/** Volume level for sound clips. */
|
||||
protected float _clipVol = 1f;
|
||||
|
||||
/** A set of soundTypes for which sound is enabled. */
|
||||
protected Set<SoundType> _disabledTypes = Sets.newHashSet();
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user