New better sound support

This commit is contained in:
Ziver Koc 2007-03-16 19:16:00 +00:00
parent 47de3ed661
commit 635d756429
3 changed files with 131 additions and 52 deletions

View file

@ -36,6 +36,15 @@ public class Vector2f {
y += i; y += i;
} }
/**
* Add to the vectro
* @param i The amount to add
*/
public void add(Vector2f i){
x += i.getX();
y += i.getY();
}
public String toString(){ public String toString(){
return "Vector2f["+x+","+y+"]"; return "Vector2f["+x+","+y+"]";
} }

View file

@ -1,9 +1,6 @@
package ei.engine.sound; package ei.engine.sound;
import java.io.IOException;
import ei.engine.scene.Entity; import ei.engine.scene.Entity;
import ei.engine.util.MultiPrintStream;
/** /**
* A sound that can be played through OpenAL * A sound that can be played through OpenAL
@ -13,7 +10,8 @@ import ei.engine.util.MultiPrintStream;
public class Sound extends Entity{ public class Sound extends Entity{
/** The buffer containing the sound */ /** The buffer containing the sound */
private int buffer; private int buffer;
private int source;
/** /**
* Create a new sound * Create a new sound
* *
@ -22,30 +20,30 @@ public class Sound extends Entity{
*/ */
public Sound(String name, String ref) { public Sound(String name, String ref) {
super(name); super(name);
try { this.buffer = SoundLoader.getInstnace().loadSound(ref);
this.buffer = SoundLoader.getInstnace().loadSound(ref);
} catch (IOException e) {
MultiPrintStream.out.println("Unable to load sound: "+ref+" - "+e.getMessage());
e.printStackTrace();
}
} }
/** /**
* Play this sound as a sound effect * Play this sound as a sound effect
*/ */
public void play() { public void play() {
SoundLoader.getInstnace().playSound(buffer, getLocation(),false); source = SoundLoader.getInstnace().playSound(buffer, true);
update();
} }
/** /**
* Loop this sound * Loop this sound
*/ */
public void loop() { public void loop() {
SoundLoader.getInstnace().playSound(buffer, getLocation(),true); SoundLoader.getInstnace().playSound(buffer, true);
update();
} }
public void update() { public void update() {
//AL10.alSource(source.get(0), AL10.AL_POSITION, sourcePos); //AL10.alSource(source.get(0), AL10.AL_POSITION, sourcePos);
SoundLoader.getInstnace().setSoundLocation(
source, getLocation().getX(),getLocation().getY(),0);
} }
/** /**

View file

@ -3,15 +3,16 @@ package ei.engine.sound;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.nio.IntBuffer; import java.nio.IntBuffer;
import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import org.lwjgl.BufferUtils; import org.lwjgl.BufferUtils;
import org.lwjgl.Sys; import org.lwjgl.Sys;
import org.lwjgl.openal.AL; import org.lwjgl.openal.AL;
import org.lwjgl.openal.AL10; import org.lwjgl.openal.AL10;
import org.lwjgl.openal.OpenALException;
import org.lwjgl.util.WaveData; import org.lwjgl.util.WaveData;
import ei.engine.math.Vector2f;
import ei.engine.sound.decoders.OggData; import ei.engine.sound.decoders.OggData;
import ei.engine.sound.decoders.OggDecoder; import ei.engine.sound.decoders.OggDecoder;
import ei.engine.util.MultiPrintStream; import ei.engine.util.MultiPrintStream;
@ -23,19 +24,18 @@ import ei.engine.util.MultiPrintStream;
* @author Ziver Koc * @author Ziver Koc
*/ */
public class SoundLoader { public class SoundLoader {
/** The number of sound sources enabled - default 8 */
public static final int MAX_SOURCES = 128;
/** The single instance of this class */ /** The single instance of this class */
private static SoundLoader instance = new SoundLoader(); private static SoundLoader instance = new SoundLoader();
/** True if sound effects are turned on */ /** True if sound effects are turned on */
private boolean soundsEnabled; private boolean soundsEnabled;
/** The number of sound sources enabled - default 8 */
private int sourceCount;
/** The map of references to IDs of previously loaded sounds */ /** The map of references to IDs of previously loaded sounds */
private HashMap<String, Integer> loaded = new HashMap<String, Integer>(); private HashMap<String, Integer> loaded = new HashMap<String, Integer>();
/** The OpenGL AL sound sources in use */ /** The OpenGL AL sound sources */
private IntBuffer sources; private ArrayList<Integer> sources = new ArrayList<Integer>();
/** The next source to be used for sound effects */
private int nextSource;
/** /**
* Create a new sound store * Create a new sound store
@ -72,18 +72,9 @@ public class SoundLoader {
soundsEnabled = true; soundsEnabled = true;
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
MultiPrintStream.out.println(e);
soundsEnabled = false; soundsEnabled = false;
} }
if (soundsEnabled) {
sourceCount = 8;
sources = BufferUtils.createIntBuffer(sourceCount);
AL10.alGenSources(sources);
if (AL10.alGetError() != AL10.AL_NO_ERROR) {
soundsEnabled = false;
}
}
} }
/** /**
@ -93,25 +84,86 @@ public class SoundLoader {
* @param buffer The ID of the buffer to play * @param buffer The ID of the buffer to play
* @param pitch The pitch to play at * @param pitch The pitch to play at
* @param gain The gain to play at * @param gain The gain to play at
* @return The id of the assigned source
*/ */
void playSound(int buffer, Vector2f pos, boolean loop) { public int playSound(int buffer, boolean loop) {
if (soundsEnabled) { if (soundsEnabled && buffer >= 0) {
nextSource++; int sourceId = getAvailableSource();
if (nextSource >= sourceCount) { if(sourceId >= 0){
nextSource = 1; MultiPrintStream.out.println("Playing sound: source="+sourceId+" buffer="+buffer);
stopSound(sourceId);
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;
} }
AL10.alSourceStop(sources.get(nextSource)); }
return -1;
AL10.alSourcei(sources.get(nextSource), AL10.AL_BUFFER, buffer); }
AL10.alSourcef(sources.get(nextSource), AL10.AL_PITCH, 1.0f);
AL10.alSourcef(sources.get(nextSource), AL10.AL_GAIN, 1.0f); /**
* Looks for a availablee source. Creates a source if
//specify where the sound is comming from by tree axes x,y and z * necessary
AL10.alSource3f(sources.get(nextSource), AL10.AL_POSITION, * @return The source id
pos.getX(), pos.getY(), 0); */
AL10.alSourcei(sources.get(nextSource), AL10.AL_LOOPING, (loop ? AL10.AL_TRUE : AL10.AL_FALSE) ); private int getAvailableSource(){
int source = -1;
AL10.alSourcePlay(sources.get(nextSource)); 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);
} }
} }
@ -122,7 +174,7 @@ public class SoundLoader {
* @return An integer value that represents the buffer -1 if sound is disabled * @return An integer value that represents the buffer -1 if sound is disabled
* @throws IOException Indicates a failure to load the sound file * @throws IOException Indicates a failure to load the sound file
*/ */
public int loadSound(String ref) throws IOException { public int loadSound(String ref){
if (!soundsEnabled) { if (!soundsEnabled) {
return -1; return -1;
} }
@ -132,7 +184,7 @@ public class SoundLoader {
buffer = ((Integer) loaded.get(ref)).intValue(); buffer = ((Integer) loaded.get(ref)).intValue();
} }
else { else {
MultiPrintStream.out.println("Loading: "+ref); MultiPrintStream.out.println("Loading sound: "+ref);
try { try {
IntBuffer buf = BufferUtils.createIntBuffer(1); IntBuffer buf = BufferUtils.createIntBuffer(1);
InputStream in = Thread.currentThread().getContextClassLoader().getResourceAsStream(ref); InputStream in = Thread.currentThread().getContextClassLoader().getResourceAsStream(ref);
@ -161,16 +213,13 @@ public class SoundLoader {
buffer = buf.get(0); buffer = buf.get(0);
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
Sys.alert("ERROR", "Failed to load: "+ref+" - "+e.getMessage());
MultiPrintStream.out.println("Failed to load: "+ref+" - "+e.getMessage()); MultiPrintStream.out.println("Failed to load: "+ref+" - "+e.getMessage());
soundsEnabled = false; soundsEnabled = false;
return -1; return -1;
} }
} }
if (buffer == -1) {
throw new IOException("Unable to load: "+ref);
}
return buffer; return buffer;
} }
@ -189,6 +238,29 @@ public class SoundLoader {
return ""; return "";
} }
} }
/**
* 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 * Get the single instance of this class