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

53 lines
1.4 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_left, float gain_right, float smoothness)
: gain_{gain_left, gain_right}
, smoothness_multiplier_{smoothness_to_multiplier(smoothness)}
, real_gain_{gain_left, gain_right}
, 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[2] = {gain_[0].load(), gain_[1].load()};
float smoothness_multiplier = smoothness_multiplier_.load();
auto apply_impl = [this](float & target, int i)
{
auto old = target;
target = last_sample_tgt_[i] + (old - last_sample_src_[i]) * real_gain_[i];
last_sample_src_[i] = old;
last_sample_tgt_[i] = target;
};
auto end = data + sample_count;
for (auto p = data; p < end;)
{
apply_impl(*p++, 0);
apply_impl(*p++, 1);
smooth_update(real_gain_[0], gain[0], smoothness_multiplier);
smooth_update(real_gain_[1], gain[1], smoothness_multiplier);
}
}
}