diff options
author | Carsten Weisse <[email protected]> | 2006-10-26 22:02:56 +0000 |
---|---|---|
committer | Carsten Weisse <[email protected]> | 2006-10-26 22:02:56 +0000 |
commit | 08d5dc327ea642eeaac8d9ad3aa2bf1c0cbd1986 (patch) | |
tree | 1d4cb1375ec4a6afb0585f3a92a169633adb7bdc /src/jake2/sound | |
parent | 67f358ca73f408481f6ee7d32658d92be38585db (diff) |
switch to lwjgl 1.0beta3
(sound and gfx tested on MacBook Pro)
Diffstat (limited to 'src/jake2/sound')
-rw-r--r-- | src/jake2/sound/lwjgl/Channel.java | 718 | ||||
-rw-r--r-- | src/jake2/sound/lwjgl/LWJGLSoundImpl.java | 990 |
2 files changed, 829 insertions, 879 deletions
diff --git a/src/jake2/sound/lwjgl/Channel.java b/src/jake2/sound/lwjgl/Channel.java index c4ab42d..0ffe1a3 100644 --- a/src/jake2/sound/lwjgl/Channel.java +++ b/src/jake2/sound/lwjgl/Channel.java @@ -3,7 +3,7 @@ * * Copyright (C) 2003 * - * $Id: Channel.java,v 1.8 2005-12-04 20:56:26 cawe Exp $ + * $Id: Channel.java,v 1.9 2006-10-26 22:02:55 cawe Exp $ */ /* Copyright (C) 1997-2001 Id Software, Inc. @@ -23,7 +23,7 @@ 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; @@ -41,6 +41,7 @@ import java.util.Iterator; import java.util.Map; import org.lwjgl.openal.AL10; +import org.lwjgl.openal.OpenALException; /** * Channel @@ -49,393 +50,396 @@ import org.lwjgl.openal.AL10; */ 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 boolean isInitialized = false; - private static int numChannels; - + 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; - for (int i = 0; i < MAX_CHANNELS; i++) { - - AL10.alGenSources(tmp); - sourceId = tmp.get(0); - - // can't generate more sources - if (sourceId <= 0) 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_ABSOLUTE, AL10.AL_TRUE); - AL10.nalSourcefv(sourceId, AL10.AL_VELOCITY, NULLVECTOR, 0); - 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); - } - isInitialized = true; - 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(); - } + // 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; + for (int i = 0; i < MAX_CHANNELS; i++) { + + AL10.alGenSources(tmp); + sourceId = tmp.get(0); + + // can't generate more sources + if (sourceId <= 0) 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); } - - static void shutdown() { - AL10.alDeleteSources(sources); - numChannels = 0; - isInitialized = false; + 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"); + 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_ABSOLUTE, AL10.AL_TRUE); - - // free the last source - numChannels++; - streamingEnabled = false; - Com.DPrintf("streaming disabled\n"); + 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; + 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())); + 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); } - - 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; + samples.position(0); + samples.limit(count); + AL10.alBufferData(buffer.get(0), format, samples, rate); + AL10.alSourceQueueBuffers(source, buffer); - // looking for a free AL source - if (!ch.active) { - break; - } + 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); } - - 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; + 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 true; + return ch; + } } - - 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; + 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) { - 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.nalSourcefv(sourceId, AL10.AL_POSITION, sourceOrigin, 0); - AL10.alSourcePlay(sourceId); - ch.modified = false; - } else { - state = AL10.alGetSourcei(sourceId, AL10.AL_SOURCE_STATE); - if (state == AL10.AL_PLAYING) { - AL10.nalSourcefv(sourceId, AL10.AL_POSITION, sourceOrigin, 0); - } 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); + 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; } - 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(); + 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; + } } + } - static void convertVector(float[] from, FloatBuffer to) { - to.put(0, from[0]); - to.put(1, from[2]); - to.put(2, -from[1]); + /* + * 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; } - 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]); + 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]); + } + } diff --git a/src/jake2/sound/lwjgl/LWJGLSoundImpl.java b/src/jake2/sound/lwjgl/LWJGLSoundImpl.java index 8954d24..97270de 100644 --- a/src/jake2/sound/lwjgl/LWJGLSoundImpl.java +++ b/src/jake2/sound/lwjgl/LWJGLSoundImpl.java @@ -2,7 +2,7 @@ * LWJGLSoundImpl.java * Copyright (C) 2004 * - * $Id: LWJGLSoundImpl.java,v 1.8 2005-12-04 17:27:34 cawe Exp $ + * $Id: LWJGLSoundImpl.java,v 1.9 2006-10-26 22:02:55 cawe Exp $ */ package jake2.sound.lwjgl; @@ -15,13 +15,9 @@ import jake2.util.Lib; import jake2.util.Vargs; import java.nio.*; -import java.util.Random; - import org.lwjgl.LWJGLException; import org.lwjgl.openal.*; -import org.lwjgl.openal.eax.EAX; -import org.lwjgl.openal.eax.EAX20; -import org.lwjgl.openal.eax.EAXListenerProperties; + /** * LWJGLSoundImpl @@ -29,577 +25,527 @@ import org.lwjgl.openal.eax.EAXListenerProperties; * @author dsanders/cwei */ public final class LWJGLSoundImpl implements Sound { - - static { - S.register(new LWJGLSoundImpl()); - }; - - private boolean hasEAX; - - private cvar_t s_volume; - - // the last 4 buffers are used for cinematics streaming + + static { + S.register(new LWJGLSoundImpl()); + }; + + private cvar_t s_volume; + + // the last 4 buffers are used for cinematics streaming private IntBuffer buffers = Lib.newIntBuffer(MAX_SFX + STREAM_QUEUE); - // singleton - private LWJGLSoundImpl() { - } + // singleton + private LWJGLSoundImpl() { + } - /* (non-Javadoc) - * @see jake2.sound.SoundImpl#Init() - */ - public boolean Init() { - - try { - initOpenAL(); - checkError(); - initOpenALExtensions(); - } catch (OpenALException e) { - Com.Printf(e.getMessage() + '\n'); - return false; - } catch (Exception e) { - Com.DPrintf(e.getMessage() + '\n'); - return false; - } - - // set the listerner (master) volume - s_volume = Cvar.Get("s_volume", "0.7", Defines.CVAR_ARCHIVE); - AL10.alGenBuffers(buffers); - int count = Channel.init(buffers); - Com.Printf("... using " + count + " channels\n"); - AL10.alDistanceModel(AL10.AL_INVERSE_DISTANCE_CLAMPED); - Cmd.AddCommand("play", new xcommand_t() { - public void execute() { - Play(); - } - }); - Cmd.AddCommand("stopsound", new xcommand_t() { - public void execute() { - StopAllSounds(); - } - }); - Cmd.AddCommand("soundlist", new xcommand_t() { - public void execute() { - SoundList(); - } - }); - Cmd.AddCommand("soundinfo", new xcommand_t() { - public void execute() { - SoundInfo_f(); - } - }); - - num_sfx = 0; - - Com.Printf("sound sampling rate: 44100Hz\n"); + /* (non-Javadoc) + * @see jake2.sound.SoundImpl#Init() + */ + public boolean Init() { + + try { + initOpenAL(); + checkError(); + } catch (OpenALException e) { + Com.Printf(e.getMessage() + '\n'); + return false; + } catch (Exception e) { + Com.DPrintf(e.getMessage() + '\n'); + return false; + } + // set the listerner (master) volume + s_volume = Cvar.Get("s_volume", "0.7", Defines.CVAR_ARCHIVE); + AL10.alGenBuffers(buffers); + int count = Channel.init(buffers); + Com.Printf("... using " + count + " channels\n"); + AL10.alDistanceModel(AL10.AL_INVERSE_DISTANCE_CLAMPED); + Cmd.AddCommand("play", new xcommand_t() { + public void execute() { + Play(); + } + }); + Cmd.AddCommand("stopsound", new xcommand_t() { + public void execute() { StopAllSounds(); - Com.Printf("------------------------------------\n"); - return true; - } - - - private void initOpenAL() throws OpenALException - { - try { AL.create(); } catch (LWJGLException e) { throw new OpenALException(e); } - String deviceName = null; - - String os = System.getProperty("os.name"); - if (os.startsWith("Windows")) { - deviceName = "DirectSound3D"; - } - - String deviceSpecifier = ALC.alcGetString(ALC.ALC_DEVICE_SPECIFIER); - String defaultSpecifier = ALC.alcGetString(ALC.ALC_DEFAULT_DEVICE_SPECIFIER); - - Com.Printf(os + " using " + ((deviceName == null) ? defaultSpecifier : deviceName) + '\n'); - - // Check for an error. - if (ALC.alcGetError() != ALC.ALC_NO_ERROR) - { - Com.DPrintf("Error with SoundDevice"); - } - } - - private void initOpenALExtensions() throws OpenALException - { - if (AL10.alIsExtensionPresent("EAX2.0")) - { - try { - EAX.create(); - Com.Printf("... using EAX2.0\n"); - hasEAX=true; - } catch (LWJGLException e) { - Com.Printf("... can't create EAX2.0\n"); - hasEAX=false; - } - } - else - { - Com.Printf("... EAX2.0 not found\n"); - hasEAX=false; - } + } + }); + Cmd.AddCommand("soundlist", new xcommand_t() { + public void execute() { + SoundList(); + } + }); + Cmd.AddCommand("soundinfo", new xcommand_t() { + public void execute() { + SoundInfo_f(); + } + }); + + num_sfx = 0; + + Com.Printf("sound sampling rate: 44100Hz\n"); + + StopAllSounds(); + Com.Printf("------------------------------------\n"); + return true; + } + + + private void initOpenAL() throws OpenALException + { + try { AL.create(); } catch (LWJGLException e) { throw new OpenALException(e); } + String deviceName = null; + + String os = System.getProperty("os.name"); + if (os.startsWith("Windows")) { + deviceName = "DirectSound3D"; } - - - void exitOpenAL() + + String defaultSpecifier = ALC.alcGetString(ALC.ALC_DEFAULT_DEVICE_SPECIFIER); + + Com.Printf(os + " using " + ((deviceName == null) ? defaultSpecifier : deviceName) + '\n'); + + // Check for an error. + if (ALC.alcGetError() != ALC.ALC_NO_ERROR) { - // Release the EAX context. - if (hasEAX){ - EAX.destroy(); - } - // Release the context and the device. - AL.destroy(); - } - - // TODO check the sfx direct buffer size - // 2MB sfx buffer - private ByteBuffer sfxDataBuffer = Lib.newByteBuffer(2 * 1024 * 1024); - - /* (non-Javadoc) - * @see jake2.sound.SoundImpl#RegisterSound(jake2.sound.sfx_t) - */ - private void initBuffer(byte[] samples, int bufferId, int freq) { - ByteBuffer data = sfxDataBuffer.slice(); - data.put(samples).flip(); - AL10.alBufferData(buffers.get(bufferId), AL10.AL_FORMAT_MONO16, - data, freq); + Com.DPrintf("Error with SoundDevice"); } + } - private void checkError() { - Com.DPrintf("AL Error: " + alErrorString() +'\n'); - } - - private String alErrorString(){ - int error; - String message = ""; - if ((error = AL10.alGetError()) != AL10.AL_NO_ERROR) { - switch(error) { - case AL10.AL_INVALID_OPERATION: message = "invalid operation"; break; - case AL10.AL_INVALID_VALUE: message = "invalid value"; break; - case AL10.AL_INVALID_ENUM: message = "invalid enum"; break; - case AL10.AL_INVALID_NAME: message = "invalid name"; break; - default: message = "" + error; - } - } - return message; - } + void exitOpenAL() + { + AL.destroy(); + } - /* (non-Javadoc) - * @see jake2.sound.SoundImpl#Shutdown() - */ - public void Shutdown() { - StopAllSounds(); - Channel.shutdown(); - AL10.alDeleteBuffers(buffers); - exitOpenAL(); - - Cmd.RemoveCommand("play"); - Cmd.RemoveCommand("stopsound"); - Cmd.RemoveCommand("soundlist"); - Cmd.RemoveCommand("soundinfo"); - - // free all sounds - for (int i = 0; i < num_sfx; i++) { - if (known_sfx[i].name == null) - continue; - known_sfx[i].clear(); - } - num_sfx = 0; - } - - /* (non-Javadoc) - * @see jake2.sound.SoundImpl#StartSound(float[], int, int, jake2.sound.sfx_t, float, float, float) - */ - public void StartSound(float[] origin, int entnum, int entchannel, sfx_t sfx, float fvol, float attenuation, float timeofs) { - - if (sfx == null) - return; - - if (sfx.name.charAt(0) == '*') - sfx = RegisterSexedSound(Globals.cl_entities[entnum].current, sfx.name); - - if (LoadSound(sfx) == null) - return; // can't load sound + // TODO check the sfx direct buffer size + // 2MB sfx buffer + private ByteBuffer sfxDataBuffer = Lib.newByteBuffer(2 * 1024 * 1024); - if (attenuation != Defines.ATTN_STATIC) - attenuation *= 0.5f; + /* (non-Javadoc) + * @see jake2.sound.SoundImpl#RegisterSound(jake2.sound.sfx_t) + */ + private void initBuffer(byte[] samples, int bufferId, int freq) { + ByteBuffer data = sfxDataBuffer.slice(); + data.put(samples).flip(); + AL10.alBufferData(buffers.get(bufferId), AL10.AL_FORMAT_MONO16, + data, freq); + } - PlaySound.allocate(origin, entnum, entchannel, buffers.get(sfx.bufferId), fvol, attenuation, timeofs); - } - - private FloatBuffer listenerOrigin = Lib.newFloatBuffer(3); - private FloatBuffer listenerOrientation = Lib.newFloatBuffer(6); - - /* (non-Javadoc) - * @see jake2.sound.SoundImpl#Update(float[], float[], float[], float[]) - */ - public void Update(float[] origin, float[] forward, float[] right, float[] up) { - - Channel.convertVector(origin, listenerOrigin); - AL10.nalListenerfv(AL10.AL_POSITION, listenerOrigin, 0); - - Channel.convertOrientation(forward, up, listenerOrientation); - AL10.nalListenerfv(AL10.AL_ORIENTATION, listenerOrientation, 0); - - // set the master volume - AL10.alListenerf(AL10.AL_GAIN, s_volume.value); - - if (hasEAX){ - if ((GameBase.gi.pointcontents.pointcontents(origin)& Defines.MASK_WATER)!= 0) { - changeEnvironment(EAX20.EAX_ENVIRONMENT_UNDERWATER); - } else { - changeEnvironment(EAX20.EAX_ENVIRONMENT_GENERIC); - } - } - - Channel.addLoopSounds(); - Channel.addPlaySounds(); - Channel.playAllSounds(listenerOrigin); - } - - private IntBuffer eaxEnv = Lib.newIntBuffer(1); - private int currentEnv = EAX20.EAX_ENVIRONMENT_UNDERWATER; - - private void changeEnvironment(int env) { - if (env == currentEnv) return; - currentEnv = env; - eaxEnv.put(0, currentEnv); - EAX20.eaxSet(EAX20.LISTENER_GUID, EAXListenerProperties.EAXLISTENER_ENVIRONMENT | EAXListenerProperties.EAXLISTENER_DEFERRED, 0, eaxEnv, 4); - } + private void checkError() { + Com.DPrintf("AL Error: " + alErrorString() +'\n'); + } - /* (non-Javadoc) - * @see jake2.sound.SoundImpl#StopAllSounds() - */ - public void StopAllSounds() { - // mute the listener (master) - AL10.alListenerf(AL10.AL_GAIN, 0); - PlaySound.reset(); - Channel.reset(); + private String alErrorString(){ + int error; + String message = ""; + if ((error = AL10.alGetError()) != AL10.AL_NO_ERROR) { + switch(error) { + case AL10.AL_INVALID_OPERATION: message = "invalid operation"; break; + case AL10.AL_INVALID_VALUE: message = "invalid value"; break; + case AL10.AL_INVALID_ENUM: message = "invalid enum"; break; + case AL10.AL_INVALID_NAME: message = "invalid name"; break; + default: message = "" + error; + } } - - /* (non-Javadoc) - * @see jake2.sound.Sound#getName() - */ - public String getName() { - return "lwjgl"; + return message; + } + + /* (non-Javadoc) + * @see jake2.sound.SoundImpl#Shutdown() + */ + public void Shutdown() { + StopAllSounds(); + Channel.shutdown(); + AL10.alDeleteBuffers(buffers); + exitOpenAL(); + + Cmd.RemoveCommand("play"); + Cmd.RemoveCommand("stopsound"); + Cmd.RemoveCommand("soundlist"); + Cmd.RemoveCommand("soundinfo"); + + // free all sounds + for (int i = 0; i < num_sfx; i++) { + if (known_sfx[i].name == null) + continue; + known_sfx[i].clear(); } + num_sfx = 0; + } + + /* (non-Javadoc) + * @see jake2.sound.SoundImpl#StartSound(float[], int, int, jake2.sound.sfx_t, float, float, float) + */ + public void StartSound(float[] origin, int entnum, int entchannel, sfx_t sfx, float fvol, float attenuation, float timeofs) { + + if (sfx == null) + return; + + if (sfx.name.charAt(0) == '*') + sfx = RegisterSexedSound(Globals.cl_entities[entnum].current, sfx.name); + + if (LoadSound(sfx) == null) + return; // can't load sound + + if (attenuation != Defines.ATTN_STATIC) + attenuation *= 0.5f; + + PlaySound.allocate(origin, entnum, entchannel, buffers.get(sfx.bufferId), fvol, attenuation, timeofs); + } + + private FloatBuffer listenerOrigin = Lib.newFloatBuffer(3); + private FloatBuffer listenerOrientation = Lib.newFloatBuffer(6); + + /* (non-Javadoc) + * @see jake2.sound.SoundImpl#Update(float[], float[], float[], float[]) + */ + public void Update(float[] origin, float[] forward, float[] right, float[] up) { + + Channel.convertVector(origin, listenerOrigin); + AL10.alListener(AL10.AL_POSITION, listenerOrigin); + + Channel.convertOrientation(forward, up, listenerOrientation); + AL10.alListener(AL10.AL_ORIENTATION, listenerOrientation); - int s_registration_sequence; - boolean s_registering; + // set the master volume + AL10.alListenerf(AL10.AL_GAIN, s_volume.value); - /* (non-Javadoc) - * @see jake2.sound.Sound#BeginRegistration() - */ - public void BeginRegistration() { - s_registration_sequence++; - s_registering = true; + Channel.addLoopSounds(); + Channel.addPlaySounds(); + Channel.playAllSounds(listenerOrigin); + } + + /* (non-Javadoc) + * @see jake2.sound.SoundImpl#StopAllSounds() + */ + public void StopAllSounds() { + // mute the listener (master) + AL10.alListenerf(AL10.AL_GAIN, 0); + PlaySound.reset(); + Channel.reset(); + } + + /* (non-Javadoc) + * @see jake2.sound.Sound#getName() + */ + public String getName() { + return "lwjgl"; + } + + int s_registration_sequence; + boolean s_registering; + + /* (non-Javadoc) + * @see jake2.sound.Sound#BeginRegistration() + */ + public void BeginRegistration() { + s_registration_sequence++; + s_registering = true; + } + + /* (non-Javadoc) + * @see jake2.sound.Sound#RegisterSound(java.lang.String) + */ + public sfx_t RegisterSound(String name) { + sfx_t sfx = FindName(name, true); + sfx.registration_sequence = s_registration_sequence; + + if (!s_registering) + LoadSound(sfx); + + return sfx; + } + + /* (non-Javadoc) + * @see jake2.sound.Sound#EndRegistration() + */ + public void EndRegistration() { + int i; + sfx_t sfx; + // free any sounds not from this registration sequence + for (i = 0; i < num_sfx; i++) { + sfx = known_sfx[i]; + if (sfx.name == null) + continue; + if (sfx.registration_sequence != s_registration_sequence) { + // don't need this sound + sfx.clear(); + } } - /* (non-Javadoc) - * @see jake2.sound.Sound#RegisterSound(java.lang.String) - */ - public sfx_t RegisterSound(String name) { - sfx_t sfx = FindName(name, true); - sfx.registration_sequence = s_registration_sequence; - - if (!s_registering) - LoadSound(sfx); - - return sfx; + // load everything in + for (i = 0; i < num_sfx; i++) { + sfx = known_sfx[i]; + if (sfx.name == null) + continue; + LoadSound(sfx); } - /* (non-Javadoc) - * @see jake2.sound.Sound#EndRegistration() - */ - public void EndRegistration() { - int i; - sfx_t sfx; - int size; - - // free any sounds not from this registration sequence - for (i = 0; i < num_sfx; i++) { - sfx = known_sfx[i]; - if (sfx.name == null) - continue; - if (sfx.registration_sequence != s_registration_sequence) { - // don't need this sound - sfx.clear(); - } - } - - // load everything in - for (i = 0; i < num_sfx; i++) { - sfx = known_sfx[i]; - if (sfx.name == null) - continue; - LoadSound(sfx); - } - - s_registering = false; + s_registering = false; + } + + sfx_t RegisterSexedSound(entity_state_t ent, String base) { + + sfx_t sfx = null; + + // determine what model the client is using + String model = null; + int n = Globals.CS_PLAYERSKINS + ent.number - 1; + if (Globals.cl.configstrings[n] != null) { + int p = Globals.cl.configstrings[n].indexOf('\\'); + if (p >= 0) { + p++; + model = Globals.cl.configstrings[n].substring(p); + //strcpy(model, p); + p = model.indexOf('/'); + if (p > 0) + model = model.substring(0, p); + } } - - sfx_t RegisterSexedSound(entity_state_t ent, String base) { - - sfx_t sfx = null; - - // determine what model the client is using - String model = null; - int n = Globals.CS_PLAYERSKINS + ent.number - 1; - if (Globals.cl.configstrings[n] != null) { - int p = Globals.cl.configstrings[n].indexOf('\\'); - if (p >= 0) { - p++; - model = Globals.cl.configstrings[n].substring(p); - //strcpy(model, p); - p = model.indexOf('/'); - if (p > 0) - model = model.substring(0, p); - } - } - // if we can't figure it out, they're male - if (model == null || model.length() == 0) - model = "male"; - - // see if we already know of the model specific sound - String sexedFilename = "#players/" + model + "/" + base.substring(1); - //Com_sprintf (sexedFilename, sizeof(sexedFilename), "#players/%s/%s", model, base+1); - sfx = FindName(sexedFilename, false); - - if (sfx != null) return sfx; - - // - // fall back strategies - // - // not found , so see if it exists - if (FS.FileLength(sexedFilename.substring(1)) > 0) { - // yes, register it - return RegisterSound(sexedFilename); - } - // try it with the female sound in the pak0.pak - if (model.equalsIgnoreCase("female")) { - String femaleFilename = "player/female/" + base.substring(1); - if (FS.FileLength("sound/" + femaleFilename) > 0) - return AliasName(sexedFilename, femaleFilename); - } - // no chance, revert to the male sound in the pak0.pak - String maleFilename = "player/male/" + base.substring(1); - return AliasName(sexedFilename, maleFilename); + // if we can't figure it out, they're male + if (model == null || model.length() == 0) + model = "male"; + + // see if we already know of the model specific sound + String sexedFilename = "#players/" + model + "/" + base.substring(1); + //Com_sprintf (sexedFilename, sizeof(sexedFilename), "#players/%s/%s", model, base+1); + sfx = FindName(sexedFilename, false); + + if (sfx != null) return sfx; + + // + // fall back strategies + // + // not found , so see if it exists + if (FS.FileLength(sexedFilename.substring(1)) > 0) { + // yes, register it + return RegisterSound(sexedFilename); } - - - static sfx_t[] known_sfx = new sfx_t[MAX_SFX]; - static { - for (int i = 0; i< known_sfx.length; i++) - known_sfx[i] = new sfx_t(); + // try it with the female sound in the pak0.pak + if (model.equalsIgnoreCase("female")) { + String femaleFilename = "player/female/" + base.substring(1); + if (FS.FileLength("sound/" + femaleFilename) > 0) + return AliasName(sexedFilename, femaleFilename); } - static int num_sfx; - - sfx_t FindName(String name, boolean create) { - int i; - sfx_t sfx = null; - - if (name == null) - Com.Error(Defines.ERR_FATAL, "S_FindName: NULL\n"); - if (name.length() == 0) - Com.Error(Defines.ERR_FATAL, "S_FindName: empty name\n"); - - if (name.length() >= Defines.MAX_QPATH) - Com.Error(Defines.ERR_FATAL, "Sound name too long: " + name); - - // see if already loaded - for (i = 0; i < num_sfx; i++) - if (name.equals(known_sfx[i].name)) { - return known_sfx[i]; - } - - if (!create) - return null; - - // find a free sfx - for (i = 0; i < num_sfx; i++) - if (known_sfx[i].name == null) - // registration_sequence < s_registration_sequence) - break; - - if (i == num_sfx) { - if (num_sfx == MAX_SFX) - Com.Error(Defines.ERR_FATAL, "S_FindName: out of sfx_t"); - num_sfx++; - } - - sfx = known_sfx[i]; - sfx.clear(); - sfx.name = name; - sfx.registration_sequence = s_registration_sequence; - sfx.bufferId = i; + // no chance, revert to the male sound in the pak0.pak + String maleFilename = "player/male/" + base.substring(1); + return AliasName(sexedFilename, maleFilename); + } + - return sfx; + static sfx_t[] known_sfx = new sfx_t[MAX_SFX]; + static { + for (int i = 0; i< known_sfx.length; i++) + known_sfx[i] = new sfx_t(); + } + static int num_sfx; + + sfx_t FindName(String name, boolean create) { + int i; + sfx_t sfx = null; + + if (name == null) + Com.Error(Defines.ERR_FATAL, "S_FindName: NULL\n"); + if (name.length() == 0) + Com.Error(Defines.ERR_FATAL, "S_FindName: empty name\n"); + + if (name.length() >= Defines.MAX_QPATH) + Com.Error(Defines.ERR_FATAL, "Sound name too long: " + name); + + // see if already loaded + for (i = 0; i < num_sfx; i++) + if (name.equals(known_sfx[i].name)) { + return known_sfx[i]; + } + + if (!create) + return null; + + // find a free sfx + for (i = 0; i < num_sfx; i++) + if (known_sfx[i].name == null) + // registration_sequence < s_registration_sequence) + break; + + if (i == num_sfx) { + if (num_sfx == MAX_SFX) + Com.Error(Defines.ERR_FATAL, "S_FindName: out of sfx_t"); + num_sfx++; } - /* + sfx = known_sfx[i]; + sfx.clear(); + sfx.name = name; + sfx.registration_sequence = s_registration_sequence; + sfx.bufferId = i; + + return sfx; + } + + /* ================== S_AliasName ================== - */ - sfx_t AliasName(String aliasname, String truename) - { - sfx_t sfx = null; - String s; - int i; - - s = new String(truename); - - // find a free sfx - for (i=0 ; i < num_sfx ; i++) - if (known_sfx[i].name == null) - break; - - if (i == num_sfx) - { - if (num_sfx == MAX_SFX) - Com.Error(Defines.ERR_FATAL, "S_FindName: out of sfx_t"); - num_sfx++; - } - - sfx = known_sfx[i]; - sfx.clear(); - sfx.name = new String(aliasname); - sfx.registration_sequence = s_registration_sequence; - sfx.truename = s; - // set the AL bufferId - sfx.bufferId = i; + */ + sfx_t AliasName(String aliasname, String truename) + { + sfx_t sfx = null; + String s; + int i; + + s = new String(truename); + + // find a free sfx + for (i=0 ; i < num_sfx ; i++) + if (known_sfx[i].name == null) + break; - return sfx; + if (i == num_sfx) + { + if (num_sfx == MAX_SFX) + Com.Error(Defines.ERR_FATAL, "S_FindName: out of sfx_t"); + num_sfx++; } - /* + sfx = known_sfx[i]; + sfx.clear(); + sfx.name = new String(aliasname); + sfx.registration_sequence = s_registration_sequence; + sfx.truename = s; + // set the AL bufferId + sfx.bufferId = i; + + return sfx; + } + + /* ============== S_LoadSound ============== - */ - public sfxcache_t LoadSound(sfx_t s) { - if (s.isCached) return s.cache; - sfxcache_t sc = WaveLoader.LoadSound(s); - if (sc != null) { - initBuffer(sc.data, s.bufferId, sc.speed); - s.isCached = true; - // free samples for GC - s.cache.data = null; - } - return sc; + */ + public sfxcache_t LoadSound(sfx_t s) { + if (s.isCached) return s.cache; + sfxcache_t sc = WaveLoader.LoadSound(s); + if (sc != null) { + initBuffer(sc.data, s.bufferId, sc.speed); + s.isCached = true; + // free samples for GC + s.cache.data = null; } + return sc; + } - /* (non-Javadoc) - * @see jake2.sound.Sound#StartLocalSound(java.lang.String) - */ - public void StartLocalSound(String sound) { - sfx_t sfx; - - sfx = RegisterSound(sound); - if (sfx == null) { - Com.Printf("S_StartLocalSound: can't cache " + sound + "\n"); - return; - } - StartSound(null, Globals.cl.playernum + 1, 0, sfx, 1, 1, 0); + /* (non-Javadoc) + * @see jake2.sound.Sound#StartLocalSound(java.lang.String) + */ + public void StartLocalSound(String sound) { + sfx_t sfx; + + sfx = RegisterSound(sound); + if (sfx == null) { + Com.Printf("S_StartLocalSound: can't cache " + sound + "\n"); + return; } + StartSound(null, Globals.cl.playernum + 1, 0, sfx, 1, 1, 0); + } private ShortBuffer streamBuffer = sfxDataBuffer.slice().order(ByteOrder.BIG_ENDIAN).asShortBuffer(); /* (non-Javadoc) - * @see jake2.sound.Sound#RawSamples(int, int, int, int, byte[]) - */ - public void RawSamples(int samples, int rate, int width, int channels, ByteBuffer data) { - int format; - if (channels == 2) { - format = (width == 2) ? AL10.AL_FORMAT_STEREO16 - : AL10.AL_FORMAT_STEREO8; - } else { - format = (width == 2) ? AL10.AL_FORMAT_MONO16 - : AL10.AL_FORMAT_MONO8; - } - - // convert to signed 16 bit samples - if (format == AL10.AL_FORMAT_MONO8) { - ShortBuffer sampleData = streamBuffer; - int value; - for (int i = 0; i < samples; i++) { - value = (data.get(i) & 0xFF) - 128; - sampleData.put(i, (short) value); - } - format = AL10.AL_FORMAT_MONO16; - width = 2; - data = sfxDataBuffer.slice(); - } - - Channel.updateStream(data, samples * channels * width, format, rate); + * @see jake2.sound.Sound#RawSamples(int, int, int, int, byte[]) + */ + public void RawSamples(int samples, int rate, int width, int channels, ByteBuffer data) { + int format; + if (channels == 2) { + format = (width == 2) ? AL10.AL_FORMAT_STEREO16 + : AL10.AL_FORMAT_STEREO8; + } else { + format = (width == 2) ? AL10.AL_FORMAT_MONO16 + : AL10.AL_FORMAT_MONO8; + } + + // convert to signed 16 bit samples + if (format == AL10.AL_FORMAT_MONO8) { + ShortBuffer sampleData = streamBuffer; + int value; + for (int i = 0; i < samples; i++) { + value = (data.get(i) & 0xFF) - 128; + sampleData.put(i, (short) value); + } + format = AL10.AL_FORMAT_MONO16; + width = 2; + data = sfxDataBuffer.slice(); } - + + Channel.updateStream(data, samples * channels * width, format, rate); + } + public void disableStreaming() { - Channel.disableStreaming(); + Channel.disableStreaming(); } - /* + /* =============================================================================== console functions =============================================================================== - */ - - void Play() { - int i; - String name; - sfx_t sfx; - - i = 1; - while (i < Cmd.Argc()) { - name = new String(Cmd.Argv(i)); - if (name.indexOf('.') == -1) - name += ".wav"; - - sfx = RegisterSound(name); - StartSound(null, Globals.cl.playernum + 1, 0, sfx, 1.0f, 1.0f, 0.0f); - i++; - } + */ + + void Play() { + int i; + String name; + sfx_t sfx; + + i = 1; + while (i < Cmd.Argc()) { + name = new String(Cmd.Argv(i)); + if (name.indexOf('.') == -1) + name += ".wav"; + + sfx = RegisterSound(name); + StartSound(null, Globals.cl.playernum + 1, 0, sfx, 1.0f, 1.0f, 0.0f); + i++; } + } - void SoundList() { - int i; - sfx_t sfx; - sfxcache_t sc; - int size, total; - - total = 0; - for (i = 0; i < num_sfx; i++) { - sfx = known_sfx[i]; - if (sfx.registration_sequence == 0) - continue; - sc = sfx.cache; - if (sc != null) { - size = sc.length * sc.width * (sc.stereo + 1); - total += size; - if (sc.loopstart >= 0) - Com.Printf("L"); - else - Com.Printf(" "); - Com.Printf("(%2db) %6i : %s\n", new Vargs(3).add(sc.width * 8).add(size).add(sfx.name)); - } else { - if (sfx.name.charAt(0) == '*') - Com.Printf(" placeholder : " + sfx.name + "\n"); - else - Com.Printf(" not loaded : " + sfx.name + "\n"); - } - } - Com.Printf("Total resident: " + total + "\n"); + void SoundList() { + int i; + sfx_t sfx; + sfxcache_t sc; + int size, total; + + total = 0; + for (i = 0; i < num_sfx; i++) { + sfx = known_sfx[i]; + if (sfx.registration_sequence == 0) + continue; + sc = sfx.cache; + if (sc != null) { + size = sc.length * sc.width * (sc.stereo + 1); + total += size; + if (sc.loopstart >= 0) + Com.Printf("L"); + else + Com.Printf(" "); + Com.Printf("(%2db) %6i : %s\n", new Vargs(3).add(sc.width * 8).add(size).add(sfx.name)); + } else { + if (sfx.name.charAt(0) == '*') + Com.Printf(" placeholder : " + sfx.name + "\n"); + else + Com.Printf(" not loaded : " + sfx.name + "\n"); + } } - - void SoundInfo_f() { + Com.Printf("Total resident: " + total + "\n"); + } - Com.Printf("%5d stereo\n", new Vargs(1).add(1)); - Com.Printf("%5d samples\n", new Vargs(1).add(22050)); - Com.Printf("%5d samplebits\n", new Vargs(1).add(16)); - Com.Printf("%5d speed\n", new Vargs(1).add(44100)); - } + void SoundInfo_f() { + + Com.Printf("%5d stereo\n", new Vargs(1).add(1)); + Com.Printf("%5d samples\n", new Vargs(1).add(22050)); + Com.Printf("%5d samplebits\n", new Vargs(1).add(16)); + Com.Printf("%5d speed\n", new Vargs(1).add(44100)); + } } |