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.
287 lines
5.9 KiB
287 lines
5.9 KiB
package mightypork.rogue.sounds;
|
|
|
|
|
|
import mightypork.utils.files.FileUtils;
|
|
import mightypork.utils.logging.Log;
|
|
import mightypork.utils.math.coord.Coord;
|
|
import mightypork.utils.patterns.Destroyable;
|
|
|
|
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;
|
|
}
|
|
|
|
}
|
|
|