#include #include 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(2, delay.samples()), 0.f) , gain_(gain) {} std::optional length() const override { return std::nullopt; } // y[n] = (−g·x[n]) + x[n−M] + (g·y[n−M]) std::size_t read(util::span 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 buffer_; std::size_t buffer_pos_ = 0; float gain_; }; } stream_ptr all_pass(stream_ptr stream, duration delay, float gain) { return std::make_shared(std::move(stream), delay, gain); } }