From 635d756429822b24ebf0e5eeb7961b1a8c4f202e Mon Sep 17 00:00:00 2001 From: Ziver Koc Date: Fri, 16 Mar 2007 19:16:00 +0000 Subject: [PATCH] New better sound support --- src/ei/engine/math/Vector2f.java | 9 ++ src/ei/engine/sound/Sound.java | 22 ++-- src/ei/engine/sound/SoundLoader.java | 152 ++++++++++++++++++++------- 3 files changed, 131 insertions(+), 52 deletions(-) diff --git a/src/ei/engine/math/Vector2f.java b/src/ei/engine/math/Vector2f.java index af4f8e7..0a8ea32 100644 --- a/src/ei/engine/math/Vector2f.java +++ b/src/ei/engine/math/Vector2f.java @@ -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+"]"; } diff --git a/src/ei/engine/sound/Sound.java b/src/ei/engine/sound/Sound.java index c2aa4fc..14716f1 100644 --- a/src/ei/engine/sound/Sound.java +++ b/src/ei/engine/sound/Sound.java @@ -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); + } /** diff --git a/src/ei/engine/sound/SoundLoader.java b/src/ei/engine/sound/SoundLoader.java index 7106121..bf35644 100644 --- a/src/ei/engine/sound/SoundLoader.java +++ b/src/ei/engine/sound/SoundLoader.java @@ -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 loaded = new HashMap(); - /** 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 sources = new ArrayList(); + /** * 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= 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