diff options
Diffstat (limited to 'src/jake2/sound/lwjgl/Channel.java')
-rw-r--r-- | src/jake2/sound/lwjgl/Channel.java | 450 |
1 files changed, 0 insertions, 450 deletions
diff --git a/src/jake2/sound/lwjgl/Channel.java b/src/jake2/sound/lwjgl/Channel.java deleted file mode 100644 index 05a2802..0000000 --- a/src/jake2/sound/lwjgl/Channel.java +++ /dev/null @@ -1,450 +0,0 @@ -/* - * Created on Jun 19, 2004 - * - * Copyright (C) 2003 - * - * $Id: Channel.java,v 1.12 2006-11-23 13:31:58 cawe Exp $ - */ -/* -Copyright (C) 1997-2001 Id Software, Inc. - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - - */ -package jake2.sound.lwjgl; - -import jake2.Defines; -import jake2.Globals; -import jake2.client.CL_ents; -import jake2.game.entity_state_t; -import jake2.qcommon.Com; -import jake2.sound.*; -import jake2.util.Lib; -import jake2.util.Math3D; - -import java.nio.*; -import java.util.Hashtable; -import java.util.Iterator; -import java.util.Map; - -import org.lwjgl.openal.AL10; -import org.lwjgl.openal.OpenALException; - -/** - * Channel - * - * @author dsanders/cwei - */ -public class Channel { - - final static int LISTENER = 0; - final static int FIXED = 1; - final static int DYNAMIC = 2; - final static int MAX_CHANNELS = 32; - private final static FloatBuffer NULLVECTOR = Lib.newFloatBuffer(3); - - private static Channel[] channels = new Channel[MAX_CHANNELS]; - private static IntBuffer sources = Lib.newIntBuffer(MAX_CHANNELS); - // a reference of L:WJGLSoundImpl.buffers - private static IntBuffer buffers; - private static Map looptable = new Hashtable(MAX_CHANNELS); - - private static int numChannels; - - // stream handling - private static boolean streamingEnabled = false; - private static int streamQueue = 0; - - // sound attributes - private int type; - private int entnum; - private int entchannel; - private int bufferId; - private int sourceId; - private float volume; - private float rolloff; - private float[] origin = {0, 0, 0}; - - // update flags - private boolean autosound; - private boolean active; - private boolean modified; - private boolean bufferChanged; - private boolean volumeChanged; - - private Channel(int sourceId) { - this.sourceId = sourceId; - clear(); - volumeChanged = false; - volume = 1.0f; - } - - private void clear() { - entnum = entchannel = bufferId = -1; - bufferChanged = false; - rolloff = 0; - autosound = false; - active = false; - modified = false; - } - - private static IntBuffer tmp = Lib.newIntBuffer(1); - - static int init(IntBuffer buffers) { - Channel.buffers = buffers; - // create channels - int sourceId; - numChannels = 0; - for (int i = 0; i < MAX_CHANNELS; i++) { - try { - AL10.alGenSources(tmp); - sourceId = tmp.get(0); - // can't generate more sources - if (sourceId <= 0) break; - } catch (OpenALException e) { - // can't generate more sources - break; - } - - sources.put(i, sourceId); - - channels[i] = new Channel(sourceId); - numChannels++; - - // set default values for AL sources - AL10.alSourcef (sourceId, AL10.AL_GAIN, 1.0f); - AL10.alSourcef (sourceId, AL10.AL_PITCH, 1.0f); - AL10.alSourcei (sourceId, AL10.AL_SOURCE_RELATIVE, AL10.AL_FALSE); - AL10.alSource(sourceId, AL10.AL_VELOCITY, NULLVECTOR); - AL10.alSourcei (sourceId, AL10.AL_LOOPING, AL10.AL_FALSE); - AL10.alSourcef (sourceId, AL10.AL_REFERENCE_DISTANCE, 200.0f); - AL10.alSourcef (sourceId, AL10.AL_MIN_GAIN, 0.0005f); - AL10.alSourcef (sourceId, AL10.AL_MAX_GAIN, 1.0f); - } - sources.limit(numChannels); - return numChannels; - } - - static void reset() { - for (int i = 0; i < numChannels; i++) { - AL10.alSourceStop(sources.get(i)); - AL10.alSourcei(sources.get(i), AL10.AL_BUFFER, 0); - channels[i].clear(); - } - } - - static void shutdown() { - AL10.alDeleteSources(sources); - numChannels = 0; - } - - static void enableStreaming() { - if (streamingEnabled) return; - - // use the last source - numChannels--; - streamingEnabled = true; - streamQueue = 0; - - int source = channels[numChannels].sourceId; - AL10.alSourcei (source, AL10.AL_SOURCE_RELATIVE, AL10.AL_TRUE); - AL10.alSourcef(source, AL10.AL_GAIN, 1.0f); - channels[numChannels].volumeChanged = true; - - Com.DPrintf("streaming enabled\n"); - } - - static void disableStreaming() { - if (!streamingEnabled) return; - unqueueStreams(); - int source = channels[numChannels].sourceId; - AL10.alSourcei (source, AL10.AL_SOURCE_RELATIVE, AL10.AL_FALSE); - - // free the last source - numChannels++; - streamingEnabled = false; - Com.DPrintf("streaming disabled\n"); - } - - static void unqueueStreams() { - if (!streamingEnabled) return; - int source = channels[numChannels].sourceId; - - // stop streaming - AL10.alSourceStop(source); - int count = AL10.alGetSourcei(source, AL10.AL_BUFFERS_QUEUED); - Com.DPrintf("unqueue " + count + " buffers\n"); - while (count-- > 0) { - AL10.alSourceUnqueueBuffers(source, tmp); - } - streamQueue = 0; - } - - static void updateStream(ByteBuffer samples, int count, int format, int rate) { - enableStreaming(); - int source = channels[numChannels].sourceId; - int processed = AL10.alGetSourcei(source, AL10.AL_BUFFERS_PROCESSED); - - boolean playing = (AL10.alGetSourcei(source, AL10.AL_SOURCE_STATE) == AL10.AL_PLAYING); - boolean interupted = !playing && streamQueue > 2; - - IntBuffer buffer = tmp; - if (interupted) { - unqueueStreams(); - buffer.put(0, buffers.get(Sound.MAX_SFX + streamQueue++)); - Com.DPrintf("queue " + (streamQueue - 1) + '\n'); - } else if (processed < 2) { - // check queue overrun - if (streamQueue >= Sound.STREAM_QUEUE) return; - buffer.put(0, buffers.get(Sound.MAX_SFX + streamQueue++)); - Com.DPrintf("queue " + (streamQueue - 1) + '\n'); - } else { - // reuse the buffer - AL10.alSourceUnqueueBuffers(source, buffer); - } - - samples.position(0); - samples.limit(count); - AL10.alBufferData(buffer.get(0), format, samples, rate); - AL10.alSourceQueueBuffers(source, buffer); - - if (streamQueue > 1 && !playing) { - Com.DPrintf("start sound\n"); - AL10.alSourcePlay(source); - } - } - - static void addPlaySounds() { - while (Channel.assign(PlaySound.nextPlayableSound())); - } - - private static boolean assign(PlaySound ps) { - if (ps == null) return false; - Channel ch = null; - int i; - for (i = 0; i < numChannels; i++) { - ch = channels[i]; - - if (ps.entchannel != 0 && ch.entnum == ps.entnum && ch.entchannel == ps.entchannel) { - // always override sound from same entity - if (ch.bufferId != ps.bufferId) { - AL10.alSourceStop(ch.sourceId); - } - break; - } - - // don't let monster sounds override player sounds - if ((ch.entnum == Globals.cl.playernum+1) && (ps.entnum != Globals.cl.playernum+1) && ch.bufferId != -1) - continue; - - // looking for a free AL source - if (!ch.active) { - break; - } - } - - if (i == numChannels) - return false; - - ch.type = ps.type; - if (ps.type == Channel.FIXED) - Math3D.VectorCopy(ps.origin, ch.origin); - ch.entnum = ps.entnum; - ch.entchannel = ps.entchannel; - ch.bufferChanged = (ch.bufferId != ps.bufferId); - ch.bufferId = ps.bufferId; - ch.rolloff = ps.attenuation * 2; - ch.volumeChanged = (ch.volume != ps.volume); - ch.volume = ps.volume; - ch.active = true; - ch.modified = true; - return true; - } - - private static Channel pickForLoop(int bufferId, float attenuation) { - Channel ch; - for (int i = 0; i < numChannels; i++) { - ch = channels[i]; - // looking for a free AL source - if (!ch.active) { - ch.entnum = 0; - ch.entchannel = 0; - ch.bufferChanged = (ch.bufferId != bufferId); - ch.bufferId = bufferId; - ch.volumeChanged = (ch.volume != 1.0f); - ch.volume = 1.0f; - ch.rolloff = attenuation * 2; - ch.active = true; - ch.modified = true; - return ch; - } - } - return null; - } - - private static FloatBuffer sourceOriginBuffer = Lib.newFloatBuffer(3); - - //stack variable - private static float[] entityOrigin = {0, 0, 0}; - - static void playAllSounds(FloatBuffer listenerOrigin) { - FloatBuffer sourceOrigin = sourceOriginBuffer; - Channel ch; - int sourceId; - int state; - - for (int i = 0; i < numChannels; i++) { - ch = channels[i]; - if (ch.active) { - sourceId = ch.sourceId; - switch (ch.type) { - case Channel.LISTENER: - sourceOrigin.put(0, listenerOrigin.get(0)); - sourceOrigin.put(1, listenerOrigin.get(1)); - sourceOrigin.put(2, listenerOrigin.get(2)); - break; - case Channel.DYNAMIC: - CL_ents.GetEntitySoundOrigin(ch.entnum, entityOrigin); - convertVector(entityOrigin, sourceOrigin); - break; - case Channel.FIXED: - convertVector(ch.origin, sourceOrigin); - break; - } - - if (ch.modified) { - if (ch.bufferChanged) { - try { - AL10.alSourcei(sourceId, AL10.AL_BUFFER, ch.bufferId); - } catch (OpenALException e) { - // fallback for buffer changing - AL10.alSourceStop(sourceId); - AL10.alSourcei(sourceId, AL10.AL_BUFFER, ch.bufferId); - } - } - if (ch.volumeChanged) { - AL10.alSourcef (sourceId, AL10.AL_GAIN, ch.volume); - } - AL10.alSourcef (sourceId, AL10.AL_ROLLOFF_FACTOR, ch.rolloff); - AL10.alSource(sourceId, AL10.AL_POSITION, sourceOrigin); - AL10.alSourcePlay(sourceId); - ch.modified = false; - } else { - state = AL10.alGetSourcei(sourceId, AL10.AL_SOURCE_STATE); - if (state == AL10.AL_PLAYING) { - AL10.alSource(sourceId, AL10.AL_POSITION, sourceOrigin); - } else { - ch.clear(); - } - } - ch.autosound = false; - } - } - } - - /* - * adddLoopSounds - * Entities with a ->sound field will generated looped sounds - * that are automatically started, stopped, and merged together - * as the entities are sent to the client - */ - static void addLoopSounds() { - - if ((Globals.cl_paused.value != 0.0f) || (Globals.cls.state != Globals.ca_active) || !Globals.cl.sound_prepped) { - removeUnusedLoopSounds(); - return; - } - - Channel ch; - sfx_t sfx; - sfxcache_t sc; - int num; - entity_state_t ent; - Object key; - int sound = 0; - - for (int i=0 ; i<Globals.cl.frame.num_entities ; i++) { - num = (Globals.cl.frame.parse_entities + i)&(Defines.MAX_PARSE_ENTITIES-1); - ent = Globals.cl_parse_entities[num]; - sound = ent.sound; - - if (sound == 0) continue; - - key = new Integer(ent.number); - ch = (Channel)looptable.get(key); - - if (ch != null) { - // keep on looping - ch.autosound = true; - Math3D.VectorCopy(ent.origin, ch.origin); - continue; - } - - sfx = Globals.cl.sound_precache[sound]; - if (sfx == null) - continue; // bad sound effect - - sc = sfx.cache; - if (sc == null) - continue; - - // allocate a channel - ch = Channel.pickForLoop(buffers.get(sfx.bufferId), 6); - if (ch == null) - break; - - ch.type = FIXED; - Math3D.VectorCopy(ent.origin, ch.origin); - ch.autosound = true; - - looptable.put(key, ch); - AL10.alSourcei(ch.sourceId, AL10.AL_LOOPING, AL10.AL_TRUE); - } - - removeUnusedLoopSounds(); - - } - - private static void removeUnusedLoopSounds() { - Channel ch; - // stop unused loopsounds - for (Iterator iter = looptable.values().iterator(); iter.hasNext();) { - ch = (Channel)iter.next(); - if (!ch.autosound) { - AL10.alSourceStop(ch.sourceId); - AL10.alSourcei(ch.sourceId, AL10.AL_LOOPING, AL10.AL_FALSE); - iter.remove(); - ch.clear(); - } - } - } - - static void convertVector(float[] from, FloatBuffer to) { - to.put(0, from[0]); - to.put(1, from[2]); - to.put(2, -from[1]); - } - - static void convertOrientation(float[] forward, float[] up, FloatBuffer orientation) { - orientation.put(0, forward[0]); - orientation.put(1, forward[2]); - orientation.put(2, -forward[1]); - orientation.put(3, up[0]); - orientation.put(4, up[2]); - orientation.put(5, -up[1]); - } - -} |