New better sound support
This commit is contained in:
parent
47de3ed661
commit
635d756429
3 changed files with 131 additions and 52 deletions
|
|
@ -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+"]";
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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,6 +10,7 @@ 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);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -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);
|
* Looks for a availablee source. Creates a source if
|
||||||
AL10.alSourcef(sources.get(nextSource), AL10.AL_GAIN, 1.0f);
|
* necessary
|
||||||
|
* @return The source id
|
||||||
|
*/
|
||||||
|
private int getAvailableSource(){
|
||||||
|
int source = -1;
|
||||||
|
MultiPrintStream.out.println("Sound sources: quantity="+sources.size());
|
||||||
|
|
||||||
//specify where the sound is comming from by tree axes x,y and z
|
//looking for a source that is not playing
|
||||||
AL10.alSource3f(sources.get(nextSource), AL10.AL_POSITION,
|
for(int i=0; i<sources.size() ;i++){
|
||||||
pos.getX(), pos.getY(), 0);
|
int state = AL10.alGetSourcei(sources.get(i), AL10.AL_SOURCE_STATE);
|
||||||
AL10.alSourcei(sources.get(nextSource), AL10.AL_LOOPING, (loop ? AL10.AL_TRUE : AL10.AL_FALSE) );
|
if(state != AL10.AL_PLAYING){
|
||||||
|
source = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
AL10.alSourcePlay(sources.get(nextSource));
|
//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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -190,6 +239,29 @@ 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
|
* Get the single instance of this class
|
||||||
*
|
*
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue