From 4490123a640fe99a2ab8534ddeccc1a3fc2908bf Mon Sep 17 00:00:00 2001 From: lisyarus Date: Sun, 2 Oct 2022 15:18:10 +0300 Subject: [PATCH] Support dynamically changing 3d sound source position --- libs/audio/include/psemek/audio/3d.hpp | 8 +++++++- libs/audio/source/3d.cpp | 27 ++++++++++++++++++++------ 2 files changed, 28 insertions(+), 7 deletions(-) diff --git a/libs/audio/include/psemek/audio/3d.hpp b/libs/audio/include/psemek/audio/3d.hpp index cf789d79..0e1d27df 100644 --- a/libs/audio/include/psemek/audio/3d.hpp +++ b/libs/audio/include/psemek/audio/3d.hpp @@ -14,7 +14,13 @@ namespace psemek::audio { void set_position(geom::point const & position); - virtual std::shared_ptr make_effect(geom::point const & position, float distance_factor); + struct mono_effect + : effect + { + virtual void set_position(geom::point const & position) = 0; + }; + + virtual std::shared_ptr make_effect(geom::point const & position, float distance_factor); private: geom::point position_; diff --git a/libs/audio/source/3d.cpp b/libs/audio/source/3d.cpp index 35f40462..f58f8852 100644 --- a/libs/audio/source/3d.cpp +++ b/libs/audio/source/3d.cpp @@ -10,10 +10,10 @@ namespace psemek::audio namespace { - struct mono_impl - : effect + struct mono_effect_impl + : listener_3d_mono::mono_effect { - mono_impl(geom::point const & source_position, geom::point & target_position, std::mutex & target_position_mutex, float distance_factor) + mono_effect_impl(geom::point const & source_position, geom::point & target_position, std::mutex & target_position_mutex, float distance_factor) : source_position_(source_position) , target_position_(target_position) , cached_target_position_(target_position) @@ -37,15 +37,30 @@ namespace psemek::audio cached_target_position_ = target_position_; } - float distance = geom::distance(cached_target_position_, source_position_) / distance_factor_; + { + std::unique_lock lock{source_position_mutex_, std::try_to_lock}; + if (lock.owns_lock()) + cached_source_position_ = source_position_; + } + + float distance = geom::distance(cached_target_position_, cached_source_position_) / distance_factor_; float factor = std::min(1.f, 1.f / (1.f + distance * distance)); for (std::size_t i = 0; i < count; ++i) data[i] = pack(unpack(data[i]) * factor); } + void set_position(geom::point const & position) override + { + std::lock_guard lock{source_position_mutex_}; + source_position_ = position; + } + private: + std::mutex source_position_mutex_; geom::point source_position_; + geom::point cached_source_position_; + geom::point & target_position_; geom::point cached_target_position_; std::mutex & target_position_mutex_; @@ -60,9 +75,9 @@ namespace psemek::audio position_ = position; } - std::shared_ptr listener_3d_mono::make_effect(const geom::point &position, float distance_factor) + std::shared_ptr listener_3d_mono::make_effect(const geom::point &position, float distance_factor) { - return std::make_shared(position, position_, position_mutex_, distance_factor); + return std::make_shared(position, position_, position_mutex_, distance_factor); } }