Open GoogleFrog opened 5 years ago
As the paste is going to expire in a few days, I'll copy my findings here, too:
[14:29] CatLady: esainane, for the love of goddess, if you could fix the ZK lobby under linux turning music to max volume after each track change, you would be eternally blessed
...
[09:22] esainane: So following up on the complaint from 19 hours ago, it looks like spring has distinct concepts for channel volume and sound source volume [09:24] esainane: https://github.com/spring/spring/blob/develop/rts/System/Sound/OpenAL/SoundSource.cpp#L355 here we see both values being used when the volume is adjusted on a track that is already playing [09:26] esainane: Looking at the behaviour in https://github.com/ZeroK-RTS/Chobby/blob/master/LuaMenu/widgets/snd_music_lite.lua#L75 the simplest way to reproduce involves disabling the current track by setting the volume to zero, then setting the volume to 0.02 which should be functionally silent, and observing it can be heard, then setting volume to 0.04, which should be increasing the volume over the previous setting, then observing that the track can't be heard anymore [09:27] esainane: The simplest fix would be to unconditionally call Spring.SetSoundStreamVolume in the lobby music widget, so we always use both volume values [09:28] esainane: But I'm not sure if this should also be considered an issue in the engine, or in springrts lua documentation, as there's no hint at this being the functionality [09:28] esainane: aaand I spoke in wrong channel
LuaMenu/widgets/snd_music_lite.lua
StartTrack()
Spring.Echo("Starting Track", trackName, volume)
We know that this much is working properly, see [f=-000001] Starting Track, sounds/lobbyMusic/Interstellar.ogg, 0.5
invokes Spring.PlaySoundStream(trackName, volume)
LuaUnsyncedCtrl::PlaySoundStream(lua_State* L)
// file, volume, enqueue
Channels::BGMusic->StreamPlay(luaL_checksstring(L, 1), luaL_optnumber(L, 2, 1.0f), luaL_optboolean(L, 3, false));
rts/System/Sound/OpenAL/AudioChannel.cpp
void AudioChannel::StreamPlay(const std::string& filepath, float volume, bool enqueue)
curStreamSrc->PlayStream(this, filepath, volume);
rts/System/Sound/OpenAL/SoundSource.cpp
void CSoundSource::PlayStream(IAudioChannel* channel, const std::string& file, float volume)
curVolume = volume;
Separately, changing the volume for a track in progress:
LuaMenu/widgets/snd_music_lite.lua
local function SetTrackVolume(volume)
Spring.SetSoundStreamVolume(volume)
or
StartTrack(GetRandomTrack(), volume)
int LuaUnsyncedCtrl::SetSoundStreamVolume(lua_State* L)
Channels::BGMusic->SetVolume(luaL_checkfloat(L, 1));
rts/System/Sound/OpenAL/AudioChannel.cpp
void AudioChannel::SetVolume(float newVolume)
volume = std::max(newVolume, 0.0f);
for (auto it = curSources.begin(); it != curSources.end(); ++it) {
(*it)->UpdateVolume();
}
We see volume taking into account both the channel volume and the sound source volume when UpdateVolume is called, and only when UpdateVolume is called.
curChannel is not referenced outside of assignment in SoundSource.cpp otherwise.
The only time UpdateVolume is called is from rts/System/Sound/OpenAL/AudioChannel.cpp:AudioChannel::SetVolume
.
AudioChannel::SetVolume
is called in many places in rts/System/Sound/OpenAL/Sound.cpp
, but none relevant to the background music channel outside of initial configuration (Channels::BGMusic->SetVolume(std::atoi(value.c_str()) * 0.01f);
) and via rts/Lua/LuaUnsyncedCtrl.cpp
. It's not going to get called every time a new track is played.
rts/System/Sound/OpenAL/SoundSource.cpp
void CSoundSource::UpdateVolume()
alSourcef(id, AL_GAIN, curVolume * curChannel->volume);
This is still a problem