- 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.
This commit is contained in:
Christoph Oelckers 2023-01-15 14:01:37 +01:00
parent 5b7826f68b
commit 3ea49a66d1
8 changed files with 47 additions and 56 deletions

View file

@ -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;
}

View file

@ -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;

View file

@ -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();

View file

@ -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);

View file

@ -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;
}
//==========================================================================

View file

@ -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;

View file

@ -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;

View file

@ -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"