lwjgl/src/java/org/lwjgl/examples/spaceinvaders/SoundManager.java

190 lines
5.6 KiB
Java

/*
* Copyright (c) 2002-2008 LWJGL Project
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of 'LWJGL' nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.lwjgl.examples.spaceinvaders;
import java.nio.IntBuffer;
import org.lwjgl.BufferUtils;
import org.lwjgl.LWJGLException;
import org.lwjgl.openal.AL;
import org.lwjgl.openal.AL10;
import org.lwjgl.util.WaveData;
/**
* <p>
* Simple sound manager for OpenAL using n sources accessed in
* a round robin schedule. Source n is reserved for a single buffer and checking for
* whether it's playing.
* </p>
* @author Brian Matzon <brian@matzon.dk>
* @version $Revision$
* $Id$
*/
public class SoundManager {
/** We support at most 256 buffers*/
private int[] buffers = new int[256];
/** Number of sources is limited tby user (and hardware) */
private int[] sources;
/** Our internal scratch buffer */
private IntBuffer scratchBuffer = BufferUtils.createIntBuffer(256);
/** Whether we're running in no sound mode */
private boolean soundOutput;
/** Current index in our buffers */
private int bufferIndex;
/** Current index in our source list */
private int sourceIndex;
/**
* Creates a new SoundManager
*/
public SoundManager() {
}
/**
* Plays a sound effect
* @param buffer Buffer index to play gotten from addSound
*/
public void playEffect(int buffer) {
if(soundOutput) {
// make sure we never choose last channel, since it is used for special sounds
int channel = sources[(sourceIndex++ % (sources.length-1))];
// link buffer and source, and play it
AL10.alSourcei(channel, AL10.AL_BUFFER, buffers[buffer]);
AL10.alSourcePlay(channel);
}
}
/**
* Plays a sound on last source
* @param buffer Buffer index to play gotten from addSound
*/
public void playSound(int buffer) {
if(soundOutput) {
AL10.alSourcei(sources[sources.length-1], AL10.AL_BUFFER, buffers[buffer]);
AL10.alSourcePlay(sources[sources.length-1]);
}
}
/**
* Whether a sound is playing on last source
* @return true if a source is playing right now on source n
*/
public boolean isPlayingSound() {
return AL10.alGetSourcei(sources[sources.length-1], AL10.AL_SOURCE_STATE) == AL10.AL_PLAYING;
}
/**
* Initializes the SoundManager
*
* @param sources Number of sources to create
*/
public void initialize(int channels) {
try {
AL.create();
// allocate sources
scratchBuffer.limit(channels);
AL10.alGenSources(scratchBuffer);
scratchBuffer.rewind();
scratchBuffer.get(sources = new int[channels]);
// could we allocate all channels?
if(AL10.alGetError() != AL10.AL_NO_ERROR) {
throw new LWJGLException("Unable to allocate " + channels + " sources");
}
// we have sound
soundOutput = true;
} catch (LWJGLException le) {
le.printStackTrace();
System.out.println("Sound disabled");
}
}
/**
* Adds a sound to the Sound Managers pool
*
* @param path Path to file to load
* @return index into SoundManagers buffer list
*/
public int addSound(String path) {
// Generate 1 buffer entry
scratchBuffer.rewind().position(0).limit(1);
AL10.alGenBuffers(scratchBuffer);
buffers[bufferIndex] = scratchBuffer.get(0);
// load wave data from buffer
WaveData wavefile = WaveData.create("spaceinvaders/" + path);
// copy to buffers
AL10.alBufferData(buffers[bufferIndex], wavefile.format, wavefile.data, wavefile.samplerate);
// unload file again
wavefile.dispose();
// return index for this sound
return bufferIndex++;
}
/**
* Destroy this SoundManager
*/
public void destroy() {
if(soundOutput) {
// stop playing sounds
scratchBuffer.position(0).limit(sources.length);
scratchBuffer.put(sources).flip();
AL10.alSourceStop(scratchBuffer);
// destroy sources
AL10.alDeleteSources(scratchBuffer);
// destroy buffers
scratchBuffer.position(0).limit(bufferIndex);
scratchBuffer.put(buffers, 0, bufferIndex).flip();
AL10.alDeleteBuffers(scratchBuffer);
// destory OpenAL
AL.destroy();
}
}
}