diff --git a/source/common/audio/sound/s_sound.cpp b/source/common/audio/sound/s_sound.cpp index 4597f57c4..a38dc9eb8 100644 --- a/source/common/audio/sound/s_sound.cpp +++ b/source/common/audio/sound/s_sound.cpp @@ -41,13 +41,14 @@ #include "m_swap.h" #include "superfasthash.h" #include "s_music.h" +#include "m_random.h" enum { DEFAULT_PITCH = 128, }; - +static FRandom pr_soundpitch ("SoundPitch"); SoundEngine* soundEngine; int sfx_empty = -1; @@ -404,6 +405,8 @@ FSoundChan *SoundEngine::StartSound(int type, const void *source, // the referenced sound so some additional checks are required 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; @@ -419,6 +422,8 @@ 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) { @@ -525,7 +530,7 @@ FSoundChan *SoundEngine::StartSound(int type, const void *source, return NULL; } - // Vary the sfx pitches. + // Vary the sfx pitches. Overridden by $PitchSet and A_StartSound. if (pitchmask != 0) { pitch = DEFAULT_PITCH - (rand() & pitchmask) + (rand() & pitchmask); @@ -549,8 +554,8 @@ FSoundChan *SoundEngine::StartSound(int type, const void *source, float sfxlength = (float)GSnd->GetMSLength(sfx->data) / 1000.f; startTime = (startflags & SNDF_LOOP) - ? (sfxlength > 0 ? fmod(startTime, sfxlength) : 0) - : clamp(startTime, 0.f, sfxlength); + ? (sfxlength > 0 ? fmodf(startTime, sfxlength) : 0.f) + : clamp(startTime, 0.f, sfxlength); if (attenuation > 0 && type != SOURCE_None) { @@ -597,9 +602,27 @@ FSoundChan *SoundEngine::StartSound(int type, const void *source, { chan->Source = source; } - - if (spitch > 0.0) + + 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; @@ -1517,6 +1540,8 @@ int SoundEngine::AddSoundLump(const char* logicalname, int lump, int CurrentPitc newsfx.Volume = 1; newsfx.Attenuation = 1; newsfx.PitchMask = CurrentPitchMask; + newsfx.DefPitch = 0.0; + newsfx.DefPitchMax = 0.0; newsfx.NearLimit = nearlimit; newsfx.LimitRange = 256 * 256; newsfx.bRandomHeader = false; @@ -1695,3 +1720,4 @@ void S_SoundReset() soundEngine->Reset(); S_RestartMusic(); } + diff --git a/source/common/audio/sound/s_soundinternal.h b/source/common/audio/sound/s_soundinternal.h index 42d60308e..58b3a27c1 100644 --- a/source/common/audio/sound/s_soundinternal.h +++ b/source/common/audio/sound/s_soundinternal.h @@ -29,6 +29,8 @@ struct sfxinfo_t uint8_t PitchMask; 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;