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;
}
/**
* Add to the vectro
* @param i The amount to add
*/
public void add(Vector2f i){
x += i.getX();
y += i.getY();
}
public String toString(){
return "Vector2f["+x+","+y+"]";
}

View file

@ -1,9 +1,6 @@
package ei.engine.sound;
import java.io.IOException;
import ei.engine.scene.Entity;
import ei.engine.util.MultiPrintStream;
/**
* A sound that can be played through OpenAL
@ -13,7 +10,8 @@ import ei.engine.util.MultiPrintStream;
public class Sound extends Entity{
/** The buffer containing the sound */
private int buffer;
private int source;
/**
* Create a new sound
*
@ -22,30 +20,30 @@ public class Sound extends Entity{
*/
public Sound(String name, String ref) {
super(name);
try {
this.buffer = SoundLoader.getInstnace().loadSound(ref);
} catch (IOException e) {
MultiPrintStream.out.println("Unable to load sound: "+ref+" - "+e.getMessage());
e.printStackTrace();
}
this.buffer = SoundLoader.getInstnace().loadSound(ref);
}
/**
* Play this sound as a sound effect
*/
public void play() {
SoundLoader.getInstnace().playSound(buffer, getLocation(),false);
source = SoundLoader.getInstnace().playSound(buffer, true);
update();
}
/**
* Loop this sound
*/
public void loop() {
SoundLoader.getInstnace().playSound(buffer, getLocation(),true);
SoundLoader.getInstnace().playSound(buffer, true);
update();
}
public void update() {
//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.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.math.Vector2f;
import ei.engine.sound.decoders.OggData;
import ei.engine.sound.decoders.OggDecoder;
import ei.engine.util.MultiPrintStream;
@ -23,19 +24,18 @@ 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 number of sound sources enabled - default 8 */
private int sourceCount;
/** The map of references to IDs of previously loaded sounds */
private HashMap<String, Integer> loaded = new HashMap<String, Integer>();
/** The OpenGL AL sound sources in use */
private IntBuffer sources;
/** The next source to be used for sound effects */
private int nextSource;
/** The OpenGL AL sound sources */
private ArrayList<Integer> sources = new ArrayList<Integer>();
/**
* Create a new sound store
@ -72,18 +72,9 @@ public class SoundLoader {
soundsEnabled = true;
} catch (Exception e) {
e.printStackTrace();
MultiPrintStream.out.println(e);
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 pitch The pitch 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) {
if (soundsEnabled) {
nextSource++;
if (nextSource >= sourceCount) {
nextSource = 1;
public int playSound(int buffer, boolean loop) {
if (soundsEnabled && buffer >= 0) {
int sourceId = getAvailableSource();
if(sourceId >= 0){
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));
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);
//specify where the sound is comming from by tree axes x,y and z
AL10.alSource3f(sources.get(nextSource), AL10.AL_POSITION,
pos.getX(), pos.getY(), 0);
AL10.alSourcei(sources.get(nextSource), AL10.AL_LOOPING, (loop ? AL10.AL_TRUE : AL10.AL_FALSE) );
AL10.alSourcePlay(sources.get(nextSource));
}
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);
}
}
@ -122,7 +174,7 @@ public class SoundLoader {
* @return An integer value that represents the buffer -1 if sound is disabled
* @throws IOException Indicates a failure to load the sound file
*/
public int loadSound(String ref) throws IOException {
public int loadSound(String ref){
if (!soundsEnabled) {
return -1;
}
@ -132,7 +184,7 @@ public class SoundLoader {
buffer = ((Integer) loaded.get(ref)).intValue();
}
else {
MultiPrintStream.out.println("Loading: "+ref);
MultiPrintStream.out.println("Loading sound: "+ref);
try {
IntBuffer buf = BufferUtils.createIntBuffer(1);
InputStream in = Thread.currentThread().getContextClassLoader().getResourceAsStream(ref);
@ -161,16 +213,13 @@ public class SoundLoader {
buffer = buf.get(0);
} catch (Exception e) {
e.printStackTrace();
Sys.alert("ERROR", "Failed to load: "+ref+" - "+e.getMessage());
MultiPrintStream.out.println("Failed to load: "+ref+" - "+e.getMessage());
soundsEnabled = false;
return -1;
}
}
if (buffer == -1) {
throw new IOException("Unable to load: "+ref);
}
return buffer;
}
@ -189,6 +238,29 @@ public class SoundLoader {
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