From dccd35ef294c1b67f5d0e38d4eaa31ffe2ef7cfa Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 25 Apr 2015 10:26:14 +0200 Subject: [PATCH] - uncoupled OpenAL music updates from UpdateSounds. UpdateSounds will not be called during screen wipes and the entire setup of this function suggests that this is not advisable at all. The OpenAL stream updates were done deep inside this function implicitly. This caused music to stop while a wipe was in progress. So in order to allow uninterrupted music playback during screen wipes the music updates need to be handled separately from sound updates and be called both in the main loop and the wipe loop. I think that the OpenAL music updating should be offloaded to a separate thread but at least it's working now without causing interruptions during wipes. --- src/d_main.cpp | 2 ++ src/s_sound.cpp | 46 +++++++++++++++++++++++++++--------------- src/s_sound.h | 1 + src/sound/i_sound.h | 1 + src/sound/oalsound.cpp | 11 ++++++---- src/sound/oalsound.h | 1 + 6 files changed, 42 insertions(+), 20 deletions(-) diff --git a/src/d_main.cpp b/src/d_main.cpp index 9b46d42c23..9ddc17cd58 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -905,6 +905,7 @@ void D_Display () } while (diff < 1); wipestart = nowtime; done = screen->WipeDo (1); + S_UpdateMusic(); // OpenAL needs this to keep the music running, thanks to a complete lack of a sane streaming implementation using callbacks. :( C_DrawConsole (hw2d); // console and M_Drawer (); // menu are drawn even on top of wipes screen->Update (); // page flip or blit buffer @@ -1003,6 +1004,7 @@ void D_DoomLoop () // Update display, next frame, with current state. I_StartTic (); D_Display (); + S_UpdateMusic(); // OpenAL needs this to keep the music running, thanks to a complete lack of a sane streaming implementation using callbacks. :( } catch (CRecoverableError &error) { diff --git a/src/s_sound.cpp b/src/s_sound.cpp index 316f31a2ea..3c820ff009 100644 --- a/src/s_sound.cpp +++ b/src/s_sound.cpp @@ -1914,29 +1914,32 @@ void S_UpdateSounds (AActor *listenactor) S_ActivatePlayList(false); } - // should never happen - S_SetListener(listener, listenactor); - - for (FSoundChan *chan = Channels; chan != NULL; chan = chan->NextChan) + if (listenactor != NULL) { - if ((chan->ChanFlags & (CHAN_EVICTED | CHAN_IS3D)) == CHAN_IS3D) + // should never happen + S_SetListener(listener, listenactor); + + for (FSoundChan *chan = Channels; chan != NULL; chan = chan->NextChan) { - CalcPosVel(chan, &pos, &vel); - GSnd->UpdateSoundParams3D(&listener, chan, !!(chan->ChanFlags & CHAN_AREA), pos, vel); + if ((chan->ChanFlags & (CHAN_EVICTED | CHAN_IS3D)) == CHAN_IS3D) + { + CalcPosVel(chan, &pos, &vel); + GSnd->UpdateSoundParams3D(&listener, chan, !!(chan->ChanFlags & CHAN_AREA), pos, vel); + } + chan->ChanFlags &= ~CHAN_JUSTSTARTED; } - chan->ChanFlags &= ~CHAN_JUSTSTARTED; - } - SN_UpdateActiveSequences(); + SN_UpdateActiveSequences(); - GSnd->UpdateListener(&listener); - GSnd->UpdateSounds(); + GSnd->UpdateListener(&listener); + GSnd->UpdateSounds(); - if (level.time >= RestartEvictionsAt) - { - RestartEvictionsAt = 0; - S_RestoreEvictedChannels(); + if (level.time >= RestartEvictionsAt) + { + RestartEvictionsAt = 0; + S_RestoreEvictedChannels(); + } } } @@ -2605,6 +2608,17 @@ void S_StopMusic (bool force) } } +//========================================================================== +// +// +// +//========================================================================== + +void S_UpdateMusic() +{ + GSnd->UpdateMusic(); +} + //========================================================================== // // CCMD playsound diff --git a/src/s_sound.h b/src/s_sound.h index 71b770cbca..49fb81fb35 100644 --- a/src/s_sound.h +++ b/src/s_sound.h @@ -329,6 +329,7 @@ int S_GetMusic (char **name); // Stops the music for sure. void S_StopMusic (bool force); +void S_UpdateMusic(); // Stop and resume music, during game PAUSE. void S_PauseSound (bool notmusic, bool notsfx); diff --git a/src/sound/i_sound.h b/src/sound/i_sound.h index 29dd947f05..ab8ec2964b 100644 --- a/src/sound/i_sound.h +++ b/src/sound/i_sound.h @@ -149,6 +149,7 @@ public: virtual void UpdateListener (SoundListener *) = 0; virtual void UpdateSounds () = 0; + virtual void UpdateMusic() {} virtual bool IsValid () = 0; virtual void PrintStatus () = 0; diff --git a/src/sound/oalsound.cpp b/src/sound/oalsound.cpp index 3ff95851fe..c4f46b95e8 100644 --- a/src/sound/oalsound.cpp +++ b/src/sound/oalsound.cpp @@ -1624,10 +1624,6 @@ void OpenALSoundRenderer::UpdateSounds() { alProcessUpdatesSOFT(); - // For some reason this isn't being called? - for(uint32 i = 0;i < Streams.Size();++i) - Streams[i]->IsEnded(); - if(ALC.EXT_disconnect) { ALCint connected = ALC_TRUE; @@ -1644,6 +1640,13 @@ void OpenALSoundRenderer::UpdateSounds() PurgeStoppedSources(); } +void OpenALSoundRenderer::UpdateMusic() +{ + // For some reason this isn't being called? + for(uint32 i = 0;i < Streams.Size();++i) + Streams[i]->IsEnded(); +} + bool OpenALSoundRenderer::IsValid() { return Device != NULL; diff --git a/src/sound/oalsound.h b/src/sound/oalsound.h index 8c92707248..9ae2db7b20 100644 --- a/src/sound/oalsound.h +++ b/src/sound/oalsound.h @@ -111,6 +111,7 @@ public: virtual void UpdateListener(SoundListener *); virtual void UpdateSounds(); + virtual void UpdateMusic(); virtual void MarkStartTime(FISoundChannel*); virtual float GetAudibility(FISoundChannel*);