From 0adae90465b159590460ad95cdd0eae59f70dfef Mon Sep 17 00:00:00 2001 From: Thilo Schulz Date: Mon, 26 Oct 2009 05:02:18 +0000 Subject: [PATCH] Fix another issue I didn't know about: cgame does not kill sound loops it startet, just stops sending the entity information for these loops. Changed it so that loops added with AddLoopingsound() are being killed again as soon as the entity to the source is not sent anymore. --- code/client/snd_openal.c | 119 +++++++++++++++++++++++---------------- 1 file changed, 69 insertions(+), 50 deletions(-) diff --git a/code/client/snd_openal.c b/code/client/snd_openal.c index a25a5c69..7e38054e 100644 --- a/code/client/snd_openal.c +++ b/code/client/snd_openal.c @@ -503,6 +503,7 @@ typedef struct src_s float lastTimePos; // On stopped loops, the last position in the buffer int lastSampleTime; // Time when this was stopped + vec3_t loopSpeakerPos; // Origin of the loop speaker qboolean local; // Is this local (relative to the cam) } src_t; @@ -581,8 +582,6 @@ static void S_AL_ScaleGain(src_t *chksrc, vec3_t origin) if(chksrc->scaleGain != scaleFactor); { chksrc->scaleGain = scaleFactor; - // if(scaleFactor > 0.0f) - // Com_Printf("%f\n", scaleFactor); qalSourcef(chksrc->alSource, AL_GAIN, chksrc->scaleGain); } } @@ -1134,6 +1133,10 @@ static void S_AL_SrcLoop( alSrcPriority_t priority, sfxHandle_t sfx, int src; sentity_t *sent = &entityList[ entityNum ]; src_t *curSource; + vec3_t sorigin, svelocity; + + if(S_AL_CheckInput(entityNum, sfx)) + return; // Do we need to allocate a new source for this entity if( !sent->srcAllocated ) @@ -1175,19 +1178,35 @@ static void S_AL_SrcLoop( alSrcPriority_t priority, sfxHandle_t sfx, { curSource->local = qtrue; - qalSourcefv( curSource->alSource, AL_POSITION, vec3_origin ); - qalSourcefv( curSource->alSource, AL_VELOCITY, vec3_origin ); + VectorClear(sorigin); + + qalSourcefv(curSource->alSource, AL_POSITION, sorigin); + qalSourcefv(curSource->alSource, AL_VELOCITY, sorigin); } else { curSource->local = qfalse; - qalSourcefv( curSource->alSource, AL_POSITION, (ALfloat *)sent->origin ); - qalSourcefv( curSource->alSource, AL_VELOCITY, (ALfloat *)velocity ); - - } + if(origin) + VectorCopy(origin, sorigin); + else + VectorCopy(sent->origin, sorigin); - S_AL_ScaleGain(curSource, sent->origin); + S_AL_SanitiseVector(sorigin); + + VectorCopy(sorigin, curSource->loopSpeakerPos); + + if(velocity) + { + VectorCopy(velocity, svelocity); + S_AL_SanitiseVector(svelocity); + } + else + VectorClear(svelocity); + + qalSourcefv( curSource->alSource, AL_POSITION, (ALfloat *)sorigin ); + qalSourcefv( curSource->alSource, AL_VELOCITY, (ALfloat *)velocity ); + } } /* @@ -1195,20 +1214,9 @@ static void S_AL_SrcLoop( alSrcPriority_t priority, sfxHandle_t sfx, S_AL_AddLoopingSound ================= */ -static -void S_AL_AddLoopingSound( int entityNum, const vec3_t origin, const vec3_t velocity, sfxHandle_t sfx ) +static void S_AL_AddLoopingSound(int entityNum, const vec3_t origin, const vec3_t velocity, sfxHandle_t sfx) { - vec3_t sanOrigin, sanVelocity; - - if(S_AL_CheckInput(entityNum, sfx)) - return; - - VectorCopy( origin, sanOrigin ); - VectorCopy( velocity, sanVelocity ); - S_AL_SanitiseVector( sanOrigin ); - S_AL_SanitiseVector( sanVelocity ); - - S_AL_SrcLoop(SRCPRI_ENTITY, sfx, sanOrigin, sanVelocity, entityNum); + S_AL_SrcLoop(SRCPRI_ENTITY, sfx, origin, velocity, entityNum); } /* @@ -1216,27 +1224,9 @@ void S_AL_AddLoopingSound( int entityNum, const vec3_t origin, const vec3_t velo S_AL_AddRealLoopingSound ================= */ -static -void S_AL_AddRealLoopingSound( int entityNum, const vec3_t origin, const vec3_t velocity, sfxHandle_t sfx ) +static void S_AL_AddRealLoopingSound(int entityNum, const vec3_t origin, const vec3_t velocity, sfxHandle_t sfx) { - vec3_t sanOrigin, sanVelocity; - - if(S_AL_CheckInput(entityNum, sfx)) - return; - - VectorCopy( origin, sanOrigin ); - VectorCopy( velocity, sanVelocity ); - S_AL_SanitiseVector( sanOrigin ); - S_AL_SanitiseVector( sanVelocity ); - - // There are certain maps (*cough* Q3:TA mpterra*) that have large quantities - // of ET_SPEAKERS in the PVS at any given time. OpenAL can't cope with mixing - // large numbers of sounds, so this culls them by distance - if( DistanceSquared( sanOrigin, lastListenerOrigin ) > (s_alMaxDistance->value + s_alGraceDistance->value) * - (s_alMaxDistance->value + s_alGraceDistance->value) ) - return; - - S_AL_SrcLoop(SRCPRI_AMBIENT, sfx, sanOrigin, sanVelocity, entityNum); + S_AL_SrcLoop(SRCPRI_AMBIENT, sfx, origin, velocity, entityNum); } /* @@ -1289,9 +1279,11 @@ void S_AL_SrcUpdate( void ) { sentity_t *sent = &entityList[ entityNum ]; - // If a looping effect hasn't been touched this frame, pause it + // If a looping effect hasn't been touched this frame, pause or kill it if(sent->loopAddedThisFrame) { + alSfx_t *curSfx; + // The sound has changed without an intervening removal if(curSource->isActive && !sent->startLoopingSound && curSource->sfx != sent->loopSfx) @@ -1315,10 +1307,32 @@ void S_AL_SrcUpdate( void ) sent->startLoopingSound = qfalse; } + curSfx = &knownSfx[curSource->sfx]; + + S_AL_ScaleGain(curSource, curSource->loopSpeakerPos); + if(!curSource->scaleGain) + { + if(curSource->isPlaying) + { + // Sound is mute, stop playback until we are in range again + S_AL_NewLoopMaster(curSource, qfalse); + qalSourceStop(curSource->alSource); + curSource->isPlaying = qfalse; + } + else if(!curSfx->loopActiveCnt && curSfx->masterLoopSrc < 0) + { + // There are no loops yet, make this one master + curSource->lastTimePos = 0; + curSource->lastSampleTime = Sys_Milliseconds(); + + curSfx->masterLoopSrc = i; + } + + continue; + } + if(!curSource->isPlaying) { - alSfx_t *curSfx = &knownSfx[curSource->sfx]; - // If there are other looping sources with the same sound, // make sure the sound of these sources are in sync. @@ -1339,7 +1353,7 @@ void S_AL_SrcUpdate( void ) // to calculate offset so the player thinks the sources continued playing while they were inaudible. secofs = master->lastTimePos + (Sys_Milliseconds() - master->lastSampleTime) / 1000.0f; - secofs = fmodf(secofs, curSfx->info.samples / curSfx->info.rate); + secofs = fmodf(secofs, (float) curSfx->info.samples / curSfx->info.rate); qalSourcef(curSource->alSource, AL_SEC_OFFSET, secofs); @@ -1369,12 +1383,17 @@ void S_AL_SrcUpdate( void ) } } - else if(curSource->isPlaying) + else if(curSource->priority == SRCPRI_AMBIENT) { - S_AL_NewLoopMaster(curSource, qfalse); - qalSourceStop(curSource->alSource); - curSource->isPlaying = qfalse; + if(curSource->isPlaying) + { + S_AL_NewLoopMaster(curSource, qfalse); + qalSourceStop(curSource->alSource); + curSource->isPlaying = qfalse; + } } + else + S_AL_SrcKill(i); continue; }