psemek/libs/audio/source/effect/all_pass.cpp
2023-10-08 15:58:51 +03:00

68 lines
1.4 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <psemek/audio/effect/all_pass.hpp>
#include <vector>
namespace psemek::audio
{
namespace
{
struct all_pass_impl
: stream
{
all_pass_impl(stream_ptr stream, duration delay, float gain)
: stream_(std::move(stream))
, buffer_(std::max<std::size_t>(2, delay.samples()), 0.f)
, gain_(gain)
{}
std::optional<std::size_t> length() const override
{
return std::nullopt;
}
// y[n] = (g·x[n]) + x[nM] + (g·y[nM])
std::size_t read(util::span<float> samples) override
{
auto count = stream_->read(samples);
for (std::size_t i = 0; i < count; ++i)
{
float input = samples[i];
samples[i] = - gain_ * input + buffer_[buffer_pos_];
buffer_[buffer_pos_] = input + gain_ * samples[i];
++buffer_pos_;
buffer_pos_ %= buffer_.size();
}
for (std::size_t i = count; i < samples.size(); ++i)
{
samples[i] = buffer_[buffer_pos_];
buffer_[buffer_pos_] = gain_ * buffer_[buffer_pos_];
++buffer_pos_;
buffer_pos_ %= buffer_.size();
}
return samples.size();
}
std::size_t played() const override
{
return stream_->played();
}
private:
stream_ptr stream_;
std::vector<float> buffer_;
std::size_t buffer_pos_ = 0;
float gain_;
};
}
stream_ptr all_pass(stream_ptr stream, duration delay, float gain)
{
return std::make_shared<all_pass_impl>(std::move(stream), delay, gain);
}
}