package com.hackhalo2.rendering.advsound;
import java.net.URI;
import java.util.BitSet;
import java.util.Iterator;
import java.util.Map;
import java.util.TreeMap;
import org.lwjgl.util.vector.Vector2f;
import org.lwjgl.util.vector.Vector3f;
import com.hackhalo2.rendering.RenderLogger;
import com.hackhalo2.rendering.interfaces.core.IManager;
import com.hackhalo2.rendering.interfaces.core.ISoundSystem;
import com.hackhalo2.rendering.interfaces.sound.ICodecable;
import com.hackhalo2.rendering.interfaces.sound.IDimensionalSound;
import com.hackhalo2.rendering.interfaces.sound.ISoundLibrary;
import com.paulscode.sound.ICodec;
import com.paulscode.sound.SoundSystem;
import com.paulscode.sound.SoundSystemConfig;
import com.paulscode.sound.SoundSystemException;
import com.paulscode.sound.libraries.LibraryJavaSound;
public class JavaSoundSystem implements ISoundSystem, ICodecable,
ISoundLibrary<LibraryJavaSound>, IDimensionalSound, IManager {
/**
* The API Version of the implementation
*/
public final int apiVersion = 1;
private SoundSystem soundSystem = null; // The SoundSystem reference
private Map<Integer, Sound> soundMap = null;
private int codecCount = 0;
private BitSet available = null;
private LibraryJavaSound library = null;
/**
* Processes status messages, warnings, and error messages.
*/
private RenderLogger logger = new RenderLogger();
public JavaSoundSystem() {
try {
this.library = new LibraryJavaSound();
this.soundMap = new TreeMap<Integer, Sound>();
this.available = new BitSet(128);
} catch (SoundSystemException e) {
this.logger.printException(e);
}
}
public JavaSoundSystem(int soundSpace) {
try {
this.library = new LibraryJavaSound();
this.soundMap = new TreeMap<Integer, Sound>();
this.available = new BitSet(soundSpace);
} catch (Exception e) {
this.logger.printException(e);
}
}
@Override
public void initialize() {
this.logger.info("ASSL_initialize", "Initializing JavaSoundSystem...", 0);
try {
this.logger.debug("ASSL_initialize", "Linking Library 'LibraryJavaSound'...", 1);
SoundSystemConfig.addLibrary(LibraryJavaSound.class);
this.logger.debug("ASSL_initialize", "Linking " + this.codecCount + " Codecs...", 1);
} catch (SoundSystemException e) {
this.logger.printException(e);
}
this.soundSystem = new SoundSystem();
this.logger.info("ASSL_initialize", "LWJGLSoundSystem set up sucessfully", 1);
}
@Override
public int queue(URI soundPath, String filename, boolean isLooped, boolean priority) {
int index = -1;
try {
Sound sound = new Sound(filename, soundPath, this.soundSystem);
index = this.available.nextClearBit(0);
if (this.soundMap.containsKey(index)) { // saftey check
this.soundMap.remove(index);
}
this.available.flip(index); // set the index to true
this.soundMap.put(index, sound); // put it in the soundMap
sound.load();
sound.setupStream(priority, isLooped,
SoundSystemConfig.ATTENUATION_ROLLOFF, 0.8f);
return index;
} catch (Exception e) {
this.logger.printException(e);
if (index != -1 && this.available.get(index)) {
this.available.clear(index);
}
return -1;
}
}
@Override
public void dequeue(int soundID) {
this.logger.debug("ASSL_dequeue", "Dequeuing sound "+soundID, 0);
if (this.soundMap.containsKey(soundID)) {
Sound sound = this.soundMap.get(soundID);
this.soundSystem.dequeueSound(sound.getName(), sound.getName());
if (this.available.get(soundID)) { // Failsafe
this.available.flip(soundID); // reset the bit so it can be
// reused
}
this.soundMap.remove(soundID); // Remove it from the map
return;
}
this.logger.warn("ASSL_dequeue", "Sound "+soundID+" doesn't exist!", 1);
}
@Override
public boolean isLooping(int soundID) {
if (this.soundMap.containsKey(soundID)) {
Sound sound = this.soundMap.get(soundID);
return sound.isLooping();
} else
return false;
}
@Override
public boolean play(int soundID) {
if (this.soundMap.containsKey(soundID)) {
Sound sound = this.soundMap.get(soundID);
sound.play();
return true;
} else
return false;
}
@Override
public boolean play2D(int soundID, Vector2f vector) {
if (this.soundMap.containsKey(soundID)) {
Sound sound = this.soundMap.get(soundID);
this.soundSystem
.setPosition(sound.getName(), vector.x, vector.y, 0);
sound.play();
return true;
} else
return false;
}
@Override
public boolean play3D(int soundID, Vector3f vector) {
if (this.soundMap.containsKey(soundID)) {
Sound sound = this.soundMap.get(soundID);
this.soundSystem.setPosition(sound.getName(), vector.x, vector.y,
vector.z);
sound.play();
return true;
} else
return false;
}
@Override
public boolean isPlaying(int soundID) {
if (this.soundMap.containsKey(soundID)) {
Sound sound = this.soundMap.get(soundID);
return this.soundSystem.playing(sound.getName());
} else
return false;
}
@Override
public byte pause(int soundID) {
if (this.soundMap.containsKey(soundID)) {
if (this.isPlaying(soundID)) {
Sound sound = this.soundMap.get(soundID);
sound.pause();
return 1;
} else
return 0;
} else
return -1;
}
@Override
public boolean isPaused(int soundID) {
if (this.soundMap.containsKey(soundID)) {
Sound sound = this.soundMap.get(soundID);
return !this.soundSystem.playing(sound.getName());
} else
return false;
}
@Override
public byte resume(int soundID) {
if (this.soundMap.containsKey(soundID)) {
if (this.isPaused(soundID)) {
Sound sound = this.soundMap.get(soundID);
sound.play();
return 1;
} else
return 0;
} else
return -1;
}
@Override
public byte mute(int soundID) {
if (this.soundMap.containsKey(soundID)) {
if (!this.isMuted(soundID)) {
Sound sound = this.soundMap.get(soundID);
sound.mute();
return 1;
} else
return 0;
} else
return -1;
}
@Override
public boolean isMuted(int soundID) {
if (this.soundMap.containsKey(soundID)) {
Sound sound = this.soundMap.get(soundID);
return sound.isMuted();
} else
return false;
}
@Override
public byte unmute(int soundID) {
if (this.soundMap.containsKey(soundID)) {
if (this.isMuted(soundID)) {
Sound sound = this.soundMap.get(soundID);
sound.unmute();
return 1;
} else
return 0;
} else
return -1;
}
@Override
public int getVolume(int soundID) {
if (this.soundMap.containsKey(soundID)) {
Sound sound = this.soundMap.get(soundID);
return sound.getVolume();
} else
return -1;
}
@Override
public void setVolume(int soundID, int volume) {
if (this.soundMap.containsKey(soundID)) {
Sound sound = this.soundMap.get(soundID);
sound.setVolume(volume);
}
}
@Override
public void stop() {
Iterator<Sound> it = this.soundMap.values().iterator();
while (it.hasNext()) {
Sound sound = it.next();
if (sound.isPlaying())
sound.stop();
}
}
@Override
public void stop(int soundID) {
if (this.soundMap.containsKey(soundID)) {
Sound sound = this.soundMap.get(soundID);
sound.stop();
}
}
@Override
public void installCodec(String format, ICodec codec)
throws SoundSystemException {
this.codecCount++;
SoundSystemConfig.setCodec(format, codec.getClass());
}
@Override
public boolean hasCustomMIDICodec() {
return SoundSystemConfig.midiCodec();
}
@Override
public LibraryJavaSound getSoundLibrary() {
return this.library;
}
@Override
public void cleanup() {
this.soundMap = null;
this.logger = null;
this.soundSystem.cleanup();
this.soundSystem = null;
this.library = null;
}
}