#include #include namespace psemek::audio { namespace { struct data_holder { std::vector storage; util::span samples; data_holder(util::span samples) : samples(samples) {} data_holder(std::vector storage) : storage(std::move(storage)) , samples(this->storage) {} }; struct raw_stream_impl : stream { raw_stream_impl(std::shared_ptr data_holder) : data_holder_(std::move(data_holder)) {} std::optional length() const override { return data_holder_->samples.size(); } std::size_t read(util::span samples) override { auto played = played_.load(); auto count = std::min(data_holder_->samples.size() - played, samples.size()); std::copy(data_holder_->samples.begin() + played, data_holder_->samples.begin() + played + count, samples.begin()); played_.fetch_add(count); return count; } std::size_t played() const override { return played_; } private: std::shared_ptr data_holder_; std::atomic played_{0}; }; struct raw_track_impl : track { raw_track_impl(std::shared_ptr data_holder) : data_holder_(std::move(data_holder)) {} stream_ptr stream() const override { return std::make_shared(data_holder_); } std::optional length() const override { return data_holder_->samples.size(); } private: std::shared_ptr data_holder_; }; } track_ptr load_raw(util::span samples) { if ((samples.size() % 2) != 0) throw std::runtime_error("bad sample count"); return std::make_shared(std::make_shared(samples)); } track_ptr load_raw(std::vector samples) { if ((samples.size() % 2) != 0) throw std::runtime_error("bad sample count"); return std::make_shared(std::make_shared(std::move(samples))); } }