mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-26 05:51:20 +00:00
- The SFX Reverb unit is now moved so that it serves as an input to the water
effect rather than as an input to the ChannelGroup Target Unit. This means the water effect is now applied after any room reverb, rather than in parallel with it. - Fixed: UI sounds should not have reverb applied to them. SVN r1450 (trunk)
This commit is contained in:
parent
1f5cf23418
commit
4535382031
5 changed files with 131 additions and 2 deletions
|
@ -4,6 +4,11 @@
|
||||||
version and removed old compatibility handlings.
|
version and removed old compatibility handlings.
|
||||||
|
|
||||||
February 25, 2009
|
February 25, 2009
|
||||||
|
- The SFX Reverb unit is now moved so that it serves as an input to the water
|
||||||
|
effect rather than as an input to the ChannelGroup Target Unit. This means
|
||||||
|
the water effect is now applied after any room reverb, rather than in
|
||||||
|
parallel with it.
|
||||||
|
- Fixed: UI sounds should not have reverb applied to them.
|
||||||
- Removed the delay for starting all sounds from one tic at exactly the same
|
- Removed the delay for starting all sounds from one tic at exactly the same
|
||||||
DSP position. Without also synchronizing the stopping of sounds, it can
|
DSP position. Without also synchronizing the stopping of sounds, it can
|
||||||
cause problems with things like the chainsaw where the sound is stopped and
|
cause problems with things like the chainsaw where the sound is stopped and
|
||||||
|
|
|
@ -1032,6 +1032,7 @@ static FSoundChan *S_StartSound(AActor *actor, const sector_t *sec, const FPolyO
|
||||||
if (chanflags & CHAN_LOOP) startflags |= SNDF_LOOP;
|
if (chanflags & CHAN_LOOP) startflags |= SNDF_LOOP;
|
||||||
if (chanflags & CHAN_AREA) startflags |= SNDF_AREA;
|
if (chanflags & CHAN_AREA) startflags |= SNDF_AREA;
|
||||||
if (chanflags & (CHAN_UI|CHAN_NOPAUSE)) startflags |= SNDF_NOPAUSE;
|
if (chanflags & (CHAN_UI|CHAN_NOPAUSE)) startflags |= SNDF_NOPAUSE;
|
||||||
|
if (chanflags & CHAN_UI) startflags |= SNDF_NOREVERB;
|
||||||
|
|
||||||
if (attenuation > 0)
|
if (attenuation > 0)
|
||||||
{
|
{
|
||||||
|
|
|
@ -610,6 +610,8 @@ bool FMODSoundRenderer::Init()
|
||||||
PrevEnvironment = DefaultEnvironments[0];
|
PrevEnvironment = DefaultEnvironments[0];
|
||||||
DSPClock.AsOne = 0;
|
DSPClock.AsOne = 0;
|
||||||
ChannelGroupTargetUnit = NULL;
|
ChannelGroupTargetUnit = NULL;
|
||||||
|
SfxReverbHooked = false;
|
||||||
|
SfxReverbPlaceholder = NULL;
|
||||||
|
|
||||||
Printf("I_InitSound: Initializing FMOD\n");
|
Printf("I_InitSound: Initializing FMOD\n");
|
||||||
|
|
||||||
|
@ -908,6 +910,35 @@ bool FMODSoundRenderer::Init()
|
||||||
result = sfx_head->getInput(0, &pausable_head, &SfxConnection);
|
result = sfx_head->getInput(0, &pausable_head, &SfxConnection);
|
||||||
if (result == FMOD_OK)
|
if (result == FMOD_OK)
|
||||||
{
|
{
|
||||||
|
// The placeholder mixer is for reference to where to connect the SFX
|
||||||
|
// reverb unit once it gets created.
|
||||||
|
result = Sys->createDSPByType(FMOD_DSP_TYPE_MIXER, &SfxReverbPlaceholder);
|
||||||
|
if (result == FMOD_OK)
|
||||||
|
{
|
||||||
|
// Replace the PausableSFX->SFX connection with
|
||||||
|
// PausableSFX->ReverbPlaceholder->SFX.
|
||||||
|
result = SfxReverbPlaceholder->addInput(pausable_head, NULL);
|
||||||
|
if (result == FMOD_OK)
|
||||||
|
{
|
||||||
|
FMOD::DSPConnection *connection;
|
||||||
|
result = sfx_head->addInput(SfxReverbPlaceholder, &connection);
|
||||||
|
if (result == FMOD_OK)
|
||||||
|
{
|
||||||
|
sfx_head->disconnectFrom(pausable_head);
|
||||||
|
SfxReverbPlaceholder->setActive(true);
|
||||||
|
SfxReverbPlaceholder->setBypass(true);
|
||||||
|
// The placeholder now takes the place of the pausable_head
|
||||||
|
// for the following connections.
|
||||||
|
pausable_head = SfxReverbPlaceholder;
|
||||||
|
SfxConnection = connection;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SfxReverbPlaceholder->release();
|
||||||
|
SfxReverbPlaceholder = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
result = WaterLP->addInput(pausable_head, NULL);
|
result = WaterLP->addInput(pausable_head, NULL);
|
||||||
WaterLP->setActive(false);
|
WaterLP->setActive(false);
|
||||||
WaterLP->setParameter(FMOD_DSP_LOWPASS_CUTOFF, snd_waterlp);
|
WaterLP->setParameter(FMOD_DSP_LOWPASS_CUTOFF, snd_waterlp);
|
||||||
|
@ -1018,6 +1049,11 @@ void FMODSoundRenderer::Shutdown()
|
||||||
WaterReverb->release();
|
WaterReverb->release();
|
||||||
WaterReverb = NULL;
|
WaterReverb = NULL;
|
||||||
}
|
}
|
||||||
|
if (SfxReverbPlaceholder != NULL)
|
||||||
|
{
|
||||||
|
SfxReverbPlaceholder->release();
|
||||||
|
SfxReverbPlaceholder = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
Sys->close();
|
Sys->close();
|
||||||
Sys->release();
|
Sys->release();
|
||||||
|
@ -1389,6 +1425,15 @@ FISoundChannel *FMODSoundRenderer::StartSound(SoundHandle sfx, float vol, int pi
|
||||||
chan->stop();
|
chan->stop();
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
if (flags & SNDF_NOREVERB)
|
||||||
|
{
|
||||||
|
FMOD_REVERB_CHANNELPROPERTIES reverb = { 0, };
|
||||||
|
if (FMOD_OK == chan->getReverbProperties(&reverb))
|
||||||
|
{
|
||||||
|
reverb.Room = -10000;
|
||||||
|
chan->setReverbProperties(&reverb);
|
||||||
|
}
|
||||||
|
}
|
||||||
chan->setPaused(false);
|
chan->setPaused(false);
|
||||||
return CommonChannelSetup(chan, reuse_chan);
|
return CommonChannelSetup(chan, reuse_chan);
|
||||||
}
|
}
|
||||||
|
@ -1487,6 +1532,15 @@ FISoundChannel *FMODSoundRenderer::StartSound3D(SoundHandle sfx, SoundListener *
|
||||||
chan->stop();
|
chan->stop();
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
if (flags & SNDF_NOREVERB)
|
||||||
|
{
|
||||||
|
FMOD_REVERB_CHANNELPROPERTIES reverb = { 0, };
|
||||||
|
if (FMOD_OK == chan->getReverbProperties(&reverb))
|
||||||
|
{
|
||||||
|
reverb.Room = -10000;
|
||||||
|
chan->setReverbProperties(&reverb);
|
||||||
|
}
|
||||||
|
}
|
||||||
chan->setPaused(false);
|
chan->setPaused(false);
|
||||||
chan->getPriority(&def_priority);
|
chan->getPriority(&def_priority);
|
||||||
FISoundChannel *schan = CommonChannelSetup(chan, reuse_chan);
|
FISoundChannel *schan = CommonChannelSetup(chan, reuse_chan);
|
||||||
|
@ -1784,13 +1838,13 @@ void FMODSoundRenderer::UpdateListener(SoundListener *listener)
|
||||||
bool underwater = false;
|
bool underwater = false;
|
||||||
const ReverbContainer *env;
|
const ReverbContainer *env;
|
||||||
|
|
||||||
|
underwater = (listener->underwater && snd_waterlp);
|
||||||
if (ForcedEnvironment)
|
if (ForcedEnvironment)
|
||||||
{
|
{
|
||||||
env = ForcedEnvironment;
|
env = ForcedEnvironment;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
underwater = (listener->underwater && snd_waterlp);
|
|
||||||
env = listener->Environment;
|
env = listener->Environment;
|
||||||
if (env == NULL)
|
if (env == NULL)
|
||||||
{
|
{
|
||||||
|
@ -1803,6 +1857,11 @@ void FMODSoundRenderer::UpdateListener(SoundListener *listener)
|
||||||
const_cast<ReverbContainer*>(env)->Modified = false;
|
const_cast<ReverbContainer*>(env)->Modified = false;
|
||||||
Sys->setReverbProperties((FMOD_REVERB_PROPERTIES *)(&env->Properties));
|
Sys->setReverbProperties((FMOD_REVERB_PROPERTIES *)(&env->Properties));
|
||||||
PrevEnvironment = env;
|
PrevEnvironment = env;
|
||||||
|
|
||||||
|
if (!SfxReverbHooked)
|
||||||
|
{
|
||||||
|
SfxReverbHooked = ReconnectSFXReverbUnit();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (underwater || env->SoftwareWater)
|
if (underwater || env->SoftwareWater)
|
||||||
|
@ -1852,6 +1911,65 @@ void FMODSoundRenderer::UpdateListener(SoundListener *listener)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// FMODSoundRenderer :: ReconnectSFXReverbUnit
|
||||||
|
//
|
||||||
|
// Locates the DSP unit responsible for software 3D reverb. There is only
|
||||||
|
// one, and it by default is connected directly to the ChannelGroup Target
|
||||||
|
// Unit. Older versions of FMOD created this at startup; newer versions
|
||||||
|
// delay creating it until the first call to setReverbProperties, at which
|
||||||
|
// point it persists until the system is closed.
|
||||||
|
//
|
||||||
|
// Upon locating the proper DSP unit, reconnects it to serve as an input to
|
||||||
|
// our water DSP chain after the Pausable SFX ChannelGroup.
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
bool FMODSoundRenderer::ReconnectSFXReverbUnit()
|
||||||
|
{
|
||||||
|
FMOD::DSP *unit;
|
||||||
|
FMOD_DSP_TYPE type;
|
||||||
|
int numinputs, i;
|
||||||
|
|
||||||
|
if (ChannelGroupTargetUnit == NULL || SfxReverbPlaceholder == NULL)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// Look for SFX Reverb unit
|
||||||
|
if (FMOD_OK != ChannelGroupTargetUnit->getNumInputs(&numinputs))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
for (i = numinputs - 1; i >= 0; --i)
|
||||||
|
{
|
||||||
|
if (FMOD_OK == ChannelGroupTargetUnit->getInput(i, &unit, NULL) &&
|
||||||
|
FMOD_OK == unit->getType(&type))
|
||||||
|
{
|
||||||
|
if (type == FMOD_DSP_TYPE_SFXREVERB)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (i < 0)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Found it! Now move it in the DSP graph to be done before the water
|
||||||
|
// effect.
|
||||||
|
if (FMOD_OK != ChannelGroupTargetUnit->disconnectFrom(unit))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (FMOD_OK != SfxReverbPlaceholder->addInput(unit, NULL))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
// FMODSoundRenderer :: Sync
|
// FMODSoundRenderer :: Sync
|
||||||
|
|
|
@ -72,6 +72,8 @@ private:
|
||||||
FISoundChannel *CommonChannelSetup(FMOD::Channel *chan, FISoundChannel *reuse_chan) const;
|
FISoundChannel *CommonChannelSetup(FMOD::Channel *chan, FISoundChannel *reuse_chan) const;
|
||||||
FMOD_MODE SetChanHeadSettings(SoundListener *listener, FMOD::Channel *chan, const FVector3 &pos, bool areasound, FMOD_MODE oldmode) const;
|
FMOD_MODE SetChanHeadSettings(SoundListener *listener, FMOD::Channel *chan, const FVector3 &pos, bool areasound, FMOD_MODE oldmode) const;
|
||||||
|
|
||||||
|
bool ReconnectSFXReverbUnit();
|
||||||
|
|
||||||
bool Init ();
|
bool Init ();
|
||||||
void Shutdown ();
|
void Shutdown ();
|
||||||
void DumpDriverCaps(FMOD_CAPS caps, int minfrequency, int maxfrequency);
|
void DumpDriverCaps(FMOD_CAPS caps, int minfrequency, int maxfrequency);
|
||||||
|
@ -93,6 +95,8 @@ private:
|
||||||
FMOD::DSP *WaterLP, *WaterReverb;
|
FMOD::DSP *WaterLP, *WaterReverb;
|
||||||
FMOD::DSPConnection *SfxConnection;
|
FMOD::DSPConnection *SfxConnection;
|
||||||
FMOD::DSP *ChannelGroupTargetUnit;
|
FMOD::DSP *ChannelGroupTargetUnit;
|
||||||
|
FMOD::DSP *SfxReverbPlaceholder;
|
||||||
|
bool SfxReverbHooked;
|
||||||
float LastWaterLP;
|
float LastWaterLP;
|
||||||
|
|
||||||
// Just for snd_status display
|
// Just for snd_status display
|
||||||
|
|
|
@ -49,7 +49,8 @@ enum EStartSoundFlags
|
||||||
SNDF_LOOP=1,
|
SNDF_LOOP=1,
|
||||||
SNDF_NOPAUSE=2,
|
SNDF_NOPAUSE=2,
|
||||||
SNDF_AREA=4,
|
SNDF_AREA=4,
|
||||||
SNDF_ABSTIME=8
|
SNDF_ABSTIME=8,
|
||||||
|
SNDF_NOREVERB=16,
|
||||||
};
|
};
|
||||||
|
|
||||||
class SoundStream
|
class SoundStream
|
||||||
|
|
Loading…
Reference in a new issue