46 lines
1.1 KiB
C++
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;
|
|
}
|
|
|
|
}
|