From 8513d3b796133c22739c6395a020ef2a4b9b7bd3 Mon Sep 17 00:00:00 2001 From: molivier Date: Wed, 24 Mar 2004 08:06:56 +0000 Subject: [PATCH] Fixed the sounds not being advanced in time while not being listened. This is a long standing bug I think, it looks like the original Quake source code has it too, though I haven't tested. Each channel now remembers the last time it was painted, and so it can resume the play at the appropriate position if it missed some painting rounds. Also, added a check to avoid looped sounds being overridden when picking a channel. git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@4055 d7cf8633-e32d-0410-b094-e92efae38249 --- snd_dma.c | 18 +++++++++++++----- snd_mix.c | 33 +++++++++++++++++++++++++++++++-- sound.h | 3 ++- 3 files changed, 46 insertions(+), 8 deletions(-) diff --git a/snd_dma.c b/snd_dma.c index 48bbaf98..ed1de728 100644 --- a/snd_dma.c +++ b/snd_dma.c @@ -425,27 +425,33 @@ channel_t *SND_PickChannel(int entnum, int entchannel) int ch_idx; int first_to_die; int life_left; + channel_t* ch; // Check for replacement sound, or find the best one to replace first_to_die = -1; life_left = 0x7fffffff; for (ch_idx=NUM_AMBIENTS ; ch_idx < NUM_AMBIENTS + MAX_DYNAMIC_CHANNELS ; ch_idx++) { + ch = &channels[ch_idx]; if (entchannel != 0 // channel 0 never overrides - && channels[ch_idx].entnum == entnum - && (channels[ch_idx].entchannel == entchannel || entchannel == -1) ) + && ch->entnum == entnum + && (ch->entchannel == entchannel || entchannel == -1) ) { // always override sound from same entity first_to_die = ch_idx; break; } // don't let monster sounds override player sounds - if (channels[ch_idx].entnum == cl.viewentity && entnum != cl.viewentity && channels[ch_idx].sfx) + if (ch->entnum == cl.viewentity && entnum != cl.viewentity && ch->sfx) continue; - if (channels[ch_idx].end - paintedtime < life_left) + // don't override looped sounds + if (ch->forceloop || (ch->sfx != NULL && ch->sfx->loopstart >= 0)) + continue; + + if (ch->end - paintedtime < life_left) { - life_left = channels[ch_idx].end - paintedtime; + life_left = ch->end - paintedtime; first_to_die = ch_idx; } } @@ -556,6 +562,7 @@ void S_StartSound(int entnum, int entchannel, sfx_t *sfx, vec3_t origin, float f target_chan->sfx = sfx; target_chan->pos = 0.0; target_chan->end = paintedtime + sfx->total_length; + target_chan->lastptime = paintedtime; // if an identical sound has also been started this frame, offset the pos // a bit to keep it from just making the first one louder @@ -703,6 +710,7 @@ void S_StaticSound (sfx_t *sfx, vec3_t origin, float vol, float attenuation) ss->master_vol = vol; ss->dist_mult = (attenuation/64) / sound_nominal_clip_dist; ss->end = paintedtime + sfx->total_length; + ss->lastptime = paintedtime; SND_Spatialize (ss, true); } diff --git a/snd_mix.c b/snd_mix.c index 6bb06589..e9075ba8 100644 --- a/snd_mix.c +++ b/snd_mix.c @@ -290,8 +290,33 @@ void S_PaintChannels(int endtime) if (!S_LoadSound (sfx, true)) continue; - ltime = paintedtime; + // if the sound hasn't been painted last time, update his position + if (ch->lastptime < paintedtime) + { + ch->pos += paintedtime - ch->lastptime; + + // If the sound should have ended by then + if ((unsigned int)ch->pos > sfx->total_length) + { + int loopstart; + if (ch->forceloop) + loopstart = 0; + else + loopstart = -1; + if (sfx->loopstart >= 0) + loopstart = sfx->loopstart; + + // If the sound is looped + if (loopstart >= 0) + ch->pos = (ch->pos - sfx->total_length) % (sfx->total_length - loopstart) + loopstart; + else + ch->pos = sfx->total_length; + ch->end = paintedtime + sfx->total_length - ch->pos; + } + } + + ltime = paintedtime; while (ltime < end) { qboolean stop_paint; @@ -309,7 +334,11 @@ void S_PaintChannels(int endtime) else stop_paint = !SND_PaintChannelFrom16(ch, count); - ltime += count; + if (!stop_paint) + { + ltime += count; + ch->lastptime = ltime; + } } else stop_paint = false; diff --git a/sound.h b/sound.h index ffefe940..c25ef15c 100644 --- a/sound.h +++ b/sound.h @@ -78,7 +78,8 @@ typedef struct int leftvol; // 0-255 volume int rightvol; // 0-255 volume int end; // end time in global paintsamples - int pos; // sample position in sfx + int lastptime; // last time this channel was painted + int pos; // sample position in sfx int looping; // where to loop, -1 = no looping int entnum; // to allow overriding a specific sound int entchannel; -- 2.39.2