diff --git a/src/engine/client/sound.cpp b/src/engine/client/sound.cpp index 6813cde9f..63df6cdb5 100644 --- a/src/engine/client/sound.cpp +++ b/src/engine/client/sound.cpp @@ -63,12 +63,10 @@ void CSound::Mix(short *pFinalOut, unsigned Frames) if(Voice.m_Flags & ISound::FLAG_POS && Voice.m_pChannel->m_Pan) { // TODO: we should respect the channel panning value - const int dx = Voice.m_X - m_CenterX.load(std::memory_order_relaxed); - const int dy = Voice.m_Y - m_CenterY.load(std::memory_order_relaxed); - float FalloffX = 0.0f; - float FalloffY = 0.0f; + const vec2 Delta = Voice.m_Position - vec2(m_ListenerPositionX.load(std::memory_order_relaxed), m_ListenerPositionY.load(std::memory_order_relaxed)); + vec2 Falloff = vec2(0.0f, 0.0f); - int RangeX = 0; // for panning + float RangeX = 0.0f; // for panning bool InVoiceField = false; switch(Voice.m_Shape) @@ -78,50 +76,34 @@ void CSound::Mix(short *pFinalOut, unsigned Frames) const float Radius = Voice.m_Circle.m_Radius; RangeX = Radius; - // dx and dy can be larger than 46341 and thus the calculation would go beyond the limits of a integer, - // therefore we cast them into float - const int Dist = (int)length(vec2(dx, dy)); + const float Dist = length(Delta); if(Dist < Radius) { InVoiceField = true; // falloff - int FalloffDistance = Radius * Voice.m_Falloff; - if(Dist > FalloffDistance) - FalloffX = FalloffY = (Radius - Dist) / (Radius - FalloffDistance); - else - FalloffX = FalloffY = 1.0f; + const float FalloffDistance = Radius * Voice.m_Falloff; + Falloff.x = Falloff.y = Dist > FalloffDistance ? (Radius - Dist) / (Radius - FalloffDistance) : 1.0f; } - else - InVoiceField = false; - break; } case ISound::SHAPE_RECTANGLE: { - RangeX = Voice.m_Rectangle.m_Width / 2.0f; + const vec2 AbsoluteDelta = vec2(absolute(Delta.x), absolute(Delta.y)); + const float w = Voice.m_Rectangle.m_Width / 2.0f; + const float h = Voice.m_Rectangle.m_Height / 2.0f; + RangeX = w; - const int abs_dx = absolute(dx); - const int abs_dy = absolute(dy); - - const int w = Voice.m_Rectangle.m_Width / 2.0f; - const int h = Voice.m_Rectangle.m_Height / 2.0f; - - if(abs_dx < w && abs_dy < h) + if(AbsoluteDelta.x < w && AbsoluteDelta.y < h) { InVoiceField = true; // falloff - int fx = Voice.m_Falloff * w; - int fy = Voice.m_Falloff * h; - - FalloffX = abs_dx > fx ? (float)(w - abs_dx) / (w - fx) : 1.0f; - FalloffY = abs_dy > fy ? (float)(h - abs_dy) / (h - fy) : 1.0f; + const vec2 FalloffDistance = vec2(w, h) * Voice.m_Falloff; + Falloff.x = AbsoluteDelta.x > FalloffDistance.x ? (w - AbsoluteDelta.x) / (w - FalloffDistance.x) : 1.0f; + Falloff.y = AbsoluteDelta.y > FalloffDistance.y ? (h - AbsoluteDelta.y) / (h - FalloffDistance.y) : 1.0f; } - else - InVoiceField = false; - break; } }; @@ -131,15 +113,15 @@ void CSound::Mix(short *pFinalOut, unsigned Frames) // panning if(!(Voice.m_Flags & ISound::FLAG_NO_PANNING)) { - if(dx > 0) - VolumeL = ((RangeX - absolute(dx)) * VolumeL) / RangeX; + if(Delta.x > 0) + VolumeL = ((RangeX - absolute(Delta.x)) * VolumeL) / RangeX; else - VolumeR = ((RangeX - absolute(dx)) * VolumeR) / RangeX; + VolumeR = ((RangeX - absolute(Delta.x)) * VolumeR) / RangeX; } { - VolumeL *= FalloffX * FalloffY; - VolumeR *= FalloffX * FalloffY; + VolumeL *= Falloff.x * Falloff.y; + VolumeR *= Falloff.x * Falloff.y; } } else @@ -723,10 +705,10 @@ void CSound::SetChannel(int ChannelId, float Vol, float Pan) m_aChannels[ChannelId].m_Pan = (int)(Pan * 255.0f); // TODO: this is only on and off right now } -void CSound::SetListenerPos(float x, float y) +void CSound::SetListenerPosition(vec2 Position) { - m_CenterX.store((int)x, std::memory_order_relaxed); - m_CenterY.store((int)y, std::memory_order_relaxed); + m_ListenerPositionX.store(Position.x, std::memory_order_relaxed); + m_ListenerPositionY.store(Position.y, std::memory_order_relaxed); } void CSound::SetVoiceVolume(CVoiceHandle Voice, float Volume) @@ -759,7 +741,7 @@ void CSound::SetVoiceFalloff(CVoiceHandle Voice, float Falloff) m_aVoices[VoiceId].m_Falloff = Falloff; } -void CSound::SetVoiceLocation(CVoiceHandle Voice, float x, float y) +void CSound::SetVoicePosition(CVoiceHandle Voice, vec2 Position) { if(!Voice.IsValid()) return; @@ -770,8 +752,7 @@ void CSound::SetVoiceLocation(CVoiceHandle Voice, float x, float y) if(m_aVoices[VoiceId].m_Age != Voice.Age()) return; - m_aVoices[VoiceId].m_X = x; - m_aVoices[VoiceId].m_Y = y; + m_aVoices[VoiceId].m_Position = Position; } void CSound::SetVoiceTimeOffset(CVoiceHandle Voice, float TimeOffset) @@ -839,7 +820,7 @@ void CSound::SetVoiceRectangle(CVoiceHandle Voice, float Width, float Height) m_aVoices[VoiceId].m_Rectangle.m_Height = maximum(0.0f, Height); } -ISound::CVoiceHandle CSound::Play(int ChannelId, int SampleId, int Flags, float x, float y) +ISound::CVoiceHandle CSound::Play(int ChannelId, int SampleId, int Flags, float Volume, vec2 Position) { const CLockScope LockScope(m_SoundLock); @@ -875,10 +856,9 @@ ISound::CVoiceHandle CSound::Play(int ChannelId, int SampleId, int Flags, float { m_aVoices[VoiceId].m_Tick = 0; } - m_aVoices[VoiceId].m_Vol = 255; + m_aVoices[VoiceId].m_Vol = (int)(clamp(Volume, 0.0f, 1.0f) * 255.0f); m_aVoices[VoiceId].m_Flags = Flags; - m_aVoices[VoiceId].m_X = (int)x; - m_aVoices[VoiceId].m_Y = (int)y; + m_aVoices[VoiceId].m_Position = Position; m_aVoices[VoiceId].m_Falloff = 0.0f; m_aVoices[VoiceId].m_Shape = ISound::SHAPE_CIRCLE; m_aVoices[VoiceId].m_Circle.m_Radius = 1500; @@ -888,14 +868,14 @@ ISound::CVoiceHandle CSound::Play(int ChannelId, int SampleId, int Flags, float return CreateVoiceHandle(VoiceId, Age); } -ISound::CVoiceHandle CSound::PlayAt(int ChannelId, int SampleId, int Flags, float x, float y) +ISound::CVoiceHandle CSound::PlayAt(int ChannelId, int SampleId, int Flags, float Volume, vec2 Position) { - return Play(ChannelId, SampleId, Flags | ISound::FLAG_POS, x, y); + return Play(ChannelId, SampleId, Flags | ISound::FLAG_POS, Volume, Position); } -ISound::CVoiceHandle CSound::Play(int ChannelId, int SampleId, int Flags) +ISound::CVoiceHandle CSound::Play(int ChannelId, int SampleId, int Flags, float Volume) { - return Play(ChannelId, SampleId, Flags, 0, 0); + return Play(ChannelId, SampleId, Flags, Volume, vec2(0.0f, 0.0f)); } void CSound::Pause(int SampleId) diff --git a/src/engine/client/sound.h b/src/engine/client/sound.h index d688ed955..f7cc4b82c 100644 --- a/src/engine/client/sound.h +++ b/src/engine/client/sound.h @@ -44,7 +44,7 @@ struct CVoice int m_Tick; int m_Vol; // 0 - 255 int m_Flags; - int m_X, m_Y; + vec2 m_Position; float m_Falloff; // [0.0, 1.0] int m_Shape; @@ -76,8 +76,10 @@ class CSound : public IEngineSound int m_NextVoice = 0; uint32_t m_MaxFrames = 0; - std::atomic m_CenterX = 0; - std::atomic m_CenterY = 0; + // This is not an std::atomic as this would require linking with + // libatomic with clang x86 as there is no native support for this. + std::atomic m_ListenerPositionX = 0.0f; + std::atomic m_ListenerPositionY = 0.0f; std::atomic m_SoundVolume = 100; int m_MixingRate = 48000; @@ -112,19 +114,19 @@ public: void SetSampleCurrentTime(int SampleId, float Time) override REQUIRES(!m_SoundLock); void SetChannel(int ChannelId, float Vol, float Pan) override; - void SetListenerPos(float x, float y) override; + void SetListenerPosition(vec2 Position) override; void SetVoiceVolume(CVoiceHandle Voice, float Volume) override REQUIRES(!m_SoundLock); void SetVoiceFalloff(CVoiceHandle Voice, float Falloff) override REQUIRES(!m_SoundLock); - void SetVoiceLocation(CVoiceHandle Voice, float x, float y) override REQUIRES(!m_SoundLock); + void SetVoicePosition(CVoiceHandle Voice, vec2 Position) override REQUIRES(!m_SoundLock); void SetVoiceTimeOffset(CVoiceHandle Voice, float TimeOffset) override REQUIRES(!m_SoundLock); // in s void SetVoiceCircle(CVoiceHandle Voice, float Radius) override REQUIRES(!m_SoundLock); void SetVoiceRectangle(CVoiceHandle Voice, float Width, float Height) override REQUIRES(!m_SoundLock); - CVoiceHandle Play(int ChannelId, int SampleId, int Flags, float x, float y) REQUIRES(!m_SoundLock); - CVoiceHandle PlayAt(int ChannelId, int SampleId, int Flags, float x, float y) override REQUIRES(!m_SoundLock); - CVoiceHandle Play(int ChannelId, int SampleId, int Flags) override REQUIRES(!m_SoundLock); + CVoiceHandle Play(int ChannelId, int SampleId, int Flags, float Volume, vec2 Position) REQUIRES(!m_SoundLock); + CVoiceHandle PlayAt(int ChannelId, int SampleId, int Flags, float Volume, vec2 Position) override REQUIRES(!m_SoundLock); + CVoiceHandle Play(int ChannelId, int SampleId, int Flags, float Volume) override REQUIRES(!m_SoundLock); void Pause(int SampleId) override REQUIRES(!m_SoundLock); void Stop(int SampleId) override REQUIRES(!m_SoundLock); void StopAll() override REQUIRES(!m_SoundLock); diff --git a/src/engine/sound.h b/src/engine/sound.h index 43c354124..e4462a95a 100644 --- a/src/engine/sound.h +++ b/src/engine/sound.h @@ -6,6 +6,8 @@ #include #include +#include + class ISound : public IInterface { MACRO_INTERFACE("sound") @@ -74,18 +76,18 @@ public: virtual void SetSampleCurrentTime(int SampleId, float Time) = 0; virtual void SetChannel(int ChannelId, float Volume, float Panning) = 0; - virtual void SetListenerPos(float x, float y) = 0; + virtual void SetListenerPosition(vec2 Position) = 0; virtual void SetVoiceVolume(CVoiceHandle Voice, float Volume) = 0; virtual void SetVoiceFalloff(CVoiceHandle Voice, float Falloff) = 0; - virtual void SetVoiceLocation(CVoiceHandle Voice, float x, float y) = 0; + virtual void SetVoicePosition(CVoiceHandle Voice, vec2 Position) = 0; virtual void SetVoiceTimeOffset(CVoiceHandle Voice, float TimeOffset) = 0; // in s virtual void SetVoiceCircle(CVoiceHandle Voice, float Radius) = 0; virtual void SetVoiceRectangle(CVoiceHandle Voice, float Width, float Height) = 0; - virtual CVoiceHandle PlayAt(int ChannelId, int SampleId, int Flags, float x, float y) = 0; - virtual CVoiceHandle Play(int ChannelId, int SampleId, int Flags) = 0; + virtual CVoiceHandle PlayAt(int ChannelId, int SampleId, int Flags, float Volume, vec2 Position) = 0; + virtual CVoiceHandle Play(int ChannelId, int SampleId, int Flags, float Volume) = 0; virtual void Pause(int SampleId) = 0; virtual void Stop(int SampleId) = 0; virtual void StopAll() = 0; diff --git a/src/game/client/components/chat.cpp b/src/game/client/components/chat.cpp index c31098abc..877978726 100644 --- a/src/game/client/components/chat.cpp +++ b/src/game/client/components/chat.cpp @@ -822,7 +822,7 @@ void CChat::AddLine(int ClientId, int Team, const char *pLine) { if(g_Config.m_SndServerMessage) { - m_pClient->m_Sounds.Play(CSounds::CHN_GUI, SOUND_CHAT_SERVER, 0); + m_pClient->m_Sounds.Play(CSounds::CHN_GUI, SOUND_CHAT_SERVER, 1.0f); m_aLastSoundPlayed[CHAT_SERVER] = Now; } } @@ -840,7 +840,7 @@ void CChat::AddLine(int ClientId, int Team, const char *pLine) Client()->Notify("DDNet Chat", aBuf); if(g_Config.m_SndHighlight) { - m_pClient->m_Sounds.Play(CSounds::CHN_GUI, SOUND_CHAT_HIGHLIGHT, 0); + m_pClient->m_Sounds.Play(CSounds::CHN_GUI, SOUND_CHAT_HIGHLIGHT, 1.0f); m_aLastSoundPlayed[CHAT_HIGHLIGHT] = Now; } @@ -863,7 +863,7 @@ void CChat::AddLine(int ClientId, int Team, const char *pLine) #endif if(PlaySound) { - m_pClient->m_Sounds.Play(CSounds::CHN_GUI, SOUND_CHAT_CLIENT, 0); + m_pClient->m_Sounds.Play(CSounds::CHN_GUI, SOUND_CHAT_CLIENT, 1.0f); m_aLastSoundPlayed[CHAT_CLIENT] = Now; } } diff --git a/src/game/client/components/mapsounds.cpp b/src/game/client/components/mapsounds.cpp index 0ddae91c2..eee0017fc 100644 --- a/src/game/client/components/mapsounds.cpp +++ b/src/game/client/components/mapsounds.cpp @@ -22,15 +22,15 @@ void CMapSounds::Play(int SoundId) if(SoundId < 0 || SoundId >= m_Count) return; - m_pClient->m_Sounds.PlaySample(CSounds::CHN_MAPSOUND, m_aSounds[SoundId], 1.0f, 0); + m_pClient->m_Sounds.PlaySample(CSounds::CHN_MAPSOUND, m_aSounds[SoundId], 0, 1.0f); } -void CMapSounds::PlayAt(int SoundId, vec2 Pos) +void CMapSounds::PlayAt(int SoundId, vec2 Position) { if(SoundId < 0 || SoundId >= m_Count) return; - m_pClient->m_Sounds.PlaySampleAt(CSounds::CHN_MAPSOUND, m_aSounds[SoundId], 1.0f, Pos, 0); + m_pClient->m_Sounds.PlaySampleAt(CSounds::CHN_MAPSOUND, m_aSounds[SoundId], 0, 1.0f, Position); } void CMapSounds::OnMapLoad() @@ -163,7 +163,7 @@ void CMapSounds::OnRender() if(!Source.m_pSource->m_Pan) Flags |= ISound::FLAG_NO_PANNING; - Source.m_Voice = m_pClient->m_Sounds.PlaySampleAt(CSounds::CHN_MAPSOUND, m_aSounds[Source.m_Sound], 1.0f, vec2(fx2f(Source.m_pSource->m_Position.x), fx2f(Source.m_pSource->m_Position.y)), Flags); + Source.m_Voice = m_pClient->m_Sounds.PlaySampleAt(CSounds::CHN_MAPSOUND, m_aSounds[Source.m_Sound], Flags, 1.0f, vec2(fx2f(Source.m_pSource->m_Position.x), fx2f(Source.m_pSource->m_Position.y))); Sound()->SetVoiceTimeOffset(Source.m_Voice, Offset); Sound()->SetVoiceFalloff(Source.m_Voice, Source.m_pSource->m_Falloff / 255.0f); switch(Source.m_pSource->m_Shape.m_Type) @@ -239,7 +239,7 @@ void CMapSounds::OnRender() x -= pGroup->m_OffsetX; y -= pGroup->m_OffsetY; - Sound()->SetVoiceLocation(Voice.m_Voice, x, y); + Sound()->SetVoicePosition(Voice.m_Voice, vec2(x, y)); ColorRGBA Volume = ColorRGBA(1.0f, 0.0f, 0.0f, 0.0f); CMapLayers::EnvelopeEval(Voice.m_pSource->m_SoundEnvOffset, Voice.m_pSource->m_SoundEnv, Volume, 1, &m_pClient->m_MapLayersBackground); diff --git a/src/game/client/components/mapsounds.h b/src/game/client/components/mapsounds.h index 2f89d402b..a623303aa 100644 --- a/src/game/client/components/mapsounds.h +++ b/src/game/client/components/mapsounds.h @@ -34,7 +34,7 @@ public: virtual int Sizeof() const override { return sizeof(*this); } void Play(int SoundId); - void PlayAt(int SoundId, vec2 Pos); + void PlayAt(int SoundId, vec2 Position); virtual void OnMapLoad() override; virtual void OnRender() override; diff --git a/src/game/client/components/players.cpp b/src/game/client/components/players.cpp index 85ea937ba..3876c5331 100644 --- a/src/game/client/components/players.cpp +++ b/src/game/client/components/players.cpp @@ -526,7 +526,7 @@ void CPlayers::RenderPlayer( if(time() - m_SkidSoundTime > time_freq() / 10) { if(g_Config.m_SndGame) - m_pClient->m_Sounds.PlayAt(CSounds::CHN_WORLD, SOUND_PLAYER_SKID, 0.25f, Position); + m_pClient->m_Sounds.PlayAt(CSounds::CHN_WORLD, SOUND_PLAYER_SKID, 1.0f, Position); m_SkidSoundTime = time(); } diff --git a/src/game/client/components/sounds.cpp b/src/game/client/components/sounds.cpp index 073fc40be..d04a20fdf 100644 --- a/src/game/client/components/sounds.cpp +++ b/src/game/client/components/sounds.cpp @@ -43,6 +43,38 @@ void CSoundLoading::Run() } } +void CSounds::UpdateChannels() +{ + const float NewGuiSoundVolume = g_Config.m_SndChatSoundVolume / 100.0f; + if(NewGuiSoundVolume != m_GuiSoundVolume) + { + m_GuiSoundVolume = NewGuiSoundVolume; + Sound()->SetChannel(CSounds::CHN_GUI, m_GuiSoundVolume, 0.0f); + } + + const float NewGameSoundVolume = g_Config.m_SndGameSoundVolume / 100.0f; + if(NewGameSoundVolume != m_GameSoundVolume) + { + m_GameSoundVolume = NewGameSoundVolume; + Sound()->SetChannel(CSounds::CHN_WORLD, 0.9f * m_GameSoundVolume, 1.0f); + Sound()->SetChannel(CSounds::CHN_GLOBAL, m_GameSoundVolume, 0.0f); + } + + const float NewMapSoundVolume = g_Config.m_SndMapSoundVolume / 100.0f; + if(NewMapSoundVolume != m_MapSoundVolume) + { + m_MapSoundVolume = NewMapSoundVolume; + Sound()->SetChannel(CSounds::CHN_MAPSOUND, m_MapSoundVolume, 1.0f); + } + + const float NewBackgroundMusicVolume = g_Config.m_SndBackgroundMusicVolume / 100.0f; + if(NewBackgroundMusicVolume != m_BackgroundMusicVolume) + { + m_BackgroundMusicVolume = NewBackgroundMusicVolume; + Sound()->SetChannel(CSounds::CHN_MUSIC, m_BackgroundMusicVolume, 1.0f); + } +} + int CSounds::GetSampleId(int SetId) { if(!g_Config.m_SndEnable || !Sound()->IsSoundEnabled() || m_WaitForSoundJob || SetId < 0 || SetId >= g_pData->m_NumSounds) @@ -67,20 +99,7 @@ int CSounds::GetSampleId(int SetId) void CSounds::OnInit() { - // setup sound channels - m_GuiSoundVolume = g_Config.m_SndChatSoundVolume / 100.0f; - m_GameSoundVolume = g_Config.m_SndGameSoundVolume / 100.0f; - m_MapSoundVolume = g_Config.m_SndMapSoundVolume / 100.0f; - m_BackgroundMusicVolume = g_Config.m_SndBackgroundMusicVolume / 100.0f; - - Sound()->SetChannel(CSounds::CHN_GUI, m_GuiSoundVolume, 0.0f); - Sound()->SetChannel(CSounds::CHN_MUSIC, m_BackgroundMusicVolume, 1.0f); - Sound()->SetChannel(CSounds::CHN_WORLD, 0.9f * m_GameSoundVolume, 1.0f); - Sound()->SetChannel(CSounds::CHN_GLOBAL, m_GameSoundVolume, 0.0f); - Sound()->SetChannel(CSounds::CHN_MAPSOUND, m_MapSoundVolume, 1.0f); - - Sound()->SetListenerPos(0.0f, 0.0f); - + UpdateChannels(); ClearQueue(); // load sounds @@ -124,38 +143,8 @@ void CSounds::OnRender() return; } - // set listener pos - Sound()->SetListenerPos(m_pClient->m_Camera.m_Center.x, m_pClient->m_Camera.m_Center.y); - - // update volume - float NewGuiSoundVol = g_Config.m_SndChatSoundVolume / 100.0f; - if(NewGuiSoundVol != m_GuiSoundVolume) - { - m_GuiSoundVolume = NewGuiSoundVol; - Sound()->SetChannel(CSounds::CHN_GUI, m_GuiSoundVolume, 1.0f); - } - - float NewGameSoundVol = g_Config.m_SndGameSoundVolume / 100.0f; - if(NewGameSoundVol != m_GameSoundVolume) - { - m_GameSoundVolume = NewGameSoundVol; - Sound()->SetChannel(CSounds::CHN_WORLD, 0.9f * m_GameSoundVolume, 1.0f); - Sound()->SetChannel(CSounds::CHN_GLOBAL, m_GameSoundVolume, 1.0f); - } - - float NewMapSoundVol = g_Config.m_SndMapSoundVolume / 100.0f; - if(NewMapSoundVol != m_MapSoundVolume) - { - m_MapSoundVolume = NewMapSoundVol; - Sound()->SetChannel(CSounds::CHN_MAPSOUND, m_MapSoundVolume, 1.0f); - } - - float NewBackgroundMusicVol = g_Config.m_SndBackgroundMusicVolume / 100.0f; - if(NewBackgroundMusicVol != m_BackgroundMusicVolume) - { - m_BackgroundMusicVolume = NewBackgroundMusicVol; - Sound()->SetChannel(CSounds::CHN_MUSIC, m_BackgroundMusicVolume, 1.0f); - } + Sound()->SetListenerPosition(m_pClient->m_Camera.m_Center); + UpdateChannels(); // play sound from queue if(m_QueuePos > 0) @@ -191,49 +180,26 @@ void CSounds::Enqueue(int Channel, int SetId) m_aQueue[m_QueuePos++].m_SetId = SetId; } -void CSounds::PlayAndRecord(int Channel, int SetId, float Vol, vec2 Pos) +void CSounds::PlayAndRecord(int Channel, int SetId, float Volume, vec2 Position) { + // TODO: Volume and position are currently not recorded for sounds played with this function + // TODO: This also causes desync sounds during demo playback of demos recorded on high ping servers: + // https://github.com/ddnet/ddnet/issues/1282 CNetMsg_Sv_SoundGlobal Msg; Msg.m_SoundId = SetId; Client()->SendPackMsgActive(&Msg, MSGFLAG_NOSEND | MSGFLAG_RECORD); - Play(Channel, SetId, Vol); + PlayAt(Channel, SetId, Volume, Position); } -void CSounds::Play(int Channel, int SetId, float Vol) +void CSounds::Play(int Channel, int SetId, float Volume) { - if(m_pClient->m_SuppressEvents) - return; - if(Channel == CHN_MUSIC && !g_Config.m_SndMusic) - return; - - int SampleId = GetSampleId(SetId); - if(SampleId == -1) - return; - - int Flags = 0; - if(Channel == CHN_MUSIC) - Flags = ISound::FLAG_LOOP; - - Sound()->Play(Channel, SampleId, Flags); + PlaySample(Channel, GetSampleId(SetId), 0, Volume); } -void CSounds::PlayAt(int Channel, int SetId, float Vol, vec2 Pos) +void CSounds::PlayAt(int Channel, int SetId, float Volume, vec2 Position) { - if(m_pClient->m_SuppressEvents) - return; - if(Channel == CHN_MUSIC && !g_Config.m_SndMusic) - return; - - int SampleId = GetSampleId(SetId); - if(SampleId == -1) - return; - - int Flags = 0; - if(Channel == CHN_MUSIC) - Flags = ISound::FLAG_LOOP; - - Sound()->PlayAt(Channel, SampleId, Flags, Pos.x, Pos.y); + PlaySampleAt(Channel, GetSampleId(SetId), 0, Volume, Position); } void CSounds::Stop(int SetId) @@ -259,24 +225,24 @@ bool CSounds::IsPlaying(int SetId) return false; } -ISound::CVoiceHandle CSounds::PlaySample(int Channel, int SampleId, float Vol, int Flags) +ISound::CVoiceHandle CSounds::PlaySample(int Channel, int SampleId, int Flags, float Volume) { - if((Channel == CHN_MUSIC && !g_Config.m_SndMusic) || SampleId == -1) + if(m_pClient->m_SuppressEvents || (Channel == CHN_MUSIC && !g_Config.m_SndMusic) || SampleId == -1) return ISound::CVoiceHandle(); if(Channel == CHN_MUSIC) Flags |= ISound::FLAG_LOOP; - return Sound()->Play(Channel, SampleId, Flags); + return Sound()->Play(Channel, SampleId, Flags, Volume); } -ISound::CVoiceHandle CSounds::PlaySampleAt(int Channel, int SampleId, float Vol, vec2 Pos, int Flags) +ISound::CVoiceHandle CSounds::PlaySampleAt(int Channel, int SampleId, int Flags, float Volume, vec2 Position) { - if((Channel == CHN_MUSIC && !g_Config.m_SndMusic) || SampleId == -1) + if(m_pClient->m_SuppressEvents || (Channel == CHN_MUSIC && !g_Config.m_SndMusic) || SampleId == -1) return ISound::CVoiceHandle(); if(Channel == CHN_MUSIC) Flags |= ISound::FLAG_LOOP; - return Sound()->PlayAt(Channel, SampleId, Flags, Pos.x, Pos.y); + return Sound()->PlayAt(Channel, SampleId, Flags, Volume, Position); } diff --git a/src/game/client/components/sounds.h b/src/game/client/components/sounds.h index 4ee5df561..8671f3bf8 100644 --- a/src/game/client/components/sounds.h +++ b/src/game/client/components/sounds.h @@ -34,12 +34,13 @@ class CSounds : public CComponent std::shared_ptr m_pSoundJob; bool m_WaitForSoundJob; + void UpdateChannels(); int GetSampleId(int SetId); - float m_GuiSoundVolume; - float m_GameSoundVolume; - float m_MapSoundVolume; - float m_BackgroundMusicVolume; + float m_GuiSoundVolume = -1.0f; + float m_GameSoundVolume = -1.0f; + float m_MapSoundVolume = -1.0f; + float m_BackgroundMusicVolume = -1.0f; public: // sound channels @@ -60,14 +61,14 @@ public: void ClearQueue(); void Enqueue(int Channel, int SetId); - void Play(int Channel, int SetId, float Vol); - void PlayAt(int Channel, int SetId, float Vol, vec2 Pos); - void PlayAndRecord(int Channel, int SetId, float Vol, vec2 Pos); + void Play(int Channel, int SetId, float Volume); + void PlayAt(int Channel, int SetId, float Volume, vec2 Position); + void PlayAndRecord(int Channel, int SetId, float Volume, vec2 Position); void Stop(int SetId); bool IsPlaying(int SetId); - ISound::CVoiceHandle PlaySample(int Channel, int SampleId, float Vol, int Flags = 0); - ISound::CVoiceHandle PlaySampleAt(int Channel, int SampleId, float Vol, vec2 Pos, int Flags = 0); + ISound::CVoiceHandle PlaySample(int Channel, int SampleId, int Flags, float Volume); + ISound::CVoiceHandle PlaySampleAt(int Channel, int SampleId, int Flags, float Volume, vec2 Position); }; #endif diff --git a/src/game/client/components/voting.cpp b/src/game/client/components/voting.cpp index 8a0282fdb..462a14e8d 100644 --- a/src/game/client/components/voting.cpp +++ b/src/game/client/components/voting.cpp @@ -269,7 +269,7 @@ void CVoting::OnMessage(int MsgType, void *pRawMsg) char aBuf[512]; str_format(aBuf, sizeof(aBuf), "%s (%s)", m_aDescription, m_aReason); Client()->Notify("DDNet Vote", aBuf); - m_pClient->m_Sounds.Play(CSounds::CHN_GUI, SOUND_CHAT_HIGHLIGHT, 0); + m_pClient->m_Sounds.Play(CSounds::CHN_GUI, SOUND_CHAT_HIGHLIGHT, 1.0f); } } } diff --git a/src/game/editor/editor.cpp b/src/game/editor/editor.cpp index 39e957dab..439c8b870 100644 --- a/src/game/editor/editor.cpp +++ b/src/game/editor/editor.cpp @@ -956,7 +956,7 @@ void CEditor::DoAudioPreview(CUIRect View, const void *pPlayPauseButtonId, const if(SampleId != m_ToolbarPreviewSound && m_ToolbarPreviewSound >= 0 && Sound()->IsPlaying(m_ToolbarPreviewSound)) Sound()->Pause(m_ToolbarPreviewSound); - Sound()->Play(CSounds::CHN_GUI, SampleId, ISound::FLAG_PREVIEW); + Sound()->Play(CSounds::CHN_GUI, SampleId, ISound::FLAG_PREVIEW, 1.0f); } } }