Made so that only the owner of the source can change the status of it
This commit is contained in:
parent
dd696b2760
commit
f25b07910e
3 changed files with 260 additions and 165 deletions
|
|
@ -8,9 +8,11 @@ import ei.engine.scene.Entity;
|
|||
* @author Kevin Glass
|
||||
*/
|
||||
public class Sound extends Entity{
|
||||
private static int soundId = 1;
|
||||
/** The buffer containing the sound */
|
||||
private int buffer;
|
||||
private int source;
|
||||
private int sourceId;
|
||||
private int id;
|
||||
|
||||
/**
|
||||
* Create a new sound
|
||||
|
|
@ -20,34 +22,66 @@ public class Sound extends Entity{
|
|||
*/
|
||||
public Sound(String name, String ref) {
|
||||
super(name);
|
||||
this.buffer = SoundLoader.getInstnace().loadSound(ref);
|
||||
id = soundId;
|
||||
soundId++;
|
||||
this.buffer = SoundLoader.getInstnace().loadSound(ref);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the unique id of the object
|
||||
*
|
||||
* @return The id of the object
|
||||
*/
|
||||
public int getSoundId(){
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the source this object uses
|
||||
*
|
||||
* @return The id of the source
|
||||
*/
|
||||
public int getSourceId(){
|
||||
return sourceId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the buffer of this object
|
||||
*
|
||||
* @return The buffer
|
||||
*/
|
||||
public int getBuffer(){
|
||||
return buffer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Play this sound as a sound effect
|
||||
*
|
||||
*/
|
||||
public void play() {
|
||||
source = SoundLoader.getInstnace().playSound(buffer, true);
|
||||
sourceId = SoundManager.getInstnace().playSound(this, false);
|
||||
update();
|
||||
}
|
||||
|
||||
/**
|
||||
* Loop this sound
|
||||
*
|
||||
*/
|
||||
public void loop() {
|
||||
SoundLoader.getInstnace().playSound(buffer, true);
|
||||
SoundManager.getInstnace().playSound(this, true);
|
||||
update();
|
||||
}
|
||||
|
||||
public void update() {
|
||||
//AL10.alSource(source.get(0), AL10.AL_POSITION, sourcePos);
|
||||
SoundLoader.getInstnace().setSoundLocation(
|
||||
source, getLocation().getX(),getLocation().getY(),0);
|
||||
SoundManager.getInstnace().setSoundLocation(
|
||||
this, getLocation().getX(),getLocation().getY(),0);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* unimplamented method
|
||||
*
|
||||
*/
|
||||
public void render() {}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,14 +3,11 @@ package ei.engine.sound;
|
|||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.IntBuffer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
|
||||
import org.lwjgl.BufferUtils;
|
||||
import org.lwjgl.Sys;
|
||||
import org.lwjgl.openal.AL;
|
||||
import org.lwjgl.openal.AL10;
|
||||
import org.lwjgl.openal.OpenALException;
|
||||
import org.lwjgl.util.WaveData;
|
||||
|
||||
import ei.engine.sound.decoders.OggData;
|
||||
|
|
@ -24,149 +21,20 @@ import ei.engine.util.MultiPrintStream;
|
|||
* @author Ziver Koc
|
||||
*/
|
||||
public class SoundLoader {
|
||||
/** The number of sound sources enabled - default 8 */
|
||||
public static final int MAX_SOURCES = 128;
|
||||
/** The single instance of this class */
|
||||
private static SoundLoader instance = new SoundLoader();
|
||||
|
||||
/** True if sound effects are turned on */
|
||||
private boolean soundsEnabled;
|
||||
/** The map of references to IDs of previously loaded sounds */
|
||||
private HashMap<String, Integer> loaded = new HashMap<String, Integer>();
|
||||
/** The OpenGL AL sound sources */
|
||||
private ArrayList<Integer> sources = new ArrayList<Integer>();
|
||||
|
||||
|
||||
/**
|
||||
* Create a new sound store
|
||||
*/
|
||||
private SoundLoader() {
|
||||
init();
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicate whether sound effects should be played
|
||||
*
|
||||
* @param sounds True if sound effects should be played
|
||||
*/
|
||||
public void setEnabled(boolean enabled) {
|
||||
this.soundsEnabled = enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if sound effects are currently enabled
|
||||
*
|
||||
* @return True if sound effects are currently enabled
|
||||
*/
|
||||
public boolean isEnabled() {
|
||||
return soundsEnabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialise the sound effects stored. This must be called
|
||||
* before anything else will work
|
||||
*/
|
||||
private void init() {
|
||||
try {
|
||||
AL.create();
|
||||
soundsEnabled = true;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
MultiPrintStream.out.println(e);
|
||||
soundsEnabled = false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Play the specified buffer as a sound effect with the specified
|
||||
* pitch and gain.
|
||||
*
|
||||
* @param buffer The ID of the buffer to play
|
||||
* @param pitch The pitch to play at
|
||||
* @param gain The gain to play at
|
||||
* @return The id of the assigned source
|
||||
*/
|
||||
public int playSound(int buffer, boolean loop) {
|
||||
if (soundsEnabled && buffer >= 0) {
|
||||
int sourceId = getAvailableSource();
|
||||
if(sourceId >= 0){
|
||||
stopSound(sourceId);
|
||||
MultiPrintStream.out.println("Playing sound: source="+sourceId+" buffer="+buffer);
|
||||
|
||||
AL10.alSourcei(sources.get(sourceId), AL10.AL_BUFFER, buffer);
|
||||
AL10.alSourcef(sources.get(sourceId), AL10.AL_PITCH, 1.0f);
|
||||
AL10.alSourcef(sources.get(sourceId), AL10.AL_GAIN, 1.0f);
|
||||
AL10.alSourcei(sources.get(sourceId), AL10.AL_LOOPING, (loop ? AL10.AL_TRUE : AL10.AL_FALSE) );
|
||||
|
||||
AL10.alSourcePlay(sources.get(sourceId));
|
||||
return sourceId;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Looks for a availablee source. Creates a source if
|
||||
* necessary
|
||||
* @return The source id
|
||||
*/
|
||||
private int getAvailableSource(){
|
||||
int source = -1;
|
||||
MultiPrintStream.out.println("Sound sources: quantity="+sources.size());
|
||||
|
||||
//looking for a source that is not playing
|
||||
for(int i=0; i<sources.size() ;i++){
|
||||
int state = AL10.alGetSourcei(sources.get(i), AL10.AL_SOURCE_STATE);
|
||||
if(state != AL10.AL_PLAYING){
|
||||
source = i;
|
||||
}
|
||||
}
|
||||
|
||||
//creating a new source
|
||||
if(source < 0 && sources.size() <= MAX_SOURCES){
|
||||
IntBuffer sourceBuffer = BufferUtils.createIntBuffer(1);
|
||||
int result;
|
||||
// Generate a source.
|
||||
AL10.alGenSources(sourceBuffer);
|
||||
|
||||
if ((result = AL10.alGetError()) != AL10.AL_NO_ERROR){
|
||||
throw new OpenALException(getALErrorString(result));
|
||||
}
|
||||
|
||||
// Save the source id.
|
||||
sources.add(new Integer(sourceBuffer.get(0)));
|
||||
source = sources.size()-1;
|
||||
}
|
||||
|
||||
// Return the source id.
|
||||
return source;
|
||||
}
|
||||
|
||||
/**
|
||||
* Stops playing a sound
|
||||
* @param sourceId The id of the source
|
||||
*/
|
||||
public void stopSound(int sourceId){
|
||||
if(sourceId >= 0){
|
||||
MultiPrintStream.out.println("Stoping sound: source="+sourceId);
|
||||
AL10.alSourceStop(sources.get(sourceId));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify the location of the sound
|
||||
* @param sourceId The id of the source
|
||||
* @param x The x axes
|
||||
* @param y The y axes
|
||||
* @param z The z axes
|
||||
*/
|
||||
public void setSoundLocation(int sourceId, float x, float y, float z){
|
||||
//specify where the sound is comming from by tree axes x,y and z
|
||||
if(sourceId >= 0){
|
||||
AL10.alSource3f(sources.get(sourceId), AL10.AL_POSITION, x, y, z);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Sound based on a specified file path in the classpath
|
||||
*
|
||||
|
|
@ -175,9 +43,9 @@ public class SoundLoader {
|
|||
* @throws IOException Indicates a failure to load the sound file
|
||||
*/
|
||||
public int loadSound(String ref){
|
||||
if (!soundsEnabled) {
|
||||
if (!SoundManager.getInstnace().isEnabled()) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
int buffer = -1;
|
||||
|
||||
if (loaded.get(ref) != null) {
|
||||
|
|
@ -215,7 +83,7 @@ public class SoundLoader {
|
|||
e.printStackTrace();
|
||||
Sys.alert("ERROR", "Failed to load: "+ref+" - "+e.getMessage());
|
||||
MultiPrintStream.out.println("Failed to load: "+ref+" - "+e.getMessage());
|
||||
soundsEnabled = false;
|
||||
SoundManager.getInstnace().setEnabled(false);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
|
@ -239,29 +107,6 @@ public class SoundLoader {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 1) Identify the error code.
|
||||
* 2) Return the error as a string.
|
||||
*/
|
||||
public static String getALErrorString(int err) {
|
||||
switch (err) {
|
||||
case AL10.AL_NO_ERROR:
|
||||
return "AL_NO_ERROR";
|
||||
case AL10.AL_INVALID_NAME:
|
||||
return "AL_INVALID_NAME";
|
||||
case AL10.AL_INVALID_ENUM:
|
||||
return "AL_INVALID_ENUM";
|
||||
case AL10.AL_INVALID_VALUE:
|
||||
return "AL_INVALID_VALUE";
|
||||
case AL10.AL_INVALID_OPERATION:
|
||||
return "AL_INVALID_OPERATION";
|
||||
case AL10.AL_OUT_OF_MEMORY:
|
||||
return "AL_OUT_OF_MEMORY";
|
||||
default:
|
||||
return "No such error code";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the single instance of this class
|
||||
*
|
||||
|
|
|
|||
216
src/ei/engine/sound/SoundManager.java
Normal file
216
src/ei/engine/sound/SoundManager.java
Normal file
|
|
@ -0,0 +1,216 @@
|
|||
package ei.engine.sound;
|
||||
|
||||
import java.nio.IntBuffer;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import org.lwjgl.BufferUtils;
|
||||
import org.lwjgl.openal.AL;
|
||||
import org.lwjgl.openal.AL10;
|
||||
import org.lwjgl.openal.OpenALException;
|
||||
|
||||
import ei.engine.util.MultiPrintStream;
|
||||
|
||||
/**
|
||||
* Responsible for holding and playing the sounds used in the game.
|
||||
*
|
||||
* @author Kevin Glass
|
||||
* @author Ziver Koc
|
||||
*/
|
||||
public class SoundManager {
|
||||
/** The number of sound sources enabled - default 8 */
|
||||
public static final int MAX_SOURCES = 128;
|
||||
/** The single instance of this class */
|
||||
private static SoundManager instance = new SoundManager();
|
||||
|
||||
/** True if sound effects are turned on */
|
||||
private boolean enabled;
|
||||
/** The OpenGL AL sound sources */
|
||||
private ArrayList<SourceNode> sources = new ArrayList<SourceNode>();
|
||||
|
||||
class SourceNode{
|
||||
int source;
|
||||
int soundId;
|
||||
|
||||
public SourceNode(int source, int sound){
|
||||
this.source = source;
|
||||
this.soundId = sound;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new sound store
|
||||
*/
|
||||
private SoundManager() {
|
||||
init();
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicate whether sound effects should be played
|
||||
*
|
||||
* @param sounds True if sound effects should be played
|
||||
*/
|
||||
public void setEnabled(boolean enabled) {
|
||||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if sound effects are currently enabled
|
||||
*
|
||||
* @return True if sound effects are currently enabled
|
||||
*/
|
||||
public boolean isEnabled() {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialise the sound effects stored. This must be called
|
||||
* before anything else will work
|
||||
*/
|
||||
private void init() {
|
||||
try {
|
||||
AL.create();
|
||||
enabled = true;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
MultiPrintStream.out.println(e);
|
||||
enabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Play the specified buffer as a sound effect with the specified
|
||||
* pitch and gain.
|
||||
*
|
||||
* @param buffer The ID of the buffer to play
|
||||
* @param pitch The pitch to play at
|
||||
* @param gain The gain to play at
|
||||
* @return The id of the assigned source
|
||||
*/
|
||||
public int playSound(Sound sound, boolean loop) {
|
||||
if (enabled && sound.getBuffer() >= 0) {
|
||||
int sourceId = getAvailableSource();
|
||||
if(sourceId >= 0){
|
||||
stopSound(sourceId);
|
||||
MultiPrintStream.out.println("Playing sound: source="+sourceId+" buffer="+sound.getBuffer());
|
||||
|
||||
AL10.alSourcei(sources.get(sourceId).source, AL10.AL_BUFFER, sound.getBuffer());
|
||||
AL10.alSourcef(sources.get(sourceId).source, AL10.AL_PITCH, 1.0f);
|
||||
AL10.alSourcef(sources.get(sourceId).source, AL10.AL_GAIN, 1.0f);
|
||||
AL10.alSourcei(sources.get(sourceId).source, AL10.AL_LOOPING, (loop ? AL10.AL_TRUE : AL10.AL_FALSE) );
|
||||
|
||||
AL10.alSourcePlay(sources.get(sourceId).source);
|
||||
sources.get(sourceId).soundId = sound.getSoundId();
|
||||
return sourceId;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Looks for a availablee source. Creates a source if
|
||||
* necessary
|
||||
* @return The source id
|
||||
*/
|
||||
private int getAvailableSource(){
|
||||
int source = -1;
|
||||
MultiPrintStream.out.println("Sound sources: quantity="+sources.size());
|
||||
|
||||
//looking for a source that is not playing
|
||||
for(int i=0; i<sources.size() ;i++){
|
||||
int state = AL10.alGetSourcei(sources.get(i).source, AL10.AL_SOURCE_STATE);
|
||||
if(state != AL10.AL_PLAYING){
|
||||
source = i;
|
||||
}
|
||||
}
|
||||
|
||||
//creating a new source
|
||||
if(source < 0 && sources.size() <= MAX_SOURCES){
|
||||
IntBuffer sourceBuffer = BufferUtils.createIntBuffer(1);
|
||||
int result;
|
||||
// Generate a source.
|
||||
AL10.alGenSources(sourceBuffer);
|
||||
|
||||
if ((result = AL10.alGetError()) != AL10.AL_NO_ERROR){
|
||||
throw new OpenALException(getALErrorString(result));
|
||||
}
|
||||
|
||||
// Save the source id.
|
||||
sources.add(new SourceNode(sourceBuffer.get(0),-1));
|
||||
source = sources.size()-1;
|
||||
}
|
||||
|
||||
// Return the source id.
|
||||
return source;
|
||||
}
|
||||
|
||||
/**
|
||||
* Stops playing a sound
|
||||
* @param sourceId The id of the source
|
||||
*/
|
||||
public void stopSound(Sound sound){
|
||||
if(sound.getSourceId() >= 0 && sources.get(sound.getSourceId()).soundId == sound.getSoundId()){
|
||||
MultiPrintStream.out.println("Stoping sound: source="+sound.getSourceId());
|
||||
AL10.alSourceStop(sources.get(sound.getSourceId()).source);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Stops playing a sound
|
||||
* @param sourceId The id of the source
|
||||
*/
|
||||
private void stopSound(int sourceId){
|
||||
if(sourceId >= 0){
|
||||
MultiPrintStream.out.println("Stoping sound: source="+sourceId);
|
||||
AL10.alSourceStop(sources.get(sourceId).source);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify the location of the sound
|
||||
* @param sourceId The id of the source
|
||||
* @param x The x axes
|
||||
* @param y The y axes
|
||||
* @param z The z axes
|
||||
*/
|
||||
public void setSoundLocation(Sound sound, float x, float y, float z){
|
||||
//specify where the sound is comming from by tree axes x,y and z
|
||||
if(sound.getSourceId() >= 0 && sources.get(sound.getSourceId()).soundId == sound.getSoundId()){
|
||||
AL10.alSource3f(sources.get(sound.getSourceId()).source, AL10.AL_POSITION, x, y, z);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 1) Identify the error code.
|
||||
* 2) Return the error as a string.
|
||||
*/
|
||||
public static String getALErrorString(int err) {
|
||||
switch (err) {
|
||||
case AL10.AL_NO_ERROR:
|
||||
return "AL_NO_ERROR";
|
||||
case AL10.AL_INVALID_NAME:
|
||||
return "AL_INVALID_NAME";
|
||||
case AL10.AL_INVALID_ENUM:
|
||||
return "AL_INVALID_ENUM";
|
||||
case AL10.AL_INVALID_VALUE:
|
||||
return "AL_INVALID_VALUE";
|
||||
case AL10.AL_INVALID_OPERATION:
|
||||
return "AL_INVALID_OPERATION";
|
||||
case AL10.AL_OUT_OF_MEMORY:
|
||||
return "AL_OUT_OF_MEMORY";
|
||||
default:
|
||||
return "No such error code";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the single instance of this class
|
||||
*
|
||||
* @return The single instnace of this class
|
||||
*/
|
||||
public static SoundManager getInstnace() {
|
||||
if(instance == null){
|
||||
instance = new SoundManager();
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue