r400 - trunk/code/client
DONOTREPLY at icculus.org
DONOTREPLY at icculus.org
Thu Dec 1 13:22:42 EST 2005
Author: tma
Date: 2005-12-01 13:22:42 -0500 (Thu, 01 Dec 2005)
New Revision: 400
Modified:
trunk/code/client/snd_openal.c
Log:
* Fixed bug where if two looping sounds were added to a single entity they
would fight for a source and you'd get a horrible distorted sound that was
each of the two sounds interleaved
* Changed the default of s_alPrecache to 1 -- having it off seems to cause
problems for some and it doesn't actually improve things much
* Changed a few of the variable names in snd_openal.c to be more sane
Modified: trunk/code/client/snd_openal.c
===================================================================
--- trunk/code/client/snd_openal.c 2005-12-01 18:01:43 UTC (rev 399)
+++ trunk/code/client/snd_openal.c 2005-12-01 18:22:42 UTC (rev 400)
@@ -114,7 +114,7 @@
// Sound effect storage, data structures
#define MAX_SFX 4096
static alSfx_t knownSfx[MAX_SFX];
-static int numSfx;
+static int numSfx = 0;
static sfxHandle_t default_sfx;
@@ -150,7 +150,7 @@
*/
static sfxHandle_t S_AL_BufferFind(const char *filename)
{
- // Look it up in the hash table
+ // Look it up in the table
sfxHandle_t sfx = -1;
int i;
@@ -163,7 +163,7 @@
}
}
- // Not found in hash table?
+ // Not found in table?
if(sfx == -1)
{
alSfx_t *ptr;
@@ -403,7 +403,7 @@
{
sfxHandle_t sfx = S_AL_BufferFind(sample);
- if((s_alPrecache->integer == 1) && (!knownSfx[sfx].inMemory) && (!knownSfx[sfx].isDefault))
+ if( s_alPrecache->integer && (!knownSfx[sfx].inMemory) && (!knownSfx[sfx].isDefault))
S_AL_BufferLoad(sfx);
knownSfx[sfx].used = Com_Milliseconds();
@@ -429,7 +429,7 @@
typedef struct src_s
{
- ALuint source; // OpenAL source object
+ ALuint alSource; // OpenAL source object
sfxHandle_t sfx; // Sound effect in use
int lastUse; // Last time used
@@ -450,15 +450,17 @@
static int srcCount = 0;
static qboolean alSourcesInitialised = qfalse;
-static int ambientCount = 0;
-
typedef struct sentity_s
{
- vec3_t origin; // Object position
+ vec3_t origin;
- int has_sfx; // Associated sound source
- int sfx;
- int touched; // Sound present this update?
+ int srcAllocated; // If a src_t has been allocated to this entity
+ int srcIndex;
+
+ qboolean loopAddedThisFrame;
+ alSrcPriority_t loopPriority;
+ sfxHandle_t loopSfx;
+ qboolean startLoopingSound;
} sentity_t;
static sentity_t entityList[MAX_GENTITIES];
@@ -479,7 +481,7 @@
memset(srcList, 0, sizeof(srcList));
srcCount = 0;
- // Cap s_sources to MAX_SRC
+ // Cap s_alSources to MAX_SRC
limit = s_alSources->integer;
if(limit > MAX_SRC)
limit = MAX_SRC;
@@ -489,7 +491,7 @@
// Allocate as many sources as possible
for(i = 0; i < limit; i++)
{
- qalGenSources(1, &srcList[i].source);
+ qalGenSources(1, &srcList[i].alSource);
if((error = qalGetError()) != AL_NO_ERROR)
break;
srcCount++;
@@ -520,8 +522,8 @@
if(srcList[i].isLocked)
Com_DPrintf( S_COLOR_YELLOW "WARNING: Source %d is locked\n", i);
- qalSourceStop(srcList[i].source);
- qalDeleteSources(1, &srcList[i].source);
+ qalSourceStop(srcList[i].alSource);
+ qalDeleteSources(1, &srcList[i].alSource);
}
memset(srcList, 0, sizeof(srcList));
@@ -557,23 +559,23 @@
srcList[src].local = local;
// Set up OpenAL source
- qalSourcei(srcList[src].source, AL_BUFFER, buffer);
- qalSourcef(srcList[src].source, AL_PITCH, 1.0f);
- qalSourcef(srcList[src].source, AL_GAIN, s_alGain->value * s_volume->value);
- qalSourcefv(srcList[src].source, AL_POSITION, null_vector);
- qalSourcefv(srcList[src].source, AL_VELOCITY, null_vector);
- qalSourcei(srcList[src].source, AL_LOOPING, AL_FALSE);
- qalSourcef(srcList[src].source, AL_REFERENCE_DISTANCE, s_alMinDistance->value);
+ qalSourcei(srcList[src].alSource, AL_BUFFER, buffer);
+ qalSourcef(srcList[src].alSource, AL_PITCH, 1.0f);
+ qalSourcef(srcList[src].alSource, AL_GAIN, s_alGain->value * s_volume->value);
+ qalSourcefv(srcList[src].alSource, AL_POSITION, null_vector);
+ qalSourcefv(srcList[src].alSource, AL_VELOCITY, null_vector);
+ qalSourcei(srcList[src].alSource, AL_LOOPING, AL_FALSE);
+ qalSourcef(srcList[src].alSource, AL_REFERENCE_DISTANCE, s_alMinDistance->value);
if(local)
{
- qalSourcei(srcList[src].source, AL_SOURCE_RELATIVE, AL_TRUE);
- qalSourcef(srcList[src].source, AL_ROLLOFF_FACTOR, 0);
+ qalSourcei(srcList[src].alSource, AL_SOURCE_RELATIVE, AL_TRUE);
+ qalSourcef(srcList[src].alSource, AL_ROLLOFF_FACTOR, 0);
}
else
{
- qalSourcei(srcList[src].source, AL_SOURCE_RELATIVE, AL_FALSE);
- qalSourcef(srcList[src].source, AL_ROLLOFF_FACTOR, s_alRolloff->value);
+ qalSourcei(srcList[src].alSource, AL_SOURCE_RELATIVE, AL_FALSE);
+ qalSourcef(srcList[src].alSource, AL_ROLLOFF_FACTOR, s_alRolloff->value);
}
}
@@ -590,19 +592,20 @@
// Stop it if it's playing
if(srcList[src].isActive)
- qalSourceStop(srcList[src].source);
+ qalSourceStop(srcList[src].alSource);
// Remove the entity association
if((srcList[src].isLooping) && (srcList[src].entity != -1))
{
int ent = srcList[src].entity;
- entityList[ent].has_sfx = 0;
- entityList[ent].sfx = -1;
- entityList[ent].touched = qfalse;
+ entityList[ent].srcAllocated = qfalse;
+ entityList[ent].srcIndex = -1;
+ entityList[ent].loopAddedThisFrame = qfalse;
+ entityList[ent].startLoopingSound = qfalse;
}
// Remove the buffer
- qalSourcei(srcList[src].source, AL_BUFFER, 0);
+ qalSourcei(srcList[src].alSource, AL_BUFFER, 0);
srcList[src].sfx = 0;
srcList[src].lastUse = 0;
@@ -660,7 +663,10 @@
// Do we have an empty one?
if(empty != -1)
+ {
+ S_AL_SrcKill( empty );
return empty;
+ }
// No. How about an overridable one?
if(weakest != -1)
@@ -755,11 +761,9 @@
S_AL_SrcSetup(src, sfx, SRCPRI_LOCAL, -1, channel, qtrue);
// Start it playing
- qalSourcePlay(srcList[src].source);
+ qalSourcePlay(srcList[src].alSource);
}
-#define POSITION_SCALE 1.0f
-
/*
=================
S_AL_StartSound
@@ -783,14 +787,14 @@
if(origin == NULL)
{
srcList[src].isTracking = qtrue;
- VectorScale(entityList[entnum].origin, POSITION_SCALE, sorigin);
+ VectorCopy( entityList[entnum].origin, sorigin );
}
else
- VectorScale(origin, POSITION_SCALE, sorigin);
- qalSourcefv(srcList[src].source, AL_POSITION, sorigin);
+ VectorCopy( origin, sorigin );
+ qalSourcefv(srcList[src].alSource, AL_POSITION, sorigin);
// Start it playing
- qalSourcePlay(srcList[src].source);
+ qalSourcePlay(srcList[src].alSource);
}
/*
@@ -805,7 +809,7 @@
for(i = 0; i < srcCount; i++)
{
if((srcList[i].isLooping) && (srcList[i].entity != -1))
- entityList[srcList[i].entity].touched = qfalse;
+ entityList[srcList[i].entity].loopAddedThisFrame = qfalse;
}
}
@@ -815,56 +819,48 @@
=================
*/
static void S_AL_SrcLoop( alSrcPriority_t priority, sfxHandle_t sfx,
- const vec3_t origin, const vec3_t velocity, int entnum)
+ const vec3_t origin, const vec3_t velocity, int entityNum )
{
- int src;
- qboolean need_to_play = qfalse;
- vec3_t sorigin;
+ int src;
+ sentity_t *sent = &entityList[ entityNum ];
- // Do we need to start a new sound playing?
- if(!entityList[entnum].has_sfx)
+ // Do we need to allocate a new source for this entity
+ if( !sent->srcAllocated )
{
// Try to get a channel
- ambientCount++;
- src = S_AL_SrcAlloc(priority, entnum, -1);
- if(src == -1)
+ src = S_AL_SrcAlloc( priority, entityNum, -1 );
+ if( src == -1 )
+ {
+ Com_Printf( S_COLOR_RED "ERROR: Failed to allocate source "
+ "for loop sfx %d on entity %d\n", sfx, entityNum );
return;
- need_to_play = qtrue;
+ }
+
+ sent->startLoopingSound = qtrue;
}
- else if(srcList[entityList[entnum].sfx].sfx != sfx)
- {
- // Need to restart. Just re-use this channel
- src = entityList[entnum].sfx;
- S_AL_SrcKill(src);
- need_to_play = qtrue;
- }
else
- src = entityList[entnum].sfx;
+ src = sent->srcIndex;
- if(need_to_play)
- {
- // Set up the effect
- S_AL_SrcSetup(src, sfx, priority, entnum, -1, qfalse);
- qalSourcei(srcList[src].source, AL_LOOPING, AL_TRUE);
- srcList[src].isLooping = qtrue;
+ sent->srcAllocated = qtrue;
+ sent->srcIndex = src;
- // Set up the entity
- entityList[entnum].has_sfx = qtrue;
- entityList[entnum].sfx = src;
- need_to_play = qtrue;
- }
+ sent->loopPriority = priority;
+ sent->loopSfx = sfx;
- // Set up the position and velocity
- VectorScale(entityList[entnum].origin, POSITION_SCALE, sorigin);
- qalSourcefv(srcList[src].source, AL_POSITION, (ALfloat *)sorigin);
- qalSourcefv(srcList[src].source, AL_VELOCITY, (ALfloat *)velocity);
+ // If this is not set then the looping sound is removed
+ sent->loopAddedThisFrame = qtrue;
- // Flag it
- entityList[entnum].touched = qtrue;
+ // UGH
+ // These lines should be called via S_AL_SrcSetup, but we
+ // can't call that yet as it buffers sfxes that may change
+ // with subsequent calls to S_AL_SrcLoop
+ srcList[ src ].entity = entityNum;
+ srcList[ src ].isLooping = qtrue;
+ srcList[ src ].isActive = qtrue;
- // Play if need be
- if(need_to_play)
- qalSourcePlay(srcList[src].source);
+ // Set up the position and velocity
+ qalSourcefv( srcList[ src ].alSource, AL_POSITION, (ALfloat *)sent->origin );
+ qalSourcefv( srcList[ src ].alSource, AL_VELOCITY, (ALfloat *)velocity );
}
/*
@@ -897,8 +893,8 @@
static
void S_AL_StopLoopingSound(int entityNum )
{
- if(entityList[entityNum].has_sfx)
- S_AL_SrcKill(entityList[entityNum].sfx);
+ if(entityList[entityNum].srcAllocated)
+ S_AL_SrcKill(entityList[entityNum].srcIndex);
}
/*
@@ -912,52 +908,71 @@
void S_AL_SrcUpdate( void )
{
int i;
- int ent;
+ int entityNum;
ALint state;
for(i = 0; i < srcCount; i++)
{
+ entityNum = srcList[i].entity;
+
if(srcList[i].isLocked)
continue;
if(!srcList[i].isActive)
continue;
- // Check if it's done, and flag it
- qalGetSourcei(srcList[i].source, AL_SOURCE_STATE, &state);
- if(state == AL_STOPPED)
- {
- S_AL_SrcKill(i);
- continue;
- }
-
// Update source parameters
if((s_alGain->modified)||(s_volume->modified))
- qalSourcef(srcList[i].source, AL_GAIN, s_alGain->value * s_volume->value);
+ qalSourcef(srcList[i].alSource, AL_GAIN, s_alGain->value * s_volume->value);
if((s_alRolloff->modified)&&(!srcList[i].local))
- qalSourcef(srcList[i].source, AL_ROLLOFF_FACTOR, s_alRolloff->value);
+ qalSourcef(srcList[i].alSource, AL_ROLLOFF_FACTOR, s_alRolloff->value);
if(s_alMinDistance->modified)
- qalSourcef(srcList[i].source, AL_REFERENCE_DISTANCE, s_alMinDistance->value);
+ qalSourcef(srcList[i].alSource, AL_REFERENCE_DISTANCE, s_alMinDistance->value);
- ent = srcList[i].entity;
-
- // If a looping effect hasn't been touched this frame, kill it
- if(srcList[i].isLooping)
+ if( srcList[ i ].isLooping )
{
- if(!entityList[ent].touched)
+ sentity_t *sent = &entityList[ entityNum ];
+
+ // If a looping effect hasn't been touched this frame, kill it
+ if( sent->loopAddedThisFrame )
{
- ambientCount--;
- S_AL_SrcKill(i);
+ // The sound has changed without an intervening removal
+ if( srcList[ i ].isActive && !sent->startLoopingSound &&
+ srcList[ i ].sfx != sent->loopSfx )
+ {
+ qalSourceStop( srcList[ i ].alSource );
+ qalSourcei( srcList[ i ].alSource, AL_BUFFER, 0 );
+ sent->startLoopingSound = qtrue;
+ }
+
+ // Ths sound hasn't been started yet
+ if( sent->startLoopingSound )
+ {
+ S_AL_SrcSetup( i, sent->loopSfx, sent->loopPriority,
+ entityNum, -1, qfalse );
+ srcList[ i ].isLooping = qtrue;
+ qalSourcei( srcList[ i ].alSource, AL_LOOPING, AL_TRUE );
+ qalSourcePlay( srcList[ i ].alSource );
+
+ sent->startLoopingSound = qfalse;
+ }
}
+ else
+ S_AL_SrcKill( i );
+
continue;
}
// See if it needs to be moved
if(srcList[i].isTracking)
+ qalSourcefv(srcList[i].alSource, AL_POSITION, entityList[entityNum].origin);
+
+ // Check if it's done, and flag it
+ qalGetSourcei(srcList[i].alSource, AL_SOURCE_STATE, &state);
+ if(state == AL_STOPPED)
{
- vec3_t sorigin;
- VectorScale(entityList[ent].origin, POSITION_SCALE, sorigin);
- qalSourcefv(srcList[i].source, AL_POSITION, entityList[ent].origin);
+ S_AL_SrcKill(i);
+ continue;
}
}
}
@@ -983,7 +998,7 @@
static
ALuint S_AL_SrcGet(srcHandle_t src)
{
- return srcList[src].source;
+ return srcList[src].alSource;
}
@@ -1042,24 +1057,10 @@
void S_AL_RawSamples(int samples, int rate, int width, int channels, const byte *data, float volume)
{
ALuint buffer;
- ALuint format = AL_FORMAT_STEREO16;
+ ALuint format;
ALint state;
- // Work out AL format
- if(width == 1)
- {
- if(channels == 1)
- format = AL_FORMAT_MONO8;
- else if(channels == 2)
- format = AL_FORMAT_STEREO8;
- }
- else if(width == 2)
- {
- if(channels == 1)
- format = AL_FORMAT_MONO16;
- else if(channels == 2)
- format = AL_FORMAT_STEREO16;
- }
+ format = S_AL_Format( width, channels );
// Create the streamSource if necessary
if(streamSourceHandle == -1)
@@ -1408,10 +1409,8 @@
float velocity[] = {0.0f, 0.0f, 0.0f};
float orientation[] = {axis[0][0], axis[0][1], axis[0][2],
axis[2][0], axis[2][1], axis[2][2]};
- vec3_t sorigin;
// Set OpenAL listener paramaters
- VectorScale(origin, POSITION_SCALE, sorigin);
qalListenerfv(AL_POSITION, (ALfloat *)origin);
qalListenerfv(AL_VELOCITY, velocity);
qalListenerfv(AL_ORIENTATION, orientation);
@@ -1561,7 +1560,7 @@
}
// New console variables
- s_alPrecache = Cvar_Get( "s_alPrecache", "0", CVAR_ARCHIVE );
+ s_alPrecache = Cvar_Get( "s_alPrecache", "1", CVAR_ARCHIVE );
s_alGain = Cvar_Get( "s_alGain", "0.4", CVAR_ARCHIVE );
s_alSources = Cvar_Get( "s_alSources", "64", CVAR_ARCHIVE );
s_alDopplerFactor = Cvar_Get( "s_alDopplerFactor", "1.0", CVAR_ARCHIVE );
More information about the quake3-commits
mailing list