- Moved some more high level sound logic out of FMODSoundRenderer:

The rolloff and channel ended callbacks now call functions in s_sound.cpp
  instead of working on the data itself and GSnd->StopSound has been replaced
  with S_StopChannel.


SVN r1227 (trunk)
This commit is contained in:
Christoph Oelckers 2008-09-15 16:02:05 +00:00
parent 760f70d3f1
commit 5d9483b632
7 changed files with 177 additions and 123 deletions

View file

@ -1,3 +1,13 @@
September 15, 2008 (Changes by Graf Zahl)
- Moved some more high level sound logic out of FMODSoundRenderer:
The rolloff and channel ended callbacks now call functions in s_sound.cpp
instead of working on the data itself and GSnd->StopSound has been replaced
with S_StopChannel.
- Changed compilation for g_doom, g_heretic, g_hexen and g_strife folders so
that all files are included by a central one instead of compiling each one
separately. This speeds up the compilation process by 25% when doing a
complete rebuild in Visual C.
September 14, 2008 (Changes by Graf Zahl)
- Cleaned up some include dependencies.
- fixed: For Chex Quest some CVars were initialized to Heretic's default.

View file

@ -320,7 +320,7 @@ void S_Shutdown ()
while (Channels != NULL)
{
GSnd->StopSound(Channels);
S_StopChannel(Channels);
}
GSnd->UpdateSounds();
for (chan = FreeChannels; chan != NULL; chan = next)
@ -986,7 +986,7 @@ static FSoundChan *S_StartSound(AActor *actor, const sector_t *sec, const FPolyO
}
if (foundit)
{
GSnd->StopSound(chan);
S_StopChannel(chan);
break;
}
}
@ -1343,7 +1343,7 @@ void S_StopSound (int channel)
if (chan->SourceType == SOURCE_None &&
(chan->EntChannel == channel || (i_compatflags & COMPATF_MAGICSILENCE)))
{
GSnd->StopSound(chan);
S_StopChannel(chan);
}
}
}
@ -1367,7 +1367,7 @@ void S_StopSound (AActor *actor, int channel)
chan->Actor == actor &&
(chan->EntChannel == channel || (i_compatflags & COMPATF_MAGICSILENCE)))
{
GSnd->StopSound(chan);
S_StopChannel(chan);
}
}
}
@ -1389,7 +1389,7 @@ void S_StopSound (const sector_t *sec, int channel)
chan->Sector == sec &&
(chan->EntChannel == channel || (i_compatflags & COMPATF_MAGICSILENCE)))
{
GSnd->StopSound(chan);
S_StopChannel(chan);
}
}
}
@ -1410,7 +1410,7 @@ void S_StopSound (const FPolyObj *poly, int channel)
chan->Poly == poly &&
(chan->EntChannel == channel || (i_compatflags & COMPATF_MAGICSILENCE)))
{
GSnd->StopSound(chan);
S_StopChannel(chan);
}
}
}
@ -1426,7 +1426,7 @@ void S_StopAllChannels ()
SN_StopAllSequences();
while (Channels != NULL)
{
GSnd->StopSound(Channels);
S_StopChannel(Channels);
}
GSnd->UpdateSounds();
}
@ -1461,7 +1461,7 @@ void S_RelinkSound (AActor *from, AActor *to)
}
else
{
GSnd->StopSound(chan);
S_StopChannel(chan);
}
}
}
@ -1612,7 +1612,7 @@ void S_EvictAllChannels()
chan->ChanFlags |= CHAN_EVICTED;
if (chan->SysChannel != NULL)
{
GSnd->StopSound(chan);
S_StopChannel(chan);
}
assert(chan->NextChan == next);
}
@ -1755,6 +1755,125 @@ static void S_SetListener(SoundListener &listener, AActor *listenactor)
//==========================================================================
//
// S_GetRolloff
//
//==========================================================================
float S_GetRolloff(FRolloffInfo *rolloff, float distance)
{
if (rolloff == NULL)
{
return 0;
}
if (distance <= rolloff->MinDistance)
{
return 1;
}
if (rolloff->RolloffType == ROLLOFF_Log)
{ // Logarithmic rolloff has no max distance where it goes silent.
return rolloff->MinDistance / (rolloff->MinDistance + rolloff->RolloffFactor * (distance - rolloff->MinDistance));
}
if (distance >= rolloff->MaxDistance)
{
return 0;
}
float volume = (rolloff->MaxDistance - distance) / (rolloff->MaxDistance - rolloff->MinDistance);
if (rolloff->RolloffType == ROLLOFF_Custom && S_SoundCurve != NULL)
{
volume = S_SoundCurve[int(S_SoundCurveSize * (1 - volume))] / 127.f;
}
if (rolloff->RolloffType == ROLLOFF_Linear)
{
return volume;
}
else
{
return (powf(10.f, volume) - 1.f) / 9.f;
}
}
//==========================================================================
//
// S_ChannelEnded (callback for sound interface code)
//
//==========================================================================
void S_ChannelEnded(FSoundChan *schan)
{
bool evicted;
if (schan != NULL)
{
// If the sound was stopped with GSnd->StopSound(), then we know
// it wasn't evicted. Otherwise, if it's looping, it must have
// been evicted. If it's not looping, then it was evicted if it
// didn't reach the end of its playback.
if (schan->ChanFlags & CHAN_FORGETTABLE)
{
evicted = false;
}
else if (schan->ChanFlags & (CHAN_LOOP | CHAN_EVICTED))
{
evicted = true;
}
else
{
unsigned int pos = GSnd->GetPosition(schan);
unsigned int len = GSnd->GetSampleLength(schan->SfxInfo->data);
if (pos == 0)
{
evicted = !!(schan->ChanFlags & CHAN_JUSTSTARTED);
}
else if (pos < len)
{
evicted = true;
}
}
if (!evicted)
{
S_ReturnChannel(schan);
}
else
{
schan->ChanFlags |= CHAN_EVICTED;
schan->SysChannel = NULL;
}
}
}
//==========================================================================
//
// S_StopChannel
//
//==========================================================================
void S_StopChannel(FSoundChan *chan)
{
if (chan == NULL)
return;
if (chan->SysChannel != NULL)
{
// S_EvictAllChannels() will set the CHAN_EVICTED flag to indicate
// that it wants to keep all the channel information around.
if (!(chan->ChanFlags & CHAN_EVICTED))
{
chan->ChanFlags |= CHAN_FORGETTABLE;
}
GSnd->StopChannel(chan);
}
else
{
S_ReturnChannel(chan);
}
}
//==========================================================================
//
// (FArchive &) << (FSoundID &)

View file

@ -210,6 +210,7 @@ FSoundChan *S_GetChannel(void *syschan);
void S_ReturnChannel(FSoundChan *chan);
void S_EvictAllChannels();
void S_StopChannel(FSoundChan *chan);
void S_LinkChannel(FSoundChan *chan, FSoundChan **head);
void S_UnlinkChannel(FSoundChan *chan);

View file

@ -1616,25 +1616,12 @@ FSoundChan *FMODSoundRenderer::CommonChannelSetup(FMOD::Channel *chan, FSoundCha
//
//==========================================================================
void FMODSoundRenderer::StopSound(FSoundChan *chan)
void FMODSoundRenderer::StopChannel(FSoundChan *chan)
{
if (chan == NULL)
return;
if (chan->SysChannel != NULL)
if (chan != NULL && chan->SysChannel != NULL)
{
// S_EvictAllChannels() will set the CHAN_EVICTED flag to indicate
// that it wants to keep all the channel information around.
if (!(chan->ChanFlags & CHAN_EVICTED))
{
chan->ChanFlags |= CHAN_FORGETTABLE;
}
((FMOD::Channel *)chan->SysChannel)->stop();
}
else
{
S_ReturnChannel(chan);
}
}
//==========================================================================
@ -1995,6 +1982,26 @@ unsigned int FMODSoundRenderer::GetMSLength(SoundHandle sfx)
}
//==========================================================================
//
// FMODSoundRenderer :: GetMSLength
//
//==========================================================================
unsigned int FMODSoundRenderer::GetSampleLength(SoundHandle sfx)
{
if (sfx.data != NULL)
{
unsigned int length;
if (((FMOD::Sound *)sfx.data)->getLength(&length, FMOD_TIMEUNIT_PCM) == FMOD_OK)
{
return length;
}
}
return 0; // Don't know.
}
//==========================================================================
//
@ -2014,58 +2021,7 @@ FMOD_RESULT F_CALLBACK FMODSoundRenderer::ChannelEndCallback
if (chan->getUserData((void **)&schan) == FMOD_OK && schan != NULL)
{
bool evicted;
// If the sound was stopped with GSnd->StopSound(), then we know
// it wasn't evicted. Otherwise, if it's looping, it must have
// been evicted. If it's not looping, then it was evicted if it
// didn't reach the end of its playback.
if (schan->ChanFlags & CHAN_FORGETTABLE)
{
evicted = false;
}
else if (schan->ChanFlags & (CHAN_LOOP | CHAN_EVICTED))
{
evicted = true;
}
else
{
FMOD::Sound *sound;
unsigned int len, pos;
evicted = false; // Assume not evicted
if (FMOD_OK == chan->getPosition(&pos, FMOD_TIMEUNIT_PCM))
{
// If position is 0, then this sound either didn't have
// a chance to play at all, or it stopped normally.
if (pos == 0)
{
if (schan->ChanFlags & CHAN_JUSTSTARTED)
{
evicted = true;
}
}
else if (FMOD_OK == chan->getCurrentSound(&sound))
{
if (FMOD_OK == sound->getLength(&len, FMOD_TIMEUNIT_PCM))
{
if (pos < len)
{
evicted = true;
}
}
}
}
}
if (!evicted)
{
S_ReturnChannel(schan);
}
else
{
schan->ChanFlags |= CHAN_EVICTED;
schan->SysChannel = NULL;
}
S_ChannelEnded(schan);
}
return FMOD_OK;
}
@ -2083,53 +2039,19 @@ float F_CALLBACK FMODSoundRenderer::RolloffCallback(FMOD_CHANNEL *channel, float
{
FMOD::Channel *chan = (FMOD::Channel *)channel;
FSoundChan *schan;
FRolloffInfo *rolloff;
if (GRolloff != NULL)
{
rolloff = GRolloff;
distance *= GDistScale;
return S_GetRolloff(GRolloff, distance * GDistScale);
}
else if (chan->getUserData((void **)&schan) == FMOD_OK && schan != NULL)
{
rolloff = &schan->Rolloff;
distance *= schan->DistanceScale;
return S_GetRolloff(&schan->Rolloff, distance * schan->DistanceScale);
}
else
{
return 0;
}
if (rolloff == NULL)
{
return 0;
}
if (distance <= rolloff->MinDistance)
{
return 1;
}
if (rolloff->RolloffType == ROLLOFF_Log)
{ // Logarithmic rolloff has no max distance where it goes silent.
return rolloff->MinDistance / (rolloff->MinDistance + rolloff->RolloffFactor * (distance - rolloff->MinDistance));
}
if (distance >= rolloff->MaxDistance)
{
return 0;
}
float volume = (rolloff->MaxDistance - distance) / (rolloff->MaxDistance - rolloff->MinDistance);
if (rolloff->RolloffType == ROLLOFF_Custom && S_SoundCurve != NULL)
{
volume = S_SoundCurve[int(S_SoundCurveSize * (1 - volume))] / 127.f;
}
if (rolloff->RolloffType == ROLLOFF_Linear)
{
return volume;
}
else
{
return (powf(10.f, volume) - 1.f) / 9.f;
}
}
//==========================================================================

View file

@ -17,6 +17,7 @@ public:
SoundHandle LoadSoundRaw(BYTE *sfxdata, int length, int frequency, int channels, int bits);
void UnloadSound (SoundHandle sfx);
unsigned int GetMSLength(SoundHandle sfx);
unsigned int GetSampleLength(SoundHandle sfx);
float GetOutputRate();
// Streaming sounds.
@ -30,7 +31,7 @@ public:
FSoundChan *StartSound3D (SoundHandle sfx, SoundListener *listener, float vol, FRolloffInfo *rolloff, float distscale, int pitch, int priority, const FVector3 &pos, const FVector3 &vel, int channum, int chanflags, FSoundChan *reuse_chan);
// Stops a sound channel.
void StopSound (FSoundChan *chan);
void StopChannel (FSoundChan *chan);
// Returns position of sound on this channel, in samples.
unsigned int GetPosition(FSoundChan *chan);

View file

@ -137,10 +137,17 @@ public:
// ambient sounds to specify a default minimum period.
return 250;
}
unsigned int GetSampleLength(SoundHandle sfx)
{
return 0;
}
float GetOutputRate()
{
return 11025; // Lies!
}
void StopChannel(FSoundChan *chan)
{
}
// Streaming sounds.
SoundStream *CreateStream (SoundStreamCallback callback, int buffbytes, int flags, int samplerate, void *userdata)
@ -162,15 +169,6 @@ public:
return NULL;
}
// Stops a sound channel.
void StopSound (FSoundChan *chan)
{
if (chan != NULL)
{
S_ReturnChannel(chan);
}
}
// Returns position of sound on this channel, in samples.
unsigned int GetPosition(FSoundChan *chan)
{

View file

@ -96,6 +96,7 @@ public:
virtual SoundHandle LoadSoundRaw(BYTE *sfxdata, int length, int frequency, int channels, int bits) = 0;
virtual void UnloadSound (SoundHandle sfx) = 0; // unloads a sound from memory
virtual unsigned int GetMSLength(SoundHandle sfx) = 0; // Gets the length of a sound at its default frequency
virtual unsigned int GetSampleLength(SoundHandle sfx) = 0; // Gets the length of a sound at its default frequency
virtual float GetOutputRate() = 0;
// Streaming sounds.
@ -107,7 +108,7 @@ public:
virtual FSoundChan *StartSound3D (SoundHandle sfx, SoundListener *listener, float vol, FRolloffInfo *rolloff, float distscale, int pitch, int priority, const FVector3 &pos, const FVector3 &vel, int channum, int chanflags, FSoundChan *reuse_chan) = 0;
// Stops a sound channel.
virtual void StopSound (FSoundChan *chan) = 0;
virtual void StopChannel (FSoundChan *chan) = 0;
// Returns position of sound on this channel, in samples.
virtual unsigned int GetPosition(FSoundChan *chan) = 0;
@ -141,4 +142,6 @@ extern SoundRenderer *GSnd;
void I_InitSound ();
void I_ShutdownSound ();
void S_ChannelEnded(FSoundChan *schan);
float S_GetRolloff(FRolloffInfo *rolloff, float distance);
#endif