#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(util::span samples) override { std::size_t count = 0; for (; index_ != streams_.size(); ++index_) { auto read = streams_[index_]->read(samples); count += read; samples.consume(read); if (samples.empty()) 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)); } }