#include #include #include namespace psemek::audio { namespace { struct fade_in_impl : stream { fade_in_impl(stream_ptr stream, float length, float start) : stream_(std::move(stream)) , length_(2 * std::round(length * frequency)) , start_samples_(2 * std::round(start * frequency)) {} std::optional length() const override { return stream_->length(); } std::size_t played() const override { return stream_->played(); } std::size_t read(float * data, std::size_t sample_count) override { auto const result = stream_->read(data, sample_count); std::fill(data, data + std::min(result, start_samples_), 0.f); if (result <= start_samples_) { start_samples_ -= result; } else { for (std::size_t i = start_samples_; i < result; i += 2) { float m = static_cast(std::min(current_, length_)) / length_; data[i + 0] *= m; data[i + 1] *= m; current_ += 2; } start_samples_ = 0; } return result; } private: stream_ptr stream_; std::size_t length_; std::size_t current_ = 0; std::size_t start_samples_; }; } stream_ptr fade_in(stream_ptr stream, float length, float start) { return std::make_shared(std::move(stream), length, start); } }