diff --git a/src/sound/backend/i_soundinternal.h b/src/sound/backend/i_soundinternal.h index aac498b00..08dd311a2 100644 --- a/src/sound/backend/i_soundinternal.h +++ b/src/sound/backend/i_soundinternal.h @@ -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. diff --git a/src/sound/s_doomsound.cpp b/src/sound/s_doomsound.cpp index 165481c70..d2f551597 100644 --- a/src/sound/s_doomsound.cpp +++ b/src/sound/s_doomsound.cpp @@ -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 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) { diff --git a/src/sound/s_sound.cpp b/src/sound/s_sound.cpp index 832ad145e..d07b744d2 100644 --- a/src/sound/s_sound.cpp +++ b/src/sound/s_sound.cpp @@ -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 diff --git a/src/sound/s_soundinternal.h b/src/sound/s_soundinternal.h index bbcd73370..2865e766b 100644 --- a/src/sound/s_soundinternal.h +++ b/src/sound/s_soundinternal.h @@ -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 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);