#include #include namespace psemek::audio { namespace { struct concat_impl : stream { concat_impl(std::vector streams) : streams_(std::move(streams)) { length_ = 0; for (auto const & stream : streams_) { if (auto length = stream->length()) *length_ += *length; else { length_ = std::nullopt; break; } } } std::optional length() const override { return length_; } std::size_t read(float * data, std::size_t sample_count) override { std::size_t count = 0; for (; index_ != streams_.size(); ++index_) { count += streams_[index_]->read(data + count, sample_count - count); if (count == sample_count) break; } played_.fetch_add(count); return count; } std::size_t played() const override { return played_; } private: std::vector streams_; std::optional length_; std::atomic played_{0}; std::size_t index_{0}; }; } stream_ptr concat(std::vector streams) { return std::make_shared(std::move(streams)); } }