diff --git a/include/snd_render.h b/include/snd_render.h index 386a98ee8..78085adcc 100644 --- a/include/snd_render.h +++ b/include/snd_render.h @@ -298,8 +298,11 @@ struct channel_s *SND_AllocChannel (void); void SND_ChannelStop (channel_t *chan); /** Scan channels looking for stopped channels. + \param wait if true, wait for the channels to be done. if false, force the + channels to be done. true is for threaded, false for + non-threaded. */ -void SND_ScanChannels (void); +void SND_ScanChannels (int wait); /** Disable ambient sounds. \todo not used, remove? diff --git a/libs/audio/renderer/snd_channels.c b/libs/audio/renderer/snd_channels.c index 24fde331b..5d81d72bc 100644 --- a/libs/audio/renderer/snd_channels.c +++ b/libs/audio/renderer/snd_channels.c @@ -37,6 +37,9 @@ static __attribute__ ((used)) const char rcsid[] = #ifdef HAVE_STRINGS_H # include #endif +#ifdef HAVE_UNISTD_H +# include +#endif #include #include "QF/bspfile.h" @@ -92,7 +95,7 @@ SND_AllocChannel (void) while (*free) { if (!(*free)->sfx) // free channel break; - if ((*free)->done) // mixer is finished with this channel + if ((*free)->done) // mixer is finished with this channel break; if (!(*free)->stop) Sys_Error ("SND_AllocChannel: bogus channel free list"); @@ -135,20 +138,46 @@ SND_ChannelStop (channel_t *chan) } void -SND_ScanChannels (void) +SND_ScanChannels (int wait) { int i; channel_t *ch; int count = 0; - for (i = 0; i < MAX_CHANNELS; i++) { - ch = &snd_channels[i]; - if (ch->sfx && ch->stop && !ch->done) { - ch->done = 1; - count++; + if (wait) { + Sys_DPrintf ("scanning channels...\n"); + do { + count = 0; + for (i = 0; i < MAX_CHANNELS; i++) { + ch = &snd_channels[i]; + if (!ch->sfx || ch->done) + continue; + ch->stop = 1; + count++; + } + Sys_DPrintf ("count = %d\n", count); +#ifdef HAVE_USLEEP + usleep (1000); +#endif + } while (count); + Sys_DPrintf ("scanning done.\n"); + for (i = 0; i < MAX_CHANNELS; i++) { + ch = &snd_channels[i]; + if (!ch->sfx) + continue; + ch->sfx->release (ch->sfx); + ch->sfx = 0; } + } else { + for (i = 0; i < MAX_CHANNELS; i++) { + ch = &snd_channels[i]; + if (ch->sfx && ch->stop && !ch->done) { + ch->done = 1; + count++; + } + } + //printf ("count: %d\n", count); } - //printf ("count: %d\n", count); } void diff --git a/libs/audio/renderer/snd_dma.c b/libs/audio/renderer/snd_dma.c index b915b2771..9b4b8274b 100644 --- a/libs/audio/renderer/snd_dma.c +++ b/libs/audio/renderer/snd_dma.c @@ -204,6 +204,7 @@ static void s_stop_all_sounds (void) { SND_StopAllSounds (); + SND_ScanChannels (0); s_clear_buffer (); } @@ -279,7 +280,7 @@ s_update (const vec3_t origin, const vec3_t forward, const vec3_t right, // mix some sound s_update_ (); - SND_ScanChannels (); + SND_ScanChannels (0); } static void diff --git a/libs/audio/renderer/snd_jack.c b/libs/audio/renderer/snd_jack.c index 55ee41c2c..1b87d499e 100644 --- a/libs/audio/renderer/snd_jack.c +++ b/libs/audio/renderer/snd_jack.c @@ -56,6 +56,13 @@ static jack_port_t *jack_out[2]; static dma_t _snd_shm; static float *output[2]; +static void +s_stop_all_sounds (void) +{ + SND_StopAllSounds (); + SND_ScanChannels (1); +} + static void s_extra_update (void) { @@ -209,7 +216,7 @@ static snd_render_funcs_t plugin_info_render_funcs = { SND_StopSound, SND_PrecacheSound, SND_SetListener, - SND_StopAllSounds, + s_stop_all_sounds, s_extra_update, SND_LocalSound, s_block_sound,