- Fixed: FMODSoundRenderer::StartSound3D must set the static variable pointing

to the rolloff information back to NULL when starting the sound fails.
- Fixed: Rolloff information was taken from the sfxinfo that contained the
  actual sound data, not the one that was used for starting the sound.



SVN r1206 (trunk)
This commit is contained in:
Christoph Oelckers 2008-09-09 09:22:47 +00:00
parent 33c7d5c8d3
commit 3b35ad2db2
8 changed files with 58 additions and 90 deletions

View File

@ -1,3 +1,9 @@
September 9, 2008 (Changes by Graf Zahl)
- Fixed: FMODSoundRenderer::StartSound3D must set the static variable pointing
to the rolloff information back to NULL when starting the sound fails.
- Fixed: Rolloff information was taken from the sfxinfo that contained the
actual sound data, not the one that was used for starting the sound.
September 7, 2008 (Changes by Graf Zahl) September 7, 2008 (Changes by Graf Zahl)
- Fixed: Chex Quest's Super Bootspork was missing the pickup message. - Fixed: Chex Quest's Super Bootspork was missing the pickup message.
- Added missing Strife automap colors for items and non-monsters. - Added missing Strife automap colors for items and non-monsters.

View File

@ -501,10 +501,10 @@ int S_AddSoundLump (const char *logicalname, int lump)
newsfx.bUsed = false; newsfx.bUsed = false;
newsfx.bSingular = false; newsfx.bSingular = false;
newsfx.bTentative = false; newsfx.bTentative = false;
newsfx.RolloffType = ROLLOFF_Doom;
newsfx.link = sfxinfo_t::NO_LINK; newsfx.link = sfxinfo_t::NO_LINK;
newsfx.MinDistance = 0; newsfx.Rolloff.RolloffType = ROLLOFF_Doom;
newsfx.MaxDistance = 0; newsfx.Rolloff.MinDistance = 0;
newsfx.Rolloff.MaxDistance = 0;
return (int)S_sfx.Push (newsfx); return (int)S_sfx.Push (newsfx);
} }
@ -1202,7 +1202,7 @@ static void S_AddSNDINFO (int lump)
case SI_Rolloff: { case SI_Rolloff: {
// $rolloff *|<logical name> [linear|log|custom] <min dist> <max dist/rolloff factor> // $rolloff *|<logical name> [linear|log|custom] <min dist> <max dist/rolloff factor>
// Using * for the name makes it the default for sounds that don't specify otherwise. // Using * for the name makes it the default for sounds that don't specify otherwise.
float *min, *max; FRolloffInfo *rolloff;
int type; int type;
int sfx; int sfx;
@ -1210,14 +1210,12 @@ static void S_AddSNDINFO (int lump)
if (sc.Compare("*")) if (sc.Compare("*"))
{ {
sfx = -1; sfx = -1;
min = &S_MinDistance; rolloff = &S_Rolloff;
max = &S_MaxDistanceOrRolloffFactor;
} }
else else
{ {
sfx = S_FindSoundTentative(sc.String); sfx = S_FindSoundTentative(sc.String);
min = &S_sfx[sfx].MinDistance; rolloff = &S_sfx[sfx].Rolloff;
max = &S_sfx[sfx].MaxDistance;
} }
type = ROLLOFF_Doom; type = ROLLOFF_Doom;
if (!sc.CheckFloat()) if (!sc.CheckFloat())
@ -1225,15 +1223,15 @@ static void S_AddSNDINFO (int lump)
sc.MustGetString(); sc.MustGetString();
if (sc.Compare("linear")) if (sc.Compare("linear"))
{ {
type = ROLLOFF_Linear; rolloff->RolloffType = ROLLOFF_Linear;
} }
else if (sc.Compare("log")) else if (sc.Compare("log"))
{ {
type = ROLLOFF_Log; rolloff->RolloffType = ROLLOFF_Log;
} }
else if (sc.Compare("custom")) else if (sc.Compare("custom"))
{ {
type = ROLLOFF_Custom; rolloff->RolloffType = ROLLOFF_Custom;
} }
else else
{ {
@ -1241,17 +1239,9 @@ static void S_AddSNDINFO (int lump)
} }
sc.MustGetFloat(); sc.MustGetFloat();
} }
if (sfx < 0) rolloff->MinDistance = sc.Float;
{
S_RolloffType = type;
}
else
{
S_sfx[sfx].RolloffType = type;
}
*min = sc.Float;
sc.MustGetFloat(); sc.MustGetFloat();
*max = sc.Float; rolloff->MaxDistance = sc.Float;
break; break;
} }

View File

@ -126,9 +126,7 @@ int sfx_empty;
FSoundChan *Channels; FSoundChan *Channels;
FSoundChan *FreeChannels; FSoundChan *FreeChannels;
int S_RolloffType; FRolloffInfo S_Rolloff;
float S_MinDistance;
float S_MaxDistanceOrRolloffFactor;
BYTE *S_SoundCurve; BYTE *S_SoundCurve;
int S_SoundCurveSize; int S_SoundCurveSize;
@ -812,6 +810,7 @@ static FSoundChan *S_StartSound(AActor *actor, const sector_t *sec, const FPolyO
int pitch; int pitch;
FSoundChan *chan; FSoundChan *chan;
FVector3 pos, vel; FVector3 pos, vel;
FRolloffInfo *rolloff;
if (sound_id <= 0 || volume <= 0) if (sound_id <= 0 || volume <= 0)
return NULL; return NULL;
@ -858,6 +857,7 @@ static FSoundChan *S_StartSound(AActor *actor, const sector_t *sec, const FPolyO
} }
sfx = &S_sfx[sound_id]; sfx = &S_sfx[sound_id];
rolloff = sfx->Rolloff.MinDistance == 0? &S_Rolloff : &sfx->Rolloff;
// Scale volume according to SNDINFO data. // Scale volume according to SNDINFO data.
volume = MIN(volume * sfx->Volume, 1.f); volume = MIN(volume * sfx->Volume, 1.f);
@ -1005,7 +1005,7 @@ static FSoundChan *S_StartSound(AActor *actor, const sector_t *sec, const FPolyO
{ {
SoundListener listener; SoundListener listener;
S_SetListener(listener, players[consoleplayer].camera); S_SetListener(listener, players[consoleplayer].camera);
chan = GSnd->StartSound3D (sfx, &listener, volume, attenuation, pitch, basepriority, pos, vel, channel, chanflags, NULL); chan = GSnd->StartSound3D (sfx, &listener, volume, rolloff, attenuation, pitch, basepriority, pos, vel, channel, chanflags, NULL);
} }
else else
{ {
@ -1093,7 +1093,7 @@ void S_RestartSound(FSoundChan *chan)
SoundListener listener; SoundListener listener;
S_SetListener(listener, players[consoleplayer].camera); S_SetListener(listener, players[consoleplayer].camera);
ochan = GSnd->StartSound3D(sfx, &listener, chan->Volume, chan->DistanceScale, chan->Pitch, ochan = GSnd->StartSound3D(sfx, &listener, chan->Volume, chan->Rolloff, chan->DistanceScale, chan->Pitch,
chan->Priority, pos, vel, chan->EntChannel, chan->ChanFlags, chan); chan->Priority, pos, vel, chan->EntChannel, chan->ChanFlags, chan);
} }
else else

View File

@ -27,6 +27,15 @@
class AActor; class AActor;
class FScanner; class FScanner;
// Default rolloff information.
struct FRolloffInfo
{
int RolloffType;
float MinDistance;
union { float MaxDistance; float RolloffFactor; };
};
// //
// SoundFX struct. // SoundFX struct.
// //
@ -61,8 +70,7 @@ struct sfxinfo_t
unsigned int link; unsigned int link;
enum { NO_LINK = 0xffffffff }; enum { NO_LINK = 0xffffffff };
float MinDistance; FRolloffInfo Rolloff;
union { float MaxDistance, RolloffFactor; };
}; };
// Rolloff types // Rolloff types
@ -158,10 +166,7 @@ public:
FArchive &operator<<(FArchive &arc, FSoundID &sid); FArchive &operator<<(FArchive &arc, FSoundID &sid);
// Default rolloff information. extern FRolloffInfo S_Rolloff;
extern int S_RolloffType;
extern float S_MinDistance;
extern float S_MaxDistanceOrRolloffFactor;
extern BYTE *S_SoundCurve; extern BYTE *S_SoundCurve;
extern int S_SoundCurveSize; extern int S_SoundCurveSize;
@ -174,6 +179,7 @@ struct FSoundChan
FSoundChan *NextChan; // Next channel in this list. FSoundChan *NextChan; // Next channel in this list.
FSoundChan **PrevChan; // Previous channel in this list. FSoundChan **PrevChan; // Previous channel in this list.
sfxinfo_t *SfxInfo; // Sound information. sfxinfo_t *SfxInfo; // Sound information.
FRolloffInfo *Rolloff; // Rolloff parameters (do not necessarily come from SfxInfo!)
QWORD_UNION StartTime; // Sound start time in DSP clocks. QWORD_UNION StartTime; // Sound start time in DSP clocks.
FSoundID SoundID; // Sound ID of playing sound. FSoundID SoundID; // Sound ID of playing sound.
FSoundID OrgID; // Sound ID of sound used to start this channel. FSoundID OrgID; // Sound ID of sound used to start this channel.

View File

@ -133,7 +133,7 @@ static bool ShowedBanner;
// The rolloff callback is called during FMOD::Sound::play, so we need this // The rolloff callback is called during FMOD::Sound::play, so we need this
// global variable to contain the sound info during that time for the // global variable to contain the sound info during that time for the
// callback. // callback.
static sfxinfo_t *GSfxInfo; static FRolloffInfo *GRolloff;
static float GDistScale; static float GDistScale;
// In the below lists, duplicate entries are for user selection. When // In the below lists, duplicate entries are for user selection. When
@ -1358,7 +1358,7 @@ FSoundChan *FMODSoundRenderer::StartSound(sfxinfo_t *sfx, float vol, int pitch,
freq = 0; freq = 0;
} }
GSfxInfo = sfx; GRolloff = NULL; // Do 2D sounds need rolloff?
result = Sys->playSound(FMOD_CHANNEL_FREE, (FMOD::Sound *)sfx->data, true, &chan); result = Sys->playSound(FMOD_CHANNEL_FREE, (FMOD::Sound *)sfx->data, true, &chan);
if (FMOD_OK == result) if (FMOD_OK == result)
{ {
@ -1398,7 +1398,8 @@ FSoundChan *FMODSoundRenderer::StartSound(sfxinfo_t *sfx, float vol, int pitch,
CVAR(Float, snd_3dspread, 180, 0) CVAR(Float, snd_3dspread, 180, 0)
FSoundChan *FMODSoundRenderer::StartSound3D(sfxinfo_t *sfx, SoundListener *listener, float vol, float distscale, FSoundChan *FMODSoundRenderer::StartSound3D(sfxinfo_t *sfx, SoundListener *listener, float vol,
FRolloffInfo *rolloff, float distscale,
int pitch, int priority, const FVector3 &pos, const FVector3 &vel, int pitch, int priority, const FVector3 &pos, const FVector3 &vel,
int channum, int chanflags, FSoundChan *reuse_chan) int channum, int chanflags, FSoundChan *reuse_chan)
{ {
@ -1424,7 +1425,7 @@ FSoundChan *FMODSoundRenderer::StartSound3D(sfxinfo_t *sfx, SoundListener *liste
} }
// Play it. // Play it.
GSfxInfo = sfx; GRolloff = rolloff;
GDistScale = distscale; GDistScale = distscale;
// Experiments indicate that playSound will ignore priorities and always succeed // Experiments indicate that playSound will ignore priorities and always succeed
@ -1478,9 +1479,11 @@ FSoundChan *FMODSoundRenderer::StartSound3D(sfxinfo_t *sfx, SoundListener *liste
HandleChannelDelay(chan, reuse_chan, freq); HandleChannelDelay(chan, reuse_chan, freq);
chan->setPaused(false); chan->setPaused(false);
FSoundChan *schan = CommonChannelSetup(chan, reuse_chan); FSoundChan *schan = CommonChannelSetup(chan, reuse_chan);
schan->Rolloff = rolloff;
return schan; return schan;
} }
GRolloff = NULL;
DPrintf ("Sound %s failed to play: %d\n", sfx->name.GetChars(), result); DPrintf ("Sound %s failed to play: %d\n", sfx->name.GetChars(), result);
return 0; return 0;
} }
@ -1618,7 +1621,7 @@ FSoundChan *FMODSoundRenderer::CommonChannelSetup(FMOD::Channel *chan, FSoundCha
} }
chan->setUserData(schan); chan->setUserData(schan);
chan->setCallback(FMOD_CHANNEL_CALLBACKTYPE_END, ChannelEndCallback, 0); chan->setCallback(FMOD_CHANNEL_CALLBACKTYPE_END, ChannelEndCallback, 0);
GSfxInfo = NULL; GRolloff = NULL;
return schan; return schan;
} }
@ -1906,24 +1909,9 @@ bool FMODSoundRenderer::LoadSound(sfxinfo_t *sfx)
FMOD_MODE samplemode; FMOD_MODE samplemode;
FMOD_CREATESOUNDEXINFO exinfo = { sizeof(exinfo), }; FMOD_CREATESOUNDEXINFO exinfo = { sizeof(exinfo), };
FMOD::Sound *sample; FMOD::Sound *sample;
int rolloff;
float mindist, maxdist;
samplemode = FMOD_3D | FMOD_OPENMEMORY | FMOD_SOFTWARE; samplemode = FMOD_3D | FMOD_OPENMEMORY | FMOD_SOFTWARE;
if (sfx->MaxDistance == 0)
{
mindist = S_MinDistance;
maxdist = S_MaxDistanceOrRolloffFactor;
rolloff = S_RolloffType;
}
else
{
mindist = sfx->MinDistance;
maxdist = sfx->MaxDistance;
rolloff = sfx->RolloffType;
}
sfxdata = NULL; sfxdata = NULL;
sample = NULL; sample = NULL;
@ -2003,11 +1991,6 @@ bool FMODSoundRenderer::LoadSound(sfxinfo_t *sfx)
if (sample != NULL) if (sample != NULL)
{ {
if (rolloff == ROLLOFF_Log)
{
maxdist = 10000.f;
}
sample->set3DMinMaxDistance(mindist, maxdist);
sample->setUserData(sfx); sample->setUserData(sfx);
} }
} }
@ -2138,63 +2121,46 @@ float F_CALLBACK FMODSoundRenderer::RolloffCallback(FMOD_CHANNEL *channel, float
{ {
FMOD::Channel *chan = (FMOD::Channel *)channel; FMOD::Channel *chan = (FMOD::Channel *)channel;
FSoundChan *schan; FSoundChan *schan;
// Defaults for Doom. FRolloffInfo *rolloff;
int type = ROLLOFF_Doom;
sfxinfo_t *sfx;
float min;
float max;
float factor;
float volume;
type = S_RolloffType; if (GRolloff != NULL)
factor = S_MaxDistanceOrRolloffFactor;
min = S_MinDistance;
max = S_MaxDistanceOrRolloffFactor;
if (GSfxInfo != NULL)
{ {
sfx = GSfxInfo; rolloff = GRolloff;
distance *= GDistScale; distance *= GDistScale;
} }
else if (chan->getUserData((void **)&schan) == FMOD_OK && schan != NULL) else if (chan->getUserData((void **)&schan) == FMOD_OK && schan != NULL)
{ {
sfx = schan->SfxInfo; rolloff = schan->Rolloff;
distance *= schan->DistanceScale; distance *= schan->DistanceScale;
} }
else else
{ {
return 0; return 0;
} }
if (sfx == NULL) if (rolloff == NULL)
{ {
return 0; return 0;
} }
if (sfx->MaxDistance == 0) if (distance <= rolloff->MinDistance)
{
type = sfx->RolloffType;
factor = sfx->RolloffFactor;
}
chan->get3DMinMaxDistance(&min, &max);
if (distance <= min)
{ {
return 1; return 1;
} }
if (type == ROLLOFF_Log) if (rolloff->RolloffType == ROLLOFF_Log)
{ // Logarithmic rolloff has no max distance where it goes silent. { // Logarithmic rolloff has no max distance where it goes silent.
return min / (min + factor * (distance - min)); return rolloff->MinDistance / (rolloff->MinDistance + rolloff->RolloffFactor * (distance - rolloff->MinDistance));
} }
if (distance >= max) if (distance >= rolloff->MaxDistance)
{ {
return 0; return 0;
} }
volume = (max - distance) / (max - min);
if (type == ROLLOFF_Custom && S_SoundCurve != NULL) 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; volume = S_SoundCurve[int(S_SoundCurveSize * (1 - volume))] / 127.f;
} }
if (type == ROLLOFF_Linear) if (rolloff->RolloffType == ROLLOFF_Linear)
{ {
return volume; return volume;
} }

View File

@ -26,7 +26,7 @@ public:
// Starts a sound. // Starts a sound.
FSoundChan *StartSound (sfxinfo_t *sfx, float vol, int pitch, int chanflags, FSoundChan *reuse_chan); FSoundChan *StartSound (sfxinfo_t *sfx, float vol, int pitch, int chanflags, FSoundChan *reuse_chan);
FSoundChan *StartSound3D (sfxinfo_t *sfx, SoundListener *listener, float vol, float distscale, int pitch, int priority, const FVector3 &pos, const FVector3 &vel, int channum, int chanflags, FSoundChan *reuse_chan); FSoundChan *StartSound3D (sfxinfo_t *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. // Stops a sound channel.
void StopSound (FSoundChan *chan); void StopSound (FSoundChan *chan);

View File

@ -149,7 +149,7 @@ public:
{ {
return NULL; return NULL;
} }
FSoundChan *StartSound3D (sfxinfo_t *sfx, SoundListener *listener, float vol, float distscale, int pitch, int priority, const FVector3 &pos, const FVector3 &vel, int channum, int chanflags, FSoundChan *reuse_chan) FSoundChan *StartSound3D (sfxinfo_t *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)
{ {
return NULL; return NULL;
} }

View File

@ -102,7 +102,7 @@ public:
// Starts a sound. // Starts a sound.
virtual FSoundChan *StartSound (sfxinfo_t *sfx, float vol, int pitch, int chanflags, FSoundChan *reuse_chan) = 0; virtual FSoundChan *StartSound (sfxinfo_t *sfx, float vol, int pitch, int chanflags, FSoundChan *reuse_chan) = 0;
virtual FSoundChan *StartSound3D (sfxinfo_t *sfx, SoundListener *listener, float vol, float distscale, int pitch, int priority, const FVector3 &pos, const FVector3 &vel, int channum, int chanflags, FSoundChan *reuse_chan) = 0; virtual FSoundChan *StartSound3D (sfxinfo_t *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. // Stops a sound channel.
virtual void StopSound (FSoundChan *chan) = 0; virtual void StopSound (FSoundChan *chan) = 0;