diff options
| author | tma <tma@edf5b092-35ff-0310-97b2-ce42778d08ea> | 2005-12-01 18:22:42 +0000 | 
|---|---|---|
| committer | tma <tma@edf5b092-35ff-0310-97b2-ce42778d08ea> | 2005-12-01 18:22:42 +0000 | 
| commit | f6613ea144c6ddcbf744b3929d2a175da2b6223d (patch) | |
| tree | b9ac6e9b603fb6e920be5b5af7e6898bd5d3a8ed | |
| parent | 0e8301fcb4fc0e69cc759b9c3c7a802067fd1f1d (diff) | |
| download | ioquake3-aero-f6613ea144c6ddcbf744b3929d2a175da2b6223d.tar.gz ioquake3-aero-f6613ea144c6ddcbf744b3929d2a175da2b6223d.zip | |
* 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
git-svn-id: svn://svn.icculus.org/quake3/trunk@400 edf5b092-35ff-0310-97b2-ce42778d08ea
| -rw-r--r-- | code/client/snd_openal.c | 243 | 
1 files changed, 121 insertions, 122 deletions
| diff --git a/code/client/snd_openal.c b/code/client/snd_openal.c index 8e4cbdb..a04ac7e 100644 --- a/code/client/snd_openal.c +++ b/code/client/snd_openal.c @@ -114,7 +114,7 @@ static qboolean alBuffersInitialised = qfalse;  // 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 @@ Find a sound effect if loaded, set up a handle otherwise  */  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 @@ static sfxHandle_t S_AL_BufferFind(const char *filename)  		}  	} -	// Not found in hash table? +	// Not found in table?  	if(sfx == -1)  	{  		alSfx_t *ptr; @@ -403,7 +403,7 @@ sfxHandle_t S_AL_RegisterSound( const char *sample, qboolean compressed )  {  	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 @@ ALuint S_AL_BufferGet(sfxHandle_t sfx)  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 src_t srcList[MAX_SRC];  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							srcAllocated; // If a src_t has been allocated to this entity +	int							srcIndex; -	int has_sfx;		// Associated sound source -	int sfx; -	int touched;		// Sound present this update? +	qboolean				loopAddedThisFrame; +	alSrcPriority_t	loopPriority; +	sfxHandle_t			loopSfx; +	qboolean				startLoopingSound;  } sentity_t;  static sentity_t entityList[MAX_GENTITIES]; @@ -479,7 +481,7 @@ qboolean S_AL_SrcInit( void )  	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 @@ qboolean S_AL_SrcInit( void )  	// 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 @@ void S_AL_SrcShutdown( void )  		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 @@ static void S_AL_SrcSetup(srcHandle_t src, sfxHandle_t sfx, alSrcPriority_t prio  	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 @@ static void S_AL_SrcKill(srcHandle_t src)  	// 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 @@ srcHandle_t S_AL_SrcAlloc( alSrcPriority_t priority, int entnum, int channel )  	// 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 @@ void S_AL_StartLocalSound(sfxHandle_t sfx, int channel)  	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 @@ void S_AL_StartSound( vec3_t origin, int entnum, int entchannel, sfxHandle_t sfx  	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 @@ void S_AL_ClearLoopingSounds( qboolean killall )  	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 @@ S_AL_SrcLoop  =================  */  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; -	} -	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; +		} + +		sent->startLoopingSound = 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; - -		// Set up the entity -		entityList[entnum].has_sfx = qtrue; -		entityList[entnum].sfx = src; -		need_to_play = qtrue; -	} +	sent->srcAllocated = qtrue; +	sent->srcIndex = src; -	// 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); +	sent->loopPriority = priority; +	sent->loopSfx = sfx; + +	// 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 @@ S_AL_StopLoopingSound  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 @@ static  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); - -		ent = srcList[i].entity; +			qalSourcef(srcList[i].alSource, AL_REFERENCE_DISTANCE, s_alMinDistance->value); -		// 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 @@ S_AL_SrcGet  static  ALuint S_AL_SrcGet(srcHandle_t src)  { -	return srcList[src].source; +	return srcList[src].alSource;  } @@ -1042,24 +1057,10 @@ static  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 @@ void S_AL_Respatialize( int entityNum, const vec3_t origin, vec3_t axis[3], int  	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 @@ qboolean S_AL_Init( soundInterface_t *si )  	}  	// 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 ); | 
