#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_->channel()->stream()->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_->channel()->stream()->length(); } private: std::shared_ptr recorder_; }; } track_ptr make_duplicator(std::shared_ptr recorder) { return std::make_shared(std::move(recorder)); } track_ptr make_duplicator(stream_ptr stream) { return make_duplicator(make_recorder(std::move(stream))); } std::pair duplicate(stream_ptr stream) { auto track = make_duplicator(std::move(stream)); return {track->stream(), track->stream()}; } }