psemek/libs/audio/source/effect/volume_base.cpp

52 lines
1.2 KiB
C++

#include <psemek/audio/effect/volume_base.hpp>
#include <psemek/audio/constants.hpp>
#include <psemek/audio/attack.hpp>
#include <cmath>
namespace psemek::audio
{
volume_base::volume_base(float gain, float attack)
: gain_{gain}
, attack_multiplier_{attack_to_multiplier(attack)}
, real_gain_{gain}
, last_sample_src_{0.f, 0.f}
, last_sample_tgt_{0.f, 0.f}
{}
float volume_base::attack() const
{
return multiplier_to_attack(attack_multiplier_.load());
}
float volume_base::attack(float value)
{
auto old = attack_multiplier_.exchange(attack_to_multiplier(value));
return multiplier_to_attack(old);
}
void volume_base::apply(float * data, std::size_t sample_count)
{
float gain = gain_.load();
float attack_multiplier = attack_multiplier_.load();
auto apply_impl = [this](float & target, float & last_src, float & last_tgt)
{
auto old = target;
target = last_tgt + (old - last_src) * real_gain_;
last_src = old;
last_tgt = target;
};
auto end = data + sample_count;
for (auto p = data; p < end;)
{
apply_impl(*p++, last_sample_src_[0], last_sample_tgt_[0]);
apply_impl(*p++, last_sample_src_[1], last_sample_tgt_[1]);
attack_update(real_gain_, gain, attack_multiplier);
}
}
}