mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-29 07:22:05 +00:00
- sound engine update.
Notable changes: * IsSourcePlayingSomething had undefined behavior when checking unattached and unpositioned sounds. * loading Blood RAW sounds with different sample rates but the same backing lump may not use the same hardware sound buffer. * when playing an unpositioned sound the attenuation is irrelevant and must be ignored. This resulted in a 3D sound being started which was mostly inaudible due to lack of valid origin.
This commit is contained in:
parent
59f09d4893
commit
318da33e39
4 changed files with 37 additions and 10 deletions
|
@ -22,6 +22,7 @@ enum EChanFlag
|
|||
|
||||
CHANF_PICKUP = CHANF_MAYBE_LOCAL,
|
||||
|
||||
CHANF_NONE = 0,
|
||||
CHANF_IS3D = 1, // internal: Sound is 3D.
|
||||
CHANF_EVICTED = 2, // internal: Sound was evicted.
|
||||
CHANF_FORGETTABLE = 4, // internal: Forget channel data when sound stops.
|
||||
|
|
|
@ -85,7 +85,7 @@ class DoomSoundEngine : public SoundEngine
|
|||
{
|
||||
// client specific parts of the sound engine go in this class.
|
||||
|
||||
void CalcPosVel(int type, const void* source, const float pt[3], int channum, int chanflags, FSoundID soundid, FVector3* pos, FVector3* vel) override;
|
||||
void CalcPosVel(int type, const void* source, const float pt[3], int channum, int chanflags, FSoundID soundid, FVector3* pos, FVector3* vel, FSoundChan *) override;
|
||||
bool ValidatePosVel(int sourcetype, const void* source, const FVector3& pos, const FVector3& vel);
|
||||
TArray<uint8_t> ReadSound(int lumpnum);
|
||||
int PickReplacement(int refid);
|
||||
|
@ -892,7 +892,7 @@ static void CalcPolyobjSoundOrg(const DVector3& listenpos, const FPolyObj* poly,
|
|||
//
|
||||
//=========================================================================
|
||||
|
||||
void DoomSoundEngine::CalcPosVel(int type, const void* source, const float pt[3], int channum, int chanflags, FSoundID soundid, FVector3* pos, FVector3* vel)
|
||||
void DoomSoundEngine::CalcPosVel(int type, const void* source, const float pt[3], int channum, int chanflags, FSoundID soundid, FVector3* pos, FVector3* vel, FSoundChan *)
|
||||
{
|
||||
if (pos != nullptr)
|
||||
{
|
||||
|
|
|
@ -335,7 +335,7 @@ FString SoundEngine::ListSoundChannels()
|
|||
|
||||
void SoundEngine::CalcPosVel(FSoundChan *chan, FVector3 *pos, FVector3 *vel)
|
||||
{
|
||||
CalcPosVel(chan->SourceType, chan->Source, chan->Point, chan->EntChannel, chan->ChanFlags, chan->OrgID, pos, vel);
|
||||
CalcPosVel(chan->SourceType, chan->Source, chan->Point, chan->EntChannel, chan->ChanFlags, chan->OrgID, pos, vel, chan);
|
||||
}
|
||||
|
||||
bool SoundEngine::ValidatePosVel(const FSoundChan* const chan, const FVector3& pos, const FVector3& vel)
|
||||
|
@ -397,7 +397,7 @@ FSoundChan *SoundEngine::StartSound(int type, const void *source,
|
|||
|
||||
org_id = sound_id;
|
||||
|
||||
CalcPosVel(type, source, &pt->X, channel, chanflags, sound_id, &pos, &vel);
|
||||
CalcPosVel(type, source, &pt->X, channel, chanflags, sound_id, &pos, &vel, nullptr);
|
||||
|
||||
if (!ValidatePosVel(type, source, pos, vel))
|
||||
{
|
||||
|
@ -577,7 +577,7 @@ FSoundChan *SoundEngine::StartSound(int type, const void *source,
|
|||
if (chanflags & (CHANF_UI|CHANF_NOPAUSE)) startflags |= SNDF_NOPAUSE;
|
||||
if (chanflags & CHANF_UI) startflags |= SNDF_NOREVERB;
|
||||
|
||||
if (attenuation > 0)
|
||||
if (attenuation > 0 && type != SOURCE_None)
|
||||
{
|
||||
LoadSound3D(sfx, &SoundBuffer);
|
||||
chan = (FSoundChan*)GSnd->StartSound3D (sfx->data3d, &listener, float(volume), rolloff, float(attenuation), pitch, basepriority, pos, vel, channel, startflags, NULL);
|
||||
|
@ -727,7 +727,8 @@ sfxinfo_t *SoundEngine::LoadSound(sfxinfo_t *sfx, FSoundLoadBuffer *pBuffer)
|
|||
// then set this one up as a link, and don't load the sound again.
|
||||
for (i = 0; i < S_sfx.Size(); i++)
|
||||
{
|
||||
if (S_sfx[i].data.isValid() && S_sfx[i].link == sfxinfo_t::NO_LINK && S_sfx[i].lumpnum == sfx->lumpnum)
|
||||
if (S_sfx[i].data.isValid() && S_sfx[i].link == sfxinfo_t::NO_LINK && S_sfx[i].lumpnum == sfx->lumpnum &&
|
||||
(!sfx->bLoadRAW || (sfx->RawRate == S_sfx[i].RawRate))) // Raw sounds with different sample rates may not share buffers, even if they use the same source data.
|
||||
{
|
||||
//DPrintf (DMSG_NOTIFY, "Linked %s to %s (%d)\n", sfx->name.GetChars(), S_sfx[i].name.GetChars(), i);
|
||||
sfx->link = i;
|
||||
|
@ -1060,6 +1061,16 @@ void SoundEngine::ChangeSoundVolume(int sourcetype, const void *source, int chan
|
|||
return;
|
||||
}
|
||||
|
||||
void SoundEngine::SetVolume(FSoundChan* chan, float volume)
|
||||
{
|
||||
if (volume < 0.0) volume = 0.0;
|
||||
else if (volume > 1.0) volume = 1.0;
|
||||
|
||||
assert(chan != nullptr);
|
||||
GSnd->ChannelVolume(chan, volume);
|
||||
chan->Volume = volume;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// S_ChangeSoundPitch
|
||||
|
@ -1153,7 +1164,7 @@ bool SoundEngine::IsSourcePlayingSomething (int sourcetype, const void *actor, i
|
|||
{
|
||||
for (FSoundChan *chan = Channels; chan != NULL; chan = chan->NextChan)
|
||||
{
|
||||
if (chan->SourceType == sourcetype && chan->Source == actor)
|
||||
if (chan->SourceType == sourcetype && (sourcetype == SOURCE_None || sourcetype == SOURCE_Unattached || chan->Source == actor))
|
||||
{
|
||||
if ((channel == 0 || chan->EntChannel == channel) && (sound_id <= 0 || chan->OrgID == sound_id))
|
||||
{
|
||||
|
@ -1558,6 +1569,14 @@ int SoundEngine::AddSoundLump(const char* logicalname, int lump, int CurrentPitc
|
|||
return (int)S_sfx.Size()-1;
|
||||
}
|
||||
|
||||
int SoundEngine::AddSfx(sfxinfo_t &sfx)
|
||||
{
|
||||
S_sfx.Push(sfx);
|
||||
if (sfx.ResourceId >= 0) ResIdMap[sfx.ResourceId] = S_sfx.Size() - 1;
|
||||
return (int)S_sfx.Size() - 1;
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// S_FindSoundTentative
|
||||
|
|
|
@ -262,7 +262,7 @@ private:
|
|||
|
||||
bool IsChannelUsed(int sourcetype, const void* actor, int channel, int* seen);
|
||||
// This is the actual sound positioning logic which needs to be provided by the client.
|
||||
virtual void CalcPosVel(int type, const void* source, const float pt[3], int channel, int chanflags, FSoundID chanSound, FVector3* pos, FVector3* vel) = 0;
|
||||
virtual void CalcPosVel(int type, const void* source, const float pt[3], int channel, int chanflags, FSoundID chanSound, FVector3* pos, FVector3* vel, FSoundChan *chan) = 0;
|
||||
// This can be overridden by the clent to provide some diagnostics. The default lets everything pass.
|
||||
virtual bool ValidatePosVel(int sourcetype, const void* source, const FVector3& pos, const FVector3& vel) { return true; }
|
||||
|
||||
|
@ -293,6 +293,7 @@ public:
|
|||
|
||||
void StopAllChannels(void);
|
||||
void SetPitch(FSoundChan* chan, float dpitch);
|
||||
void SetVolume(FSoundChan* chan, float vol);
|
||||
|
||||
FSoundChan* GetChannel(void* syschan);
|
||||
void RestoreEvictedChannels();
|
||||
|
@ -316,7 +317,7 @@ public:
|
|||
void RelinkSound(int sourcetype, const void* from, const void* to, const FVector3* optpos);
|
||||
void ChangeSoundVolume(int sourcetype, const void* source, int channel, double dvolume);
|
||||
void ChangeSoundPitch(int sourcetype, const void* source, int channel, double pitch, int sound_id = -1);
|
||||
bool IsSourcePlayingSomething(int sourcetype, const void* actor, int channel, int sound_id);
|
||||
bool IsSourcePlayingSomething(int sourcetype, const void* actor, int channel, int sound_id = -1);
|
||||
|
||||
// Stop and resume music, during game PAUSE.
|
||||
int GetSoundPlayingInfo(int sourcetype, const void* source, int sound_id);
|
||||
|
@ -375,12 +376,17 @@ public:
|
|||
{
|
||||
S_rnd.Clear();
|
||||
}
|
||||
bool isValidSoundId(int id)
|
||||
{
|
||||
return id > 0 && id < (int)S_sfx.Size() && !S_sfx[id].bTentative && S_sfx[id].lumpnum != sfx_empty;
|
||||
}
|
||||
|
||||
template<class func> bool EnumerateChannels(func callback)
|
||||
{
|
||||
for (FSoundChan* chan = Channels; chan; chan = chan->NextChan)
|
||||
{
|
||||
if (callback(chan)) return true;
|
||||
int res = callback(chan);
|
||||
if (res) return res > 0;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -403,6 +409,7 @@ public:
|
|||
int FindSoundNoHash(const char* logicalname);
|
||||
int FindSoundByLump(int lump);
|
||||
int AddSoundLump(const char* logicalname, int lump, int CurrentPitchMask, int resid = -1, int nearlimit = 2);
|
||||
int AddSfx(sfxinfo_t &sfx);
|
||||
int FindSoundTentative(const char* name);
|
||||
void CacheRandomSound(sfxinfo_t* sfx);
|
||||
unsigned int GetMSLength(FSoundID sound);
|
||||
|
|
Loading…
Reference in a new issue