- 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.
This commit is contained in:
Christoph Oelckers 2020-09-27 09:46:12 +02:00
parent 2b64f8fb19
commit c65f707a20
4 changed files with 57 additions and 6 deletions

View file

@ -181,7 +181,7 @@ class OpenALSoundStream : public SoundStream
ALuint Source; ALuint Source;
std::atomic<bool> Playing; std::atomic<bool> Playing;
bool Looping; //bool Looping;
ALfloat Volume; ALfloat Volume;
bool SetupSource() bool SetupSource()
@ -227,7 +227,7 @@ class OpenALSoundStream : public SoundStream
public: public:
OpenALSoundStream(OpenALSoundRenderer *renderer) 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)); memset(Buffers, 0, sizeof(Buffers));
Renderer->AddStream(this); Renderer->AddStream(this);
@ -1098,6 +1098,10 @@ SoundHandle OpenALSoundRenderer::LoadSound(uint8_t *sfxdata, int length)
data.resize(total * 2); data.resize(total * 2);
} }
data.resize(total); data.resize(total);
if (total == 0)
{
return retval;
}
SoundDecoder_Close(decoder); SoundDecoder_Close(decoder);
ALenum err; ALenum err;
@ -1516,6 +1520,9 @@ void OpenALSoundRenderer::StopChannel(FISoundChannel *chan)
if((i=SfxGroup.Find(source)) < SfxGroup.Size()) if((i=SfxGroup.Find(source)) < SfxGroup.Size())
SfxGroup.Delete(i); SfxGroup.Delete(i);
if (!(chan->ChanFlags & CHANF_EVICTED))
soundEngine->SoundDone(chan);
FreeSfx.Push(source); FreeSfx.Push(source);
} }

View file

@ -183,20 +183,31 @@ static ReverbContainer Underwater =
false false
}; };
static ReverbContainer SewerPipe4 = static ReverbContainer SewerPipe3 =
{ {
&Underwater, &Underwater,
"Sewer Pipe 2", "Sewer Pipe 3",
0x1503, 0x1503,
true, true,
false, 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 }, {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 false
}; };
static ReverbContainer SewerPipe = static ReverbContainer SewerPipe =
{ {
&SewerPipe4, &SewerPipe2,
"Sewer Pipe", "Sewer Pipe",
0x1500, 0x1500,
true, true,

View file

@ -593,6 +593,7 @@ FSoundChan *SoundEngine::StartSound(int type, const void *source,
chan->Priority = basepriority; chan->Priority = basepriority;
chan->DistanceScale = float(attenuation); chan->DistanceScale = float(attenuation);
chan->SourceType = type; chan->SourceType = type;
chan->UserData = 0;
if (type == SOURCE_Unattached) if (type == SOURCE_Unattached)
{ {
chan->Point[0] = pt->X; chan->Point[1] = pt->Y; chan->Point[2] = pt->Z; 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; return count;
} }
@ -1346,13 +1357,29 @@ void SoundEngine::ChannelEnded(FISoundChannel *ichan)
} }
if (!evicted) if (!evicted)
{ {
ReturnChannel(schan); schan->ChanFlags &= ~CHANF_EVICTED;
} }
else else
{ {
schan->ChanFlags |= CHANF_EVICTED; schan->ChanFlags |= CHANF_EVICTED;
schan->SysChannel = NULL; schan->SysChannel = NULL;
} }
}
}
//==========================================================================
//
//
//
//==========================================================================
void SoundEngine::SoundDone(FISoundChannel* ichan)
{
FSoundChan* schan = static_cast<FSoundChan*>(ichan);
if (schan != NULL)
{
ReturnChannel(schan);
} }
} }

View file

@ -166,6 +166,7 @@ struct FSoundChan : public FISoundChannel
FSoundID OrgID; // Sound ID of sound used to start this channel. FSoundID OrgID; // Sound ID of sound used to start this channel.
float Volume; float Volume;
int EntChannel; // Actor's sound channel. 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 Pitch; // Pitch variation.
int16_t NearLimit; int16_t NearLimit;
int8_t Priority; int8_t Priority;
@ -303,6 +304,10 @@ public:
virtual void CacheSound(sfxinfo_t* sfx); virtual void CacheSound(sfxinfo_t* sfx);
void CacheSound(int sfx) { CacheSound(&S_sfx[sfx]); } void CacheSound(int sfx) { CacheSound(&S_sfx[sfx]); }
void UnloadSound(sfxinfo_t* sfx); void UnloadSound(sfxinfo_t* sfx);
void UnloadSound(int sfx)
{
UnloadSound(&S_sfx[sfx]);
}
void UpdateSounds(int time); void UpdateSounds(int time);
@ -410,6 +415,7 @@ public:
// Allow this to be overridden for special needs. // Allow this to be overridden for special needs.
virtual float GetRolloff(const FRolloffInfo* rolloff, float distance); virtual float GetRolloff(const FRolloffInfo* rolloff, float distance);
virtual void ChannelEnded(FISoundChannel* ichan); // allows the client to do bookkeeping on the sound. 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. // Lookup utilities.
int FindSound(const char* logicalname); int FindSound(const char* logicalname);