aboutsummaryrefslogtreecommitdiffstats
path: root/src/jake2/sound/lwjgl
diff options
context:
space:
mode:
authorCarsten Weisse <[email protected]>2006-10-26 22:02:56 +0000
committerCarsten Weisse <[email protected]>2006-10-26 22:02:56 +0000
commit08d5dc327ea642eeaac8d9ad3aa2bf1c0cbd1986 (patch)
tree1d4cb1375ec4a6afb0585f3a92a169633adb7bdc /src/jake2/sound/lwjgl
parent67f358ca73f408481f6ee7d32658d92be38585db (diff)
switch to lwjgl 1.0beta3 (sound and gfx tested on MacBook Pro)
Diffstat (limited to 'src/jake2/sound/lwjgl')
-rw-r--r--src/jake2/sound/lwjgl/Channel.java718
-rw-r--r--src/jake2/sound/lwjgl/LWJGLSoundImpl.java990
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));
+ }
}