#include #include namespace psemek::audio { namespace { struct duplicate_stream_impl : stream { duplicate_stream_impl(std::shared_ptr recorder) : recorder_(std::move(recorder)) {} std::optional length() const override { return recorder_->length(); } std::size_t played() const override { return played_.load(); } std::size_t read(util::span samples) override { auto buffer = recorder_->buffer(); auto played = played_.load(); if (buffer.size() < played + samples.size()) { recorder_->request(samples.size()); buffer = recorder_->buffer(); } auto count = std::min(samples.size(), buffer.size() - played); std::copy(buffer.data() + played, buffer.data() + played + count, samples.begin()); played_.fetch_add(count); return count; } private: std::shared_ptr recorder_; std::atomic played_{0}; }; struct duplicate_track_impl : track { duplicate_track_impl(std::shared_ptr recorder) : recorder_(std::move(recorder)) {} stream_ptr stream() const override { return std::make_shared(recorder_); } std::optional length() const override { return recorder_->length(); } private: std::shared_ptr recorder_; }; } track_ptr make_duplicator(std::shared_ptr recorder) { return std::make_shared(std::move(recorder)); } }