osb/source/frontend/StarMainMixer.cpp
Kai Blaschke 431a9c00a5
Fixed a huge amount of Clang warnings
On Linux and macOS, using Clang to compile OpenStarbound produces about 400 MB worth of warnings during the build, making the compiler output unreadable and slowing the build down considerably.

99% of the warnings were unqualified uses of std::move and std::forward, which are now all properly qualified.

Fixed a few other minor warnings about non-virtual destructors and some uses of std::move preventing copy elision on temporary objects.

Most remaining warnings are now unused parameters.
2024-02-19 16:55:19 +01:00

148 lines
4.9 KiB
C++

#include "StarMainMixer.hpp"
#include "StarJsonExtra.hpp"
#include "StarRoot.hpp"
#include "StarConfiguration.hpp"
#include "StarUniverseClient.hpp"
#include "StarPlayer.hpp"
#include "StarAssets.hpp"
#include "StarWorldClient.hpp"
#include "StarWorldPainter.hpp"
#include "StarVoice.hpp"
namespace Star {
MainMixer::MainMixer(unsigned sampleRate, unsigned channels) {
m_mixer = make_shared<Mixer>(sampleRate, channels);
}
void MainMixer::setUniverseClient(UniverseClientPtr universeClient) {
m_universeClient = std::move(universeClient);
}
void MainMixer::setWorldPainter(WorldPainterPtr worldPainter) {
m_worldPainter = std::move(worldPainter);
}
void MainMixer::update(float dt, bool muteSfx, bool muteMusic) {
auto assets = Root::singleton().assets();
auto updateGroupVolume = [&](MixerGroup group, bool muted, String const& settingName) {
if (m_mutedGroups.contains(group) != muted) {
if (muted) {
m_mutedGroups.add(group);
m_mixer->setGroupVolume(group, 0, 1.0f);
} else {
m_mutedGroups.remove(group);
m_mixer->setGroupVolume(group, m_groupVolumes[group], 1.0f);
}
} else if (!m_mutedGroups.contains(group)) {
float volumeSetting = Root::singleton().configuration()->get(settingName).toFloat() / 100.0f;
if (!m_groupVolumes.contains(group) || volumeSetting != m_groupVolumes[group]) {
m_mixer->setGroupVolume(group, volumeSetting);
m_groupVolumes[group] = volumeSetting;
}
}
};
updateGroupVolume(MixerGroup::Effects, muteSfx, "sfxVol");
updateGroupVolume(MixerGroup::Music, muteMusic, "musicVol");
updateGroupVolume(MixerGroup::Cinematic, false, "sfxVol");
updateGroupVolume(MixerGroup::Instruments, muteSfx, "instrumentVol");
WorldClientPtr currentWorld;
if (m_universeClient)
currentWorld = m_universeClient->worldClient();
if (currentWorld) {
for (auto audioInstance : currentWorld->pullPendingAudio())
m_mixer->play(audioInstance);
for (auto audioInstance : currentWorld->pullPendingMusic()) {
audioInstance->setMixerGroup(MixerGroup::Music);
m_mixer->play(audioInstance);
}
if (m_universeClient && m_universeClient->mainPlayer()->underwater()) {
if (!m_mixer->hasEffect("lowpass"))
m_mixer->addEffect("lowpass", m_mixer->lowpass(32), 0.50f);
if (!m_mixer->hasEffect("echo"))
m_mixer->addEffect("echo", m_mixer->echo(0.2f, 0.6f, 0.4f), 0.50f);
} else {
if (m_mixer->hasEffect("lowpass"))
m_mixer->removeEffect("lowpass", 0.5f);
if (m_mixer->hasEffect("echo"))
m_mixer->removeEffect("echo", 0.5f);
}
float baseMaxDistance = assets->json("/sfx.config:baseMaxDistance").toFloat();
Vec2F stereoAdjustmentRange = jsonToVec2F(assets->json("/sfx.config:stereoAdjustmentRange"));
float attenuationGamma = assets->json("/sfx.config:attenuationGamma").toFloat();
auto playerPos = m_universeClient->mainPlayer()->position();
auto cameraPos = m_worldPainter->camera().centerWorldPosition();
auto worldGeometry = currentWorld->geometry();
Mixer::PositionalAttenuationFunction attenuationFunction = [&](unsigned channel, Vec2F pos, float rangeMultiplier) {
Vec2F playerDiff = worldGeometry.diff(pos, playerPos);
Vec2F cameraDiff = worldGeometry.diff(pos, cameraPos);
float playerMagSq = playerDiff.magnitudeSquared();
float cameraMagSq = cameraDiff.magnitudeSquared();
Vec2F diff;
float diffMagnitude;
if (playerMagSq < cameraMagSq) {
diff = playerDiff;
diffMagnitude = sqrt(playerMagSq);
}
else {
diff = cameraDiff;
diffMagnitude = sqrt(cameraMagSq);
}
if (diffMagnitude == 0.0f)
return 0.0f;
Vec2F diffNorm = diff / diffMagnitude;
float stereoIncidence = channel == 0 ? -diffNorm[0] : diffNorm[0];
float maxDistance = baseMaxDistance * rangeMultiplier * lerp((stereoIncidence + 1.0f) / 2.0f, stereoAdjustmentRange[0], stereoAdjustmentRange[1]);
return pow(clamp(diffMagnitude / maxDistance, 0.0f, 1.0f), 1.0f / attenuationGamma);
};
if (Voice* voice = Voice::singletonPtr())
voice->update(dt, attenuationFunction);
m_mixer->update(dt, attenuationFunction);
} else {
if (m_mixer->hasEffect("lowpass"))
m_mixer->removeEffect("lowpass", 0);
if (m_mixer->hasEffect("echo"))
m_mixer->removeEffect("echo", 0);
if (Voice* voice = Voice::singletonPtr())
voice->update(dt);
m_mixer->update(dt);
}
}
MixerPtr MainMixer::mixer() const {
return m_mixer;
}
void MainMixer::setSpeed(float speed) {
m_mixer->setSpeed(max(speed, 0.0f));
}
void MainMixer::setVolume(float volume, float rampTime) {
m_mixer->setVolume(volume, rampTime);
}
void MainMixer::read(int16_t* sampleData, size_t frameCount, Mixer::ExtraMixFunction extraMixFunction) {
m_mixer->read(sampleData, frameCount, extraMixFunction);
}
}