mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-10 23:02:08 +00:00
- 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:
parent
760f70d3f1
commit
5d9483b632
7 changed files with 177 additions and 123 deletions
|
@ -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.
|
||||
|
|
137
src/s_sound.cpp
137
src/s_sound.cpp
|
@ -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 &)
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue