package org.newdawn.slick.openal; import org.lwjgl.openal.AL10; import org.lwjgl.openal.AL11; /** * A sound that can be played through OpenAL * * @author Kevin Glass * @author Nathan Sweet <misc@n4te.com> */ public class AudioImpl implements Audio { /** The store from which this sound was loaded */ protected SoundStore store; /** The buffer containing the sound */ protected int buffer; /** The index of the source being used to play this sound */ protected int index = -1; /** The length of the audio */ protected float length; /** * Create a new sound * * @param store The sound store from which the sound was created * @param buffer The buffer containing the sound data */ AudioImpl(SoundStore store, int buffer) { this.store = store; this.buffer = buffer; int bytes = AL10.alGetBufferi(buffer, AL10.AL_SIZE); int bits = AL10.alGetBufferi(buffer, AL10.AL_BITS); int channels = AL10.alGetBufferi(buffer, AL10.AL_CHANNELS); int freq = AL10.alGetBufferi(buffer, AL10.AL_FREQUENCY); int samples = bytes / (bits / 8); length = (samples / (float) freq) / channels; } /** * Calls stop() and releases this buffer from memory. For music, this will * stop the source, remove any queued buffers, and close the stream. * For sound, this will stop the source and release the buffer contained by * the Sound. */ public void release() { int oldIndex = index; stop(); if (oldIndex!=-1) //detach buffer from source AL10.alSourcei(SoundStore.get().getSource(oldIndex), AL10.AL_BUFFER, 0); //delete buffer if (buffer!=0) AL10.alDeleteBuffers(buffer); index = -1; buffer = 0; } /** * Get the ID of the OpenAL buffer holding this data (if any). This method * is not valid with streaming resources. * * If the source has been released, this will return zero. * * @return The ID of the OpenAL buffer holding this data */ public int getBufferID() { return buffer; } /** * Returns the index of the source found in the SoundStore; * the source ID can then be retrieved with SoundStore.getSource(). * This may be -1 if the sound is not attached to a source. * @return the last attached source */ protected int getSourceIndex() { return index; } /** * */ protected AudioImpl() { } /** * @see org.newdawn.slick.openal.Audio#stop() */ public void stop() { if (index != -1) { store.stopSource(index); index = -1; } } /** * @see org.newdawn.slick.openal.Audio#isPlaying() */ public boolean isPlaying() { if (index != -1) { return SoundStore.get().isPlaying(index); } return false; } /** * Returns true if this audio has a source attached and that source * is currently paused. * @return true if paused */ public boolean isPaused() { if (index != -1) return SoundStore.get().isPaused(index); return false; } /** * @see org.newdawn.slick.openal.Audio#playAsSoundEffect(float, float, boolean) */ public int playAsSoundEffect(float pitch, float gain, boolean loop) { if (buffer==0) return 0; index = store.playAsSound(buffer, pitch, gain, loop); return store.getSource(index); } /** * @see org.newdawn.slick.openal.Audio#playAsSoundEffect(float, float, boolean, float, float, float) */ public int playAsSoundEffect(float pitch, float gain, boolean loop, float x, float y, float z) { if (buffer==0) return 0; index = store.playAsSoundAt(buffer, pitch, gain, loop, x, y, z); return store.getSource(index); } /** * @see org.newdawn.slick.openal.Audio#playAsMusic(float, float, boolean) */ public int playAsMusic(float pitch, float gain, boolean loop) { if (buffer==0) return 0; store.playAsMusic(buffer, pitch, gain, loop); index = 0; return store.getSource(0); } /** * Pause the music currently being played */ public static void pauseMusic() { SoundStore.get().pauseLoop(); } /** * Restart the music currently being paused */ public static void restartMusic() { SoundStore.get().restartLoop(); } /** * @see org.newdawn.slick.openal.Audio#setPosition(float) */ public boolean setPosition(float position) { position = position % length; AL10.alSourcef(store.getSource(index), AL11.AL_SEC_OFFSET, position); if (AL10.alGetError() != 0) { return false; } return true; } /** * @see org.newdawn.slick.openal.Audio#getPosition() */ public float getPosition() { return AL10.alGetSourcef(store.getSource(index), AL11.AL_SEC_OFFSET); } }