From 3ea49a66d1ddc941106819e11d85e45a08ec3d98 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 15 Jan 2023 14:01:37 +0100 Subject: [PATCH] - cleaned up the pitch management in the sound backend. This now treats all pitch methods equally instead of the preferential treatment of Doom's original pitch hack. Most importantly, the sound channel now stores the pitch as a floating point value instead of 9.7 fixed point. snd_pitched now also gets checked in the sound engine, not the low level interface. --- src/common/audio/sound/i_sound.cpp | 7 +-- src/common/audio/sound/i_sound.h | 4 +- src/common/audio/sound/oalsound.cpp | 19 +++---- src/common/audio/sound/oalsound.h | 4 +- src/common/audio/sound/s_sound.cpp | 63 +++++++++++------------- src/common/audio/sound/s_soundinternal.h | 2 +- src/sound/s_doomsound.cpp | 2 + src/version.h | 2 +- 8 files changed, 47 insertions(+), 56 deletions(-) diff --git a/src/common/audio/sound/i_sound.cpp b/src/common/audio/sound/i_sound.cpp index efd8a06e1..90fda4be2 100644 --- a/src/common/audio/sound/i_sound.cpp +++ b/src/common/audio/sound/i_sound.cpp @@ -70,9 +70,6 @@ CVAR(Int, snd_hrtf, -1, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) CVAR(String, snd_backend, DEF_BACKEND, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) -// killough 2/21/98: optionally use varying pitched sounds -CVAR (Bool, snd_pitched, false, CVAR_ARCHIVE) - SoundRenderer *GSnd; bool nosound; bool nosfx; @@ -178,11 +175,11 @@ public: } // Starts a sound. - FISoundChannel *StartSound (SoundHandle sfx, float vol, int pitch, int chanflags, FISoundChannel *reuse_chan, float startTime) + FISoundChannel *StartSound (SoundHandle sfx, float vol, float pitch, int chanflags, FISoundChannel *reuse_chan, float startTime) { return NULL; } - FISoundChannel *StartSound3D (SoundHandle sfx, SoundListener *listener, float vol, FRolloffInfo *rolloff, float distscale, int pitch, int priority, const FVector3 &pos, const FVector3 &vel, int channum, int chanflags, FISoundChannel *reuse_chan, float startTime) + FISoundChannel *StartSound3D (SoundHandle sfx, SoundListener *listener, float vol, FRolloffInfo *rolloff, float distscale, float pitch, int priority, const FVector3 &pos, const FVector3 &vel, int channum, int chanflags, FISoundChannel *reuse_chan, float startTime) { return NULL; } diff --git a/src/common/audio/sound/i_sound.h b/src/common/audio/sound/i_sound.h index 016098d48..b2f281f29 100644 --- a/src/common/audio/sound/i_sound.h +++ b/src/common/audio/sound/i_sound.h @@ -117,8 +117,8 @@ public: virtual SoundStream *CreateStream (SoundStreamCallback callback, int buffbytes, int flags, int samplerate, void *userdata) = 0; // Starts a sound. - virtual FISoundChannel *StartSound (SoundHandle sfx, float vol, int pitch, int chanflags, FISoundChannel *reuse_chan, float startTime = 0.f) = 0; - virtual FISoundChannel *StartSound3D (SoundHandle sfx, SoundListener *listener, float vol, FRolloffInfo *rolloff, float distscale, int pitch, int priority, const FVector3 &pos, const FVector3 &vel, int channum, int chanflags, FISoundChannel *reuse_chan, float startTime = 0.f) = 0; + virtual FISoundChannel *StartSound (SoundHandle sfx, float vol, float pitch, int chanflags, FISoundChannel *reuse_chan, float startTime = 0.f) = 0; + virtual FISoundChannel *StartSound3D (SoundHandle sfx, SoundListener *listener, float vol, FRolloffInfo *rolloff, float distscale, float pitch, int priority, const FVector3 &pos, const FVector3 &vel, int channum, int chanflags, FISoundChannel *reuse_chan, float startTime = 0.f) = 0; // Stops a sound channel. virtual void StopChannel (FISoundChannel *chan) = 0; diff --git a/src/common/audio/sound/oalsound.cpp b/src/common/audio/sound/oalsound.cpp index dd7af7485..81ec4cae7 100644 --- a/src/common/audio/sound/oalsound.cpp +++ b/src/common/audio/sound/oalsound.cpp @@ -110,7 +110,6 @@ ReverbContainer *ForcedEnvironment; EXTERN_CVAR (Int, snd_channels) EXTERN_CVAR (Int, snd_samplerate) EXTERN_CVAR (Bool, snd_waterreverb) -EXTERN_CVAR (Bool, snd_pitched) EXTERN_CVAR (Int, snd_hrtf) @@ -527,8 +526,6 @@ public: #define PITCH_MULT (0.7937005f) /* Approx. 4 semitones lower; what Nash suggested */ -#define PITCH(pitch) (snd_pitched ? (pitch)/128.f : 1.f) - static size_t GetChannelCount(ChannelConfig chans) { switch(chans) @@ -1224,7 +1221,7 @@ SoundStream *OpenALSoundRenderer::CreateStream(SoundStreamCallback callback, int return stream; } -FISoundChannel *OpenALSoundRenderer::StartSound(SoundHandle sfx, float vol, int pitch, int chanflags, FISoundChannel *reuse_chan, float startTime) +FISoundChannel *OpenALSoundRenderer::StartSound(SoundHandle sfx, float vol, float pitch, int chanflags, FISoundChannel *reuse_chan, float startTime) { if(FreeSfx.Size() == 0) { @@ -1270,9 +1267,9 @@ FISoundChannel *OpenALSoundRenderer::StartSound(SoundHandle sfx, float vol, int alSourcef(source, AL_ROOM_ROLLOFF_FACTOR, 0.f); } if(WasInWater && !(chanflags&SNDF_NOREVERB)) - alSourcef(source, AL_PITCH, PITCH(pitch)*PITCH_MULT); + alSourcef(source, AL_PITCH, pitch * PITCH_MULT); else - alSourcef(source, AL_PITCH, PITCH(pitch)); + alSourcef(source, AL_PITCH, pitch); if(!reuse_chan || reuse_chan->StartTime == 0) { @@ -1326,7 +1323,7 @@ FISoundChannel *OpenALSoundRenderer::StartSound(SoundHandle sfx, float vol, int } FISoundChannel *OpenALSoundRenderer::StartSound3D(SoundHandle sfx, SoundListener *listener, float vol, - FRolloffInfo *rolloff, float distscale, int pitch, int priority, const FVector3 &pos, const FVector3 &vel, + FRolloffInfo *rolloff, float distscale, float pitch, int priority, const FVector3 &pos, const FVector3 &vel, int channum, int chanflags, FISoundChannel *reuse_chan, float startTime) { float dist_sqr = (float)(pos - listener->position).LengthSquared(); @@ -1438,9 +1435,9 @@ FISoundChannel *OpenALSoundRenderer::StartSound3D(SoundHandle sfx, SoundListener alSourcef(source, AL_ROOM_ROLLOFF_FACTOR, 0.f); } if(WasInWater && !(chanflags&SNDF_NOREVERB)) - alSourcef(source, AL_PITCH, PITCH(pitch)*PITCH_MULT); + alSourcef(source, AL_PITCH, pitch * PITCH_MULT); else - alSourcef(source, AL_PITCH, PITCH(pitch)); + alSourcef(source, AL_PITCH, pitch); if(!reuse_chan || reuse_chan->StartTime == 0) { @@ -1762,7 +1759,7 @@ void OpenALSoundRenderer::UpdateListener(SoundListener *listener) { ALuint source = GET_PTRID(schan->SysChannel); if (source && !(schan->ChanFlags & CHANF_UI)) - alSourcef(source, AL_PITCH, schan->Pitch / 128.0f * PITCH_MULT); + alSourcef(source, AL_PITCH, schan->Pitch * PITCH_MULT); schan = schan->NextChan; } getALError(); @@ -1800,7 +1797,7 @@ void OpenALSoundRenderer::UpdateListener(SoundListener *listener) { ALuint source = GET_PTRID(schan->SysChannel); if (source && !(schan->ChanFlags & CHANF_UI)) - alSourcef(source, AL_PITCH, schan->Pitch / 128.0f); + alSourcef(source, AL_PITCH, schan->Pitch); schan = schan->NextChan; } getALError(); diff --git a/src/common/audio/sound/oalsound.h b/src/common/audio/sound/oalsound.h index 93436f4ec..90cb8c8bd 100644 --- a/src/common/audio/sound/oalsound.h +++ b/src/common/audio/sound/oalsound.h @@ -45,8 +45,8 @@ public: virtual SoundStream *CreateStream(SoundStreamCallback callback, int buffbytes, int flags, int samplerate, void *userdata); // Starts a sound. - virtual FISoundChannel *StartSound(SoundHandle sfx, float vol, int pitch, int chanflags, FISoundChannel *reuse_chan, float startTime); - virtual FISoundChannel *StartSound3D(SoundHandle sfx, SoundListener *listener, float vol, FRolloffInfo *rolloff, float distscale, int pitch, int priority, const FVector3 &pos, const FVector3 &vel, int channum, int chanflags, FISoundChannel *reuse_chan, float startTime); + FISoundChannel *StartSound(SoundHandle sfx, float vol, float pitch, int chanflags, FISoundChannel *reuse_chan, float startTime) override; + FISoundChannel *StartSound3D(SoundHandle sfx, SoundListener *listener, float vol, FRolloffInfo *rolloff, float distscale, float pitch, int priority, const FVector3 &pos, const FVector3 &vel, int channum, int chanflags, FISoundChannel *reuse_chan, float startTime) override; // Changes a channel's volume. virtual void ChannelVolume(FISoundChannel *chan, float volume); diff --git a/src/common/audio/sound/s_sound.cpp b/src/common/audio/sound/s_sound.cpp index 97225c87c..11c598f04 100644 --- a/src/common/audio/sound/s_sound.cpp +++ b/src/common/audio/sound/s_sound.cpp @@ -49,6 +49,8 @@ CVARD(Bool, snd_enabled, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG, "enables/disables sound effects") CVAR(Bool, i_soundinbackground, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) CVAR(Bool, i_pauseinbackground, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) +// killough 2/21/98: optionally use varying pitched sounds +CVAR(Bool, snd_pitched, false, CVAR_ARCHIVE) int SoundEnabled() { @@ -368,6 +370,31 @@ FSoundID SoundEngine::ResolveSound(const void *, int, FSoundID soundid, float &a } } +//========================================================================== +// +// +// +//========================================================================== + +static float CalcPitch(int pitchmask, float defpitch, float defpitchmax) +{ + if (defpitch > 0.0) // $PitchSet overrides $PitchShift + { + if (defpitchmax > 0.0 && defpitch != defpitchmax) + { + defpitch = pr_soundpitch.GenRand_Real1() * (defpitchmax - defpitch) + defpitch; + } + return defpitch; + } + + // Vary the sfx pitches. Overridden by $PitchSet and A_StartSound. + if (pitchmask != 0 && snd_pitched) + { + return (DEFAULT_PITCH - (pr_soundpitch() & pitchmask) + (pr_soundpitch() & pitchmask)) / (float)DEFAULT_PITCH; + } + return 1.f; +} + //========================================================================== // // S_StartSound @@ -386,7 +413,6 @@ FSoundChan *SoundEngine::StartSound(int type, const void *source, EChanFlags chanflags = flags; int basepriority; FSoundID org_id; - int pitch; FSoundChan *chan; FVector3 pos, vel; FRolloffInfo *rolloff; @@ -419,7 +445,6 @@ FSoundChan *SoundEngine::StartSound(int type, const void *source, float limit_range = sfx->LimitRange; float defpitch = sfx->DefPitch; float defpitchmax = sfx->DefPitchMax; - auto pitchmask = sfx->PitchMask; rolloff = &sfx->Rolloff; // Resolve player sounds, random sounds, and aliases @@ -542,16 +567,7 @@ FSoundChan *SoundEngine::StartSound(int type, const void *source, return NULL; } - // Vary the sfx pitches. Overridden by $PitchSet and A_StartSound. - if (pitchmask != 0) - { - pitch = DEFAULT_PITCH - (rand() & pitchmask) + (rand() & pitchmask); - } - else - { - pitch = DEFAULT_PITCH; - } - + float pitch = spitch > 0 ? spitch : CalcPitch(sfx->PitchMask, defpitch, defpitchmax); if (chanflags & CHANF_EVICTED) { chan = NULL; @@ -614,27 +630,6 @@ FSoundChan *SoundEngine::StartSound(int type, const void *source, { chan->Source = 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; @@ -1077,7 +1072,7 @@ void SoundEngine::SetPitch(FSoundChan *chan, float pitch) { assert(chan != nullptr); GSnd->ChannelPitch(chan, max(0.0001f, pitch)); - chan->Pitch = max(1, int(float(DEFAULT_PITCH) * pitch)); + chan->Pitch = pitch; } //========================================================================== diff --git a/src/common/audio/sound/s_soundinternal.h b/src/common/audio/sound/s_soundinternal.h index 562c59f15..b29081fda 100644 --- a/src/common/audio/sound/s_soundinternal.h +++ b/src/common/audio/sound/s_soundinternal.h @@ -120,7 +120,7 @@ struct FSoundChan : public FISoundChannel float Volume; int EntChannel; // Actor's sound channel. int UserData; // Not used by the engine, the caller can use this to store some additional info. - int16_t Pitch; // Pitch variation. + float Pitch; // Pitch variation. int16_t NearLimit; int8_t Priority; uint8_t SourceType; diff --git a/src/sound/s_doomsound.cpp b/src/sound/s_doomsound.cpp index 68786ae69..697fdcc3a 100644 --- a/src/sound/s_doomsound.cpp +++ b/src/sound/s_doomsound.cpp @@ -841,6 +841,8 @@ static FSerializer &Serialize(FSerializer &arc, const char *key, FSoundChan &cha ("rolloffmax", chan.Rolloff.MaxDistance) ("limitrange", chan.LimitRange); + if (SaveVersion < 4560) chan.Pitch /= 128.f; + switch (chan.SourceType) { case SOURCE_None: break; diff --git a/src/version.h b/src/version.h index a0d96719d..11a743561 100644 --- a/src/version.h +++ b/src/version.h @@ -88,7 +88,7 @@ const char *GetVersionString(); // Use 4500 as the base git save version, since it's higher than the // SVN revision ever got. -#define SAVEVER 4559 +#define SAVEVER 4560 // This is so that derivates can use the same savegame versions without worrying about engine compatibility #define GAMESIG "GZDOOM"