Add simple 1st order feedforward filters

This commit is contained in:
Nikita Lisitsa 2023-01-06 20:09:43 +03:00
parent ef95af60ae
commit 630ae28301
2 changed files with 82 additions and 0 deletions

View file

@ -0,0 +1,14 @@
#pragma once
#include <psemek/audio/stream.hpp>
namespace psemek::audio
{
// Turns x[n] into a0*x[n] + a1*x[n-1]
stream_ptr feedforward_filter(stream_ptr stream, float a0, float a1);
stream_ptr low_pass_filter(stream_ptr stream);
stream_ptr high_pass_filter(stream_ptr stream);
}

View file

@ -0,0 +1,68 @@
#include <psemek/audio/effect/filter.hpp>
namespace psemek::audio
{
namespace
{
struct feedforward_filter_impl
: stream
{
feedforward_filter_impl(stream_ptr stream, float a0, float a1)
: stream_(std::move(stream))
, a0_(a0)
, a1_(a1)
{}
std::optional<std::size_t> length() const override
{
return stream_->length();
}
std::size_t read(float * data, std::size_t sample_count) override
{
std::size_t count = stream_->read(data, sample_count);
for (std::size_t i = 0; i < count; i += 2)
{
std::swap(prev_[0], data[i + 0]);
std::swap(prev_[1], data[i + 1]);
data[i + 0] = prev_[0] * a0_ + data[i + 0] * a1_;
data[i + 1] = prev_[1] * a0_ + data[i + 1] * a1_;
}
return count;
}
std::size_t played() const override
{
return stream_->played();
}
private:
stream_ptr stream_;
float a0_;
float a1_;
float prev_[2]{0.f};
};
}
stream_ptr feedforward_filter(stream_ptr stream, float a0, float a1)
{
return std::make_shared<feedforward_filter_impl>(std::move(stream), a0, a1);
}
stream_ptr low_pass_filter(stream_ptr stream)
{
return feedforward_filter(std::move(stream), 1.f, 1.f);
}
stream_ptr high_pass_filter(stream_ptr stream)
{
return feedforward_filter(std::move(stream), 1.f, -1.f);
}
}