diff --git a/src/sound/s_advsound.cpp b/src/sound/s_advsound.cpp index ae0a6002f..1c48544f1 100644 --- a/src/sound/s_advsound.cpp +++ b/src/sound/s_advsound.cpp @@ -1079,13 +1079,21 @@ static void S_AddSNDINFO (int lump) break; case SI_PitchSet: { - // $pitchset + // $pitchset [range maximum] int sfx; sc.MustGetString(); sfx = soundEngine->FindSoundTentative(sc.String); sc.MustGetFloat(); S_sfx[sfx].DefPitch = (float)sc.Float; + if (sc.CheckFloat()) + { + S_sfx[sfx].DefPitchMax = (float)sc.Float; + } + else + { + S_sfx[sfx].DefPitchMax = 0; + } } break; diff --git a/src/sound/s_sound.cpp b/src/sound/s_sound.cpp index 032bf00e9..9c066c30c 100644 --- a/src/sound/s_sound.cpp +++ b/src/sound/s_sound.cpp @@ -44,13 +44,14 @@ #include "s_soundinternal.h" #include "m_swap.h" #include "superfasthash.h" +#include "m_random.h" enum { DEFAULT_PITCH = 128, }; - +static FRandom pr_soundpitch ("SoundPitch"); SoundEngine* soundEngine; int sfx_empty = -1; @@ -411,6 +412,7 @@ FSoundChan *SoundEngine::StartSound(int type, const void *source, int near_limit = sfx->NearLimit; float limit_range = sfx->LimitRange; float defpitch = sfx->DefPitch; + float defpitchmax = sfx->DefPitchMax; auto pitchmask = sfx->PitchMask; rolloff = &sfx->Rolloff; @@ -427,6 +429,7 @@ FSoundChan *SoundEngine::StartSound(int type, const void *source, near_limit = newsfx->NearLimit; limit_range = newsfx->LimitRange; defpitch = newsfx->DefPitch; + defpitchmax = newsfx->DefPitchMax; } if (rolloff->MinDistance == 0) { @@ -609,7 +612,23 @@ FSoundChan *SoundEngine::StartSound(int type, const void *source, if (spitch > 0.0) // A_StartSound has top priority over all others. SetPitch(chan, spitch); else if (defpitch > 0.0) // $PitchSet overrides $PitchShift + { + if (defpitchmax > 0.0) + { + if (defpitchmax < defpitch) + std::swap(defpitch, defpitchmax); + + if (defpitch != defpitchmax) + { + FRandom &rng = pr_soundpitch; + int random = (rng)(0x7FFF); + float frandom = random / float(0x7FFF); + + defpitch = frandom * (defpitchmax - defpitch) + defpitch; + } + } SetPitch(chan, defpitch); + } } return chan; @@ -1506,6 +1525,7 @@ int SoundEngine::AddSoundLump(const char* logicalname, int lump, int CurrentPitc newsfx.Attenuation = 1; newsfx.PitchMask = CurrentPitchMask; newsfx.DefPitch = 0.0; + newsfx.DefPitchMax = 0.0; newsfx.NearLimit = nearlimit; newsfx.LimitRange = 256 * 256; newsfx.bRandomHeader = false; diff --git a/src/sound/s_soundinternal.h b/src/sound/s_soundinternal.h index efc320b01..a38176bbd 100644 --- a/src/sound/s_soundinternal.h +++ b/src/sound/s_soundinternal.h @@ -30,6 +30,7 @@ struct sfxinfo_t int16_t NearLimit; // 0 means unlimited float LimitRange; // Range for sound limiting (squared for faster computations) float DefPitch; // A defined pitch instead of a random one the sound plays at, similar to A_StartSound. + float DefPitchMax; // Randomized range with stronger control over pitch itself. unsigned bRandomHeader:1; unsigned bLoadRAW:1;