From c65f707a206409f971b6350a9b0fcc39c6d76a85 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 27 Sep 2020 09:46:12 +0200 Subject: [PATCH] - added a proper 'sound finished' callback to the sound engine. Backported from Raze - without this there is no way to implement sounds that can unload themselves, because the existing ChannelEnded function is called when the sound is still active. --- src/common/audio/sound/oalsound.cpp | 11 +++++++-- src/common/audio/sound/s_environment.cpp | 17 +++++++++++--- src/common/audio/sound/s_sound.cpp | 29 +++++++++++++++++++++++- src/common/audio/sound/s_soundinternal.h | 6 +++++ 4 files changed, 57 insertions(+), 6 deletions(-) diff --git a/src/common/audio/sound/oalsound.cpp b/src/common/audio/sound/oalsound.cpp index ee3e127c3..d97c9d5a6 100644 --- a/src/common/audio/sound/oalsound.cpp +++ b/src/common/audio/sound/oalsound.cpp @@ -181,7 +181,7 @@ class OpenALSoundStream : public SoundStream ALuint Source; std::atomic Playing; - bool Looping; + //bool Looping; ALfloat Volume; bool SetupSource() @@ -227,7 +227,7 @@ class OpenALSoundStream : public SoundStream public: OpenALSoundStream(OpenALSoundRenderer *renderer) - : Renderer(renderer), Source(0), Playing(false), Looping(false), Volume(1.0f) + : Renderer(renderer), Source(0), Playing(false), Volume(1.0f) { memset(Buffers, 0, sizeof(Buffers)); Renderer->AddStream(this); @@ -1098,6 +1098,10 @@ SoundHandle OpenALSoundRenderer::LoadSound(uint8_t *sfxdata, int length) data.resize(total * 2); } data.resize(total); + if (total == 0) + { + return retval; + } SoundDecoder_Close(decoder); ALenum err; @@ -1516,6 +1520,9 @@ void OpenALSoundRenderer::StopChannel(FISoundChannel *chan) if((i=SfxGroup.Find(source)) < SfxGroup.Size()) SfxGroup.Delete(i); + if (!(chan->ChanFlags & CHANF_EVICTED)) + soundEngine->SoundDone(chan); + FreeSfx.Push(source); } diff --git a/src/common/audio/sound/s_environment.cpp b/src/common/audio/sound/s_environment.cpp index 9bc3cf4d7..d2e52e21a 100644 --- a/src/common/audio/sound/s_environment.cpp +++ b/src/common/audio/sound/s_environment.cpp @@ -183,20 +183,31 @@ static ReverbContainer Underwater = false }; -static ReverbContainer SewerPipe4 = +static ReverbContainer SewerPipe3 = { &Underwater, - "Sewer Pipe 2", + "Sewer Pipe 3", 0x1503, true, false, + {0,21, 1.7f, 0.80f, -1000, -1000, 0, 1.54f, 0.14f, 1.0f, 200, 0.014f, 0.0f,0.0f,0.0f, 1023, 0.021f, 0.0f,0.0f,0.0f, 0.250f, 0.00f, 0.25f, 0.000f, -5.0f, 5000.0f, 250.0f, 0.0f, 80.0f, 60.0f, 0x3f }, + false +}; + +static ReverbContainer SewerPipe2 = +{ + &SewerPipe3, + "Sewer Pipe 2", + 0x1502, + true, + false, {0,21, 1.7f, 0.80f, -1000, -1000, 0, 1.81f, 0.14f, 1.0f, 229, 0.014f, 0.0f,0.0f,0.0f, 1023, 0.021f, 0.0f,0.0f,0.0f, 0.250f, 0.00f, 0.25f, 0.000f, -5.0f, 5000.0f, 250.0f, 0.0f, 80.0f, 60.0f, 0x3f }, false }; static ReverbContainer SewerPipe = { - &SewerPipe4, + &SewerPipe2, "Sewer Pipe", 0x1500, true, diff --git a/src/common/audio/sound/s_sound.cpp b/src/common/audio/sound/s_sound.cpp index c5e2bc072..a38dc9eb8 100644 --- a/src/common/audio/sound/s_sound.cpp +++ b/src/common/audio/sound/s_sound.cpp @@ -593,6 +593,7 @@ FSoundChan *SoundEngine::StartSound(int type, const void *source, chan->Priority = basepriority; chan->DistanceScale = float(attenuation); chan->SourceType = type; + chan->UserData = 0; if (type == SOURCE_Unattached) { chan->Point[0] = pt->X; chan->Point[1] = pt->Y; chan->Point[2] = pt->Z; @@ -1093,6 +1094,16 @@ int SoundEngine::GetSoundPlayingInfo (int sourcetype, const void *source, int so } } } + else + { + for (FSoundChan* chan = Channels; chan != NULL; chan = chan->NextChan) + { + if ((sourcetype == SOURCE_Any || (chan->SourceType == sourcetype && chan->Source == source))) + { + count++; + } + } + } return count; } @@ -1346,13 +1357,29 @@ void SoundEngine::ChannelEnded(FISoundChannel *ichan) } if (!evicted) { - ReturnChannel(schan); + schan->ChanFlags &= ~CHANF_EVICTED; } else { schan->ChanFlags |= CHANF_EVICTED; schan->SysChannel = NULL; } + + } +} + +//========================================================================== +// +// +// +//========================================================================== + +void SoundEngine::SoundDone(FISoundChannel* ichan) +{ + FSoundChan* schan = static_cast(ichan); + if (schan != NULL) + { + ReturnChannel(schan); } } diff --git a/src/common/audio/sound/s_soundinternal.h b/src/common/audio/sound/s_soundinternal.h index 3a7ec251b..58b3a27c1 100644 --- a/src/common/audio/sound/s_soundinternal.h +++ b/src/common/audio/sound/s_soundinternal.h @@ -166,6 +166,7 @@ struct FSoundChan : public FISoundChannel FSoundID OrgID; // Sound ID of sound used to start this channel. float Volume; int EntChannel; // Actor's sound channel. + int UserData; // Not used by the engine, the caller can use this to store some additional info. int16_t Pitch; // Pitch variation. int16_t NearLimit; int8_t Priority; @@ -303,6 +304,10 @@ public: virtual void CacheSound(sfxinfo_t* sfx); void CacheSound(int sfx) { CacheSound(&S_sfx[sfx]); } void UnloadSound(sfxinfo_t* sfx); + void UnloadSound(int sfx) + { + UnloadSound(&S_sfx[sfx]); + } void UpdateSounds(int time); @@ -410,6 +415,7 @@ public: // Allow this to be overridden for special needs. virtual float GetRolloff(const FRolloffInfo* rolloff, float distance); virtual void ChannelEnded(FISoundChannel* ichan); // allows the client to do bookkeeping on the sound. + virtual void SoundDone(FISoundChannel* ichan); // gets called when the sound has been completely taken down. // Lookup utilities. int FindSound(const char* logicalname);