mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-10 14:51:40 +00:00
- Fixed two bugs in FMODSoundRenderer::HandleChannelDelay():
* Looping sounds that have been playing for a very long time, were evicted, and then were restarted need to have their positions clamped to lie within the bounds of the sounds. If we try to set a start position very far beyond the end, it will overflow inside FMOD and not work. * A start time of 0 is not actually valid and means the sound was never assigned a start time. - The latter bug also reveals a problem with starting looped sounds evicted: They need to be assigned a start time so if they should have the opportunity to start later, they will be properly synchronized. SVN r1987 (trunk)
This commit is contained in:
parent
424c6e8963
commit
51eb6465a2
7 changed files with 61 additions and 5 deletions
|
@ -1,3 +1,15 @@
|
|||
November 17, 2009
|
||||
- Fixed two bugs in FMODSoundRenderer::HandleChannelDelay():
|
||||
* Looping sounds that have been playing for a very long time, were evicted,
|
||||
and then were restarted need to have their positions clamped to lie
|
||||
within the bounds of the sounds. If we try to set a start position very
|
||||
far beyond the end, it will overflow inside FMOD and not work.
|
||||
* A start time of 0 is not actually valid and means the sound was never
|
||||
assigned a start time.
|
||||
- The latter bug also reveals a problem with starting looped sounds evicted:
|
||||
They need to be assigned a start time so if they should have the opportunity
|
||||
to start later, they will be properly synchronized.
|
||||
|
||||
November 17, 2009 (Changes by Graf Zahl)
|
||||
- fixed: P_NowayTraverse was called with a trace distance of 128 instead of
|
||||
the 64 that should have been used.
|
||||
|
|
|
@ -1053,6 +1053,7 @@ static FSoundChan *S_StartSound(AActor *actor, const sector_t *sec, const FPolyO
|
|||
if (chan == NULL && (chanflags & CHAN_LOOP))
|
||||
{
|
||||
chan = (FSoundChan*)S_GetChannel(NULL);
|
||||
GSnd->MarkStartTime(chan);
|
||||
chanflags |= CHAN_EVICTED;
|
||||
}
|
||||
if (attenuation > 0)
|
||||
|
|
|
@ -1650,6 +1650,10 @@ FISoundChannel *FMODSoundRenderer::StartSound3D(SoundHandle sfx, SoundListener *
|
|||
}
|
||||
if (!HandleChannelDelay(chan, reuse_chan, flags & (SNDF_ABSTIME | SNDF_LOOP), freq))
|
||||
{
|
||||
// FMOD seems to get confused if you stop a channel right after
|
||||
// starting it, so hopefully this function will never fail.
|
||||
// (Presumably you need an update between them, but I haven't
|
||||
// tested this hypothesis.)
|
||||
chan->stop();
|
||||
return NULL;
|
||||
}
|
||||
|
@ -1674,6 +1678,19 @@ FISoundChannel *FMODSoundRenderer::StartSound3D(SoundHandle sfx, SoundListener *
|
|||
return 0;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// FMODSoundRenderer :: MarkStartTime
|
||||
//
|
||||
// Marks a channel's start time without actually playing it.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FMODSoundRenderer::MarkStartTime(FISoundChannel *chan)
|
||||
{
|
||||
Sys->getDSPClock(&chan->StartTime.Hi, &chan->StartTime.Lo);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// FMODSoundRenderer :: HandleChannelDelay
|
||||
|
@ -1704,11 +1721,26 @@ bool FMODSoundRenderer::HandleChannelDelay(FMOD::Channel *chan, FISoundChannel *
|
|||
}
|
||||
reuse_chan->StartTime.AsOne = QWORD(nowtime.AsOne - seekpos * OutputRate / freq);
|
||||
}
|
||||
else
|
||||
else if (reuse_chan->StartTime.AsOne != 0)
|
||||
{
|
||||
QWORD difftime = nowtime.AsOne - reuse_chan->StartTime.AsOne;
|
||||
if (difftime > 0)
|
||||
{
|
||||
// Clamp the position of looping sounds to be within the sound.
|
||||
// If we try to start it several minutes past its normal end,
|
||||
// FMOD doesn't like that.
|
||||
if (flags & SNDF_LOOP)
|
||||
{
|
||||
FMOD::Sound *sound;
|
||||
if (FMOD_OK == chan->getCurrentSound(&sound))
|
||||
{
|
||||
unsigned int len;
|
||||
if (FMOD_OK == sound->getLength(&len, FMOD_TIMEUNIT_MS))
|
||||
{
|
||||
difftime %= len;
|
||||
}
|
||||
}
|
||||
}
|
||||
return chan->setPosition((unsigned int)(difftime / OutputRate), FMOD_TIMEUNIT_MS) == FMOD_OK;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,6 +33,9 @@ public:
|
|||
// Stops a sound channel.
|
||||
void StopChannel (FISoundChannel *chan);
|
||||
|
||||
// Marks a channel's start time without actually playing it.
|
||||
void MarkStartTime (FISoundChannel *chan);
|
||||
|
||||
// Returns position of sound on this channel, in samples.
|
||||
unsigned int GetPosition(FISoundChannel *chan);
|
||||
|
||||
|
|
|
@ -159,7 +159,7 @@ public:
|
|||
return NULL;
|
||||
}
|
||||
|
||||
// Starts a sound. (No, not really.)
|
||||
// Starts a sound.
|
||||
FISoundChannel *StartSound (SoundHandle sfx, float vol, int pitch, int chanflags, FISoundChannel *reuse_chan)
|
||||
{
|
||||
return NULL;
|
||||
|
@ -169,6 +169,11 @@ public:
|
|||
return NULL;
|
||||
}
|
||||
|
||||
// Marks a channel's start time without actually playing it.
|
||||
void MarkStartTime (FISoundChannel *chan)
|
||||
{
|
||||
}
|
||||
|
||||
// Returns position of sound on this channel, in samples.
|
||||
unsigned int GetPosition(FISoundChannel *chan)
|
||||
{
|
||||
|
|
|
@ -109,6 +109,9 @@ public:
|
|||
// Stops a sound channel.
|
||||
virtual void StopChannel (FISoundChannel *chan) = 0;
|
||||
|
||||
// Marks a channel's start time without actually playing it.
|
||||
virtual void MarkStartTime (FISoundChannel *chan) = 0;
|
||||
|
||||
// Returns position of sound on this channel, in samples.
|
||||
virtual unsigned int GetPosition(FISoundChannel *chan) = 0;
|
||||
|
||||
|
|
|
@ -232,7 +232,7 @@ public:
|
|||
uint32 fillcolor;
|
||||
FRemapTable *remap;
|
||||
const BYTE *translation;
|
||||
DWORD colorOverlay;
|
||||
uint32 colorOverlay;
|
||||
INTBOOL alphaChannel;
|
||||
INTBOOL flipX;
|
||||
fixed_t shadowAlpha;
|
||||
|
@ -404,7 +404,7 @@ public:
|
|||
virtual bool WipeDo(int ticks);
|
||||
virtual void WipeCleanup();
|
||||
|
||||
DWORD GetLastFPS() const { return LastCount; }
|
||||
uint32 GetLastFPS() const { return LastCount; }
|
||||
|
||||
#ifdef _WIN32
|
||||
virtual void PaletteChanged () = 0;
|
||||
|
@ -418,7 +418,7 @@ protected:
|
|||
DFrameBuffer () {}
|
||||
|
||||
private:
|
||||
DWORD LastMS, LastSec, FrameCount, LastCount, LastTic;
|
||||
uint32 LastMS, LastSec, FrameCount, LastCount, LastTic;
|
||||
};
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue