#include #include #include namespace psemek::audio { namespace { struct duplicate_impl : stream { duplicate_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(float * data, std::size_t sample_count) override { auto buffer = recorder_->buffer(); auto played = played_.load(); if (buffer.size() < played + sample_count) { recorder_->request(sample_count); buffer = recorder_->buffer(); } auto count = std::min(sample_count, buffer.size() - played); std::copy(buffer.data() + played, buffer.data() + played + count, data); played_.fetch_add(count); return count; } private: std::shared_ptr recorder_; std::atomic played_{0}; }; } duplicator make_duplicator(stream_ptr stream) { auto recorder = make_recorder(std::move(stream)); return [recorder]{ return std::make_shared(recorder); }; } }