psemek/libs/audio/source/resampler.cpp

46 lines
1.1 KiB
C++

#include <psemek/audio/resampler.hpp>
#include <psemek/geom/math.hpp>
#include <vector>
namespace psemek::audio
{
void resampler::feed(util::span<float const> samples, float ratio)
{
result_.clear();
if (samples.empty())
return;
float const delta = 1.f / ratio;
while (position_ < 0)
{
result_.push_back(geom::lerp(last_sample_[0], samples[0], position_frac_));
result_.push_back(geom::lerp(last_sample_[1], samples[1], position_frac_));
advance(delta);
}
while (2 * position_ + 3 < samples.size())
{
result_.push_back(geom::lerp(samples[2 * position_ + 0], samples[2 * position_ + 2], position_frac_));
result_.push_back(geom::lerp(samples[2 * position_ + 1], samples[2 * position_ + 3], position_frac_));
advance(delta);
}
position_ -= static_cast<int>(samples.size()) / 2;
last_sample_[0] = samples[samples.size() - 2];
last_sample_[1] = samples[samples.size() - 1];
}
void resampler::advance(float delta)
{
position_frac_ += delta;
auto floor = static_cast<int>(std::floor(position_frac_));
position_ += floor;
position_frac_ -= floor;
}
}