package sound; import java.io.IOException; import java.nio.ByteBuffer; import java.nio.FloatBuffer; import java.nio.IntBuffer; import org.lwjgl.BufferUtils; import org.lwjgl.LWJGLException; import org.lwjgl.openal.AL; import org.lwjgl.openal.AL10; public class Sound { /** Buffers hold sound data. */ public static IntBuffer buffer = BufferUtils.createIntBuffer(1); /** Sources are points emitting sound. */ IntBuffer source = BufferUtils.createIntBuffer(1); /** Buffer for Streaming files */ private ByteBuffer dataBuffer[] = new ByteBuffer[3]; /** Position of the source sound. */ FloatBuffer sourcePos = (FloatBuffer)BufferUtils.createFloatBuffer(3).put(new float[] { 0.0f, 0.0f, 0.0f }).rewind(); /** Velocity of the source sound. */ FloatBuffer sourceVel = (FloatBuffer)BufferUtils.createFloatBuffer(3).put(new float[] { 0.0f, 0.0f, 0.0f }).rewind(); /** Position of the listener. */ FloatBuffer listenerPos = (FloatBuffer)BufferUtils.createFloatBuffer(3).put(new float[] { 0.0f, 0.0f, 0.0f }).rewind(); /** Velocity of the listener. */ FloatBuffer listenerVel = (FloatBuffer)BufferUtils.createFloatBuffer(3).put(new float[] { 0.0f, 0.0f, 0.0f }).rewind(); /** Orientation of the listener. (first 3 elements are "at", second 3 are "up") */ FloatBuffer listenerOri = (FloatBuffer)BufferUtils.createFloatBuffer(6).put(new float[] { 0.0f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f }).rewind(); SoundLoader sound; public Sound(String path) throws IOException { for(int i = 0; i < dataBuffer.length; i++) { dataBuffer[i] = ByteBuffer.allocateDirect(4096); } loadALData(path); setListenerValues(); } /** * boolean LoadALData() * * This function will load our sample data from the disk using the Alut * utility and send the data into OpenAL as a buffer. A source is then * also created to play that buffer. * @throws IOException */ private void loadALData(String path) throws IOException { // Load wav data into a buffer. AL10.alGenBuffers(buffer); checkError(); if(path.endsWith("wav")) { //Loads the wave file from this class's package in your classpath sound = new WaveLoader(path); } // Bind the buffer with the source. AL10.alGenSources(source); checkError(); AL10.alSourcei(source.get(0), AL10.AL_BUFFER, buffer.get(0) ); AL10.alSourcef(source.get(0), AL10.AL_PITCH, 1.0f ); AL10.alSourcef(source.get(0), AL10.AL_GAIN, 1.0f ); AL10.alSource (source.get(0), AL10.AL_POSITION, sourcePos ); AL10.alSource (source.get(0), AL10.AL_VELOCITY, sourceVel ); checkError(); continuePlaying(); } private void continuePlaying() { while(sound.readCorrectly() && sound.read(dataBuffer[0]) != -1) { AL10.alBufferData(buffer.get(0), sound.getFormat(), dataBuffer[0], sound.getSampleRate()); } } private void checkError() { if(AL10.alGetError() != AL10.AL_NO_ERROR) System.err.println(AL10.AL_FALSE); } /** * void setListenerValues() * * We already defined certain values for the Listener, but we need * to tell OpenAL to use that data. This function does just that. */ public void setListenerValues() { AL10.alListener(AL10.AL_POSITION, listenerPos); AL10.alListener(AL10.AL_VELOCITY, listenerVel); AL10.alListener(AL10.AL_ORIENTATION, listenerOri); } /** * void killALData() * * We have allocated memory for our buffers and sources which needs * to be returned to the system. This function frees that memory. */ public void killALData() { AL10.alDeleteSources(source); AL10.alDeleteBuffers(buffer); } public static void main(String[] args) throws IOException { try { AL.create(); } catch (LWJGLException le) { le.printStackTrace(); return; } AL10.alGetError(); Sound one = new Sound("/tests/resources/sounds/seal16.wav"); one.play(); while(one.isPlaying()); one.killALData(); } public void play() { AL10.alSourcePlay(source.get(0)); } public void pause() { AL10.alSourcePause(source.get(0)); } public void stop() { AL10.alSourceStop(source.get(0)); } public boolean isPlaying() { return AL10.alGetSourcei(source.get(0), AL10.AL_SOURCE_STATE) == AL10.AL_PLAYING; } private class Streamer extends Thread { SoundLoader sl; public Streamer(SoundLoader sl) { this.sl = sl; } public void run() { } } }