| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172 |
- #include <SDL.h>
- #include "CSound.h"
- #include "WallpaperEngine/FileSystem/Container.h"
- #include <algorithm>
- using namespace WallpaperEngine::Render::Objects;
- CSound::CSound (Wallpapers::CScene& scene, const Sound& sound) :
- CObject (scene, sound), m_sound (sound), m_playing (scene.getSoundPlayRequest (sound.id).value_or (!sound.startsilent.value_or (false))) {
- if (this->getContext ().getApp ().getContext ().settings.audio.enabled) {
- this->load ();
- }
- }
- CSound::~CSound () {
- for (const auto& stream : this->m_audioStreams) {
- this->getScene ().getAudioContext ().removeStream (stream.first);
- delete stream.second;
- }
- this->m_audioStreams.clear ();
- }
- void CSound::load () {
- for (const auto& cur : this->m_sound.sounds) {
- auto stream
- = new Audio::AudioStream (this->getScene ().getAudioContext (), this->getAssetLocator ().read (cur));
- stream->setRepeat (this->m_sound.playbackmode == PlaybackMode_Loop);
- this->m_audioStreams.insert_or_assign (this->getScene ().getAudioContext ().addStream (stream), stream);
- }
- }
- void CSound::render () { this->applyEffectiveVolume (); }
- void CSound::play () {
- this->m_playing = true;
- this->applyEffectiveVolume ();
- }
- void CSound::stop () {
- this->m_playing = false;
- this->applyEffectiveVolume ();
- }
- void CSound::setVolumeOverride (std::optional<int> volume) {
- this->m_screenVolumeOverride = volume;
- this->applyEffectiveVolume ();
- }
- void CSound::applyEffectiveVolume () {
- // The screen-level policy (mute/ambient-volume, set via setVolumeOverride from
- // CScene::setAudioPolicy) and the wallpaper author's own per-object "volume" property (e.g.
- // picking which of several alternate music tracks plays) are independent inputs that have to
- // combine, not overwrite each other - otherwise picking a track would undo screen muting, or
- // muting a screen would make track selection pointless.
- const int base = this->m_screenVolumeOverride.value_or (
- this->getContext ().getApp ().getContext ().state.audio.volume
- );
- const float fraction = this->m_sound.volume && this->m_sound.volume->value
- ? std::clamp (this->m_sound.volume->value->getFloat (), 0.0f, 1.0f)
- : 1.0f;
- const int effective = this->m_playing ? static_cast<int> (static_cast<float> (base) * fraction) : 0;
- for (const auto& entry : this->m_audioStreams) {
- this->getScene ().getAudioContext ().setStreamVolume (entry.first, effective);
- }
- }
|