Add 3d mono audio effect
This commit is contained in:
parent
c4ead52fd6
commit
3f758e845d
3 changed files with 93 additions and 1 deletions
|
|
@ -5,4 +5,4 @@ file(GLOB_RECURSE PSEMEK_AUDIO_SOURCES RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" "s
|
|||
|
||||
psemek_add_library(psemek-audio ${PSEMEK_AUDIO_HEADERS} ${PSEMEK_AUDIO_SOURCES})
|
||||
target_include_directories(psemek-audio PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include")
|
||||
target_link_libraries(psemek-audio PUBLIC psemek-sdl2 psemek-util psemek-log SDL2_mixer)
|
||||
target_link_libraries(psemek-audio PUBLIC psemek-sdl2 psemek-geom psemek-util psemek-log SDL2_mixer)
|
||||
|
|
|
|||
24
libs/audio/include/psemek/audio/3d.hpp
Normal file
24
libs/audio/include/psemek/audio/3d.hpp
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
#pragma once
|
||||
|
||||
#include <psemek/audio/effect.hpp>
|
||||
#include <psemek/geom/point.hpp>
|
||||
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <mutex>
|
||||
|
||||
namespace psemek::audio
|
||||
{
|
||||
|
||||
struct listener_3d_mono
|
||||
{
|
||||
void set_position(geom::point<float, 3> const & position);
|
||||
|
||||
virtual std::shared_ptr<effect> make_effect(geom::point<float, 3> const & position, float distance_factor);
|
||||
|
||||
private:
|
||||
geom::point<float, 3> position_;
|
||||
std::mutex position_mutex_;
|
||||
};
|
||||
|
||||
}
|
||||
68
libs/audio/source/3d.cpp
Normal file
68
libs/audio/source/3d.cpp
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
#include <psemek/audio/3d.hpp>
|
||||
#include <psemek/util/not_implemented.hpp>
|
||||
|
||||
#include <optional>
|
||||
#include <mutex>
|
||||
|
||||
namespace psemek::audio
|
||||
{
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
struct mono_impl
|
||||
: effect
|
||||
{
|
||||
mono_impl(geom::point<float, 3> const & source_position, geom::point<float, 3> & target_position, std::mutex & target_position_mutex, float distance_factor)
|
||||
: source_position_(source_position)
|
||||
, target_position_(target_position)
|
||||
, cached_target_position_(target_position)
|
||||
, target_position_mutex_(target_position_mutex)
|
||||
, distance_factor_(distance_factor)
|
||||
{}
|
||||
|
||||
std::string_view name() const override
|
||||
{
|
||||
return "mono_3d";
|
||||
}
|
||||
|
||||
void init(int, int) override
|
||||
{ }
|
||||
|
||||
void operator()(sample * data, std::size_t count) override
|
||||
{
|
||||
{
|
||||
std::unique_lock lock{target_position_mutex_, std::try_to_lock};
|
||||
if (lock.owns_lock())
|
||||
cached_target_position_ = target_position_;
|
||||
}
|
||||
|
||||
float distance = geom::distance(cached_target_position_, 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);
|
||||
}
|
||||
|
||||
private:
|
||||
geom::point<float, 3> source_position_;
|
||||
geom::point<float, 3> & target_position_;
|
||||
geom::point<float, 3> cached_target_position_;
|
||||
std::mutex & target_position_mutex_;
|
||||
float distance_factor_;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
void listener_3d_mono::set_position(geom::point<float, 3> const & position)
|
||||
{
|
||||
std::lock_guard lock{position_mutex_};
|
||||
position_ = position;
|
||||
}
|
||||
|
||||
std::shared_ptr<effect> listener_3d_mono::make_effect(const geom::point<float, 3> &position, float distance_factor)
|
||||
{
|
||||
return std::make_shared<mono_impl>(position, position_, position_mutex_, distance_factor);
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue