- 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;
std::atomic<bool> 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);
}

View file

@ -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,

View file

@ -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<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.
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);