Rogue: Savage Rats, a retro-themed dungeon crawler
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
rogue-savage-rats/src/mightypork/rogue/sounds/AudioX.java

287 lines
5.8 KiB

package mightypork.rogue.sounds;
import mightypork.utils.control.Destroyable;
import mightypork.utils.files.FileUtils;
import mightypork.utils.logging.Log;
import mightypork.utils.math.coord.Coord;
import org.newdawn.slick.openal.Audio;
import org.newdawn.slick.openal.SoundStore;
/**
* Wrapper class for slick audio
*
* @author MightyPork
*/
public class AudioX implements Destroyable {
private enum PlayMode
{
EFFECT, MUSIC;
};
private Audio audio = null;
private double pauseLoopPosition = 0;
private boolean looping = false;
private boolean paused = false;
private PlayMode mode = PlayMode.EFFECT;
private double lastPlayPitch = 1;
private double lastPlayGain = 1;
private final String resourcePath;
private boolean loadFailed = false;
/**
* Create deferred primitive audio player
*
* @param resourceName resource to load when needed
*/
public AudioX(String resourceName) {
this.audio = null;
this.resourcePath = resourceName;
}
/**
* Pause loop (remember position and stop playing) - if was looping
*/
public void pauseLoop()
{
if (!load()) return;
if (isPlaying() && looping) {
pauseLoopPosition = audio.getPosition();
stop();
paused = true;
}
}
/**
* Resume loop (if was paused)
*
* @return source ID
*/
public int resumeLoop()
{
if (!load()) return -1;
int source = -1;
if (looping && paused) {
if (mode == PlayMode.MUSIC) {
source = audio.playAsMusic((float) lastPlayPitch, (float) lastPlayGain, true);
} else {
source = audio.playAsSoundEffect((float) lastPlayPitch, (float) lastPlayGain, true);
}
audio.setPosition((float) pauseLoopPosition);
paused = false;
}
return source;
}
/**
* Check if resource is loaded
*
* @return resource is loaded
*/
private boolean isLoaded()
{
return audio != null;
}
/**
* Try to load if not loaded already
*
* @return is loaded
*/
public boolean load()
{
if (isLoaded()) return true; // already loaded
if (loadFailed || resourcePath == null) return false; // not loaded, but
// can't load
// anyway
loadFailed = false;
try {
String ext = FileUtils.getExtension(resourcePath);
// java 6 can't use String switch :(
if (ext.equalsIgnoreCase("ogg")) {
audio = SoundStore.get().getOgg(resourcePath);
} else if (ext.equalsIgnoreCase("wav")) {
audio = SoundStore.get().getWAV(resourcePath);
} else if (ext.equalsIgnoreCase("aif")) {
audio = SoundStore.get().getAIF(resourcePath);
} else if (ext.equalsIgnoreCase("mod")) {
audio = SoundStore.get().getMOD(resourcePath);
} else {
Log.e("Invalid audio file extension: " + resourcePath);
loadFailed = true; // don't try next time
}
} catch (Exception e) {
Log.e("Could not load " + resourcePath, e);
loadFailed = true; // don't try next time
}
return isLoaded();
}
public void stop()
{
if (!isLoaded()) return;
audio.stop();
paused = false;
}
public boolean isPlaying()
{
if (!isLoaded()) return false;
return audio.isPlaying();
}
public boolean isPaused()
{
if (!isLoaded()) return false;
return audio.isPaused();
}
/**
* Play as sound effect at listener position
*
* @param pitch pitch (1 = default)
* @param gain gain (0-1)
* @param loop looping
* @return source id
*/
public int playAsEffect(double pitch, double gain, boolean loop)
{
return playAsEffect(pitch, gain, loop, SoundSystem.getListener());
}
/**
* Play as sound effect at given X-Y position
*
* @param pitch pitch (1 = default)
* @param gain gain (0-1)
* @param loop looping
* @param x
* @param y
* @return source id
*/
public int playAsEffect(double pitch, double gain, boolean loop, double x, double y)
{
return playAsEffect(pitch, gain, loop, x, y, SoundSystem.getListener().z);
}
/**
* Play as sound effect at given position
*
* @param pitch pitch (1 = default)
* @param gain gain (0-1)
* @param loop looping
* @param x
* @param y
* @param z
* @return source id
*/
public int playAsEffect(double pitch, double gain, boolean loop, double x, double y, double z)
{
if (!load()) return -1;
this.lastPlayPitch = pitch;
this.lastPlayGain = gain;
looping = loop;
mode = PlayMode.EFFECT;
return audio.playAsSoundEffect((float) pitch, (float) gain, loop, (float) x, (float) y, (float) z);
}
/**
* Play as sound effect at given position
*
* @param pitch pitch (1 = default)
* @param gain gain (0-1)
* @param loop looping
* @param pos coord
* @return source id
*/
public int playAsEffect(double pitch, double gain, boolean loop, Coord pos)
{
if (!load()) return -1;
return playAsEffect(pitch, gain, loop, pos.x, pos.y, pos.z);
}
/**
* Play as music using source 0.<br>
* Discouraged, since this does not allow cross-fading.
*
* @param pitch play pitch
* @param gain play gain
* @param loop looping
* @return source
*/
public int playAsMusic(double pitch, double gain, boolean loop)
{
if (!load()) return -1;
this.lastPlayPitch = (float) pitch;
this.lastPlayGain = (float) gain;
looping = loop;
mode = PlayMode.MUSIC;
return audio.playAsMusic((float) pitch, (float) gain, loop);
}
@Override
public void destroy()
{
if (!isLoaded()) return;
audio.release();
audio = null;
}
@Override
public int hashCode()
{
final int prime = 31;
int result = 1;
result = prime * result + ((resourcePath == null) ? 0 : resourcePath.hashCode());
return result;
}
@Override
public boolean equals(Object obj)
{
if (this == obj) return true;
if (obj == null) return false;
if (!(obj instanceof AudioX)) return false;
AudioX other = (AudioX) obj;
if (resourcePath == null) {
if (other.resourcePath != null) return false;
} else if (!resourcePath.equals(other.resourcePath)) {
return false;
}
return true;
}
}