52 lines
1.3 KiB
C++
52 lines
1.3 KiB
C++
#include <psemek/audio/effect/volume_base.hpp>
|
|
#include <psemek/audio/constants.hpp>
|
|
#include <psemek/audio/smooth.hpp>
|
|
|
|
#include <cmath>
|
|
|
|
namespace psemek::audio
|
|
{
|
|
|
|
volume_base::volume_base(float gain, float smoothness)
|
|
: gain_{gain}
|
|
, smoothness_multiplier_{smoothness_to_multiplier(smoothness)}
|
|
, real_gain_{gain}
|
|
, last_sample_src_{0.f, 0.f}
|
|
, last_sample_tgt_{0.f, 0.f}
|
|
{}
|
|
|
|
float volume_base::smoothness() const
|
|
{
|
|
return multiplier_to_smoothness(smoothness_multiplier_.load());
|
|
}
|
|
|
|
float volume_base::smoothness(float value)
|
|
{
|
|
auto old = smoothness_multiplier_.exchange(smoothness_to_multiplier(value));
|
|
return multiplier_to_smoothness(old);
|
|
}
|
|
|
|
void volume_base::apply(float * data, std::size_t sample_count)
|
|
{
|
|
float gain = gain_.load();
|
|
float smoothness_multiplier = smoothness_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]);
|
|
|
|
smooth_update(real_gain_, gain, smoothness_multiplier);
|
|
}
|
|
}
|
|
|
|
}
|